Home | History | Annotate | Download | only in filters
      1 // Copyright (c) 2012 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/message_loop/message_loop.h"
      9 #include "base/run_loop.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "media/base/audio_buffer.h"
     12 #include "media/base/decoder_buffer.h"
     13 #include "media/base/mock_filters.h"
     14 #include "media/base/test_data_util.h"
     15 #include "media/base/test_helpers.h"
     16 #include "media/ffmpeg/ffmpeg_common.h"
     17 #include "media/filters/ffmpeg_audio_decoder.h"
     18 #include "media/filters/ffmpeg_glue.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 using ::testing::_;
     22 using ::testing::StrictMock;
     23 
     24 namespace media {
     25 
     26 class FFmpegAudioDecoderTest : public testing::Test {
     27  public:
     28   FFmpegAudioDecoderTest()
     29       : decoder_(new FFmpegAudioDecoder(message_loop_.message_loop_proxy(),
     30                                         LogCB())),
     31         pending_decode_(false),
     32         pending_reset_(false),
     33         last_decode_status_(AudioDecoder::kOk) {
     34     FFmpegGlue::InitializeFFmpeg();
     35 
     36     vorbis_extradata_ = ReadTestDataFile("vorbis-extradata");
     37 
     38     // Refer to media/test/data/README for details on vorbis test data.
     39     for (int i = 0; i < 4; ++i) {
     40       scoped_refptr<DecoderBuffer> buffer =
     41           ReadTestDataFile(base::StringPrintf("vorbis-packet-%d", i));
     42 
     43       if (i < 3) {
     44         buffer->set_timestamp(base::TimeDelta());
     45       } else {
     46         buffer->set_timestamp(base::TimeDelta::FromMicroseconds(2902));
     47       }
     48 
     49       buffer->set_duration(base::TimeDelta());
     50       encoded_audio_.push_back(buffer);
     51     }
     52 
     53     // Push in an EOS buffer.
     54     encoded_audio_.push_back(DecoderBuffer::CreateEOSBuffer());
     55 
     56     Initialize();
     57   }
     58 
     59   virtual ~FFmpegAudioDecoderTest() {
     60     EXPECT_FALSE(pending_decode_);
     61     EXPECT_FALSE(pending_reset_);
     62   }
     63 
     64   void Initialize() {
     65     AudioDecoderConfig config(kCodecVorbis,
     66                               kSampleFormatPlanarF32,
     67                               CHANNEL_LAYOUT_STEREO,
     68                               44100,
     69                               vorbis_extradata_->data(),
     70                               vorbis_extradata_->data_size(),
     71                               false);  // Not encrypted.
     72     decoder_->Initialize(config,
     73                          NewExpectedStatusCB(PIPELINE_OK),
     74                          base::Bind(&FFmpegAudioDecoderTest::OnDecoderOutput,
     75                                     base::Unretained(this)));
     76     base::RunLoop().RunUntilIdle();
     77   }
     78 
     79   void SatisfyPendingDecode() {
     80     base::RunLoop().RunUntilIdle();
     81   }
     82 
     83   void Decode() {
     84     pending_decode_ = true;
     85     scoped_refptr<DecoderBuffer> buffer(encoded_audio_.front());
     86     encoded_audio_.pop_front();
     87     decoder_->Decode(buffer,
     88                      base::Bind(&FFmpegAudioDecoderTest::DecodeFinished,
     89                                 base::Unretained(this)));
     90     base::RunLoop().RunUntilIdle();
     91     EXPECT_FALSE(pending_decode_);
     92     EXPECT_EQ(AudioDecoder::kOk, last_decode_status_);
     93   }
     94 
     95   void Reset() {
     96     pending_reset_ = true;
     97     decoder_->Reset(base::Bind(
     98         &FFmpegAudioDecoderTest::ResetFinished, base::Unretained(this)));
     99     base::RunLoop().RunUntilIdle();
    100   }
    101 
    102   void Stop() {
    103     decoder_->Stop();
    104     base::RunLoop().RunUntilIdle();
    105   }
    106 
    107   void OnDecoderOutput(const scoped_refptr<AudioBuffer>& buffer) {
    108     EXPECT_FALSE(buffer->end_of_stream());
    109     decoded_audio_.push_back(buffer);
    110   }
    111 
    112   void DecodeFinished(AudioDecoder::Status status) {
    113     EXPECT_TRUE(pending_decode_);
    114     pending_decode_ = false;
    115 
    116     last_decode_status_ = status;
    117   }
    118 
    119   void ResetFinished() {
    120     EXPECT_TRUE(pending_reset_);
    121     // Reset should always finish after Decode.
    122     EXPECT_FALSE(pending_decode_);
    123 
    124     pending_reset_ = false;
    125   }
    126 
    127   void ExpectDecodedAudio(size_t i, int64 timestamp, int64 duration) {
    128     EXPECT_LT(i, decoded_audio_.size());
    129     EXPECT_EQ(timestamp, decoded_audio_[i]->timestamp().InMicroseconds());
    130     EXPECT_EQ(duration, decoded_audio_[i]->duration().InMicroseconds());
    131   }
    132 
    133   base::MessageLoop message_loop_;
    134   scoped_ptr<FFmpegAudioDecoder> decoder_;
    135   bool pending_decode_;
    136   bool pending_reset_;
    137 
    138   scoped_refptr<DecoderBuffer> vorbis_extradata_;
    139 
    140   std::deque<scoped_refptr<DecoderBuffer> > encoded_audio_;
    141   std::deque<scoped_refptr<AudioBuffer> > decoded_audio_;
    142   AudioDecoder::Status last_decode_status_;
    143 };
    144 
    145 TEST_F(FFmpegAudioDecoderTest, Initialize) {
    146   AudioDecoderConfig config(kCodecVorbis,
    147                             kSampleFormatPlanarF32,
    148                             CHANNEL_LAYOUT_STEREO,
    149                             44100,
    150                             vorbis_extradata_->data(),
    151                             vorbis_extradata_->data_size(),
    152                             false);  // Not encrypted.
    153   Stop();
    154 }
    155 
    156 TEST_F(FFmpegAudioDecoderTest, ProduceAudioSamples) {
    157   // Vorbis requires N+1 packets to produce audio data for N packets.
    158   //
    159   // This will should result in the demuxer receiving three reads for two
    160   // requests to produce audio samples.
    161   Decode();
    162   Decode();
    163   Decode();
    164   Decode();
    165 
    166   ASSERT_EQ(3u, decoded_audio_.size());
    167   ExpectDecodedAudio(0, 0, 2902);
    168   ExpectDecodedAudio(1, 2902, 13061);
    169   ExpectDecodedAudio(2, 15963, 23219);
    170 
    171   // Call one more time with EOS.
    172   Decode();
    173   ASSERT_EQ(3u, decoded_audio_.size());
    174   Stop();
    175 }
    176 
    177 TEST_F(FFmpegAudioDecoderTest, PendingDecode_Stop) {
    178   Decode();
    179   Stop();
    180   SatisfyPendingDecode();
    181 }
    182 
    183 TEST_F(FFmpegAudioDecoderTest, PendingDecode_Reset) {
    184   Decode();
    185   Reset();
    186   SatisfyPendingDecode();
    187   Stop();
    188 }
    189 
    190 TEST_F(FFmpegAudioDecoderTest, PendingDecode_ResetStop) {
    191   Decode();
    192   Reset();
    193   Stop();
    194   SatisfyPendingDecode();
    195 }
    196 
    197 }  // namespace media
    198