Index: content/renderer/media/webmediaplayer_impl.cc |
diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc |
index a99c3aef5920e14e1db9ac4e0afb103eb5867f8b..31015e4f4019f02edb2e8f2d83f1f55ff98bbe1a 100644 |
--- a/content/renderer/media/webmediaplayer_impl.cc |
+++ b/content/renderer/media/webmediaplayer_impl.cc |
@@ -15,6 +15,7 @@ |
#include "base/debug/crash_logging.h" |
#include "base/message_loop/message_loop_proxy.h" |
#include "base/metrics/histogram.h" |
+#include "base/stl_util.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/synchronization/waitable_event.h" |
#include "cc/layers/video_layer.h" |
@@ -37,6 +38,8 @@ |
#include "media/base/media_log.h" |
#include "media/base/media_switches.h" |
#include "media/base/pipeline.h" |
+#include "media/base/text_cue.h" |
+#include "media/base/text_renderer.h" |
#include "media/base/video_frame.h" |
#include "media/filters/audio_renderer_impl.h" |
#include "media/filters/chunk_demuxer.h" |
@@ -46,6 +49,7 @@ |
#include "media/filters/gpu_video_accelerator_factories.h" |
#include "media/filters/gpu_video_decoder.h" |
#include "media/filters/opus_audio_decoder.h" |
+#include "media/filters/text_decoder_impl.h" |
#include "media/filters/video_renderer_base.h" |
#include "media/filters/vpx_video_decoder.h" |
#include "third_party/WebKit/public/platform/WebMediaSource.h" |
@@ -960,6 +964,15 @@ WebMediaPlayerImpl::OnTextTrack(media::TextKind kind, |
text_track)); |
} |
+void WebMediaPlayerImpl::AddTextStream(media::DemuxerStream* text_stream, |
+ media::TextKind kind, |
+ const std::string& label, |
+ const std::string& language) { |
+ DCHECK(main_loop_->BelongsToCurrentThread()); |
+ scoped_ptr<media::TextTrack> text_track = OnTextTrack(kind, label, language); |
+ text_track_map_[text_stream] = text_track.release(); |
acolwell GONE FROM CHROMIUM
2013/09/25 23:23:10
I don't think you need the map here. You can hide
Matthew Heaney (Chromium)
2013/09/29 03:31:23
Done.
|
+} |
+ |
void WebMediaPlayerImpl::OnKeyError(const std::string& session_id, |
media::MediaKeys::KeyError error_code, |
int system_code) { |
@@ -1028,6 +1041,9 @@ void WebMediaPlayerImpl::StartPipeline() { |
UMA_HISTOGRAM_BOOLEAN("Media.MSE.Playback", |
(load_type_ == LoadTypeMediaSource)); |
+ const bool enable_inband_text_tracks = |
+ cmd_line->HasSwitch(switches::kEnableInbandTextTracks); |
+ |
// Figure out which demuxer to use. |
if (load_type_ != LoadTypeMediaSource) { |
DCHECK(!chunk_demuxer_); |
@@ -1036,14 +1052,17 @@ void WebMediaPlayerImpl::StartPipeline() { |
demuxer_.reset(new media::FFmpegDemuxer( |
media_loop_, data_source_.get(), |
BIND_TO_RENDER_LOOP_1(&WebMediaPlayerImpl::OnNeedKey, ""), |
+ enable_inband_text_tracks, |
media_log_)); |
} else { |
DCHECK(!chunk_demuxer_); |
DCHECK(!data_source_); |
+ // TODO(matthewjheaney): Once we have resolved the threading issues, |
+ // change the chunk demuxer to user the same mechanism as for ffmpeg. |
media::AddTextTrackCB add_text_track_cb; |
- if (cmd_line->HasSwitch(switches::kEnableInbandTextTracks)) { |
+ if (enable_inband_text_tracks) { |
add_text_track_cb = |
base::Bind(&WebMediaPlayerImpl::OnTextTrack, base::Unretained(this)); |
} |
@@ -1121,6 +1140,20 @@ void WebMediaPlayerImpl::StartPipeline() { |
true)); |
filter_collection->SetVideoRenderer(video_renderer.Pass()); |
+ if (load_type_ != LoadTypeMediaSource && enable_inband_text_tracks) { |
+ scoped_ptr<media::TextDecoder> text_decoder( |
+ new media::TextDecoderImpl(media_loop_)); |
+ |
+ scoped_ptr<media::TextRenderer> text_renderer( |
+ new media::TextRenderer( |
+ media_loop_, |
+ text_decoder.Pass(), |
+ BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::AddTextStream), |
+ BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::CueReady))); |
+ |
+ filter_collection->SetTextRenderer(text_renderer.Pass()); |
+ } |
+ |
// ... and we're ready to go! |
starting_ = true; |
pipeline_->Start( |
@@ -1177,6 +1210,8 @@ void WebMediaPlayerImpl::Destroy() { |
&base::WaitableEvent::Signal, base::Unretained(&waiter))); |
waiter.Wait(); |
+ STLDeleteValues(&text_track_map_); |
+ |
// Let V8 know we are not using extra resources anymore. |
if (incremented_externally_allocated_memory_) { |
v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); |
@@ -1243,4 +1278,26 @@ void WebMediaPlayerImpl::FrameReady( |
&WebMediaPlayerImpl::Repaint, AsWeakPtr())); |
} |
+void WebMediaPlayerImpl::CueReady( |
acolwell GONE FROM CHROMIUM
2013/09/25 23:23:10
You shouldn't need this. You can hide the thread h
Matthew Heaney (Chromium)
2013/09/29 03:31:23
Done.
|
+ media::DemuxerStream* text_stream, |
+ const scoped_refptr<media::TextCue>& text_cue) { |
+ DCHECK(main_loop_->BelongsToCurrentThread()); |
+ DCHECK_NE(text_stream, static_cast<media::DemuxerStream*>(NULL)); |
+ DCHECK(text_cue != NULL && !text_cue->text().empty()); |
+ |
+ TextTrackMap::iterator it = text_track_map_.find(text_stream); |
+ DCHECK(it != text_track_map_.end()); |
+ |
+ media::TextTrack* text_track = it->second; |
+ DCHECK_NE(text_track, static_cast<media::TextTrack*>(NULL)); |
+ |
+ base::TimeDelta start = text_cue->timestamp(); |
+ base::TimeDelta end = start + text_cue->duration(); |
+ |
+ text_track->addWebVTTCue(start, end, |
+ text_cue->id(), |
+ text_cue->text(), |
+ text_cue->settings()); |
+} |
+ |
} // namespace content |