16d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
26d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
36d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// found in the LICENSE file.
46d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
56d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include <deque>
66d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
76d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/bind.h"
86d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/format_macros.h"
96d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/md5.h"
106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/message_loop/message_loop.h"
116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/run_loop.h"
126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/strings/stringprintf.h"
136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "base/sys_byteorder.h"
146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "build/build_config.h"
156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/base/audio_buffer.h"
166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/base/audio_bus.h"
176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/base/audio_hash.h"
186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/base/decoder_buffer.h"
196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/base/test_data_util.h"
206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/base/test_helpers.h"
216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h"
226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/filters/audio_file_reader.h"
236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/filters/ffmpeg_audio_decoder.h"
246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/filters/in_memory_url_protocol.h"
256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "media/filters/opus_audio_decoder.h"
266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)namespace media {
296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// The number of packets to read and then decode from each file.
316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)static const size_t kDecodeRuns = 3;
326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)static const uint8_t kOpusExtraData[] = {
336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x02,
346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // The next two bytes represent the codec delay.
356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    0x00, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00};
366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)enum AudioDecoderType {
386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  FFMPEG,
396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  OPUS,
406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)struct DecodedBufferExpectations {
436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const int64 timestamp;
446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const int64 duration;
456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const char* hash;
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)struct DecoderTestData {
496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const AudioDecoderType decoder_type;
506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const AudioCodec codec;
516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const char* filename;
526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const DecodedBufferExpectations* expectations;
536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const int first_packet_pts;
546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const int samples_per_second;
556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const ChannelLayout channel_layout;
566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Tells gtest how to print our DecoderTestData structure.
596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)std::ostream& operator<<(std::ostream& os, const DecoderTestData& data) {
606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return os << data.filename;
616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Marks negative timestamp buffers for discard or transfers FFmpeg's built in
646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// discard metadata in favor of setting DiscardPadding on the DecoderBuffer.
656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Allows better testing of AudioDiscardHelper usage.
666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)static void SetDiscardPadding(AVPacket* packet,
676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                              const scoped_refptr<DecoderBuffer> buffer,
686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                              double samples_per_second) {
696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Discard negative timestamps.
706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (buffer->timestamp() + buffer->duration() < base::TimeDelta()) {
716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    buffer->set_discard_padding(
726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        std::make_pair(kInfiniteDuration(), base::TimeDelta()));
736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (buffer->timestamp() < base::TimeDelta()) {
766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    buffer->set_discard_padding(
776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        std::make_pair(-buffer->timestamp(), base::TimeDelta()));
786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // If the timestamp is positive, try to use FFmpeg's discard data.
826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  int skip_samples_size = 0;
836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const uint32* skip_samples_ptr =
846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      reinterpret_cast<const uint32*>(av_packet_get_side_data(
856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          packet, AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (skip_samples_size < 4)
876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  buffer->set_discard_padding(std::make_pair(
896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      base::TimeDelta::FromSecondsD(base::ByteSwapToLE32(*skip_samples_ptr) /
906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                    samples_per_second),
916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      base::TimeDelta()));
926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class AudioDecoderTest : public testing::TestWithParam<DecoderTestData> {
956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) public:
966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AudioDecoderTest()
976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      : pending_decode_(false),
986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        pending_reset_(false),
996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        last_decode_status_(AudioDecoder::kDecodeError) {
1006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    switch (GetParam().decoder_type) {
1016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      case FFMPEG:
1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        decoder_.reset(new FFmpegAudioDecoder(
1036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            message_loop_.message_loop_proxy(), LogCB()));
1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        break;
1056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      case OPUS:
1066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        decoder_.reset(
1076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)            new OpusAudioDecoder(message_loop_.message_loop_proxy()));
1086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        break;
1096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
1106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  virtual ~AudioDecoderTest() {
1136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_FALSE(pending_decode_);
1146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_FALSE(pending_reset_);
1156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) protected:
1186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) {
1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_FALSE(pending_decode_);
1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    pending_decode_ = true;
1216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    last_decode_status_ = AudioDecoder::kDecodeError;
1226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    decoder_->Decode(
1236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        buffer,
1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(&AudioDecoderTest::DecodeFinished, base::Unretained(this)));
1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
1266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_FALSE(pending_decode_);
1276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void SendEndOfStream() {
1306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    DecodeBuffer(DecoderBuffer::CreateEOSBuffer());
1316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void Initialize() {
1346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Load the test data file.
1356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    data_ = ReadTestDataFile(GetParam().filename);
1366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    protocol_.reset(
1376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        new InMemoryUrlProtocol(data_->data(), data_->data_size(), false));
1386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    reader_.reset(new AudioFileReader(protocol_.get()));
1396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_TRUE(reader_->OpenDemuxerForTesting());
1406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Load the first packet and check its timestamp.
1426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AVPacket packet;
1436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_TRUE(reader_->ReadPacketForTesting(&packet));
1446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(GetParam().first_packet_pts, packet.pts);
1456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    start_timestamp_ = ConvertFromTimeBase(
1466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        reader_->GetAVStreamForTesting()->time_base, packet.pts);
1476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    av_free_packet(&packet);
1486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Seek back to the beginning.
1506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_TRUE(reader_->SeekForTesting(start_timestamp_));
1516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AudioDecoderConfig config;
1536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AVCodecContextToAudioDecoderConfig(
1546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        reader_->codec_context_for_testing(), false, &config, false);
1556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(GetParam().codec, config.codec());
1576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(GetParam().samples_per_second, config.samples_per_second());
1586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(GetParam().channel_layout, config.channel_layout());
1596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    InitializeDecoder(config);
1616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void InitializeDecoder(const AudioDecoderConfig& config) {
1646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    InitializeDecoderWithStatus(config, PIPELINE_OK);
1656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void InitializeDecoderWithStatus(const AudioDecoderConfig& config,
1686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                   PipelineStatus status) {
1696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    decoder_->Initialize(
1706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        config,
1716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        NewExpectedStatusCB(status),
1726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(&AudioDecoderTest::OnDecoderOutput, base::Unretained(this)));
1736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
1746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void Decode() {
1776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AVPacket packet;
1786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_TRUE(reader_->ReadPacketForTesting(&packet));
1796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Split out packet metadata before making a copy.
1816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    av_packet_split_side_data(&packet);
1826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_refptr<DecoderBuffer> buffer =
1846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        DecoderBuffer::CopyFrom(packet.data, packet.size);
1856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    buffer->set_timestamp(ConvertFromTimeBase(
1866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        reader_->GetAVStreamForTesting()->time_base, packet.pts));
1876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    buffer->set_duration(ConvertFromTimeBase(
1886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        reader_->GetAVStreamForTesting()->time_base, packet.duration));
1896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Don't set discard padding for Opus, it already has discard behavior set
1916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // based on the codec delay in the AudioDecoderConfig.
1926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (GetParam().decoder_type == FFMPEG)
1936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      SetDiscardPadding(&packet, buffer, GetParam().samples_per_second);
1946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // DecodeBuffer() shouldn't need the original packet since it uses the copy.
1966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    av_free_packet(&packet);
1976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    DecodeBuffer(buffer);
1986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
1996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void Reset() {
2016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_FALSE(pending_reset_);
2026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    pending_reset_ = true;
2036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    decoder_->Reset(
2046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(&AudioDecoderTest::ResetFinished, base::Unretained(this)));
2056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
2066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_FALSE(pending_reset_);
2076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void Seek(base::TimeDelta seek_time) {
2106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    Reset();
2116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    decoded_audio_.clear();
2126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_TRUE(reader_->SeekForTesting(seek_time));
2136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void OnDecoderOutput(const scoped_refptr<AudioBuffer>& buffer) {
2166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_FALSE(buffer->end_of_stream());
2176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    decoded_audio_.push_back(buffer);
2186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void DecodeFinished(AudioDecoder::Status status) {
2216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_TRUE(pending_decode_);
2226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_FALSE(pending_reset_);
2236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    pending_decode_ = false;
2246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    last_decode_status_ = status;
2256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void ResetFinished() {
2286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_TRUE(pending_reset_);
2296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_FALSE(pending_decode_);
2306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    pending_reset_ = false;
2316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Generates an MD5 hash of the audio signal.  Should not be used for checks
2346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // across platforms as audio varies slightly across platforms.
2356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string GetDecodedAudioMD5(size_t i) {
2366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    CHECK_LT(i, decoded_audio_.size());
2376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const scoped_refptr<AudioBuffer>& buffer = decoded_audio_[i];
2386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<AudioBus> output =
2406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        AudioBus::Create(buffer->channel_count(), buffer->frame_count());
2416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    buffer->ReadFrames(buffer->frame_count(), 0, 0, output.get());
2426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::MD5Context context;
2446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::MD5Init(&context);
2456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    for (int ch = 0; ch < output->channels(); ++ch) {
2466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      base::MD5Update(
2476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          &context,
2486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          base::StringPiece(reinterpret_cast<char*>(output->channel(ch)),
2496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            output->frames() * sizeof(*output->channel(ch))));
2506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
2516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::MD5Digest digest;
2526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::MD5Final(&digest, &context);
2536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return base::MD5DigestToBase16(digest);
2546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  void ExpectDecodedAudio(size_t i, const std::string& exact_hash) {
2576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    CHECK_LT(i, decoded_audio_.size());
2586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const scoped_refptr<AudioBuffer>& buffer = decoded_audio_[i];
2596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const DecodedBufferExpectations& sample_info = GetParam().expectations[i];
2616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(sample_info.timestamp, buffer->timestamp().InMicroseconds());
2626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(sample_info.duration, buffer->duration().InMicroseconds());
2636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_FALSE(buffer->end_of_stream());
2646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    scoped_ptr<AudioBus> output =
2666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        AudioBus::Create(buffer->channel_count(), buffer->frame_count());
2676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    buffer->ReadFrames(buffer->frame_count(), 0, 0, output.get());
2686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Generate a lossy hash of the audio used for comparison across platforms.
2706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    AudioHash audio_hash;
2716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    audio_hash.Update(output.get(), output->frames());
2726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    EXPECT_EQ(sample_info.hash, audio_hash.ToString());
2736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    if (!exact_hash.empty()) {
2756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      EXPECT_EQ(exact_hash, GetDecodedAudioMD5(i));
2766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      // Verify different hashes are being generated.  None of our test data
2786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      // files have audio that hashes out exactly the same.
2796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      if (i > 0)
2806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        EXPECT_NE(exact_hash, GetDecodedAudioMD5(i - 1));
2816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
2826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  size_t decoded_audio_size() const { return decoded_audio_.size(); }
2856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::TimeDelta start_timestamp() const { return start_timestamp_; }
2866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const scoped_refptr<AudioBuffer>& decoded_audio(size_t i) {
2876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return decoded_audio_[i];
2886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AudioDecoder::Status last_decode_status() const {
2906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return last_decode_status_;
2916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
2926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) private:
2946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::MessageLoop message_loop_;
2956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_refptr<DecoderBuffer> data_;
2966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<InMemoryUrlProtocol> protocol_;
2976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<AudioFileReader> reader_;
2986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
2996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<AudioDecoder> decoder_;
3006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  bool pending_decode_;
3016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  bool pending_reset_;
3026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AudioDecoder::Status last_decode_status_;
3036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::deque<scoped_refptr<AudioBuffer> > decoded_audio_;
3056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::TimeDelta start_timestamp_;
3066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AudioDecoderTest);
3086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
3096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class OpusAudioDecoderBehavioralTest : public AudioDecoderTest {};
3116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class FFmpegAudioDecoderBehavioralTest : public AudioDecoderTest {};
3126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(AudioDecoderTest, Initialize) {
3146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(Initialize());
3156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
3166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Verifies decode audio as well as the Decode() -> Reset() sequence.
3186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(AudioDecoderTest, ProduceAudioSamples) {
3196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(Initialize());
3206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Run the test multiple times with a seek back to the beginning in between.
3226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::vector<std::string> decoded_audio_md5_hashes;
3236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
3246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    for (size_t j = 0; j < kDecodeRuns; ++j) {
3256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      do {
3266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        Decode();
3276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        ASSERT_EQ(last_decode_status(), AudioDecoder::kOk);
3286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        // Some codecs have a multiple buffer delay and require an extra
3296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        // Decode() step to extract the desired number of output buffers.
3306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      } while (j == 0 && decoded_audio_size() == 0);
3316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      // On the first pass record the exact MD5 hash for each decoded buffer.
3336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      if (i == 0)
3346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j));
3356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
3366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_EQ(kDecodeRuns, decoded_audio_size());
3386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // On the first pass verify the basic audio hash and sample info.  On the
3406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // second, verify the exact MD5 sum for each packet.  It shouldn't change.
3416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    for (size_t j = 0; j < kDecodeRuns; ++j) {
3426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j));
3436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]);
3446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    }
3456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SendEndOfStream();
3476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    ASSERT_EQ(kDecodeRuns, decoded_audio_size());
3486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Seek back to the beginning.  Calls Reset() on the decoder.
3506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    Seek(start_timestamp());
3516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
3526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
3536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
354116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_P(AudioDecoderTest, Decode) {
3556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(Initialize());
3566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  Decode();
3576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(AudioDecoder::kOk, last_decode_status());
3586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
3596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
360116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_P(AudioDecoderTest, Reset) {
3616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(Initialize());
3626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  Reset();
3636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
3646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(AudioDecoderTest, NoTimestamp) {
3666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(Initialize());
3676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));
3686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  buffer->set_timestamp(kNoTimestamp());
3696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DecodeBuffer(buffer);
3706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(AudioDecoder::kDecodeError, last_decode_status());
3716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
3726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(OpusAudioDecoderBehavioralTest, InitializeWithNoCodecDelay) {
3746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(GetParam().decoder_type, OPUS);
3756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AudioDecoderConfig decoder_config;
3766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  decoder_config.Initialize(kCodecOpus,
3776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            kSampleFormatF32,
3786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            CHANNEL_LAYOUT_STEREO,
3796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            48000,
3806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            kOpusExtraData,
3816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            ARRAYSIZE_UNSAFE(kOpusExtraData),
3826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            false,
3836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            false,
3846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            base::TimeDelta::FromMilliseconds(80),
3856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            0);
3866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  InitializeDecoder(decoder_config);
3876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
3886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(OpusAudioDecoderBehavioralTest, InitializeWithBadCodecDelay) {
3906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(GetParam().decoder_type, OPUS);
3916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  AudioDecoderConfig decoder_config;
3926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  decoder_config.Initialize(
3936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kCodecOpus,
3946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kSampleFormatF32,
3956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      CHANNEL_LAYOUT_STEREO,
3966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      48000,
3976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kOpusExtraData,
3986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ARRAYSIZE_UNSAFE(kOpusExtraData),
3996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      false,
4006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      false,
4016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(80),
4026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      // Use a different codec delay than in the extradata.
4036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      100);
4046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  InitializeDecoderWithStatus(decoder_config, DECODER_ERROR_NOT_SUPPORTED);
4056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
4066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(FFmpegAudioDecoderBehavioralTest, InitializeWithBadConfig) {
4086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const AudioDecoderConfig decoder_config(kCodecVorbis,
4096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                          kSampleFormatF32,
4106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                          CHANNEL_LAYOUT_STEREO,
4116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                          // Invalid sample rate of zero.
4126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                          0,
4136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                          NULL,
4146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                          0,
4156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                          false);
4166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  InitializeDecoderWithStatus(decoder_config, DECODER_ERROR_NOT_SUPPORTED);
4176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
4186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kSfxOpusExpectations[] = {
4206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {0, 13500, "-2.70,-1.41,-0.78,-1.27,-2.56,-3.73,"},
4216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {13500, 20000, "5.48,5.93,6.04,5.83,5.54,5.45,"},
4226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {33500, 20000, "-3.45,-3.35,-3.57,-4.12,-4.74,-5.14,"},
4236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kBearOpusExpectations[] = {
4266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {500, 3500, "-0.26,0.87,1.36,0.84,-0.30,-1.22,"},
4276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {4000, 10000, "0.09,0.23,0.21,0.03,-0.17,-0.24,"},
4286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {14000, 10000, "0.10,0.24,0.23,0.04,-0.14,-0.23,"},
4296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecoderTestData kOpusTests[] = {
4326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {OPUS, kCodecOpus, "sfx-opus.ogg", kSfxOpusExpectations, -312, 48000,
4336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_MONO},
4346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {OPUS, kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
4356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_STEREO},
4366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Dummy data for behavioral tests.
4396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecoderTestData kOpusBehavioralTest[] = {
4406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {OPUS, kUnknownAudioCodec, "", NULL, 0, 0, CHANNEL_LAYOUT_NONE},
4416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(OpusAudioDecoderTest,
4446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        AudioDecoderTest,
4456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        testing::ValuesIn(kOpusTests));
4466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(OpusAudioDecoderBehavioralTest,
4476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        OpusAudioDecoderBehavioralTest,
4486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        testing::ValuesIn(kOpusBehavioralTest));
4496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
4516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kSfxMp3Expectations[] = {
4526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {0, 1065, "2.81,3.99,4.53,4.10,3.08,2.46,"},
4536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {1065, 26122, "-3.81,-4.14,-3.90,-3.36,-3.03,-3.23,"},
4546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {27188, 26122, "4.24,3.95,4.22,4.78,5.13,4.93,"},
4556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kSfxAdtsExpectations[] = {
4586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {0, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"},
4596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {23219, 23219, "0.54,0.88,2.19,3.54,3.24,1.63,"},
4606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {46439, 23219, "1.42,1.69,2.95,4.23,4.02,2.36,"},
4616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif
4636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(OS_CHROMEOS)
4656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kSfxFlacExpectations[] = {
4666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {0, 104489, "-2.42,-1.12,0.71,1.70,1.09,-0.68,"},
4676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {104489, 104489, "-1.99,-0.67,1.18,2.19,1.60,-0.16,"},
4686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {208979, 79433, "2.84,2.70,3.23,4.06,4.59,4.44,"},
4696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif
4716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kSfxWaveExpectations[] = {
4736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {0, 23219, "-1.23,-0.87,0.47,1.85,1.88,0.29,"},
4746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {23219, 23219, "0.75,1.10,2.43,3.78,3.53,1.93,"},
4756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {46439, 23219, "1.27,1.56,2.83,4.13,3.87,2.23,"},
4766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kFourChannelWaveExpectations[] = {
4796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {0, 11609, "-1.68,1.68,0.89,-3.45,1.52,1.15,"},
4806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {11609, 11609, "43.26,9.06,18.27,35.98,19.45,7.46,"},
4816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {23219, 11609, "36.37,9.45,16.04,27.67,18.81,10.15,"},
4826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kSfxOggExpectations[] = {
4856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {0, 13061, "-0.33,1.25,2.86,3.26,2.09,0.14,"},
4866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {13061, 23219, "-2.79,-2.42,-1.06,0.33,0.93,-0.64,"},
4876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {36281, 23219, "-1.19,-0.80,0.57,1.97,2.08,0.51,"},
4886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecodedBufferExpectations kBearOgvExpectations[] = {
4916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {0, 13061, "-1.25,0.10,2.11,2.29,1.50,-0.68,"},
4926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {13061, 23219, "-1.80,-1.41,-0.13,1.30,1.65,0.01,"},
4936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {36281, 23219, "-1.43,-1.25,0.11,1.29,1.86,0.14,"},
4946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
4956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
4966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecoderTestData kFFmpegTests[] = {
4976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(USE_PROPRIETARY_CODECS)
4986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {FFMPEG, kCodecMP3, "sfx.mp3", kSfxMp3Expectations, 0, 44100,
4996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_MONO},
5006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {FFMPEG, kCodecAAC, "sfx.adts", kSfxAdtsExpectations, 0, 44100,
5016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_MONO},
5026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif
5036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#if defined(OS_CHROMEOS)
5046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {FFMPEG, kCodecFLAC, "sfx.flac", kSfxFlacExpectations, 0, 44100,
5056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_MONO},
5066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#endif
5076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {FFMPEG, kCodecPCM, "sfx_f32le.wav", kSfxWaveExpectations, 0, 44100,
5086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_MONO},
5096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {FFMPEG, kCodecPCM, "4ch.wav", kFourChannelWaveExpectations, 0, 44100,
5106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_QUAD},
5116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {FFMPEG, kCodecVorbis, "sfx.ogg", kSfxOggExpectations, 0, 44100,
5126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_MONO},
5136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Note: bear.ogv is incorrectly muxed such that valid samples are given
5146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // negative timestamps, this marks them for discard per the ogg vorbis spec.
5156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {FFMPEG, kCodecVorbis, "bear.ogv", kBearOgvExpectations, -704, 44100,
5166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)     CHANNEL_LAYOUT_STEREO},
5176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
5186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
5196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Dummy data for behavioral tests.
5206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)const DecoderTestData kFFmpegBehavioralTest[] = {
5216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    {FFMPEG, kUnknownAudioCodec, "", NULL, 0, 0, CHANNEL_LAYOUT_NONE},
5226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)};
5236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
5246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderTest,
5256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        AudioDecoderTest,
5266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        testing::ValuesIn(kFFmpegTests));
5276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderBehavioralTest,
5286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        FFmpegAudioDecoderBehavioralTest,
5296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                        testing::ValuesIn(kFFmpegBehavioralTest));
5306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
5316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}  // namespace media
532