15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/audio_renderer_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_helpers.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/metrics/histogram.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/single_thread_task_runner.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/base/audio_buffer.h"
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_buffer_converter.h"
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "media/base/audio_hardware_config.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/audio_splicer.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/base/bind_to_current_loop.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/demuxer_stream.h"
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/filters/audio_clock.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/filters/decrypting_demuxer_stream.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum AudioRendererEvent {
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  INITIALIZED,
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RENDER_ERROR,
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RENDER_EVENT_MAX = RENDER_ERROR,
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void HistogramRendererEvent(AudioRendererEvent event) {
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION(
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      "Media.AudioRendererEvents", event, RENDER_EVENT_MAX + 1);
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AudioRendererImpl::AudioRendererImpl(
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    media::AudioRendererSink* sink,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedVector<AudioDecoder> decoders,
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const SetDecryptorReadyCB& set_decryptor_ready_cb,
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const AudioHardwareConfig& hardware_config,
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const scoped_refptr<MediaLog>& media_log)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : task_runner_(task_runner),
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      expecting_config_changes_(false),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sink_(sink),
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      audio_buffer_stream_(new AudioBufferStream(task_runner,
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                 decoders.Pass(),
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                 set_decryptor_ready_cb,
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                 media_log)),
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      hardware_config_(hardware_config),
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      playback_rate_(0),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state_(kUninitialized),
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      buffering_state_(BUFFERING_HAVE_NOTHING),
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      rendering_(false),
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      sink_playing_(false),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_read_(false),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      received_end_of_stream_(false),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rendered_end_of_stream_(false),
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      weak_factory_(this) {
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_buffer_stream_->set_splice_observer(base::Bind(
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_buffer_stream_->set_config_change_observer(base::Bind(
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AudioRendererImpl::~AudioRendererImpl() {
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__;
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If Render() is in progress, this call will wait for Render() to finish.
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // After this call, the |sink_| will not call back into |this| anymore.
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sink_->Stop();
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!init_cb_.is_null())
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AudioRendererImpl::StartTicking() {
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!rendering_);
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rendering_ = true;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Wait for an eventual call to SetPlaybackRate() to start rendering.
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (playback_rate_ == 0) {
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(!sink_playing_);
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StartRendering_Locked();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AudioRendererImpl::StartRendering_Locked() {
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(state_, kPlaying);
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(!sink_playing_);
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_NE(playback_rate_, 0);
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  sink_playing_ = true;
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::AutoUnlock auto_unlock(lock_);
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  sink_->Play();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AudioRendererImpl::StopTicking() {
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(rendering_);
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rendering_ = false;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Rendering should have already been stopped with a zero playback rate.
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (playback_rate_ == 0) {
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK(!sink_playing_);
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StopRendering_Locked();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AudioRendererImpl::StopRendering_Locked() {
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(state_, kPlaying);
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(sink_playing_);
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  sink_playing_ = false;
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::AutoUnlock auto_unlock(lock_);
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  sink_->Pause();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AudioRendererImpl::SetMediaTime(base::TimeDelta time) {
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << time.InMicroseconds() << ")";
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!rendering_);
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(state_, kFlushed);
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  start_timestamp_ = time;
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ended_timestamp_ = kInfiniteDuration();
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  last_render_ticks_ = base::TimeTicks();
1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  audio_clock_.reset(new AudioClock(time, audio_parameters_.sample_rate()));
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)base::TimeDelta AudioRendererImpl::CurrentMediaTime() {
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(2) << __FUNCTION__;
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // In practice the Render() method is called with a high enough frequency
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // that returning only the front timestamp is good enough and also prevents
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // returning values that go backwards in time.
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::AutoLock auto_lock(lock_);
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return audio_clock_->front_timestamp();
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeDelta AudioRendererImpl::CurrentMediaTimeForSyncingVideo() {
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(2) << __FUNCTION__;
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::AutoLock auto_lock(lock_);
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (last_render_ticks_.is_null())
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return audio_clock_->front_timestamp();
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return audio_clock_->TimestampSinceWriting(base::TimeTicks::Now() -
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             last_render_ticks_);
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TimeSource* AudioRendererImpl::GetTimeSource() {
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return this;
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererImpl::Flush(const base::Closure& callback) {
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(state_, kPlaying);
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(flush_cb_.is_null());
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  flush_cb_ = callback;
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ChangeState_Locked(kFlushing);
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (pending_read_)
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ChangeState_Locked(kFlushed);
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DoFlush_Locked();
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AudioRendererImpl::DoFlush_Locked() {
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  lock_.AssertAcquired();
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(!pending_read_);
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(state_, kFlushed);
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_buffer_stream_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone,
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                         weak_factory_.GetWeakPtr()));
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AudioRendererImpl::ResetDecoderDone() {
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  {
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::AutoLock auto_lock(lock_);
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(state_, kFlushed);
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(!flush_cb_.is_null());
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    received_end_of_stream_ = false;
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rendered_end_of_stream_ = false;
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Flush() may have been called while underflowed/not fully buffered.
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (buffering_state_ != BUFFERING_HAVE_NOTHING)
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    splicer_->Reset();
227effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (buffer_converter_)
228effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      buffer_converter_->Reset();
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    algorithm_->FlushBuffers();
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Changes in buffering state are always posted. Flush callback must only be
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // run after buffering state has been set back to nothing.
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&flush_cb_));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void AudioRendererImpl::StartPlaying() {
238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(1) << __FUNCTION__;
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!sink_playing_);
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK_EQ(state_, kFlushed);
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(buffering_state_, BUFFERING_HAVE_NOTHING);
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!pending_read_) << "Pending read must complete before seeking";
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ChangeState_Locked(kPlaying);
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AttemptRead_Locked();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AudioRendererImpl::Initialize(DemuxerStream* stream,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const PipelineStatusCB& init_cb,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const StatisticsCB& statistics_cb,
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   const BufferingStateCB& buffering_state_cb,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const base::Closure& ended_cb,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const PipelineStatusCB& error_cb) {
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(stream);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!init_cb.is_null());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!statistics_cb.is_null());
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(!buffering_state_cb.is_null());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!ended_cb.is_null());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!error_cb.is_null());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(kUninitialized, state_);
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(sink_.get());
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = kInitializing;
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Always post |init_cb_| because |this| could be destroyed if initialization
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // failed.
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  init_cb_ = BindToCurrentLoop(init_cb);
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  buffering_state_cb_ = buffering_state_cb;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ended_cb_ = ended_cb;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error_cb_ = error_cb;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
278effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  expecting_config_changes_ = stream->SupportsConfigChanges();
279effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!expecting_config_changes_) {
280effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // The actual buffer size is controlled via the size of the AudioBus
281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // provided to Render(), so just choose something reasonable here for looks.
282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    int buffer_size = stream->audio_decoder_config().samples_per_second() / 100;
283effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    audio_parameters_.Reset(
284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        AudioParameters::AUDIO_PCM_LOW_LATENCY,
285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        stream->audio_decoder_config().channel_layout(),
286effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        ChannelLayoutToChannelCount(
287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch            stream->audio_decoder_config().channel_layout()),
288effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        stream->audio_decoder_config().samples_per_second(),
289effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        stream->audio_decoder_config().bits_per_channel(),
290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        buffer_size);
291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    buffer_converter_.reset();
292effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } else {
293effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    // TODO(rileya): Support hardware config changes
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const AudioParameters& hw_params = hardware_config_.GetOutputConfig();
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    audio_parameters_.Reset(
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        hw_params.format(),
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        // Always use the source's channel layout and channel count to avoid
29846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        // premature downmixing (http://crbug.com/379288), platform specific
29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        // issues around channel layouts (http://crbug.com/266674), and
30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        // unnecessary upmixing overhead.
30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        stream->audio_decoder_config().channel_layout(),
30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        ChannelLayoutToChannelCount(
30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            stream->audio_decoder_config().channel_layout()),
30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        hw_params.sample_rate(),
30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        hw_params.bits_per_sample(),
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        hardware_config_.GetHighLatencyBufferSize());
307effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
308effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  audio_clock_.reset(
3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate()));
311010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_buffer_stream_->Initialize(
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      stream,
3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      false,
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      statistics_cb,
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
31723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!success) {
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state_ = kUninitialized;
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!audio_parameters_.IsValid()) {
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ChangeState_Locked(kUninitialized);
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (expecting_config_changes_)
338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    buffer_converter_.reset(new AudioBufferConverter(audio_parameters_));
339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  splicer_.reset(new AudioSplicer(audio_parameters_.sample_rate()));
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We're all good! Continue initializing the rest of the audio renderer
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // based on the decoder format.
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  algorithm_.reset(new AudioRendererAlgorithm());
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  algorithm_->Initialize(audio_parameters_);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ChangeState_Locked(kFlushed);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HistogramRendererEvent(INITIALIZED);
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    base::AutoUnlock auto_unlock(lock_);
35223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    sink_->Initialize(audio_parameters_, this);
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    sink_->Start();
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Some sinks play on start...
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    sink_->Pause();
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!sink_playing_);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererImpl::SetVolume(float volume) {
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(sink_.get());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sink_->SetVolume(volume);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AudioRendererImpl::DecodedAudioReady(
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    AudioBufferStream::Status status,
3717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const scoped_refptr<AudioBuffer>& buffer) {
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DVLOG(2) << __FUNCTION__ << "(" << status << ")";
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock auto_lock(lock_);
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(state_ != kUninitialized);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(pending_read_);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_read_ = false;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status == AudioBufferStream::ABORTED ||
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      status == AudioBufferStream::DEMUXER_READ_ABORTED) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HandleAbortedReadOrDecodeError(false);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status == AudioBufferStream::DECODE_ERROR) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HandleAbortedReadOrDecodeError(true);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(status, AudioBufferStream::OK);
393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(buffer.get());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (state_ == kFlushing) {
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ChangeState_Locked(kFlushed);
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DoFlush_Locked();
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
401effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (expecting_config_changes_) {
402effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(buffer_converter_);
403effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    buffer_converter_->AddInput(buffer);
404effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    while (buffer_converter_->HasNextBuffer()) {
405effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (!splicer_->AddInput(buffer_converter_->GetNextBuffer())) {
406effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        HandleAbortedReadOrDecodeError(true);
407effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return;
408effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      }
409effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } else {
411effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!splicer_->AddInput(buffer)) {
412effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      HandleAbortedReadOrDecodeError(true);
413effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return;
414effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!splicer_->HasNextBuffer()) {
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AttemptRead_Locked();
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool need_another_buffer = false;
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (splicer_->HasNextBuffer())
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    need_another_buffer = HandleSplicerBuffer_Locked(splicer_->GetNextBuffer());
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!need_another_buffer && !CanRead_Locked())
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AttemptRead_Locked();
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool AudioRendererImpl::HandleSplicerBuffer_Locked(
4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const scoped_refptr<AudioBuffer>& buffer) {
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  lock_.AssertAcquired();
435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (buffer->end_of_stream()) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    received_end_of_stream_ = true;
4378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else {
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (state_ == kPlaying) {
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (IsBeforeStartTime(buffer))
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return true;
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Trim off any additional time before the start timestamp.
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const base::TimeDelta trim_time = start_timestamp_ - buffer->timestamp();
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (trim_time > base::TimeDelta()) {
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        buffer->TrimStart(buffer->frame_count() *
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          (static_cast<double>(trim_time.InMicroseconds()) /
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           buffer->duration().InMicroseconds()));
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // If the entire buffer was trimmed, request a new one.
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!buffer->frame_count())
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return true;
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (state_ != kUninitialized)
4558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      algorithm_->EnqueueBuffer(buffer);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (state_) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kUninitialized:
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case kInitializing:
461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case kFlushing:
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
4648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case kFlushed:
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(!pending_read_);
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
4688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kPlaying:
470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (buffer->end_of_stream() || algorithm_->IsQueueFull()) {
471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        if (buffering_state_ == BUFFERING_HAVE_NOTHING)
472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          SetBufferingState_Locked(BUFFERING_HAVE_ENOUGH);
473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        return false;
474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return true;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AudioRendererImpl::AttemptRead() {
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AttemptRead_Locked();
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AudioRendererImpl::AttemptRead_Locked() {
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  lock_.AssertAcquired();
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CanRead_Locked())
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_read_ = true;
493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  audio_buffer_stream_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                        weak_factory_.GetWeakPtr()));
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AudioRendererImpl::CanRead_Locked() {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  lock_.AssertAcquired();
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (state_) {
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kUninitialized:
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case kInitializing:
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case kFlushing:
504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case kFlushed:
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kPlaying:
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !pending_read_ && !received_end_of_stream_ &&
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !algorithm_->IsQueueFull();
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_GE(playback_rate, 0);
5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(sink_.get());
5204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::AutoLock auto_lock(lock_);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have two cases here:
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Play: current_playback_rate == 0 && playback_rate != 0
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Pause: current_playback_rate != 0 && playback_rate == 0
5265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  float current_playback_rate = playback_rate_;
5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  playback_rate_ = playback_rate;
528cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
529cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!rendering_)
530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (current_playback_rate == 0 && playback_rate != 0) {
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    StartRendering_Locked();
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (current_playback_rate != 0 && playback_rate == 0) {
538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    StopRendering_Locked();
539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
543116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool AudioRendererImpl::IsBeforeStartTime(
5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const scoped_refptr<AudioBuffer>& buffer) {
545116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(state_, kPlaying);
5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return buffer.get() && !buffer->end_of_stream() &&
547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch         (buffer->timestamp() + buffer->duration()) < start_timestamp_;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int AudioRendererImpl::Render(AudioBus* audio_bus,
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int audio_delay_milliseconds) {
5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const int requested_frames = audio_bus->frames();
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds(
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      audio_delay_milliseconds);
555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const int delay_frames = static_cast<int>(playback_delay.InSecondsF() *
556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                            audio_parameters_.sample_rate());
5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int frames_written = 0;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::AutoLock auto_lock(lock_);
5601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    last_render_ticks_ = base::TimeTicks::Now();
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (!algorithm_) {
5646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      audio_clock_->WroteAudio(
5656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          0, requested_frames, delay_frames, playback_rate_);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (playback_rate_ == 0) {
5706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      audio_clock_->WroteAudio(
5716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          0, requested_frames, delay_frames, playback_rate_);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Mute audio by returning 0 when not playing.
576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (state_ != kPlaying) {
5776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      audio_clock_->WroteAudio(
5786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          0, requested_frames, delay_frames, playback_rate_);
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return 0;
580010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We use the following conditions to determine end of playback:
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   1) Algorithm can not fill the audio callback buffer
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   2) We received an end of stream buffer
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   3) We haven't already signalled that we've ended
586116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    //   4) We've played all known audio data sent to hardware
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We use the following conditions to determine underflow:
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   1) Algorithm can not fill the audio callback buffer
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   2) We have NOT received an end of stream buffer
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   3) We are in the kPlaying state
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Otherwise the buffer has data we can send to the device.
594010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (algorithm_->frames_buffered() > 0) {
5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      frames_written =
5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          algorithm_->FillBuffer(audio_bus, requested_frames, playback_rate_);
597010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
598010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Per the TimeSource API the media time should always increase even after
6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // we've rendered all known audio data. Doing so simplifies scenarios where
6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // we have other sources of media data that need to be scheduled after audio
6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // data has ended.
6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //
6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // That being said, we don't want to advance time when underflowed as we
6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // know more decoded frames will eventually arrive. If we did, we would
6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // throw things out of sync when said decoded frames arrive.
6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int frames_after_end_of_stream = 0;
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (frames_written == 0) {
6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (received_end_of_stream_) {
6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (ended_timestamp_ == kInfiniteDuration())
6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ended_timestamp_ = audio_clock_->back_timestamp();
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        frames_after_end_of_stream = requested_frames;
6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      } else if (state_ == kPlaying &&
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 buffering_state_ != BUFFERING_HAVE_NOTHING) {
6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        algorithm_->IncreaseQueueCapacity();
6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SetBufferingState_Locked(BUFFERING_HAVE_NOTHING);
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    audio_clock_->WroteAudio(frames_written + frames_after_end_of_stream,
6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             requested_frames,
6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             delay_frames,
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             playback_rate_);
6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (CanRead_Locked()) {
62623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      task_runner_->PostTask(FROM_HERE,
62723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                             base::Bind(&AudioRendererImpl::AttemptRead,
62823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                        weak_factory_.GetWeakPtr()));
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (audio_clock_->front_timestamp() >= ended_timestamp_ &&
6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        !rendered_end_of_stream_) {
6331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      rendered_end_of_stream_ = true;
6341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_runner_->PostTask(FROM_HERE, ended_cb_);
6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK_LE(frames_written, requested_frames);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return frames_written;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererImpl::OnRenderError() {
6430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // UMA data tells us this happens ~0.01% of the time. Trigger an error instead
6440de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // of trying to gracefully fall back to a fake sink. It's very likely
6450de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // OnRenderError() should be removed and the audio stack handle errors without
6460de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // notifying clients. See http://crbug.com/234708 for details.
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HistogramRendererEvent(RENDER_ERROR);
6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Post to |task_runner_| as this is called on the audio callback thread.
6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  task_runner_->PostTask(FROM_HERE,
6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         base::Bind(error_cb_, PIPELINE_ERROR_DECODE));
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) {
6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(task_runner_->BelongsToCurrentThread());
655a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  lock_.AssertAcquired();
656a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK;
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (state_) {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kUninitialized:
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case kInitializing:
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
663a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case kFlushing:
664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ChangeState_Locked(kFlushed);
665a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (status == PIPELINE_OK) {
666a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        DoFlush_Locked();
667a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        return;
668a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
670a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      error_cb_.Run(status);
671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::ResetAndReturn(&flush_cb_).Run();
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
673116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
674cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    case kFlushed:
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kPlaying:
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (status != PIPELINE_OK)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        error_cb_.Run(status);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AudioRendererImpl::ChangeState_Locked(State new_state) {
6834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
6844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lock_.AssertAcquired();
6854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  state_ = new_state;
6864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
6874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
688effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AudioRendererImpl::OnNewSpliceBuffer(base::TimeDelta splice_timestamp) {
689effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(task_runner_->BelongsToCurrentThread());
690effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  splicer_->SetSpliceTimestamp(splice_timestamp);
691effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
692effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
693effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AudioRendererImpl::OnConfigChange() {
694effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(task_runner_->BelongsToCurrentThread());
695effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(expecting_config_changes_);
696effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  buffer_converter_->ResetTimestampState();
6970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Drain flushed buffers from the converter so the AudioSplicer receives all
6980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // data ahead of any OnNewSpliceBuffer() calls.  Since discontinuities should
6990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // only appear after config changes, AddInput() should never fail here.
7000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  while (buffer_converter_->HasNextBuffer())
7010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CHECK(splicer_->AddInput(buffer_converter_->GetNextBuffer()));
702effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
703effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
704116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AudioRendererImpl::SetBufferingState_Locked(
705116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    BufferingState buffering_state) {
706116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DVLOG(1) << __FUNCTION__ << " : " << buffering_state_ << " -> "
707116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch           << buffering_state;
708116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_NE(buffering_state_, buffering_state);
709116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  lock_.AssertAcquired();
710116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  buffering_state_ = buffering_state;
711116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
712116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  task_runner_->PostTask(FROM_HERE,
713116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         base::Bind(buffering_state_cb_, buffering_state_));
714116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
715116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
717