Index: media/renderers/renderer_impl.cc |
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc |
index 7381e94ef695c43036c62291bbbcb0f918057fa6..94fbe94eaff5593ed3b185bb542c33ec06a969aa 100644 |
--- a/media/renderers/renderer_impl.cc |
+++ b/media/renderers/renderer_impl.cc |
@@ -32,6 +32,8 @@ static const int kDefaultVideoUnderflowThresholdMs = 3000; |
static const int kAudioRestartUnderflowThresholdMs = 2000; |
+static const int kTimeUpdateIntervalMs = 50; |
+ |
class RendererImpl::RendererClientInternal : public RendererClient { |
public: |
RendererClientInternal(DemuxerStream::Type type, RendererImpl* renderer) |
@@ -58,6 +60,11 @@ class RendererImpl::RendererClientInternal : public RendererClient { |
DCHECK(type_ == DemuxerStream::VIDEO); |
renderer_->OnVideoOpacityChange(opaque); |
} |
+ void OnTimeUpdate(base::TimeDelta curr_time, |
+ base::TimeDelta max_time, |
+ base::TimeTicks capture_time) override { |
+ NOTREACHED(); |
+ } |
private: |
DemuxerStream::Type type_; |
@@ -243,6 +250,7 @@ void RendererImpl::RestartStreamPlayback(DemuxerStream* stream, |
if (time_ticking_) { |
time_ticking_ = false; |
time_source_->StopTicking(); |
+ CancelPeriodicMediaTimeUpdates(); |
} |
audio_renderer_->Flush( |
base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); |
@@ -300,7 +308,7 @@ void RendererImpl::SetVolume(float volume) { |
base::TimeDelta RendererImpl::GetMediaTime() { |
// No BelongsToCurrentThread() checking because this can be called from other |
// threads. |
- return time_source_->CurrentMediaTime(); |
+ return time_source_->CurrentMediaTime(nullptr); |
} |
bool RendererImpl::HasAudio() { |
@@ -743,6 +751,7 @@ void RendererImpl::PausePlayback() { |
if (time_ticking_) { |
time_ticking_ = false; |
time_source_->StopTicking(); |
+ CancelPeriodicMediaTimeUpdates(); |
} |
if (playback_rate_ > 0 && video_renderer_) |
video_renderer_->OnTimeStateChanged(false); |
@@ -757,6 +766,8 @@ void RendererImpl::StartPlayback() { |
time_ticking_ = true; |
time_source_->StartTicking(); |
+ SchedulePeriodicMediaTimeUpdates(); |
+ |
if (playback_rate_ > 0 && video_renderer_) |
video_renderer_->OnTimeStateChanged(true); |
} |
@@ -848,4 +859,40 @@ void RendererImpl::OnVideoOpacityChange(bool opaque) { |
client_->OnVideoOpacityChange(opaque); |
} |
+void RendererImpl::UpdateMediaTime() { |
+ DCHECK(task_runner_->BelongsToCurrentThread()); |
+ DCHECK(time_ticking_); |
+ |
+ base::TimeTicks capture_time; |
+ base::TimeDelta curr_time = time_source_->CurrentMediaTime(&capture_time); |
+ // Allow some slop to account for delays in scheduling time update tasks. |
+ base::TimeDelta max_time = |
+ curr_time + base::TimeDelta::FromMilliseconds(2 * kTimeUpdateIntervalMs); |
+ client_->OnTimeUpdate(curr_time, max_time, capture_time); |
+} |
+ |
+void RendererImpl::SchedulePeriodicMediaTimeUpdates() { |
+ DVLOG(2) << __func__; |
+ DCHECK(task_runner_->BelongsToCurrentThread()); |
+ |
+ base::TimeTicks capture_time; |
+ base::TimeDelta curr_time = time_source_->CurrentMediaTime(&capture_time); |
+ client_->OnTimeUpdate(curr_time, curr_time, capture_time); |
+ |
+ time_update_timer_.Start( |
+ FROM_HERE, base::TimeDelta::FromMilliseconds(kTimeUpdateIntervalMs), |
+ base::Bind(&RendererImpl::UpdateMediaTime, weak_this_)); |
+} |
+ |
+void RendererImpl::CancelPeriodicMediaTimeUpdates() { |
+ DVLOG(2) << __func__; |
+ DCHECK(task_runner_->BelongsToCurrentThread()); |
+ |
+ time_update_timer_.Stop(); |
+ |
+ base::TimeTicks capture_time; |
+ base::TimeDelta curr_time = time_source_->CurrentMediaTime(&capture_time); |
+ client_->OnTimeUpdate(curr_time, curr_time, capture_time); |
+} |
+ |
} // namespace media |