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 "base/bind.h"
      6 #include "base/callback_helpers.h"
      7 #include "base/gtest_prod_util.h"
      8 #include "base/memory/scoped_vector.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/stl_util.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "media/base/audio_buffer.h"
     13 #include "media/base/audio_timestamp_helper.h"
     14 #include "media/base/gmock_callback_support.h"
     15 #include "media/base/mock_audio_renderer_sink.h"
     16 #include "media/base/mock_filters.h"
     17 #include "media/base/test_helpers.h"
     18 #include "media/filters/audio_renderer_impl.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 using ::base::Time;
     22 using ::base::TimeTicks;
     23 using ::base::TimeDelta;
     24 using ::testing::_;
     25 using ::testing::AnyNumber;
     26 using ::testing::Invoke;
     27 using ::testing::Return;
     28 using ::testing::NiceMock;
     29 using ::testing::StrictMock;
     30 
     31 namespace media {
     32 
     33 // Constants to specify the type of audio data used.
     34 static AudioCodec kCodec = kCodecVorbis;
     35 static SampleFormat kSampleFormat = kSampleFormatPlanarF32;
     36 static ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
     37 static int kChannels = ChannelLayoutToChannelCount(kChannelLayout);
     38 static int kSamplesPerSecond = 44100;
     39 
     40 // Constants for distinguishing between muted audio and playing audio when using
     41 // ConsumeBufferedData(). Must match the type needed by kSampleFormat.
     42 static float kMutedAudio = 0.0f;
     43 static float kPlayingAudio = 0.5f;
     44 
     45 class AudioRendererImplTest : public ::testing::Test {
     46  public:
     47   // Give the decoder some non-garbage media properties.
     48   AudioRendererImplTest()
     49       : demuxer_stream_(DemuxerStream::AUDIO),
     50         decoder_(new MockAudioDecoder()) {
     51     AudioDecoderConfig audio_config(kCodec,
     52                                     kSampleFormat,
     53                                     kChannelLayout,
     54                                     kSamplesPerSecond,
     55                                     NULL,
     56                                     0,
     57                                     false);
     58     demuxer_stream_.set_audio_decoder_config(audio_config);
     59 
     60     // Used to save callbacks and run them at a later time.
     61     EXPECT_CALL(*decoder_, Read(_))
     62         .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ReadDecoder));
     63 
     64     // Set up audio properties.
     65     EXPECT_CALL(*decoder_, bits_per_channel())
     66         .WillRepeatedly(Return(audio_config.bits_per_channel()));
     67     EXPECT_CALL(*decoder_, channel_layout())
     68         .WillRepeatedly(Return(audio_config.channel_layout()));
     69     EXPECT_CALL(*decoder_, samples_per_second())
     70         .WillRepeatedly(Return(audio_config.samples_per_second()));
     71 
     72     ScopedVector<AudioDecoder> decoders;
     73     decoders.push_back(decoder_);
     74 
     75     renderer_.reset(new AudioRendererImpl(
     76         message_loop_.message_loop_proxy(),
     77         new NiceMock<MockAudioRendererSink>(),
     78         decoders.Pass(),
     79         SetDecryptorReadyCB(),
     80         false));
     81 
     82     // Stub out time.
     83     renderer_->set_now_cb_for_testing(base::Bind(
     84         &AudioRendererImplTest::GetTime, base::Unretained(this)));
     85   }
     86 
     87   virtual ~AudioRendererImplTest() {
     88     SCOPED_TRACE("~AudioRendererImplTest()");
     89     WaitableMessageLoopEvent event;
     90     renderer_->Stop(event.GetClosure());
     91     event.RunAndWait();
     92   }
     93 
     94   void ExpectUnsupportedAudioDecoder() {
     95     EXPECT_CALL(*decoder_, Initialize(_, _, _))
     96         .WillOnce(RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED));
     97   }
     98 
     99   void ExpectUnsupportedAudioDecoderConfig() {
    100     EXPECT_CALL(*decoder_, bits_per_channel())
    101         .WillRepeatedly(Return(3));
    102     EXPECT_CALL(*decoder_, channel_layout())
    103         .WillRepeatedly(Return(CHANNEL_LAYOUT_UNSUPPORTED));
    104     EXPECT_CALL(*decoder_, samples_per_second())
    105         .WillRepeatedly(Return(0));
    106     EXPECT_CALL(*decoder_, Initialize(_, _, _))
    107         .WillOnce(RunCallback<1>(PIPELINE_OK));
    108   }
    109 
    110   MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&));
    111   MOCK_METHOD0(OnUnderflow, void());
    112   MOCK_METHOD0(OnDisabled, void());
    113   MOCK_METHOD1(OnError, void(PipelineStatus));
    114 
    115   void OnAudioTimeCallback(TimeDelta current_time, TimeDelta max_time) {
    116     CHECK(current_time <= max_time);
    117   }
    118 
    119   void Initialize() {
    120     EXPECT_CALL(*decoder_, Initialize(_, _, _))
    121         .WillOnce(RunCallback<1>(PIPELINE_OK));
    122 
    123     InitializeWithStatus(PIPELINE_OK);
    124 
    125     next_timestamp_.reset(
    126         new AudioTimestampHelper(decoder_->samples_per_second()));
    127   }
    128 
    129   void InitializeWithStatus(PipelineStatus expected) {
    130     SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected));
    131 
    132     WaitableMessageLoopEvent event;
    133     renderer_->Initialize(
    134         &demuxer_stream_,
    135         event.GetPipelineStatusCB(),
    136         base::Bind(&AudioRendererImplTest::OnStatistics,
    137                    base::Unretained(this)),
    138         base::Bind(&AudioRendererImplTest::OnUnderflow,
    139                    base::Unretained(this)),
    140         base::Bind(&AudioRendererImplTest::OnAudioTimeCallback,
    141                    base::Unretained(this)),
    142         ended_event_.GetClosure(),
    143         base::Bind(&AudioRendererImplTest::OnDisabled,
    144                    base::Unretained(this)),
    145         base::Bind(&AudioRendererImplTest::OnError,
    146                    base::Unretained(this)));
    147     event.RunAndWaitForStatus(expected);
    148 
    149     // We should have no reads.
    150     EXPECT_TRUE(read_cb_.is_null());
    151   }
    152 
    153   void Preroll() {
    154     Preroll(0, PIPELINE_OK);
    155   }
    156 
    157   void Preroll(int timestamp_ms, PipelineStatus expected) {
    158     SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp_ms, expected));
    159 
    160     TimeDelta timestamp = TimeDelta::FromMilliseconds(timestamp_ms);
    161     next_timestamp_->SetBaseTimestamp(timestamp);
    162 
    163     // Fill entire buffer to complete prerolling.
    164     WaitableMessageLoopEvent event;
    165     renderer_->Preroll(timestamp, event.GetPipelineStatusCB());
    166     WaitForPendingRead();
    167     DeliverRemainingAudio();
    168     event.RunAndWaitForStatus(PIPELINE_OK);
    169 
    170     // We should have no reads.
    171     EXPECT_TRUE(read_cb_.is_null());
    172   }
    173 
    174   void Play() {
    175     SCOPED_TRACE("Play()");
    176     WaitableMessageLoopEvent event;
    177     renderer_->Play(event.GetClosure());
    178     renderer_->SetPlaybackRate(1.0f);
    179     event.RunAndWait();
    180   }
    181 
    182   void WaitForEnded() {
    183     SCOPED_TRACE("WaitForEnded()");
    184     ended_event_.RunAndWait();
    185   }
    186 
    187   void WaitForPendingRead() {
    188     SCOPED_TRACE("WaitForPendingRead()");
    189     if (!read_cb_.is_null())
    190       return;
    191 
    192     DCHECK(wait_for_pending_read_cb_.is_null());
    193 
    194     WaitableMessageLoopEvent event;
    195     wait_for_pending_read_cb_ = event.GetClosure();
    196     event.RunAndWait();
    197 
    198     DCHECK(!read_cb_.is_null());
    199     DCHECK(wait_for_pending_read_cb_.is_null());
    200   }
    201 
    202   // Delivers |size| frames with value kPlayingAudio to |renderer_|.
    203   void SatisfyPendingRead(size_t size) {
    204     CHECK(!read_cb_.is_null());
    205 
    206     scoped_refptr<AudioBuffer> buffer =
    207         MakePlanarAudioBuffer<float>(kSampleFormat,
    208                                      kChannels,
    209                                      kPlayingAudio,
    210                                      0.0f,
    211                                      size,
    212                                      next_timestamp_->GetTimestamp(),
    213                                      next_timestamp_->GetFrameDuration(size));
    214     next_timestamp_->AddFrames(size);
    215 
    216     DeliverBuffer(AudioDecoder::kOk, buffer);
    217   }
    218 
    219   void AbortPendingRead() {
    220     DeliverBuffer(AudioDecoder::kAborted, NULL);
    221   }
    222 
    223   void DeliverEndOfStream() {
    224     DeliverBuffer(AudioDecoder::kOk, AudioBuffer::CreateEOSBuffer());
    225   }
    226 
    227   // Delivers frames until |renderer_|'s internal buffer is full and no longer
    228   // has pending reads.
    229   void DeliverRemainingAudio() {
    230     SatisfyPendingRead(frames_remaining_in_buffer());
    231   }
    232 
    233   // Attempts to consume |requested_frames| frames from |renderer_|'s internal
    234   // buffer, returning true if all |requested_frames| frames were consumed,
    235   // false if less than |requested_frames| frames were consumed.
    236   //
    237   // |muted| is optional and if passed will get set if the value of
    238   // the consumed data is muted audio.
    239   bool ConsumeBufferedData(uint32 requested_frames, bool* muted) {
    240     scoped_ptr<AudioBus> bus =
    241         AudioBus::Create(kChannels, std::max(requested_frames, 1u));
    242     uint32 frames_read = renderer_->FillBuffer(bus.get(), requested_frames, 0);
    243 
    244     if (muted)
    245       *muted = frames_read < 1 || bus->channel(0)[0] == kMutedAudio;
    246     return frames_read == requested_frames;
    247   }
    248 
    249   // Attempts to consume all data available from the renderer.  Returns the
    250   // number of frames read.  Since time is frozen, the audio delay will increase
    251   // as frames come in.
    252   int ConsumeAllBufferedData() {
    253     renderer_->DisableUnderflowForTesting();
    254 
    255     int frames_read = 0;
    256     int total_frames_read = 0;
    257 
    258     const int kRequestFrames = 1024;
    259     scoped_ptr<AudioBus> bus = AudioBus::Create(kChannels, kRequestFrames);
    260 
    261     do {
    262       TimeDelta audio_delay = TimeDelta::FromMicroseconds(
    263           total_frames_read * Time::kMicrosecondsPerSecond /
    264           static_cast<float>(decoder_->samples_per_second()));
    265 
    266       frames_read = renderer_->FillBuffer(
    267           bus.get(), kRequestFrames, audio_delay.InMilliseconds());
    268       total_frames_read += frames_read;
    269     } while (frames_read > 0);
    270 
    271     return total_frames_read;
    272   }
    273 
    274   uint32 frames_buffered() {
    275     return renderer_->algorithm_->frames_buffered();
    276   }
    277 
    278   uint32 buffer_capacity() {
    279     return renderer_->algorithm_->QueueCapacity();
    280   }
    281 
    282   uint32 frames_remaining_in_buffer() {
    283     // This can happen if too much data was delivered, in which case the buffer
    284     // will accept the data but not increase capacity.
    285     if (frames_buffered() > buffer_capacity()) {
    286       return 0;
    287     }
    288     return buffer_capacity() - frames_buffered();
    289   }
    290 
    291   void CallResumeAfterUnderflow() {
    292     renderer_->ResumeAfterUnderflow();
    293   }
    294 
    295   TimeDelta CalculatePlayTime(int frames_filled) {
    296     return TimeDelta::FromMicroseconds(
    297         frames_filled * Time::kMicrosecondsPerSecond /
    298         renderer_->audio_parameters_.sample_rate());
    299   }
    300 
    301   void EndOfStreamTest(float playback_rate) {
    302     Initialize();
    303     Preroll();
    304     Play();
    305     renderer_->SetPlaybackRate(playback_rate);
    306 
    307     // Drain internal buffer, we should have a pending read.
    308     int total_frames = frames_buffered();
    309     int frames_filled = ConsumeAllBufferedData();
    310     WaitForPendingRead();
    311 
    312     // Due to how the cross-fade algorithm works we won't get an exact match
    313     // between the ideal and expected number of frames consumed.  In the faster
    314     // than normal playback case, more frames are created than should exist and
    315     // vice versa in the slower than normal playback case.
    316     const float kEpsilon = 0.20 * (total_frames / playback_rate);
    317     EXPECT_NEAR(frames_filled, total_frames / playback_rate, kEpsilon);
    318 
    319     // Figure out how long until the ended event should fire.
    320     TimeDelta audio_play_time = CalculatePlayTime(frames_filled);
    321     DVLOG(1) << "audio_play_time = " << audio_play_time.InSecondsF();
    322 
    323     // Fulfill the read with an end-of-stream packet.  We shouldn't report ended
    324     // nor have a read until we drain the internal buffer.
    325     DeliverEndOfStream();
    326 
    327     // Advance time half way without an ended expectation.
    328     AdvanceTime(audio_play_time / 2);
    329     ConsumeBufferedData(frames_buffered(), NULL);
    330 
    331     // Advance time by other half and expect the ended event.
    332     AdvanceTime(audio_play_time / 2);
    333     ConsumeBufferedData(frames_buffered(), NULL);
    334     WaitForEnded();
    335   }
    336 
    337   void AdvanceTime(TimeDelta time) {
    338     base::AutoLock auto_lock(lock_);
    339     time_ += time;
    340   }
    341 
    342   // Fixture members.
    343   base::MessageLoop message_loop_;
    344   scoped_ptr<AudioRendererImpl> renderer_;
    345 
    346  private:
    347   TimeTicks GetTime() {
    348     base::AutoLock auto_lock(lock_);
    349     return time_;
    350   }
    351 
    352   void ReadDecoder(const AudioDecoder::ReadCB& read_cb) {
    353     // TODO(scherkus): Make this a DCHECK after threading semantics are fixed.
    354     if (base::MessageLoop::current() != &message_loop_) {
    355       message_loop_.PostTask(FROM_HERE, base::Bind(
    356           &AudioRendererImplTest::ReadDecoder,
    357           base::Unretained(this), read_cb));
    358       return;
    359     }
    360 
    361     CHECK(read_cb_.is_null()) << "Overlapping reads are not permitted";
    362     read_cb_ = read_cb;
    363 
    364     // Wake up WaitForPendingRead() if needed.
    365     if (!wait_for_pending_read_cb_.is_null())
    366       base::ResetAndReturn(&wait_for_pending_read_cb_).Run();
    367   }
    368 
    369   void DeliverBuffer(AudioDecoder::Status status,
    370                      const scoped_refptr<AudioBuffer>& buffer) {
    371     CHECK(!read_cb_.is_null());
    372     base::ResetAndReturn(&read_cb_).Run(status, buffer);
    373   }
    374 
    375   MockDemuxerStream demuxer_stream_;
    376   MockAudioDecoder* decoder_;
    377 
    378   // Used for stubbing out time in the audio callback thread.
    379   base::Lock lock_;
    380   TimeTicks time_;
    381 
    382   // Used for satisfying reads.
    383   AudioDecoder::ReadCB read_cb_;
    384   scoped_ptr<AudioTimestampHelper> next_timestamp_;
    385 
    386   WaitableMessageLoopEvent ended_event_;
    387 
    388   // Run during ReadDecoder() to unblock WaitForPendingRead().
    389   base::Closure wait_for_pending_read_cb_;
    390 
    391   DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest);
    392 };
    393 
    394 TEST_F(AudioRendererImplTest, Initialize_Failed) {
    395   ExpectUnsupportedAudioDecoderConfig();
    396   InitializeWithStatus(PIPELINE_ERROR_INITIALIZATION_FAILED);
    397 }
    398 
    399 TEST_F(AudioRendererImplTest, Initialize_Successful) {
    400   Initialize();
    401 }
    402 
    403 TEST_F(AudioRendererImplTest, Initialize_DecoderInitFailure) {
    404   ExpectUnsupportedAudioDecoder();
    405   InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED);
    406 }
    407 
    408 TEST_F(AudioRendererImplTest, Preroll) {
    409   Initialize();
    410   Preroll();
    411 }
    412 
    413 TEST_F(AudioRendererImplTest, Play) {
    414   Initialize();
    415   Preroll();
    416   Play();
    417 
    418   // Drain internal buffer, we should have a pending read.
    419   EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL));
    420   WaitForPendingRead();
    421 }
    422 
    423 TEST_F(AudioRendererImplTest, EndOfStream) {
    424   EndOfStreamTest(1.0);
    425 }
    426 
    427 TEST_F(AudioRendererImplTest, EndOfStream_FasterPlaybackSpeed) {
    428   EndOfStreamTest(2.0);
    429 }
    430 
    431 TEST_F(AudioRendererImplTest, EndOfStream_SlowerPlaybackSpeed) {
    432   EndOfStreamTest(0.5);
    433 }
    434 
    435 TEST_F(AudioRendererImplTest, Underflow) {
    436   Initialize();
    437   Preroll();
    438   Play();
    439 
    440   // Drain internal buffer, we should have a pending read.
    441   EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL));
    442   WaitForPendingRead();
    443 
    444   // Verify the next FillBuffer() call triggers the underflow callback
    445   // since the decoder hasn't delivered any data after it was drained.
    446   const size_t kDataSize = 1024;
    447   EXPECT_CALL(*this, OnUnderflow());
    448   EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL));
    449 
    450   renderer_->ResumeAfterUnderflow();
    451 
    452   // Verify after resuming that we're still not getting data.
    453   bool muted = false;
    454   EXPECT_EQ(0u, frames_buffered());
    455   EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted));
    456   EXPECT_TRUE(muted);
    457 
    458   // Deliver data, we should get non-muted audio.
    459   DeliverRemainingAudio();
    460   EXPECT_TRUE(ConsumeBufferedData(kDataSize, &muted));
    461   EXPECT_FALSE(muted);
    462 }
    463 
    464 TEST_F(AudioRendererImplTest, Underflow_EndOfStream) {
    465   Initialize();
    466   Preroll();
    467   Play();
    468 
    469   // Figure out how long until the ended event should fire.  Since
    470   // ConsumeBufferedData() doesn't provide audio delay information, the time
    471   // until the ended event fires is equivalent to the longest buffered section,
    472   // which is the initial frames_buffered() read.
    473   TimeDelta time_until_ended = CalculatePlayTime(frames_buffered());
    474 
    475   // Drain internal buffer, we should have a pending read.
    476   EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL));
    477   WaitForPendingRead();
    478 
    479   // Verify the next FillBuffer() call triggers the underflow callback
    480   // since the decoder hasn't delivered any data after it was drained.
    481   const size_t kDataSize = 1024;
    482   EXPECT_CALL(*this, OnUnderflow());
    483   EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL));
    484 
    485   // Deliver a little bit of data.
    486   SatisfyPendingRead(kDataSize);
    487   WaitForPendingRead();
    488 
    489   // Verify we're getting muted audio during underflow.
    490   bool muted = false;
    491   EXPECT_EQ(kDataSize, frames_buffered());
    492   EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted));
    493   EXPECT_TRUE(muted);
    494 
    495   // Now deliver end of stream, we should get our little bit of data back.
    496   DeliverEndOfStream();
    497   EXPECT_EQ(kDataSize, frames_buffered());
    498   EXPECT_TRUE(ConsumeBufferedData(kDataSize, &muted));
    499   EXPECT_FALSE(muted);
    500 
    501   // Attempt to read to make sure we're truly at the end of stream.
    502   AdvanceTime(time_until_ended);
    503   EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted));
    504   EXPECT_TRUE(muted);
    505   WaitForEnded();
    506 }
    507 
    508 TEST_F(AudioRendererImplTest, Underflow_ResumeFromCallback) {
    509   Initialize();
    510   Preroll();
    511   Play();
    512 
    513   // Drain internal buffer, we should have a pending read.
    514   EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL));
    515   WaitForPendingRead();
    516 
    517   // Verify the next FillBuffer() call triggers the underflow callback
    518   // since the decoder hasn't delivered any data after it was drained.
    519   const size_t kDataSize = 1024;
    520   EXPECT_CALL(*this, OnUnderflow())
    521       .WillOnce(Invoke(this, &AudioRendererImplTest::CallResumeAfterUnderflow));
    522   EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL));
    523 
    524   // Verify after resuming that we're still not getting data.
    525   bool muted = false;
    526   EXPECT_EQ(0u, frames_buffered());
    527   EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted));
    528   EXPECT_TRUE(muted);
    529 
    530   // Deliver data, we should get non-muted audio.
    531   DeliverRemainingAudio();
    532   EXPECT_TRUE(ConsumeBufferedData(kDataSize, &muted));
    533   EXPECT_FALSE(muted);
    534 }
    535 
    536 TEST_F(AudioRendererImplTest, AbortPendingRead_Preroll) {
    537   Initialize();
    538 
    539   // Start prerolling and wait for a read.
    540   WaitableMessageLoopEvent event;
    541   renderer_->Preroll(TimeDelta(), event.GetPipelineStatusCB());
    542   WaitForPendingRead();
    543 
    544   // Simulate the decoder aborting the pending read.
    545   AbortPendingRead();
    546   event.RunAndWaitForStatus(PIPELINE_OK);
    547 
    548   // Preroll again to a different timestamp and verify it completed normally.
    549   Preroll(1000, PIPELINE_OK);
    550 }
    551 
    552 TEST_F(AudioRendererImplTest, AbortPendingRead_Pause) {
    553   Initialize();
    554 
    555   Preroll();
    556   Play();
    557 
    558   // Partially drain internal buffer so we get a pending read.
    559   EXPECT_TRUE(ConsumeBufferedData(frames_buffered() / 2, NULL));
    560   WaitForPendingRead();
    561 
    562   // Start pausing.
    563   WaitableMessageLoopEvent event;
    564   renderer_->Pause(event.GetClosure());
    565 
    566   // Simulate the decoder aborting the pending read.
    567   AbortPendingRead();
    568   event.RunAndWait();
    569 
    570   // Preroll again to a different timestamp and verify it completed normally.
    571   Preroll(1000, PIPELINE_OK);
    572 }
    573 
    574 }  // namespace media
    575