Index: media/base/pipeline.cc |
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc |
index 9790c61cb5ca792c12d44a3f7b1b45392892565d..cc2587e1a5700dddc6f425e002fc5e76a951cd00 100644 |
--- a/media/base/pipeline.cc |
+++ b/media/base/pipeline.cc |
@@ -21,6 +21,7 @@ |
#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/video_decoder.h" |
#include "media/base/video_decoder_config.h" |
#include "media/base/video_renderer.h" |
@@ -47,6 +48,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 +295,14 @@ void Pipeline::OnDemuxerError(PipelineStatus error) { |
SetError(error); |
} |
+void Pipeline::AddTextStream(DemuxerStream* text_stream, |
+ TextKind kind, |
+ const std::string& label, |
+ const std::string& language) { |
+ DCHECK(message_loop_->BelongsToCurrentThread()); |
+ text_renderer_->AddTextStream(text_stream, kind, label, language); |
+} |
+ |
void Pipeline::SetError(PipelineStatus error) { |
DCHECK(IsRunning()); |
DCHECK_NE(PIPELINE_OK, error); |
@@ -537,6 +547,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 +561,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 +604,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 +632,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 +653,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 +714,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 +747,12 @@ 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_) |
acolwell GONE FROM CHROMIUM
2013/10/08 15:45:24
nit: Add {} since this is a multi-line statement.
Matthew Heaney (Chromium)
2013/10/13 05:30:17
Done.
|
+ text_renderer_->Initialize( |
+ base::Bind(&Pipeline::OnTextRendererEnded, base::Unretained(this))); |
+ |
StateTransitionTask(PIPELINE_OK); |
} |
@@ -802,6 +844,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! |
{ |
@@ -845,6 +888,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()); |
@@ -854,6 +909,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(); |