Browse Source

packetizer: hevc: allow empty SPS/PPS in DCR

pull/199/head
François Cartegnie 11 months ago
committed by Jean-Baptiste Kempf
parent
commit
36e3056262
  1. 10
      modules/codec/omxil/omxil.c
  2. 20
      modules/packetizer/hevc.c
  3. 75
      modules/packetizer/hevc_nal.c
  4. 4
      modules/packetizer/hevc_nal.h

10
modules/codec/omxil/omxil.c

@ -1064,12 +1064,10 @@ static int OpenGeneric( vlc_object_t *p_this, bool b_encode )
}
else if( p_dec->fmt_in->i_codec == VLC_CODEC_HEVC && !p_sys->in.b_direct )
{
size_t i_filled_len = 0;
uint8_t *p_buf = hevc_hvcC_to_AnnexB_NAL(
p_dec->fmt_in->p_extra, p_dec->fmt_in->i_extra,
&i_filled_len, &p_sys->i_nal_size_length );
if( p_buf == NULL )
size_t i_filled_len;
if( !hevc_hvcC_to_AnnexB_NAL( p_dec->fmt_in->p_extra, p_dec->fmt_in->i_extra,
&p_buf, &i_filled_len,
&p_sys->i_nal_size_length )
{
msg_Dbg(p_dec, "hevc_hvcC_to_AnnexB_NAL() failed");
goto error;

20
modules/packetizer/hevc.c

@ -250,23 +250,21 @@ static int Open(vlc_object_t *p_this)
/* Check if we have hvcC as extradata */
if(hevc_ishvcC(p_extra, i_extra))
{
p_dec->pf_packetize = PacketizeHVC1;
/* Clear hvcC/HVC1 extra, to be replaced with AnnexB */
free(p_dec->fmt_out.p_extra);
p_dec->fmt_out.i_extra = 0;
size_t i_new_extra = 0;
p_dec->fmt_out.p_extra =
hevc_hvcC_to_AnnexB_NAL(p_extra, i_extra,
&i_new_extra, &p_sys->i_nal_length_size);
if(!p_dec->fmt_out.p_extra)
uint8_t *p_new_extra;
size_t i_new_extra;
if(!hevc_hvcC_to_AnnexB_NAL(p_extra, i_extra,
&p_new_extra, &i_new_extra,
&p_sys->i_nal_length_size))
{
msg_Err( p_dec, "Invalid HVCC extradata");
Close( VLC_OBJECT(p_dec) );
return VLC_EGENERIC;
}
/* Clear hvcC/HVC1 extra, to be replaced with AnnexB */
free(p_dec->fmt_out.p_extra);
p_dec->fmt_out.p_extra = p_new_extra;
p_dec->fmt_out.i_extra = i_new_extra;
p_dec->pf_packetize = PacketizeHVC1;
}
else
{

75
modules/packetizer/hevc_nal.c

@ -303,16 +303,16 @@ struct hevc_slice_segment_header_t
};
/* Computes size and does check the whole struct integrity */
static size_t get_hvcC_to_AnnexB_NAL_size( const uint8_t *p_buf, size_t i_buf )
static bool get_hvcC_to_AnnexB_NAL_size( const uint8_t *p_buf, size_t i_buf, size_t *pi_res )
{
size_t i_total = 0;
if( i_buf < HEVC_MIN_HVCC_SIZE )
return 0;
return false;
const uint8_t i_nal_length_size = (p_buf[21] & 0x03) + 1;
if(i_nal_length_size == 3)
return 0;
return false;
const uint8_t i_num_array = p_buf[22];
p_buf += 23; i_buf -= 23;
@ -320,7 +320,7 @@ static size_t get_hvcC_to_AnnexB_NAL_size( const uint8_t *p_buf, size_t i_buf )
for( uint8_t i = 0; i < i_num_array; i++ )
{
if(i_buf < 3)
return 0;
return false;
const uint16_t i_num_nalu = p_buf[1] << 8 | p_buf[2];
p_buf += 3; i_buf -= 3;
@ -328,11 +328,11 @@ static size_t get_hvcC_to_AnnexB_NAL_size( const uint8_t *p_buf, size_t i_buf )
for( uint16_t j = 0; j < i_num_nalu; j++ )
{
if(i_buf < 2)
return 0;
return false;
const uint16_t i_nalu_length = p_buf[0] << 8 | p_buf[1];
if(i_buf < (size_t)i_nalu_length + 2)
return 0;
return false;
i_total += i_nalu_length + 4; // annexb_startcode4;
p_buf += i_nalu_length + 2;
@ -340,48 +340,53 @@ static size_t get_hvcC_to_AnnexB_NAL_size( const uint8_t *p_buf, size_t i_buf )
}
}
return i_total;
*pi_res = i_total;
return true;
}
uint8_t * hevc_hvcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
size_t *pi_result, uint8_t *pi_nal_length_size )
bool hevc_hvcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
uint8_t **pp_result, size_t *pi_result,
uint8_t *pi_nal_length_size )
{
*pi_result = get_hvcC_to_AnnexB_NAL_size( p_buf, i_buf ); /* Does all checks */
if( *pi_result == 0 )
return NULL;
if( pi_nal_length_size )
*pi_nal_length_size = hevc_getNALLengthSize( p_buf );
size_t i_result;
if(!get_hvcC_to_AnnexB_NAL_size( p_buf, i_buf, &i_result )) /* Does all checks */
return false;
uint8_t *p_ret;
uint8_t *p_out_buf = p_ret = malloc( *pi_result );
if( !p_out_buf )
const uint8_t i_nal_length_size = hevc_getNALLengthSize( p_buf );
uint8_t *p_out_buf = NULL;
if( i_result > 0 )
{
*pi_result = 0;
return NULL;
}
const uint8_t i_num_array = p_buf[22];
p_buf += 23;
p_out_buf = malloc( i_result );
if( !p_out_buf )
return false;
for( uint8_t i = 0; i < i_num_array; i++ )
{
const uint16_t i_num_nalu = p_buf[1] << 8 | p_buf[2];
p_buf += 3;
const uint8_t i_num_array = p_buf[22];
p_buf += 23;
for( uint16_t j = 0; j < i_num_nalu; j++ )
for( uint8_t i = 0; i < i_num_array; i++ )
{
const uint16_t i_nalu_length = p_buf[0] << 8 | p_buf[1];
const uint16_t i_num_nalu = p_buf[1] << 8 | p_buf[2];
p_buf += 3;
memcpy( p_out_buf, annexb_startcode4, 4 );
memcpy( &p_out_buf[4], &p_buf[2], i_nalu_length );
for( uint16_t j = 0; j < i_num_nalu; j++ )
{
const uint16_t i_nalu_length = p_buf[0] << 8 | p_buf[1];
memcpy( p_out_buf, annexb_startcode4, 4 );
memcpy( &p_out_buf[4], &p_buf[2], i_nalu_length );
p_out_buf += 4 + i_nalu_length;
p_buf += 2 + i_nalu_length;
p_out_buf += 4 + i_nalu_length;
p_buf += 2 + i_nalu_length;
}
}
}
return p_ret;
*pp_result = p_out_buf;
*pi_result = i_result;
if( pi_nal_length_size )
*pi_nal_length_size = i_nal_length_size;
return true;
}
static bool hevc_parse_scaling_list_rbsp( bs_t *p_bs )

4
modules/packetizer/hevc_nal.h

@ -349,8 +349,8 @@ uint8_t * hevc_create_dcr( const struct hevc_dcr_params *p_params,
bool b_completeness, size_t *pi_size );
/* Converts HEVCDecoderConfigurationRecord to Annex B format */
uint8_t * hevc_hvcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
size_t *pi_res, uint8_t *pi_nal_length_size );
bool hevc_hvcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
uint8_t **pp_res, size_t *pi_res, uint8_t *pi_nal_length_size );
/*
* POC computing

Loading…
Cancel
Save