11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/filters/renderer_impl.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback_helpers.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/compiler_specific.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/location.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/single_thread_task_runner.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/audio_renderer.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/demuxer_stream_provider.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/time_source.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/video_renderer.h" 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/wall_clock_time_source.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media { 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciRendererImpl::RendererImpl( 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DemuxerStreamProvider* demuxer_stream_provider, 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<AudioRenderer> audio_renderer, 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<VideoRenderer> video_renderer) 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : state_(STATE_UNINITIALIZED), 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_(task_runner), 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci demuxer_stream_provider_(demuxer_stream_provider), 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_(audio_renderer.Pass()), 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_renderer_(video_renderer.Pass()), 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_source_(NULL), 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_ticking_(false), 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_buffering_state_(BUFFERING_HAVE_NOTHING), 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_buffering_state_(BUFFERING_HAVE_NOTHING), 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_ended_(false), 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_ended_(false), 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci underflow_disabled_for_testing_(false), 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci clockless_video_playback_enabled_for_testing_(false), 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this), 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_this_(weak_factory_.GetWeakPtr()) { 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciRendererImpl::~RendererImpl() { 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Tear down in opposite order of construction as |video_renderer_| can still 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // need |time_source_| (which can be |audio_renderer_|) to be alive. 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_renderer_.reset(); 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_.reset(); 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FireAllPendingCallbacks(); 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::Initialize(const base::Closure& init_cb, 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const StatisticsCB& statistics_cb, 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::Closure& ended_cb, 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const PipelineStatusCB& error_cb, 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const BufferingStateCB& buffering_state_cb) { 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_UNINITIALIZED) << state_; 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!init_cb.is_null()); 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!statistics_cb.is_null()); 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!ended_cb.is_null()); 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!error_cb.is_null()); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!buffering_state_cb.is_null()); 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO) || 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO)); 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci statistics_cb_ = statistics_cb; 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ended_cb_ = ended_cb; 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error_cb_ = error_cb; 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffering_state_cb_ = buffering_state_cb; 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci init_cb_ = init_cb; 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state_ = STATE_INITIALIZING; 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InitializeAudioRenderer(); 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::Flush(const base::Closure& flush_cb) { 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_PLAYING) << state_; 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(flush_cb_.is_null()); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flush_cb_ = flush_cb; 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state_ = STATE_FLUSHING; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (time_ticking_) 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PausePlayback(); 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FlushAudioRenderer(); 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::StartPlayingFrom(base::TimeDelta time) { 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_PLAYING) << state_; 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_source_->SetMediaTime(time); 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (audio_renderer_) 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_->StartPlaying(); 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (video_renderer_) 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_renderer_->StartPlayingFrom(time); 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::SetPlaybackRate(float playback_rate) { 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Playback rate changes are only carried out while playing. 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_ != STATE_PLAYING) 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_source_->SetPlaybackRate(playback_rate); 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::SetVolume(float volume) { 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (audio_renderer_) 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_->SetVolume(volume); 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeDelta RendererImpl::GetMediaTime() { 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // No BelongsToCurrentThread() checking because this can be called from other 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // threads. 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return time_source_->CurrentMediaTime(); 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool RendererImpl::HasAudio() { 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return audio_renderer_ != NULL; 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool RendererImpl::HasVideo() { 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return video_renderer_ != NULL; 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::SetCdm(MediaKeys* cdm) { 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(xhwang): Explore to possibility to move CDM setting from 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // WebMediaPlayerImpl to this class. See http://crbug.com/401264 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::DisableUnderflowForTesting() { 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_UNINITIALIZED); 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci underflow_disabled_for_testing_ = true; 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::EnableClocklessVideoPlaybackForTesting() { 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_UNINITIALIZED); 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(underflow_disabled_for_testing_) 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << "Underflow must be disabled for clockless video playback"; 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci clockless_video_playback_enabled_for_testing_ = true; 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeDelta RendererImpl::GetMediaTimeForSyncingVideo() { 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // No BelongsToCurrentThread() checking because this can be called from other 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // threads. 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(scherkus): Currently called from VideoRendererImpl's internal thread, 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // which should go away at some point http://crbug.com/110814 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (clockless_video_playback_enabled_for_testing_) 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return base::TimeDelta::Max(); 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return time_source_->CurrentMediaTimeForSyncingVideo(); 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::InitializeAudioRenderer() { 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!init_cb_.is_null()); 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PipelineStatusCB done_cb = 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnAudioRendererInitializeDone, weak_this_); 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO)) { 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_.reset(); 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_->Initialize( 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO), 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci done_cb, 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnUpdateStatistics, weak_this_), 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnBufferingStateChanged, weak_this_, 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &audio_buffering_state_), 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnAudioRendererEnded, weak_this_), 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnError, weak_this_)); 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__ << ": " << status; 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!init_cb_.is_null()); 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (status != PIPELINE_OK) { 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_.reset(); 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnError(status); 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InitializeVideoRenderer(); 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::InitializeVideoRenderer() { 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!init_cb_.is_null()); 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PipelineStatusCB done_cb = 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnVideoRendererInitializeDone, weak_this_); 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO)) { 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_renderer_.reset(); 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_renderer_->Initialize( 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO), 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci demuxer_stream_provider_->GetLiveness() == 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DemuxerStreamProvider::LIVENESS_LIVE, 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci done_cb, 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnUpdateStatistics, weak_this_), 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnBufferingStateChanged, 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_this_, 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &video_buffering_state_), 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnVideoRendererEnded, weak_this_), 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnError, weak_this_), 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::GetMediaTimeForSyncingVideo, 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Unretained(this))); 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__ << ": " << status; 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_INITIALIZING) << state_; 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!init_cb_.is_null()); 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (status != PIPELINE_OK) { 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_.reset(); 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_renderer_.reset(); 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnError(status); 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (audio_renderer_) { 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_source_ = audio_renderer_->GetTimeSource(); 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci wall_clock_time_source_.reset(new WallClockTimeSource()); 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_source_ = wall_clock_time_source_.get(); 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state_ = STATE_PLAYING; 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(time_source_); 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(audio_renderer_ || video_renderer_); 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ResetAndReturn(&init_cb_).Run(); 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::FlushAudioRenderer() { 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_FLUSHING) << state_; 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!flush_cb_.is_null()); 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!audio_renderer_) { 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnAudioRendererFlushDone(); 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_renderer_->Flush( 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnAudioRendererFlushDone, weak_this_)); 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnAudioRendererFlushDone() { 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_ == STATE_ERROR) { 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(flush_cb_.is_null()); 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_FLUSHING) << state_; 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!flush_cb_.is_null()); 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(audio_buffering_state_, BUFFERING_HAVE_NOTHING); 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_ended_ = false; 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FlushVideoRenderer(); 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::FlushVideoRenderer() { 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_FLUSHING) << state_; 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!flush_cb_.is_null()); 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!video_renderer_) { 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OnVideoRendererFlushDone(); 3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_renderer_->Flush( 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&RendererImpl::OnVideoRendererFlushDone, weak_this_)); 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnVideoRendererFlushDone() { 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_ == STATE_ERROR) { 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(flush_cb_.is_null()); 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_FLUSHING) << state_; 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!flush_cb_.is_null()); 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(video_buffering_state_, BUFFERING_HAVE_NOTHING); 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_ended_ = false; 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state_ = STATE_PLAYING; 3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ResetAndReturn(&flush_cb_).Run(); 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnUpdateStatistics(const PipelineStatistics& stats) { 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci statistics_cb_.Run(stats); 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnBufferingStateChanged(BufferingState* buffering_state, 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BufferingState new_buffering_state) { 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__ << "(" << *buffering_state << ", " 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << new_buffering_state << ") " 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << (buffering_state == &audio_buffering_state_ ? "audio" : "video"); 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool was_waiting_for_enough_data = WaitingForEnoughData(); 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *buffering_state = new_buffering_state; 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Disable underflow by ignoring updates that renderers have ran out of data. 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_ == STATE_PLAYING && underflow_disabled_for_testing_ && 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_ticking_) { 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << "Update ignored because underflow is disabled for testing."; 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Renderer underflowed. 3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!was_waiting_for_enough_data && WaitingForEnoughData()) { 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PausePlayback(); 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(scherkus): Fire BUFFERING_HAVE_NOTHING callback to alert clients of 3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // underflow state http://crbug.com/144683 3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Renderer prerolled. 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (was_waiting_for_enough_data && !WaitingForEnoughData()) { 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci StartPlayback(); 3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci buffering_state_cb_.Run(BUFFERING_HAVE_ENOUGH); 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool RendererImpl::WaitingForEnoughData() const { 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_ != STATE_PLAYING) 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (audio_renderer_ && audio_buffering_state_ != BUFFERING_HAVE_ENOUGH) 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (video_renderer_ && video_buffering_state_ != BUFFERING_HAVE_ENOUGH) 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::PausePlayback() { 3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(time_ticking_); 3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (state_) { 3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case STATE_PLAYING: 4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(PlaybackHasEnded() || WaitingForEnoughData()) 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << "Playback should only pause due to ending or underflowing"; 4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case STATE_FLUSHING: 4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // It's OK to pause playback when flushing. 4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case STATE_UNINITIALIZED: 4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case STATE_INITIALIZING: 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case STATE_ERROR: 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED() << "Invalid state: " << state_; 4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_ticking_ = false; 4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_source_->StopTicking(); 4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::StartPlayback() { 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(state_, STATE_PLAYING); 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!time_ticking_); 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!WaitingForEnoughData()); 4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_ticking_ = true; 4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci time_source_->StartTicking(); 4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnAudioRendererEnded() { 4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_ != STATE_PLAYING) 4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!audio_ended_); 4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci audio_ended_ = true; 4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RunEndedCallbackIfNeeded(); 4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnVideoRendererEnded() { 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (state_ != STATE_PLAYING) 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!video_ended_); 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci video_ended_ = true; 4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RunEndedCallbackIfNeeded(); 4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool RendererImpl::PlaybackHasEnded() const { 4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (audio_renderer_ && !audio_ended_) 4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (video_renderer_ && !video_ended_) 4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::RunEndedCallbackIfNeeded() { 4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__; 4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!PlaybackHasEnded()) 4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (time_ticking_) 4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PausePlayback(); 4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ended_cb_.Run(); 4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::OnError(PipelineStatus error) { 4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DVLOG(1) << __FUNCTION__ << "(" << error << ")"; 4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; 4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state_ = STATE_ERROR; 4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Pipeline will destroy |this| as the result of error. 4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ResetAndReturn(&error_cb_).Run(error); 4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FireAllPendingCallbacks(); 4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RendererImpl::FireAllPendingCallbacks() { 4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(task_runner_->BelongsToCurrentThread()); 4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!init_cb_.is_null()) 4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ResetAndReturn(&init_cb_).Run(); 5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!flush_cb_.is_null()) 5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ResetAndReturn(&flush_cb_).Run(); 5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace media 506