summaryrefslogtreecommitdiff
path: root/chromium/media/ffmpeg
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-06-18 14:10:49 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-06-18 13:53:24 +0000
commit813fbf95af77a531c57a8c497345ad2c61d475b3 (patch)
tree821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/media/ffmpeg
parentaf6588f8d723931a298c995fa97259bb7f7deb55 (diff)
downloadqtwebengine-chromium-813fbf95af77a531c57a8c497345ad2c61d475b3.tar.gz
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/media/ffmpeg')
-rw-r--r--chromium/media/ffmpeg/ffmpeg_common.cc30
-rw-r--r--chromium/media/ffmpeg/ffmpeg_common.h1
-rw-r--r--chromium/media/ffmpeg/ffmpeg_common_unittest.cc12
-rw-r--r--chromium/media/ffmpeg/ffmpeg_regression_tests.cc515
-rw-r--r--chromium/media/ffmpeg/ffmpeg_unittest.cc589
5 files changed, 270 insertions, 877 deletions
diff --git a/chromium/media/ffmpeg/ffmpeg_common.cc b/chromium/media/ffmpeg/ffmpeg_common.cc
index 3b92d3db706..3b212ed79ad 100644
--- a/chromium/media/ffmpeg/ffmpeg_common.cc
+++ b/chromium/media/ffmpeg/ffmpeg_common.cc
@@ -10,7 +10,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "media/base/decoder_buffer.h"
-#include "media/base/video_frame.h"
#include "media/base/video_util.h"
namespace media {
@@ -18,8 +17,8 @@ namespace media {
// Why FF_INPUT_BUFFER_PADDING_SIZE? FFmpeg assumes all input buffers are
// padded. Check here to ensure FFmpeg only receives data padded to its
// specifications.
-COMPILE_ASSERT(DecoderBuffer::kPaddingSize >= FF_INPUT_BUFFER_PADDING_SIZE,
- decoder_buffer_padding_size_does_not_fit_ffmpeg_requirement);
+static_assert(DecoderBuffer::kPaddingSize >= FF_INPUT_BUFFER_PADDING_SIZE,
+ "DecoderBuffer padding size does not fit ffmpeg requirement");
// Alignment requirement by FFmpeg for input and output buffers. This need to
// be updated to match FFmpeg when it changes.
@@ -30,22 +29,22 @@ static const int kFFmpegBufferAddressAlignment = 32;
#endif
// Check here to ensure FFmpeg only receives data aligned to its specifications.
-COMPILE_ASSERT(
+static_assert(
DecoderBuffer::kAlignmentSize >= kFFmpegBufferAddressAlignment &&
DecoderBuffer::kAlignmentSize % kFFmpegBufferAddressAlignment == 0,
- decoder_buffer_alignment_size_does_not_fit_ffmpeg_requirement);
+ "DecoderBuffer alignment size does not fit ffmpeg requirement");
// Allows faster SIMD YUV convert. Also, FFmpeg overreads/-writes occasionally.
// See video_get_buffer() in libavcodec/utils.c.
static const int kFFmpegOutputBufferPaddingSize = 16;
-COMPILE_ASSERT(VideoFrame::kFrameSizePadding >= kFFmpegOutputBufferPaddingSize,
- video_frame_padding_size_does_not_fit_ffmpeg_requirement);
+static_assert(VideoFrame::kFrameSizePadding >= kFFmpegOutputBufferPaddingSize,
+ "VideoFrame padding size does not fit ffmpeg requirement");
-COMPILE_ASSERT(
+static_assert(
VideoFrame::kFrameAddressAlignment >= kFFmpegBufferAddressAlignment &&
VideoFrame::kFrameAddressAlignment % kFFmpegBufferAddressAlignment == 0,
- video_frame_address_alignment_does_not_fit_ffmpeg_requirement);
+ "VideoFrame frame address alignment does not fit ffmpeg requirement");
static const AVRational kMicrosBase = { 1, base::Time::kMicrosecondsPerSecond };
@@ -92,6 +91,8 @@ static AudioCodec CodecIDToAudioCodec(AVCodecID codec_id) {
return kCodecPCM_MULAW;
case AV_CODEC_ID_OPUS:
return kCodecOpus;
+ case AV_CODEC_ID_ALAC:
+ return kCodecALAC;
default:
DVLOG(1) << "Unknown audio CodecID: " << codec_id;
}
@@ -103,6 +104,8 @@ static AVCodecID AudioCodecToCodecID(AudioCodec audio_codec,
switch (audio_codec) {
case kCodecAAC:
return AV_CODEC_ID_AAC;
+ case kCodecALAC:
+ return AV_CODEC_ID_ALAC;
case kCodecMP3:
return AV_CODEC_ID_MP3;
case kCodecPCM:
@@ -242,6 +245,8 @@ SampleFormat AVSampleFormatToSampleFormat(AVSampleFormat sample_format) {
return kSampleFormatF32;
case AV_SAMPLE_FMT_S16P:
return kSampleFormatPlanarS16;
+ case AV_SAMPLE_FMT_S32P:
+ return kSampleFormatPlanarS32;
case AV_SAMPLE_FMT_FLTP:
return kSampleFormatPlanarF32;
default:
@@ -407,6 +412,12 @@ void AVStreamToVideoDecoderConfig(
coded_size = visible_rect.size();
}
+ // YV12 frames may be in HD color space.
+ if (format == VideoFrame::YV12 &&
+ stream->codec->colorspace == AVCOL_SPC_BT709) {
+ format = VideoFrame::YV12HD;
+ }
+
// Pad out |coded_size| for subsampled YUV formats.
if (format != VideoFrame::YV24) {
coded_size.set_width((coded_size.width() + 1) / 2 * 2);
@@ -546,6 +557,7 @@ PixelFormat VideoFormatToPixelFormat(VideoFrame::Format video_format) {
case VideoFrame::YV16:
return PIX_FMT_YUV422P;
case VideoFrame::YV12:
+ case VideoFrame::YV12HD:
return PIX_FMT_YUV420P;
case VideoFrame::YV12J:
return PIX_FMT_YUVJ420P;
diff --git a/chromium/media/ffmpeg/ffmpeg_common.h b/chromium/media/ffmpeg/ffmpeg_common.h
index 3616a150aab..a73fddd3716 100644
--- a/chromium/media/ffmpeg/ffmpeg_common.h
+++ b/chromium/media/ffmpeg/ffmpeg_common.h
@@ -32,6 +32,7 @@ extern "C" {
MSVC_PUSH_DISABLE_WARNING(4244);
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
+#include <libavformat/internal.h>
#include <libavformat/avio.h>
#include <libavutil/avutil.h>
#include <libavutil/imgutils.h>
diff --git a/chromium/media/ffmpeg/ffmpeg_common_unittest.cc b/chromium/media/ffmpeg/ffmpeg_common_unittest.cc
index 0d9bdc9980f..ff0730732f9 100644
--- a/chromium/media/ffmpeg/ffmpeg_common_unittest.cc
+++ b/chromium/media/ffmpeg/ffmpeg_common_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "media/ffmpeg/ffmpeg_common.h"
#include "media/filters/ffmpeg_glue.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -88,6 +89,17 @@ TEST_F(FFmpegCommonTest, UTCDateToTime_Valid) {
EXPECT_EQ(0, exploded.millisecond);
}
+#if defined(ALLOCATOR_SHIM) && defined(GTEST_HAS_DEATH_TEST)
+TEST_F(FFmpegCommonTest, WinAllocatorShimDeathTest) {
+ scoped_ptr<char, base::FreeDeleter> ptr;
+ // INT_MAX - 128 is carefully chosen to be below the default limit for
+ // ffmpeg allocations, but above the maximum allowed limit by the allocator
+ // shim, so we can be certain the code is being hit.
+ EXPECT_DEATH(ptr.reset(static_cast<char*>(av_malloc(INT_MAX - 128))), "");
+ ASSERT_TRUE(!ptr);
+}
+#endif
+
TEST_F(FFmpegCommonTest, UTCDateToTime_Invalid) {
const char* invalid_date_strings[] = {
"",
diff --git a/chromium/media/ffmpeg/ffmpeg_regression_tests.cc b/chromium/media/ffmpeg/ffmpeg_regression_tests.cc
index ebb2b9a628c..91fde9105ea 100644
--- a/chromium/media/ffmpeg/ffmpeg_regression_tests.cc
+++ b/chromium/media/ffmpeg/ffmpeg_regression_tests.cc
@@ -18,51 +18,31 @@
//
// Test cases labeled FLAKY may not always pass, but they should never crash or
// cause any kind of warnings or errors under tooling.
-//
-// Frame hashes must be generated with --video-threads=1 for correctness.
-//
-// Known issues:
-// Cr47325 will generate an UninitValue error under Valgrind inside of the
-// MD5 hashing code. The error occurs due to some problematic error
-// resilence code for H264 inside of FFmpeg. See http://crbug.com/119020
-//
-// Some OGG files leak ~30 bytes of memory, upstream tracking bug:
-// https://ffmpeg.org/trac/ffmpeg/ticket/1244
-//
-// Some OGG files leak hundreds of kilobytes of memory, upstream bug:
-// https://ffmpeg.org/trac/ffmpeg/ticket/1931
-
-#include "media/filters/pipeline_integration_test_base.h"
#include <string>
#include "base/bind.h"
-#include "media/base/test_data_util.h"
+#include "media/test/pipeline_integration_test_base.h"
namespace media {
const char kRegressionTestDataPathPrefix[] = "internal/";
struct RegressionTestData {
- RegressionTestData(const char* filename, PipelineStatus init_status,
- PipelineStatus end_status, const char* video_md5,
- const char* audio_md5)
- : video_md5(video_md5),
- audio_md5(audio_md5),
- filename(std::string(kRegressionTestDataPathPrefix) + filename),
+ RegressionTestData(const char* filename,
+ PipelineStatus init_status,
+ PipelineStatus end_status)
+ : filename(std::string(kRegressionTestDataPathPrefix) + filename),
init_status(init_status),
- end_status(end_status) {
- }
+ end_status(end_status) {}
- const char* video_md5;
- const char* audio_md5;
std::string filename;
PipelineStatus init_status;
PipelineStatus end_status;
};
// Used for tests which just need to run without crashing or tooling errors, but
-// which may have undefined behavior for hashing, etc.
+// which may have undefined PipelineStatus results.
struct FlakyRegressionTestData {
FlakyRegressionTestData(const char* filename)
: filename(std::string(kRegressionTestDataPathPrefix) + filename) {
@@ -81,243 +61,248 @@ class FlakyFFmpegRegressionTest
public PipelineIntegrationTestBase {
};
-#define FFMPEG_TEST_CASE(name, fn, init_status, end_status, video_md5, \
- audio_md5) \
- INSTANTIATE_TEST_CASE_P(name, FFmpegRegressionTest, \
- testing::Values(RegressionTestData(fn, \
- init_status, \
- end_status, \
- video_md5, \
- audio_md5)));
+#define FFMPEG_TEST_CASE(name, fn, init_status, end_status) \
+ INSTANTIATE_TEST_CASE_P( \
+ name, FFmpegRegressionTest, \
+ testing::Values(RegressionTestData(fn, init_status, end_status)));
#define FLAKY_FFMPEG_TEST_CASE(name, fn) \
INSTANTIATE_TEST_CASE_P(FLAKY_##name, FlakyFFmpegRegressionTest, \
testing::Values(FlakyRegressionTestData(fn)));
// Test cases from issues.
-FFMPEG_TEST_CASE(Cr47325, "security/47325.mp4", PIPELINE_OK, PIPELINE_OK,
- "2a7a938c6b5979621cec998f02d9bbb6",
- "3.61,1.64,-3.24,0.12,1.50,-0.86,");
-FFMPEG_TEST_CASE(Cr47761, "crbug47761.ogg", PIPELINE_OK, PIPELINE_OK,
- kNullVideoHash,
- "8.89,8.55,8.88,8.01,8.23,7.69,");
-FFMPEG_TEST_CASE(Cr50045, "crbug50045.mp4", PIPELINE_OK, PIPELINE_OK,
- "c345e9ef9ebfc6bfbcbe3f0ddc3125ba",
- "2.72,-6.27,-6.11,-3.17,-5.58,1.26,");
-FFMPEG_TEST_CASE(Cr62127, "crbug62127.webm", PIPELINE_OK,
- PIPELINE_OK, "a064b2776fc5aef3e9cba47967a75db9",
- kNullAudioHash);
-FFMPEG_TEST_CASE(Cr93620, "security/93620.ogg", PIPELINE_OK, PIPELINE_OK,
- kNullVideoHash,
- "-10.55,-10.10,-10.42,-10.35,-10.29,-10.72,");
-FFMPEG_TEST_CASE(Cr100492, "security/100492.webm", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr100543, "security/100543.webm", PIPELINE_OK, PIPELINE_OK,
- "c16691cc9178db3adbf7e562cadcd6e6",
- "1211.73,304.89,1311.54,371.34,1283.06,299.63,");
-FFMPEG_TEST_CASE(Cr101458, "security/101458.webm", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr108416, "security/108416.webm", PIPELINE_OK, PIPELINE_OK,
- "5cb3a934795cd552753dec7687928291",
- "-17.87,-37.20,-23.33,45.57,8.13,-9.92,");
-FFMPEG_TEST_CASE(Cr110849, "security/110849.mkv",
+FFMPEG_TEST_CASE(Cr47325, "security/47325.mp4", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr47761, "crbug47761.ogg", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr50045, "crbug50045.mp4", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr62127, "crbug62127.webm", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr93620, "security/93620.ogg", PIPELINE_OK, PIPELINE_OK);
+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);
+FFMPEG_TEST_CASE(Cr101458, "security/101458.webm", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr108416, "security/108416.webm", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr110849,
+ "security/110849.mkv",
DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
+FFMPEG_TEST_CASE(Cr112384,
+ "security/112384.webm",
+ DEMUXER_ERROR_COULD_NOT_PARSE,
+ DEMUXER_ERROR_COULD_NOT_PARSE);
+FFMPEG_TEST_CASE(Cr112976, "security/112976.ogg", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr116927,
+ "security/116927.ogv",
DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr112384, "security/112384.webm",
- DEMUXER_ERROR_COULD_NOT_PARSE, DEMUXER_ERROR_COULD_NOT_PARSE,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr117912, "security/117912.webm", DEMUXER_ERROR_COULD_NOT_OPEN,
- DEMUXER_ERROR_COULD_NOT_OPEN, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr123481, "security/123481.ogv", PIPELINE_OK,
- PIPELINE_OK, "e6dd853fcbd746c8bb2ab2b8fc376fc7",
- "1.28,-0.32,-0.81,0.08,1.66,0.89,");
-FFMPEG_TEST_CASE(Cr132779, "security/132779.webm",
- DEMUXER_ERROR_COULD_NOT_PARSE, DEMUXER_ERROR_COULD_NOT_PARSE,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr140165, "security/140165.ogg", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr140647, "security/140647.ogv", DEMUXER_ERROR_COULD_NOT_OPEN,
- DEMUXER_ERROR_COULD_NOT_OPEN, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr142738, "crbug142738.ogg", PIPELINE_OK, PIPELINE_OK,
- kNullVideoHash,
- "-1.22,0.45,1.79,1.80,-0.30,-1.21,");
-FFMPEG_TEST_CASE(Cr152691, "security/152691.mp3", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr161639, "security/161639.m4a", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr222754, "security/222754.mp4", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr234630a, "security/234630a.mov", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-15.52,-18.90,-15.33,-16.68,-14.41,-15.89,");
-FFMPEG_TEST_CASE(Cr234630b, "security/234630b.mov", PIPELINE_ERROR_DECODE,
- PIPELINE_ERROR_DECODE, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(Cr242786, "security/242786.webm", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-1.72,-0.83,0.84,1.70,1.23,-0.53,");
+ DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
+FFMPEG_TEST_CASE(Cr117912,
+ "security/117912.webm",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(Cr123481, "security/123481.ogv", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr132779,
+ "security/132779.webm",
+ DEMUXER_ERROR_COULD_NOT_PARSE,
+ DEMUXER_ERROR_COULD_NOT_PARSE);
+FFMPEG_TEST_CASE(Cr140165, "security/140165.ogg", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr140647,
+ "security/140647.ogv",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(Cr142738, "crbug142738.ogg", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr152691,
+ "security/152691.mp3",
+ PIPELINE_OK,
+ PIPELINE_ERROR_DECODE);
+FFMPEG_TEST_CASE(Cr161639,
+ "security/161639.m4a",
+ PIPELINE_OK,
+ PIPELINE_ERROR_DECODE);
+FFMPEG_TEST_CASE(Cr222754,
+ "security/222754.mp4",
+ PIPELINE_OK,
+ PIPELINE_ERROR_DECODE);
+FFMPEG_TEST_CASE(Cr234630a, "security/234630a.mov", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr234630b,
+ "security/234630b.mov",
+ PIPELINE_OK,
+ PIPELINE_ERROR_DECODE);
+FFMPEG_TEST_CASE(Cr242786, "security/242786.webm", PIPELINE_OK, PIPELINE_OK);
// Test for out-of-bounds access with slightly corrupt file (detection logic
// thinks it's a MONO file, but actually contains STEREO audio).
-FFMPEG_TEST_CASE(Cr275590, "security/275590.m4a",
- DECODER_ERROR_NOT_SUPPORTED, DEMUXER_ERROR_COULD_NOT_OPEN,
- kNullVideoHash, kNullAudioHash);
+FFMPEG_TEST_CASE(Cr275590,
+ "security/275590.m4a",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(Cr444522, "security/444522.mp4", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(Cr444539,
+ "security/444539.m4a",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(Cr444546,
+ "security/444546.mp4",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(Cr449958,
+ "security/449958.webm",
+ PIPELINE_OK,
+ PIPELINE_ERROR_DECODE);
// General MP4 test cases.
-FFMPEG_TEST_CASE(MP4_0, "security/aac.10419.mp4", DEMUXER_ERROR_COULD_NOT_OPEN,
- DEMUXER_ERROR_COULD_NOT_OPEN, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(MP4_1, "security/clockh264aac_200021889.mp4",
- DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(MP4_2, "security/clockh264aac_200701257.mp4", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(MP4_5, "security/clockh264aac_3022500.mp4",
- DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
- DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(MP4_6, "security/clockh264aac_344289.mp4", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(MP4_7, "security/clockh264mp3_187697.mp4",
- DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
+FFMPEG_TEST_CASE(MP4_0,
+ "security/aac.10419.mp4",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(MP4_1,
+ "security/clockh264aac_200021889.mp4",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(MP4_2,
+ "security/clockh264aac_200701257.mp4",
+ PIPELINE_OK,
+ PIPELINE_OK);
+FFMPEG_TEST_CASE(MP4_5,
+ "security/clockh264aac_3022500.mp4",
DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(MP4_8, "security/h264.705767.mp4",
- DEMUXER_ERROR_COULD_NOT_PARSE, DEMUXER_ERROR_COULD_NOT_PARSE,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(MP4_9, "security/smclockmp4aac_1_0.mp4",
- DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(MP4_16, "security/looping2.mov",
- DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN,
- kNullVideoHash, kNullAudioHash);
+ DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
+FFMPEG_TEST_CASE(MP4_6,
+ "security/clockh264aac_344289.mp4",
+ PIPELINE_OK,
+ PIPELINE_OK);
+FFMPEG_TEST_CASE(MP4_7,
+ "security/clockh264mp3_187697.mp4",
+ PIPELINE_OK,
+ PIPELINE_OK);
+FFMPEG_TEST_CASE(MP4_8,
+ "security/h264.705767.mp4",
+ DEMUXER_ERROR_COULD_NOT_PARSE,
+ DEMUXER_ERROR_COULD_NOT_PARSE);
+FFMPEG_TEST_CASE(MP4_9,
+ "security/smclockmp4aac_1_0.mp4",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(MP4_11, "security/null1.mp4", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(MP4_16,
+ "security/looping2.mov",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(MP4_17, "security/assert2.mov", PIPELINE_OK, PIPELINE_OK);
// General OGV test cases.
-FFMPEG_TEST_CASE(OGV_1, "security/out.163.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_2, "security/out.391.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_5, "security/smclocktheora_1_0.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_7, "security/smclocktheora_1_102.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_8, "security/smclocktheora_1_104.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_9, "security/smclocktheora_1_110.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_10, "security/smclocktheora_1_179.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_11, "security/smclocktheora_1_20.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_12, "security/smclocktheora_1_723.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_14, "security/smclocktheora_2_10405.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_15, "security/smclocktheora_2_10619.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_16, "security/smclocktheora_2_1075.ogv",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_18, "security/wav.711.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_19, "security/null1.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_20, "security/null2.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_21, "security/assert1.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(OGV_22, "security/assert2.ogv", DECODER_ERROR_NOT_SUPPORTED,
- DECODER_ERROR_NOT_SUPPORTED, kNullVideoHash, kNullAudioHash);
+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_5,
+ "security/smclocktheora_1_0.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+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",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(OGV_9,
+ "security/smclocktheora_1_110.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(OGV_10,
+ "security/smclocktheora_1_179.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+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_14,
+ "security/smclocktheora_2_10405.ogv",
+ 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_16,
+ "security/smclocktheora_2_1075.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(OGV_17,
+ "security/vorbis.482086.ogv",
+ PIPELINE_OK,
+ PIPELINE_OK);
+FFMPEG_TEST_CASE(OGV_18,
+ "security/wav.711.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(OGV_19,
+ "security/null1.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(OGV_20,
+ "security/null2.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(OGV_21,
+ "security/assert1.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(OGV_22,
+ "security/assert2.ogv",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(OGV_23,
+ "security/assert2.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,
- "39e92700cbb77478fd63f49db855e7e5", kNullAudioHash);
-FFMPEG_TEST_CASE(WEBM_3, "security/out.webm.139771.2965",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(WEBM_4, "security/out.webm.68798.1929",
- DECODER_ERROR_NOT_SUPPORTED, DECODER_ERROR_NOT_SUPPORTED,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(WEBM_5, "frame_size_change.webm", PIPELINE_OK,
- PIPELINE_OK, "d8fcf2896b7400a2261bac9e9ea930f8",
- kNullAudioHash);
+FFMPEG_TEST_CASE(WEBM_0, "security/memcpy.webm", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(WEBM_1, "security/no-bug.webm", PIPELINE_OK, PIPELINE_OK);
+FFMPEG_TEST_CASE(WEBM_2,
+ "security/uninitialize.webm",
+ DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
+ DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
+FFMPEG_TEST_CASE(WEBM_4,
+ "security/out.webm.68798.1929",
+ DECODER_ERROR_NOT_SUPPORTED,
+ DECODER_ERROR_NOT_SUPPORTED);
+FFMPEG_TEST_CASE(WEBM_5, "frame_size_change.webm", PIPELINE_OK, PIPELINE_OK);
-// Audio Functional Tests
-FFMPEG_TEST_CASE(AUDIO_GAMING_0, "gaming/a_220_00.mp3", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "0.36,1.25,2.98,4.29,4.19,2.76,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_1, "gaming/a_220_00_v2.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "2.17,3.31,5.15,6.33,5.97,4.35,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_2, "gaming/ai_laser1.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "7.70,10.81,13.19,10.07,7.39,7.56,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_3, "gaming/ai_laser2.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "5.99,8.04,9.71,8.69,7.81,7.52,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_4, "gaming/ai_laser3.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-0.32,1.44,3.75,5.88,6.32,3.22,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_5, "gaming/ai_laser4.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "4.75,4.16,2.21,3.01,5.51,6.11,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_6, "gaming/ai_laser5.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "6.04,7.46,8.78,7.32,4.16,3.97,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_7, "gaming/footstep1.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-0.50,0.29,2.35,4.79,5.14,2.24,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_8, "gaming/footstep3.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-2.87,-3.05,-4.10,-3.20,-2.20,-2.20,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_9, "gaming/footstep4.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "10.35,10.74,11.60,12.83,12.69,10.67,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_10, "gaming/laser1.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-9.48,-12.94,-1.75,7.66,5.61,-0.58,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_11, "gaming/laser2.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-7.53,-6.28,3.37,0.73,-5.83,-4.70,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_12, "gaming/laser3.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-13.62,-6.55,2.52,-10.10,-10.68,-5.43,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_13, "gaming/leg1.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "5.62,5.79,5.81,5.60,6.18,6.15,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_14, "gaming/leg2.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "-0.88,1.32,2.74,3.07,0.88,-0.03,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_15, "gaming/leg3.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "17.77,18.59,19.57,18.84,17.62,17.22,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_16, "gaming/lock_on.ogg", PIPELINE_OK,
- PIPELINE_OK, kNullVideoHash,
- "3.08,-4.33,-5.04,-0.24,1.83,5.16,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_17, "gaming/enemy_lock_on.ogg",
- PIPELINE_OK, PIPELINE_OK, kNullVideoHash,
- "-2.24,-1.00,-2.75,-0.87,1.11,-0.58,");
-FFMPEG_TEST_CASE(AUDIO_GAMING_18, "gaming/rocket_launcher.mp3",
- PIPELINE_OK, PIPELINE_OK, kNullVideoHash,
- "-3.08,0.18,2.49,1.98,-2.20,-4.74,");
+// General MKV test cases.
+FFMPEG_TEST_CASE(MKV_0,
+ "security/nested_tags_lang.mka.627.628",
+ PIPELINE_OK,
+ PIPELINE_ERROR_DECODE);
+FFMPEG_TEST_CASE(MKV_1,
+ "security/nested_tags_lang.mka.667.628",
+ PIPELINE_OK,
+ PIPELINE_ERROR_DECODE);
// Allocate gigabytes of memory, likely can't be run on 32bit machines.
-FFMPEG_TEST_CASE(BIG_MEM_1, "security/bigmem1.mov",
- DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(BIG_MEM_2, "security/looping1.mov",
- DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN,
- kNullVideoHash, kNullAudioHash);
-FFMPEG_TEST_CASE(BIG_MEM_5, "security/looping5.mov",
- DEMUXER_ERROR_COULD_NOT_OPEN, DEMUXER_ERROR_COULD_NOT_OPEN,
- kNullVideoHash, kNullAudioHash);
+FFMPEG_TEST_CASE(BIG_MEM_1,
+ "security/bigmem1.mov",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(BIG_MEM_2,
+ "security/looping1.mov",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
+FFMPEG_TEST_CASE(BIG_MEM_5,
+ "security/looping5.mov",
+ DEMUXER_ERROR_COULD_NOT_OPEN,
+ DEMUXER_ERROR_COULD_NOT_OPEN);
FLAKY_FFMPEG_TEST_CASE(BIG_MEM_3, "security/looping3.mov");
FLAKY_FFMPEG_TEST_CASE(BIG_MEM_4, "security/looping4.mov");
@@ -336,44 +321,17 @@ FLAKY_FFMPEG_TEST_CASE(OGV_13, "security/smclocktheora_1_790.ogv");
FLAKY_FFMPEG_TEST_CASE(MP4_3, "security/clockh264aac_300413969.mp4");
FLAKY_FFMPEG_TEST_CASE(MP4_4, "security/clockh264aac_301350139.mp4");
FLAKY_FFMPEG_TEST_CASE(MP4_12, "security/assert1.mov");
+FLAKY_FFMPEG_TEST_CASE(WEBM_3, "security/out.webm.139771.2965");
+
// Not really flaky, but can't pass the seek test.
FLAKY_FFMPEG_TEST_CASE(MP4_10, "security/null1.m4a");
-
-// TODO(wolenetz/dalecurtis): The following have flaky audio hash result.
-// See http://crbug.com/237371
-FLAKY_FFMPEG_TEST_CASE(Cr112976, "security/112976.ogg");
-FLAKY_FFMPEG_TEST_CASE(MKV_0, "security/nested_tags_lang.mka.627.628");
-FLAKY_FFMPEG_TEST_CASE(MKV_1, "security/nested_tags_lang.mka.667.628");
-FLAKY_FFMPEG_TEST_CASE(MP4_11, "security/null1.mp4");
-
-// TODO(wolenetz/dalecurtis): The following have flaky init status: on mac
-// ia32 Chrome, observed PIPELINE_OK instead of DECODER_ERROR_NOT_SUPPORTED.
FLAKY_FFMPEG_TEST_CASE(Cr112670, "security/112670.mp4");
-FLAKY_FFMPEG_TEST_CASE(OGV_17, "security/vorbis.482086.ogv");
-
-// TODO(wolenetz/dalecurtis): The following have flaky init status: on mac
-// ia32 Chrome, observed DUMUXER_ERROR_NO_SUPPORTED_STREAMS instead of
-// DECODER_ERROR_NOT_SUPPORTED.
-FLAKY_FFMPEG_TEST_CASE(Cr116927, "security/116927.ogv");
-FLAKY_FFMPEG_TEST_CASE(WEBM_2, "security/uninitialize.webm");
-
-// Videos with massive gaps between frame timestamps that result in long hangs
-// with our pipeline. Should be uncommented when we support clockless playback.
-// FFMPEG_TEST_CASE(WEBM_0, "security/memcpy.webm", PIPELINE_OK, PIPELINE_OK,
-// kNullVideoHash, kNullAudioHash);
-// FFMPEG_TEST_CASE(MP4_17, "security/assert2.mov", PIPELINE_OK, PIPELINE_OK,
-// kNullVideoHash, kNullAudioHash);
-// FFMPEG_TEST_CASE(OGV_23, "security/assert2.ogv", PIPELINE_OK, PIPELINE_OK,
-// kNullVideoHash, kNullAudioHash);
TEST_P(FFmpegRegressionTest, BasicPlayback) {
if (GetParam().init_status == PIPELINE_OK) {
- ASSERT_TRUE(Start(GetTestDataFilePath(GetParam().filename),
- GetParam().init_status, kHashed));
+ ASSERT_EQ(PIPELINE_OK, Start(GetParam().filename, kClockless));
Play();
ASSERT_EQ(WaitUntilEndedOrError(), GetParam().end_status);
- EXPECT_EQ(GetParam().video_md5, GetVideoHash());
- EXPECT_EQ(GetParam().audio_md5, GetAudioHash());
// Check for ended if the pipeline is expected to finish okay.
if (GetParam().end_status == PIPELINE_OK) {
@@ -383,15 +341,14 @@ TEST_P(FFmpegRegressionTest, BasicPlayback) {
Seek(base::TimeDelta::FromMilliseconds(0));
}
} else {
- ASSERT_FALSE(Start(GetTestDataFilePath(GetParam().filename),
- GetParam().init_status, kHashed));
- EXPECT_EQ(GetParam().video_md5, GetVideoHash());
- EXPECT_EQ(GetParam().audio_md5, GetAudioHash());
+ // Don't bother checking the exact status as we only care that the
+ // pipeline failed to start.
+ EXPECT_NE(PIPELINE_OK, Start(GetParam().filename));
}
}
TEST_P(FlakyFFmpegRegressionTest, BasicPlayback) {
- if (Start(GetTestDataFilePath(GetParam().filename))) {
+ if (Start(GetParam().filename, kClockless) == PIPELINE_OK) {
Play();
WaitUntilEndedOrError();
}
diff --git a/chromium/media/ffmpeg/ffmpeg_unittest.cc b/chromium/media/ffmpeg/ffmpeg_unittest.cc
deleted file mode 100644
index 0bb7fa7ca4f..00000000000
--- a/chromium/media/ffmpeg/ffmpeg_unittest.cc
+++ /dev/null
@@ -1,589 +0,0 @@
-// 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.
-
-// ffmpeg_unittests verify that the parts of the FFmpeg API that Chromium uses
-// function as advertised for each media format that Chromium supports. This
-// mostly includes stuff like reporting proper timestamps, seeking to
-// keyframes, and supporting certain features like reordered_opaque.
-//
-
-#include <limits>
-#include <queue>
-
-#include "base/base_paths.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/memory_mapped_file.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/path_service.h"
-#include "base/strings/string_util.h"
-#include "base/test/perf_test_suite.h"
-#include "base/test/perf_time_logger.h"
-#include "media/base/media.h"
-#include "media/ffmpeg/ffmpeg_common.h"
-#include "media/filters/ffmpeg_glue.h"
-#include "media/filters/in_memory_url_protocol.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-int main(int argc, char** argv) {
- return base::PerfTestSuite(argc, argv).Run();
-}
-
-namespace media {
-
-// Mirror setting in ffmpeg_video_decoder.
-static const int kDecodeThreads = 2;
-
-class AVPacketQueue {
- public:
- AVPacketQueue() {
- }
-
- ~AVPacketQueue() {
- flush();
- }
-
- bool empty() {
- return packets_.empty();
- }
-
- AVPacket* peek() {
- return packets_.front();
- }
-
- void pop() {
- AVPacket* packet = packets_.front();
- packets_.pop();
- av_free_packet(packet);
- delete packet;
- }
-
- void push(AVPacket* packet) {
- av_dup_packet(packet);
- packets_.push(packet);
- }
-
- void flush() {
- while (!empty()) {
- pop();
- }
- }
-
- private:
- std::queue<AVPacket*> packets_;
-
- 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()
- : av_format_context_(NULL),
- audio_stream_index_(-1),
- video_stream_index_(-1),
- decoded_audio_time_(AV_NOPTS_VALUE),
- decoded_audio_duration_(AV_NOPTS_VALUE),
- decoded_video_time_(AV_NOPTS_VALUE),
- decoded_video_duration_(AV_NOPTS_VALUE),
- duration_(AV_NOPTS_VALUE) {
- InitializeFFmpeg();
-
- audio_buffer_.reset(av_frame_alloc());
- video_buffer_.reset(av_frame_alloc());
- }
-
- virtual ~FFmpegTest() {
- }
-
- void OpenAndReadFile(const std::string& name) {
- OpenFile(name);
- OpenCodecs();
- ReadRemainingFile();
- }
-
- void OpenFile(const std::string& name) {
- base::FilePath path;
- PathService::Get(base::DIR_SOURCE_ROOT, &path);
- path = path.AppendASCII("media")
- .AppendASCII("test")
- .AppendASCII("data")
- .AppendASCII("content")
- .AppendASCII(name.c_str());
- EXPECT_TRUE(base::PathExists(path));
-
- CHECK(file_data_.Initialize(path));
- protocol_.reset(new InMemoryUrlProtocol(
- file_data_.data(), file_data_.length(), false));
- glue_.reset(new FFmpegGlue(protocol_.get()));
-
- ASSERT_TRUE(glue_->OpenContext()) << "Could not open " << path.value();
- av_format_context_ = glue_->format_context();
- ASSERT_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();
- duration_ = std::max(duration_, duration);
- }
-
- // Final check to see if the container itself specifies a duration.
- AVRational av_time_base = {1, AV_TIME_BASE};
- int64 duration =
- ConvertFromTimeBase(av_time_base,
- av_format_context_->duration).InMicroseconds();
- duration_ = std::max(duration_, duration);
- }
-
- void OpenCodecs() {
- for (unsigned int i = 0; i < av_format_context_->nb_streams; ++i) {
- AVStream* av_stream = av_format_context_->streams[i];
- AVCodecContext* av_codec_context = av_stream->codec;
- AVCodec* av_codec = avcodec_find_decoder(av_codec_context->codec_id);
-
- EXPECT_TRUE(av_codec)
- << "Could not find AVCodec with CodecID "
- << av_codec_context->codec_id;
-
- av_codec_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
- av_codec_context->thread_count = kDecodeThreads;
-
- EXPECT_EQ(0, avcodec_open2(av_codec_context, av_codec, NULL))
- << "Could not open AVCodecContext with CodecID "
- << av_codec_context->codec_id;
-
- if (av_codec->type == AVMEDIA_TYPE_AUDIO) {
- EXPECT_EQ(-1, audio_stream_index_) << "Found multiple audio streams.";
- audio_stream_index_ = static_cast<int>(i);
- } else if (av_codec->type == AVMEDIA_TYPE_VIDEO) {
- EXPECT_EQ(-1, video_stream_index_) << "Found multiple video streams.";
- video_stream_index_ = static_cast<int>(i);
- } else {
- ADD_FAILURE() << "Found unknown stream type.";
- }
- }
- }
-
- void Flush() {
- if (has_audio()) {
- audio_packets_.flush();
- avcodec_flush_buffers(av_audio_context());
- }
- if (has_video()) {
- video_packets_.flush();
- avcodec_flush_buffers(av_video_context());
- }
- }
-
- void ReadUntil(int64 time) {
- while (true) {
- scoped_ptr<AVPacket> packet(new AVPacket());
- if (av_read_frame(av_format_context_, packet.get()) < 0) {
- break;
- }
-
- int stream_index = static_cast<int>(packet->stream_index);
- int64 packet_time = AV_NOPTS_VALUE;
- if (stream_index == audio_stream_index_) {
- packet_time =
- ConvertFromTimeBase(av_audio_stream()->time_base, packet->pts)
- .InMicroseconds();
- audio_packets_.push(packet.release());
- } else if (stream_index == video_stream_index_) {
- packet_time =
- ConvertFromTimeBase(av_video_stream()->time_base, packet->pts)
- .InMicroseconds();
- video_packets_.push(packet.release());
- } else {
- ADD_FAILURE() << "Found packet that belongs to unknown stream.";
- }
-
- if (packet_time > time) {
- break;
- }
- }
- }
-
- void ReadRemainingFile() {
- ReadUntil(std::numeric_limits<int64>::max());
- }
-
- bool StepDecodeAudio() {
- EXPECT_TRUE(has_audio());
- if (!has_audio() || audio_packets_.empty()) {
- return false;
- }
-
- // Decode until output is produced, end of stream, or error.
- while (true) {
- int result = 0;
- int got_audio = 0;
- bool end_of_stream = false;
-
- AVPacket packet;
- if (audio_packets_.empty()) {
- av_init_packet(&packet);
- end_of_stream = true;
- } else {
- memcpy(&packet, audio_packets_.peek(), sizeof(packet));
- }
-
- av_frame_unref(audio_buffer_.get());
- result = avcodec_decode_audio4(av_audio_context(), audio_buffer_.get(),
- &got_audio, &packet);
- if (!audio_packets_.empty()) {
- audio_packets_.pop();
- }
-
- EXPECT_GE(result, 0) << "Audio decode error.";
- if (result < 0 || (got_audio == 0 && end_of_stream)) {
- return false;
- }
-
- if (result > 0) {
- double microseconds = 1.0L * audio_buffer_->nb_samples /
- av_audio_context()->sample_rate *
- base::Time::kMicrosecondsPerSecond;
- decoded_audio_duration_ = static_cast<int64>(microseconds);
-
- if (packet.pts == static_cast<int64>(AV_NOPTS_VALUE)) {
- EXPECT_NE(decoded_audio_time_, static_cast<int64>(AV_NOPTS_VALUE))
- << "We never received an initial timestamped audio packet! "
- << "Looks like there's a seeking/parsing bug in FFmpeg.";
- decoded_audio_time_ += decoded_audio_duration_;
- } else {
- decoded_audio_time_ =
- ConvertFromTimeBase(av_audio_stream()->time_base, packet.pts)
- .InMicroseconds();
- }
- return true;
- }
- }
- return true;
- }
-
- bool StepDecodeVideo() {
- EXPECT_TRUE(has_video());
- if (!has_video() || video_packets_.empty()) {
- return false;
- }
-
- // Decode until output is produced, end of stream, or error.
- while (true) {
- int result = 0;
- int got_picture = 0;
- bool end_of_stream = false;
-
- AVPacket packet;
- if (video_packets_.empty()) {
- av_init_packet(&packet);
- end_of_stream = true;
- } else {
- memcpy(&packet, video_packets_.peek(), sizeof(packet));
- }
-
- av_frame_unref(video_buffer_.get());
- av_video_context()->reordered_opaque = packet.pts;
- result = avcodec_decode_video2(av_video_context(), video_buffer_.get(),
- &got_picture, &packet);
- if (!video_packets_.empty()) {
- video_packets_.pop();
- }
-
- EXPECT_GE(result, 0) << "Video decode error.";
- if (result < 0 || (got_picture == 0 && end_of_stream)) {
- return false;
- }
-
- if (got_picture) {
- AVRational doubled_time_base;
- doubled_time_base.den = av_video_stream()->r_frame_rate.num;
- doubled_time_base.num = av_video_stream()->r_frame_rate.den;
- doubled_time_base.den *= 2;
-
- decoded_video_time_ =
- ConvertFromTimeBase(av_video_stream()->time_base,
- video_buffer_->reordered_opaque)
- .InMicroseconds();
- decoded_video_duration_ =
- ConvertFromTimeBase(doubled_time_base,
- 2 + video_buffer_->repeat_pict)
- .InMicroseconds();
- return true;
- }
- }
- }
-
- void DecodeRemainingAudio() {
- while (StepDecodeAudio()) {}
- }
-
- void DecodeRemainingVideo() {
- while (StepDecodeVideo()) {}
- }
-
- void SeekTo(double position) {
- int64 seek_time =
- static_cast<int64>(position * base::Time::kMicrosecondsPerSecond);
- int flags = AVSEEK_FLAG_BACKWARD;
-
- // Passing -1 as our stream index lets FFmpeg pick a default stream.
- // FFmpeg will attempt to use the lowest-index video stream, if present,
- // followed by the lowest-index audio stream.
- EXPECT_GE(0, av_seek_frame(av_format_context_, -1, seek_time, flags))
- << "Failed to seek to position " << position;
- Flush();
- }
-
- bool has_audio() { return audio_stream_index_ >= 0; }
- bool has_video() { return video_stream_index_ >= 0; }
- int64 decoded_audio_time() { return decoded_audio_time_; }
- int64 decoded_audio_duration() { return decoded_audio_duration_; }
- int64 decoded_video_time() { return decoded_video_time_; }
- int64 decoded_video_duration() { return decoded_video_duration_; }
- int64 duration() { return duration_; }
-
- AVStream* av_audio_stream() {
- return av_format_context_->streams[audio_stream_index_];
- }
- AVStream* av_video_stream() {
- return av_format_context_->streams[video_stream_index_];
- }
- AVCodecContext* av_audio_context() {
- return av_audio_stream()->codec;
- }
- AVCodecContext* av_video_context() {
- return av_video_stream()->codec;
- }
-
- private:
- void InitializeFFmpeg() {
- static bool initialized = false;
- if (initialized) {
- return;
- }
-
- base::FilePath path;
- PathService::Get(base::DIR_MODULE, &path);
- EXPECT_TRUE(InitializeMediaLibrary(path))
- << "Could not initialize media library.";
-
- initialized = true;
- }
-
- AVFormatContext* av_format_context_;
- int audio_stream_index_;
- int video_stream_index_;
- AVPacketQueue audio_packets_;
- AVPacketQueue video_packets_;
-
- scoped_ptr<AVFrame, media::ScopedPtrAVFreeFrame> audio_buffer_;
- scoped_ptr<AVFrame, media::ScopedPtrAVFreeFrame> video_buffer_;
-
- int64 decoded_audio_time_;
- int64 decoded_audio_duration_;
- int64 decoded_video_time_;
- int64 decoded_video_duration_;
- int64 duration_;
-
- base::MemoryMappedFile file_data_;
- scoped_ptr<InMemoryUrlProtocol> protocol_;
- scoped_ptr<FFmpegGlue> glue_;
-
- DISALLOW_COPY_AND_ASSIGN(FFmpegTest);
-};
-
-#define FFMPEG_TEST_CASE(name, extension) \
- INSTANTIATE_TEST_CASE_P(name##_##extension, FFmpegTest, \
- testing::Values(#name "." #extension));
-
-// Covers all our basic formats.
-FFMPEG_TEST_CASE(sync0, mp4);
-FFMPEG_TEST_CASE(sync0, ogv);
-FFMPEG_TEST_CASE(sync0, webm);
-FFMPEG_TEST_CASE(sync1, m4a);
-FFMPEG_TEST_CASE(sync1, mp3);
-FFMPEG_TEST_CASE(sync1, mp4);
-FFMPEG_TEST_CASE(sync1, ogg);
-FFMPEG_TEST_CASE(sync1, ogv);
-FFMPEG_TEST_CASE(sync1, webm);
-FFMPEG_TEST_CASE(sync2, m4a);
-FFMPEG_TEST_CASE(sync2, mp3);
-FFMPEG_TEST_CASE(sync2, mp4);
-FFMPEG_TEST_CASE(sync2, ogg);
-FFMPEG_TEST_CASE(sync2, ogv);
-FFMPEG_TEST_CASE(sync2, webm);
-
-// Covers our LayoutTest file.
-FFMPEG_TEST_CASE(counting, ogv);
-
-TEST_P(FFmpegTest, Perf) {
- {
- base::PerfTimeLogger timer("Opening file");
- OpenFile(GetParam());
- }
- {
- base::PerfTimeLogger timer("Opening codecs");
- OpenCodecs();
- }
- {
- base::PerfTimeLogger timer("Reading file");
- ReadRemainingFile();
- }
- if (has_audio()) {
- base::PerfTimeLogger timer("Decoding audio");
- DecodeRemainingAudio();
- }
- if (has_video()) {
- base::PerfTimeLogger timer("Decoding video");
- DecodeRemainingVideo();
- }
- {
- base::PerfTimeLogger timer("Seeking to zero");
- SeekTo(0);
- }
-}
-
-TEST_P(FFmpegTest, Loop_Audio) {
- OpenAndReadFile(GetParam());
- if (!has_audio()) {
- return;
- }
-
- const int kSteps = 4;
- std::vector<int64> expected_timestamps_;
- for (int i = 0; i < kSteps; ++i) {
- EXPECT_TRUE(StepDecodeAudio());
- expected_timestamps_.push_back(decoded_audio_time());
- }
-
- SeekTo(0);
- ReadRemainingFile();
-
- for (int i = 0; i < kSteps; ++i) {
- EXPECT_TRUE(StepDecodeAudio());
- EXPECT_EQ(expected_timestamps_[i], decoded_audio_time())
- << "Frame " << i << " had a mismatched timestamp.";
- }
-}
-
-TEST_P(FFmpegTest, Loop_Video) {
- OpenAndReadFile(GetParam());
- if (!has_video()) {
- return;
- }
-
- const int kSteps = 4;
- std::vector<int64> expected_timestamps_;
- for (int i = 0; i < kSteps; ++i) {
- EXPECT_TRUE(StepDecodeVideo());
- expected_timestamps_.push_back(decoded_video_time());
- }
-
- SeekTo(0);
- ReadRemainingFile();
-
- for (int i = 0; i < kSteps; ++i) {
- EXPECT_TRUE(StepDecodeVideo());
- EXPECT_EQ(expected_timestamps_[i], decoded_video_time())
- << "Frame " << i << " had a mismatched timestamp.";
- }
-}
-
-TEST_P(FFmpegTest, Seek_Audio) {
- OpenAndReadFile(GetParam());
- if (!has_audio() && duration() >= 0.5) {
- return;
- }
-
- SeekTo(duration() - 0.5);
- ReadRemainingFile();
-
- EXPECT_TRUE(StepDecodeAudio());
- EXPECT_NE(static_cast<int64>(AV_NOPTS_VALUE), decoded_audio_time());
-}
-
-TEST_P(FFmpegTest, Seek_Video) {
- OpenAndReadFile(GetParam());
- if (!has_video() && duration() >= 0.5) {
- return;
- }
-
- SeekTo(duration() - 0.5);
- ReadRemainingFile();
-
- EXPECT_TRUE(StepDecodeVideo());
- EXPECT_NE(static_cast<int64>(AV_NOPTS_VALUE), decoded_video_time());
-}
-
-TEST_P(FFmpegTest, Decode_Audio) {
- OpenAndReadFile(GetParam());
- if (!has_audio()) {
- return;
- }
-
- int64 last_audio_time = AV_NOPTS_VALUE;
- while (StepDecodeAudio()) {
- ASSERT_GT(decoded_audio_time(), last_audio_time);
- last_audio_time = decoded_audio_time();
- }
-}
-
-TEST_P(FFmpegTest, Decode_Video) {
- OpenAndReadFile(GetParam());
- if (!has_video()) {
- return;
- }
-
- int64 last_video_time = AV_NOPTS_VALUE;
- while (StepDecodeVideo()) {
- ASSERT_GT(decoded_video_time(), last_video_time);
- last_video_time = decoded_video_time();
- }
-}
-
-TEST_P(FFmpegTest, Duration) {
- OpenAndReadFile(GetParam());
-
- if (has_audio()) {
- DecodeRemainingAudio();
- }
-
- if (has_video()) {
- DecodeRemainingVideo();
- }
-
- double expected = static_cast<double>(duration());
- double actual = static_cast<double>(
- std::max(decoded_audio_time() + decoded_audio_duration(),
- decoded_video_time() + decoded_video_duration()));
- EXPECT_NEAR(expected, actual, 500000)
- << "Duration is off by more than 0.5 seconds.";
-}
-
-TEST_F(FFmpegTest, VideoPlayedCollapse) {
- OpenFile("test.ogv");
- OpenCodecs();
-
- SeekTo(0.5);
- ReadRemainingFile();
- EXPECT_TRUE(StepDecodeVideo());
- VLOG(1) << decoded_video_time();
-
- SeekTo(2.83);
- ReadRemainingFile();
- EXPECT_TRUE(StepDecodeVideo());
- VLOG(1) << decoded_video_time();
-
- SeekTo(0.4);
- ReadRemainingFile();
- EXPECT_TRUE(StepDecodeVideo());
- VLOG(1) << decoded_video_time();
-}
-
-} // namespace media