| Index: media/filters/audio_file_reader_unittest.cc
|
| diff --git a/media/filters/audio_file_reader_unittest.cc b/media/filters/audio_file_reader_unittest.cc
|
| index 28c9837cb2e189d48629c3f0d5fec9adca0af999..4ce2ab6ff44a7da6e351ecc2dd9c520e769f25db 100644
|
| --- a/media/filters/audio_file_reader_unittest.cc
|
| +++ b/media/filters/audio_file_reader_unittest.cc
|
| @@ -3,12 +3,14 @@
|
| // found in the LICENSE file.
|
|
|
| #include "base/logging.h"
|
| +#include "base/md5.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "build/build_config.h"
|
| #include "media/base/audio_bus.h"
|
| #include "media/base/audio_hash.h"
|
| #include "media/base/decoder_buffer.h"
|
| #include "media/base/test_data_util.h"
|
| +#include "media/ffmpeg/ffmpeg_common.h"
|
| #include "media/filters/audio_file_reader.h"
|
| #include "media/filters/in_memory_url_protocol.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| @@ -17,20 +19,20 @@ namespace media {
|
|
|
| class AudioFileReaderTest : public testing::Test {
|
| public:
|
| - AudioFileReaderTest() {}
|
| + AudioFileReaderTest() : packet_verification_disabled_(false) {}
|
| virtual ~AudioFileReaderTest() {}
|
|
|
| void Initialize(const char* filename) {
|
| data_ = ReadTestDataFile(filename);
|
| - protocol_.reset(new InMemoryUrlProtocol(
|
| - data_->data(), data_->data_size(), false));
|
| + protocol_.reset(
|
| + new InMemoryUrlProtocol(data_->data(), data_->data_size(), false));
|
| reader_.reset(new AudioFileReader(protocol_.get()));
|
| }
|
|
|
| // Reads and the entire file provided to Initialize().
|
| void ReadAndVerify(const char* expected_audio_hash, int expected_frames) {
|
| - scoped_ptr<AudioBus> decoded_audio_data = AudioBus::Create(
|
| - reader_->channels(), reader_->GetNumberOfFrames());
|
| + scoped_ptr<AudioBus> decoded_audio_data =
|
| + AudioBus::Create(reader_->channels(), reader_->GetNumberOfFrames());
|
| int actual_frames = reader_->Read(decoded_audio_data.get());
|
| ASSERT_LE(actual_frames, decoded_audio_data->frames());
|
| ASSERT_EQ(expected_frames, actual_frames);
|
| @@ -40,8 +42,50 @@ class AudioFileReaderTest : public testing::Test {
|
| EXPECT_EQ(expected_audio_hash, audio_hash.ToString());
|
| }
|
|
|
| - void RunTest(const char* fn, const char* hash, int channels, int sample_rate,
|
| - base::TimeDelta duration, int frames, int trimmed_frames) {
|
| + // Verify packets are consistent across demuxer runs. Reads the first few
|
| + // packets and then seeks back to the start timestamp and verifies that the
|
| + // hashes match on the packets just read.
|
| + void VerifyPackets() {
|
| + const int kReads = 3;
|
| + const int kTestPasses = 2;
|
| +
|
| + AVPacket packet;
|
| + base::TimeDelta start_timestamp;
|
| + std::vector<std::string> packet_md5_hashes_;
|
| + for (int i = 0; i < kTestPasses; ++i) {
|
| + for (int j = 0; j < kReads; ++j) {
|
| + ASSERT_TRUE(reader_->ReadPacketForTesting(&packet));
|
| +
|
| + // Remove metadata from the packet data section before hashing.
|
| + av_packet_split_side_data(&packet);
|
| +
|
| + // On the first pass save the MD5 hash of each packet, on subsequent
|
| + // passes ensure it matches.
|
| + const std::string md5_hash = base::MD5String(base::StringPiece(
|
| + reinterpret_cast<char*>(packet.data), packet.size));
|
| + if (i == 0) {
|
| + packet_md5_hashes_.push_back(md5_hash);
|
| + if (j == 0) {
|
| + start_timestamp = ConvertFromTimeBase(
|
| + reader_->codec_context_for_testing()->time_base, packet.pts);
|
| + }
|
| + } else {
|
| + EXPECT_EQ(packet_md5_hashes_[j], md5_hash) << "j = " << j;
|
| + }
|
| +
|
| + av_free_packet(&packet);
|
| + }
|
| + ASSERT_TRUE(reader_->SeekForTesting(start_timestamp));
|
| + }
|
| + }
|
| +
|
| + void RunTest(const char* fn,
|
| + const char* hash,
|
| + int channels,
|
| + int sample_rate,
|
| + base::TimeDelta duration,
|
| + int frames,
|
| + int trimmed_frames) {
|
| Initialize(fn);
|
| ASSERT_TRUE(reader_->Open());
|
| EXPECT_EQ(channels, reader_->channels());
|
| @@ -49,6 +93,8 @@ class AudioFileReaderTest : public testing::Test {
|
| EXPECT_EQ(duration.InMicroseconds(),
|
| reader_->GetDuration().InMicroseconds());
|
| EXPECT_EQ(frames, reader_->GetNumberOfFrames());
|
| + if (!packet_verification_disabled_)
|
| + ASSERT_NO_FATAL_FAILURE(VerifyPackets());
|
| ReadAndVerify(hash, trimmed_frames);
|
| }
|
|
|
| @@ -60,15 +106,20 @@ class AudioFileReaderTest : public testing::Test {
|
| void RunTestFailingDecode(const char* fn) {
|
| Initialize(fn);
|
| EXPECT_TRUE(reader_->Open());
|
| - scoped_ptr<AudioBus> decoded_audio_data = AudioBus::Create(
|
| - reader_->channels(), reader_->GetNumberOfFrames());
|
| + scoped_ptr<AudioBus> decoded_audio_data =
|
| + AudioBus::Create(reader_->channels(), reader_->GetNumberOfFrames());
|
| EXPECT_EQ(reader_->Read(decoded_audio_data.get()), 0);
|
| }
|
|
|
| + void disable_packet_verification() {
|
| + packet_verification_disabled_ = true;
|
| + }
|
| +
|
| protected:
|
| scoped_refptr<DecoderBuffer> data_;
|
| scoped_ptr<InMemoryUrlProtocol> protocol_;
|
| scoped_ptr<AudioFileReader> reader_;
|
| + bool packet_verification_disabled_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(AudioFileReaderTest);
|
| };
|
| @@ -82,49 +133,97 @@ TEST_F(AudioFileReaderTest, InvalidFile) {
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, WithVideo) {
|
| - RunTest("bear.ogv", "-2.49,-0.75,0.38,1.60,0.70,-1.22,", 2, 44100,
|
| - base::TimeDelta::FromMicroseconds(1011520), 44609, 44609);
|
| + RunTest("bear.ogv",
|
| + "-2.49,-0.75,0.38,1.60,0.70,-1.22,",
|
| + 2,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(1011520),
|
| + 44609,
|
| + 44609);
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, Vorbis) {
|
| - RunTest("sfx.ogg", "4.36,4.81,4.84,4.45,4.61,4.63,", 1, 44100,
|
| - base::TimeDelta::FromMicroseconds(350001), 15436, 15436);
|
| + RunTest("sfx.ogg",
|
| + "4.36,4.81,4.84,4.45,4.61,4.63,",
|
| + 1,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(350001),
|
| + 15436,
|
| + 15436);
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, WaveU8) {
|
| - RunTest("sfx_u8.wav", "-1.23,-1.57,-1.14,-0.91,-0.87,-0.07,", 1, 44100,
|
| - base::TimeDelta::FromMicroseconds(288414), 12720, 12719);
|
| + RunTest("sfx_u8.wav",
|
| + "-1.23,-1.57,-1.14,-0.91,-0.87,-0.07,",
|
| + 1,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(288414),
|
| + 12720,
|
| + 12719);
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, WaveS16LE) {
|
| - RunTest("sfx_s16le.wav", "3.05,2.87,3.00,3.32,3.58,4.08,", 1, 44100,
|
| - base::TimeDelta::FromMicroseconds(288414), 12720, 12719);
|
| + RunTest("sfx_s16le.wav",
|
| + "3.05,2.87,3.00,3.32,3.58,4.08,",
|
| + 1,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(288414),
|
| + 12720,
|
| + 12719);
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, WaveS24LE) {
|
| - RunTest("sfx_s24le.wav", "3.03,2.86,2.99,3.31,3.57,4.06,", 1, 44100,
|
| - base::TimeDelta::FromMicroseconds(288414), 12720, 12719);
|
| + RunTest("sfx_s24le.wav",
|
| + "3.03,2.86,2.99,3.31,3.57,4.06,",
|
| + 1,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(288414),
|
| + 12720,
|
| + 12719);
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, WaveF32LE) {
|
| - RunTest("sfx_f32le.wav", "3.03,2.86,2.99,3.31,3.57,4.06,", 1, 44100,
|
| - base::TimeDelta::FromMicroseconds(288414), 12720, 12719);
|
| + RunTest("sfx_f32le.wav",
|
| + "3.03,2.86,2.99,3.31,3.57,4.06,",
|
| + 1,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(288414),
|
| + 12720,
|
| + 12719);
|
| }
|
|
|
| #if defined(USE_PROPRIETARY_CODECS)
|
| TEST_F(AudioFileReaderTest, MP3) {
|
| - RunTest("sfx.mp3", "3.05,2.87,3.00,3.32,3.58,4.08,", 1, 44100,
|
| - base::TimeDelta::FromMicroseconds(313470), 13825, 12719);
|
| + RunTest("sfx.mp3",
|
| + "3.05,2.87,3.00,3.32,3.58,4.08,",
|
| + 1,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(313470),
|
| + 13825,
|
| + 12719);
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, CorruptMP3) {
|
| - RunTest("corrupt.mp3", "-4.95,-2.95,-0.44,1.16,0.31,-2.21,", 1, 44100,
|
| - base::TimeDelta::FromMicroseconds(1018826), 44931, 44928);
|
| + // Disable packet verification since the file is corrupt and FFmpeg does not
|
| + // make any guarantees on packet consistency in this case.
|
| + disable_packet_verification();
|
| + RunTest("corrupt.mp3",
|
| + "-4.95,-2.95,-0.44,1.16,0.31,-2.21,",
|
| + 1,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(1018826),
|
| + 44931,
|
| + 44928);
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, AAC) {
|
| - RunTest("sfx.m4a", "1.81,1.66,2.32,3.27,4.46,3.36,", 1, 44100,
|
| - base::TimeDelta::FromMicroseconds(312001), 13760, 13312);
|
| + RunTest("sfx.m4a",
|
| + "1.81,1.66,2.32,3.27,4.46,3.36,",
|
| + 1,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(312001),
|
| + 13760,
|
| + 13312);
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, MidStreamConfigChangesFail) {
|
| @@ -137,8 +236,13 @@ TEST_F(AudioFileReaderTest, VorbisInvalidChannelLayout) {
|
| }
|
|
|
| TEST_F(AudioFileReaderTest, WaveValidFourChannelLayout) {
|
| - RunTest("4ch.wav", "131.71,38.02,130.31,44.89,135.98,42.52,", 4, 44100,
|
| - base::TimeDelta::FromMicroseconds(100001), 4411, 4410);
|
| + RunTest("4ch.wav",
|
| + "131.71,38.02,130.31,44.89,135.98,42.52,",
|
| + 4,
|
| + 44100,
|
| + base::TimeDelta::FromMicroseconds(100001),
|
| + 4411,
|
| + 4410);
|
| }
|
|
|
| } // namespace media
|
|
|