Index: media/filters/video_renderer_base.cc |
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc |
index 325c007d44012bd0c32cfae16ceb75982602aa8b..481c7840173bf210ab098d960af7c395a253b524 100644 |
--- a/media/filters/video_renderer_base.cc |
+++ b/media/filters/video_renderer_base.cc |
@@ -104,6 +104,7 @@ void VideoRendererBase::Preroll(base::TimeDelta time, |
state_ = kPrerolling; |
preroll_cb_ = cb; |
preroll_timestamp_ = time; |
+ prerolling_delayed_frame_ = NULL; |
AttemptRead_Locked(); |
} |
@@ -421,31 +422,19 @@ void VideoRendererBase::FrameReady(VideoDecoder::DecoderStatus status, |
// Discard frames until we reach our desired preroll timestamp. |
if (state_ == kPrerolling && !frame->IsEndOfStream() && |
- (frame->GetTimestamp() + frame->GetDuration()) <= preroll_timestamp_) { |
+ frame->GetTimestamp() <= preroll_timestamp_) { |
+ prerolling_delayed_frame_ = frame; |
AttemptRead_Locked(); |
return; |
} |
- // Adjust the incoming frame if its rendering stop time is past the duration |
- // of the video itself. This is typically the last frame of the video and |
- // occurs if the container specifies a duration that isn't a multiple of the |
- // frame rate. Another way for this to happen is for the container to state a |
- // smaller duration than the largest packet timestamp. |
- if (!frame->IsEndOfStream()) { |
- base::TimeDelta duration = get_duration_cb_.Run(); |
- if (frame->GetTimestamp() > duration) |
- frame->SetTimestamp(duration); |
- if ((frame->GetTimestamp() + frame->GetDuration()) > duration) |
- frame->SetDuration(duration - frame->GetTimestamp()); |
+ if (prerolling_delayed_frame_) { |
+ DCHECK_EQ(state_, kPrerolling); |
+ AddReadyFrame(prerolling_delayed_frame_); |
+ prerolling_delayed_frame_ = NULL; |
} |
- // This one's a keeper! Place it in the ready queue. |
- ready_frames_.push_back(frame); |
- DCHECK_LE(NumFrames_Locked(), limits::kMaxVideoFrames); |
- if (!frame->IsEndOfStream()) |
- time_cb_.Run(frame->GetTimestamp() + frame->GetDuration()); |
- frame_available_.Signal(); |
- |
+ AddReadyFrame(frame); |
PipelineStatistics statistics; |
statistics.video_frames_decoded = 1; |
statistics_cb_.Run(statistics); |
@@ -482,6 +471,23 @@ void VideoRendererBase::FrameReady(VideoDecoder::DecoderStatus status, |
} |
} |
+void VideoRendererBase::AddReadyFrame(const scoped_refptr<VideoFrame>& frame) { |
+ // Adjust the incoming frame if its rendering stop time is past the duration |
+ // of the video itself. This is typically the last frame of the video and |
+ // occurs if the container specifies a duration that isn't a multiple of the |
+ // frame rate. Another way for this to happen is for the container to state a |
+ // smaller duration than the largest packet timestamp. |
+ base::TimeDelta duration = get_duration_cb_.Run(); |
+ if (frame->GetTimestamp() > duration || frame->IsEndOfStream()) { |
+ frame->SetTimestamp(duration); |
+ } |
+ |
+ ready_frames_.push_back(frame); |
+ DCHECK_LE(NumFrames_Locked(), limits::kMaxVideoFrames); |
+ time_cb_.Run(frame->GetTimestamp()); |
+ frame_available_.Signal(); |
+} |
+ |
void VideoRendererBase::AttemptRead_Locked() { |
lock_.AssertAcquired(); |
DCHECK_NE(kEnded, state_); |
@@ -511,7 +517,7 @@ void VideoRendererBase::AttemptFlush_Locked() { |
lock_.AssertAcquired(); |
DCHECK_EQ(kFlushing, state_); |
- // Get rid of any ready frames. |
+ prerolling_delayed_frame_ = NULL; |
ready_frames_.clear(); |
if (!pending_paint_ && !pending_read_) { |
@@ -526,13 +532,7 @@ base::TimeDelta VideoRendererBase::CalculateSleepDuration( |
float playback_rate) { |
// Determine the current and next presentation timestamps. |
base::TimeDelta now = get_time_cb_.Run(); |
- base::TimeDelta this_pts = current_frame_->GetTimestamp(); |
- base::TimeDelta next_pts; |
- if (!next_frame->IsEndOfStream()) { |
- next_pts = next_frame->GetTimestamp(); |
- } else { |
- next_pts = this_pts + current_frame_->GetDuration(); |
- } |
+ base::TimeDelta next_pts = next_frame->GetTimestamp(); |
// Scale our sleep based on the playback rate. |
base::TimeDelta sleep = next_pts - now; |