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 8f6bf8a3d0254dc82578f0fb4a5f7b20f1a7f029..8c564ad0b989871a43c31331a2b99e2abd8447dc 100644 |
| --- a/media/filters/video_renderer_base.cc |
| +++ b/media/filters/video_renderer_base.cc |
| @@ -7,6 +7,7 @@ |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/callback_helpers.h" |
| +#include "base/message_loop.h" |
| #include "base/threading/platform_thread.h" |
| #include "media/base/buffers.h" |
| #include "media/base/limits.h" |
| @@ -19,10 +20,13 @@ base::TimeDelta VideoRendererBase::kMaxLastFrameDuration() { |
| return base::TimeDelta::FromMilliseconds(250); |
| } |
| -VideoRendererBase::VideoRendererBase(const base::Closure& paint_cb, |
| - const SetOpaqueCB& set_opaque_cb, |
| - bool drop_frames) |
| - : frame_available_(&lock_), |
| +VideoRendererBase::VideoRendererBase( |
| + const scoped_refptr<base::MessageLoopProxy>& message_loop, |
| + const base::Closure& paint_cb, |
| + const SetOpaqueCB& set_opaque_cb, |
| + bool drop_frames) |
| + : message_loop_(message_loop), |
| + frame_available_(&lock_), |
| state_(kUninitialized), |
| thread_(base::kNullThreadHandle), |
| pending_read_(false), |
| @@ -36,6 +40,7 @@ VideoRendererBase::VideoRendererBase(const base::Closure& paint_cb, |
| } |
| void VideoRendererBase::Play(const base::Closure& callback) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| base::AutoLock auto_lock(lock_); |
| DCHECK_EQ(kPrerolled, state_); |
| state_ = kPlaying; |
| @@ -43,6 +48,7 @@ void VideoRendererBase::Play(const base::Closure& callback) { |
| } |
| void VideoRendererBase::Pause(const base::Closure& callback) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| base::AutoLock auto_lock(lock_); |
| DCHECK(state_ != kUninitialized || state_ == kError); |
| state_ = kPaused; |
| @@ -50,19 +56,17 @@ void VideoRendererBase::Pause(const base::Closure& callback) { |
| } |
| void VideoRendererBase::Flush(const base::Closure& callback) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| base::AutoLock auto_lock(lock_); |
| DCHECK_EQ(state_, kPaused); |
| flush_cb_ = callback; |
| state_ = kFlushingDecoder; |
| - // We must unlock here because the callback might run within the Flush() |
| - // call. |
| - // TODO: Remove this line when fixing http://crbug.com/125020 |
| - base::AutoUnlock auto_unlock(lock_); |
| - decoder_->Reset(base::Bind(&VideoRendererBase::OnDecoderFlushDone, this)); |
| + decoder_->Reset(base::Bind(&VideoRendererBase::OnDecoderResetDone, this)); |
| } |
| void VideoRendererBase::Stop(const base::Closure& callback) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| if (state_ == kStopped) { |
| callback.Run(); |
| return; |
| @@ -94,12 +98,14 @@ void VideoRendererBase::Stop(const base::Closure& callback) { |
| } |
| void VideoRendererBase::SetPlaybackRate(float playback_rate) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| base::AutoLock auto_lock(lock_); |
| playback_rate_ = playback_rate; |
| } |
| void VideoRendererBase::Preroll(base::TimeDelta time, |
| const PipelineStatusCB& cb) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| base::AutoLock auto_lock(lock_); |
| DCHECK_EQ(state_, kFlushed) << "Must flush prior to prerolling."; |
| DCHECK(!cb.is_null()); |
| @@ -122,6 +128,7 @@ void VideoRendererBase::Initialize(const scoped_refptr<DemuxerStream>& stream, |
| const PipelineStatusCB& error_cb, |
| const TimeDeltaCB& get_time_cb, |
| const TimeDeltaCB& get_duration_cb) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| base::AutoLock auto_lock(lock_); |
| DCHECK(stream); |
| DCHECK(!decoders.empty()); |
| @@ -151,6 +158,7 @@ void VideoRendererBase::Initialize(const scoped_refptr<DemuxerStream>& stream, |
| void VideoRendererBase::InitializeNextDecoder( |
| const scoped_refptr<DemuxerStream>& demuxer_stream, |
| scoped_ptr<VideoDecoderList> decoders) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| lock_.AssertAcquired(); |
| DCHECK(!decoders->empty()); |
| @@ -173,6 +181,7 @@ void VideoRendererBase::OnDecoderInitDone( |
| const scoped_refptr<DemuxerStream>& demuxer_stream, |
| scoped_ptr<VideoDecoderList> decoders, |
| PipelineStatus status) { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| base::AutoLock auto_lock(lock_); |
| if (state_ == kStopped) |
| @@ -330,7 +339,8 @@ void VideoRendererBase::ThreadMain() { |
| // Frame dropped: read again. |
| ++frames_dropped; |
| ready_frames_.pop_front(); |
| - AttemptRead_Locked(); |
| + message_loop_->PostTask(FROM_HERE, base::Bind( |
| + &VideoRendererBase::AttemptRead, this)); |
| } |
| // Continue waiting for the current paint to finish. |
| frame_available_.TimedWait(kIdleTimeDelta); |
| @@ -345,7 +355,8 @@ void VideoRendererBase::ThreadMain() { |
| DCHECK(!pending_paint_); |
| DCHECK(!ready_frames_.empty()); |
| SetCurrentFrameToNextReadyFrame(); |
| - AttemptRead_Locked(); |
| + message_loop_->PostTask(FROM_HERE, base::Bind( |
| + &VideoRendererBase::AttemptRead, this)); |
| base::AutoUnlock auto_unlock(lock_); |
| paint_cb_.Run(); |
| @@ -558,15 +569,21 @@ void VideoRendererBase::AddReadyFrame(const scoped_refptr<VideoFrame>& frame) { |
| frame_available_.Signal(); |
| } |
| +void VideoRendererBase::AttemptRead() { |
| + base::AutoLock auto_lock(lock_); |
| + AttemptRead_Locked(); |
| +} |
| + |
| void VideoRendererBase::AttemptRead_Locked() { |
| + DCHECK(message_loop_->BelongsToCurrentThread()); |
| lock_.AssertAcquired(); |
| - DCHECK_NE(kEnded, state_); |
| if (pending_read_ || |
| NumFrames_Locked() == limits::kMaxVideoFrames || |
| (!ready_frames_.empty() && ready_frames_.back()->IsEndOfStream()) || |
| state_ == kFlushingDecoder || |
| - state_ == kFlushing) { |
| + state_ == kFlushing || |
| + state_ == kEnded) { |
|
scherkus (not reviewing)
2012/12/06 21:22:14
due to task-posting it's possible to run AttemptRe
|
| return; |
| } |
| @@ -574,7 +591,7 @@ void VideoRendererBase::AttemptRead_Locked() { |
| decoder_->Read(base::Bind(&VideoRendererBase::FrameReady, this)); |
| } |
| -void VideoRendererBase::OnDecoderFlushDone() { |
| +void VideoRendererBase::OnDecoderResetDone() { |
| base::AutoLock auto_lock(lock_); |
| DCHECK_EQ(kFlushingDecoder, state_); |
| DCHECK(!pending_read_); |