Migrate away from the PrefMetricsService-based device ID in PrefHashCalculator.
[chromium-blink-merge.git] / media / filters / audio_renderer_impl.cc
blob144e054e765836bbd0c33a81c5606debe57711cc
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_buffer_converter.h"
19 #include "media/base/audio_hardware_config.h"
20 #include "media/base/audio_splicer.h"
21 #include "media/base/bind_to_current_loop.h"
22 #include "media/base/demuxer_stream.h"
23 #include "media/filters/audio_clock.h"
24 #include "media/filters/decrypting_demuxer_stream.h"
26 namespace media {
28 namespace {
30 enum AudioRendererEvent {
31 INITIALIZED,
32 RENDER_ERROR,
33 RENDER_EVENT_MAX = RENDER_ERROR,
36 void HistogramRendererEvent(AudioRendererEvent event) {
37 UMA_HISTOGRAM_ENUMERATION(
38 "Media.AudioRendererEvents", event, RENDER_EVENT_MAX + 1);
41 } // namespace
43 AudioRendererImpl::AudioRendererImpl(
44 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
45 media::AudioRendererSink* sink,
46 ScopedVector<AudioDecoder> decoders,
47 const SetDecryptorReadyCB& set_decryptor_ready_cb,
48 AudioHardwareConfig* hardware_config)
49 : task_runner_(task_runner),
50 expecting_config_changes_(false),
51 sink_(sink),
52 audio_buffer_stream_(new AudioBufferStream(task_runner,
53 decoders.Pass(),
54 set_decryptor_ready_cb)),
55 hardware_config_(hardware_config),
56 playback_rate_(0),
57 state_(kUninitialized),
58 buffering_state_(BUFFERING_HAVE_NOTHING),
59 rendering_(false),
60 sink_playing_(false),
61 pending_read_(false),
62 received_end_of_stream_(false),
63 rendered_end_of_stream_(false),
64 weak_factory_(this) {
65 audio_buffer_stream_->set_splice_observer(base::Bind(
66 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
67 audio_buffer_stream_->set_config_change_observer(base::Bind(
68 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
71 AudioRendererImpl::~AudioRendererImpl() {
72 DVLOG(1) << __FUNCTION__;
73 DCHECK(task_runner_->BelongsToCurrentThread());
75 // If Render() is in progress, this call will wait for Render() to finish.
76 // After this call, the |sink_| will not call back into |this| anymore.
77 sink_->Stop();
79 if (!init_cb_.is_null())
80 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
83 void AudioRendererImpl::StartTicking() {
84 DVLOG(1) << __FUNCTION__;
85 DCHECK(task_runner_->BelongsToCurrentThread());
86 DCHECK(!rendering_);
87 rendering_ = true;
89 base::AutoLock auto_lock(lock_);
90 // Wait for an eventual call to SetPlaybackRate() to start rendering.
91 if (playback_rate_ == 0) {
92 DCHECK(!sink_playing_);
93 return;
96 StartRendering_Locked();
99 void AudioRendererImpl::StartRendering_Locked() {
100 DVLOG(1) << __FUNCTION__;
101 DCHECK(task_runner_->BelongsToCurrentThread());
102 DCHECK_EQ(state_, kPlaying);
103 DCHECK(!sink_playing_);
104 DCHECK_NE(playback_rate_, 0);
105 lock_.AssertAcquired();
107 sink_playing_ = true;
109 base::AutoUnlock auto_unlock(lock_);
110 sink_->Play();
113 void AudioRendererImpl::StopTicking() {
114 DVLOG(1) << __FUNCTION__;
115 DCHECK(task_runner_->BelongsToCurrentThread());
116 DCHECK(rendering_);
117 rendering_ = false;
119 base::AutoLock auto_lock(lock_);
120 // Rendering should have already been stopped with a zero playback rate.
121 if (playback_rate_ == 0) {
122 DCHECK(!sink_playing_);
123 return;
126 StopRendering_Locked();
129 void AudioRendererImpl::StopRendering_Locked() {
130 DCHECK(task_runner_->BelongsToCurrentThread());
131 DCHECK_EQ(state_, kPlaying);
132 DCHECK(sink_playing_);
133 lock_.AssertAcquired();
135 sink_playing_ = false;
137 base::AutoUnlock auto_unlock(lock_);
138 sink_->Pause();
141 void AudioRendererImpl::SetMediaTime(base::TimeDelta time) {
142 DVLOG(1) << __FUNCTION__ << "(" << time.InMicroseconds() << ")";
143 DCHECK(task_runner_->BelongsToCurrentThread());
145 base::AutoLock auto_lock(lock_);
146 DCHECK(!rendering_);
147 DCHECK_EQ(state_, kFlushed);
149 start_timestamp_ = time;
152 base::TimeDelta AudioRendererImpl::CurrentMediaTime() {
153 DVLOG(1) << __FUNCTION__;
154 DCHECK(task_runner_->BelongsToCurrentThread());
156 // TODO(scherkus): Finish implementing when ready to switch Pipeline to using
157 // TimeSource http://crbug.com/370634
158 NOTIMPLEMENTED();
160 return base::TimeDelta();
163 TimeSource* AudioRendererImpl::GetTimeSource() {
164 return this;
167 void AudioRendererImpl::Flush(const base::Closure& callback) {
168 DVLOG(1) << __FUNCTION__;
169 DCHECK(task_runner_->BelongsToCurrentThread());
171 base::AutoLock auto_lock(lock_);
172 DCHECK_EQ(state_, kPlaying);
173 DCHECK(flush_cb_.is_null());
175 flush_cb_ = callback;
176 ChangeState_Locked(kFlushing);
178 if (pending_read_)
179 return;
181 ChangeState_Locked(kFlushed);
182 DoFlush_Locked();
185 void AudioRendererImpl::DoFlush_Locked() {
186 DCHECK(task_runner_->BelongsToCurrentThread());
187 lock_.AssertAcquired();
189 DCHECK(!pending_read_);
190 DCHECK_EQ(state_, kFlushed);
192 audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone,
193 weak_factory_.GetWeakPtr()));
196 void AudioRendererImpl::ResetDecoderDone() {
197 DCHECK(task_runner_->BelongsToCurrentThread());
199 base::AutoLock auto_lock(lock_);
201 DCHECK_EQ(state_, kFlushed);
202 DCHECK(!flush_cb_.is_null());
204 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
205 received_end_of_stream_ = false;
206 rendered_end_of_stream_ = false;
208 // Flush() may have been called while underflowed/not fully buffered.
209 if (buffering_state_ != BUFFERING_HAVE_NOTHING)
210 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
212 splicer_->Reset();
213 if (buffer_converter_)
214 buffer_converter_->Reset();
215 algorithm_->FlushBuffers();
218 // Changes in buffering state are always posted. Flush callback must only be
219 // run after buffering state has been set back to nothing.
220 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_));
223 void AudioRendererImpl::StartPlaying() {
224 DVLOG(1) << __FUNCTION__;
225 DCHECK(task_runner_->BelongsToCurrentThread());
227 base::AutoLock auto_lock(lock_);
228 DCHECK(!sink_playing_);
229 DCHECK_EQ(state_, kFlushed);
230 DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
231 DCHECK(!pending_read_) << "Pending read must complete before seeking";
233 ChangeState_Locked(kPlaying);
234 AttemptRead_Locked();
237 void AudioRendererImpl::Initialize(DemuxerStream* stream,
238 const PipelineStatusCB& init_cb,
239 const StatisticsCB& statistics_cb,
240 const TimeCB& time_cb,
241 const BufferingStateCB& buffering_state_cb,
242 const base::Closure& ended_cb,
243 const PipelineStatusCB& error_cb) {
244 DCHECK(task_runner_->BelongsToCurrentThread());
245 DCHECK(stream);
246 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
247 DCHECK(!init_cb.is_null());
248 DCHECK(!statistics_cb.is_null());
249 DCHECK(!time_cb.is_null());
250 DCHECK(!buffering_state_cb.is_null());
251 DCHECK(!ended_cb.is_null());
252 DCHECK(!error_cb.is_null());
253 DCHECK_EQ(kUninitialized, state_);
254 DCHECK(sink_);
256 state_ = kInitializing;
258 init_cb_ = init_cb;
259 time_cb_ = time_cb;
260 buffering_state_cb_ = buffering_state_cb;
261 ended_cb_ = ended_cb;
262 error_cb_ = error_cb;
264 expecting_config_changes_ = stream->SupportsConfigChanges();
265 if (!expecting_config_changes_) {
266 // The actual buffer size is controlled via the size of the AudioBus
267 // provided to Render(), so just choose something reasonable here for looks.
268 int buffer_size = stream->audio_decoder_config().samples_per_second() / 100;
269 audio_parameters_.Reset(
270 AudioParameters::AUDIO_PCM_LOW_LATENCY,
271 stream->audio_decoder_config().channel_layout(),
272 ChannelLayoutToChannelCount(
273 stream->audio_decoder_config().channel_layout()),
275 stream->audio_decoder_config().samples_per_second(),
276 stream->audio_decoder_config().bits_per_channel(),
277 buffer_size);
278 buffer_converter_.reset();
279 } else {
280 // TODO(rileya): Support hardware config changes
281 const AudioParameters& hw_params = hardware_config_->GetOutputConfig();
282 audio_parameters_.Reset(
283 hw_params.format(),
284 // Always use the source's channel layout and channel count to avoid
285 // premature downmixing (http://crbug.com/379288), platform specific
286 // issues around channel layouts (http://crbug.com/266674), and
287 // unnecessary upmixing overhead.
288 stream->audio_decoder_config().channel_layout(),
289 ChannelLayoutToChannelCount(
290 stream->audio_decoder_config().channel_layout()),
291 hw_params.input_channels(),
292 hw_params.sample_rate(),
293 hw_params.bits_per_sample(),
294 hardware_config_->GetHighLatencyBufferSize());
297 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
299 audio_buffer_stream_->Initialize(
300 stream,
301 false,
302 statistics_cb,
303 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
304 weak_factory_.GetWeakPtr()));
307 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
308 DCHECK(task_runner_->BelongsToCurrentThread());
310 base::AutoLock auto_lock(lock_);
312 if (!success) {
313 state_ = kUninitialized;
314 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
315 return;
318 if (!audio_parameters_.IsValid()) {
319 ChangeState_Locked(kUninitialized);
320 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
321 return;
324 if (expecting_config_changes_)
325 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_));
326 splicer_.reset(new AudioSplicer(audio_parameters_.sample_rate()));
328 // We're all good! Continue initializing the rest of the audio renderer
329 // based on the decoder format.
330 algorithm_.reset(new AudioRendererAlgorithm());
331 algorithm_->Initialize(audio_parameters_);
333 ChangeState_Locked(kFlushed);
335 HistogramRendererEvent(INITIALIZED);
338 base::AutoUnlock auto_unlock(lock_);
339 sink_->Initialize(audio_parameters_, this);
340 sink_->Start();
342 // Some sinks play on start...
343 sink_->Pause();
346 DCHECK(!sink_playing_);
348 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
351 void AudioRendererImpl::SetVolume(float volume) {
352 DCHECK(task_runner_->BelongsToCurrentThread());
353 DCHECK(sink_);
354 sink_->SetVolume(volume);
357 void AudioRendererImpl::DecodedAudioReady(
358 AudioBufferStream::Status status,
359 const scoped_refptr<AudioBuffer>& buffer) {
360 DVLOG(2) << __FUNCTION__ << "(" << status << ")";
361 DCHECK(task_runner_->BelongsToCurrentThread());
363 base::AutoLock auto_lock(lock_);
364 DCHECK(state_ != kUninitialized);
366 CHECK(pending_read_);
367 pending_read_ = false;
369 if (status == AudioBufferStream::ABORTED ||
370 status == AudioBufferStream::DEMUXER_READ_ABORTED) {
371 HandleAbortedReadOrDecodeError(false);
372 return;
375 if (status == AudioBufferStream::DECODE_ERROR) {
376 HandleAbortedReadOrDecodeError(true);
377 return;
380 DCHECK_EQ(status, AudioBufferStream::OK);
381 DCHECK(buffer.get());
383 if (state_ == kFlushing) {
384 ChangeState_Locked(kFlushed);
385 DoFlush_Locked();
386 return;
389 if (expecting_config_changes_) {
390 DCHECK(buffer_converter_);
391 buffer_converter_->AddInput(buffer);
392 while (buffer_converter_->HasNextBuffer()) {
393 if (!splicer_->AddInput(buffer_converter_->GetNextBuffer())) {
394 HandleAbortedReadOrDecodeError(true);
395 return;
398 } else {
399 if (!splicer_->AddInput(buffer)) {
400 HandleAbortedReadOrDecodeError(true);
401 return;
405 if (!splicer_->HasNextBuffer()) {
406 AttemptRead_Locked();
407 return;
410 bool need_another_buffer = false;
411 while (splicer_->HasNextBuffer())
412 need_another_buffer = HandleSplicerBuffer_Locked(splicer_->GetNextBuffer());
414 if (!need_another_buffer && !CanRead_Locked())
415 return;
417 AttemptRead_Locked();
420 bool AudioRendererImpl::HandleSplicerBuffer_Locked(
421 const scoped_refptr<AudioBuffer>& buffer) {
422 lock_.AssertAcquired();
423 if (buffer->end_of_stream()) {
424 received_end_of_stream_ = true;
425 } else {
426 if (state_ == kPlaying) {
427 if (IsBeforeStartTime(buffer))
428 return true;
430 // Trim off any additional time before the start timestamp.
431 const base::TimeDelta trim_time = start_timestamp_ - buffer->timestamp();
432 if (trim_time > base::TimeDelta()) {
433 buffer->TrimStart(buffer->frame_count() *
434 (static_cast<double>(trim_time.InMicroseconds()) /
435 buffer->duration().InMicroseconds()));
437 // If the entire buffer was trimmed, request a new one.
438 if (!buffer->frame_count())
439 return true;
442 if (state_ != kUninitialized)
443 algorithm_->EnqueueBuffer(buffer);
446 switch (state_) {
447 case kUninitialized:
448 case kInitializing:
449 case kFlushing:
450 NOTREACHED();
451 return false;
453 case kFlushed:
454 DCHECK(!pending_read_);
455 return false;
457 case kPlaying:
458 if (buffer->end_of_stream() || algorithm_->IsQueueFull()) {
459 if (buffering_state_ == BUFFERING_HAVE_NOTHING)
460 SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH);
461 return false;
463 return true;
465 return false;
468 void AudioRendererImpl::AttemptRead() {
469 base::AutoLock auto_lock(lock_);
470 AttemptRead_Locked();
473 void AudioRendererImpl::AttemptRead_Locked() {
474 DCHECK(task_runner_->BelongsToCurrentThread());
475 lock_.AssertAcquired();
477 if (!CanRead_Locked())
478 return;
480 pending_read_ = true;
481 audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
482 weak_factory_.GetWeakPtr()));
485 bool AudioRendererImpl::CanRead_Locked() {
486 lock_.AssertAcquired();
488 switch (state_) {
489 case kUninitialized:
490 case kInitializing:
491 case kFlushing:
492 case kFlushed:
493 return false;
495 case kPlaying:
496 break;
499 return !pending_read_ && !received_end_of_stream_ &&
500 !algorithm_->IsQueueFull();
503 void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
504 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
505 DCHECK(task_runner_->BelongsToCurrentThread());
506 DCHECK_GE(playback_rate, 0);
507 DCHECK(sink_);
509 base::AutoLock auto_lock(lock_);
511 // We have two cases here:
512 // Play: current_playback_rate == 0 && playback_rate != 0
513 // Pause: current_playback_rate != 0 && playback_rate == 0
514 float current_playback_rate = playback_rate_;
515 playback_rate_ = playback_rate;
517 if (!rendering_)
518 return;
520 if (current_playback_rate == 0 && playback_rate != 0) {
521 StartRendering_Locked();
522 return;
525 if (current_playback_rate != 0 && playback_rate == 0) {
526 StopRendering_Locked();
527 return;
531 bool AudioRendererImpl::IsBeforeStartTime(
532 const scoped_refptr<AudioBuffer>& buffer) {
533 DCHECK_EQ(state_, kPlaying);
534 return buffer && !buffer->end_of_stream() &&
535 (buffer->timestamp() + buffer->duration()) < start_timestamp_;
538 int AudioRendererImpl::Render(AudioBus* audio_bus,
539 int audio_delay_milliseconds) {
540 const int requested_frames = audio_bus->frames();
541 base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds(
542 audio_delay_milliseconds);
543 const int delay_frames = static_cast<int>(playback_delay.InSecondsF() *
544 audio_parameters_.sample_rate());
545 int frames_written = 0;
546 base::Closure time_cb;
548 base::AutoLock auto_lock(lock_);
550 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
551 if (!algorithm_) {
552 audio_clock_->WroteSilence(requested_frames, delay_frames);
553 return 0;
556 if (playback_rate_ == 0) {
557 audio_clock_->WroteSilence(requested_frames, delay_frames);
558 return 0;
561 // Mute audio by returning 0 when not playing.
562 if (state_ != kPlaying) {
563 audio_clock_->WroteSilence(requested_frames, delay_frames);
564 return 0;
567 // We use the following conditions to determine end of playback:
568 // 1) Algorithm can not fill the audio callback buffer
569 // 2) We received an end of stream buffer
570 // 3) We haven't already signalled that we've ended
571 // 4) We've played all known audio data sent to hardware
573 // We use the following conditions to determine underflow:
574 // 1) Algorithm can not fill the audio callback buffer
575 // 2) We have NOT received an end of stream buffer
576 // 3) We are in the kPlaying state
578 // Otherwise the buffer has data we can send to the device.
579 const base::TimeDelta media_timestamp_before_filling =
580 audio_clock_->CurrentMediaTimestamp(base::TimeDelta());
581 if (algorithm_->frames_buffered() > 0) {
582 frames_written =
583 algorithm_->FillBuffer(audio_bus, requested_frames, playback_rate_);
584 audio_clock_->WroteAudio(
585 frames_written, delay_frames, playback_rate_, algorithm_->GetTime());
587 audio_clock_->WroteSilence(requested_frames - frames_written, delay_frames);
589 if (frames_written == 0) {
590 if (received_end_of_stream_ && !rendered_end_of_stream_ &&
591 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) ==
592 audio_clock_->last_endpoint_timestamp()) {
593 rendered_end_of_stream_ = true;
594 ended_cb_.Run();
595 } else if (!received_end_of_stream_ && state_ == kPlaying) {
596 if (buffering_state_ != BUFFERING_HAVE_NOTHING) {
597 algorithm_->IncreaseQueueCapacity();
598 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
603 if (CanRead_Locked()) {
604 task_runner_->PostTask(FROM_HERE,
605 base::Bind(&AudioRendererImpl::AttemptRead,
606 weak_factory_.GetWeakPtr()));
609 // We only want to execute |time_cb_| if time has progressed and we haven't
610 // signaled end of stream yet.
611 if (media_timestamp_before_filling !=
612 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) &&
613 !rendered_end_of_stream_) {
614 time_cb =
615 base::Bind(time_cb_,
616 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()),
617 audio_clock_->last_endpoint_timestamp());
621 if (!time_cb.is_null())
622 task_runner_->PostTask(FROM_HERE, time_cb);
624 DCHECK_LE(frames_written, requested_frames);
625 return frames_written;
628 void AudioRendererImpl::OnRenderError() {
629 // UMA data tells us this happens ~0.01% of the time. Trigger an error instead
630 // of trying to gracefully fall back to a fake sink. It's very likely
631 // OnRenderError() should be removed and the audio stack handle errors without
632 // notifying clients. See http://crbug.com/234708 for details.
633 HistogramRendererEvent(RENDER_ERROR);
634 error_cb_.Run(PIPELINE_ERROR_DECODE);
637 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) {
638 lock_.AssertAcquired();
640 PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK;
641 switch (state_) {
642 case kUninitialized:
643 case kInitializing:
644 NOTREACHED();
645 return;
646 case kFlushing:
647 ChangeState_Locked(kFlushed);
648 if (status == PIPELINE_OK) {
649 DoFlush_Locked();
650 return;
653 error_cb_.Run(status);
654 base::ResetAndReturn(&flush_cb_).Run();
655 return;
657 case kFlushed:
658 case kPlaying:
659 if (status != PIPELINE_OK)
660 error_cb_.Run(status);
661 return;
665 void AudioRendererImpl::ChangeState_Locked(State new_state) {
666 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
667 lock_.AssertAcquired();
668 state_ = new_state;
671 void AudioRendererImpl::OnNewSpliceBuffer(base::TimeDelta splice_timestamp) {
672 DCHECK(task_runner_->BelongsToCurrentThread());
673 splicer_->SetSpliceTimestamp(splice_timestamp);
676 void AudioRendererImpl::OnConfigChange() {
677 DCHECK(task_runner_->BelongsToCurrentThread());
678 DCHECK(expecting_config_changes_);
679 buffer_converter_->ResetTimestampState();
680 // Drain flushed buffers from the converter so the AudioSplicer receives all
681 // data ahead of any OnNewSpliceBuffer() calls. Since discontinuities should
682 // only appear after config changes, AddInput() should never fail here.
683 while (buffer_converter_->HasNextBuffer())
684 CHECK(splicer_->AddInput(buffer_converter_->GetNextBuffer()));
687 void AudioRendererImpl::SetBufferingState_Locked(
688 BufferingState buffering_state) {
689 DVLOG(1) << __FUNCTION__ << " : " << buffering_state_ << " -> "
690 << buffering_state;
691 DCHECK_NE(buffering_state_, buffering_state);
692 lock_.AssertAcquired();
693 buffering_state_ = buffering_state;
695 task_runner_->PostTask(FROM_HERE,
696 base::Bind(buffering_state_cb_, buffering_state_));
699 } // namespace media