| Index: media/filters/video_renderer_base.cc
|
| diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
|
| index da5c3cdf8a8fd05e5db13500795559ed84b0d572..29e004c19c39db79b198ff09b9c90108c629c735 100644
|
| --- a/media/filters/video_renderer_base.cc
|
| +++ b/media/filters/video_renderer_base.cc
|
| @@ -112,7 +112,8 @@ void VideoRendererBase::Preroll(base::TimeDelta time,
|
| AttemptRead_Locked();
|
| }
|
|
|
| -void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder,
|
| +void VideoRendererBase::Initialize(const scoped_refptr<DemuxerStream>& stream,
|
| + const VideoDecoderList& decoders,
|
| const PipelineStatusCB& init_cb,
|
| const StatisticsCB& statistics_cb,
|
| const TimeCB& max_time_cb,
|
| @@ -122,7 +123,9 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder,
|
| const TimeDeltaCB& get_time_cb,
|
| const TimeDeltaCB& get_duration_cb) {
|
| base::AutoLock auto_lock(lock_);
|
| - DCHECK(decoder);
|
| + DCHECK(stream);
|
| + DCHECK(!decoders.empty());
|
| + DCHECK_EQ(stream->type(), DemuxerStream::VIDEO);
|
| DCHECK(!init_cb.is_null());
|
| DCHECK(!statistics_cb.is_null());
|
| DCHECK(!max_time_cb.is_null());
|
| @@ -131,8 +134,8 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder,
|
| DCHECK(!get_time_cb.is_null());
|
| DCHECK(!get_duration_cb.is_null());
|
| DCHECK_EQ(kUninitialized, state_);
|
| - decoder_ = decoder;
|
|
|
| + init_cb_ = init_cb;
|
| statistics_cb_ = statistics_cb;
|
| max_time_cb_ = max_time_cb;
|
| size_changed_cb_ = size_changed_cb;
|
| @@ -141,20 +144,65 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder,
|
| get_time_cb_ = get_time_cb;
|
| get_duration_cb_ = get_duration_cb;
|
|
|
| + scoped_ptr<VideoDecoderList> decoder_list(new VideoDecoderList(decoders));
|
| + InitializeNextDecoder(stream, decoder_list.Pass());
|
| +}
|
| +
|
| +void VideoRendererBase::InitializeNextDecoder(
|
| + const scoped_refptr<DemuxerStream>& demuxer_stream,
|
| + scoped_ptr<VideoDecoderList> decoders) {
|
| + lock_.AssertAcquired();
|
| + DCHECK(!decoders->empty());
|
| +
|
| + scoped_refptr<VideoDecoder> decoder = decoders->front();
|
| + decoders->pop_front();
|
| +
|
| + DCHECK(decoder);
|
| + decoder_ = decoder;
|
| +
|
| + base::AutoUnlock auto_unlock(lock_);
|
| + decoder->Initialize(
|
| + demuxer_stream,
|
| + base::Bind(&VideoRendererBase::OnDecoderInitDone, this,
|
| + demuxer_stream,
|
| + base::Passed(&decoders)),
|
| + statistics_cb_);
|
| +}
|
| +
|
| +void VideoRendererBase::OnDecoderInitDone(
|
| + const scoped_refptr<DemuxerStream>& demuxer_stream,
|
| + scoped_ptr<VideoDecoderList> decoders,
|
| + PipelineStatus status) {
|
| + base::AutoLock auto_lock(lock_);
|
| +
|
| + if (state_ == kStopped)
|
| + return;
|
| +
|
| + if (!decoders->empty() && status == DECODER_ERROR_NOT_SUPPORTED) {
|
| + InitializeNextDecoder(demuxer_stream, decoders.Pass());
|
| + return;
|
| + }
|
| +
|
| + if (status != PIPELINE_OK) {
|
| + state_ = kError;
|
| + base::ResetAndReturn(&init_cb_).Run(status);
|
| + return;
|
| + }
|
| +
|
| // We're all good! Consider ourselves flushed. (ThreadMain() should never
|
| // see us in the kUninitialized state).
|
| // Since we had an initial Preroll(), we consider ourself flushed, because we
|
| // have not populated any buffers yet.
|
| state_ = kFlushed;
|
|
|
| - set_opaque_cb_.Run(!decoder->HasAlpha());
|
| + set_opaque_cb_.Run(!decoder_->HasAlpha());
|
| set_opaque_cb_.Reset();
|
|
|
| // Create our video thread.
|
| if (!base::PlatformThread::Create(0, this, &thread_)) {
|
| NOTREACHED() << "Video thread creation failed";
|
| state_ = kError;
|
| - init_cb.Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| + base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| return;
|
| }
|
|
|
| @@ -163,7 +211,13 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder,
|
| // TODO(scherkus): find out if this is necessary, but it seems to help.
|
| ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL);
|
| #endif // defined(OS_WIN)
|
| - init_cb.Run(PIPELINE_OK);
|
| + base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
|
| +}
|
| +
|
| +void VideoRendererBase::PrepareForShutdownHack() {
|
| + base::AutoLock auto_lock(lock_);
|
| + if (decoder_)
|
| + decoder_->PrepareForShutdownHack();
|
| }
|
|
|
| // PlatformThread::Delegate implementation.
|
|
|