Home | History | Annotate | Download | only in filters
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <deque>
      6 
      7 #include "base/bind.h"
      8 #include "base/format_macros.h"
      9 #include "base/md5.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/run_loop.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "base/sys_byteorder.h"
     14 #include "build/build_config.h"
     15 #include "media/base/audio_buffer.h"
     16 #include "media/base/audio_bus.h"
     17 #include "media/base/audio_hash.h"
     18 #include "media/base/decoder_buffer.h"
     19 #include "media/base/test_data_util.h"
     20 #include "media/base/test_helpers.h"
     21 #include "media/ffmpeg/ffmpeg_common.h"
     22 #include "media/filters/audio_file_reader.h"
     23 #include "media/filters/ffmpeg_audio_decoder.h"
     24 #include "media/filters/in_memory_url_protocol.h"
     25 #include "media/filters/opus_audio_decoder.h"
     26 #include "testing/gtest/include/gtest/gtest.h"
     27 
     28 namespace media {
     29 
     30 // The number of packets to read and then decode from each file.
     31 static const size_t kDecodeRuns = 3;
     32 static const uint8_t kOpusExtraData[] = {
     33     0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, 0x01, 0x02,
     34     // The next two bytes represent the codec delay.
     35     0x00, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00};
     36 
     37 enum AudioDecoderType {
     38   FFMPEG,
     39   OPUS,
     40 };
     41 
     42 struct DecodedBufferExpectations {
     43   const int64 timestamp;
     44   const int64 duration;
     45   const char* hash;
     46 };
     47 
     48 struct DecoderTestData {
     49   const AudioDecoderType decoder_type;
     50   const AudioCodec codec;
     51   const char* filename;
     52   const DecodedBufferExpectations* expectations;
     53   const int first_packet_pts;
     54   const int samples_per_second;
     55   const ChannelLayout channel_layout;
     56 };
     57 
     58 // Tells gtest how to print our DecoderTestData structure.
     59 std::ostream& operator<<(std::ostream& os, const DecoderTestData& data) {
     60   return os << data.filename;
     61 }
     62 
     63 // Marks negative timestamp buffers for discard or transfers FFmpeg's built in
     64 // discard metadata in favor of setting DiscardPadding on the DecoderBuffer.
     65 // Allows better testing of AudioDiscardHelper usage.
     66 static void SetDiscardPadding(AVPacket* packet,
     67                               const scoped_refptr<DecoderBuffer> buffer,
     68                               double samples_per_second) {
     69   // Discard negative timestamps.
     70   if (buffer->timestamp() + buffer->duration() < base::TimeDelta()) {
     71     buffer->set_discard_padding(
     72         std::make_pair(kInfiniteDuration(), base::TimeDelta()));
     73     return;
     74   }
     75   if (buffer->timestamp() < base::TimeDelta()) {
     76     buffer->set_discard_padding(
     77         std::make_pair(-buffer->timestamp(), base::TimeDelta()));
     78     return;
     79   }
     80 
     81   // If the timestamp is positive, try to use FFmpeg's discard data.
     82   int skip_samples_size = 0;
     83   const uint32* skip_samples_ptr =
     84       reinterpret_cast<const uint32*>(av_packet_get_side_data(
     85           packet, AV_PKT_DATA_SKIP_SAMPLES, &skip_samples_size));
     86   if (skip_samples_size < 4)
     87     return;
     88   buffer->set_discard_padding(std::make_pair(
     89       base::TimeDelta::FromSecondsD(base::ByteSwapToLE32(*skip_samples_ptr) /
     90                                     samples_per_second),
     91       base::TimeDelta()));
     92 }
     93 
     94 class AudioDecoderTest : public testing::TestWithParam<DecoderTestData> {
     95  public:
     96   AudioDecoderTest()
     97       : pending_decode_(false),
     98         pending_reset_(false),
     99         last_decode_status_(AudioDecoder::kDecodeError) {
    100     switch (GetParam().decoder_type) {
    101       case FFMPEG:
    102         decoder_.reset(new FFmpegAudioDecoder(
    103             message_loop_.message_loop_proxy(), LogCB()));
    104         break;
    105       case OPUS:
    106         decoder_.reset(
    107             new OpusAudioDecoder(message_loop_.message_loop_proxy()));
    108         break;
    109     }
    110   }
    111 
    112   virtual ~AudioDecoderTest() {
    113     EXPECT_FALSE(pending_decode_);
    114     EXPECT_FALSE(pending_reset_);
    115   }
    116 
    117  protected:
    118   void DecodeBuffer(const scoped_refptr<DecoderBuffer>& buffer) {
    119     ASSERT_FALSE(pending_decode_);
    120     pending_decode_ = true;
    121     last_decode_status_ = AudioDecoder::kDecodeError;
    122     decoder_->Decode(
    123         buffer,
    124         base::Bind(&AudioDecoderTest::DecodeFinished, base::Unretained(this)));
    125     base::RunLoop().RunUntilIdle();
    126     ASSERT_FALSE(pending_decode_);
    127   }
    128 
    129   void SendEndOfStream() {
    130     DecodeBuffer(DecoderBuffer::CreateEOSBuffer());
    131   }
    132 
    133   void Initialize() {
    134     // Load the test data file.
    135     data_ = ReadTestDataFile(GetParam().filename);
    136     protocol_.reset(
    137         new InMemoryUrlProtocol(data_->data(), data_->data_size(), false));
    138     reader_.reset(new AudioFileReader(protocol_.get()));
    139     ASSERT_TRUE(reader_->OpenDemuxerForTesting());
    140 
    141     // Load the first packet and check its timestamp.
    142     AVPacket packet;
    143     ASSERT_TRUE(reader_->ReadPacketForTesting(&packet));
    144     EXPECT_EQ(GetParam().first_packet_pts, packet.pts);
    145     start_timestamp_ = ConvertFromTimeBase(
    146         reader_->GetAVStreamForTesting()->time_base, packet.pts);
    147     av_free_packet(&packet);
    148 
    149     // Seek back to the beginning.
    150     ASSERT_TRUE(reader_->SeekForTesting(start_timestamp_));
    151 
    152     AudioDecoderConfig config;
    153     AVCodecContextToAudioDecoderConfig(
    154         reader_->codec_context_for_testing(), false, &config, false);
    155 
    156     EXPECT_EQ(GetParam().codec, config.codec());
    157     EXPECT_EQ(GetParam().samples_per_second, config.samples_per_second());
    158     EXPECT_EQ(GetParam().channel_layout, config.channel_layout());
    159 
    160     InitializeDecoder(config);
    161   }
    162 
    163   void InitializeDecoder(const AudioDecoderConfig& config) {
    164     InitializeDecoderWithStatus(config, PIPELINE_OK);
    165   }
    166 
    167   void InitializeDecoderWithStatus(const AudioDecoderConfig& config,
    168                                    PipelineStatus status) {
    169     decoder_->Initialize(
    170         config,
    171         NewExpectedStatusCB(status),
    172         base::Bind(&AudioDecoderTest::OnDecoderOutput, base::Unretained(this)));
    173     base::RunLoop().RunUntilIdle();
    174   }
    175 
    176   void Decode() {
    177     AVPacket packet;
    178     ASSERT_TRUE(reader_->ReadPacketForTesting(&packet));
    179 
    180     // Split out packet metadata before making a copy.
    181     av_packet_split_side_data(&packet);
    182 
    183     scoped_refptr<DecoderBuffer> buffer =
    184         DecoderBuffer::CopyFrom(packet.data, packet.size);
    185     buffer->set_timestamp(ConvertFromTimeBase(
    186         reader_->GetAVStreamForTesting()->time_base, packet.pts));
    187     buffer->set_duration(ConvertFromTimeBase(
    188         reader_->GetAVStreamForTesting()->time_base, packet.duration));
    189 
    190     // Don't set discard padding for Opus, it already has discard behavior set
    191     // based on the codec delay in the AudioDecoderConfig.
    192     if (GetParam().decoder_type == FFMPEG)
    193       SetDiscardPadding(&packet, buffer, GetParam().samples_per_second);
    194 
    195     // DecodeBuffer() shouldn't need the original packet since it uses the copy.
    196     av_free_packet(&packet);
    197     DecodeBuffer(buffer);
    198   }
    199 
    200   void Reset() {
    201     ASSERT_FALSE(pending_reset_);
    202     pending_reset_ = true;
    203     decoder_->Reset(
    204         base::Bind(&AudioDecoderTest::ResetFinished, base::Unretained(this)));
    205     base::RunLoop().RunUntilIdle();
    206     ASSERT_FALSE(pending_reset_);
    207   }
    208 
    209   void Seek(base::TimeDelta seek_time) {
    210     Reset();
    211     decoded_audio_.clear();
    212     ASSERT_TRUE(reader_->SeekForTesting(seek_time));
    213   }
    214 
    215   void OnDecoderOutput(const scoped_refptr<AudioBuffer>& buffer) {
    216     EXPECT_FALSE(buffer->end_of_stream());
    217     decoded_audio_.push_back(buffer);
    218   }
    219 
    220   void DecodeFinished(AudioDecoder::Status status) {
    221     EXPECT_TRUE(pending_decode_);
    222     EXPECT_FALSE(pending_reset_);
    223     pending_decode_ = false;
    224     last_decode_status_ = status;
    225   }
    226 
    227   void ResetFinished() {
    228     EXPECT_TRUE(pending_reset_);
    229     EXPECT_FALSE(pending_decode_);
    230     pending_reset_ = false;
    231   }
    232 
    233   // Generates an MD5 hash of the audio signal.  Should not be used for checks
    234   // across platforms as audio varies slightly across platforms.
    235   std::string GetDecodedAudioMD5(size_t i) {
    236     CHECK_LT(i, decoded_audio_.size());
    237     const scoped_refptr<AudioBuffer>& buffer = decoded_audio_[i];
    238 
    239     scoped_ptr<AudioBus> output =
    240         AudioBus::Create(buffer->channel_count(), buffer->frame_count());
    241     buffer->ReadFrames(buffer->frame_count(), 0, 0, output.get());
    242 
    243     base::MD5Context context;
    244     base::MD5Init(&context);
    245     for (int ch = 0; ch < output->channels(); ++ch) {
    246       base::MD5Update(
    247           &context,
    248           base::StringPiece(reinterpret_cast<char*>(output->channel(ch)),
    249                             output->frames() * sizeof(*output->channel(ch))));
    250     }
    251     base::MD5Digest digest;
    252     base::MD5Final(&digest, &context);
    253     return base::MD5DigestToBase16(digest);
    254   }
    255 
    256   void ExpectDecodedAudio(size_t i, const std::string& exact_hash) {
    257     CHECK_LT(i, decoded_audio_.size());
    258     const scoped_refptr<AudioBuffer>& buffer = decoded_audio_[i];
    259 
    260     const DecodedBufferExpectations& sample_info = GetParam().expectations[i];
    261     EXPECT_EQ(sample_info.timestamp, buffer->timestamp().InMicroseconds());
    262     EXPECT_EQ(sample_info.duration, buffer->duration().InMicroseconds());
    263     EXPECT_FALSE(buffer->end_of_stream());
    264 
    265     scoped_ptr<AudioBus> output =
    266         AudioBus::Create(buffer->channel_count(), buffer->frame_count());
    267     buffer->ReadFrames(buffer->frame_count(), 0, 0, output.get());
    268 
    269     // Generate a lossy hash of the audio used for comparison across platforms.
    270     AudioHash audio_hash;
    271     audio_hash.Update(output.get(), output->frames());
    272     EXPECT_EQ(sample_info.hash, audio_hash.ToString());
    273 
    274     if (!exact_hash.empty()) {
    275       EXPECT_EQ(exact_hash, GetDecodedAudioMD5(i));
    276 
    277       // Verify different hashes are being generated.  None of our test data
    278       // files have audio that hashes out exactly the same.
    279       if (i > 0)
    280         EXPECT_NE(exact_hash, GetDecodedAudioMD5(i - 1));
    281     }
    282   }
    283 
    284   size_t decoded_audio_size() const { return decoded_audio_.size(); }
    285   base::TimeDelta start_timestamp() const { return start_timestamp_; }
    286   const scoped_refptr<AudioBuffer>& decoded_audio(size_t i) {
    287     return decoded_audio_[i];
    288   }
    289   AudioDecoder::Status last_decode_status() const {
    290     return last_decode_status_;
    291   }
    292 
    293  private:
    294   base::MessageLoop message_loop_;
    295   scoped_refptr<DecoderBuffer> data_;
    296   scoped_ptr<InMemoryUrlProtocol> protocol_;
    297   scoped_ptr<AudioFileReader> reader_;
    298 
    299   scoped_ptr<AudioDecoder> decoder_;
    300   bool pending_decode_;
    301   bool pending_reset_;
    302   AudioDecoder::Status last_decode_status_;
    303 
    304   std::deque<scoped_refptr<AudioBuffer> > decoded_audio_;
    305   base::TimeDelta start_timestamp_;
    306 
    307   DISALLOW_COPY_AND_ASSIGN(AudioDecoderTest);
    308 };
    309 
    310 class OpusAudioDecoderBehavioralTest : public AudioDecoderTest {};
    311 class FFmpegAudioDecoderBehavioralTest : public AudioDecoderTest {};
    312 
    313 TEST_P(AudioDecoderTest, Initialize) {
    314   ASSERT_NO_FATAL_FAILURE(Initialize());
    315 }
    316 
    317 // Verifies decode audio as well as the Decode() -> Reset() sequence.
    318 TEST_P(AudioDecoderTest, ProduceAudioSamples) {
    319   ASSERT_NO_FATAL_FAILURE(Initialize());
    320 
    321   // Run the test multiple times with a seek back to the beginning in between.
    322   std::vector<std::string> decoded_audio_md5_hashes;
    323   for (int i = 0; i < 2; ++i) {
    324     for (size_t j = 0; j < kDecodeRuns; ++j) {
    325       do {
    326         Decode();
    327         ASSERT_EQ(last_decode_status(), AudioDecoder::kOk);
    328         // Some codecs have a multiple buffer delay and require an extra
    329         // Decode() step to extract the desired number of output buffers.
    330       } while (j == 0 && decoded_audio_size() == 0);
    331 
    332       // On the first pass record the exact MD5 hash for each decoded buffer.
    333       if (i == 0)
    334         decoded_audio_md5_hashes.push_back(GetDecodedAudioMD5(j));
    335     }
    336 
    337     ASSERT_EQ(kDecodeRuns, decoded_audio_size());
    338 
    339     // On the first pass verify the basic audio hash and sample info.  On the
    340     // second, verify the exact MD5 sum for each packet.  It shouldn't change.
    341     for (size_t j = 0; j < kDecodeRuns; ++j) {
    342       SCOPED_TRACE(base::StringPrintf("i = %d, j = %" PRIuS, i, j));
    343       ExpectDecodedAudio(j, i == 0 ? "" : decoded_audio_md5_hashes[j]);
    344     }
    345 
    346     SendEndOfStream();
    347     ASSERT_EQ(kDecodeRuns, decoded_audio_size());
    348 
    349     // Seek back to the beginning.  Calls Reset() on the decoder.
    350     Seek(start_timestamp());
    351   }
    352 }
    353 
    354 TEST_P(AudioDecoderTest, Decode) {
    355   ASSERT_NO_FATAL_FAILURE(Initialize());
    356   Decode();
    357   EXPECT_EQ(AudioDecoder::kOk, last_decode_status());
    358 }
    359 
    360 TEST_P(AudioDecoderTest, Reset) {
    361   ASSERT_NO_FATAL_FAILURE(Initialize());
    362   Reset();
    363 }
    364 
    365 TEST_P(AudioDecoderTest, NoTimestamp) {
    366   ASSERT_NO_FATAL_FAILURE(Initialize());
    367   scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));
    368   buffer->set_timestamp(kNoTimestamp());
    369   DecodeBuffer(buffer);
    370   EXPECT_EQ(AudioDecoder::kDecodeError, last_decode_status());
    371 }
    372 
    373 TEST_P(OpusAudioDecoderBehavioralTest, InitializeWithNoCodecDelay) {
    374   ASSERT_EQ(GetParam().decoder_type, OPUS);
    375   AudioDecoderConfig decoder_config;
    376   decoder_config.Initialize(kCodecOpus,
    377                             kSampleFormatF32,
    378                             CHANNEL_LAYOUT_STEREO,
    379                             48000,
    380                             kOpusExtraData,
    381                             ARRAYSIZE_UNSAFE(kOpusExtraData),
    382                             false,
    383                             false,
    384                             base::TimeDelta::FromMilliseconds(80),
    385                             0);
    386   InitializeDecoder(decoder_config);
    387 }
    388 
    389 TEST_P(OpusAudioDecoderBehavioralTest, InitializeWithBadCodecDelay) {
    390   ASSERT_EQ(GetParam().decoder_type, OPUS);
    391   AudioDecoderConfig decoder_config;
    392   decoder_config.Initialize(
    393       kCodecOpus,
    394       kSampleFormatF32,
    395       CHANNEL_LAYOUT_STEREO,
    396       48000,
    397       kOpusExtraData,
    398       ARRAYSIZE_UNSAFE(kOpusExtraData),
    399       false,
    400       false,
    401       base::TimeDelta::FromMilliseconds(80),
    402       // Use a different codec delay than in the extradata.
    403       100);
    404   InitializeDecoderWithStatus(decoder_config, DECODER_ERROR_NOT_SUPPORTED);
    405 }
    406 
    407 TEST_P(FFmpegAudioDecoderBehavioralTest, InitializeWithBadConfig) {
    408   const AudioDecoderConfig decoder_config(kCodecVorbis,
    409                                           kSampleFormatF32,
    410                                           CHANNEL_LAYOUT_STEREO,
    411                                           // Invalid sample rate of zero.
    412                                           0,
    413                                           NULL,
    414                                           0,
    415                                           false);
    416   InitializeDecoderWithStatus(decoder_config, DECODER_ERROR_NOT_SUPPORTED);
    417 }
    418 
    419 const DecodedBufferExpectations kSfxOpusExpectations[] = {
    420     {0, 13500, "-2.70,-1.41,-0.78,-1.27,-2.56,-3.73,"},
    421     {13500, 20000, "5.48,5.93,6.04,5.83,5.54,5.45,"},
    422     {33500, 20000, "-3.45,-3.35,-3.57,-4.12,-4.74,-5.14,"},
    423 };
    424 
    425 const DecodedBufferExpectations kBearOpusExpectations[] = {
    426     {500, 3500, "-0.26,0.87,1.36,0.84,-0.30,-1.22,"},
    427     {4000, 10000, "0.09,0.23,0.21,0.03,-0.17,-0.24,"},
    428     {14000, 10000, "0.10,0.24,0.23,0.04,-0.14,-0.23,"},
    429 };
    430 
    431 const DecoderTestData kOpusTests[] = {
    432     {OPUS, kCodecOpus, "sfx-opus.ogg", kSfxOpusExpectations, -312, 48000,
    433      CHANNEL_LAYOUT_MONO},
    434     {OPUS, kCodecOpus, "bear-opus.ogg", kBearOpusExpectations, 24, 48000,
    435      CHANNEL_LAYOUT_STEREO},
    436 };
    437 
    438 // Dummy data for behavioral tests.
    439 const DecoderTestData kOpusBehavioralTest[] = {
    440     {OPUS, kUnknownAudioCodec, "", NULL, 0, 0, CHANNEL_LAYOUT_NONE},
    441 };
    442 
    443 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderTest,
    444                         AudioDecoderTest,
    445                         testing::ValuesIn(kOpusTests));
    446 INSTANTIATE_TEST_CASE_P(OpusAudioDecoderBehavioralTest,
    447                         OpusAudioDecoderBehavioralTest,
    448                         testing::ValuesIn(kOpusBehavioralTest));
    449 
    450 #if defined(USE_PROPRIETARY_CODECS)
    451 const DecodedBufferExpectations kSfxMp3Expectations[] = {
    452     {0, 1065, "2.81,3.99,4.53,4.10,3.08,2.46,"},
    453     {1065, 26122, "-3.81,-4.14,-3.90,-3.36,-3.03,-3.23,"},
    454     {27188, 26122, "4.24,3.95,4.22,4.78,5.13,4.93,"},
    455 };
    456 
    457 const DecodedBufferExpectations kSfxAdtsExpectations[] = {
    458     {0, 23219, "-1.90,-1.53,-0.15,1.28,1.23,-0.33,"},
    459     {23219, 23219, "0.54,0.88,2.19,3.54,3.24,1.63,"},
    460     {46439, 23219, "1.42,1.69,2.95,4.23,4.02,2.36,"},
    461 };
    462 #endif
    463 
    464 #if defined(OS_CHROMEOS)
    465 const DecodedBufferExpectations kSfxFlacExpectations[] = {
    466     {0, 104489, "-2.42,-1.12,0.71,1.70,1.09,-0.68,"},
    467     {104489, 104489, "-1.99,-0.67,1.18,2.19,1.60,-0.16,"},
    468     {208979, 79433, "2.84,2.70,3.23,4.06,4.59,4.44,"},
    469 };
    470 #endif
    471 
    472 const DecodedBufferExpectations kSfxWaveExpectations[] = {
    473     {0, 23219, "-1.23,-0.87,0.47,1.85,1.88,0.29,"},
    474     {23219, 23219, "0.75,1.10,2.43,3.78,3.53,1.93,"},
    475     {46439, 23219, "1.27,1.56,2.83,4.13,3.87,2.23,"},
    476 };
    477 
    478 const DecodedBufferExpectations kFourChannelWaveExpectations[] = {
    479     {0, 11609, "-1.68,1.68,0.89,-3.45,1.52,1.15,"},
    480     {11609, 11609, "43.26,9.06,18.27,35.98,19.45,7.46,"},
    481     {23219, 11609, "36.37,9.45,16.04,27.67,18.81,10.15,"},
    482 };
    483 
    484 const DecodedBufferExpectations kSfxOggExpectations[] = {
    485     {0, 13061, "-0.33,1.25,2.86,3.26,2.09,0.14,"},
    486     {13061, 23219, "-2.79,-2.42,-1.06,0.33,0.93,-0.64,"},
    487     {36281, 23219, "-1.19,-0.80,0.57,1.97,2.08,0.51,"},
    488 };
    489 
    490 const DecodedBufferExpectations kBearOgvExpectations[] = {
    491     {0, 13061, "-1.25,0.10,2.11,2.29,1.50,-0.68,"},
    492     {13061, 23219, "-1.80,-1.41,-0.13,1.30,1.65,0.01,"},
    493     {36281, 23219, "-1.43,-1.25,0.11,1.29,1.86,0.14,"},
    494 };
    495 
    496 const DecoderTestData kFFmpegTests[] = {
    497 #if defined(USE_PROPRIETARY_CODECS)
    498     {FFMPEG, kCodecMP3, "sfx.mp3", kSfxMp3Expectations, 0, 44100,
    499      CHANNEL_LAYOUT_MONO},
    500     {FFMPEG, kCodecAAC, "sfx.adts", kSfxAdtsExpectations, 0, 44100,
    501      CHANNEL_LAYOUT_MONO},
    502 #endif
    503 #if defined(OS_CHROMEOS)
    504     {FFMPEG, kCodecFLAC, "sfx.flac", kSfxFlacExpectations, 0, 44100,
    505      CHANNEL_LAYOUT_MONO},
    506 #endif
    507     {FFMPEG, kCodecPCM, "sfx_f32le.wav", kSfxWaveExpectations, 0, 44100,
    508      CHANNEL_LAYOUT_MONO},
    509     {FFMPEG, kCodecPCM, "4ch.wav", kFourChannelWaveExpectations, 0, 44100,
    510      CHANNEL_LAYOUT_QUAD},
    511     {FFMPEG, kCodecVorbis, "sfx.ogg", kSfxOggExpectations, 0, 44100,
    512      CHANNEL_LAYOUT_MONO},
    513     // Note: bear.ogv is incorrectly muxed such that valid samples are given
    514     // negative timestamps, this marks them for discard per the ogg vorbis spec.
    515     {FFMPEG, kCodecVorbis, "bear.ogv", kBearOgvExpectations, -704, 44100,
    516      CHANNEL_LAYOUT_STEREO},
    517 };
    518 
    519 // Dummy data for behavioral tests.
    520 const DecoderTestData kFFmpegBehavioralTest[] = {
    521     {FFMPEG, kUnknownAudioCodec, "", NULL, 0, 0, CHANNEL_LAYOUT_NONE},
    522 };
    523 
    524 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderTest,
    525                         AudioDecoderTest,
    526                         testing::ValuesIn(kFFmpegTests));
    527 INSTANTIATE_TEST_CASE_P(FFmpegAudioDecoderBehavioralTest,
    528                         FFmpegAudioDecoderBehavioralTest,
    529                         testing::ValuesIn(kFFmpegBehavioralTest));
    530 
    531 }  // namespace media
    532