diff options
Diffstat (limited to 'media/renderers/renderer_impl.cc')
-rw-r--r-- | media/renderers/renderer_impl.cc | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc index e81c97ae..8088b07 100644 --- a/media/renderers/renderer_impl.cc +++ b/media/renderers/renderer_impl.cc @@ -7,18 +7,24 @@ #include "base/bind.h" #include "base/callback.h" #include "base/callback_helpers.h" +#include "base/command_line.h" #include "base/compiler_specific.h" #include "base/location.h" #include "base/single_thread_task_runner.h" +#include "base/strings/string_number_conversions.h" #include "media/base/audio_renderer.h" #include "media/base/bind_to_current_loop.h" #include "media/base/demuxer_stream_provider.h" +#include "media/base/media_switches.h" #include "media/base/time_source.h" #include "media/base/video_renderer.h" #include "media/base/wall_clock_time_source.h" namespace media { +// See |video_underflow_threshold_|. +static const int kDefaultVideoUnderflowThresholdMs = 3000; + RendererImpl::RendererImpl( const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, scoped_ptr<AudioRenderer> audio_renderer, @@ -36,9 +42,22 @@ RendererImpl::RendererImpl( cdm_context_(nullptr), underflow_disabled_for_testing_(false), clockless_video_playback_enabled_for_testing_(false), + video_underflow_threshold_( + base::TimeDelta::FromMilliseconds(kDefaultVideoUnderflowThresholdMs)), weak_factory_(this) { weak_this_ = weak_factory_.GetWeakPtr(); DVLOG(1) << __FUNCTION__; + + // TODO(dalecurtis): Remove once experiments for http://crbug.com/470940 are + // complete. + int threshold_ms = 0; + std::string threshold_ms_str( + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kVideoUnderflowThresholdMs)); + if (base::StringToInt(threshold_ms_str, &threshold_ms) && threshold_ms > 0) { + video_underflow_threshold_ = + base::TimeDelta::FromMilliseconds(threshold_ms); + } } RendererImpl::~RendererImpl() { @@ -336,7 +355,7 @@ void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { if (audio_renderer_) { time_source_ = audio_renderer_->GetTimeSource(); - } else { + } else if (!time_source_) { wall_clock_time_source_.reset(new WallClockTimeSource()); time_source_ = wall_clock_time_source_.get(); } @@ -419,12 +438,37 @@ void RendererImpl::OnUpdateStatistics(const PipelineStatistics& stats) { void RendererImpl::OnBufferingStateChanged(BufferingState* buffering_state, BufferingState new_buffering_state) { + const bool is_audio = buffering_state == &audio_buffering_state_; DVLOG(1) << __FUNCTION__ << "(" << *buffering_state << ", " - << new_buffering_state << ") " - << (buffering_state == &audio_buffering_state_ ? "audio" : "video"); + << new_buffering_state << ") " << (is_audio ? "audio" : "video"); DCHECK(task_runner_->BelongsToCurrentThread()); + bool was_waiting_for_enough_data = WaitingForEnoughData(); + // When audio is present, defer underflow callbacks for some time to avoid + // unnecessary glitches in audio; see http://crbug.com/144683#c53. + if (audio_renderer_ && !is_audio && state_ == STATE_PLAYING) { + if (video_buffering_state_ == BUFFERING_HAVE_ENOUGH && + new_buffering_state == BUFFERING_HAVE_NOTHING && + deferred_underflow_cb_.IsCancelled()) { + deferred_underflow_cb_.Reset(base::Bind( + &RendererImpl::OnBufferingStateChanged, weak_factory_.GetWeakPtr(), + buffering_state, new_buffering_state)); + task_runner_->PostDelayedTask(FROM_HERE, + deferred_underflow_cb_.callback(), + video_underflow_threshold_); + return; + } + + deferred_underflow_cb_.Cancel(); + } else if (!deferred_underflow_cb_.IsCancelled() && is_audio && + new_buffering_state == BUFFERING_HAVE_NOTHING) { + // If audio underflows while we have a deferred video underflow in progress + // we want to mark video as underflowed immediately and cancel the deferral. + deferred_underflow_cb_.Cancel(); + video_buffering_state_ = BUFFERING_HAVE_NOTHING; + } + *buffering_state = new_buffering_state; // Disable underflow by ignoring updates that renderers have ran out of data. |