@ -1151,7 +1151,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
int needs_reinit = 0 ;
int field_pic_flag , bottom_field_flag ;
int first_slice = sl = = h - > slice_ctx & & ! h - > current_slice ;
int frame_num , picture_structure , droppabl e;
int frame_num , droppable , picture_structur e;
int mb_aff_frame , last_mb_aff_frame ;
PPS * pps ;
@ -1219,7 +1219,8 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
}
// to make a few old functions happy, it's wrong though
h - > pict_type = sl - > slice_type ;
if ( ! h - > setup_finished )
h - > pict_type = sl - > slice_type ;
pps_id = get_ue_golomb ( & sl - > gb ) ;
if ( pps_id > = MAX_PPS_COUNT ) {
@ -1247,8 +1248,13 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
h - > pps . sps_id ) ;
return AVERROR_INVALIDDATA ;
}
if ( first_slice )
if ( first_slice & & ! h - > setup_finished ) {
h - > pps = * h - > pps_buffers [ pps_id ] ;
} else if ( h - > setup_finished & & h - > dequant_coeff_pps ! = pps_id ) {
av_log ( h - > avctx , AV_LOG_ERROR , " PPS changed between slices \n " ) ;
return AVERROR_INVALIDDATA ;
}
if ( pps - > sps_id ! = h - > sps . sps_id | |
pps - > sps_id ! = h - > current_sps_id | |
@ -1288,10 +1294,6 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
}
h - > avctx - > profile = ff_h264_get_profile ( & h - > sps ) ;
h - > avctx - > level = h - > sps . level_idc ;
h - > avctx - > refs = h - > sps . ref_frame_count ;
must_reinit = ( h - > context_initialized & &
( 16 * h - > sps . mb_width ! = h - > avctx - > coded_width
| | 16 * h - > sps . mb_height * ( 2 - h - > sps . frame_mbs_only_flag ) ! = h - > avctx - > coded_height
@ -1307,31 +1309,37 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
if ( first_slice & & av_cmp_q ( h - > sps . sar , h - > avctx - > sample_aspect_ratio ) )
must_reinit = 1 ;
h - > mb_width = h - > sps . mb_width ;
h - > mb_height = h - > sps . mb_height * ( 2 - h - > sps . frame_mbs_only_flag ) ;
h - > mb_num = h - > mb_width * h - > mb_height ;
h - > mb_stride = h - > mb_width + 1 ;
if ( ! h - > setup_finished ) {
h - > avctx - > profile = ff_h264_get_profile ( & h - > sps ) ;
h - > avctx - > level = h - > sps . level_idc ;
h - > avctx - > refs = h - > sps . ref_frame_count ;
h - > b_stride = h - > mb_width * 4 ;
h - > mb_width = h - > sps . mb_width ;
h - > mb_height = h - > sps . mb_height * ( 2 - h - > sps . frame_mbs_only_flag ) ;
h - > mb_num = h - > mb_width * h - > mb_height ;
h - > mb_stride = h - > mb_width + 1 ;
h - > chroma_y_shift = h - > sps . chroma_format_idc < = 1 ; // 400 uses yuv420p
h - > b_stride = h - > mb_width * 4 ;
h - > width = 16 * h - > mb_width ;
h - > height = 16 * h - > mb_height ;
h - > chroma_y_shift = h - > sps . chroma_format_idc < = 1 ; // 400 uses yuv420p
ret = init_dimensions ( h ) ;
if ( ret < 0 )
return ret ;
h - > width = 16 * h - > mb_width ;
h - > height = 16 * h - > mb_height ;
if ( h - > sps . video_signal_type_present_flag ) {
h - > avctx - > color_range = h - > sps . full_range > 0 ? AVCOL_RANGE_JPEG
: AVCOL_RANGE_MPEG ;
if ( h - > sps . colour_description_present_flag ) {
if ( h - > avctx - > colorspace ! = h - > sps . colorspace )
needs_reinit = 1 ;
h - > avctx - > color_primaries = h - > sps . color_primaries ;
h - > avctx - > color_trc = h - > sps . color_trc ;
h - > avctx - > colorspace = h - > sps . colorspace ;
ret = init_dimensions ( h ) ;
if ( ret < 0 )
return ret ;
if ( h - > sps . video_signal_type_present_flag ) {
h - > avctx - > color_range = h - > sps . full_range > 0 ? AVCOL_RANGE_JPEG
: AVCOL_RANGE_MPEG ;
if ( h - > sps . colour_description_present_flag ) {
if ( h - > avctx - > colorspace ! = h - > sps . colorspace )
needs_reinit = 1 ;
h - > avctx - > color_primaries = h - > sps . color_primaries ;
h - > avctx - > color_trc = h - > sps . color_trc ;
h - > avctx - > colorspace = h - > sps . colorspace ;
}
}
}
@ -1397,12 +1405,16 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
}
}
if ( ! h - > setup_finished )
h - > frame_num = frame_num ;
sl - > mb_mbaff = 0 ;
mb_aff_frame = 0 ;
last_mb_aff_frame = h - > mb_aff_frame ;
last_pic_structure = h - > picture_structure ;
last_pic_droppable = h - > droppable ;
droppable = h - > nal_ref_idc = = 0 ;
droppable = h - > nal_ref_idc = = 0 ;
if ( h - > sps . frame_mbs_only_flag ) {
picture_structure = PICT_FRAME ;
} else {
@ -1420,6 +1432,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
mb_aff_frame = h - > sps . mb_aff ;
}
}
if ( h - > current_slice ) {
if ( last_pic_structure ! = picture_structure | |
last_pic_droppable ! = droppable | |
@ -1437,9 +1450,11 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
}
h - > picture_structure = picture_structure ;
h - > droppable = droppable ;
h - > frame_num = frame_num ;
h - > mb_aff_frame = mb_aff_frame ;
if ( ! h - > setup_finished ) {
h - > droppable = droppable ;
h - > picture_structure = picture_structure ;
h - > mb_aff_frame = mb_aff_frame ;
}
sl - > mb_field_decoding_flag = picture_structure ! = PICT_FRAME ;
if ( h - > current_slice = = 0 ) {
@ -1624,8 +1639,8 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
h - > last_slice_type = - 1 ;
}
h - > cur_pic_ptr - > frame_num = h - > frame_num ; // FIXME frame_num cleanup
if ( ! h - > setup_finished )
h - > cur_pic_ptr - > frame_num = h - > frame_num ; // FIXME frame_num cleanup
av_assert1 ( h - > mb_num = = h - > mb_width * h - > mb_height ) ;
if ( first_mb_in_slice < < FIELD_OR_MBAFF_PICTURE ( h ) > = h - > mb_num | |
@ -1652,20 +1667,34 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
get_ue_golomb ( & sl - > gb ) ; /* idr_pic_id */
if ( h - > sps . poc_type = = 0 ) {
h - > poc_lsb = get_bits ( & sl - > gb , h - > sps . log2_max_poc_lsb ) ;
int poc_lsb = get_bits ( & sl - > gb , h - > sps . log2_max_poc_lsb ) ;
if ( h - > pps . pic_order_present = = 1 & & h - > picture_structure = = PICT_FRAME )
h - > delta_poc_bottom = get_se_golomb ( & sl - > gb ) ;
if ( ! h - > setup_finished )
h - > poc_lsb = poc_lsb ;
if ( h - > pps . pic_order_present = = 1 & & h - > picture_structure = = PICT_FRAME ) {
int delta_poc_bottom = get_se_golomb ( & sl - > gb ) ;
if ( ! h - > setup_finished )
h - > delta_poc_bottom = delta_poc_bottom ;
}
}
if ( h - > sps . poc_type = = 1 & & ! h - > sps . delta_pic_order_always_zero_flag ) {
h - > delta_poc [ 0 ] = get_se_golomb ( & sl - > gb ) ;
int delta_poc = get_se_golomb ( & sl - > gb ) ;
if ( ! h - > setup_finished )
h - > delta_poc [ 0 ] = delta_poc ;
if ( h - > pps . pic_order_present = = 1 & & h - > picture_structure = = PICT_FRAME )
h - > delta_poc [ 1 ] = get_se_golomb ( & sl - > gb ) ;
if ( h - > pps . pic_order_present = = 1 & & h - > picture_structure = = PICT_FRAME ) {
delta_poc = get_se_golomb ( & sl - > gb ) ;
if ( ! h - > setup_finished )
h - > delta_poc [ 1 ] = delta_poc ;
}
}
ff_init_poc ( h , h - > cur_pic_ptr - > field_poc , & h - > cur_pic_ptr - > poc ) ;
if ( ! h - > setup_finished )
ff_init_poc ( h , h - > cur_pic_ptr - > field_poc , & h - > cur_pic_ptr - > poc ) ;
if ( h - > pps . redundant_pic_cnt_present )
sl - > redundant_pic_count = get_ue_golomb ( & sl - > gb ) ;