Add explicit |forceOnlineSignin| to user pod status
[chromium-blink-merge.git] / media / filters / audio_renderer_impl.cc
blob9ade30dc0dc6fdbba1dae9d7e8cbd041aee6638e
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"
7 #include <math.h>
9 #include <algorithm>
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"
24 namespace media {
26 namespace {
28 enum AudioRendererEvent {
29 INITIALIZED,
30 RENDER_ERROR,
31 MAX_EVENTS
34 void HistogramRendererEvent(AudioRendererEvent event) {
35 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event, MAX_EVENTS);
38 } // namespace
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),
46 weak_factory_(this),
47 sink_(sink),
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),
52 sink_playing_(false),
53 pending_read_(false),
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);
74 callback.Run();
75 earliest_end_time_ = now_cb_.Run();
77 if (algorithm_->playback_rate() != 0)
78 DoPlay_Locked();
79 else
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) &&
89 !sink_playing_) {
91 base::AutoUnlock auto_unlock(lock_);
92 sink_->Play();
95 sink_playing_ = true;
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);
107 DoPause_Locked();
109 callback.Run();
112 void AudioRendererImpl::DoPause_Locked() {
113 DCHECK(task_runner_->BelongsToCurrentThread());
114 lock_.AssertAcquired();
116 if (sink_playing_) {
118 base::AutoUnlock auto_unlock(lock_);
119 sink_->Pause();
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;
134 if (pending_read_) {
135 ChangeState_Locked(kFlushing);
136 return;
139 DoFlush_Locked();
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_)));
152 return;
155 ResetDecoder();
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)
167 return;
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();
179 splicer_->Reset();
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().
192 if (sink_) {
193 sink_->Stop();
194 sink_ = NULL;
198 base::AutoLock auto_lock(lock_);
199 ChangeState_Locked(kStopped);
200 algorithm_.reset(NULL);
201 init_cb_.Reset();
202 underflow_cb_.Reset();
203 time_cb_.Reset();
204 flush_cb_.Reset();
207 callback.Run();
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);
221 preroll_cb_ = cb;
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());
236 DCHECK(stream);
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_);
246 DCHECK(sink_);
248 weak_this_ = weak_factory_.GetWeakPtr();
249 init_cb_ = init_cb;
250 statistics_cb_ = statistics_cb;
251 underflow_cb_ = underflow_cb;
252 time_cb_ = time_cb;
253 ended_cb_ = ended_cb;
254 disabled_cb_ = disabled_cb;
255 error_cb_ = error_cb;
257 decoder_selector_->SelectAudioDecoder(
258 stream,
259 statistics_cb,
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) {
272 DCHECK(!sink_);
273 return;
276 if (!decoder) {
277 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
278 return;
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);
294 return;
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());
311 sink_->Start();
313 // Some sinks play on start...
314 sink_->Pause();
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());
341 DCHECK(sink_);
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);
359 return;
362 if (status == AudioDecoder::kDecodeError) {
363 HandleAbortedReadOrDecodeError(true);
364 return;
367 DCHECK_EQ(status, AudioDecoder::kOk);
368 DCHECK(buffer.get());
370 if (state_ == kFlushing) {
371 ChangeState_Locked(kPaused);
372 DoFlush_Locked();
373 return;
376 if (!splicer_->AddInput(buffer)) {
377 HandleAbortedReadOrDecodeError(true);
378 return;
381 if (!splicer_->HasNextBuffer()) {
382 AttemptRead_Locked();
383 return;
386 bool need_another_buffer = false;
387 while (splicer_->HasNextBuffer())
388 need_another_buffer = HandleSplicerBuffer(splicer_->GetNextBuffer());
390 if (!need_another_buffer && !CanRead_Locked())
391 return;
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);
405 } else {
406 if (state_ == kPrerolling) {
407 if (IsBeforePrerollTime(buffer))
408 return true;
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())
420 return true;
423 if (state_ != kUninitialized && state_ != kStopped)
424 algorithm_->EnqueueBuffer(buffer);
427 switch (state_) {
428 case kUninitialized:
429 case kFlushing:
430 NOTREACHED();
431 return false;
433 case kPaused:
434 DCHECK(!pending_read_);
435 return false;
437 case kPrerolling:
438 if (!buffer->end_of_stream() && !algorithm_->IsQueueFull())
439 return true;
440 ChangeState_Locked(kPaused);
441 base::ResetAndReturn(&preroll_cb_).Run(PIPELINE_OK);
442 return false;
444 case kPlaying:
445 case kUnderflow:
446 return false;
448 case kRebuffering:
449 if (!algorithm_->IsQueueFull())
450 return true;
451 ChangeState_Locked(kPlaying);
452 return false;
454 case kStopped:
455 return false;
457 return false;
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())
470 return;
472 pending_read_ = true;
473 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_));
476 bool AudioRendererImpl::CanRead_Locked() {
477 lock_.AssertAcquired();
479 switch (state_) {
480 case kUninitialized:
481 case kPaused:
482 case kFlushing:
483 case kStopped:
484 return false;
486 case kPrerolling:
487 case kPlaying:
488 case kUnderflow:
489 case kRebuffering:
490 break;
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);
501 DCHECK(sink_);
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)
510 DoPlay_Locked();
511 else if (current_playback_rate != 0 && playback_rate == 0)
512 DoPause_Locked();
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.
538 if (!algorithm_)
539 return 0;
541 float playback_rate = algorithm_->playback_rate();
542 if (playback_rate == 0)
543 return 0;
545 // Mute audio by returning 0 when not playing.
546 if (state_ != kPlaying)
547 return 0;
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;
571 ended_cb_.Run();
572 } else if (!received_end_of_stream_ && state_ == kPlaying &&
573 !underflow_disabled_) {
574 ChangeState_Locked(kUnderflow);
575 underflow_cb = underflow_cb_;
576 } else {
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
591 // difference.
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
611 // effects.
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())
635 underflow_cb.Run();
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);
657 disabled_cb_.Run();
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;
668 switch (state_) {
669 case kUninitialized:
670 NOTREACHED();
671 return;
672 case kPaused:
673 if (status != PIPELINE_OK)
674 error_cb_.Run(status);
675 return;
676 case kFlushing:
677 ChangeState_Locked(kPaused);
679 if (status == PIPELINE_OK) {
680 DoFlush_Locked();
681 return;
684 error_cb_.Run(status);
685 base::ResetAndReturn(&flush_cb_).Run();
686 return;
687 case kPrerolling:
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);
692 return;
693 case kPlaying:
694 case kUnderflow:
695 case kRebuffering:
696 case kStopped:
697 if (status != PIPELINE_OK)
698 error_cb_.Run(status);
699 return;
703 void AudioRendererImpl::ChangeState_Locked(State new_state) {
704 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
705 lock_.AssertAcquired();
706 state_ = new_state;
709 } // namespace media