diff options
author | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-07 16:55:55 +0000 |
---|---|---|
committer | dalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-07 16:55:55 +0000 |
commit | 96e8ffb4e805c7266a2fc1fbe0e470052019bad9 (patch) | |
tree | 6abac1a5cc8a9b2764fbbef96f2d549afd57b466 /media | |
parent | 162b17b7439328792c3096db73f378f5109e2656 (diff) | |
download | chromium_src-96e8ffb4e805c7266a2fc1fbe0e470052019bad9.zip chromium_src-96e8ffb4e805c7266a2fc1fbe0e470052019bad9.tar.gz chromium_src-96e8ffb4e805c7266a2fc1fbe0e470052019bad9.tar.bz2 |
Replicate FFmpeg's video frame allocation strategy.
This should avoid accidental overreads and overwrites due to our
VideoFrame's not being as large as FFmpeg expects.
BUG=368980
TEST=new regression test
Review URL: https://codereview.chromium.org/270193002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@268831 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/ffmpeg/ffmpeg_regression_tests.cc | 1 | ||||
-rw-r--r-- | media/filters/ffmpeg_video_decoder.cc | 26 |
2 files changed, 19 insertions, 8 deletions
diff --git a/media/ffmpeg/ffmpeg_regression_tests.cc b/media/ffmpeg/ffmpeg_regression_tests.cc index 0b68fd0..311a28e 100644 --- a/media/ffmpeg/ffmpeg_regression_tests.cc +++ b/media/ffmpeg/ffmpeg_regression_tests.cc @@ -323,6 +323,7 @@ FLAKY_FFMPEG_TEST_CASE(BIG_MEM_4, "security/looping4.mov"); FLAKY_FFMPEG_TEST_CASE(Cr99652, "security/99652.webm"); FLAKY_FFMPEG_TEST_CASE(Cr100464, "security/100464.webm"); FLAKY_FFMPEG_TEST_CASE(Cr111342, "security/111342.ogm"); +FLAKY_FFMPEG_TEST_CASE(Cr368980, "security/368980.mp4"); FLAKY_FFMPEG_TEST_CASE(OGV_0, "security/big_dims.ogv"); FLAKY_FFMPEG_TEST_CASE(OGV_3, "security/smclock_1_0.ogv"); FLAKY_FFMPEG_TEST_CASE(OGV_4, "security/smclock.ogv.1.0.ogv"); diff --git a/media/filters/ffmpeg_video_decoder.cc b/media/filters/ffmpeg_video_decoder.cc index 12980c1..bc2346d 100644 --- a/media/filters/ffmpeg_video_decoder.cc +++ b/media/filters/ffmpeg_video_decoder.cc @@ -72,8 +72,8 @@ int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, format == VideoFrame::YV12J); gfx::Size size(codec_context->width, codec_context->height); - int ret; - if ((ret = av_image_check_size(size.width(), size.height(), 0, NULL)) < 0) + const int ret = av_image_check_size(size.width(), size.height(), 0, NULL); + if (ret < 0) return ret; gfx::Size natural_size; @@ -85,12 +85,22 @@ int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, natural_size = config_.natural_size(); } - if (!VideoFrame::IsValidConfig(format, size, gfx::Rect(size), natural_size)) + // FFmpeg has specific requirements on the allocation size of the frame. The + // following logic replicates FFmpeg's allocation strategy to ensure buffers + // are not overread / overwritten. See ff_init_buffer_info() for details. + // + // When lowres is non-zero, dimensions should be divided by 2^(lowres), but + // since we don't use this, just DCHECK that it's zero. + DCHECK_EQ(codec_context->lowres, 0); + gfx::Size coded_size(std::max(size.width(), codec_context->coded_width), + std::max(size.height(), codec_context->coded_height)); + + if (!VideoFrame::IsValidConfig( + format, coded_size, gfx::Rect(size), natural_size)) return AVERROR(EINVAL); - scoped_refptr<VideoFrame> video_frame = - frame_pool_.CreateFrame(format, size, gfx::Rect(size), - natural_size, kNoTimestamp()); + scoped_refptr<VideoFrame> video_frame = frame_pool_.CreateFrame( + format, coded_size, gfx::Rect(size), natural_size, kNoTimestamp()); for (int i = 0; i < 3; i++) { frame->base[i] = video_frame->data(i); @@ -101,8 +111,8 @@ int FFmpegVideoDecoder::GetVideoBuffer(AVCodecContext* codec_context, frame->opaque = NULL; video_frame.swap(reinterpret_cast<VideoFrame**>(&frame->opaque)); frame->type = FF_BUFFER_TYPE_USER; - frame->width = codec_context->width; - frame->height = codec_context->height; + frame->width = coded_size.width(); + frame->height = coded_size.height(); frame->format = codec_context->pix_fmt; return 0; |