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/message_loop/message_loop_proxy.h"
16 #include "base/metrics/histogram.h"
17 #include "media/base/audio_buffer.h"
18 #include "media/base/audio_splicer.h"
19 #include "media/base/bind_to_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::MessageLoopProxy
>& message_loop
,
42 media::AudioRendererSink
* sink
,
43 ScopedVector
<AudioDecoder
> decoders
,
44 const SetDecryptorReadyCB
& set_decryptor_ready_cb
,
45 bool increase_preroll_on_underflow
)
46 : message_loop_(message_loop
),
49 decoder_selector_(new AudioDecoderSelector(
50 message_loop
, decoders
.Pass(), set_decryptor_ready_cb
)),
51 now_cb_(base::Bind(&base::TimeTicks::Now
)),
52 state_(kUninitialized
),
55 received_end_of_stream_(false),
56 rendered_end_of_stream_(false),
57 audio_time_buffered_(kNoTimestamp()),
58 current_time_(kNoTimestamp()),
59 underflow_disabled_(false),
60 increase_preroll_on_underflow_(increase_preroll_on_underflow
),
61 preroll_aborted_(false) {
64 AudioRendererImpl::~AudioRendererImpl() {
65 // Stop() should have been called and |algorithm_| should have been destroyed.
66 DCHECK(state_
== kUninitialized
|| state_
== kStopped
);
67 DCHECK(!algorithm_
.get());
70 void AudioRendererImpl::Play(const base::Closure
& callback
) {
71 DCHECK(message_loop_
->BelongsToCurrentThread());
73 base::AutoLock
auto_lock(lock_
);
74 DCHECK_EQ(state_
, kPaused
);
75 ChangeState_Locked(kPlaying
);
77 earliest_end_time_
= now_cb_
.Run();
79 if (algorithm_
->playback_rate() != 0)
82 DCHECK(!sink_playing_
);
85 void AudioRendererImpl::DoPlay_Locked() {
86 DCHECK(message_loop_
->BelongsToCurrentThread());
87 lock_
.AssertAcquired();
88 earliest_end_time_
= now_cb_
.Run();
90 if (state_
== kPlaying
&& !sink_playing_
) {
92 base::AutoUnlock
auto_unlock(lock_
);
100 void AudioRendererImpl::Pause(const base::Closure
& callback
) {
101 DCHECK(message_loop_
->BelongsToCurrentThread());
103 base::AutoLock
auto_lock(lock_
);
104 DCHECK(state_
== kPlaying
|| state_
== kUnderflow
||
105 state_
== kRebuffering
) << "state_ == " << state_
;
106 pause_cb_
= callback
;
107 ChangeState_Locked(kPaused
);
109 // Pause only when we've completed our pending read.
111 base::ResetAndReturn(&pause_cb_
).Run();
116 void AudioRendererImpl::DoPause_Locked() {
117 DCHECK(message_loop_
->BelongsToCurrentThread());
118 lock_
.AssertAcquired();
122 base::AutoUnlock
auto_unlock(lock_
);
125 sink_playing_
= false;
129 void AudioRendererImpl::Flush(const base::Closure
& callback
) {
130 DCHECK(message_loop_
->BelongsToCurrentThread());
132 if (decrypting_demuxer_stream_
) {
133 decrypting_demuxer_stream_
->Reset(base::Bind(
134 &AudioRendererImpl::ResetDecoder
, weak_this_
, callback
));
138 decoder_
->Reset(callback
);
141 void AudioRendererImpl::ResetDecoder(const base::Closure
& callback
) {
142 DCHECK(message_loop_
->BelongsToCurrentThread());
143 decoder_
->Reset(callback
);
146 void AudioRendererImpl::Stop(const base::Closure
& callback
) {
147 DCHECK(message_loop_
->BelongsToCurrentThread());
148 DCHECK(!callback
.is_null());
150 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
151 // task-running guards that check |state_| with DCHECK().
159 base::AutoLock
auto_lock(lock_
);
160 ChangeState_Locked(kStopped
);
161 algorithm_
.reset(NULL
);
163 underflow_cb_
.Reset();
170 void AudioRendererImpl::Preroll(base::TimeDelta time
,
171 const PipelineStatusCB
& cb
) {
172 DCHECK(message_loop_
->BelongsToCurrentThread());
174 base::AutoLock
auto_lock(lock_
);
175 DCHECK(!sink_playing_
);
176 DCHECK_EQ(state_
, kPaused
);
177 DCHECK(!pending_read_
) << "Pending read must complete before seeking";
178 DCHECK(pause_cb_
.is_null());
179 DCHECK(preroll_cb_
.is_null());
181 ChangeState_Locked(kPrerolling
);
183 preroll_timestamp_
= time
;
185 // Throw away everything and schedule our reads.
186 audio_time_buffered_
= kNoTimestamp();
187 current_time_
= kNoTimestamp();
188 received_end_of_stream_
= false;
189 rendered_end_of_stream_
= false;
190 preroll_aborted_
= false;
193 algorithm_
->FlushBuffers();
194 earliest_end_time_
= now_cb_
.Run();
196 AttemptRead_Locked();
199 void AudioRendererImpl::Initialize(DemuxerStream
* stream
,
200 const PipelineStatusCB
& init_cb
,
201 const StatisticsCB
& statistics_cb
,
202 const base::Closure
& underflow_cb
,
203 const TimeCB
& time_cb
,
204 const base::Closure
& ended_cb
,
205 const base::Closure
& disabled_cb
,
206 const PipelineStatusCB
& error_cb
) {
207 DCHECK(message_loop_
->BelongsToCurrentThread());
209 DCHECK_EQ(stream
->type(), DemuxerStream::AUDIO
);
210 DCHECK(!init_cb
.is_null());
211 DCHECK(!statistics_cb
.is_null());
212 DCHECK(!underflow_cb
.is_null());
213 DCHECK(!time_cb
.is_null());
214 DCHECK(!ended_cb
.is_null());
215 DCHECK(!disabled_cb
.is_null());
216 DCHECK(!error_cb
.is_null());
217 DCHECK_EQ(kUninitialized
, state_
);
220 weak_this_
= weak_factory_
.GetWeakPtr();
222 statistics_cb_
= statistics_cb
;
223 underflow_cb_
= underflow_cb
;
225 ended_cb_
= ended_cb
;
226 disabled_cb_
= disabled_cb
;
227 error_cb_
= error_cb
;
229 decoder_selector_
->SelectAudioDecoder(
232 base::Bind(&AudioRendererImpl::OnDecoderSelected
, weak_this_
));
235 void AudioRendererImpl::OnDecoderSelected(
236 scoped_ptr
<AudioDecoder
> decoder
,
237 scoped_ptr
<DecryptingDemuxerStream
> decrypting_demuxer_stream
) {
238 DCHECK(message_loop_
->BelongsToCurrentThread());
240 base::AutoLock
auto_lock(lock_
);
241 scoped_ptr
<AudioDecoderSelector
> deleter(decoder_selector_
.Pass());
243 if (state_
== kStopped
) {
249 base::ResetAndReturn(&init_cb_
).Run(DECODER_ERROR_NOT_SUPPORTED
);
253 decoder_
= decoder
.Pass();
254 decrypting_demuxer_stream_
= decrypting_demuxer_stream
.Pass();
256 int sample_rate
= decoder_
->samples_per_second();
258 // The actual buffer size is controlled via the size of the AudioBus provided
259 // to Render(), so just choose something reasonable here for looks.
260 int buffer_size
= decoder_
->samples_per_second() / 100;
261 audio_parameters_
= AudioParameters(
262 AudioParameters::AUDIO_PCM_LOW_LATENCY
, decoder_
->channel_layout(),
263 sample_rate
, decoder_
->bits_per_channel(), buffer_size
);
264 if (!audio_parameters_
.IsValid()) {
265 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_ERROR_INITIALIZATION_FAILED
);
269 splicer_
.reset(new AudioSplicer(sample_rate
));
271 // We're all good! Continue initializing the rest of the audio renderer based
272 // on the decoder format.
273 algorithm_
.reset(new AudioRendererAlgorithm());
274 algorithm_
->Initialize(0, audio_parameters_
);
276 ChangeState_Locked(kPaused
);
278 HistogramRendererEvent(INITIALIZED
);
281 base::AutoUnlock
auto_unlock(lock_
);
282 sink_
->Initialize(audio_parameters_
, weak_this_
.get());
285 // Some sinks play on start...
289 DCHECK(!sink_playing_
);
291 base::ResetAndReturn(&init_cb_
).Run(PIPELINE_OK
);
294 void AudioRendererImpl::ResumeAfterUnderflow() {
295 DCHECK(message_loop_
->BelongsToCurrentThread());
296 base::AutoLock
auto_lock(lock_
);
297 if (state_
== kUnderflow
) {
298 // The "&& preroll_aborted_" is a hack. If preroll is aborted, then we
299 // shouldn't even reach the kUnderflow state to begin with. But for now
300 // we're just making sure that the audio buffer capacity (i.e. the
301 // number of bytes that need to be buffered for preroll to complete)
302 // does not increase due to an aborted preroll.
303 // TODO(vrk): Fix this bug correctly! (crbug.com/151352)
304 if (increase_preroll_on_underflow_
&& !preroll_aborted_
)
305 algorithm_
->IncreaseQueueCapacity();
307 ChangeState_Locked(kRebuffering
);
311 void AudioRendererImpl::SetVolume(float volume
) {
312 DCHECK(message_loop_
->BelongsToCurrentThread());
314 sink_
->SetVolume(volume
);
317 void AudioRendererImpl::DecodedAudioReady(
318 AudioDecoder::Status status
,
319 const scoped_refptr
<AudioBuffer
>& buffer
) {
320 DVLOG(1) << __FUNCTION__
<< "(" << status
<< ")";
321 DCHECK(message_loop_
->BelongsToCurrentThread());
323 base::AutoLock
auto_lock(lock_
);
324 DCHECK(state_
== kPaused
|| state_
== kPrerolling
|| state_
== kPlaying
||
325 state_
== kUnderflow
|| state_
== kRebuffering
|| state_
== kStopped
);
327 CHECK(pending_read_
);
328 pending_read_
= false;
330 if (status
== AudioDecoder::kAborted
) {
331 HandleAbortedReadOrDecodeError(false);
335 if (status
== AudioDecoder::kDecodeError
) {
336 HandleAbortedReadOrDecodeError(true);
340 DCHECK_EQ(status
, AudioDecoder::kOk
);
341 DCHECK(buffer
.get());
343 if (!splicer_
->AddInput(buffer
)) {
344 HandleAbortedReadOrDecodeError(true);
348 if (!splicer_
->HasNextBuffer()) {
349 AttemptRead_Locked();
353 bool need_another_buffer
= false;
354 while (splicer_
->HasNextBuffer())
355 need_another_buffer
= HandleSplicerBuffer(splicer_
->GetNextBuffer());
357 if (!need_another_buffer
&& !CanRead_Locked())
360 AttemptRead_Locked();
363 bool AudioRendererImpl::HandleSplicerBuffer(
364 const scoped_refptr
<AudioBuffer
>& buffer
) {
365 if (buffer
->end_of_stream()) {
366 received_end_of_stream_
= true;
368 // Transition to kPlaying if we are currently handling an underflow since
369 // no more data will be arriving.
370 if (state_
== kUnderflow
|| state_
== kRebuffering
)
371 ChangeState_Locked(kPlaying
);
373 if (state_
== kPrerolling
&& IsBeforePrerollTime(buffer
))
376 if (state_
!= kUninitialized
&& state_
!= kStopped
)
377 algorithm_
->EnqueueBuffer(buffer
);
386 DCHECK(!pending_read_
);
387 base::ResetAndReturn(&pause_cb_
).Run();
391 if (!buffer
->end_of_stream() && !algorithm_
->IsQueueFull())
393 ChangeState_Locked(kPaused
);
394 base::ResetAndReturn(&preroll_cb_
).Run(PIPELINE_OK
);
402 if (!algorithm_
->IsQueueFull())
404 ChangeState_Locked(kPlaying
);
413 void AudioRendererImpl::AttemptRead() {
414 base::AutoLock
auto_lock(lock_
);
415 AttemptRead_Locked();
418 void AudioRendererImpl::AttemptRead_Locked() {
419 DCHECK(message_loop_
->BelongsToCurrentThread());
420 lock_
.AssertAcquired();
422 if (!CanRead_Locked())
425 pending_read_
= true;
426 decoder_
->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady
, weak_this_
));
429 bool AudioRendererImpl::CanRead_Locked() {
430 lock_
.AssertAcquired();
445 return !pending_read_
&& !received_end_of_stream_
&&
446 !algorithm_
->IsQueueFull();
449 void AudioRendererImpl::SetPlaybackRate(float playback_rate
) {
450 DVLOG(1) << __FUNCTION__
<< "(" << playback_rate
<< ")";
451 DCHECK(message_loop_
->BelongsToCurrentThread());
452 DCHECK_GE(playback_rate
, 0);
455 base::AutoLock
auto_lock(lock_
);
457 // We have two cases here:
458 // Play: current_playback_rate == 0 && playback_rate != 0
459 // Pause: current_playback_rate != 0 && playback_rate == 0
460 float current_playback_rate
= algorithm_
->playback_rate();
461 if (current_playback_rate
== 0 && playback_rate
!= 0)
463 else if (current_playback_rate
!= 0 && playback_rate
== 0)
466 algorithm_
->SetPlaybackRate(playback_rate
);
469 bool AudioRendererImpl::IsBeforePrerollTime(
470 const scoped_refptr
<AudioBuffer
>& buffer
) {
471 DCHECK_EQ(state_
, kPrerolling
);
472 return buffer
&& !buffer
->end_of_stream() &&
473 (buffer
->timestamp() + buffer
->duration()) < preroll_timestamp_
;
476 int AudioRendererImpl::Render(AudioBus
* audio_bus
,
477 int audio_delay_milliseconds
) {
478 const int requested_frames
= audio_bus
->frames();
479 base::TimeDelta current_time
= kNoTimestamp();
480 base::TimeDelta max_time
= kNoTimestamp();
481 base::TimeDelta playback_delay
= base::TimeDelta::FromMilliseconds(
482 audio_delay_milliseconds
);
484 int frames_written
= 0;
485 base::Closure underflow_cb
;
487 base::AutoLock
auto_lock(lock_
);
489 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
493 float playback_rate
= algorithm_
->playback_rate();
494 if (playback_rate
== 0)
497 // Mute audio by returning 0 when not playing.
498 if (state_
!= kPlaying
)
501 // We use the following conditions to determine end of playback:
502 // 1) Algorithm can not fill the audio callback buffer
503 // 2) We received an end of stream buffer
504 // 3) We haven't already signalled that we've ended
505 // 4) Our estimated earliest end time has expired
507 // TODO(enal): we should replace (4) with a check that the browser has no
508 // more audio data or at least use a delayed callback.
510 // We use the following conditions to determine underflow:
511 // 1) Algorithm can not fill the audio callback buffer
512 // 2) We have NOT received an end of stream buffer
513 // 3) We are in the kPlaying state
515 // Otherwise the buffer has data we can send to the device.
516 frames_written
= algorithm_
->FillBuffer(audio_bus
, requested_frames
);
517 if (frames_written
== 0) {
518 const base::TimeTicks now
= now_cb_
.Run();
520 if (received_end_of_stream_
&& !rendered_end_of_stream_
&&
521 now
>= earliest_end_time_
) {
522 rendered_end_of_stream_
= true;
524 } else if (!received_end_of_stream_
&& state_
== kPlaying
&&
525 !underflow_disabled_
) {
526 ChangeState_Locked(kUnderflow
);
527 underflow_cb
= underflow_cb_
;
529 // We can't write any data this cycle. For example, we may have
530 // sent all available data to the audio device while not reaching
531 // |earliest_end_time_|.
535 if (CanRead_Locked()) {
536 message_loop_
->PostTask(FROM_HERE
, base::Bind(
537 &AudioRendererImpl::AttemptRead
, weak_this_
));
540 // The |audio_time_buffered_| is the ending timestamp of the last frame
541 // buffered at the audio device. |playback_delay| is the amount of time
542 // buffered at the audio device. The current time can be computed by their
544 if (audio_time_buffered_
!= kNoTimestamp()) {
545 // Adjust the delay according to playback rate.
546 base::TimeDelta adjusted_playback_delay
=
547 base::TimeDelta::FromMicroseconds(ceil(
548 playback_delay
.InMicroseconds() * playback_rate
));
550 base::TimeDelta previous_time
= current_time_
;
551 current_time_
= audio_time_buffered_
- adjusted_playback_delay
;
553 // Time can change in one of two ways:
554 // 1) The time of the audio data at the audio device changed, or
555 // 2) The playback delay value has changed
557 // We only want to set |current_time| (and thus execute |time_cb_|) if
558 // time has progressed and we haven't signaled end of stream yet.
560 // Why? The current latency of the system results in getting the last call
561 // to FillBuffer() later than we'd like, which delays firing the 'ended'
562 // event, which delays the looping/trigging performance of short sound
565 // TODO(scherkus): revisit this and switch back to relying on playback
566 // delay after we've revamped our audio IPC subsystem.
567 if (current_time_
> previous_time
&& !rendered_end_of_stream_
) {
568 current_time
= current_time_
;
572 // The call to FillBuffer() on |algorithm_| has increased the amount of
573 // buffered audio data. Update the new amount of time buffered.
574 max_time
= algorithm_
->GetTime();
575 audio_time_buffered_
= max_time
;
577 if (frames_written
> 0) {
578 UpdateEarliestEndTime_Locked(
579 frames_written
, playback_delay
, now_cb_
.Run());
583 if (current_time
!= kNoTimestamp() && max_time
!= kNoTimestamp())
584 time_cb_
.Run(current_time
, max_time
);
586 if (!underflow_cb
.is_null())
589 DCHECK_LE(frames_written
, requested_frames
);
590 return frames_written
;
593 void AudioRendererImpl::UpdateEarliestEndTime_Locked(
594 int frames_filled
, const base::TimeDelta
& playback_delay
,
595 const base::TimeTicks
& time_now
) {
596 DCHECK_GT(frames_filled
, 0);
598 base::TimeDelta predicted_play_time
= base::TimeDelta::FromMicroseconds(
599 static_cast<float>(frames_filled
) * base::Time::kMicrosecondsPerSecond
/
600 audio_parameters_
.sample_rate());
602 lock_
.AssertAcquired();
603 earliest_end_time_
= std::max(
604 earliest_end_time_
, time_now
+ playback_delay
+ predicted_play_time
);
607 void AudioRendererImpl::OnRenderError() {
608 HistogramRendererEvent(RENDER_ERROR
);
612 void AudioRendererImpl::DisableUnderflowForTesting() {
613 underflow_disabled_
= true;
616 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error
) {
617 PipelineStatus status
= is_decode_error
? PIPELINE_ERROR_DECODE
: PIPELINE_OK
;
623 if (status
!= PIPELINE_OK
)
624 error_cb_
.Run(status
);
625 base::ResetAndReturn(&pause_cb_
).Run();
628 // This is a signal for abort if it's not an error.
629 preroll_aborted_
= !is_decode_error
;
630 ChangeState_Locked(kPaused
);
631 base::ResetAndReturn(&preroll_cb_
).Run(status
);
637 if (status
!= PIPELINE_OK
)
638 error_cb_
.Run(status
);
643 void AudioRendererImpl::ChangeState_Locked(State new_state
) {
644 DVLOG(1) << __FUNCTION__
<< " : " << state_
<< " -> " << new_state
;
645 lock_
.AssertAcquired();