Browse Source

packetizer: h264: improve nal abstraction

pull/163/head
François Cartegnie 2 years ago
parent
commit
cbccd2a239
  1. 39
      modules/codec/hxxx_helper.c
  2. 4
      modules/codec/videotoolbox/decoder.c
  3. 14
      modules/packetizer/h264.c
  4. 41
      modules/packetizer/h264_nal.c
  5. 11
      modules/packetizer/h264_nal.h
  6. 46
      modules/packetizer/h264_slice.c
  7. 1
      modules/packetizer/h264_slice.h

39
modules/codec/hxxx_helper.c

@ -201,34 +201,38 @@ h264_helper_parse_nal(struct hxxx_helper *hh, const uint8_t *p_nal, size_t i_nal
return VLC_EGENERIC;
const enum h264_nal_unit_type_e i_nal_type = p_nal[0] & 0x1F;
uint8_t i_id;
if (i_nal_type == H264_NAL_SPS)
{
h264_get_xps_id(p_nal, i_nal, &i_id);
LOAD_xPS(hh->h264.sps_list, hh->h264.i_sps_count,
p_xps->i_id, H264_SPS_ID_MAX,
i_id, H264_SPS_ID_MAX,
h264_sequence_parameter_set_t,
h264_decode_sps,
h264_release_sps);
hh->h264.i_current_sps = ((h264_sequence_parameter_set_t*)p_xps)->i_id;
msg_Dbg(hh->p_obj, "new SPS parsed: %u", hh->h264.i_current_sps);
hh->h264.i_current_sps = i_id;
msg_Dbg(hh->p_obj, "new SPS parsed: %u", i_id);
}
else if (i_nal_type == H264_NAL_PPS)
{
h264_get_xps_id(p_nal, i_nal, &i_id);
LOAD_xPS(hh->h264.pps_list, hh->h264.i_pps_count,
p_xps->i_id, H264_PPS_ID_MAX,
i_id, H264_PPS_ID_MAX,
h264_picture_parameter_set_t,
h264_decode_pps,
h264_release_pps);
msg_Dbg(hh->p_obj, "new PPS parsed: %u", ((h264_picture_parameter_set_t*)p_xps)->i_id);
msg_Dbg(hh->p_obj, "new PPS parsed: %u", i_id);
}
else if(i_nal_type == H264_NAL_SPS_EXT)
{
h264_get_xps_id(p_nal, i_nal, &i_id);
LOAD_xPS(hh->h264.spsext_list, hh->h264.i_spsext_count,
p_xps->i_sps_id, H264_SPSEXT_ID_MAX,
i_id, H264_SPSEXT_ID_MAX,
h264_sequence_parameter_set_extension_t,
h264_decode_sps_extension,
h264_release_sps_extension);
msg_Dbg(hh->p_obj, "new SPSEXT parsed: %u", ((h264_sequence_parameter_set_extension_t*)p_xps)->i_sps_id);
msg_Dbg(hh->p_obj, "new SPSEXT parsed: %u", i_id);
}
else if (i_nal_type <= H264_NAL_SLICE_IDR
&& i_nal_type != H264_NAL_UNKNOWN)
@ -254,14 +258,14 @@ h264_helper_parse_nal(struct hxxx_helper *hh, const uint8_t *p_nal, size_t i_nal
return VLC_EGENERIC;
struct hxxx_helper_nal *hsps =
&hh->h264.sps_list[hpps->h264_pps->i_sps_id];
&hh->h264.sps_list[h264_get_pps_sps_id(hpps->h264_pps)];
if (hsps->b == NULL)
return VLC_EGENERIC;
assert(hpps->h264_pps->i_sps_id == hsps->h264_sps->i_id);
if (hsps->h264_sps->i_id != hh->h264.i_current_sps)
assert(h264_get_pps_sps_id(hpps->h264_pps) == h264_get_sps_id(hsps->h264_sps));
if (h264_get_sps_id(hsps->h264_sps) != hh->h264.i_current_sps)
{
hh->h264.i_current_sps = hsps->h264_sps->i_id;
hh->h264.i_current_sps = h264_get_sps_id(hsps->h264_sps);
hh->i_config_version++;
}
}
@ -874,12 +878,9 @@ hxxx_helper_get_current_profile_level(const struct hxxx_helper *hh,
if(hh->i_codec == VLC_CODEC_H264)
{
const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
if (hsps)
{
*p_profile = hsps->h264_sps->i_profile;
*p_level = hsps->h264_sps->i_level;
if (hsps && hsps->h264_sps &&
h264_get_sps_profile_tier_level(hsps->h264_sps, p_profile, p_level))
return VLC_SUCCESS;
}
}
else if(hh->i_codec == VLC_CODEC_HEVC)
{
@ -896,11 +897,9 @@ int h264_helper_get_constraint_flag(const struct hxxx_helper *hh,
assert(hh->i_codec == VLC_CODEC_H264);
const struct hxxx_helper_nal *hsps = h264_helper_get_current_sps(hh);
if (hsps)
{
*pi_constraints = hsps->h264_sps->i_constraint_set_flags;
if (hsps && hsps->h264_sps &&
h264_get_constraints_set(hsps->h264_sps, pi_constraints))
return VLC_SUCCESS;
}
return VLC_EGENERIC;
}

4
modules/codec/videotoolbox/decoder.c

@ -201,7 +201,7 @@ static void GetxPSH264(uint8_t i_pps_id, void *priv,
if (*pp_pps == NULL)
*pp_sps = NULL;
else
*pp_sps = h264ctx->hh.h264.sps_list[(*pp_pps)->i_sps_id].h264_sps;
*pp_sps = h264ctx->hh.h264.sps_list[h264_get_pps_sps_id(*pp_pps)].h264_sps;
}
struct sei_callback_h264_s
@ -271,7 +271,7 @@ static bool FillReorderInfoH264(decoder_t *p_dec, const block_t *p_block,
p_info->b_keyframe = slicetype == H264_SLICE_TYPE_I;
p_info->b_flush = p_info->b_keyframe || h264_has_mmco5(slice);
p_info->b_field = h264_is_field_pic(slice);
p_info->b_progressive = !p_sps->mb_adaptive_frame_field_flag &&
p_info->b_progressive = !h264_using_adaptive_frames(p_sps) &&
!p_info->b_field;
struct sei_callback_h264_s sei;

14
modules/packetizer/h264.c

@ -200,8 +200,12 @@ static void ActivateSets( decoder_t *p_dec, const h264_sequence_parameter_set_t
if( p_sps )
{
p_dec->fmt_out.i_profile = p_sps->i_profile;
p_dec->fmt_out.i_level = p_sps->i_level;
uint8_t pl[2];
if( h264_get_sps_profile_tier_level( p_sps, pl, &pl[1] ) )
{
p_dec->fmt_out.i_profile = pl[0];
p_dec->fmt_out.i_level = pl[1];
}
(void) h264_get_picture_size( p_sps,
&p_dec->fmt_out.video.i_x_offset,
@ -789,7 +793,7 @@ static block_t *OutputPicture( decoder_t *p_dec )
if( p_sys->i_recoveryfnum != UINT_MAX )
{
assert(p_sys->b_recovered == false);
const unsigned maxFrameNum = 1 << (p_sps->i_log2_max_frame_num + 4);
const unsigned maxFrameNum = h264_get_max_frame_num( p_sps );
if( ( p_sys->i_recoveryfnum > maxFrameNum &&
i_frame_num < p_sys->i_recoverystartfnum &&
@ -851,7 +855,7 @@ static block_t *OutputPicture( decoder_t *p_dec )
unsigned i_num_clock_ts = h264_get_num_ts( p_sps, p_sys->p_slice, p_sys->i_pic_struct, tFOC, bFOC );
if( p_sps->frame_mbs_only_flag == 0 && p_sps->vui.b_pic_struct_present_flag )
if( !h264_is_frames_only( p_sps ) && p_sys->i_pic_struct != UINT8_MAX )
{
switch( p_sys->i_pic_struct )
{
@ -1138,7 +1142,7 @@ static void GetSPSPPS( uint8_t i_pps_id, void *priv,
if( *pp_pps == NULL )
*pp_sps = NULL;
else
*pp_sps = p_sys->sps[(*pp_pps)->i_sps_id].p_sps;
*pp_sps = p_sys->sps[h264_get_pps_sps_id(*pp_pps)].p_sps;
}
static h264_slice_t * ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag )

41
modules/packetizer/h264_nal.c

@ -774,6 +774,16 @@ bool h264_get_xps_id( const uint8_t *p_buf, size_t i_buf, uint8_t *pi_id )
return !bs_error( &bs ) && *pi_id <= i_max;
}
uint8_t h264_get_sps_id( const h264_sequence_parameter_set_t *p_sps )
{
return p_sps->i_id;
}
uint8_t h264_get_pps_sps_id( const h264_picture_parameter_set_t *p_pps )
{
return p_pps->i_sps_id;
}
static const h264_level_limits_t * h264_get_level_limits( const h264_sequence_parameter_set_t *p_sps )
{
uint16_t i_level_number = p_sps->i_level;
@ -844,6 +854,37 @@ bool h264_get_dpb_values( const h264_sequence_parameter_set_t *p_sps,
return true;
}
unsigned h264_get_max_frame_num( const h264_sequence_parameter_set_t *p_sps )
{
return 1 << (p_sps->i_log2_max_frame_num + 4);
}
bool h264_is_frames_only( const h264_sequence_parameter_set_t *p_sps )
{
return p_sps->frame_mbs_only_flag;
}
bool h264_using_adaptive_frames( const h264_sequence_parameter_set_t *p_sps )
{
return p_sps->mb_adaptive_frame_field_flag;
}
bool h264_get_sps_profile_tier_level( const h264_sequence_parameter_set_t *p_sps,
uint8_t *pi_profile, uint8_t *pi_level)
{
*pi_profile = p_sps->i_profile;
*pi_level = p_sps->i_level;
return true;
}
bool h264_get_constraints_set( const h264_sequence_parameter_set_t *p_sps,
uint8_t *pi_constraints )
{
*pi_constraints = p_sps->i_constraint_set_flags;
return true;
}
bool h264_get_picture_size( const h264_sequence_parameter_set_t *p_sps,
unsigned *p_ox, unsigned *p_oy,
unsigned *p_w, unsigned *p_h,

11
modules/packetizer/h264_nal.h

@ -99,6 +99,9 @@ void h264_release_sps( h264_sequence_parameter_set_t * );
void h264_release_pps( h264_picture_parameter_set_t * );
void h264_release_sps_extension( h264_sequence_parameter_set_extension_t * );
uint8_t h264_get_sps_id( const h264_sequence_parameter_set_t * );
uint8_t h264_get_pps_sps_id( const h264_picture_parameter_set_t * );
struct h264_sequence_parameter_set_t
{
uint8_t i_id;
@ -207,6 +210,14 @@ uint8_t * h264_avcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf,
bool h264_get_dpb_values( const h264_sequence_parameter_set_t *,
uint8_t *pi_depth, unsigned *pi_delay );
unsigned h264_get_max_frame_num( const h264_sequence_parameter_set_t * );
bool h264_is_frames_only( const h264_sequence_parameter_set_t * );
bool h264_using_adaptive_frames( const h264_sequence_parameter_set_t * );
bool h264_get_sps_profile_tier_level( const h264_sequence_parameter_set_t *,
uint8_t *pi_profile, uint8_t *pi_level );
bool h264_get_constraints_set( const h264_sequence_parameter_set_t *p_sps,
uint8_t *pi_constraints );
bool h264_get_picture_size( const h264_sequence_parameter_set_t *,
unsigned *p_ox, unsigned *p_oy,
unsigned *p_w, unsigned *p_h,

46
modules/packetizer/h264_slice.c

@ -89,27 +89,9 @@ void h264_slice_release( h264_slice_t *p_slice )
free( p_slice );
}
void h264_slice_init( h264_slice_t *p_slice )
{
p_slice->i_nal_type = -1;
p_slice->i_nal_ref_idc = -1;
p_slice->i_idr_pic_id = -1;
p_slice->i_frame_num = 0;
p_slice->type = H264_SLICE_TYPE_UNKNOWN;
p_slice->i_pic_parameter_set_id = -1;
p_slice->i_field_pic_flag = 0;
p_slice->i_bottom_field_flag = -1;
p_slice->i_pic_order_cnt_type = -1;
p_slice->i_pic_order_cnt_lsb = -1;
p_slice->i_delta_pic_order_cnt_bottom = -1;
p_slice->i_delta_pic_order_cnt0 = 0;
p_slice->i_delta_pic_order_cnt1 = 0;
p_slice->has_mmco5 = false;
}
void h264_slice_copy_idr_id( const h264_slice_t *src, h264_slice_t *dst )
{
if( !src || dst->i_idr_pic_id != -1 )
if( !src || src->i_nal_type != H264_NAL_SLICE_IDR ) /* value only set on IDR */
return;
dst->i_idr_pic_id = src->i_idr_pic_id;
}
@ -123,7 +105,6 @@ h264_slice_t * h264_decode_slice( const uint8_t *p_buffer, size_t i_buffer,
h264_slice_t *p_slice = calloc( 1, sizeof(*p_slice) );
if( !p_slice )
return NULL;
h264_slice_init( p_slice );
int i_slice_type;
bs_t s;
@ -495,22 +476,23 @@ bool h264_IsFirstVCLNALUnit( const h264_slice_t *p_prev, const h264_slice_t *p_c
p_cur->i_field_pic_flag != p_prev->i_field_pic_flag ||
!p_cur->i_nal_ref_idc != !p_prev->i_nal_ref_idc )
return true;
if( (p_cur->i_bottom_field_flag != -1) &&
(p_prev->i_bottom_field_flag != -1) &&
(p_cur->i_bottom_field_flag != p_prev->i_bottom_field_flag) )
return true;
if( p_cur->i_pic_order_cnt_type == 0 &&
( p_cur->i_pic_order_cnt_lsb != p_prev->i_pic_order_cnt_lsb ||
p_cur->i_delta_pic_order_cnt_bottom != p_prev->i_delta_pic_order_cnt_bottom ) )
return true;
else if( p_cur->i_pic_order_cnt_type == 1 &&
( p_cur->i_delta_pic_order_cnt0 != p_prev->i_delta_pic_order_cnt0 ||
p_cur->i_delta_pic_order_cnt1 != p_prev->i_delta_pic_order_cnt1 ) )
if( p_cur->i_field_pic_flag && /* present in both and differs in value */
p_cur->i_bottom_field_flag != p_prev->i_bottom_field_flag )
return true;
if( p_cur->i_pic_order_cnt_type == p_prev->i_pic_order_cnt_type )
{
if( p_cur->i_pic_order_cnt_type == 0 &&
( p_cur->i_pic_order_cnt_lsb != p_prev->i_pic_order_cnt_lsb ||
p_cur->i_delta_pic_order_cnt_bottom != p_prev->i_delta_pic_order_cnt_bottom ) )
return true;
else if( p_cur->i_pic_order_cnt_type == 1 &&
( p_cur->i_delta_pic_order_cnt0 != p_prev->i_delta_pic_order_cnt0 ||
p_cur->i_delta_pic_order_cnt1 != p_prev->i_delta_pic_order_cnt1 ) )
return true;
}
if( ( p_cur->i_nal_type == H264_NAL_SLICE_IDR || p_prev->i_nal_type == H264_NAL_SLICE_IDR ) &&
( p_cur->i_nal_type != p_prev->i_nal_type || p_cur->i_idr_pic_id != p_prev->i_idr_pic_id ) )
return true;
return false;
}

1
modules/packetizer/h264_slice.h

@ -49,7 +49,6 @@ unsigned h264_get_frame_num( const h264_slice_t *p_slice );
unsigned h264_get_nal_ref_idc( const h264_slice_t *p_slice );
bool h264_has_mmco5( const h264_slice_t *p_slice );
void h264_slice_release( h264_slice_t *p_slice );
void h264_slice_init( h264_slice_t *p_slice );
void h264_slice_copy_idr_id( const h264_slice_t *src, h264_slice_t *dst );

Loading…
Cancel
Save