Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1104)

Unified Diff: media/filters/audio_file_reader_unittest.cc

Issue 311373004: Consolidate and improve audio decoding test for all decoders. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. DEPS roll. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..8dc054dae6c168e59736aba15779bd09db391d73 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,69 @@ 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) {
+ AVDictionary* GetMetadata() {
+ return reader_->format_context_for_testing()
+ ->streams[reader_->stream_index_for_testing()]
+ ->metadata;
+ }
+
+ // 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() {
wolenetz 2014/06/16 23:36:08 Verify packet pts/dts/duration and any other impor
DaleCurtis 2014/06/19 01:05:52 Not here, AudioFileReader doesn't care about times
+ const int kReads = 3;
+ const int kTestPasses = 2;
+ const char* kContainerName =
+ reader_->format_context_for_testing()->iformat->name;
+
+ 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));
+ base::StringPiece packet_data = base::StringPiece(
+ reinterpret_cast<char*>(packet.data), packet.size);
+
+ // FFmpeg's ogg demuxer drops metadata from the packets after the first
+ // demuxing. Currently our test files only have metadata in the first
wolenetz 2014/06/16 23:36:08 aside: Is this a bug upstream? Do we use the metad
DaleCurtis 2014/06/19 01:05:52 No, I figured out the problem. I hadn't removed si
+ // packet, so limit the fix to those packets.
wolenetz 2014/06/16 23:36:08 nit: s/limit the fix to those packets/explicitly d
DaleCurtis 2014/06/19 01:05:52 Removed.
+ if (i == 0 && j == 0 && strcmp(kContainerName, "ogg") == 0) {
+ AVDictionaryEntry* tag = NULL;
+ tag = av_dict_get(GetMetadata(), "", tag, AV_DICT_IGNORE_SUFFIX);
+ if (tag) {
+ const size_t metadata_index = packet_data.find(tag->key);
+ CHECK_NE(metadata_index, std::string::npos);
+ packet_data.remove_suffix(packet_data.length() - metadata_index);
+ }
+ }
+
+ // On the first pass save the MD5 hash of each packet, on subsequent
+ // passes ensure it matches.
+ const std::string md5_hash = base::MD5String(packet_data);
+ 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 +112,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 +125,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 +152,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 +255,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

Powered by Google App Engine
This is Rietveld 408576698