summaryrefslogtreecommitdiffstats
path: root/media/ffmpeg
diff options
context:
space:
mode:
authordalecurtis@google.com <dalecurtis@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-22 23:06:45 +0000
committerdalecurtis@google.com <dalecurtis@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-22 23:06:45 +0000
commit7a032766439f88961cf02aa8b06e31c865c30692 (patch)
treea8aba2889c7644e184728b287ceb95eb165e0250 /media/ffmpeg
parentdc6ea7623f8289de35907a940e1e980b65f16aae (diff)
downloadchromium_src-7a032766439f88961cf02aa8b06e31c865c30692.zip
chromium_src-7a032766439f88961cf02aa8b06e31c865c30692.tar.gz
chromium_src-7a032766439f88961cf02aa8b06e31c865c30692.tar.bz2
Fix media code to work with new ffmpeg.
Once ffmpeg git, svn are updated to new ffmpeg, will update DEPS in this CL. Which when committed, should seal the deal for the ffmpeg roll. API Changes: avutil: SampleFormat->AVSampleFormat avutil: av_get_bits_per_sample_fmt -> av_get_bytes_per_sample avcodec: avcodec_open -> avcodec_open2(..., NULL) avcodec: avcodec_decode_video2(... AVPacket ...) -> const AVPacket. avformat: av_open_input_file -> avformat_open_input avformat: av_register_protocol2 -> ffurl_register_protocol avformat: av_close_input_file -> avformat_close_input(&...) avformat: av_find_stream_info -> avformat_find_stream_info(..., NULL) URLContext now has a url_open2 method as well, for now I've set this to NULL. Also fixes: - ffmpeg_unittests change threading to mirror ffmpeg_video_decoder. There's an issue where threading causes the last frames of a no-audio video to be clipped. It existed before this ffmpeg roll, but because threading was disabled by default in ffmpeg, we never noticed it. - ffmpeg_demuxer_tests: GetBitrate_UnsetInContainer_NoFileSize now passes. - New ffmpeg_unittests passes: sync0_ogv/FFmpegTest.Seek_Video/0, where GetParam() = "sync0.ogv" sync1_ogv/FFmpegTest.Seek_Video/0, where GetParam() = "sync1.ogv" sync2_ogv/FFmpegTest.Seek_Video/0, where GetParam() = "sync2.ogv" FFmpeg fixups here, https://chromiumcodereview.appspot.com/9325049/ New git repo here: http://git.chromium.org/gitweb/?p=chromium/third_party/ffmpeg.git;a=summary Merge+Patches diff: https://chromiumcodereview.appspot.com/9317107 BUG=110776 TEST=unittests, layouttests, etc. Trybots. Review URL: https://chromiumcodereview.appspot.com/9317096 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123123 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/ffmpeg')
-rw-r--r--media/ffmpeg/ffmpeg_common.cc38
-rw-r--r--media/ffmpeg/ffmpeg_common.h1
-rw-r--r--media/ffmpeg/ffmpeg_regression_tests.cc49
-rw-r--r--media/ffmpeg/ffmpeg_unittest.cc34
-rw-r--r--media/ffmpeg/file_protocol.cc3
5 files changed, 76 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..9b7d2dd 100644
--- a/media/ffmpeg/ffmpeg_regression_tests.cc
+++ b/media/ffmpeg/ffmpeg_regression_tests.cc
@@ -1,6 +1,18 @@
// 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 symlink or copy the security directory into media/test/data folder and
+// build the ffmpeg_regression_tests target to run these tests.
+//
+// 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 +48,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 +82,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 +100,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 +120,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,