Index: media/filters/video_renderer_algorithm.cc |
diff --git a/media/filters/video_renderer_algorithm.cc b/media/filters/video_renderer_algorithm.cc |
index d29cad890ebcaecf92a6381b8d55378cc4ead8ad..2670823ab508988738d35c614a73a74f8918865c 100644 |
--- a/media/filters/video_renderer_algorithm.cc |
+++ b/media/filters/video_renderer_algorithm.cc |
@@ -69,28 +69,24 @@ scoped_refptr<VideoFrame> VideoRendererAlgorithm::Render( |
// to Render(). If so, we assume the last frame provided was rendered during |
// those intervals and adjust its render count appropriately. |
AccountForMissedIntervals(deadline_min, deadline_max); |
- last_deadline_max_ = deadline_max; |
// Step 3: Update the wall clock timestamps and frame duration estimates for |
// all frames currently in the |frame_queue_|. |
- if (!UpdateFrameStatistics()) { |
- DVLOG(2) << "Failed to update frame statistics."; |
- |
+ UpdateFrameStatistics(); |
+ const bool have_known_duration = average_frame_duration_ > base::TimeDelta(); |
+ if (!(was_time_moving_ && have_known_duration)) { |
ReadyFrame& ready_frame = frame_queue_[last_frame_index_]; |
DCHECK(ready_frame.frame); |
// If duration is unknown, we don't have enough frames to make a good guess |
// about which frame to use, so always choose the first. |
- if (average_frame_duration_ == base::TimeDelta() && |
- !ready_frame.start_time.is_null()) { |
+ if (was_time_moving_ && !have_known_duration) |
++ready_frame.render_count; |
- } |
return ready_frame.frame; |
} |
- DCHECK_GT(average_frame_duration_, base::TimeDelta()); |
- |
+ last_deadline_max_ = deadline_max; |
base::TimeDelta selected_frame_drift; |
// Step 4: Attempt to find the best frame by cadence. |
@@ -250,7 +246,8 @@ size_t VideoRendererAlgorithm::RemoveExpiredFrames(base::TimeTicks deadline) { |
if (deadline > last_deadline_max_) |
last_deadline_max_ = deadline; |
- if (!UpdateFrameStatistics() || frame_queue_.size() < 2) |
+ UpdateFrameStatistics(); |
+ if (frame_queue_.size() < 2) |
return 0; |
DCHECK_GT(average_frame_duration_, base::TimeDelta()); |
@@ -308,6 +305,7 @@ void VideoRendererAlgorithm::Reset() { |
first_frame_ = true; |
cadence_frame_counter_ = 0; |
last_render_ignored_cadence_frame_ = false; |
+ was_time_moving_ = false; |
// Default to ATSC IS/191 recommendations for maximum acceptable drift before |
// we have enough frames to base the maximum on frame duration. |
@@ -414,7 +412,7 @@ void VideoRendererAlgorithm::AccountForMissedIntervals( |
base::TimeTicks deadline_min, |
base::TimeTicks deadline_max) { |
if (last_deadline_max_.is_null() || deadline_min <= last_deadline_max_ || |
- !have_rendered_frames_) { |
+ !have_rendered_frames_ || !was_time_moving_) { |
return; |
} |
@@ -445,7 +443,7 @@ void VideoRendererAlgorithm::AccountForMissedIntervals( |
ready_frame.render_count += render_cycle_count; |
} |
-bool VideoRendererAlgorithm::UpdateFrameStatistics() { |
+void VideoRendererAlgorithm::UpdateFrameStatistics() { |
DCHECK(!frame_queue_.empty()); |
// Figure out all current ready frame times at once. |
@@ -454,10 +452,9 @@ bool VideoRendererAlgorithm::UpdateFrameStatistics() { |
for (const auto& ready_frame : frame_queue_) |
media_timestamps.push_back(ready_frame.frame->timestamp()); |
- // If time has stopped, we can bail out early. |
std::vector<base::TimeTicks> wall_clock_times; |
- if (!wall_clock_time_cb_.Run(media_timestamps, &wall_clock_times)) |
- return false; |
+ was_time_moving_ = |
+ wall_clock_time_cb_.Run(media_timestamps, &wall_clock_times); |
// Transfer the converted wall clock times into our frame queue. |
DCHECK_EQ(wall_clock_times.size(), frame_queue_.size()); |
@@ -473,7 +470,7 @@ bool VideoRendererAlgorithm::UpdateFrameStatistics() { |
frame_queue_.back().start_time = wall_clock_times.back(); |
if (!frame_duration_calculator_.count()) |
- return false; |
+ return; |
// Compute |average_frame_duration_|, a moving average of the last few frames; |
// see kMovingAverageSamples for the exact number. |
@@ -496,7 +493,7 @@ bool VideoRendererAlgorithm::UpdateFrameStatistics() { |
// If we were called via RemoveExpiredFrames() and Render() was never called, |
// we may not have a render interval yet. |
if (render_interval_ == base::TimeDelta()) |
- return true; |
+ return; |
const bool cadence_changed = cadence_estimator_.UpdateCadenceEstimate( |
render_interval_, average_frame_duration_, max_acceptable_drift_); |
@@ -504,15 +501,10 @@ bool VideoRendererAlgorithm::UpdateFrameStatistics() { |
// No need to update cadence if there's been no change; cadence will be set |
// as frames are added to the queue. |
if (!cadence_changed) |
- return true; |
+ return; |
cadence_frame_counter_ = 0; |
UpdateCadenceForFrames(); |
- |
- // Thus far there appears to be no need for special 3:2 considerations, the |
- // smoothness scores seem to naturally fit that pattern based on maximizing |
- // frame coverage. |
- return true; |
} |
void VideoRendererAlgorithm::UpdateCadenceForFrames() { |