vlc | branch: master | Francois Cartegnie <[email protected]> | Wed Mar 15 11:05:26 2017 +0100| [15b212af6508a15f18c9ad0c162163f73d351410] | committer: Francois Cartegnie
packetizer: h264: split first vcl unit test > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=15b212af6508a15f18c9ad0c162163f73d351410 --- modules/packetizer/h264.c | 128 ++++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 62 deletions(-) diff --git a/modules/packetizer/h264.c b/modules/packetizer/h264.c index 4301b17..ee273e30 100644 --- a/modules/packetizer/h264.c +++ b/modules/packetizer/h264.c @@ -79,6 +79,7 @@ typedef struct int i_idr_pic_id; + int i_pic_order_cnt_type; int i_pic_order_cnt_lsb; int i_delta_pic_order_cnt_bottom; @@ -162,7 +163,7 @@ static block_t *OutputPicture( decoder_t *p_dec ); static void PutSPS( decoder_t *p_dec, block_t *p_frag ); static void PutPPS( decoder_t *p_dec, block_t *p_frag ); static bool ParseSliceHeader( decoder_t *p_dec, int i_nal_ref_idc, int i_nal_type, - const block_t *p_frag, bool *pb_new_picture, slice_t *p_slice ); + const block_t *p_frag, slice_t *p_slice ); static bool ParseSeiCallback( const hxxx_sei_data_t *, void * ); @@ -260,12 +261,41 @@ static void SliceInit( slice_t *p_slice ) 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; } +static bool IsFirstVCLNALUnit( const slice_t *p_prev, const slice_t *p_cur ) +{ + /* Detection of the first VCL NAL unit of a primary coded picture + * (cf. 7.4.1.2.4) */ + if( p_cur->i_frame_num != p_prev->i_frame_num || + p_cur->i_pic_parameter_set_id != p_prev->i_pic_parameter_set_id || + 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 ) ) + 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; +} + /***************************************************************************** * Open: probe the packetizer and return score * When opening after demux, the packetizer is only loaded AFTER the decoder @@ -555,24 +585,27 @@ static block_t *ParseNALBlock( decoder_t *p_dec, bool *pb_ts_used, block_t *p_fr if( i_nal_type >= H264_NAL_SLICE && i_nal_type <= H264_NAL_SLICE_IDR ) { - slice_t slice; + slice_t newslice; - if( ParseSliceHeader( p_dec, i_nal_ref_idc, i_nal_type, p_frag, &b_new_picture, &slice ) ) + if( ParseSliceHeader( p_dec, i_nal_ref_idc, i_nal_type, p_frag, &newslice ) ) { - /* */ + /* Only IDR carries the id, to be propagated */ + if( newslice.i_idr_pic_id == -1 ) + newslice.i_idr_pic_id = p_sys->slice.i_idr_pic_id; + + b_new_picture = IsFirstVCLNALUnit( &p_sys->slice, &newslice ); if( b_new_picture && p_sys->b_slice ) p_pic = OutputPicture( p_dec ); /* */ - p_sys->slice = slice; - p_sys->b_slice = true; + p_sys->slice = newslice; } else { - p_sys->b_slice = true; p_sys->p_active_pps = NULL; /* Fragment will be discarded later on */ } + p_sys->b_slice = true; } else if( i_nal_type == H264_NAL_SPS ) { @@ -875,12 +908,11 @@ static void PutPPS( decoder_t *p_dec, block_t *p_frag ) } static bool ParseSliceHeader( decoder_t *p_dec, int i_nal_ref_idc, int i_nal_type, - const block_t *p_frag, bool *pb_new_picture, slice_t *p_slice ) + const block_t *p_frag, slice_t *p_slice ) { decoder_sys_t *p_sys = p_dec->p_sys; int i_slice_type; - slice_t slice; - SliceInit( &slice ); + SliceInit( p_slice ); bs_t s; unsigned i_bitflow = 0; @@ -902,36 +934,36 @@ static bool ParseSliceHeader( decoder_t *p_dec, int i_nal_ref_idc, int i_nal_typ switch( (i_slice_type = bs_read_ue( &s )) ) { case 0: case 5: - slice.i_frame_type = BLOCK_FLAG_TYPE_P; + p_slice->i_frame_type = BLOCK_FLAG_TYPE_P; break; case 1: case 6: - slice.i_frame_type = BLOCK_FLAG_TYPE_B; + p_slice->i_frame_type = BLOCK_FLAG_TYPE_B; break; case 2: case 7: - slice.i_frame_type = BLOCK_FLAG_TYPE_I; + p_slice->i_frame_type = BLOCK_FLAG_TYPE_I; break; case 3: case 8: /* SP */ - slice.i_frame_type = BLOCK_FLAG_TYPE_P; + p_slice->i_frame_type = BLOCK_FLAG_TYPE_P; break; case 4: case 9: - slice.i_frame_type = BLOCK_FLAG_TYPE_I; + p_slice->i_frame_type = BLOCK_FLAG_TYPE_I; break; default: - slice.i_frame_type = 0; + p_slice->i_frame_type = 0; break; } /* */ - slice.i_nal_type = i_nal_type; - slice.i_nal_ref_idc = i_nal_ref_idc; + p_slice->i_nal_type = i_nal_type; + p_slice->i_nal_ref_idc = i_nal_ref_idc; - slice.i_pic_parameter_set_id = bs_read_ue( &s ); - if( slice.i_pic_parameter_set_id > H264_PPS_ID_MAX ) + p_slice->i_pic_parameter_set_id = bs_read_ue( &s ); + if( p_slice->i_pic_parameter_set_id > H264_PPS_ID_MAX ) return false; /* Bind matched/referred PPS and SPS */ const h264_picture_parameter_set_t *p_pps = - p_sys->p_active_pps = p_sys->pps[slice.i_pic_parameter_set_id].p_pps; + p_sys->p_active_pps = p_sys->pps[p_slice->i_pic_parameter_set_id].p_pps; if( p_pps == NULL ) return false; @@ -942,62 +974,34 @@ static bool ParseSliceHeader( decoder_t *p_dec, int i_nal_ref_idc, int i_nal_typ ActivateSets( p_dec, p_sps, p_pps ); - slice.i_frame_num = bs_read( &s, p_sps->i_log2_max_frame_num + 4 ); + p_slice->i_frame_num = bs_read( &s, p_sps->i_log2_max_frame_num + 4 ); if( !p_sps->frame_mbs_only_flag ) { /* field_pic_flag */ - slice.i_field_pic_flag = bs_read( &s, 1 ); - if( slice.i_field_pic_flag ) - slice.i_bottom_field_flag = bs_read( &s, 1 ); + p_slice->i_field_pic_flag = bs_read( &s, 1 ); + if( p_slice->i_field_pic_flag ) + p_slice->i_bottom_field_flag = bs_read( &s, 1 ); } - slice.i_idr_pic_id = p_sys->slice.i_idr_pic_id; - if( slice.i_nal_type == H264_NAL_SLICE_IDR ) - slice.i_idr_pic_id = bs_read_ue( &s ); + if( p_slice->i_nal_type == H264_NAL_SLICE_IDR ) + p_slice->i_idr_pic_id = bs_read_ue( &s ); + p_slice->i_pic_order_cnt_type = p_sps->i_pic_order_cnt_type; if( p_sps->i_pic_order_cnt_type == 0 ) { - slice.i_pic_order_cnt_lsb = bs_read( &s, p_sps->i_log2_max_pic_order_cnt_lsb + 4 ); - if( p_pps->i_pic_order_present_flag && !slice.i_field_pic_flag ) - slice.i_delta_pic_order_cnt_bottom = bs_read_se( &s ); + p_slice->i_pic_order_cnt_lsb = bs_read( &s, p_sps->i_log2_max_pic_order_cnt_lsb + 4 ); + if( p_pps->i_pic_order_present_flag && !p_slice->i_field_pic_flag ) + p_slice->i_delta_pic_order_cnt_bottom = bs_read_se( &s ); } else if( (p_sps->i_pic_order_cnt_type == 1) && (!p_sps->i_delta_pic_order_always_zero_flag) ) { - slice.i_delta_pic_order_cnt0 = bs_read_se( &s ); - if( p_pps->i_pic_order_present_flag && !slice.i_field_pic_flag ) - slice.i_delta_pic_order_cnt1 = bs_read_se( &s ); + p_slice->i_delta_pic_order_cnt0 = bs_read_se( &s ); + if( p_pps->i_pic_order_present_flag && !p_slice->i_field_pic_flag ) + p_slice->i_delta_pic_order_cnt1 = bs_read_se( &s ); } - /* Detection of the first VCL NAL unit of a primary coded picture - * (cf. 7.4.1.2.4) */ - bool b_pic = false; - if( slice.i_frame_num != p_sys->slice.i_frame_num || - slice.i_pic_parameter_set_id != p_sys->slice.i_pic_parameter_set_id || - slice.i_field_pic_flag != p_sys->slice.i_field_pic_flag || - !slice.i_nal_ref_idc != !p_sys->slice.i_nal_ref_idc ) - b_pic = true; - if( (slice.i_bottom_field_flag != -1) && - (p_sys->slice.i_bottom_field_flag != -1) && - (slice.i_bottom_field_flag != p_sys->slice.i_bottom_field_flag) ) - b_pic = true; - if( p_sps->i_pic_order_cnt_type == 0 && - ( slice.i_pic_order_cnt_lsb != p_sys->slice.i_pic_order_cnt_lsb || - slice.i_delta_pic_order_cnt_bottom != p_sys->slice.i_delta_pic_order_cnt_bottom ) ) - b_pic = true; - else if( p_sps->i_pic_order_cnt_type == 1 && - ( slice.i_delta_pic_order_cnt0 != p_sys->slice.i_delta_pic_order_cnt0 || - slice.i_delta_pic_order_cnt1 != p_sys->slice.i_delta_pic_order_cnt1 ) ) - b_pic = true; - if( ( slice.i_nal_type == H264_NAL_SLICE_IDR || p_sys->slice.i_nal_type == H264_NAL_SLICE_IDR ) && - ( slice.i_nal_type != p_sys->slice.i_nal_type || slice.i_idr_pic_id != p_sys->slice.i_idr_pic_id ) ) - b_pic = true; - - /* */ - *pb_new_picture = b_pic; - *p_slice = slice; - return true; } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
