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.
6 #include "base/callback_helpers.h"
7 #include "base/format_macros.h"
8 #include "base/run_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "media/base/audio_buffer_converter.h"
11 #include "media/base/audio_hardware_config.h"
12 #include "media/base/audio_splicer.h"
13 #include "media/base/fake_audio_renderer_sink.h"
14 #include "media/base/gmock_callback_support.h"
15 #include "media/base/mock_filters.h"
16 #include "media/base/test_helpers.h"
17 #include "media/renderers/audio_renderer_impl.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using ::base::TimeDelta
;
22 using ::testing::Return
;
23 using ::testing::SaveArg
;
29 // Since AudioBufferConverter is used due to different input/output sample
30 // rates, define some helper types to differentiate between the two.
32 explicit InputFrames(int value
) : value(value
) {}
37 explicit OutputFrames(int value
) : value(value
) {}
43 // Constants to specify the type of audio data used.
44 static AudioCodec kCodec
= kCodecVorbis
;
45 static SampleFormat kSampleFormat
= kSampleFormatPlanarF32
;
46 static ChannelLayout kChannelLayout
= CHANNEL_LAYOUT_STEREO
;
47 static int kChannelCount
= 2;
48 static int kChannels
= ChannelLayoutToChannelCount(kChannelLayout
);
50 // Use a different output sample rate so the AudioBufferConverter is invoked.
51 static int kInputSamplesPerSecond
= 5000;
52 static int kOutputSamplesPerSecond
= 10000;
54 ACTION_P(EnterPendingDecoderInitStateAction
, test
) {
55 test
->EnterPendingDecoderInitState(arg1
);
58 class AudioRendererImplTest
: public ::testing::Test
{
60 // Give the decoder some non-garbage media properties.
61 AudioRendererImplTest()
62 : hardware_config_(AudioParameters(), AudioParameters()),
63 demuxer_stream_(DemuxerStream::AUDIO
),
64 decoder_(new MockAudioDecoder()),
66 AudioDecoderConfig
audio_config(kCodec
,
69 kInputSamplesPerSecond
,
73 demuxer_stream_
.set_audio_decoder_config(audio_config
);
75 // Used to save callbacks and run them at a later time.
76 EXPECT_CALL(*decoder_
, Decode(_
, _
))
77 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::DecodeDecoder
));
78 EXPECT_CALL(*decoder_
, Reset(_
))
79 .WillRepeatedly(Invoke(this, &AudioRendererImplTest::ResetDecoder
));
81 // Mock out demuxer reads.
82 EXPECT_CALL(demuxer_stream_
, Read(_
)).WillRepeatedly(
83 RunCallback
<0>(DemuxerStream::kOk
,
84 scoped_refptr
<DecoderBuffer
>(new DecoderBuffer(0))));
85 EXPECT_CALL(demuxer_stream_
, SupportsConfigChanges())
86 .WillRepeatedly(Return(true));
87 AudioParameters
out_params(AudioParameters::AUDIO_PCM_LOW_LATENCY
,
89 kOutputSamplesPerSecond
,
90 SampleFormatToBytesPerChannel(kSampleFormat
) * 8,
92 hardware_config_
.UpdateOutputConfig(out_params
);
93 ScopedVector
<AudioDecoder
> decoders
;
94 decoders
.push_back(decoder_
);
95 sink_
= new FakeAudioRendererSink();
96 renderer_
.reset(new AudioRendererImpl(message_loop_
.message_loop_proxy(),
103 virtual ~AudioRendererImplTest() {
104 SCOPED_TRACE("~AudioRendererImplTest()");
107 void ExpectUnsupportedAudioDecoder() {
108 EXPECT_CALL(*decoder_
, Initialize(_
, _
, _
))
109 .WillOnce(DoAll(SaveArg
<2>(&output_cb_
),
110 RunCallback
<1>(DECODER_ERROR_NOT_SUPPORTED
)));
113 MOCK_METHOD1(OnStatistics
, void(const PipelineStatistics
&));
114 MOCK_METHOD1(OnBufferingStateChange
, void(BufferingState
));
115 MOCK_METHOD1(OnError
, void(PipelineStatus
));
116 MOCK_METHOD0(OnWaitingForDecryptionKey
, void(void));
118 void InitializeRenderer(const PipelineStatusCB
& pipeline_status_cb
) {
119 EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
120 renderer_
->Initialize(
121 &demuxer_stream_
, pipeline_status_cb
, SetDecryptorReadyCB(),
122 base::Bind(&AudioRendererImplTest::OnStatistics
,
123 base::Unretained(this)),
124 base::Bind(&AudioRendererImplTest::OnBufferingStateChange
,
125 base::Unretained(this)),
126 base::Bind(&AudioRendererImplTest::OnEnded
, base::Unretained(this)),
127 base::Bind(&AudioRendererImplTest::OnError
, base::Unretained(this)),
128 base::Bind(&AudioRendererImplTest::OnWaitingForDecryptionKey
,
129 base::Unretained(this)));
133 EXPECT_CALL(*decoder_
, Initialize(_
, _
, _
))
134 .WillOnce(DoAll(SaveArg
<2>(&output_cb_
),
135 RunCallback
<1>(PIPELINE_OK
)));
136 InitializeWithStatus(PIPELINE_OK
);
138 next_timestamp_
.reset(new AudioTimestampHelper(kInputSamplesPerSecond
));
141 void InitializeWithStatus(PipelineStatus expected
) {
142 SCOPED_TRACE(base::StringPrintf("InitializeWithStatus(%d)", expected
));
144 WaitableMessageLoopEvent event
;
145 InitializeRenderer(event
.GetPipelineStatusCB());
146 event
.RunAndWaitForStatus(expected
);
148 // We should have no reads.
149 EXPECT_TRUE(decode_cb_
.is_null());
152 void InitializeAndDestroy() {
153 EXPECT_CALL(*decoder_
, Initialize(_
, _
, _
))
154 .WillOnce(RunCallback
<1>(PIPELINE_OK
));
156 WaitableMessageLoopEvent event
;
157 InitializeRenderer(event
.GetPipelineStatusCB());
159 // Destroy the |renderer_| before we let the MessageLoop run, this simulates
160 // an interleaving in which we end up destroying the |renderer_| while the
161 // OnDecoderSelected callback is in flight.
163 event
.RunAndWaitForStatus(PIPELINE_ERROR_ABORT
);
166 void InitializeAndDestroyDuringDecoderInit() {
167 EXPECT_CALL(*decoder_
, Initialize(_
, _
, _
))
168 .WillOnce(EnterPendingDecoderInitStateAction(this));
170 WaitableMessageLoopEvent event
;
171 InitializeRenderer(event
.GetPipelineStatusCB());
172 base::RunLoop().RunUntilIdle();
173 DCHECK(!init_decoder_cb_
.is_null());
176 event
.RunAndWaitForStatus(PIPELINE_ERROR_ABORT
);
179 void EnterPendingDecoderInitState(PipelineStatusCB cb
) {
180 init_decoder_cb_
= cb
;
183 void FlushDuringPendingRead() {
184 SCOPED_TRACE("FlushDuringPendingRead()");
185 WaitableMessageLoopEvent flush_event
;
186 renderer_
->Flush(flush_event
.GetClosure());
187 SatisfyPendingRead(InputFrames(256));
188 flush_event
.RunAndWait();
190 EXPECT_FALSE(IsReadPending());
194 Preroll(base::TimeDelta(), base::TimeDelta(), PIPELINE_OK
);
197 void Preroll(base::TimeDelta start_timestamp
,
198 base::TimeDelta first_timestamp
,
199 PipelineStatus expected
) {
200 SCOPED_TRACE(base::StringPrintf("Preroll(%" PRId64
", %d)",
201 first_timestamp
.InMilliseconds(),
203 next_timestamp_
->SetBaseTimestamp(first_timestamp
);
205 // Fill entire buffer to complete prerolling.
206 renderer_
->SetMediaTime(start_timestamp
);
207 renderer_
->StartPlaying();
208 WaitForPendingRead();
209 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH
));
210 DeliverRemainingAudio();
213 void StartTicking() {
214 renderer_
->StartTicking();
215 renderer_
->SetPlaybackRate(1.0f
);
218 void StopTicking() { renderer_
->StopTicking(); }
220 bool IsReadPending() const {
221 return !decode_cb_
.is_null();
224 void WaitForPendingRead() {
225 SCOPED_TRACE("WaitForPendingRead()");
226 if (!decode_cb_
.is_null())
229 DCHECK(wait_for_pending_decode_cb_
.is_null());
231 WaitableMessageLoopEvent event
;
232 wait_for_pending_decode_cb_
= event
.GetClosure();
235 DCHECK(!decode_cb_
.is_null());
236 DCHECK(wait_for_pending_decode_cb_
.is_null());
239 // Delivers decoded frames to |renderer_|.
240 void SatisfyPendingRead(InputFrames frames
) {
241 CHECK_GT(frames
.value
, 0);
242 CHECK(!decode_cb_
.is_null());
244 scoped_refptr
<AudioBuffer
> buffer
=
245 MakeAudioBuffer
<float>(kSampleFormat
,
248 kInputSamplesPerSecond
,
252 next_timestamp_
->GetTimestamp());
253 next_timestamp_
->AddFrames(frames
.value
);
255 DeliverBuffer(AudioDecoder::kOk
, buffer
);
258 void DeliverEndOfStream() {
259 DCHECK(!decode_cb_
.is_null());
261 // Return EOS buffer to trigger EOS frame.
262 EXPECT_CALL(demuxer_stream_
, Read(_
))
263 .WillOnce(RunCallback
<0>(DemuxerStream::kOk
,
264 DecoderBuffer::CreateEOSBuffer()));
266 // Satify pending |decode_cb_| to trigger a new DemuxerStream::Read().
267 message_loop_
.PostTask(
269 base::Bind(base::ResetAndReturn(&decode_cb_
), AudioDecoder::kOk
));
271 WaitForPendingRead();
273 message_loop_
.PostTask(
275 base::Bind(base::ResetAndReturn(&decode_cb_
), AudioDecoder::kOk
));
277 base::RunLoop().RunUntilIdle();
280 // Delivers frames until |renderer_|'s internal buffer is full and no longer
281 // has pending reads.
282 void DeliverRemainingAudio() {
283 while (frames_remaining_in_buffer().value
> 0) {
284 SatisfyPendingRead(InputFrames(256));
288 // Attempts to consume |requested_frames| frames from |renderer_|'s internal
289 // buffer. Returns true if and only if all of |requested_frames| were able
291 bool ConsumeBufferedData(OutputFrames requested_frames
) {
292 scoped_ptr
<AudioBus
> bus
=
293 AudioBus::Create(kChannels
, requested_frames
.value
);
295 EXPECT_TRUE(sink_
->Render(bus
.get(), 0, &frames_read
));
296 return frames_read
== requested_frames
.value
;
299 OutputFrames
frames_buffered() {
300 return OutputFrames(renderer_
->algorithm_
->frames_buffered());
303 OutputFrames
buffer_capacity() {
304 return OutputFrames(renderer_
->algorithm_
->QueueCapacity());
307 OutputFrames
frames_remaining_in_buffer() {
308 // This can happen if too much data was delivered, in which case the buffer
309 // will accept the data but not increase capacity.
310 if (frames_buffered().value
> buffer_capacity().value
) {
311 return OutputFrames(0);
313 return OutputFrames(buffer_capacity().value
- frames_buffered().value
);
316 void force_config_change() {
317 renderer_
->OnConfigChange();
320 InputFrames
converter_input_frames_left() const {
322 renderer_
->buffer_converter_
->input_frames_left_for_testing());
325 bool splicer_has_next_buffer() const {
326 return renderer_
->splicer_
->HasNextBuffer();
329 base::TimeDelta
CurrentMediaTime() {
330 return renderer_
->CurrentMediaTime();
333 bool ended() const { return ended_
; }
336 base::MessageLoop message_loop_
;
337 scoped_ptr
<AudioRendererImpl
> renderer_
;
338 scoped_refptr
<FakeAudioRendererSink
> sink_
;
339 AudioHardwareConfig hardware_config_
;
342 void DecodeDecoder(const scoped_refptr
<DecoderBuffer
>& buffer
,
343 const AudioDecoder::DecodeCB
& decode_cb
) {
344 // TODO(scherkus): Make this a DCHECK after threading semantics are fixed.
345 if (base::MessageLoop::current() != &message_loop_
) {
346 message_loop_
.PostTask(FROM_HERE
, base::Bind(
347 &AudioRendererImplTest::DecodeDecoder
,
348 base::Unretained(this), buffer
, decode_cb
));
352 CHECK(decode_cb_
.is_null()) << "Overlapping decodes are not permitted";
353 decode_cb_
= decode_cb
;
355 // Wake up WaitForPendingRead() if needed.
356 if (!wait_for_pending_decode_cb_
.is_null())
357 base::ResetAndReturn(&wait_for_pending_decode_cb_
).Run();
360 void ResetDecoder(const base::Closure
& reset_cb
) {
361 if (!decode_cb_
.is_null()) {
362 // |reset_cb| will be called in DeliverBuffer(), after the decoder is
364 reset_cb_
= reset_cb
;
368 message_loop_
.PostTask(FROM_HERE
, reset_cb
);
371 void DeliverBuffer(AudioDecoder::Status status
,
372 const scoped_refptr
<AudioBuffer
>& buffer
) {
373 CHECK(!decode_cb_
.is_null());
374 if (buffer
.get() && !buffer
->end_of_stream())
375 output_cb_
.Run(buffer
);
376 base::ResetAndReturn(&decode_cb_
).Run(status
);
378 if (!reset_cb_
.is_null())
379 base::ResetAndReturn(&reset_cb_
).Run();
381 base::RunLoop().RunUntilIdle();
389 MockDemuxerStream demuxer_stream_
;
390 MockAudioDecoder
* decoder_
;
392 // Used for satisfying reads.
393 AudioDecoder::OutputCB output_cb_
;
394 AudioDecoder::DecodeCB decode_cb_
;
395 base::Closure reset_cb_
;
396 scoped_ptr
<AudioTimestampHelper
> next_timestamp_
;
398 // Run during DecodeDecoder() to unblock WaitForPendingRead().
399 base::Closure wait_for_pending_decode_cb_
;
401 PipelineStatusCB init_decoder_cb_
;
404 DISALLOW_COPY_AND_ASSIGN(AudioRendererImplTest
);
407 TEST_F(AudioRendererImplTest
, Initialize_Successful
) {
411 TEST_F(AudioRendererImplTest
, Initialize_DecoderInitFailure
) {
412 ExpectUnsupportedAudioDecoder();
413 InitializeWithStatus(DECODER_ERROR_NOT_SUPPORTED
);
416 TEST_F(AudioRendererImplTest
, Preroll
) {
421 TEST_F(AudioRendererImplTest
, StartTicking
) {
426 // Drain internal buffer, we should have a pending read.
427 EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
428 WaitForPendingRead();
431 TEST_F(AudioRendererImplTest
, EndOfStream
) {
436 // Drain internal buffer, we should have a pending read.
437 EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
438 WaitForPendingRead();
440 // Forcefully trigger underflow.
441 EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
442 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING
));
444 // Fulfill the read with an end-of-stream buffer. Doing so should change our
445 // buffering state so playback resumes.
446 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH
));
447 DeliverEndOfStream();
449 // Consume all remaining data. We shouldn't have signal ended yet.
450 EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
451 base::RunLoop().RunUntilIdle();
452 EXPECT_FALSE(ended());
454 // Ended should trigger on next render call.
455 EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
456 base::RunLoop().RunUntilIdle();
457 EXPECT_TRUE(ended());
460 TEST_F(AudioRendererImplTest
, Underflow
) {
465 // Drain internal buffer, we should have a pending read.
466 EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
467 WaitForPendingRead();
469 // Verify the next FillBuffer() call triggers a buffering state change
471 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING
));
472 EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
474 // Verify we're still not getting audio data.
475 EXPECT_EQ(0, frames_buffered().value
);
476 EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
478 // Deliver enough data to have enough for buffering.
479 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH
));
480 DeliverRemainingAudio();
482 // Verify we're getting audio data.
483 EXPECT_TRUE(ConsumeBufferedData(OutputFrames(1)));
486 TEST_F(AudioRendererImplTest
, Underflow_CapacityResetsAfterFlush
) {
491 // Drain internal buffer, we should have a pending read.
492 EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
493 WaitForPendingRead();
495 // Verify the next FillBuffer() call triggers the underflow callback
496 // since the decoder hasn't delivered any data after it was drained.
497 OutputFrames initial_capacity
= buffer_capacity();
498 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING
));
499 EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
501 // Verify that the buffer capacity increased as a result of underflowing.
502 EXPECT_GT(buffer_capacity().value
, initial_capacity
.value
);
504 // Verify that the buffer capacity is restored to the |initial_capacity|.
505 FlushDuringPendingRead();
506 EXPECT_EQ(buffer_capacity().value
, initial_capacity
.value
);
509 TEST_F(AudioRendererImplTest
, Underflow_Flush
) {
515 EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
516 WaitForPendingRead();
517 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING
));
518 EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
519 WaitForPendingRead();
522 // We shouldn't expect another buffering state change when flushing.
523 FlushDuringPendingRead();
526 TEST_F(AudioRendererImplTest
, PendingRead_Flush
) {
532 // Partially drain internal buffer so we get a pending read.
533 EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
534 WaitForPendingRead();
538 EXPECT_TRUE(IsReadPending());
540 // Flush and expect to be notified that we have nothing.
541 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING
));
542 FlushDuringPendingRead();
544 // Preroll again to a different timestamp and verify it completed normally.
545 const base::TimeDelta seek_timestamp
=
546 base::TimeDelta::FromMilliseconds(1000);
547 Preroll(seek_timestamp
, seek_timestamp
, PIPELINE_OK
);
550 TEST_F(AudioRendererImplTest
, PendingRead_Destroy
) {
556 // Partially drain internal buffer so we get a pending read.
557 EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
558 WaitForPendingRead();
562 EXPECT_TRUE(IsReadPending());
567 TEST_F(AudioRendererImplTest
, PendingFlush_Destroy
) {
573 // Partially drain internal buffer so we get a pending read.
574 EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
575 WaitForPendingRead();
579 EXPECT_TRUE(IsReadPending());
582 WaitableMessageLoopEvent flush_event
;
583 renderer_
->Flush(flush_event
.GetClosure());
585 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING
));
586 SatisfyPendingRead(InputFrames(256));
591 TEST_F(AudioRendererImplTest
, InitializeThenDestroy
) {
592 InitializeAndDestroy();
595 TEST_F(AudioRendererImplTest
, InitializeThenDestroyDuringDecoderInit
) {
596 InitializeAndDestroyDuringDecoderInit();
599 TEST_F(AudioRendererImplTest
, ConfigChangeDrainsConverter
) {
604 // Drain internal buffer, we should have a pending read.
605 EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
606 WaitForPendingRead();
608 // Deliver a little bit of data. Use an odd data size to ensure there is data
609 // left in the AudioBufferConverter. Ensure no buffers are in the splicer.
610 SatisfyPendingRead(InputFrames(2053));
611 EXPECT_FALSE(splicer_has_next_buffer());
612 EXPECT_GT(converter_input_frames_left().value
, 0);
614 // Force a config change and then ensure all buffered data has been put into
616 force_config_change();
617 EXPECT_TRUE(splicer_has_next_buffer());
618 EXPECT_EQ(0, converter_input_frames_left().value
);
621 TEST_F(AudioRendererImplTest
, TimeUpdatesOnFirstBuffer
) {
626 AudioTimestampHelper
timestamp_helper(kOutputSamplesPerSecond
);
627 timestamp_helper
.SetBaseTimestamp(base::TimeDelta());
629 // Time should be the starting timestamp as nothing's been consumed yet.
630 EXPECT_EQ(timestamp_helper
.GetTimestamp(), CurrentMediaTime());
632 // Consume some audio data.
633 OutputFrames
frames_to_consume(frames_buffered().value
/ 2);
634 EXPECT_TRUE(ConsumeBufferedData(frames_to_consume
));
635 WaitForPendingRead();
637 // Time shouldn't change just yet because we've only sent the initial audio
638 // data to the hardware.
639 EXPECT_EQ(timestamp_helper
.GetTimestamp(), CurrentMediaTime());
641 // Consume some more audio data.
642 frames_to_consume
= frames_buffered();
643 EXPECT_TRUE(ConsumeBufferedData(frames_to_consume
));
645 // Now time should change now that the audio hardware has called back.
646 timestamp_helper
.AddFrames(frames_to_consume
.value
);
647 EXPECT_EQ(timestamp_helper
.GetTimestamp(), CurrentMediaTime());
650 TEST_F(AudioRendererImplTest
, RenderingDelayedForEarlyStartTime
) {
653 // Choose a first timestamp a few buffers into the future, which ends halfway
654 // through the desired output buffer; this allows for maximum test coverage.
655 const double kBuffers
= 4.5;
656 const base::TimeDelta first_timestamp
= base::TimeDelta::FromSecondsD(
657 hardware_config_
.GetOutputBufferSize() * kBuffers
/
658 hardware_config_
.GetOutputSampleRate());
660 Preroll(base::TimeDelta(), first_timestamp
, PIPELINE_OK
);
663 // Verify the first few buffers are silent.
664 scoped_ptr
<AudioBus
> bus
=
665 AudioBus::Create(hardware_config_
.GetOutputConfig());
667 for (int i
= 0; i
< std::floor(kBuffers
); ++i
) {
668 EXPECT_TRUE(sink_
->Render(bus
.get(), 0, &frames_read
));
669 EXPECT_EQ(frames_read
, bus
->frames());
670 for (int j
= 0; j
< bus
->frames(); ++j
)
671 ASSERT_FLOAT_EQ(0.0f
, bus
->channel(0)[j
]);
672 WaitForPendingRead();
673 DeliverRemainingAudio();
676 // Verify the last buffer is half silence and half real data.
677 EXPECT_TRUE(sink_
->Render(bus
.get(), 0, &frames_read
));
678 EXPECT_EQ(frames_read
, bus
->frames());
679 const int zero_frames
=
680 bus
->frames() * (kBuffers
- static_cast<int>(kBuffers
));
682 for (int i
= 0; i
< zero_frames
; ++i
)
683 ASSERT_FLOAT_EQ(0.0f
, bus
->channel(0)[i
]);
684 for (int i
= zero_frames
; i
< bus
->frames(); ++i
)
685 ASSERT_NE(0.0f
, bus
->channel(0)[i
]);
688 TEST_F(AudioRendererImplTest
, ImmediateEndOfStream
) {
691 SCOPED_TRACE("Preroll()");
692 renderer_
->StartPlaying();
693 WaitForPendingRead();
694 EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH
));
695 DeliverEndOfStream();
699 // Read a single frame. We shouldn't be able to satisfy it.
700 EXPECT_FALSE(ended());
701 EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
702 base::RunLoop().RunUntilIdle();
703 EXPECT_TRUE(ended());
706 TEST_F(AudioRendererImplTest
, OnRenderErrorCausesDecodeError
) {
711 EXPECT_CALL(*this, OnError(PIPELINE_ERROR_DECODE
));
712 sink_
->OnRenderError();
713 base::RunLoop().RunUntilIdle();
716 // Test for AudioRendererImpl calling Pause()/Play() on the sink when the
717 // playback rate is set to zero and non-zero.
718 TEST_F(AudioRendererImplTest
, SetPlaybackRate
) {
722 // Rendering hasn't started. Sink should always be paused.
723 EXPECT_EQ(FakeAudioRendererSink::kPaused
, sink_
->state());
724 renderer_
->SetPlaybackRate(0.0f
);
725 EXPECT_EQ(FakeAudioRendererSink::kPaused
, sink_
->state());
726 renderer_
->SetPlaybackRate(1.0f
);
727 EXPECT_EQ(FakeAudioRendererSink::kPaused
, sink_
->state());
729 // Rendering has started with non-zero rate. Rate changes will affect sink
731 renderer_
->StartTicking();
732 EXPECT_EQ(FakeAudioRendererSink::kPlaying
, sink_
->state());
733 renderer_
->SetPlaybackRate(0.0f
);
734 EXPECT_EQ(FakeAudioRendererSink::kPaused
, sink_
->state());
735 renderer_
->SetPlaybackRate(1.0f
);
736 EXPECT_EQ(FakeAudioRendererSink::kPlaying
, sink_
->state());
738 // Rendering has stopped. Sink should be paused.
739 renderer_
->StopTicking();
740 EXPECT_EQ(FakeAudioRendererSink::kPaused
, sink_
->state());
742 // Start rendering with zero playback rate. Sink should be paused until
743 // non-zero rate is set.
744 renderer_
->SetPlaybackRate(0.0f
);
745 renderer_
->StartTicking();
746 EXPECT_EQ(FakeAudioRendererSink::kPaused
, sink_
->state());
747 renderer_
->SetPlaybackRate(1.0f
);
748 EXPECT_EQ(FakeAudioRendererSink::kPlaying
, sink_
->state());