Chromium Code Reviews| Index: media/filters/video_renderer_base.cc |
| diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc |
| index 92bedba8afbf052965ddf5515aef651c12b65396..475addcad452b671c2a47bd0f8b079dcdaf403dd 100644 |
| --- a/media/filters/video_renderer_base.cc |
| +++ b/media/filters/video_renderer_base.cc |
| @@ -129,28 +129,37 @@ void VideoRendererBase::SetPlaybackRate(float playback_rate) { |
| playback_rate_ = playback_rate; |
| } |
| -void VideoRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) { |
| - base::AutoLock auto_lock(lock_); |
| - // There is a race condition between filters to receive SeekTask(). |
| - // It turns out we could receive buffer from decoder before seek() |
| - // is called on us. so we do the following: |
| - // kFlushed => ( Receive first buffer or Seek() ) => kSeeking and |
| - // kSeeking => ( Receive enough buffers) => kPrerolled. ) |
| - DCHECK(kPrerolled == state_ || kFlushed == state_ || kSeeking == state_); |
| - |
| - if (state_ == kPrerolled) { |
| - // Already get enough buffers from decoder. |
| - callback->Run(); |
| - delete callback; |
| - } else { |
| - // Otherwise we are either kFlushed or kSeeking, but without enough buffers; |
| - // we should save the callback function and call it later. |
| - state_ = kSeeking; |
| - seek_callback_.reset(callback); |
| +void VideoRendererBase::Seek(base::TimeDelta time, const FilterStatusCB& cb) { |
| + bool run_callback = false; |
| + |
| + { |
| + base::AutoLock auto_lock(lock_); |
| + // There is a race condition between filters to receive SeekTask(). |
| + // It turns out we could receive buffer from decoder before seek() |
| + // is called on us. so we do the following: |
| + // kFlushed => ( Receive first buffer or Seek() ) => kSeeking and |
| + // kSeeking => ( Receive enough buffers) => kPrerolled. ) |
| + DCHECK(kPrerolled == state_ || kFlushed == state_ || kSeeking == state_); |
| + DCHECK(!cb.is_null()); |
| + DCHECK(seek_cb_.is_null()); |
| + |
| + if (state_ == kPrerolled) { |
| + // Already get enough buffers from decoder. |
| + run_callback = true; |
| + |
| + } else { |
| + // Otherwise we are either kFlushed or kSeeking, but without enough |
| + // buffers we should save the callback function and call it later. |
| + state_ = kSeeking; |
| + seek_cb_ = cb; |
| + } |
| + |
| + seek_timestamp_ = time; |
| + ScheduleRead_Locked(); |
| } |
| - seek_timestamp_ = time; |
| - ScheduleRead_Locked(); |
| + if (run_callback) |
| + cb.Run(PIPELINE_OK); |
| } |
| void VideoRendererBase::Initialize(VideoDecoder* decoder, |
| @@ -462,9 +471,8 @@ void VideoRendererBase::ConsumeVideoFrame(scoped_refptr<VideoFrame> frame) { |
| // If we reach prerolled state before Seek() is called by pipeline, |
| // |seek_callback_| is not set, we will return immediately during |
| // when Seek() is eventually called. |
| - if ((seek_callback_.get())) { |
| - seek_callback_->Run(); |
| - seek_callback_.reset(); |
| + if (!seek_cb_.is_null()) { |
| + CopyAndResetCB(seek_cb_).Run(PIPELINE_OK); |
| } |
| } |
| } else if (state_ == kFlushing && pending_reads_ == 0 && !pending_paint_) { |
| @@ -578,6 +586,8 @@ void VideoRendererBase::EnterErrorState_Locked(PipelineStatus status) { |
| lock_.AssertAcquired(); |
| scoped_ptr<FilterCallback> callback; |
|
Ami GONE FROM CHROMIUM
2011/05/12 20:42:16
Typically the reason we have this sort of stack va
acolwell GONE FROM CHROMIUM
2011/05/12 22:30:40
Done.
|
| + FilterStatusCB status_cb; |
| + |
| switch (state_) { |
| case kUninitialized: |
| case kPrerolled: |
| @@ -592,10 +602,10 @@ void VideoRendererBase::EnterErrorState_Locked(PipelineStatus status) { |
| callback.swap(flush_callback_); |
| break; |
| - case kSeeking: |
| - CHECK(seek_callback_.get()); |
| - callback.swap(seek_callback_); |
| - break; |
| + case kSeeking: { |
| + CHECK(!seek_cb_.is_null()); |
| + status_cb = CopyAndResetCB(seek_cb_); |
|
Ami GONE FROM CHROMIUM
2011/05/12 20:42:16
std::swap() fits in better here, esp. if you take
acolwell GONE FROM CHROMIUM
2011/05/12 22:30:40
Done.
|
| + } break; |
|
Ami GONE FROM CHROMIUM
2011/05/12 20:42:16
braces should be unnecessary.
acolwell GONE FROM CHROMIUM
2011/05/12 22:30:40
Done.
|
| case kStopped: |
| NOTREACHED() << "Should not error if stopped."; |
| @@ -605,6 +615,12 @@ void VideoRendererBase::EnterErrorState_Locked(PipelineStatus status) { |
| return; |
| } |
| state_ = kError; |
| + |
| + if (!status_cb.is_null()) { |
| + status_cb.Run(status); |
| + return; |
| + } |
| + |
| host()->SetError(status); |
|
Ami GONE FROM CHROMIUM
2011/05/12 20:42:16
Is it really right to not set the host's error sta
acolwell GONE FROM CHROMIUM
2011/05/12 22:30:40
Yes. Calling host()->SetError() is the old style o
Ami GONE FROM CHROMIUM
2011/05/12 22:49:25
I understand this, but I'm questioning whether the
acolwell GONE FROM CHROMIUM
2011/05/13 00:49:10
Sorry I wasn't clear. Yes this is safe because in
|
| if (callback.get()) |