diff options
Diffstat (limited to 'media/ffmpeg')
-rw-r--r-- | media/ffmpeg/ffmpeg_common.cc | 38 | ||||
-rw-r--r-- | media/ffmpeg/ffmpeg_common.h | 1 | ||||
-rw-r--r-- | media/ffmpeg/ffmpeg_regression_tests.cc | 51 | ||||
-rw-r--r-- | media/ffmpeg/ffmpeg_unittest.cc | 34 | ||||
-rw-r--r-- | media/ffmpeg/file_protocol.cc | 3 |
5 files changed, 78 insertions, 49 deletions
diff --git a/media/ffmpeg/ffmpeg_common.cc b/media/ffmpeg/ffmpeg_common.cc index 4fc7f4e..978aff0 100644 --- a/media/ffmpeg/ffmpeg_common.cc +++ b/media/ffmpeg/ffmpeg_common.cc @@ -178,14 +178,14 @@ void AVCodecContextToAudioDecoderConfig( DCHECK_EQ(codec_context->codec_type, AVMEDIA_TYPE_AUDIO); AudioCodec codec = CodecIDToAudioCodec(codec_context->codec_id); - int bits_per_channel = av_get_bits_per_sample_fmt(codec_context->sample_fmt); + int bytes_per_channel = av_get_bytes_per_sample(codec_context->sample_fmt); ChannelLayout channel_layout = ChannelLayoutToChromeChannelLayout(codec_context->channel_layout, codec_context->channels); int samples_per_second = codec_context->sample_rate; config->Initialize(codec, - bits_per_channel, + bytes_per_channel << 3, channel_layout, samples_per_second, codec_context->extradata, @@ -289,35 +289,35 @@ void VideoDecoderConfigToAVCodecContext( ChannelLayout ChannelLayoutToChromeChannelLayout(int64_t layout, int channels) { switch (layout) { - case CH_LAYOUT_MONO: + case AV_CH_LAYOUT_MONO: return CHANNEL_LAYOUT_MONO; - case CH_LAYOUT_STEREO: + case AV_CH_LAYOUT_STEREO: return CHANNEL_LAYOUT_STEREO; - case CH_LAYOUT_2_1: + case AV_CH_LAYOUT_2_1: return CHANNEL_LAYOUT_2_1; - case CH_LAYOUT_SURROUND: + case AV_CH_LAYOUT_SURROUND: return CHANNEL_LAYOUT_SURROUND; - case CH_LAYOUT_4POINT0: + case AV_CH_LAYOUT_4POINT0: return CHANNEL_LAYOUT_4POINT0; - case CH_LAYOUT_2_2: + case AV_CH_LAYOUT_2_2: return CHANNEL_LAYOUT_2_2; - case CH_LAYOUT_QUAD: + case AV_CH_LAYOUT_QUAD: return CHANNEL_LAYOUT_QUAD; - case CH_LAYOUT_5POINT0: + case AV_CH_LAYOUT_5POINT0: return CHANNEL_LAYOUT_5POINT0; - case CH_LAYOUT_5POINT1: + case AV_CH_LAYOUT_5POINT1: return CHANNEL_LAYOUT_5POINT1; - case CH_LAYOUT_5POINT0_BACK: + case AV_CH_LAYOUT_5POINT0_BACK: return CHANNEL_LAYOUT_5POINT0_BACK; - case CH_LAYOUT_5POINT1_BACK: + case AV_CH_LAYOUT_5POINT1_BACK: return CHANNEL_LAYOUT_5POINT1_BACK; - case CH_LAYOUT_7POINT0: + case AV_CH_LAYOUT_7POINT0: return CHANNEL_LAYOUT_7POINT0; - case CH_LAYOUT_7POINT1: + case AV_CH_LAYOUT_7POINT1: return CHANNEL_LAYOUT_7POINT1; - case CH_LAYOUT_7POINT1_WIDE: + case AV_CH_LAYOUT_7POINT1_WIDE: return CHANNEL_LAYOUT_7POINT1_WIDE; - case CH_LAYOUT_STEREO_DOWNMIX: + case AV_CH_LAYOUT_STEREO_DOWNMIX: return CHANNEL_LAYOUT_STEREO_DOWNMIX; default: // FFmpeg channel_layout is 0 for .wav and .mp3. We know mono and stereo @@ -376,7 +376,7 @@ void DestroyAVFormatContext(AVFormatContext* format_context) { // 1. AVStream is alive. // 2. AVCodecContext in AVStream is alive. // 3. AVCodec in AVCodecContext is alive. - // Notice that closing a codec context without prior avcodec_open() will + // Notice that closing a codec context without prior avcodec_open2() will // result in a crash in FFmpeg. if (stream && stream->codec && stream->codec->codec) { stream->discard = AVDISCARD_ALL; @@ -386,7 +386,7 @@ void DestroyAVFormatContext(AVFormatContext* format_context) { } // Then finally cleanup the format context. - av_close_input_file(format_context); + avformat_close_input(&format_context); } } // namespace media diff --git a/media/ffmpeg/ffmpeg_common.h b/media/ffmpeg/ffmpeg_common.h index 6ebd5fa..22ddb7c 100644 --- a/media/ffmpeg/ffmpeg_common.h +++ b/media/ffmpeg/ffmpeg_common.h @@ -22,6 +22,7 @@ MSVC_PUSH_DISABLE_WARNING(4244); #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavformat/avio.h> +#include <libavformat/url.h> #include <libavutil/avutil.h> #include <libavutil/mathematics.h> #include <libavutil/log.h> diff --git a/media/ffmpeg/ffmpeg_regression_tests.cc b/media/ffmpeg/ffmpeg_regression_tests.cc index 8df6c10..727673f 100644 --- a/media/ffmpeg/ffmpeg_regression_tests.cc +++ b/media/ffmpeg/ffmpeg_regression_tests.cc @@ -1,6 +1,20 @@ // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// +// Regression tests for FFmpeg. Security test files can be found in the +// internal media test data directory: +// +// svn://svn.chromium.org/chrome-internal/trunk/data/media/security/ +// +// Simply add the custom_dep below to your gclient and sync: +// +// "src/media/test/data/security": +// "svn://chrome-svn/chrome-internal/trunk/data/media/security" +// +// Many of the files here do not cause issues outside of tooling, so you'll need +// to run this test under ASAN, TSAN, and Valgrind to ensure that all issues are +// caught. #include "media/filters/pipeline_integration_test_base.h" @@ -36,8 +50,6 @@ class FFmpegRegressionTest // Test cases from issues. FFMPEG_TEST_CASE(Cr93620, "security/93620.ogg", PIPELINE_OK, PIPELINE_OK); -FFMPEG_TEST_CASE(Cr99652, "security/99652.webm", PIPELINE_OK, - PIPELINE_ERROR_DECODE); FFMPEG_TEST_CASE(Cr100492, "security/100492.webm", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); FFMPEG_TEST_CASE(Cr100543, "security/100543.webm", PIPELINE_OK, PIPELINE_OK); @@ -72,19 +84,12 @@ FFMPEG_TEST_CASE(MP4_9, "security/smclockmp4aac_1_0.mp4", DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN); // General OGV test cases. -FFMPEG_TEST_CASE(OGV_0, "security/big_dims.ogv", PIPELINE_ERROR_DECODE, - PIPELINE_ERROR_DECODE); FFMPEG_TEST_CASE(OGV_1, "security/out.163.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); FFMPEG_TEST_CASE(OGV_2, "security/out.391.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); -FFMPEG_TEST_CASE(OGV_3, "security/smclock_1_0.ogv", PIPELINE_OK, PIPELINE_OK); -FFMPEG_TEST_CASE(OGV_4, "security/smclock.ogv.1.0.ogv", PIPELINE_OK, - PIPELINE_OK); FFMPEG_TEST_CASE(OGV_5, "security/smclocktheora_1_0.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); -FFMPEG_TEST_CASE(OGV_6, "security/smclocktheora_1_10000.ogv", - PIPELINE_ERROR_DECODE, PIPELINE_ERROR_DECODE); FFMPEG_TEST_CASE(OGV_7, "security/smclocktheora_1_102.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); FFMPEG_TEST_CASE(OGV_8, "security/smclocktheora_1_104.ogv", @@ -97,14 +102,16 @@ FFMPEG_TEST_CASE(OGV_11, "security/smclocktheora_1_20.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); FFMPEG_TEST_CASE(OGV_12, "security/smclocktheora_1_723.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); -FFMPEG_TEST_CASE(OGV_13, "security/smclocktheora_1_790.ogv", PIPELINE_OK, - PIPELINE_OK); FFMPEG_TEST_CASE(OGV_14, "security/smclocktheora_2_10405.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); +FFMPEG_TEST_CASE(OGV_15, "security/smclocktheora_2_10619.ogv", + DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); FFMPEG_TEST_CASE(OGV_16, "security/smclocktheora_2_1075.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); FFMPEG_TEST_CASE(OGV_17, "security/vorbis.482086.ogv", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); +FFMPEG_TEST_CASE(OGV_18, "security/wav.711.ogv", DECODER_ERROR_NOT_SUPPORTED, + DECODER_ERROR_NOT_SUPPORTED); // General WebM test cases. FFMPEG_TEST_CASE(WEBM_1, "security/no-bug.webm", PIPELINE_OK, PIPELINE_OK); @@ -115,15 +122,25 @@ FFMPEG_TEST_CASE(WEBM_3, "security/out.webm.139771.2965", FFMPEG_TEST_CASE(WEBM_4, "security/out.webm.68798.1929", DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); -// Flaky, maybe larger issues. -FFMPEG_TEST_CASE(Cr100464, "security/100464.webm", PIPELINE_OK, +// Flaky, maybe larger issues. All eventually fail in the browser. +FFMPEG_TEST_CASE(FLAKY_Cr99652, "security/99652.webm", PIPELINE_OK, + PIPELINE_ERROR_DECODE); +FFMPEG_TEST_CASE(FLAKY_Cr100464, "security/100464.webm", PIPELINE_OK, + PIPELINE_ERROR_DECODE); +FFMPEG_TEST_CASE(FLAKY_Cr111342, "security/111342.ogm", PIPELINE_OK, PIPELINE_ERROR_DECODE); +FFMPEG_TEST_CASE(FLAKY_OGV_0, "security/big_dims.ogv", PIPELINE_OK, + PIPELINE_ERROR_DECODE); +FFMPEG_TEST_CASE(FLAKY_OGV_3, "security/smclock_1_0.ogv", PIPELINE_ERROR_DECODE, + PIPELINE_ERROR_DECODE); +FFMPEG_TEST_CASE(FLAKY_OGV_4, "security/smclock.ogv.1.0.ogv", + PIPELINE_OK, PIPELINE_ERROR_DECODE); +FFMPEG_TEST_CASE(FLAKY_OGV_6, "security/smclocktheora_1_10000.ogv", + PIPELINE_OK, PIPELINE_ERROR_DECODE); +FFMPEG_TEST_CASE(FLAKY_OGV_13, "security/smclocktheora_1_790.ogv", + PIPELINE_ERROR_DECODE, PIPELINE_ERROR_DECODE); // Current crashers. -// FFMPEG_TEST_CASE(Cr111342, "security/111342.ogm", PIPELINE_OK, PIPELINE_OK); -// FFMPEG_TEST_CASE(OGV_15, "security/smclocktheora_2_10619.ogv", -// DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED); -// FFMPEG_TEST_CASE(OGV_18, "security/wav.711.ogv", PIPELINE_OK, PIPELINE_OK); // FFMPEG_TEST_CASE(Cr112976, "security/112976.ogg", PIPELINE_OK, PIPELINE_OK); // Clock failures. http://crbug.com/113037 diff --git a/media/ffmpeg/ffmpeg_unittest.cc b/media/ffmpeg/ffmpeg_unittest.cc index 9e377aa..121f0a6 100644 --- a/media/ffmpeg/ffmpeg_unittest.cc +++ b/media/ffmpeg/ffmpeg_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -46,6 +46,9 @@ int main(int argc, char** argv) { namespace media { +// Mirror setting in ffmpeg_video_decoder. +static const int kDecodeThreads = 2; + class AVPacketQueue { public: AVPacketQueue() { @@ -87,6 +90,8 @@ class AVPacketQueue { DISALLOW_COPY_AND_ASSIGN(AVPacketQueue); }; +// TODO(dalecurtis): We should really just use PipelineIntegrationTests instead +// of a one-off step decoder so we're exercising the real pipeline. class FFmpegTest : public testing::TestWithParam<const char*> { protected: FFmpegTest() @@ -133,18 +138,18 @@ class FFmpegTest : public testing::TestWithParam<const char*> { std::string ascii_path = path.value(); #endif - EXPECT_EQ(0, av_open_input_file(&av_format_context_, - ascii_path.c_str(), - NULL, 0, NULL)) + EXPECT_EQ(0, avformat_open_input(&av_format_context_, + ascii_path.c_str(), + NULL, NULL)) << "Could not open " << path.value(); - EXPECT_LE(0, av_find_stream_info(av_format_context_)) + EXPECT_LE(0, avformat_find_stream_info(av_format_context_, NULL)) << "Could not find stream information for " << path.value(); // Determine duration by picking max stream duration. for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) { AVStream* av_stream = av_format_context_->streams[i]; - int64 duration = ConvertFromTimeBase(av_stream->time_base, - av_stream->duration).InMicroseconds(); + int64 duration = ConvertFromTimeBase( + av_stream->time_base, av_stream->duration).InMicroseconds(); duration_ = std::max(duration_, duration); } @@ -152,12 +157,12 @@ class FFmpegTest : public testing::TestWithParam<const char*> { AVRational av_time_base = {1, AV_TIME_BASE}; int64 duration = ConvertFromTimeBase(av_time_base, - av_format_context_->duration).InMicroseconds(); + av_format_context_->duration).InMicroseconds(); duration_ = std::max(duration_, duration); } void CloseFile() { - av_close_input_file(av_format_context_); + avformat_close_input(&av_format_context_); } void OpenCodecs() { @@ -169,7 +174,13 @@ class FFmpegTest : public testing::TestWithParam<const char*> { EXPECT_TRUE(av_codec) << "Could not find AVCodec with CodecID " << av_codec_context->codec_id; - EXPECT_EQ(0, avcodec_open(av_codec_context, av_codec)) + + av_codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; + av_codec_context->err_recognition = AV_EF_CAREFUL; + av_codec_context->thread_count = ( + av_codec_context->codec_id == CODEC_ID_THEORA ? 1 : kDecodeThreads); + + EXPECT_EQ(0, avcodec_open2(av_codec_context, av_codec, NULL)) << "Could not open AVCodecContext with CodecID " << av_codec_context->codec_id; @@ -271,7 +282,7 @@ class FFmpegTest : public testing::TestWithParam<const char*> { if (result > 0) { // TODO(scherkus): move this to ffmpeg_common.h and dedup. int64 denominator = av_audio_context()->channels * - av_get_bits_per_sample_fmt(av_audio_context()->sample_fmt) / 8 * + av_get_bytes_per_sample(av_audio_context()->sample_fmt) * av_audio_context()->sample_rate; double microseconds = size_out / (denominator / @@ -402,7 +413,6 @@ class FFmpegTest : public testing::TestWithParam<const char*> { EXPECT_TRUE(InitializeMediaLibrary(path)) << "Could not initialize media library."; - avcodec_init(); av_log_set_level(AV_LOG_FATAL); av_register_all(); av_register_protocol2(&kFFmpegFileProtocol, sizeof(kFFmpegFileProtocol)); diff --git a/media/ffmpeg/file_protocol.cc b/media/ffmpeg/file_protocol.cc index 26ba8ce..49b9f1c 100644 --- a/media/ffmpeg/file_protocol.cc +++ b/media/ffmpeg/file_protocol.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -78,6 +78,7 @@ MSVC_POP_WARNING() URLProtocol kFFmpegFileProtocol = { "file", &OpenContext, + NULL, // url_open2 &ReadContext, &WriteContext, &SeekContext, |