Currently, SPS.mb_height is actually what the spec calls PicHeightInMapUnits, which is half the frame height when interlacing is allowed. Calling this 'mb_height' is quite confusing, and there are at least two associated bugs where this field is treated as the actual frame height - in the h264 parser and in the code computing maximum reordering buffer size for a given level. Fix those issues (and avoid possible future ones) by exporting the real frame height in this field.tags/n3.3
| @@ -439,6 +439,15 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, | |||||
| sps->gaps_in_frame_num_allowed_flag = get_bits1(gb); | sps->gaps_in_frame_num_allowed_flag = get_bits1(gb); | ||||
| sps->mb_width = get_ue_golomb(gb) + 1; | sps->mb_width = get_ue_golomb(gb) + 1; | ||||
| sps->mb_height = get_ue_golomb(gb) + 1; | sps->mb_height = get_ue_golomb(gb) + 1; | ||||
| sps->frame_mbs_only_flag = get_bits1(gb); | |||||
| if (sps->mb_height >= INT_MAX / 2) { | |||||
| av_log(avctx, AV_LOG_ERROR, "height overflow\n"); | |||||
| goto fail; | |||||
| } | |||||
| sps->mb_height *= 2 - sps->frame_mbs_only_flag; | |||||
| if ((unsigned)sps->mb_width >= INT_MAX / 16 || | if ((unsigned)sps->mb_width >= INT_MAX / 16 || | ||||
| (unsigned)sps->mb_height >= INT_MAX / 16 || | (unsigned)sps->mb_height >= INT_MAX / 16 || | ||||
| av_image_check_size(16 * sps->mb_width, | av_image_check_size(16 * sps->mb_width, | ||||
| @@ -447,7 +456,6 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, | |||||
| goto fail; | goto fail; | ||||
| } | } | ||||
| sps->frame_mbs_only_flag = get_bits1(gb); | |||||
| if (!sps->frame_mbs_only_flag) | if (!sps->frame_mbs_only_flag) | ||||
| sps->mb_aff = get_bits1(gb); | sps->mb_aff = get_bits1(gb); | ||||
| else | else | ||||
| @@ -56,7 +56,8 @@ typedef struct SPS { | |||||
| int ref_frame_count; ///< num_ref_frames | int ref_frame_count; ///< num_ref_frames | ||||
| int gaps_in_frame_num_allowed_flag; | int gaps_in_frame_num_allowed_flag; | ||||
| int mb_width; ///< pic_width_in_mbs_minus1 + 1 | int mb_width; ///< pic_width_in_mbs_minus1 + 1 | ||||
| int mb_height; ///< pic_height_in_map_units_minus1 + 1 | |||||
| ///< (pic_height_in_map_units_minus1 + 1) * (2 - frame_mbs_only_flag) | |||||
| int mb_height; | |||||
| int frame_mbs_only_flag; | int frame_mbs_only_flag; | ||||
| int mb_aff; ///< mb_adaptive_frame_field_flag | int mb_aff; ///< mb_adaptive_frame_field_flag | ||||
| int direct_8x8_inference_flag; | int direct_8x8_inference_flag; | ||||
| @@ -926,11 +926,11 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl) | |||||
| h->avctx->refs = sps->ref_frame_count; | h->avctx->refs = sps->ref_frame_count; | ||||
| if (h->mb_width != sps->mb_width || | if (h->mb_width != sps->mb_width || | ||||
| h->mb_height != sps->mb_height * (2 - sps->frame_mbs_only_flag)) | |||||
| h->mb_height != sps->mb_height) | |||||
| needs_reinit = 1; | needs_reinit = 1; | ||||
| h->mb_width = sps->mb_width; | h->mb_width = sps->mb_width; | ||||
| h->mb_height = sps->mb_height * (2 - sps->frame_mbs_only_flag); | |||||
| h->mb_height = sps->mb_height; | |||||
| h->mb_num = h->mb_width * h->mb_height; | h->mb_num = h->mb_width * h->mb_height; | ||||
| h->mb_stride = h->mb_width + 1; | h->mb_stride = h->mb_width + 1; | ||||