12f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)// found in the LICENSE file.
42f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
52f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include <deque>
62f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
72f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "base/bind.h"
82f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "base/message_loop/message_loop.h"
92f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "base/run_loop.h"
102f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "base/strings/stringprintf.h"
112f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "media/base/audio_buffer.h"
122f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "media/base/decoder_buffer.h"
132f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "media/base/mock_filters.h"
142f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "media/base/test_data_util.h"
152f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "media/base/test_helpers.h"
162f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "media/ffmpeg/ffmpeg_common.h"
172f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "media/filters/ffmpeg_audio_decoder.h"
182f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "media/filters/ffmpeg_glue.h"
192f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
202f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
212f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)using ::testing::_;
222f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)using ::testing::StrictMock;
232f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
242f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)namespace media {
252f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
262f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)class FFmpegAudioDecoderTest : public testing::Test {
272f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles) public:
282f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  FFmpegAudioDecoderTest()
292f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)      : decoder_(new FFmpegAudioDecoder(message_loop_.message_loop_proxy(),
302f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                                        LogCB())),
312f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)        pending_decode_(false),
322f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)        pending_reset_(false),
332f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)        last_decode_status_(AudioDecoder::kOk) {
342f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    FFmpegGlue::InitializeFFmpeg();
352f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
362f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    vorbis_extradata_ = ReadTestDataFile("vorbis-extradata");
372f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
382f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    // Refer to media/test/data/README for details on vorbis test data.
392f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    for (int i = 0; i < 4; ++i) {
402f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)      scoped_refptr<DecoderBuffer> buffer =
412f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)          ReadTestDataFile(base::StringPrintf("vorbis-packet-%d", i));
422f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
432f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)      if (i < 3) {
442f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)        buffer->set_timestamp(base::TimeDelta());
452f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)      } else {
462f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)        buffer->set_timestamp(base::TimeDelta::FromMicroseconds(2902));
472f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)      }
482f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
492f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)      buffer->set_duration(base::TimeDelta());
502f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)      encoded_audio_.push_back(buffer);
512f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    }
522f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
532f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    // Push in an EOS buffer.
542f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    encoded_audio_.push_back(DecoderBuffer::CreateEOSBuffer());
552f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
562f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    Initialize();
572f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
582f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
592f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  virtual ~FFmpegAudioDecoderTest() {
602f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_FALSE(pending_decode_);
612f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_FALSE(pending_reset_);
622f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
632f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
642f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void Initialize() {
652f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    AudioDecoderConfig config(kCodecVorbis,
662f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                              kSampleFormatPlanarF32,
672f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                              CHANNEL_LAYOUT_STEREO,
682f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                              44100,
692f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                              vorbis_extradata_->data(),
702f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                              vorbis_extradata_->data_size(),
712f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                              false);  // Not encrypted.
722f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    decoder_->Initialize(config,
732f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                         NewExpectedStatusCB(PIPELINE_OK),
742f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                         base::Bind(&FFmpegAudioDecoderTest::OnDecoderOutput,
752f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                                    base::Unretained(this)));
762f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
772f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
782f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
792f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void SatisfyPendingDecode() {
802f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
812f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
822f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
832f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void Decode() {
842f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    pending_decode_ = true;
852f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    scoped_refptr<DecoderBuffer> buffer(encoded_audio_.front());
862f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    encoded_audio_.pop_front();
872f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    decoder_->Decode(buffer,
882f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                     base::Bind(&FFmpegAudioDecoderTest::DecodeFinished,
892f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                                base::Unretained(this)));
902f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
912f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_FALSE(pending_decode_);
922f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_EQ(AudioDecoder::kOk, last_decode_status_);
932f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
942f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
952f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void Reset() {
962f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    pending_reset_ = true;
972f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    decoder_->Reset(base::Bind(
982f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)        &FFmpegAudioDecoderTest::ResetFinished, base::Unretained(this)));
992f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
1002f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
1012f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1022f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void Stop() {
1032f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    decoder_->Stop();
1042f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
1052f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
1062f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1072f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void OnDecoderOutput(const scoped_refptr<AudioBuffer>& buffer) {
1082f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_FALSE(buffer->end_of_stream());
1092f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    decoded_audio_.push_back(buffer);
1102f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
1112f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1122f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void DecodeFinished(AudioDecoder::Status status) {
1132f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_TRUE(pending_decode_);
1142f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    pending_decode_ = false;
1152f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1162f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    last_decode_status_ = status;
1172f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
1182f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1192f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void ResetFinished() {
1202f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_TRUE(pending_reset_);
1212f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    // Reset should always finish after Decode.
1222f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_FALSE(pending_decode_);
1232f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1242f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    pending_reset_ = false;
1252f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
1262f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1272f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  void ExpectDecodedAudio(size_t i, int64 timestamp, int64 duration) {
1282f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_LT(i, decoded_audio_.size());
1292f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_EQ(timestamp, decoded_audio_[i]->timestamp().InMicroseconds());
1302f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)    EXPECT_EQ(duration, decoded_audio_[i]->duration().InMicroseconds());
1312f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  }
1322f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1332f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  base::MessageLoop message_loop_;
1342f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  scoped_ptr<FFmpegAudioDecoder> decoder_;
1352f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  bool pending_decode_;
1362f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  bool pending_reset_;
1372f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1382f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  scoped_refptr<DecoderBuffer> vorbis_extradata_;
1392f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1402f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  std::deque<scoped_refptr<DecoderBuffer> > encoded_audio_;
1412f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  std::deque<scoped_refptr<AudioBuffer> > decoded_audio_;
1422f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  AudioDecoder::Status last_decode_status_;
1432f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)};
1442f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1452f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)TEST_F(FFmpegAudioDecoderTest, Initialize) {
1462f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  AudioDecoderConfig config(kCodecVorbis,
1472f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                            kSampleFormatPlanarF32,
1482f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                            CHANNEL_LAYOUT_STEREO,
1492f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                            44100,
1502f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                            vorbis_extradata_->data(),
1512f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                            vorbis_extradata_->data_size(),
1522f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)                            false);  // Not encrypted.
1532f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Stop();
1542f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)}
1552f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1562f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)TEST_F(FFmpegAudioDecoderTest, ProduceAudioSamples) {
1572f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  // Vorbis requires N+1 packets to produce audio data for N packets.
1582f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  //
1592f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  // This will should result in the demuxer receiving three reads for two
1602f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  // requests to produce audio samples.
1612f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Decode();
1622f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Decode();
1632f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Decode();
1642f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Decode();
1652f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1662f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  ASSERT_EQ(3u, decoded_audio_.size());
1672f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  ExpectDecodedAudio(0, 0, 2902);
1682f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  ExpectDecodedAudio(1, 2902, 13061);
1692f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  ExpectDecodedAudio(2, 15963, 23219);
1702f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1712f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  // Call one more time with EOS.
1722f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Decode();
1732f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  ASSERT_EQ(3u, decoded_audio_.size());
1742f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Stop();
1752f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)}
1762f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1772f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)TEST_F(FFmpegAudioDecoderTest, PendingDecode_Stop) {
1782f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Decode();
1792f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Stop();
1802f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  SatisfyPendingDecode();
1812f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)}
1822f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1832f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)TEST_F(FFmpegAudioDecoderTest, PendingDecode_Reset) {
1842f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Decode();
1852f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Reset();
1862f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  SatisfyPendingDecode();
1872f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Stop();
1882f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)}
1892f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1902f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)TEST_F(FFmpegAudioDecoderTest, PendingDecode_ResetStop) {
1912f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Decode();
1922f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Reset();
1932f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  Stop();
1942f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  SatisfyPendingDecode();
1952f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)}
1962f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)
1972f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)}  // namespace media
198