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