| 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;
|
|
|