Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Unified Diff: media/filters/video_renderer_algorithm.cc

Issue 1160853006: Improve audio/video sync during underflow, reduce underflow frequency. (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/filters/video_renderer_algorithm.h ('k') | media/filters/video_renderer_algorithm_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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() {
« no previous file with comments | « media/filters/video_renderer_algorithm.h ('k') | media/filters/video_renderer_algorithm_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698