| Index: media/filters/video_renderer_algorithm.cc
|
| diff --git a/media/filters/video_renderer_algorithm.cc b/media/filters/video_renderer_algorithm.cc
|
| index a0016566210550d123b99460037b3cc0ac8a7c22..052321dae5366fe152acc1e61627bfd750324c12 100644
|
| --- a/media/filters/video_renderer_algorithm.cc
|
| +++ b/media/filters/video_renderer_algorithm.cc
|
| @@ -94,10 +94,12 @@ scoped_refptr<VideoFrame> VideoRendererAlgorithm::Render(
|
| base::TimeDelta selected_frame_drift;
|
|
|
| // Step 4: Attempt to find the best frame by cadence.
|
| + bool was_frame_selected_by_cadence = false;
|
| int cadence_overage = 0;
|
| int frame_to_render =
|
| FindBestFrameByCadence(first_frame_ ? nullptr : &cadence_overage);
|
| if (frame_to_render >= 0) {
|
| + was_frame_selected_by_cadence = true;
|
| selected_frame_drift =
|
| CalculateAbsoluteDriftForFrame(deadline_min, frame_to_render);
|
| }
|
| @@ -121,7 +123,12 @@ scoped_refptr<VideoFrame> VideoRendererAlgorithm::Render(
|
| }
|
|
|
| if (frame_to_render >= 0) {
|
| - cadence_overage = 0;
|
| + if (was_frame_selected_by_cadence) {
|
| + cadence_overage = 0;
|
| + was_frame_selected_by_cadence = false;
|
| + DVLOG(2) << "Overriding frame selected by cadence because of drift: "
|
| + << selected_frame_drift;
|
| + }
|
| selected_frame_drift =
|
| CalculateAbsoluteDriftForFrame(deadline_min, frame_to_render);
|
| }
|
| @@ -132,7 +139,10 @@ scoped_refptr<VideoFrame> VideoRendererAlgorithm::Render(
|
| // selection is going to be bad because it means no suitable frame has any
|
| // coverage of the deadline interval.
|
| if (frame_to_render < 0 || selected_frame_drift > max_acceptable_drift_) {
|
| - cadence_overage = 0;
|
| + if (was_frame_selected_by_cadence) {
|
| + cadence_overage = 0;
|
| + was_frame_selected_by_cadence = false;
|
| + }
|
| frame_to_render = FindBestFrameByDrift(deadline_min, &selected_frame_drift);
|
| }
|
|
|
| @@ -189,11 +199,14 @@ scoped_refptr<VideoFrame> VideoRendererAlgorithm::Render(
|
| }
|
| }
|
|
|
| + // Increment the frame counter for all frames removed after the last
|
| + // rendered frame.
|
| + cadence_frame_counter_ += frame_to_render - last_frame_index_;
|
| frame_queue_.erase(frame_queue_.begin(),
|
| frame_queue_.begin() + frame_to_render);
|
| }
|
|
|
| - if (last_render_had_glitch_) {
|
| + if (last_render_had_glitch_ && !first_frame_) {
|
| DVLOG(2) << "Deadline: [" << deadline_min.ToInternalValue() << ", "
|
| << deadline_max.ToInternalValue()
|
| << "], Interval: " << render_interval_.InMicroseconds()
|
| @@ -215,6 +228,14 @@ scoped_refptr<VideoFrame> VideoRendererAlgorithm::Render(
|
| deadline_min >= frame_queue_.front().start_time - render_interval_ / 2) {
|
| frame_queue_.front().render_count += cadence_overage + 1;
|
| frame_queue_.front().drop_count += cadence_overage;
|
| +
|
| + // Once we reach a glitch in our cadence sequence, reset the base frame
|
| + // number used for defining the cadence sequence.
|
| + if (!was_frame_selected_by_cadence && cadence_estimator_.has_cadence()) {
|
| + cadence_frame_counter_ = 0;
|
| + UpdateCadenceForFrames();
|
| + }
|
| +
|
| first_frame_ = false;
|
| }
|
|
|
| @@ -235,8 +256,9 @@ size_t VideoRendererAlgorithm::RemoveExpiredFrames(base::TimeTicks deadline) {
|
|
|
| // Finds and removes all frames which are too old to be used; I.e., the end of
|
| // their render interval is further than |max_acceptable_drift_| from the
|
| - // given |deadline|.
|
| - size_t frames_to_expire = 0;
|
| + // given |deadline|. We also always expire anything inserted before the last
|
| + // rendered frame.
|
| + size_t frames_to_expire = last_frame_index_;
|
| const base::TimeTicks minimum_start_time =
|
| deadline - max_acceptable_drift_ - average_frame_duration_;
|
| for (; frames_to_expire < frame_queue_.size() - 1; ++frames_to_expire) {
|
| @@ -247,6 +269,7 @@ size_t VideoRendererAlgorithm::RemoveExpiredFrames(base::TimeTicks deadline) {
|
| if (!frames_to_expire)
|
| return 0;
|
|
|
| + cadence_frame_counter_ += frames_to_expire - last_frame_index_;
|
| frame_queue_.erase(frame_queue_.begin(),
|
| frame_queue_.begin() + frames_to_expire);
|
|
|
| @@ -282,6 +305,7 @@ void VideoRendererAlgorithm::Reset() {
|
| cadence_estimator_.Reset();
|
| frame_duration_calculator_.Reset();
|
| first_frame_ = true;
|
| + cadence_frame_counter_ = 0;
|
|
|
| // Default to ATSC IS/191 recommendations for maximum acceptable drift before
|
| // we have enough frames to base the maximum on frame duration.
|
| @@ -474,6 +498,7 @@ bool VideoRendererAlgorithm::UpdateFrameStatistics() {
|
| if (!cadence_changed)
|
| return true;
|
|
|
| + cadence_frame_counter_ = 0;
|
| UpdateCadenceForFrames();
|
|
|
| // Thus far there appears to be no need for special 3:2 considerations, the
|
| @@ -489,7 +514,8 @@ void VideoRendererAlgorithm::UpdateCadenceForFrames() {
|
| // cadence selection.
|
| frame_queue_[i].ideal_render_count =
|
| cadence_estimator_.has_cadence()
|
| - ? cadence_estimator_.GetCadenceForFrame(i - last_frame_index_)
|
| + ? cadence_estimator_.GetCadenceForFrame(cadence_frame_counter_ +
|
| + (i - last_frame_index_))
|
| : 0;
|
| }
|
| }
|
|
|