[FFmpeg-cvslog] h264_ps: export actual height in MBs as SPS.mb_height
Anton Khirnov
git at videolan.org
Thu Nov 17 16:18:52 EET 2016
ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Sat Jul 2 16:48:26 2016 +0200| [a8cbe5a0ccebf60a8a8b0aba5d5716dd54c1595c] | committer: Anton Khirnov
h264_ps: export actual height in MBs as SPS.mb_height
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.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a8cbe5a0ccebf60a8a8b0aba5d5716dd54c1595c
---
libavcodec/h264_ps.c | 10 +++++++++-
libavcodec/h264_ps.h | 3 ++-
libavcodec/h264_slice.c | 4 ++--
3 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 4a56c73..d1b4280 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -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->mb_width = 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 ||
(unsigned)sps->mb_height >= INT_MAX / 16 ||
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;
}
- sps->frame_mbs_only_flag = get_bits1(gb);
if (!sps->frame_mbs_only_flag)
sps->mb_aff = get_bits1(gb);
else
diff --git a/libavcodec/h264_ps.h b/libavcodec/h264_ps.h
index 2835b87..9a32d93 100644
--- a/libavcodec/h264_ps.h
+++ b/libavcodec/h264_ps.h
@@ -56,7 +56,8 @@ typedef struct SPS {
int ref_frame_count; ///< num_ref_frames
int gaps_in_frame_num_allowed_flag;
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 mb_aff; ///< mb_adaptive_frame_field_flag
int direct_8x8_inference_flag;
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index aa53570..ce8df50 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -926,11 +926,11 @@ static int h264_init_ps(H264Context *h, const H264SliceContext *sl)
h->avctx->refs = sps->ref_frame_count;
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;
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_stride = h->mb_width + 1;
More information about the ffmpeg-cvslog
mailing list