diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-06-18 14:10:49 +0200 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2015-06-18 13:53:24 +0000 |
commit | 813fbf95af77a531c57a8c497345ad2c61d475b3 (patch) | |
tree | 821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/media/ffmpeg | |
parent | af6588f8d723931a298c995fa97259bb7f7deb55 (diff) | |
download | qtwebengine-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.cc | 30 | ||||
-rw-r--r-- | chromium/media/ffmpeg/ffmpeg_common.h | 1 | ||||
-rw-r--r-- | chromium/media/ffmpeg/ffmpeg_common_unittest.cc | 12 | ||||
-rw-r--r-- | chromium/media/ffmpeg/ffmpeg_regression_tests.cc | 515 | ||||
-rw-r--r-- | chromium/media/ffmpeg/ffmpeg_unittest.cc | 589 |
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 |