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/audio_decoder_selector.h"
22 #include "media/filters/decrypting_demuxer_stream.h"
28 enum AudioRendererEvent
{
34 void HistogramRendererEvent(AudioRendererEvent event
) {
35 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event
, MAX_EVENTS
);
40 AudioRendererImpl::AudioRendererImpl(
41 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
,
42 media::AudioRendererSink
* sink
,
43 ScopedVector
<AudioDecoder
> decoders
,
44 const SetDecryptorReadyCB
& set_decryptor_ready_cb
)
45 : task_runner_(task_runner
),
48 decoder_selector_(new AudioDecoderSelector(
49 task_runner
, decoders
.Pass(), set_decryptor_ready_cb
)),
50 now_cb_(base::Bind(&base::TimeTicks::Now
)),
51 state_(kUninitialized
),
54 received_end_of_stream_(false),
55 rendered_end_of_stream_(false),
56 audio_time_buffered_(kNoTimestamp()),
57 current_time_(kNoTimestamp()),
58 underflow_disabled_(false),
59 preroll_aborted_(false) {
62 AudioRendererImpl::~AudioRendererImpl() {
63 // Stop() should have been called and |algorithm_| should have been destroyed.
64 DCHECK(state_
== kUninitialized
|| state_
== kStopped
);
65 DCHECK(!algorithm_
.get());
68 void AudioRendererImpl::Play(const base::Closure
& callback
) {
69 DCHECK(task_runner_
->BelongsToCurrentThread());
71 base::AutoLock
auto_lock(lock_
);
72 DCHECK_EQ(state_
, kPaused
);
73 ChangeState_Locked(kPlaying
);
75 earliest_end_time_
= now_cb_
.Run();
77 if (algorithm_
->playback_rate() != 0)
80 DCHECK(!sink_playing_
);
83 void AudioRendererImpl::DoPlay_Locked() {
84 DCHECK(task_runner_
->BelongsToCurrentThread());
85 lock_
.AssertAcquired();
86 earliest_end_time_
= now_cb_
.Run();
88 if ((state_
== kPlaying
|| state_
== kRebuffering
|| state_
== kUnderflow
) &&
91 base::AutoUnlock
auto_unlock(lock_
);
99 void AudioRendererImpl::Pause(const base::Closure
& callback
) {
100 DCHECK(task_runner_
->BelongsToCurrentThread());
102 base::AutoLock
auto_lock(lock_
);
103 DCHECK(state_
== kPlaying
|| state_
== kUnderflow
||
104 state_
== kRebuffering
) << "state_ == " << state_
;
105 ChangeState_Locked(kPaused
);
112 void AudioRendererImpl::DoPause_Locked() {
113 DCHECK(task_runner_
->BelongsToCurrentThread());
114 lock_
.AssertAcquired();
118 base::AutoUnlock
auto_unlock(lock_
);
121 sink_playing_
= false;
125 void AudioRendererImpl::Flush(const base::Closure
& callback
) {
126 DCHECK(task_runner_
->BelongsToCurrentThread());
128 base::AutoLock
auto_lock(lock_
);
129 DCHECK_EQ(state_
, kPaused
);
130 DCHECK(flush_cb_
.is_null());
132 flush_cb_
= callback
;
135 ChangeState_Locked(kFlushing
);
142 void AudioRendererImpl::DoFlush_Locked() {
143 DCHECK(task_runner_
->BelongsToCurrentThread());
144 lock_
.AssertAcquired();
146 DCHECK(!pending_read_
);
147 DCHECK_EQ(state_
, kPaused
);
149 if (decrypting_demuxer_stream_
) {
150 decrypting_demuxer_stream_
->Reset(BindToCurrentLoop(
151 base::Bind(&AudioRendererImpl::ResetDecoder
, weak_this_
)));
158 void AudioRendererImpl::ResetDecoder() {
159 DCHECK(task_runner_
->BelongsToCurrentThread());
160 decoder_
->Reset(BindToCurrentLoop(
161 base::Bind(&AudioRendererImpl::ResetDecoderDone
, weak_this_
)));
164 void AudioRendererImpl::ResetDecoderDone() {
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());
189 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
190 // task-running guards that check |state_| with DCHECK().
198 base::AutoLock
auto_lock(lock_
);
199 ChangeState_Locked(kStopped
);
200 algorithm_
.reset(NULL
);
202 underflow_cb_
.Reset();
210 void AudioRendererImpl::Preroll(base::TimeDelta time
,
211 const PipelineStatusCB
& cb
) {
212 DCHECK(task_runner_
->BelongsToCurrentThread());
214 base::AutoLock
auto_lock(lock_
);
215 DCHECK(!sink_playing_
);
216 DCHECK_EQ(state_
, kPaused
);
217 DCHECK(!pending_read_
) << "Pending read must complete before seeking";
218 DCHECK(preroll_cb_
.is_null());
220 ChangeState_Locked(kPrerolling
);
222 preroll_timestamp_
= time
;
224 AttemptRead_Locked();
227 void AudioRendererImpl::Initialize(DemuxerStream
* stream
,
228 const PipelineStatusCB
& init_cb
,
229 const StatisticsCB
& statistics_cb
,
230 const base::Closure
& underflow_cb
,
231 const TimeCB
& time_cb
,
232 const base::Closure
& ended_cb
,
233 const base::Closure
& disabled_cb
,
234 const PipelineStatusCB
& error_cb
) {
235 DCHECK(task_runner_
->BelongsToCurrentThread());
237 DCHECK_EQ(stream
->type(), DemuxerStream::AUDIO
);
238 DCHECK(!init_cb
.is_null());
239 DCHECK(!statistics_cb
.is_null());
240 DCHECK(!underflow_cb
.is_null());
241 DCHECK(!time_cb
.is_null());
242 DCHECK(!ended_cb
.is_null());
243 DCHECK(!disabled_cb
.is_null());
244 DCHECK(!error_cb
.is_null());
245 DCHECK_EQ(kUninitialized
, state_
);
248 weak_this_
= weak_factory_
.GetWeakPtr();
250 statistics_cb_
= statistics_cb
;
251 underflow_cb_
= underflow_cb
;
253 ended_cb_
= ended_cb
;
254 disabled_cb_
= disabled_cb
;
255 error_cb_
= error_cb
;
257 decoder_selector_
->SelectAudioDecoder(
260 base::Bind(&AudioRendererImpl::OnDecoderSelected
, weak_this_
));
263 void AudioRendererImpl::OnDecoderSelected(
264 scoped_ptr
<AudioDecoder
> decoder
,
265 scoped_ptr
<DecryptingDemuxerStream
> decrypting_demuxer_stream
) {
266 DCHECK(task_runner_
->BelongsToCurrentThread());
268 base::AutoLock
auto_lock(lock_
);
269 scoped_ptr
<AudioDecoderSelector
> deleter(decoder_selector_
.Pass());
271 if (state_
== kStopped
) {
277 base::ResetAndReturn(&init_cb_
).Run(DECODER_ERROR_NOT_SUPPORTED
);
281 decoder_
= decoder
.Pass();
282 decrypting_demuxer_stream_
= decrypting_demuxer_stream
.Pass();
284 int sample_rate
= decoder_
->samples_per_second();
286 // The actual buffer size is controlled via the size of the AudioBus provided
287 // to Render(), so just choose something reasonable here for looks.
288 int buffer_size
= decoder_
->samples_per_second() / 100;
289 audio_parameters_
= AudioParameters(
290 AudioParameters::AUDIO_PCM_LOW_LATENCY
, decoder_
->channel_layout(),
291 sample_rate
, decoder_
->bits_per_channel(), buffer_size
);
292 if (!audio_parameters_
.IsValid()) {
293 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_ERROR_INITIALIZATION_FAILED
);
297 splicer_
.reset(new AudioSplicer(sample_rate
));
299 // We're all good! Continue initializing the rest of the audio renderer based
300 // on the decoder format.
301 algorithm_
.reset(new AudioRendererAlgorithm());
302 algorithm_
->Initialize(0, audio_parameters_
);
304 ChangeState_Locked(kPaused
);
306 HistogramRendererEvent(INITIALIZED
);
309 base::AutoUnlock
auto_unlock(lock_
);
310 sink_
->Initialize(audio_parameters_
, weak_this_
.get());
313 // Some sinks play on start...
317 DCHECK(!sink_playing_
);
319 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_OK
);
322 void AudioRendererImpl::ResumeAfterUnderflow() {
323 DCHECK(task_runner_
->BelongsToCurrentThread());
324 base::AutoLock
auto_lock(lock_
);
325 if (state_
== kUnderflow
) {
326 // The "!preroll_aborted_" is a hack. If preroll is aborted, then we
327 // shouldn't even reach the kUnderflow state to begin with. But for now
328 // we're just making sure that the audio buffer capacity (i.e. the
329 // number of bytes that need to be buffered for preroll to complete)
330 // does not increase due to an aborted preroll.
331 // TODO(vrk): Fix this bug correctly! (crbug.com/151352)
332 if (!preroll_aborted_
)
333 algorithm_
->IncreaseQueueCapacity();
335 ChangeState_Locked(kRebuffering
);
339 void AudioRendererImpl::SetVolume(float volume
) {
340 DCHECK(task_runner_
->BelongsToCurrentThread());
342 sink_
->SetVolume(volume
);
345 void AudioRendererImpl::DecodedAudioReady(
346 AudioDecoder::Status status
,
347 const scoped_refptr
<AudioBuffer
>& buffer
) {
348 DVLOG(1) << __FUNCTION__
<< "(" << status
<< ")";
349 DCHECK(task_runner_
->BelongsToCurrentThread());
351 base::AutoLock
auto_lock(lock_
);
352 DCHECK(state_
!= kUninitialized
);
354 CHECK(pending_read_
);
355 pending_read_
= false;
357 if (status
== AudioDecoder::kAborted
) {
358 HandleAbortedReadOrDecodeError(false);
362 if (status
== AudioDecoder::kDecodeError
) {
363 HandleAbortedReadOrDecodeError(true);
367 DCHECK_EQ(status
, AudioDecoder::kOk
);
368 DCHECK(buffer
.get());
370 if (state_
== kFlushing
) {
371 ChangeState_Locked(kPaused
);
376 if (!splicer_
->AddInput(buffer
)) {
377 HandleAbortedReadOrDecodeError(true);
381 if (!splicer_
->HasNextBuffer()) {
382 AttemptRead_Locked();
386 bool need_another_buffer
= false;
387 while (splicer_
->HasNextBuffer())
388 need_another_buffer
= HandleSplicerBuffer(splicer_
->GetNextBuffer());
390 if (!need_another_buffer
&& !CanRead_Locked())
393 AttemptRead_Locked();
396 bool AudioRendererImpl::HandleSplicerBuffer(
397 const scoped_refptr
<AudioBuffer
>& buffer
) {
398 if (buffer
->end_of_stream()) {
399 received_end_of_stream_
= true;
401 // Transition to kPlaying if we are currently handling an underflow since
402 // no more data will be arriving.
403 if (state_
== kUnderflow
|| state_
== kRebuffering
)
404 ChangeState_Locked(kPlaying
);
406 if (state_
== kPrerolling
) {
407 if (IsBeforePrerollTime(buffer
))
410 // Trim off any additional time before the preroll timestamp.
411 const base::TimeDelta trim_time
=
412 preroll_timestamp_
- buffer
->timestamp();
413 if (trim_time
> base::TimeDelta()) {
414 buffer
->TrimStart(buffer
->frame_count() *
415 (static_cast<double>(trim_time
.InMicroseconds()) /
416 buffer
->duration().InMicroseconds()));
418 // If the entire buffer was trimmed, request a new one.
419 if (!buffer
->frame_count())
423 if (state_
!= kUninitialized
&& state_
!= kStopped
)
424 algorithm_
->EnqueueBuffer(buffer
);
434 DCHECK(!pending_read_
);
438 if (!buffer
->end_of_stream() && !algorithm_
->IsQueueFull())
440 ChangeState_Locked(kPaused
);
441 base::ResetAndReturn(&preroll_cb_
).Run(PIPELINE_OK
);
449 if (!algorithm_
->IsQueueFull())
451 ChangeState_Locked(kPlaying
);
460 void AudioRendererImpl::AttemptRead() {
461 base::AutoLock
auto_lock(lock_
);
462 AttemptRead_Locked();
465 void AudioRendererImpl::AttemptRead_Locked() {
466 DCHECK(task_runner_
->BelongsToCurrentThread());
467 lock_
.AssertAcquired();
469 if (!CanRead_Locked())
472 pending_read_
= true;
473 decoder_
->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady
, weak_this_
));
476 bool AudioRendererImpl::CanRead_Locked() {
477 lock_
.AssertAcquired();
493 return !pending_read_
&& !received_end_of_stream_
&&
494 !algorithm_
->IsQueueFull();
497 void AudioRendererImpl::SetPlaybackRate(float playback_rate
) {
498 DVLOG(1) << __FUNCTION__
<< "(" << playback_rate
<< ")";
499 DCHECK(task_runner_
->BelongsToCurrentThread());
500 DCHECK_GE(playback_rate
, 0);
503 base::AutoLock
auto_lock(lock_
);
505 // We have two cases here:
506 // Play: current_playback_rate == 0 && playback_rate != 0
507 // Pause: current_playback_rate != 0 && playback_rate == 0
508 float current_playback_rate
= algorithm_
->playback_rate();
509 if (current_playback_rate
== 0 && playback_rate
!= 0)
511 else if (current_playback_rate
!= 0 && playback_rate
== 0)
514 algorithm_
->SetPlaybackRate(playback_rate
);
517 bool AudioRendererImpl::IsBeforePrerollTime(
518 const scoped_refptr
<AudioBuffer
>& buffer
) {
519 DCHECK_EQ(state_
, kPrerolling
);
520 return buffer
&& !buffer
->end_of_stream() &&
521 (buffer
->timestamp() + buffer
->duration()) < preroll_timestamp_
;
524 int AudioRendererImpl::Render(AudioBus
* audio_bus
,
525 int audio_delay_milliseconds
) {
526 const int requested_frames
= audio_bus
->frames();
527 base::TimeDelta current_time
= kNoTimestamp();
528 base::TimeDelta max_time
= kNoTimestamp();
529 base::TimeDelta playback_delay
= base::TimeDelta::FromMilliseconds(
530 audio_delay_milliseconds
);
532 int frames_written
= 0;
533 base::Closure underflow_cb
;
535 base::AutoLock
auto_lock(lock_
);
537 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
541 float playback_rate
= algorithm_
->playback_rate();
542 if (playback_rate
== 0)
545 // Mute audio by returning 0 when not playing.
546 if (state_
!= kPlaying
)
549 // We use the following conditions to determine end of playback:
550 // 1) Algorithm can not fill the audio callback buffer
551 // 2) We received an end of stream buffer
552 // 3) We haven't already signalled that we've ended
553 // 4) Our estimated earliest end time has expired
555 // TODO(enal): we should replace (4) with a check that the browser has no
556 // more audio data or at least use a delayed callback.
558 // We use the following conditions to determine underflow:
559 // 1) Algorithm can not fill the audio callback buffer
560 // 2) We have NOT received an end of stream buffer
561 // 3) We are in the kPlaying state
563 // Otherwise the buffer has data we can send to the device.
564 frames_written
= algorithm_
->FillBuffer(audio_bus
, requested_frames
);
565 if (frames_written
== 0) {
566 const base::TimeTicks now
= now_cb_
.Run();
568 if (received_end_of_stream_
&& !rendered_end_of_stream_
&&
569 now
>= earliest_end_time_
) {
570 rendered_end_of_stream_
= true;
572 } else if (!received_end_of_stream_
&& state_
== kPlaying
&&
573 !underflow_disabled_
) {
574 ChangeState_Locked(kUnderflow
);
575 underflow_cb
= underflow_cb_
;
577 // We can't write any data this cycle. For example, we may have
578 // sent all available data to the audio device while not reaching
579 // |earliest_end_time_|.
583 if (CanRead_Locked()) {
584 task_runner_
->PostTask(FROM_HERE
, base::Bind(
585 &AudioRendererImpl::AttemptRead
, weak_this_
));
588 // The |audio_time_buffered_| is the ending timestamp of the last frame
589 // buffered at the audio device. |playback_delay| is the amount of time
590 // buffered at the audio device. The current time can be computed by their
592 if (audio_time_buffered_
!= kNoTimestamp()) {
593 // Adjust the delay according to playback rate.
594 base::TimeDelta adjusted_playback_delay
=
595 base::TimeDelta::FromMicroseconds(ceil(
596 playback_delay
.InMicroseconds() * playback_rate
));
598 base::TimeDelta previous_time
= current_time_
;
599 current_time_
= audio_time_buffered_
- adjusted_playback_delay
;
601 // Time can change in one of two ways:
602 // 1) The time of the audio data at the audio device changed, or
603 // 2) The playback delay value has changed
605 // We only want to set |current_time| (and thus execute |time_cb_|) if
606 // time has progressed and we haven't signaled end of stream yet.
608 // Why? The current latency of the system results in getting the last call
609 // to FillBuffer() later than we'd like, which delays firing the 'ended'
610 // event, which delays the looping/trigging performance of short sound
613 // TODO(scherkus): revisit this and switch back to relying on playback
614 // delay after we've revamped our audio IPC subsystem.
615 if (current_time_
> previous_time
&& !rendered_end_of_stream_
) {
616 current_time
= current_time_
;
620 // The call to FillBuffer() on |algorithm_| has increased the amount of
621 // buffered audio data. Update the new amount of time buffered.
622 max_time
= algorithm_
->GetTime();
623 audio_time_buffered_
= max_time
;
625 if (frames_written
> 0) {
626 UpdateEarliestEndTime_Locked(
627 frames_written
, playback_delay
, now_cb_
.Run());
631 if (current_time
!= kNoTimestamp() && max_time
!= kNoTimestamp())
632 time_cb_
.Run(current_time
, max_time
);
634 if (!underflow_cb
.is_null())
637 DCHECK_LE(frames_written
, requested_frames
);
638 return frames_written
;
641 void AudioRendererImpl::UpdateEarliestEndTime_Locked(
642 int frames_filled
, const base::TimeDelta
& playback_delay
,
643 const base::TimeTicks
& time_now
) {
644 DCHECK_GT(frames_filled
, 0);
646 base::TimeDelta predicted_play_time
= base::TimeDelta::FromMicroseconds(
647 static_cast<float>(frames_filled
) * base::Time::kMicrosecondsPerSecond
/
648 audio_parameters_
.sample_rate());
650 lock_
.AssertAcquired();
651 earliest_end_time_
= std::max(
652 earliest_end_time_
, time_now
+ playback_delay
+ predicted_play_time
);
655 void AudioRendererImpl::OnRenderError() {
656 HistogramRendererEvent(RENDER_ERROR
);
660 void AudioRendererImpl::DisableUnderflowForTesting() {
661 underflow_disabled_
= true;
664 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error
) {
665 lock_
.AssertAcquired();
667 PipelineStatus status
= is_decode_error
? PIPELINE_ERROR_DECODE
: PIPELINE_OK
;
673 if (status
!= PIPELINE_OK
)
674 error_cb_
.Run(status
);
677 ChangeState_Locked(kPaused
);
679 if (status
== PIPELINE_OK
) {
684 error_cb_
.Run(status
);
685 base::ResetAndReturn(&flush_cb_
).Run();
688 // This is a signal for abort if it's not an error.
689 preroll_aborted_
= !is_decode_error
;
690 ChangeState_Locked(kPaused
);
691 base::ResetAndReturn(&preroll_cb_
).Run(status
);
697 if (status
!= PIPELINE_OK
)
698 error_cb_
.Run(status
);
703 void AudioRendererImpl::ChangeState_Locked(State new_state
) {
704 DVLOG(1) << __FUNCTION__
<< " : " << state_
<< " -> " << new_state
;
705 lock_
.AssertAcquired();