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