Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(660)

Unified Diff: media/filters/ffmpeg_text_decoder.cc

Issue 23702007: Render inband text tracks in the media pipeline (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/ffmpeg_text_decoder.cc
diff --git a/media/filters/ffmpeg_text_decoder.cc b/media/filters/ffmpeg_text_decoder.cc
new file mode 100644
index 0000000000000000000000000000000000000000..370abdf322f8fb30a12594101f8afe4af54cffa6
--- /dev/null
+++ b/media/filters/ffmpeg_text_decoder.cc
@@ -0,0 +1,126 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/filters/ffmpeg_text_decoder.h"
+
+#include "base/callback_helpers.h"
+#include "media/base/bind_to_loop.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/demuxer.h"
+#include "media/base/text_buffer.h"
+#include "media/filters/ffmpeg_glue.h"
+
+namespace media {
+
+FFmpegTextDecoder::FFmpegTextDecoder(
+ const scoped_refptr<base::MessageLoopProxy>& message_loop)
+ : message_loop_(message_loop),
+ weak_factory_(this) {
+}
+
+FFmpegTextDecoder::~FFmpegTextDecoder() {
+}
+
+void FFmpegTextDecoder::Initialize(Demuxer* demuxer) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+ DCHECK_NE(demuxer, static_cast<Demuxer*>(NULL));
+
+ FFmpegGlue::InitializeFFmpeg();
+
+ if (!demuxer_streams_.empty()) {
+ // TODO(scherkus): initialization currently happens more than once in
+ // PipelineIntegrationTest.BasicPlayback.
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 Do we really need this? I don't think we should be
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
+ LOG(ERROR) << "Initialize has already been called.";
+ CHECK(false);
+ }
+
+ weak_this_ = weak_factory_.GetWeakPtr();
+
+ int stream_count = demuxer->GetStreamCount();
+ demuxer_streams_.reserve(stream_count);
+
+ for (int idx = 0; idx < stream_count; ++idx) {
+ DemuxerStream* stream = demuxer->GetStreamByIndex(idx);
+ if (stream == NULL || stream->type() != DemuxerStream::TEXT) {
+ demuxer_streams_.push_back(NULL);
+ } else {
+ demuxer_streams_.push_back(stream);
+ }
+ }
+
+ read_callbacks_.resize(stream_count);
+}
+
+void FFmpegTextDecoder::Read(int index, const ReadCB& read_cb) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+ DCHECK(!read_cb.is_null());
+
+ ReadCB& cb = read_callbacks_[index];
+ CHECK(cb.is_null()) << "Overlapping decodes are not supported.";
+
+ cb = BindToCurrentLoop(read_cb);
+
+ DemuxerStream* stream = demuxer_streams_[index];
+ CHECK(stream);
+
+ stream->Read(base::Bind(
+ &FFmpegTextDecoder::BufferReady, weak_this_, index));
+}
+
+void FFmpegTextDecoder::BufferReady(
acolwell GONE FROM CHROMIUM 2013/09/12 00:15:15 nit:There doesn't appear to be anything FFmpeg spe
Matthew Heaney (Chromium) 2013/09/13 19:51:54 Done.
+ int index,
+ DemuxerStream::Status status,
+ const scoped_refptr<DecoderBuffer>& input) {
+ DCHECK(message_loop_->BelongsToCurrentThread());
+
+ ReadCB& read_cb = read_callbacks_[index];
+ DCHECK(!read_cb.is_null());
+
+ if (status == DemuxerStream::kAborted) {
+ DCHECK(!input.get());
+ base::ResetAndReturn(&read_cb).Run(index, NULL);
+ return;
+ }
+
+ if (input->end_of_stream()) {
+ base::ResetAndReturn(&read_cb).Run(index, NULL);
+ return;
+ }
+
+ DCHECK_EQ(status, DemuxerStream::kOk);
+ DCHECK(input.get());
+
+ scoped_refptr<TextBuffer> text_buffer(
+ new TextBuffer(input->timestamp(),
+ input->duration()));
+
+ // The side data here contains both the cue id and cue settings,
+ // separated using a 0xFF marker.
+ const uint8* side_data = input->side_data();
+ DCHECK_NE(side_data, static_cast<const uint8*>(NULL));
+
+ int side_data_size = input->side_data_size();
+ DCHECK_GE(side_data_size, 1);
+
+ const uint8* side_data_end = side_data + side_data_size;
+
+ const uint8* id_end = std::find(side_data, side_data_end, 0xFF);
+ DCHECK_NE(id_end, side_data_end);
+ DCHECK_EQ(*id_end, 0xFF);
+
+ int id_size = id_end - side_data;
+ DCHECK_GE(id_size, 0);
+
+ text_buffer->set_id(side_data, id_size);
+
+ int settings_size = side_data_size - id_size - 1;
+ DCHECK_GE(settings_size, 0);
+
+ text_buffer->set_settings(id_end + 1, settings_size);
+ text_buffer->set_text(input->data(), input->data_size());
+
+ base::ResetAndReturn(&read_cb).Run(index, text_buffer);
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698