1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/logging.h" 6#include "base/md5.h" 7#include "base/memory/scoped_ptr.h" 8#include "build/build_config.h" 9#include "media/base/audio_bus.h" 10#include "media/base/audio_hash.h" 11#include "media/base/decoder_buffer.h" 12#include "media/base/test_data_util.h" 13#include "media/ffmpeg/ffmpeg_common.h" 14#include "media/filters/audio_file_reader.h" 15#include "media/filters/in_memory_url_protocol.h" 16#include "testing/gtest/include/gtest/gtest.h" 17 18namespace media { 19 20class AudioFileReaderTest : public testing::Test { 21 public: 22 AudioFileReaderTest() : packet_verification_disabled_(false) {} 23 virtual ~AudioFileReaderTest() {} 24 25 void Initialize(const char* filename) { 26 data_ = ReadTestDataFile(filename); 27 protocol_.reset( 28 new InMemoryUrlProtocol(data_->data(), data_->data_size(), false)); 29 reader_.reset(new AudioFileReader(protocol_.get())); 30 } 31 32 // Reads and the entire file provided to Initialize(). 33 void ReadAndVerify(const char* expected_audio_hash, int expected_frames) { 34 scoped_ptr<AudioBus> decoded_audio_data = 35 AudioBus::Create(reader_->channels(), reader_->GetNumberOfFrames()); 36 int actual_frames = reader_->Read(decoded_audio_data.get()); 37 ASSERT_LE(actual_frames, decoded_audio_data->frames()); 38 ASSERT_EQ(expected_frames, actual_frames); 39 40 AudioHash audio_hash; 41 audio_hash.Update(decoded_audio_data.get(), actual_frames); 42 EXPECT_EQ(expected_audio_hash, audio_hash.ToString()); 43 } 44 45 // Verify packets are consistent across demuxer runs. Reads the first few 46 // packets and then seeks back to the start timestamp and verifies that the 47 // hashes match on the packets just read. 48 void VerifyPackets() { 49 const int kReads = 3; 50 const int kTestPasses = 2; 51 52 AVPacket packet; 53 base::TimeDelta start_timestamp; 54 std::vector<std::string> packet_md5_hashes_; 55 for (int i = 0; i < kTestPasses; ++i) { 56 for (int j = 0; j < kReads; ++j) { 57 ASSERT_TRUE(reader_->ReadPacketForTesting(&packet)); 58 59 // Remove metadata from the packet data section before hashing. 60 av_packet_split_side_data(&packet); 61 62 // On the first pass save the MD5 hash of each packet, on subsequent 63 // passes ensure it matches. 64 const std::string md5_hash = base::MD5String(base::StringPiece( 65 reinterpret_cast<char*>(packet.data), packet.size)); 66 if (i == 0) { 67 packet_md5_hashes_.push_back(md5_hash); 68 if (j == 0) { 69 start_timestamp = ConvertFromTimeBase( 70 reader_->codec_context_for_testing()->time_base, packet.pts); 71 } 72 } else { 73 EXPECT_EQ(packet_md5_hashes_[j], md5_hash) << "j = " << j; 74 } 75 76 av_free_packet(&packet); 77 } 78 ASSERT_TRUE(reader_->SeekForTesting(start_timestamp)); 79 } 80 } 81 82 void RunTest(const char* fn, 83 const char* hash, 84 int channels, 85 int sample_rate, 86 base::TimeDelta duration, 87 int frames, 88 int trimmed_frames) { 89 Initialize(fn); 90 ASSERT_TRUE(reader_->Open()); 91 EXPECT_EQ(channels, reader_->channels()); 92 EXPECT_EQ(sample_rate, reader_->sample_rate()); 93 EXPECT_EQ(duration.InMicroseconds(), 94 reader_->GetDuration().InMicroseconds()); 95 EXPECT_EQ(frames, reader_->GetNumberOfFrames()); 96 if (!packet_verification_disabled_) 97 ASSERT_NO_FATAL_FAILURE(VerifyPackets()); 98 ReadAndVerify(hash, trimmed_frames); 99 } 100 101 void RunTestFailingDemux(const char* fn) { 102 Initialize(fn); 103 EXPECT_FALSE(reader_->Open()); 104 } 105 106 void RunTestFailingDecode(const char* fn) { 107 Initialize(fn); 108 EXPECT_TRUE(reader_->Open()); 109 scoped_ptr<AudioBus> decoded_audio_data = 110 AudioBus::Create(reader_->channels(), reader_->GetNumberOfFrames()); 111 EXPECT_EQ(reader_->Read(decoded_audio_data.get()), 0); 112 } 113 114 void disable_packet_verification() { 115 packet_verification_disabled_ = true; 116 } 117 118 protected: 119 scoped_refptr<DecoderBuffer> data_; 120 scoped_ptr<InMemoryUrlProtocol> protocol_; 121 scoped_ptr<AudioFileReader> reader_; 122 bool packet_verification_disabled_; 123 124 DISALLOW_COPY_AND_ASSIGN(AudioFileReaderTest); 125}; 126 127TEST_F(AudioFileReaderTest, WithoutOpen) { 128 Initialize("bear.ogv"); 129} 130 131TEST_F(AudioFileReaderTest, InvalidFile) { 132 RunTestFailingDemux("ten_byte_file"); 133} 134 135TEST_F(AudioFileReaderTest, WithVideo) { 136 RunTest("bear.ogv", 137 "-2.49,-0.75,0.38,1.60,0.70,-1.22,", 138 2, 139 44100, 140 base::TimeDelta::FromMicroseconds(1011520), 141 44609, 142 44609); 143} 144 145TEST_F(AudioFileReaderTest, Vorbis) { 146 RunTest("sfx.ogg", 147 "4.36,4.81,4.84,4.45,4.61,4.63,", 148 1, 149 44100, 150 base::TimeDelta::FromMicroseconds(350001), 151 15436, 152 15436); 153} 154 155TEST_F(AudioFileReaderTest, WaveU8) { 156 RunTest("sfx_u8.wav", 157 "-1.23,-1.57,-1.14,-0.91,-0.87,-0.07,", 158 1, 159 44100, 160 base::TimeDelta::FromMicroseconds(288414), 161 12720, 162 12719); 163} 164 165TEST_F(AudioFileReaderTest, WaveS16LE) { 166 RunTest("sfx_s16le.wav", 167 "3.05,2.87,3.00,3.32,3.58,4.08,", 168 1, 169 44100, 170 base::TimeDelta::FromMicroseconds(288414), 171 12720, 172 12719); 173} 174 175TEST_F(AudioFileReaderTest, WaveS24LE) { 176 RunTest("sfx_s24le.wav", 177 "3.03,2.86,2.99,3.31,3.57,4.06,", 178 1, 179 44100, 180 base::TimeDelta::FromMicroseconds(288414), 181 12720, 182 12719); 183} 184 185TEST_F(AudioFileReaderTest, WaveF32LE) { 186 RunTest("sfx_f32le.wav", 187 "3.03,2.86,2.99,3.31,3.57,4.06,", 188 1, 189 44100, 190 base::TimeDelta::FromMicroseconds(288414), 191 12720, 192 12719); 193} 194 195#if defined(USE_PROPRIETARY_CODECS) 196TEST_F(AudioFileReaderTest, MP3) { 197 RunTest("sfx.mp3", 198 "5.59,7.11,6.63,6.23,5.58,5.22,", 199 1, 200 44100, 201 base::TimeDelta::FromMicroseconds(313470), 202 13825, 203 10496); 204} 205 206TEST_F(AudioFileReaderTest, CorruptMP3) { 207 // Disable packet verification since the file is corrupt and FFmpeg does not 208 // make any guarantees on packet consistency in this case. 209 disable_packet_verification(); 210 RunTest("corrupt.mp3", 211 "-4.95,-2.95,-0.44,1.16,0.31,-2.21,", 212 1, 213 44100, 214 base::TimeDelta::FromMicroseconds(1018826), 215 44931, 216 44928); 217} 218 219TEST_F(AudioFileReaderTest, AAC) { 220 RunTest("sfx.m4a", 221 "1.81,1.66,2.32,3.27,4.46,3.36,", 222 1, 223 44100, 224 base::TimeDelta::FromMicroseconds(312001), 225 13760, 226 13312); 227} 228 229TEST_F(AudioFileReaderTest, MidStreamConfigChangesFail) { 230 RunTestFailingDecode("midstream_config_change.mp3"); 231} 232#endif 233 234TEST_F(AudioFileReaderTest, VorbisInvalidChannelLayout) { 235 RunTestFailingDemux("9ch.ogg"); 236} 237 238TEST_F(AudioFileReaderTest, WaveValidFourChannelLayout) { 239 RunTest("4ch.wav", 240 "131.71,38.02,130.31,44.89,135.98,42.52,", 241 4, 242 44100, 243 base::TimeDelta::FromMicroseconds(100001), 244 4411, 245 4410); 246} 247 248} // namespace media 249