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