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/run_loop.h"
8#include "base/strings/stringprintf.h"
9#include "media/base/audio_buffer_converter.h"
10#include "media/base/audio_hardware_config.h"
11#include "media/base/audio_splicer.h"
12#include "media/base/fake_audio_renderer_sink.h"
13#include "media/base/gmock_callback_support.h"
14#include "media/base/mock_filters.h"
15#include "media/base/test_helpers.h"
16#include "media/filters/audio_renderer_impl.h"
17#include "testing/gtest/include/gtest/gtest.h"
18
19using ::base::TimeDelta;
20using ::testing::_;
21using ::testing::Return;
22using ::testing::SaveArg;
23
24namespace media {
25
26namespace {
27
28// Since AudioBufferConverter is used due to different input/output sample
29// rates, define some helper types to differentiate between the two.
30struct InputFrames {
31  explicit InputFrames(int value) : value(value) {}
32  int value;
33};
34
35struct OutputFrames {
36  explicit OutputFrames(int value) : value(value) {}
37  int value;
38};
39
40}  // namespace
41
42// Constants to specify the type of audio data used.
43static AudioCodec kCodec = kCodecVorbis;
44static SampleFormat kSampleFormat = kSampleFormatPlanarF32;
45static ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO;
46static int kChannelCount = 2;
47static int kChannels = ChannelLayoutToChannelCount(kChannelLayout);
48
49// Use a different output sample rate so the AudioBufferConverter is invoked.
50static int kInputSamplesPerSecond = 5000;
51static int kOutputSamplesPerSecond = 10000;
52
53ACTION_P(EnterPendingDecoderInitStateAction, test) {
54  test->EnterPendingDecoderInitState(arg1);
55}
56
57class AudioRendererImplTest : public ::testing::Test {
58 public:
59  // Give the decoder some non-garbage media properties.
60  AudioRendererImplTest()
61      : hardware_config_(AudioParameters(), AudioParameters()),
62        demuxer_stream_(DemuxerStream::AUDIO),
63        decoder_(new MockAudioDecoder()),
64        ended_(false) {
65    AudioDecoderConfig audio_config(kCodec,
66                                    kSampleFormat,
67                                    kChannelLayout,
68                                    kInputSamplesPerSecond,
69                                    NULL,
70                                    0,
71                                    false);
72    demuxer_stream_.set_audio_decoder_config(audio_config);
73
74    // Used to save callbacks and run them at a later time.
75    EXPECT_CALL(*decoder_, Decode(_, _))
76        .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder));
77    EXPECT_CALL(*decoder_, Reset(_))
78        .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder));
79
80    // Mock out demuxer reads.
81    EXPECT_CALL(demuxer_stream_, Read(_)).WillRepeatedly(
82        RunCallback<0>(DemuxerStream::kOk,
83                       scoped_refptr<DecoderBuffer>(new DecoderBuffer(0))));
84    EXPECT_CALL(demuxer_stream_, SupportsConfigChanges())
85        .WillRepeatedly(Return(true));
86    AudioParameters out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
87                               kChannelLayout,
88                               kOutputSamplesPerSecond,
89                               SampleFormatToBytesPerChannel(kSampleFormat) * 8,
90                               512);
91    hardware_config_.UpdateOutputConfig(out_params);
92    ScopedVector<AudioDecoder> decoders;
93    decoders.push_back(decoder_);
94    sink_ = new FakeAudioRendererSink();
95    renderer_.reset(new AudioRendererImpl(message_loop_.message_loop_proxy(),
96                                          sink_.get(),
97                                          decoders.Pass(),
98                                          SetDecryptorReadyCB(),
99                                          hardware_config_,
100                                          new MediaLog()));
101  }
102
103  virtual ~AudioRendererImplTest() {
104    SCOPED_TRACE("~AudioRendererImplTest()");
105  }
106
107  void ExpectUnsupportedAudioDecoder() {
108    EXPECT_CALL(*decoder_, Initialize(_, _, _))
109        .WillOnce(DoAll(SaveArg<2>(&output_cb_),
110                        RunCallback<1>(DECODER_ERROR_NOT_SUPPORTED)));
111  }
112
113  MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&));
114  MOCK_METHOD1(OnBufferingStateChange, void(BufferingState));
115  MOCK_METHOD1(OnError, void(PipelineStatus));
116
117  void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) {
118    renderer_->Initialize(
119        &demuxer_stream_,
120        pipeline_status_cb,
121        base::Bind(&AudioRendererImplTest::OnStatistics,
122                   base::Unretained(this)),
123        base::Bind(&AudioRendererImplTest::OnBufferingStateChange,
124                   base::Unretained(this)),
125        base::Bind(&AudioRendererImplTest::OnEnded,
126                   base::Unretained(this)),
127        base::Bind(&AudioRendererImplTest::OnError,
128                   base::Unretained(this)));
129  }
130
131  void Initialize() {
132    EXPECT_CALL(*decoder_, Initialize(_, _, _))
133        .WillOnce(DoAll(SaveArg<2>(&output_cb_),
134                        RunCallback<1>(PIPELINE_OK)));
135    InitializeWithStatus(PIPELINE_OK);
136
137    next_timestamp_.reset(new AudioTimestampHelper(kInputSamplesPerSecond));
138  }
139
140  void InitializeWithStatus(PipelineStatus expected) {
141    SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected));
142
143    WaitableMessageLoopEvent event;
144    InitializeRenderer(event.GetPipelineStatusCB());
145    event.RunAndWaitForStatus(expected);
146
147    // We should have no reads.
148    EXPECT_TRUE(decode_cb_.is_null());
149  }
150
151  void InitializeAndDestroy() {
152    EXPECT_CALL(*decoder_, Initialize(_, _, _))
153        .WillOnce(RunCallback<1>(PIPELINE_OK));
154
155    WaitableMessageLoopEvent event;
156    InitializeRenderer(event.GetPipelineStatusCB());
157
158    // Destroy the |renderer_| before we let the MessageLoop run, this simulates
159    // an interleaving in which we end up destroying the |renderer_| while the
160    // OnDecoderSelected callback is in flight.
161    renderer_.reset();
162    event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT);
163  }
164
165  void InitializeAndDestroyDuringDecoderInit() {
166    EXPECT_CALL(*decoder_, Initialize(_, _, _))
167        .WillOnce(EnterPendingDecoderInitStateAction(this));
168
169    WaitableMessageLoopEvent event;
170    InitializeRenderer(event.GetPipelineStatusCB());
171    base::RunLoop().RunUntilIdle();
172    DCHECK(!init_decoder_cb_.is_null());
173
174    renderer_.reset();
175    event.RunAndWaitForStatus(PIPELINE_ERROR_ABORT);
176  }
177
178  void EnterPendingDecoderInitState(PipelineStatusCB cb) {
179    init_decoder_cb_ = cb;
180  }
181
182  void FlushDuringPendingRead() {
183    SCOPED_TRACE("FlushDuringPendingRead()");
184    WaitableMessageLoopEvent flush_event;
185    renderer_->Flush(flush_event.GetClosure());
186    SatisfyPendingRead(InputFrames(256));
187    flush_event.RunAndWait();
188
189    EXPECT_FALSE(IsReadPending());
190  }
191
192  void Preroll() {
193    Preroll(0, PIPELINE_OK);
194  }
195
196  void Preroll(int timestamp_ms, PipelineStatus expected) {
197    SCOPED_TRACE(base::StringPrintf("Preroll(%d, %d)", timestamp_ms, expected));
198
199    TimeDelta timestamp = TimeDelta::FromMilliseconds(timestamp_ms);
200    next_timestamp_->SetBaseTimestamp(timestamp);
201
202    // Fill entire buffer to complete prerolling.
203    renderer_->SetMediaTime(timestamp);
204    renderer_->StartPlaying();
205    WaitForPendingRead();
206    EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
207    DeliverRemainingAudio();
208  }
209
210  void StartTicking() {
211    renderer_->StartTicking();
212    renderer_->SetPlaybackRate(1.0f);
213  }
214
215  void StopTicking() { renderer_->StopTicking(); }
216
217  bool IsReadPending() const {
218    return !decode_cb_.is_null();
219  }
220
221  void WaitForPendingRead() {
222    SCOPED_TRACE("WaitForPendingRead()");
223    if (!decode_cb_.is_null())
224      return;
225
226    DCHECK(wait_for_pending_decode_cb_.is_null());
227
228    WaitableMessageLoopEvent event;
229    wait_for_pending_decode_cb_ = event.GetClosure();
230    event.RunAndWait();
231
232    DCHECK(!decode_cb_.is_null());
233    DCHECK(wait_for_pending_decode_cb_.is_null());
234  }
235
236  // Delivers decoded frames to |renderer_|.
237  void SatisfyPendingRead(InputFrames frames) {
238    CHECK_GT(frames.value, 0);
239    CHECK(!decode_cb_.is_null());
240
241    scoped_refptr<AudioBuffer> buffer =
242        MakeAudioBuffer<float>(kSampleFormat,
243                               kChannelLayout,
244                               kChannelCount,
245                               kInputSamplesPerSecond,
246                               1.0f,
247                               0.0f,
248                               frames.value,
249                               next_timestamp_->GetTimestamp());
250    next_timestamp_->AddFrames(frames.value);
251
252    DeliverBuffer(AudioDecoder::kOk, buffer);
253  }
254
255  void DeliverEndOfStream() {
256    DCHECK(!decode_cb_.is_null());
257
258    // Return EOS buffer to trigger EOS frame.
259    EXPECT_CALL(demuxer_stream_, Read(_))
260        .WillOnce(RunCallback<0>(DemuxerStream::kOk,
261                                 DecoderBuffer::CreateEOSBuffer()));
262
263    // Satify pending |decode_cb_| to trigger a new DemuxerStream::Read().
264    message_loop_.PostTask(
265        FROM_HERE,
266        base::Bind(base::ResetAndReturn(&decode_cb_), AudioDecoder::kOk));
267
268    WaitForPendingRead();
269
270    message_loop_.PostTask(
271        FROM_HERE,
272        base::Bind(base::ResetAndReturn(&decode_cb_), AudioDecoder::kOk));
273
274    base::RunLoop().RunUntilIdle();
275  }
276
277  // Delivers frames until |renderer_|'s internal buffer is full and no longer
278  // has pending reads.
279  void DeliverRemainingAudio() {
280    while (frames_remaining_in_buffer().value > 0) {
281      SatisfyPendingRead(InputFrames(256));
282    }
283  }
284
285  // Attempts to consume |requested_frames| frames from |renderer_|'s internal
286  // buffer. Returns true if and only if all of |requested_frames| were able
287  // to be consumed.
288  bool ConsumeBufferedData(OutputFrames requested_frames) {
289    scoped_ptr<AudioBus> bus =
290        AudioBus::Create(kChannels, requested_frames.value);
291    int frames_read = 0;
292    EXPECT_TRUE(sink_->Render(bus.get(), 0, &frames_read));
293    return frames_read == requested_frames.value;
294  }
295
296  OutputFrames frames_buffered() {
297    return OutputFrames(renderer_->algorithm_->frames_buffered());
298  }
299
300  OutputFrames buffer_capacity() {
301    return OutputFrames(renderer_->algorithm_->QueueCapacity());
302  }
303
304  OutputFrames frames_remaining_in_buffer() {
305    // This can happen if too much data was delivered, in which case the buffer
306    // will accept the data but not increase capacity.
307    if (frames_buffered().value > buffer_capacity().value) {
308      return OutputFrames(0);
309    }
310    return OutputFrames(buffer_capacity().value - frames_buffered().value);
311  }
312
313  void force_config_change() {
314    renderer_->OnConfigChange();
315  }
316
317  InputFrames converter_input_frames_left() const {
318    return InputFrames(
319        renderer_->buffer_converter_->input_frames_left_for_testing());
320  }
321
322  bool splicer_has_next_buffer() const {
323    return renderer_->splicer_->HasNextBuffer();
324  }
325
326  base::TimeDelta CurrentMediaTime() {
327    return renderer_->CurrentMediaTime();
328  }
329
330  bool ended() const { return ended_; }
331
332  // Fixture members.
333  base::MessageLoop message_loop_;
334  scoped_ptr<AudioRendererImpl> renderer_;
335  scoped_refptr<FakeAudioRendererSink> sink_;
336  AudioHardwareConfig hardware_config_;
337
338 private:
339  void DecodeDecoder(const scoped_refptr<DecoderBuffer>& buffer,
340                     const AudioDecoder::DecodeCB& decode_cb) {
341    // TODO(scherkus): Make this a DCHECK after threading semantics are fixed.
342    if (base::MessageLoop::current() != &message_loop_) {
343      message_loop_.PostTask(FROM_HERE, base::Bind(
344          &AudioRendererImplTest::DecodeDecoder,
345          base::Unretained(this), buffer, decode_cb));
346      return;
347    }
348
349    CHECK(decode_cb_.is_null()) << "Overlapping decodes are not permitted";
350    decode_cb_ = decode_cb;
351
352    // Wake up WaitForPendingRead() if needed.
353    if (!wait_for_pending_decode_cb_.is_null())
354      base::ResetAndReturn(&wait_for_pending_decode_cb_).Run();
355  }
356
357  void ResetDecoder(const base::Closure& reset_cb) {
358    if (!decode_cb_.is_null()) {
359      // |reset_cb| will be called in DeliverBuffer(), after the decoder is
360      // flushed.
361      reset_cb_ = reset_cb;
362      return;
363    }
364
365    message_loop_.PostTask(FROM_HERE, reset_cb);
366  }
367
368  void DeliverBuffer(AudioDecoder::Status status,
369                     const scoped_refptr<AudioBuffer>& buffer) {
370    CHECK(!decode_cb_.is_null());
371    if (buffer.get() && !buffer->end_of_stream())
372      output_cb_.Run(buffer);
373    base::ResetAndReturn(&decode_cb_).Run(status);
374
375    if (!reset_cb_.is_null())
376      base::ResetAndReturn(&reset_cb_).Run();
377
378    base::RunLoop().RunUntilIdle();
379  }
380
381  void OnEnded() {
382    CHECK(!ended_);
383    ended_ = true;
384  }
385
386  MockDemuxerStream demuxer_stream_;
387  MockAudioDecoder* decoder_;
388
389  // Used for satisfying reads.
390  AudioDecoder::OutputCB output_cb_;
391  AudioDecoder::DecodeCB decode_cb_;
392  base::Closure reset_cb_;
393  scoped_ptr<AudioTimestampHelper> next_timestamp_;
394
395  // Run during DecodeDecoder() to unblock WaitForPendingRead().
396  base::Closure wait_for_pending_decode_cb_;
397
398  PipelineStatusCB init_decoder_cb_;
399  bool ended_;
400
401  DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest);
402};
403
404TEST_F(AudioRendererImplTest, Initialize_Successful) {
405  Initialize();
406}
407
408TEST_F(AudioRendererImplTest, Initialize_DecoderInitFailure) {
409  ExpectUnsupportedAudioDecoder();
410  InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED);
411}
412
413TEST_F(AudioRendererImplTest, Preroll) {
414  Initialize();
415  Preroll();
416}
417
418TEST_F(AudioRendererImplTest, StartTicking) {
419  Initialize();
420  Preroll();
421  StartTicking();
422
423  // Drain internal buffer, we should have a pending read.
424  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
425  WaitForPendingRead();
426}
427
428TEST_F(AudioRendererImplTest, EndOfStream) {
429  Initialize();
430  Preroll();
431  StartTicking();
432
433  // Drain internal buffer, we should have a pending read.
434  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
435  WaitForPendingRead();
436
437  // Forcefully trigger underflow.
438  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
439  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
440
441  // Fulfill the read with an end-of-stream buffer. Doing so should change our
442  // buffering state so playback resumes.
443  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
444  DeliverEndOfStream();
445
446  // Consume all remaining data. We shouldn't have signal ended yet.
447  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
448  base::RunLoop().RunUntilIdle();
449  EXPECT_FALSE(ended());
450
451  // Ended should trigger on next render call.
452  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
453  base::RunLoop().RunUntilIdle();
454  EXPECT_TRUE(ended());
455}
456
457TEST_F(AudioRendererImplTest, Underflow) {
458  Initialize();
459  Preroll();
460  StartTicking();
461
462  // Drain internal buffer, we should have a pending read.
463  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
464  WaitForPendingRead();
465
466  // Verify the next FillBuffer() call triggers a buffering state change
467  // update.
468  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
469  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
470
471  // Verify we're still not getting audio data.
472  EXPECT_EQ(0, frames_buffered().value);
473  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
474
475  // Deliver enough data to have enough for buffering.
476  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
477  DeliverRemainingAudio();
478
479  // Verify we're getting audio data.
480  EXPECT_TRUE(ConsumeBufferedData(OutputFrames(1)));
481}
482
483TEST_F(AudioRendererImplTest, Underflow_CapacityResetsAfterFlush) {
484  Initialize();
485  Preroll();
486  StartTicking();
487
488  // Drain internal buffer, we should have a pending read.
489  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
490  WaitForPendingRead();
491
492  // Verify the next FillBuffer() call triggers the underflow callback
493  // since the decoder hasn't delivered any data after it was drained.
494  OutputFrames initial_capacity = buffer_capacity();
495  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
496  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
497
498  // Verify that the buffer capacity increased as a result of underflowing.
499  EXPECT_GT(buffer_capacity().value, initial_capacity.value);
500
501  // Verify that the buffer capacity is restored to the |initial_capacity|.
502  FlushDuringPendingRead();
503  EXPECT_EQ(buffer_capacity().value, initial_capacity.value);
504}
505
506TEST_F(AudioRendererImplTest, Underflow_Flush) {
507  Initialize();
508  Preroll();
509  StartTicking();
510
511  // Force underflow.
512  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
513  WaitForPendingRead();
514  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
515  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
516  WaitForPendingRead();
517  StopTicking();
518
519  // We shouldn't expect another buffering state change when flushing.
520  FlushDuringPendingRead();
521}
522
523TEST_F(AudioRendererImplTest, PendingRead_Flush) {
524  Initialize();
525
526  Preroll();
527  StartTicking();
528
529  // Partially drain internal buffer so we get a pending read.
530  EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
531  WaitForPendingRead();
532
533  StopTicking();
534
535  EXPECT_TRUE(IsReadPending());
536
537  // Flush and expect to be notified that we have nothing.
538  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
539  FlushDuringPendingRead();
540
541  // Preroll again to a different timestamp and verify it completed normally.
542  Preroll(1000, PIPELINE_OK);
543}
544
545TEST_F(AudioRendererImplTest, PendingRead_Destroy) {
546  Initialize();
547
548  Preroll();
549  StartTicking();
550
551  // Partially drain internal buffer so we get a pending read.
552  EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
553  WaitForPendingRead();
554
555  StopTicking();
556
557  EXPECT_TRUE(IsReadPending());
558
559  renderer_.reset();
560}
561
562TEST_F(AudioRendererImplTest, PendingFlush_Destroy) {
563  Initialize();
564
565  Preroll();
566  StartTicking();
567
568  // Partially drain internal buffer so we get a pending read.
569  EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
570  WaitForPendingRead();
571
572  StopTicking();
573
574  EXPECT_TRUE(IsReadPending());
575
576  // Start flushing.
577  WaitableMessageLoopEvent flush_event;
578  renderer_->Flush(flush_event.GetClosure());
579
580  EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
581  SatisfyPendingRead(InputFrames(256));
582
583  renderer_.reset();
584}
585
586TEST_F(AudioRendererImplTest, InitializeThenDestroy) {
587  InitializeAndDestroy();
588}
589
590TEST_F(AudioRendererImplTest, InitializeThenDestroyDuringDecoderInit) {
591  InitializeAndDestroyDuringDecoderInit();
592}
593
594TEST_F(AudioRendererImplTest, ConfigChangeDrainsConverter) {
595  Initialize();
596  Preroll();
597  StartTicking();
598
599  // Drain internal buffer, we should have a pending read.
600  EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
601  WaitForPendingRead();
602
603  // Deliver a little bit of data.  Use an odd data size to ensure there is data
604  // left in the AudioBufferConverter.  Ensure no buffers are in the splicer.
605  SatisfyPendingRead(InputFrames(2053));
606  EXPECT_FALSE(splicer_has_next_buffer());
607  EXPECT_GT(converter_input_frames_left().value, 0);
608
609  // Force a config change and then ensure all buffered data has been put into
610  // the splicer.
611  force_config_change();
612  EXPECT_TRUE(splicer_has_next_buffer());
613  EXPECT_EQ(0, converter_input_frames_left().value);
614}
615
616TEST_F(AudioRendererImplTest, TimeUpdatesOnFirstBuffer) {
617  Initialize();
618  Preroll();
619  StartTicking();
620
621  AudioTimestampHelper timestamp_helper(kOutputSamplesPerSecond);
622  timestamp_helper.SetBaseTimestamp(base::TimeDelta());
623
624  // Time should be the starting timestamp as nothing's been consumed yet.
625  EXPECT_EQ(timestamp_helper.GetTimestamp(), CurrentMediaTime());
626
627  // Consume some audio data.
628  OutputFrames frames_to_consume(frames_buffered().value / 2);
629  EXPECT_TRUE(ConsumeBufferedData(frames_to_consume));
630  WaitForPendingRead();
631
632  // Time shouldn't change just yet because we've only sent the initial audio
633  // data to the hardware.
634  EXPECT_EQ(timestamp_helper.GetTimestamp(), CurrentMediaTime());
635
636  // Consume some more audio data.
637  frames_to_consume = frames_buffered();
638  EXPECT_TRUE(ConsumeBufferedData(frames_to_consume));
639
640  // Now time should change now that the audio hardware has called back.
641  timestamp_helper.AddFrames(frames_to_consume.value);
642  EXPECT_EQ(timestamp_helper.GetTimestamp(), CurrentMediaTime());
643}
644
645TEST_F(AudioRendererImplTest, ImmediateEndOfStream) {
646  Initialize();
647  {
648    SCOPED_TRACE("Preroll()");
649    renderer_->StartPlaying();
650    WaitForPendingRead();
651    EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
652    DeliverEndOfStream();
653  }
654  StartTicking();
655
656  // Read a single frame. We shouldn't be able to satisfy it.
657  EXPECT_FALSE(ended());
658  EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
659  base::RunLoop().RunUntilIdle();
660  EXPECT_TRUE(ended());
661}
662
663TEST_F(AudioRendererImplTest, OnRenderErrorCausesDecodeError) {
664  Initialize();
665  Preroll();
666  StartTicking();
667
668  EXPECT_CALL(*this, OnError(PIPELINE_ERROR_DECODE));
669  sink_->OnRenderError();
670  base::RunLoop().RunUntilIdle();
671}
672
673// Test for AudioRendererImpl calling Pause()/Play() on the sink when the
674// playback rate is set to zero and non-zero.
675TEST_F(AudioRendererImplTest, SetPlaybackRate) {
676  Initialize();
677  Preroll();
678
679  // Rendering hasn't started. Sink should always be paused.
680  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
681  renderer_->SetPlaybackRate(0.0f);
682  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
683  renderer_->SetPlaybackRate(1.0f);
684  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
685
686  // Rendering has started with non-zero rate. Rate changes will affect sink
687  // state.
688  renderer_->StartTicking();
689  EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
690  renderer_->SetPlaybackRate(0.0f);
691  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
692  renderer_->SetPlaybackRate(1.0f);
693  EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
694
695  // Rendering has stopped. Sink should be paused.
696  renderer_->StopTicking();
697  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
698
699  // Start rendering with zero playback rate. Sink should be paused until
700  // non-zero rate is set.
701  renderer_->SetPlaybackRate(0.0f);
702  renderer_->StartTicking();
703  EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
704  renderer_->SetPlaybackRate(1.0f);
705  EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
706}
707
708}  // namespace media
709