Report errors from ChromiumEnv::GetChildren in Posix.
[chromium-blink-merge.git] / media / filters / audio_renderer_impl.cc
bloba4b0370ab1237011156bf1711e07b8c5b844e5c6
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/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"
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::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),
47 weak_factory_(this),
48 sink_(sink),
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),
53 sink_playing_(false),
54 pending_read_(false),
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);
76 callback.Run();
77 earliest_end_time_ = now_cb_.Run();
79 if (algorithm_->playback_rate() != 0)
80 DoPlay_Locked();
81 else
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_);
93 sink_->Play();
96 sink_playing_ = true;
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.
110 if (!pending_read_)
111 base::ResetAndReturn(&pause_cb_).Run();
113 DoPause_Locked();
116 void AudioRendererImpl::DoPause_Locked() {
117 DCHECK(message_loop_->BelongsToCurrentThread());
118 lock_.AssertAcquired();
120 if (sink_playing_) {
122 base::AutoUnlock auto_unlock(lock_);
123 sink_->Pause();
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));
135 return;
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().
153 if (sink_) {
154 sink_->Stop();
155 sink_ = NULL;
159 base::AutoLock auto_lock(lock_);
160 ChangeState_Locked(kStopped);
161 algorithm_.reset(NULL);
162 init_cb_.Reset();
163 underflow_cb_.Reset();
164 time_cb_.Reset();
167 callback.Run();
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);
182 preroll_cb_ = cb;
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;
192 splicer_->Reset();
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());
208 DCHECK(stream);
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_);
218 DCHECK(sink_);
220 weak_this_ = weak_factory_.GetWeakPtr();
221 init_cb_ = init_cb;
222 statistics_cb_ = statistics_cb;
223 underflow_cb_ = underflow_cb;
224 time_cb_ = time_cb;
225 ended_cb_ = ended_cb;
226 disabled_cb_ = disabled_cb;
227 error_cb_ = error_cb;
229 decoder_selector_->SelectAudioDecoder(
230 stream,
231 statistics_cb,
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) {
244 DCHECK(!sink_);
245 return;
248 if (!decoder) {
249 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
250 return;
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);
266 return;
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());
283 sink_->Start();
285 // Some sinks play on start...
286 sink_->Pause();
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());
313 DCHECK(sink_);
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);
332 return;
335 if (status == AudioDecoder::kDecodeError) {
336 HandleAbortedReadOrDecodeError(true);
337 return;
340 DCHECK_EQ(status, AudioDecoder::kOk);
341 DCHECK(buffer.get());
343 if (!splicer_->AddInput(buffer)) {
344 HandleAbortedReadOrDecodeError(true);
345 return;
348 if (!splicer_->HasNextBuffer()) {
349 AttemptRead_Locked();
350 return;
353 bool need_another_buffer = false;
354 while (splicer_->HasNextBuffer())
355 need_another_buffer = HandleSplicerBuffer(splicer_->GetNextBuffer());
357 if (!need_another_buffer && !CanRead_Locked())
358 return;
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);
372 } else {
373 if (state_ == kPrerolling && IsBeforePrerollTime(buffer))
374 return true;
376 if (state_ != kUninitialized && state_ != kStopped)
377 algorithm_->EnqueueBuffer(buffer);
380 switch (state_) {
381 case kUninitialized:
382 NOTREACHED();
383 return false;
385 case kPaused:
386 DCHECK(!pending_read_);
387 base::ResetAndReturn(&pause_cb_).Run();
388 return false;
390 case kPrerolling:
391 if (!buffer->end_of_stream() && !algorithm_->IsQueueFull())
392 return true;
393 ChangeState_Locked(kPaused);
394 base::ResetAndReturn(&preroll_cb_).Run(PIPELINE_OK);
395 return false;
397 case kPlaying:
398 case kUnderflow:
399 return false;
401 case kRebuffering:
402 if (!algorithm_->IsQueueFull())
403 return true;
404 ChangeState_Locked(kPlaying);
405 return false;
407 case kStopped:
408 return false;
410 return false;
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())
423 return;
425 pending_read_ = true;
426 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_));
429 bool AudioRendererImpl::CanRead_Locked() {
430 lock_.AssertAcquired();
432 switch (state_) {
433 case kUninitialized:
434 case kPaused:
435 case kStopped:
436 return false;
438 case kPrerolling:
439 case kPlaying:
440 case kUnderflow:
441 case kRebuffering:
442 break;
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);
453 DCHECK(sink_);
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)
462 DoPlay_Locked();
463 else if (current_playback_rate != 0 && playback_rate == 0)
464 DoPause_Locked();
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.
490 if (!algorithm_)
491 return 0;
493 float playback_rate = algorithm_->playback_rate();
494 if (playback_rate == 0)
495 return 0;
497 // Mute audio by returning 0 when not playing.
498 if (state_ != kPlaying)
499 return 0;
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;
523 ended_cb_.Run();
524 } else if (!received_end_of_stream_ && state_ == kPlaying &&
525 !underflow_disabled_) {
526 ChangeState_Locked(kUnderflow);
527 underflow_cb = underflow_cb_;
528 } else {
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
543 // difference.
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
563 // effects.
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())
587 underflow_cb.Run();
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);
609 disabled_cb_.Run();
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;
618 switch (state_) {
619 case kUninitialized:
620 NOTREACHED();
621 return;
622 case kPaused:
623 if (status != PIPELINE_OK)
624 error_cb_.Run(status);
625 base::ResetAndReturn(&pause_cb_).Run();
626 return;
627 case kPrerolling:
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);
632 return;
633 case kPlaying:
634 case kUnderflow:
635 case kRebuffering:
636 case kStopped:
637 if (status != PIPELINE_OK)
638 error_cb_.Run(status);
639 return;
643 void AudioRendererImpl::ChangeState_Locked(State new_state) {
644 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
645 lock_.AssertAcquired();
646 state_ = new_state;
649 } // namespace media