summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-07 16:55:55 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-07 16:55:55 +0000
commit96e8ffb4e805c7266a2fc1fbe0e470052019bad9 (patch)
tree6abac1a5cc8a9b2764fbbef96f2d549afd57b466 /media
parent162b17b7439328792c3096db73f378f5109e2656 (diff)
downloadchromium_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.cc1
-rw-r--r--media/filters/ffmpeg_video_decoder.cc26
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;