audio_decoder_unittest.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. // Copyright 2014 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. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <vector>
  8. #include "base/bind.h"
  9. #include "base/callback_helpers.h"
  10. #include "base/containers/circular_deque.h"
  11. #include "base/format_macros.h"
  12. #include "base/hash/md5.h"
  13. #include "base/run_loop.h"
  14. #include "base/strings/stringprintf.h"
  15. #include "base/sys_byteorder.h"
  16. #include "base/test/task_environment.h"
  17. #include "base/threading/platform_thread.h"
  18. #include "base/time/time.h"
  19. #include "build/build_config.h"
  20. #include "media/base/audio_buffer.h"
  21. #include "media/base/audio_bus.h"
  22. #include "media/base/audio_hash.h"
  23. #include "media/base/decoder_buffer.h"
  24. #include "media/base/media_util.h"
  25. #include "media/base/test_data_util.h"
  26. #include "media/base/test_helpers.h"
  27. #include "media/base/timestamp_constants.h"
  28. #include "media/ffmpeg/ffmpeg_common.h"
  29. #include "media/filters/audio_file_reader.h"
  30. #include "media/filters/ffmpeg_audio_decoder.h"
  31. #include "media/filters/in_memory_url_protocol.h"
  32. #include "media/media_buildflags.h"
  33. #include "testing/gtest/include/gtest/gtest.h"
  34. #if BUILDFLAG(IS_ANDROID)
  35. #include "base/android/build_info.h"
  36. #include "media/base/android/media_codec_util.h"
  37. #include "media/filters/android/media_codec_audio_decoder.h"
  38. #endif
  39. #if BUILDFLAG(IS_MAC)
  40. #include "media/filters/mac/audio_toolbox_audio_decoder.h"
  41. #endif
  42. #if BUILDFLAG(USE_PROPRIETARY_CODECS)
  43. #include "media/formats/mpeg/adts_stream_parser.h"
  44. #endif
  45. using testing::Combine;
  46. using testing::TestWithParam;
  47. using testing::Values;
  48. using testing::ValuesIn;
  49. namespace media {
  50. namespace {
  51. // The number of packets to read and then decode from each file.
  52. const size_t kDecodeRuns = 3;
  53. struct DecodedBufferExpectations {
  54. int64_t timestamp;
  55. int64_t duration;
  56. const char* hash;
  57. };
  58. struct TestParams {
  59. AudioCodec codec;
  60. const char* filename;
  61. const DecodedBufferExpectations* expectations;
  62. int first_packet_pts;
  63. int samples_per_second;
  64. ChannelLayout channel_layout;
  65. };
  66. // Tells gtest how to print our TestParams structure.
  67. std::ostream& operator<<(std::ostream& os, const TestParams& params) {
  68. return os << params.filename;
  69. }
  70. // Marks negative timestamp buffers for discard or transfers FFmpeg's built in
  71. // discard metadata in favor of setting DiscardPadding on the DecoderBuffer.
  72. // Allows better testing of AudioDiscardHelper usage.
  73. void SetDiscardPadding(AVPacket* packet,
  74. DecoderBuffer* buffer,
  75. double samples_per_second) {
  76. // Discard negative timestamps.
  77. if ((buffer->timestamp() + buffer->duration()).is_negative()) {
  78. buffer->set_discard_padding(
  79. std::make_pair(kInfiniteDuration, base::TimeDelta()));
  80. return;
  81. }
  82. if (buffer->timestamp().is_negative()) {
  83. buffer->set_discard_padding(
  84. std::make_pair(-buffer->timestamp(), base::TimeDelta()));
  85. return;
  86. }
  87. // If the timestamp is positive, try to use FFmpeg's discard data.
  88. size_t skip_samples_size = 0;
  89. const uint32_t* skip_samples_ptr =
  90. reinterpret_cast<const uint32_t*>(av_packet_get_side_data(
  91. packet, AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
  92. if (skip_samples_size < 4)
  93. return;
  94. buffer->set_discard_padding(
  95. std::make_pair(base::Seconds(base::ByteSwapToLE32(*skip_samples_ptr) /
  96. samples_per_second),
  97. base::TimeDelta()));
  98. }
  99. } // namespace
  100. class AudioDecoderTest
  101. : public TestWithParam<std::tuple<AudioDecoderType, TestParams>> {
  102. public:
  103. AudioDecoderTest()
  104. : decoder_type_(std::get<0>(GetParam())),
  105. params_(std::get<1>(GetParam())),
  106. pending_decode_(false),
  107. pending_reset_(false),
  108. last_decode_status_(DecoderStatus::Codes::kFailed) {
  109. switch (decoder_type_) {
  110. case AudioDecoderType::kFFmpeg:
  111. decoder_ = std::make_unique<FFmpegAudioDecoder>(
  112. task_environment_.GetMainThreadTaskRunner(), &media_log_);
  113. break;
  114. #if BUILDFLAG(IS_ANDROID)
  115. case AudioDecoderType::kMediaCodec:
  116. decoder_ = std::make_unique<MediaCodecAudioDecoder>(
  117. task_environment_.GetMainThreadTaskRunner());
  118. break;
  119. #elif BUILDFLAG(IS_MAC)
  120. case AudioDecoderType::kAudioToolbox:
  121. decoder_ = std::make_unique<AudioToolboxAudioDecoder>();
  122. break;
  123. #endif
  124. default:
  125. EXPECT_TRUE(false) << "Decoder is not supported by this test.";
  126. break;
  127. }
  128. }
  129. AudioDecoderTest(const AudioDecoderTest&) = delete;
  130. AudioDecoderTest& operator=(const AudioDecoderTest&) = delete;
  131. virtual ~AudioDecoderTest() {
  132. EXPECT_FALSE(pending_decode_);
  133. EXPECT_FALSE(pending_reset_);
  134. }
  135. void SetUp() override {
  136. if (!IsSupported())
  137. GTEST_SKIP() << "Unsupported platform.";
  138. }
  139. protected:
  140. bool IsSupported() const {
  141. #if BUILDFLAG(IS_MAC)
  142. if (decoder_type_ == AudioDecoderType::kAudioToolbox) {
  143. if (__builtin_available(macOS 10.15, *))
  144. return true; // Annoyingly !__builtin_available() doesn't work.
  145. return false;
  146. }
  147. #endif // BUILDFLAG(IS_MAC)
  148. return true;
  149. }
  150. void DecodeBuffer(scoped_refptr<DecoderBuffer> buffer) {
  151. ASSERT_FALSE(pending_decode_);
  152. pending_decode_ = true;
  153. last_decode_status_ = DecoderStatus::Codes::kFailed;
  154. base::RunLoop run_loop;
  155. decoder_->Decode(
  156. std::move(buffer),
  157. base::BindOnce(&AudioDecoderTest::DecodeFinished,
  158. base::Unretained(this), run_loop.QuitClosure()));
  159. run_loop.Run();
  160. ASSERT_FALSE(pending_decode_);
  161. }
  162. void SendEndOfStream() { DecodeBuffer(DecoderBuffer::CreateEOSBuffer()); }
  163. // Set the TestParams explicitly. Can be use to reinitialize the decoder with
  164. // different TestParams.
  165. void set_params(const TestParams& params) { params_ = params; }
  166. void SetReinitializeParams();
  167. void Initialize() {
  168. // Load the test data file.
  169. data_ = ReadTestDataFile(params_.filename);
  170. protocol_ = std::make_unique<InMemoryUrlProtocol>(
  171. data_->data(), data_->data_size(), false);
  172. reader_ = std::make_unique<AudioFileReader>(protocol_.get());
  173. ASSERT_TRUE(reader_->OpenDemuxerForTesting());
  174. // Load the first packet and check its timestamp.
  175. AVPacket packet;
  176. ASSERT_TRUE(reader_->ReadPacketForTesting(&packet));
  177. EXPECT_EQ(params_.first_packet_pts, packet.pts);
  178. start_timestamp_ = ConvertFromTimeBase(
  179. reader_->GetAVStreamForTesting()->time_base, packet.pts);
  180. // Seek back to the beginning.
  181. ASSERT_TRUE(reader_->SeekForTesting(start_timestamp_));
  182. AudioDecoderConfig config;
  183. ASSERT_TRUE(AVCodecContextToAudioDecoderConfig(
  184. reader_->codec_context_for_testing(), EncryptionScheme::kUnencrypted,
  185. &config));
  186. #if BUILDFLAG(IS_ANDROID) && BUILDFLAG(USE_PROPRIETARY_CODECS)
  187. // MediaCodec type requires config->extra_data() for AAC codec. For ADTS
  188. // streams we need to extract it with a separate procedure.
  189. if (decoder_type_ == AudioDecoderType::kMediaCodec &&
  190. params_.codec == AudioCodec::kAAC && config.extra_data().empty()) {
  191. int sample_rate;
  192. ChannelLayout channel_layout;
  193. std::vector<uint8_t> extra_data;
  194. ASSERT_GT(ADTSStreamParser().ParseFrameHeader(
  195. packet.data, packet.size, nullptr, &sample_rate,
  196. &channel_layout, nullptr, nullptr, &extra_data),
  197. 0);
  198. config.Initialize(AudioCodec::kAAC, kSampleFormatS16, channel_layout,
  199. sample_rate, extra_data, EncryptionScheme::kUnencrypted,
  200. base::TimeDelta(), 0);
  201. ASSERT_FALSE(config.extra_data().empty());
  202. }
  203. #endif
  204. av_packet_unref(&packet);
  205. EXPECT_EQ(params_.codec, config.codec());
  206. EXPECT_EQ(params_.samples_per_second, config.samples_per_second());
  207. EXPECT_EQ(params_.channel_layout, config.channel_layout());
  208. InitializeDecoder(config);
  209. }
  210. void InitializeDecoder(const AudioDecoderConfig& config) {
  211. InitializeDecoderWithResult(config, true);
  212. }
  213. void InitializeDecoderWithResult(const AudioDecoderConfig& config,
  214. bool success) {
  215. decoder_->Initialize(config, nullptr,
  216. base::BindOnce(
  217. [](bool success, DecoderStatus status) {
  218. EXPECT_EQ(status.is_ok(), success);
  219. },
  220. success),
  221. base::BindRepeating(&AudioDecoderTest::OnDecoderOutput,
  222. base::Unretained(this)),
  223. base::DoNothing());
  224. base::RunLoop().RunUntilIdle();
  225. }
  226. void Decode() {
  227. AVPacket packet;
  228. ASSERT_TRUE(reader_->ReadPacketForTesting(&packet));
  229. scoped_refptr<DecoderBuffer> buffer =
  230. DecoderBuffer::CopyFrom(packet.data, packet.size);
  231. buffer->set_timestamp(ConvertFromTimeBase(
  232. reader_->GetAVStreamForTesting()->time_base, packet.pts));
  233. buffer->set_duration(ConvertFromTimeBase(
  234. reader_->GetAVStreamForTesting()->time_base, packet.duration));
  235. if (packet.flags & AV_PKT_FLAG_KEY)
  236. buffer->set_is_key_frame(true);
  237. // Don't set discard padding for Opus, it already has discard behavior set
  238. // based on the codec delay in the AudioDecoderConfig.
  239. if (decoder_type_ == AudioDecoderType::kFFmpeg &&
  240. params_.codec != AudioCodec::kOpus) {
  241. SetDiscardPadding(&packet, buffer.get(), params_.samples_per_second);
  242. }
  243. // DecodeBuffer() shouldn't need the original packet since it uses the copy.
  244. av_packet_unref(&packet);
  245. DecodeBuffer(std::move(buffer));
  246. }
  247. void Reset() {
  248. ASSERT_FALSE(pending_reset_);
  249. pending_reset_ = true;
  250. decoder_->Reset(base::BindOnce(&AudioDecoderTest::ResetFinished,
  251. base::Unretained(this)));
  252. base::RunLoop().RunUntilIdle();
  253. ASSERT_FALSE(pending_reset_);
  254. }
  255. void Seek(base::TimeDelta seek_time) {
  256. Reset();
  257. decoded_audio_.clear();
  258. ASSERT_TRUE(reader_->SeekForTesting(seek_time));
  259. }
  260. void OnDecoderOutput(scoped_refptr<AudioBuffer> buffer) {
  261. EXPECT_FALSE(buffer->end_of_stream());
  262. decoded_audio_.push_back(std::move(buffer));
  263. }
  264. void DecodeFinished(base::OnceClosure quit_closure, DecoderStatus status) {
  265. EXPECT_TRUE(pending_decode_);
  266. EXPECT_FALSE(pending_reset_);
  267. pending_decode_ = false;
  268. last_decode_status_ = std::move(status);
  269. std::move(quit_closure).Run();
  270. }
  271. void ResetFinished() {
  272. EXPECT_TRUE(pending_reset_);
  273. EXPECT_FALSE(pending_decode_);
  274. pending_reset_ = false;
  275. }
  276. // Generates an MD5 hash of the audio signal. Should not be used for checks
  277. // across platforms as audio varies slightly across platforms.
  278. std::string GetDecodedAudioMD5(size_t i) {
  279. CHECK_LT(i, decoded_audio_.size());
  280. const scoped_refptr<AudioBuffer>& buffer = decoded_audio_[i];
  281. std::unique_ptr<AudioBus> output =
  282. AudioBus::Create(buffer->channel_count(), buffer->frame_count());
  283. buffer->ReadFrames(buffer->frame_count(), 0, 0, output.get());
  284. base::MD5Context context;
  285. base::MD5Init(&context);
  286. for (int ch = 0; ch < output->channels(); ++ch) {
  287. base::MD5Update(
  288. &context,
  289. base::StringPiece(reinterpret_cast<char*>(output->channel(ch)),
  290. output->frames() * sizeof(*output->channel(ch))));
  291. }
  292. base::MD5Digest digest;
  293. base::MD5Final(&digest, &context);
  294. return base::MD5DigestToBase16(digest);
  295. }
  296. void ExpectDecodedAudio(size_t i, const std::string& exact_hash) {
  297. CHECK_LT(i, decoded_audio_.size());
  298. const scoped_refptr<AudioBuffer>& buffer = decoded_audio_[i];
  299. const DecodedBufferExpectations& sample_info = params_.expectations[i];
  300. EXPECT_EQ(sample_info.timestamp, buffer->timestamp().InMicroseconds());
  301. EXPECT_EQ(sample_info.duration, buffer->duration().InMicroseconds());
  302. EXPECT_FALSE(buffer->end_of_stream());
  303. std::unique_ptr<AudioBus> output =
  304. AudioBus::Create(buffer->channel_count(), buffer->frame_count());
  305. buffer->ReadFrames(buffer->frame_count(), 0, 0, output.get());
  306. // Generate a lossy hash of the audio used for comparison across platforms.
  307. AudioHash audio_hash;
  308. audio_hash.Update(output.get(), output->frames());
  309. EXPECT_TRUE(audio_hash.IsEquivalent(sample_info.hash, 0.03))
  310. << "Audio hashes differ. Expected: " << sample_info.hash
  311. << " Actual: " << audio_hash.ToString();
  312. if (!exact_hash.empty()) {
  313. EXPECT_EQ(exact_hash, GetDecodedAudioMD5(i));
  314. // Verify different hashes are being generated. None of our test data
  315. // files have audio that hashes out exactly the same.
  316. if (i > 0)
  317. EXPECT_NE(exact_hash, GetDecodedAudioMD5(i - 1));
  318. }
  319. }
  320. size_t decoded_audio_size() const { return decoded_audio_.size(); }
  321. base::TimeDelta start_timestamp() const { return start_timestamp_; }
  322. const scoped_refptr<AudioBuffer>& decoded_audio(size_t i) {
  323. return decoded_audio_[i];
  324. }
  325. const DecoderStatus& last_decode_status() const {
  326. return last_decode_status_;
  327. }
  328. private:
  329. const AudioDecoderType decoder_type_;
  330. // Current TestParams used to initialize the test and decoder. The initial
  331. // valie is std::get<1>(GetParam()). Could be overridden by set_param() so
  332. // that the decoder can be reinitialized with different parameters.
  333. TestParams params_;
  334. base::test::SingleThreadTaskEnvironment task_environment_;
  335. NullMediaLog media_log_;
  336. scoped_refptr<DecoderBuffer> data_;
  337. std::unique_ptr<InMemoryUrlProtocol> protocol_;
  338. std::unique_ptr<AudioFileReader> reader_;
  339. std::unique_ptr<AudioDecoder> decoder_;
  340. bool pending_decode_;
  341. bool pending_reset_;
  342. DecoderStatus last_decode_status_ = DecoderStatus::Codes::kOk;
  343. base::circular_deque<scoped_refptr<AudioBuffer>> decoded_audio_;
  344. base::TimeDelta start_timestamp_;
  345. };
  346. const DecodedBufferExpectations kBearOpusExpectations[] = {
  347. {500, 3500, "-0.26,0.87,1.36,0.84,-0.30,-1.22,"},
  348. {4000, 10000, "0.09,0.23,0.21,0.03,-0.17,-0.24,"},
  349. {14000, 10000, "0.10,0.24,0.23,0.04,-0.14,-0.23,"},
  350. };
  351. // Test params to test decoder reinitialization. Choose opus because it is
  352. // supported on all platforms we test on.
  353. const TestParams kReinitializeTestParams = {
  354. AudioCodec::kOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
  355. CHANNEL_LAYOUT_STEREO};
  356. #if BUILDFLAG(IS_ANDROID)
  357. #if BUILDFLAG(USE_PROPRIETARY_CODECS)
  358. const DecodedBufferExpectations kSfxAdtsMcExpectations[] = {
  359. {0, 23219, "-1.80,-1.49,-0.23,1.11,1.54,-0.11,"},
  360. {23219, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"},
  361. {46439, 23219, "0.54,0.88,2.19,3.54,3.24,1.63,"},
  362. };
  363. const DecodedBufferExpectations kHeAacMcExpectations[] = {
  364. {0, 42666, "-1.76,-0.12,1.72,1.45,0.10,-1.32,"},
  365. {42666, 42666, "-1.78,-0.13,1.70,1.44,0.09,-1.32,"},
  366. {85333, 42666, "-1.78,-0.13,1.70,1.44,0.08,-1.33,"},
  367. };
  368. #endif // defined(USE_PROPRIETARY_CODECS)
  369. const TestParams kMediaCodecTestParams[] = {
  370. {AudioCodec::kOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
  371. CHANNEL_LAYOUT_STEREO},
  372. #if BUILDFLAG(USE_PROPRIETARY_CODECS)
  373. {AudioCodec::kAAC, "sfx.adts", kSfxAdtsMcExpectations, 0, 44100,
  374. CHANNEL_LAYOUT_MONO},
  375. {AudioCodec::kAAC, "bear-audio-implicit-he-aac-v2.aac",
  376. kHeAacMcExpectations, 0, 24000, CHANNEL_LAYOUT_MONO},
  377. #endif // defined(USE_PROPRIETARY_CODECS)
  378. };
  379. #endif // BUILDFLAG(IS_ANDROID)
  380. #if BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PROPRIETARY_CODECS)
  381. const DecodedBufferExpectations kNoiseXheAAcExpectations[] = {
  382. {0, 42666, "6.09,2.44,-4.73,4.06,6.47,1.29,"},
  383. {42666, 42666, "-5.16,0.94,3.14,2.52,5.26,-0.24,"},
  384. {85333, 42666, "7.90,-0.09,-3.65,1.41,-4.26,-1.32,"},
  385. };
  386. const DecodedBufferExpectations kNoiseMonoXheAAcExpectations[] = {
  387. {0, 34829, "-1.94,-1.64,-0.37,0.94,1.36,-0.26,"},
  388. {34829, 34829, "-1.43,-1.14,0.13,1.43,1.86,0.24,"},
  389. {69659, 34829, "-1.13,-0.84,0.42,1.71,2.14,0.53,"},
  390. };
  391. const TestParams kAudioToolboxTestParams[] = {
  392. {AudioCodec::kAAC, "noise-xhe-aac.mp4", kNoiseXheAAcExpectations, 0, 48000,
  393. CHANNEL_LAYOUT_STEREO},
  394. {AudioCodec::kAAC, "noise-xhe-aac-mono.mp4", kNoiseMonoXheAAcExpectations,
  395. 0, 29400, CHANNEL_LAYOUT_MONO},
  396. };
  397. #endif // BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PROPRIETARY_CODECS)
  398. const DecodedBufferExpectations kSfxMp3Expectations[] = {
  399. {0, 1065, "2.81,3.99,4.53,4.10,3.08,2.46,"},
  400. {1065, 26122, "-3.81,-4.14,-3.90,-3.36,-3.03,-3.23,"},
  401. {27188, 26122, "4.24,3.95,4.22,4.78,5.13,4.93,"},
  402. };
  403. #if BUILDFLAG(USE_PROPRIETARY_CODECS)
  404. const DecodedBufferExpectations kSfxAdtsExpectations[] = {
  405. {0, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"},
  406. {23219, 23219, "0.54,0.88,2.19,3.54,3.24,1.63,"},
  407. {46439, 23219, "1.42,1.69,2.95,4.23,4.02,2.36,"},
  408. };
  409. #endif
  410. const DecodedBufferExpectations kSfxFlacExpectations[] = {
  411. {0, 104489, "-2.42,-1.12,0.71,1.70,1.09,-0.68,"},
  412. {104489, 104489, "-1.99,-0.67,1.18,2.19,1.60,-0.16,"},
  413. {208979, 79433, "2.84,2.70,3.23,4.06,4.59,4.44,"},
  414. };
  415. const DecodedBufferExpectations kSfxWaveExpectations[] = {
  416. {0, 23219, "-1.23,-0.87,0.47,1.85,1.88,0.29,"},
  417. {23219, 23219, "0.75,1.10,2.43,3.78,3.53,1.93,"},
  418. {46439, 23219, "1.27,1.56,2.83,4.13,3.87,2.23,"},
  419. };
  420. const DecodedBufferExpectations kFourChannelWaveExpectations[] = {
  421. {0, 11609, "-1.68,1.68,0.89,-3.45,1.52,1.15,"},
  422. {11609, 11609, "43.26,9.06,18.27,35.98,19.45,7.46,"},
  423. {23219, 11609, "36.37,9.45,16.04,27.67,18.81,10.15,"},
  424. };
  425. const DecodedBufferExpectations kSfxOggExpectations[] = {
  426. {0, 13061, "-0.33,1.25,2.86,3.26,2.09,0.14,"},
  427. {13061, 23219, "-2.79,-2.42,-1.06,0.33,0.93,-0.64,"},
  428. {36281, 23219, "-1.19,-0.80,0.57,1.97,2.08,0.51,"},
  429. };
  430. const DecodedBufferExpectations kBearOgvExpectations[] = {
  431. {0, 13061, "-1.25,0.10,2.11,2.29,1.50,-0.68,"},
  432. {13061, 23219, "-1.80,-1.41,-0.13,1.30,1.65,0.01,"},
  433. {36281, 23219, "-1.43,-1.25,0.11,1.29,1.86,0.14,"},
  434. };
  435. #if defined(OPUS_FIXED_POINT)
  436. const DecodedBufferExpectations kSfxOpusExpectations[] = {
  437. {0, 13500, "-2.70,-1.41,-0.78,-1.27,-2.56,-3.73,"},
  438. {13500, 20000, "5.48,5.93,6.05,5.83,5.54,5.46,"},
  439. {33500, 20000, "-3.44,-3.34,-3.57,-4.11,-4.74,-5.13,"},
  440. };
  441. #else
  442. const DecodedBufferExpectations kSfxOpusExpectations[] = {
  443. {0, 13500, "-2.70,-1.41,-0.78,-1.27,-2.56,-3.73,"},
  444. {13500, 20000, "5.48,5.93,6.04,5.83,5.54,5.45,"},
  445. {33500, 20000, "-3.45,-3.35,-3.57,-4.12,-4.74,-5.14,"},
  446. };
  447. #endif
  448. const TestParams kFFmpegTestParams[] = {
  449. {AudioCodec::kMP3, "sfx.mp3", kSfxMp3Expectations, 0, 44100,
  450. CHANNEL_LAYOUT_MONO},
  451. #if BUILDFLAG(USE_PROPRIETARY_CODECS)
  452. {AudioCodec::kAAC, "sfx.adts", kSfxAdtsExpectations, 0, 44100,
  453. CHANNEL_LAYOUT_MONO},
  454. #endif
  455. {AudioCodec::kFLAC, "sfx-flac.mp4", kSfxFlacExpectations, 0, 44100,
  456. CHANNEL_LAYOUT_MONO},
  457. {AudioCodec::kFLAC, "sfx.flac", kSfxFlacExpectations, 0, 44100,
  458. CHANNEL_LAYOUT_MONO},
  459. {AudioCodec::kPCM, "sfx_f32le.wav", kSfxWaveExpectations, 0, 44100,
  460. CHANNEL_LAYOUT_MONO},
  461. {AudioCodec::kPCM, "4ch.wav", kFourChannelWaveExpectations, 0, 44100,
  462. CHANNEL_LAYOUT_QUAD},
  463. {AudioCodec::kVorbis, "sfx.ogg", kSfxOggExpectations, 0, 44100,
  464. CHANNEL_LAYOUT_MONO},
  465. // Note: bear.ogv is incorrectly muxed such that valid samples are given
  466. // negative timestamps, this marks them for discard per the ogg vorbis spec.
  467. {AudioCodec::kVorbis, "bear.ogv", kBearOgvExpectations, -704, 44100,
  468. CHANNEL_LAYOUT_STEREO},
  469. {AudioCodec::kOpus, "sfx-opus.ogg", kSfxOpusExpectations, -312, 48000,
  470. CHANNEL_LAYOUT_MONO},
  471. {AudioCodec::kOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
  472. CHANNEL_LAYOUT_STEREO},
  473. };
  474. void AudioDecoderTest::SetReinitializeParams() {
  475. #if BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PROPRIETARY_CODECS)
  476. // AudioToolbox only supports xHE-AAC, so we can't use the Opus params. We can
  477. // instead just swap between the two test parameter sets.
  478. if (decoder_type_ == AudioDecoderType::kAudioToolbox) {
  479. set_params(params_.channel_layout ==
  480. kAudioToolboxTestParams[0].channel_layout
  481. ? kAudioToolboxTestParams[1]
  482. : kAudioToolboxTestParams[0]);
  483. return;
  484. }
  485. #endif
  486. set_params(kReinitializeTestParams);
  487. }
  488. TEST_P(AudioDecoderTest, Initialize) {
  489. ASSERT_NO_FATAL_FAILURE(Initialize());
  490. }
  491. TEST_P(AudioDecoderTest, Reinitialize_AfterInitialize) {
  492. ASSERT_NO_FATAL_FAILURE(Initialize());
  493. SetReinitializeParams();
  494. ASSERT_NO_FATAL_FAILURE(Initialize());
  495. Decode();
  496. }
  497. TEST_P(AudioDecoderTest, Reinitialize_AfterDecode) {
  498. ASSERT_NO_FATAL_FAILURE(Initialize());
  499. Decode();
  500. SetReinitializeParams();
  501. ASSERT_NO_FATAL_FAILURE(Initialize());
  502. Decode();
  503. }
  504. TEST_P(AudioDecoderTest, Reinitialize_AfterReset) {
  505. ASSERT_NO_FATAL_FAILURE(Initialize());
  506. Decode();
  507. Reset();
  508. SetReinitializeParams();
  509. ASSERT_NO_FATAL_FAILURE(Initialize());
  510. Decode();
  511. }
  512. // Verifies decode audio as well as the Decode() -> Reset() sequence.
  513. TEST_P(AudioDecoderTest, ProduceAudioSamples) {
  514. ASSERT_NO_FATAL_FAILURE(Initialize());
  515. // Run the test multiple times with a seek back to the beginning in between.
  516. std::vector<std::string> decoded_audio_md5_hashes;
  517. for (int i = 0; i < 2; ++i) {
  518. // Run decoder until we get at least |kDecodeRuns| output buffers.
  519. // Keeping Decode() in a loop seems to be the simplest way to guarantee that
  520. // the predefined number of output buffers are produced without draining
  521. // (i.e. decoding EOS).
  522. do {
  523. ASSERT_NO_FATAL_FAILURE(Decode());
  524. ASSERT_TRUE(last_decode_status().is_ok());
  525. } while (decoded_audio_size() < kDecodeRuns);
  526. // With MediaCodecAudioDecoder the output buffers might appear after
  527. // some delay. Since we keep decoding in a loop, the number of output
  528. // buffers when they eventually appear might exceed |kDecodeRuns|.
  529. ASSERT_LE(kDecodeRuns, decoded_audio_size());
  530. // On the first pass record the exact MD5 hash for each decoded buffer.
  531. if (i == 0) {
  532. for (size_t j = 0; j < kDecodeRuns; ++j)
  533. decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j));
  534. }
  535. // On the first pass verify the basic audio hash and sample info. On the
  536. // second, verify the exact MD5 sum for each packet. It shouldn't change.
  537. for (size_t j = 0; j < kDecodeRuns; ++j) {
  538. SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j));
  539. ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]);
  540. }
  541. SendEndOfStream();
  542. // Seek back to the beginning. Calls Reset() on the decoder.
  543. Seek(start_timestamp());
  544. }
  545. }
  546. TEST_P(AudioDecoderTest, Decode) {
  547. ASSERT_NO_FATAL_FAILURE(Initialize());
  548. Decode();
  549. EXPECT_TRUE(last_decode_status().is_ok());
  550. }
  551. TEST_P(AudioDecoderTest, Reset) {
  552. ASSERT_NO_FATAL_FAILURE(Initialize());
  553. Reset();
  554. }
  555. TEST_P(AudioDecoderTest, NoTimestamp) {
  556. ASSERT_NO_FATAL_FAILURE(Initialize());
  557. scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));
  558. buffer->set_timestamp(kNoTimestamp);
  559. DecodeBuffer(std::move(buffer));
  560. EXPECT_THAT(last_decode_status(), IsDecodeErrorStatus());
  561. }
  562. INSTANTIATE_TEST_SUITE_P(FFmpeg,
  563. AudioDecoderTest,
  564. Combine(Values(AudioDecoderType::kFFmpeg),
  565. ValuesIn(kFFmpegTestParams)));
  566. #if BUILDFLAG(IS_ANDROID)
  567. INSTANTIATE_TEST_SUITE_P(MediaCodec,
  568. AudioDecoderTest,
  569. Combine(Values(AudioDecoderType::kMediaCodec),
  570. ValuesIn(kMediaCodecTestParams)));
  571. #endif // BUILDFLAG(IS_ANDROID)
  572. #if BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PROPRIETARY_CODECS)
  573. INSTANTIATE_TEST_SUITE_P(AudioToolbox,
  574. AudioDecoderTest,
  575. Combine(Values(AudioDecoderType::kAudioToolbox),
  576. ValuesIn(kAudioToolboxTestParams)));
  577. #endif // BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PROPRIETARY_CODECS)
  578. } // namespace media