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