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.
5 #include "media/filters/audio_renderer_impl.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/callback_helpers.h"
14 #include "base/logging.h"
15 #include "base/metrics/histogram.h"
16 #include "base/single_thread_task_runner.h"
17 #include "media/base/audio_buffer.h"
18 #include "media/base/audio_splicer.h"
19 #include "media/base/bind_to_current_loop.h"
20 #include "media/base/demuxer_stream.h"
21 #include "media/filters/decrypting_demuxer_stream.h"
27 enum AudioRendererEvent
{
33 void HistogramRendererEvent(AudioRendererEvent event
) {
34 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event
, MAX_EVENTS
);
39 AudioRendererImpl::AudioRendererImpl(
40 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
,
41 media::AudioRendererSink
* sink
,
42 ScopedVector
<AudioDecoder
> decoders
,
43 const SetDecryptorReadyCB
& set_decryptor_ready_cb
)
44 : task_runner_(task_runner
),
47 decoder_selector_(new AudioDecoderSelector(
48 task_runner
, decoders
.Pass(), set_decryptor_ready_cb
)),
49 now_cb_(base::Bind(&base::TimeTicks::Now
)),
50 state_(kUninitialized
),
53 received_end_of_stream_(false),
54 rendered_end_of_stream_(false),
55 audio_time_buffered_(kNoTimestamp()),
56 current_time_(kNoTimestamp()),
57 underflow_disabled_(false),
58 preroll_aborted_(false) {
61 AudioRendererImpl::~AudioRendererImpl() {
62 // Stop() should have been called and |algorithm_| should have been destroyed.
63 DCHECK(state_
== kUninitialized
|| state_
== kStopped
);
64 DCHECK(!algorithm_
.get());
67 void AudioRendererImpl::Play(const base::Closure
& callback
) {
68 DCHECK(task_runner_
->BelongsToCurrentThread());
70 base::AutoLock
auto_lock(lock_
);
71 DCHECK_EQ(state_
, kPaused
);
72 ChangeState_Locked(kPlaying
);
74 earliest_end_time_
= now_cb_
.Run();
76 if (algorithm_
->playback_rate() != 0)
79 DCHECK(!sink_playing_
);
82 void AudioRendererImpl::DoPlay_Locked() {
83 DCHECK(task_runner_
->BelongsToCurrentThread());
84 lock_
.AssertAcquired();
85 earliest_end_time_
= now_cb_
.Run();
87 if ((state_
== kPlaying
|| state_
== kRebuffering
|| state_
== kUnderflow
) &&
90 base::AutoUnlock
auto_unlock(lock_
);
98 void AudioRendererImpl::Pause(const base::Closure
& callback
) {
99 DCHECK(task_runner_
->BelongsToCurrentThread());
101 base::AutoLock
auto_lock(lock_
);
102 DCHECK(state_
== kPlaying
|| state_
== kUnderflow
||
103 state_
== kRebuffering
) << "state_ == " << state_
;
104 ChangeState_Locked(kPaused
);
111 void AudioRendererImpl::DoPause_Locked() {
112 DCHECK(task_runner_
->BelongsToCurrentThread());
113 lock_
.AssertAcquired();
117 base::AutoUnlock
auto_unlock(lock_
);
120 sink_playing_
= false;
124 void AudioRendererImpl::Flush(const base::Closure
& callback
) {
125 DCHECK(task_runner_
->BelongsToCurrentThread());
127 base::AutoLock
auto_lock(lock_
);
128 DCHECK_EQ(state_
, kPaused
);
129 DCHECK(flush_cb_
.is_null());
131 flush_cb_
= callback
;
134 ChangeState_Locked(kFlushing
);
141 void AudioRendererImpl::DoFlush_Locked() {
142 DCHECK(task_runner_
->BelongsToCurrentThread());
143 lock_
.AssertAcquired();
145 DCHECK(!pending_read_
);
146 DCHECK_EQ(state_
, kPaused
);
148 if (decrypting_demuxer_stream_
) {
149 decrypting_demuxer_stream_
->Reset(
150 base::Bind(&AudioRendererImpl::ResetDecoder
, weak_this_
));
157 void AudioRendererImpl::ResetDecoder() {
158 DCHECK(task_runner_
->BelongsToCurrentThread());
159 decoder_
->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone
, weak_this_
));
162 void AudioRendererImpl::ResetDecoderDone() {
163 DCHECK(task_runner_
->BelongsToCurrentThread());
165 base::AutoLock
auto_lock(lock_
);
166 if (state_
== kStopped
)
169 DCHECK_EQ(state_
, kPaused
);
170 DCHECK(!flush_cb_
.is_null());
172 audio_time_buffered_
= kNoTimestamp();
173 current_time_
= kNoTimestamp();
174 received_end_of_stream_
= false;
175 rendered_end_of_stream_
= false;
176 preroll_aborted_
= false;
178 earliest_end_time_
= now_cb_
.Run();
180 algorithm_
->FlushBuffers();
182 base::ResetAndReturn(&flush_cb_
).Run();
185 void AudioRendererImpl::Stop(const base::Closure
& callback
) {
186 DCHECK(task_runner_
->BelongsToCurrentThread());
187 DCHECK(!callback
.is_null());
188 DCHECK(stop_cb_
.is_null());
192 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
193 // task-running guards that check |state_| with DCHECK().
196 base::AutoLock
auto_lock(lock_
);
197 if (state_
== kInitializing
) {
198 decoder_selector_
->Abort();
202 if (state_
== kStopped
) {
203 task_runner_
->PostTask(FROM_HERE
, base::ResetAndReturn(&stop_cb_
));
207 ChangeState_Locked(kStopped
);
209 underflow_cb_
.Reset();
219 if (decrypting_demuxer_stream_
) {
220 decrypting_demuxer_stream_
->Stop(
221 base::Bind(&AudioRendererImpl::StopDecoder
, weak_this_
));
228 void AudioRendererImpl::StopDecoder() {
229 DCHECK(task_runner_
->BelongsToCurrentThread());
230 DCHECK(!stop_cb_
.is_null());
233 decoder_
->Stop(base::ResetAndReturn(&stop_cb_
));
237 task_runner_
->PostTask(FROM_HERE
, base::ResetAndReturn(&stop_cb_
));
240 void AudioRendererImpl::Preroll(base::TimeDelta time
,
241 const PipelineStatusCB
& cb
) {
242 DCHECK(task_runner_
->BelongsToCurrentThread());
244 base::AutoLock
auto_lock(lock_
);
245 DCHECK(!sink_playing_
);
246 DCHECK_EQ(state_
, kPaused
);
247 DCHECK(!pending_read_
) << "Pending read must complete before seeking";
248 DCHECK(preroll_cb_
.is_null());
250 ChangeState_Locked(kPrerolling
);
252 preroll_timestamp_
= time
;
254 AttemptRead_Locked();
257 void AudioRendererImpl::Initialize(DemuxerStream
* stream
,
258 const PipelineStatusCB
& init_cb
,
259 const StatisticsCB
& statistics_cb
,
260 const base::Closure
& underflow_cb
,
261 const TimeCB
& time_cb
,
262 const base::Closure
& ended_cb
,
263 const base::Closure
& disabled_cb
,
264 const PipelineStatusCB
& error_cb
) {
265 DCHECK(task_runner_
->BelongsToCurrentThread());
267 DCHECK_EQ(stream
->type(), DemuxerStream::AUDIO
);
268 DCHECK(!init_cb
.is_null());
269 DCHECK(!statistics_cb
.is_null());
270 DCHECK(!underflow_cb
.is_null());
271 DCHECK(!time_cb
.is_null());
272 DCHECK(!ended_cb
.is_null());
273 DCHECK(!disabled_cb
.is_null());
274 DCHECK(!error_cb
.is_null());
275 DCHECK_EQ(kUninitialized
, state_
);
278 state_
= kInitializing
;
280 weak_this_
= weak_factory_
.GetWeakPtr();
282 statistics_cb_
= statistics_cb
;
283 underflow_cb_
= underflow_cb
;
285 ended_cb_
= ended_cb
;
286 disabled_cb_
= disabled_cb
;
287 error_cb_
= error_cb
;
289 decoder_selector_
->SelectDecoder(
292 base::Bind(&AudioRendererImpl::OnDecoderSelected
, weak_this_
));
295 void AudioRendererImpl::OnDecoderSelected(
296 scoped_ptr
<AudioDecoder
> decoder
,
297 scoped_ptr
<DecryptingDemuxerStream
> decrypting_demuxer_stream
) {
298 DCHECK(task_runner_
->BelongsToCurrentThread());
300 scoped_ptr
<AudioDecoderSelector
> deleter(decoder_selector_
.Pass());
301 decoder_
= decoder
.Pass();
303 if (!decoder_
|| !stop_cb_
.is_null()) {
305 base::AutoLock
auto_lock(lock_
);
306 ChangeState_Locked(kUninitialized
);
308 // Stop() called during initialization.
309 if (!stop_cb_
.is_null()) {
310 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_ERROR_ABORT
);
311 Stop(base::ResetAndReturn(&stop_cb_
));
313 base::ResetAndReturn(&init_cb_
).Run(DECODER_ERROR_NOT_SUPPORTED
);
318 base::AutoLock
auto_lock(lock_
);
319 decrypting_demuxer_stream_
= decrypting_demuxer_stream
.Pass();
321 int sample_rate
= decoder_
->samples_per_second();
323 // The actual buffer size is controlled via the size of the AudioBus
324 // provided to Render(), so just choose something reasonable here for looks.
325 int buffer_size
= decoder_
->samples_per_second() / 100;
326 audio_parameters_
= AudioParameters(
327 AudioParameters::AUDIO_PCM_LOW_LATENCY
, decoder_
->channel_layout(),
328 sample_rate
, decoder_
->bits_per_channel(), buffer_size
);
329 if (!audio_parameters_
.IsValid()) {
330 ChangeState_Locked(kUninitialized
);
331 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_ERROR_INITIALIZATION_FAILED
);
335 splicer_
.reset(new AudioSplicer(sample_rate
));
337 // We're all good! Continue initializing the rest of the audio renderer
338 // based on the decoder format.
339 algorithm_
.reset(new AudioRendererAlgorithm());
340 algorithm_
->Initialize(0, audio_parameters_
);
342 ChangeState_Locked(kPaused
);
344 HistogramRendererEvent(INITIALIZED
);
347 base::AutoUnlock
auto_unlock(lock_
);
348 sink_
->Initialize(audio_parameters_
, weak_this_
.get());
351 // Some sinks play on start...
355 DCHECK(!sink_playing_
);
357 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_OK
);
360 void AudioRendererImpl::ResumeAfterUnderflow() {
361 DCHECK(task_runner_
->BelongsToCurrentThread());
362 base::AutoLock
auto_lock(lock_
);
363 if (state_
== kUnderflow
) {
364 // The "!preroll_aborted_" is a hack. If preroll is aborted, then we
365 // shouldn't even reach the kUnderflow state to begin with. But for now
366 // we're just making sure that the audio buffer capacity (i.e. the
367 // number of bytes that need to be buffered for preroll to complete)
368 // does not increase due to an aborted preroll.
369 // TODO(vrk): Fix this bug correctly! (crbug.com/151352)
370 if (!preroll_aborted_
)
371 algorithm_
->IncreaseQueueCapacity();
373 ChangeState_Locked(kRebuffering
);
377 void AudioRendererImpl::SetVolume(float volume
) {
378 DCHECK(task_runner_
->BelongsToCurrentThread());
380 sink_
->SetVolume(volume
);
383 void AudioRendererImpl::DecodedAudioReady(
384 AudioDecoder::Status status
,
385 const scoped_refptr
<AudioBuffer
>& buffer
) {
386 DVLOG(1) << __FUNCTION__
<< "(" << status
<< ")";
387 DCHECK(task_runner_
->BelongsToCurrentThread());
389 base::AutoLock
auto_lock(lock_
);
390 DCHECK(state_
!= kUninitialized
);
392 CHECK(pending_read_
);
393 pending_read_
= false;
395 if (status
== AudioDecoder::kAborted
) {
396 HandleAbortedReadOrDecodeError(false);
400 if (status
== AudioDecoder::kDecodeError
) {
401 HandleAbortedReadOrDecodeError(true);
405 DCHECK_EQ(status
, AudioDecoder::kOk
);
406 DCHECK(buffer
.get());
408 if (state_
== kFlushing
) {
409 ChangeState_Locked(kPaused
);
414 if (!splicer_
->AddInput(buffer
)) {
415 HandleAbortedReadOrDecodeError(true);
419 if (!splicer_
->HasNextBuffer()) {
420 AttemptRead_Locked();
424 bool need_another_buffer
= false;
425 while (splicer_
->HasNextBuffer())
426 need_another_buffer
= HandleSplicerBuffer(splicer_
->GetNextBuffer());
428 if (!need_another_buffer
&& !CanRead_Locked())
431 AttemptRead_Locked();
434 bool AudioRendererImpl::HandleSplicerBuffer(
435 const scoped_refptr
<AudioBuffer
>& buffer
) {
436 if (buffer
->end_of_stream()) {
437 received_end_of_stream_
= true;
439 // Transition to kPlaying if we are currently handling an underflow since
440 // no more data will be arriving.
441 if (state_
== kUnderflow
|| state_
== kRebuffering
)
442 ChangeState_Locked(kPlaying
);
444 if (state_
== kPrerolling
) {
445 if (IsBeforePrerollTime(buffer
))
448 // Trim off any additional time before the preroll timestamp.
449 const base::TimeDelta trim_time
=
450 preroll_timestamp_
- buffer
->timestamp();
451 if (trim_time
> base::TimeDelta()) {
452 buffer
->TrimStart(buffer
->frame_count() *
453 (static_cast<double>(trim_time
.InMicroseconds()) /
454 buffer
->duration().InMicroseconds()));
456 // If the entire buffer was trimmed, request a new one.
457 if (!buffer
->frame_count())
461 if (state_
!= kUninitialized
&& state_
!= kStopped
)
462 algorithm_
->EnqueueBuffer(buffer
);
473 DCHECK(!pending_read_
);
477 if (!buffer
->end_of_stream() && !algorithm_
->IsQueueFull())
479 ChangeState_Locked(kPaused
);
480 base::ResetAndReturn(&preroll_cb_
).Run(PIPELINE_OK
);
488 if (!algorithm_
->IsQueueFull())
490 ChangeState_Locked(kPlaying
);
499 void AudioRendererImpl::AttemptRead() {
500 base::AutoLock
auto_lock(lock_
);
501 AttemptRead_Locked();
504 void AudioRendererImpl::AttemptRead_Locked() {
505 DCHECK(task_runner_
->BelongsToCurrentThread());
506 lock_
.AssertAcquired();
508 if (!CanRead_Locked())
511 pending_read_
= true;
512 decoder_
->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady
, weak_this_
));
515 bool AudioRendererImpl::CanRead_Locked() {
516 lock_
.AssertAcquired();
533 return !pending_read_
&& !received_end_of_stream_
&&
534 !algorithm_
->IsQueueFull();
537 void AudioRendererImpl::SetPlaybackRate(float playback_rate
) {
538 DVLOG(1) << __FUNCTION__
<< "(" << playback_rate
<< ")";
539 DCHECK(task_runner_
->BelongsToCurrentThread());
540 DCHECK_GE(playback_rate
, 0);
543 base::AutoLock
auto_lock(lock_
);
545 // We have two cases here:
546 // Play: current_playback_rate == 0 && playback_rate != 0
547 // Pause: current_playback_rate != 0 && playback_rate == 0
548 float current_playback_rate
= algorithm_
->playback_rate();
549 if (current_playback_rate
== 0 && playback_rate
!= 0)
551 else if (current_playback_rate
!= 0 && playback_rate
== 0)
554 algorithm_
->SetPlaybackRate(playback_rate
);
557 bool AudioRendererImpl::IsBeforePrerollTime(
558 const scoped_refptr
<AudioBuffer
>& buffer
) {
559 DCHECK_EQ(state_
, kPrerolling
);
560 return buffer
&& !buffer
->end_of_stream() &&
561 (buffer
->timestamp() + buffer
->duration()) < preroll_timestamp_
;
564 int AudioRendererImpl::Render(AudioBus
* audio_bus
,
565 int audio_delay_milliseconds
) {
566 const int requested_frames
= audio_bus
->frames();
567 base::TimeDelta current_time
= kNoTimestamp();
568 base::TimeDelta max_time
= kNoTimestamp();
569 base::TimeDelta playback_delay
= base::TimeDelta::FromMilliseconds(
570 audio_delay_milliseconds
);
572 int frames_written
= 0;
573 base::Closure underflow_cb
;
575 base::AutoLock
auto_lock(lock_
);
577 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
581 float playback_rate
= algorithm_
->playback_rate();
582 if (playback_rate
== 0)
585 // Mute audio by returning 0 when not playing.
586 if (state_
!= kPlaying
)
589 // We use the following conditions to determine end of playback:
590 // 1) Algorithm can not fill the audio callback buffer
591 // 2) We received an end of stream buffer
592 // 3) We haven't already signalled that we've ended
593 // 4) Our estimated earliest end time has expired
595 // TODO(enal): we should replace (4) with a check that the browser has no
596 // more audio data or at least use a delayed callback.
598 // We use the following conditions to determine underflow:
599 // 1) Algorithm can not fill the audio callback buffer
600 // 2) We have NOT received an end of stream buffer
601 // 3) We are in the kPlaying state
603 // Otherwise the buffer has data we can send to the device.
604 frames_written
= algorithm_
->FillBuffer(audio_bus
, requested_frames
);
605 if (frames_written
== 0) {
606 const base::TimeTicks now
= now_cb_
.Run();
608 if (received_end_of_stream_
&& !rendered_end_of_stream_
&&
609 now
>= earliest_end_time_
) {
610 rendered_end_of_stream_
= true;
612 } else if (!received_end_of_stream_
&& state_
== kPlaying
&&
613 !underflow_disabled_
) {
614 ChangeState_Locked(kUnderflow
);
615 underflow_cb
= underflow_cb_
;
617 // We can't write any data this cycle. For example, we may have
618 // sent all available data to the audio device while not reaching
619 // |earliest_end_time_|.
623 if (CanRead_Locked()) {
624 task_runner_
->PostTask(FROM_HERE
, base::Bind(
625 &AudioRendererImpl::AttemptRead
, weak_this_
));
628 // The |audio_time_buffered_| is the ending timestamp of the last frame
629 // buffered at the audio device. |playback_delay| is the amount of time
630 // buffered at the audio device. The current time can be computed by their
632 if (audio_time_buffered_
!= kNoTimestamp()) {
633 // Adjust the delay according to playback rate.
634 base::TimeDelta adjusted_playback_delay
=
635 base::TimeDelta::FromMicroseconds(ceil(
636 playback_delay
.InMicroseconds() * playback_rate
));
638 base::TimeDelta previous_time
= current_time_
;
639 current_time_
= audio_time_buffered_
- adjusted_playback_delay
;
641 // Time can change in one of two ways:
642 // 1) The time of the audio data at the audio device changed, or
643 // 2) The playback delay value has changed
645 // We only want to set |current_time| (and thus execute |time_cb_|) if
646 // time has progressed and we haven't signaled end of stream yet.
648 // Why? The current latency of the system results in getting the last call
649 // to FillBuffer() later than we'd like, which delays firing the 'ended'
650 // event, which delays the looping/trigging performance of short sound
653 // TODO(scherkus): revisit this and switch back to relying on playback
654 // delay after we've revamped our audio IPC subsystem.
655 if (current_time_
> previous_time
&& !rendered_end_of_stream_
) {
656 current_time
= current_time_
;
660 // The call to FillBuffer() on |algorithm_| has increased the amount of
661 // buffered audio data. Update the new amount of time buffered.
662 max_time
= algorithm_
->GetTime();
663 audio_time_buffered_
= max_time
;
665 if (frames_written
> 0) {
666 UpdateEarliestEndTime_Locked(
667 frames_written
, playback_delay
, now_cb_
.Run());
671 if (current_time
!= kNoTimestamp() && max_time
!= kNoTimestamp())
672 time_cb_
.Run(current_time
, max_time
);
674 if (!underflow_cb
.is_null())
677 DCHECK_LE(frames_written
, requested_frames
);
678 return frames_written
;
681 void AudioRendererImpl::UpdateEarliestEndTime_Locked(
682 int frames_filled
, const base::TimeDelta
& playback_delay
,
683 const base::TimeTicks
& time_now
) {
684 DCHECK_GT(frames_filled
, 0);
686 base::TimeDelta predicted_play_time
= base::TimeDelta::FromMicroseconds(
687 static_cast<float>(frames_filled
) * base::Time::kMicrosecondsPerSecond
/
688 audio_parameters_
.sample_rate());
690 lock_
.AssertAcquired();
691 earliest_end_time_
= std::max(
692 earliest_end_time_
, time_now
+ playback_delay
+ predicted_play_time
);
695 void AudioRendererImpl::OnRenderError() {
696 HistogramRendererEvent(RENDER_ERROR
);
700 void AudioRendererImpl::DisableUnderflowForTesting() {
701 underflow_disabled_
= true;
704 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error
) {
705 lock_
.AssertAcquired();
707 PipelineStatus status
= is_decode_error
? PIPELINE_ERROR_DECODE
: PIPELINE_OK
;
714 if (status
!= PIPELINE_OK
)
715 error_cb_
.Run(status
);
718 ChangeState_Locked(kPaused
);
720 if (status
== PIPELINE_OK
) {
725 error_cb_
.Run(status
);
726 base::ResetAndReturn(&flush_cb_
).Run();
729 // This is a signal for abort if it's not an error.
730 preroll_aborted_
= !is_decode_error
;
731 ChangeState_Locked(kPaused
);
732 base::ResetAndReturn(&preroll_cb_
).Run(status
);
738 if (status
!= PIPELINE_OK
)
739 error_cb_
.Run(status
);
744 void AudioRendererImpl::ChangeState_Locked(State new_state
) {
745 DVLOG(1) << __FUNCTION__
<< " : " << state_
<< " -> " << new_state
;
746 lock_
.AssertAcquired();