Index: media/base/pipeline.cc |
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc |
index 5454fa7c11636a010cc73dfba55c8e90158e0775..e82f88dd6ec19b487d14ae6020cd0dd662da91c2 100644 |
--- a/media/base/pipeline.cc |
+++ b/media/base/pipeline.cc |
@@ -21,6 +21,8 @@ |
#include "media/base/clock.h" |
#include "media/base/filter_collection.h" |
#include "media/base/media_log.h" |
+#include "media/base/text_renderer.h" |
+#include "media/base/text_track_config.h" |
#include "media/base/video_decoder.h" |
#include "media/base/video_decoder_config.h" |
#include "media/base/video_renderer.h" |
@@ -47,6 +49,7 @@ Pipeline::Pipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop, |
state_(kCreated), |
audio_ended_(false), |
video_ended_(false), |
+ text_ended_(false), |
audio_disabled_(false), |
demuxer_(NULL), |
creation_time_(default_tick_clock_.NowTicks()) { |
@@ -293,6 +296,19 @@ void Pipeline::OnDemuxerError(PipelineStatus error) { |
SetError(error); |
} |
+void Pipeline::AddTextStream(DemuxerStream* text_stream, |
+ const TextTrackConfig& config) { |
+ message_loop_->PostTask(FROM_HERE, base::Bind( |
+ &Pipeline::AddTextStreamTask, base::Unretained(this), |
+ text_stream, config)); |
+} |
+ |
+void Pipeline::RemoveTextStream(DemuxerStream* text_stream) { |
+ message_loop_->PostTask(FROM_HERE, base::Bind( |
+ &Pipeline::RemoveTextStreamTask, base::Unretained(this), |
+ text_stream)); |
+} |
+ |
void Pipeline::SetError(PipelineStatus error) { |
DCHECK(IsRunning()); |
DCHECK_NE(PIPELINE_OK, error); |
@@ -537,6 +553,10 @@ void Pipeline::DoSeek( |
bound_fns.Push(base::Bind( |
&VideoRenderer::Pause, base::Unretained(video_renderer_.get()))); |
} |
+ if (text_renderer_) { |
+ bound_fns.Push(base::Bind( |
+ &TextRenderer::Pause, base::Unretained(text_renderer_.get()))); |
+ } |
// Flush. |
if (audio_renderer_) { |
@@ -547,6 +567,10 @@ void Pipeline::DoSeek( |
bound_fns.Push(base::Bind( |
&VideoRenderer::Flush, base::Unretained(video_renderer_.get()))); |
} |
+ if (text_renderer_) { |
+ bound_fns.Push(base::Bind( |
+ &TextRenderer::Flush, base::Unretained(text_renderer_.get()))); |
+ } |
// Seek demuxer. |
bound_fns.Push(base::Bind( |
@@ -586,6 +610,11 @@ void Pipeline::DoPlay(const PipelineStatusCB& done_cb) { |
&VideoRenderer::Play, base::Unretained(video_renderer_.get()))); |
} |
+ if (text_renderer_) { |
+ bound_fns.Push(base::Bind( |
+ &TextRenderer::Play, base::Unretained(text_renderer_.get()))); |
+ } |
+ |
pending_callbacks_ = SerialRunner::Run(bound_fns, done_cb); |
} |
@@ -609,6 +638,11 @@ void Pipeline::DoStop(const PipelineStatusCB& done_cb) { |
&VideoRenderer::Stop, base::Unretained(video_renderer_.get()))); |
} |
+ if (text_renderer_) { |
+ bound_fns.Push(base::Bind( |
+ &TextRenderer::Stop, base::Unretained(text_renderer_.get()))); |
+ } |
+ |
pending_callbacks_ = SerialRunner::Run(bound_fns, done_cb); |
} |
@@ -625,6 +659,7 @@ void Pipeline::OnStopCompleted(PipelineStatus status) { |
filter_collection_.reset(); |
audio_renderer_.reset(); |
video_renderer_.reset(); |
+ text_renderer_.reset(); |
demuxer_ = NULL; |
// If we stop during initialization/seeking we want to run |seek_cb_| |
@@ -685,6 +720,13 @@ void Pipeline::OnVideoRendererEnded() { |
media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::VIDEO_ENDED)); |
} |
+void Pipeline::OnTextRendererEnded() { |
+ // Force post to process ended messages after current execution frame. |
+ message_loop_->PostTask(FROM_HERE, base::Bind( |
+ &Pipeline::DoTextRendererEnded, base::Unretained(this))); |
+ media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::TEXT_ENDED)); |
+} |
+ |
// Called from any thread. |
void Pipeline::OnUpdateStatistics(const PipelineStatistics& stats) { |
base::AutoLock auto_lock(lock_); |
@@ -711,6 +753,13 @@ void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection, |
buffering_state_cb_ = buffering_state_cb; |
duration_change_cb_ = duration_change_cb; |
+ text_renderer_ = filter_collection_->GetTextRenderer(); |
+ |
+ if (text_renderer_) { |
+ text_renderer_->Initialize( |
+ base::Bind(&Pipeline::OnTextRendererEnded, base::Unretained(this))); |
+ } |
+ |
StateTransitionTask(PIPELINE_OK); |
} |
@@ -800,6 +849,7 @@ void Pipeline::SeekTask(TimeDelta time, const PipelineStatusCB& seek_cb) { |
seek_cb_ = seek_cb; |
audio_ended_ = false; |
video_ended_ = false; |
+ text_ended_ = false; |
// Kick off seeking! |
{ |
@@ -843,6 +893,18 @@ void Pipeline::DoVideoRendererEnded() { |
RunEndedCallbackIfNeeded(); |
} |
+void Pipeline::DoTextRendererEnded() { |
+ DCHECK(message_loop_->BelongsToCurrentThread()); |
+ |
+ if (state_ != kStarted) |
+ return; |
+ |
+ DCHECK(!text_ended_); |
+ text_ended_ = true; |
+ |
+ RunEndedCallbackIfNeeded(); |
+} |
+ |
void Pipeline::RunEndedCallbackIfNeeded() { |
DCHECK(message_loop_->BelongsToCurrentThread()); |
@@ -852,6 +914,9 @@ void Pipeline::RunEndedCallbackIfNeeded() { |
if (video_renderer_ && !video_ended_) |
return; |
+ if (text_renderer_ && text_renderer_->HasTracks() && !text_ended_) |
+ return; |
+ |
{ |
base::AutoLock auto_lock(lock_); |
clock_->EndOfStream(); |
@@ -876,11 +941,24 @@ void Pipeline::AudioDisabledTask() { |
StartClockIfWaitingForTimeUpdate_Locked(); |
} |
+void Pipeline::AddTextStreamTask(DemuxerStream* text_stream, |
+ const TextTrackConfig& config) { |
+ DCHECK(message_loop_->BelongsToCurrentThread()); |
+ // TODO(matthewjheaney): fix up text_ended_ when text stream |
+ // is added (http://crbug.com/321446). |
+ text_renderer_->AddTextStream(text_stream, config); |
+} |
+ |
+void Pipeline::RemoveTextStreamTask(DemuxerStream* text_stream) { |
+ DCHECK(message_loop_->BelongsToCurrentThread()); |
+ text_renderer_->RemoveTextStream(text_stream); |
+} |
+ |
void Pipeline::InitializeDemuxer(const PipelineStatusCB& done_cb) { |
DCHECK(message_loop_->BelongsToCurrentThread()); |
demuxer_ = filter_collection_->GetDemuxer(); |
- demuxer_->Initialize(this, done_cb); |
+ demuxer_->Initialize(this, done_cb, text_renderer_); |
} |
void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { |