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