| Index: media/filters/text_decoder_impl.cc
|
| diff --git a/media/filters/text_decoder_impl.cc b/media/filters/text_decoder_impl.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4eda5089b6d4a6df68111443e78e9673850f8dea
|
| --- /dev/null
|
| +++ b/media/filters/text_decoder_impl.cc
|
| @@ -0,0 +1,89 @@
|
| +// 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/text_decoder_impl.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_cue.h"
|
| +
|
| +namespace media {
|
| +
|
| +TextDecoderImpl::TextDecoderImpl(
|
| + const scoped_refptr<base::MessageLoopProxy>& message_loop)
|
| + : message_loop_(message_loop),
|
| + weak_factory_(this) {
|
| +}
|
| +
|
| +TextDecoderImpl::~TextDecoderImpl() {
|
| +}
|
| +
|
| +void TextDecoderImpl::Initialize() {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| + weak_this_ = weak_factory_.GetWeakPtr();
|
| +}
|
| +
|
| +void TextDecoderImpl::Read(DemuxerStream* stream, const ReadCB& read_cb) {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| + DCHECK(!read_cb.is_null());
|
| +
|
| + ReadCB& cb = read_callbacks_[stream];
|
| + CHECK(cb.is_null()) << "Overlapping decodes are not supported.";
|
| +
|
| + cb = BindToCurrentLoop(read_cb);
|
| +
|
| + stream->Read(base::Bind(
|
| + &TextDecoderImpl::BufferReady, weak_this_, stream));
|
| +}
|
| +
|
| +void TextDecoderImpl::BufferReady(
|
| + DemuxerStream* stream,
|
| + DemuxerStream::Status status,
|
| + const scoped_refptr<DecoderBuffer>& input) {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| +
|
| + ReadCB& read_cb = read_callbacks_[stream];
|
| + DCHECK(!read_cb.is_null());
|
| +
|
| + if (status == DemuxerStream::kAborted) {
|
| + DCHECK(!input.get());
|
| + base::ResetAndReturn(&read_cb).Run(stream, NULL);
|
| + return;
|
| + }
|
| +
|
| + if (input->end_of_stream()) {
|
| + base::ResetAndReturn(&read_cb).Run(stream, NULL);
|
| + return;
|
| + }
|
| +
|
| + DCHECK_EQ(status, DemuxerStream::kOk);
|
| + DCHECK(input.get());
|
| + DCHECK_GE(input->side_data_size(), 2);
|
| +
|
| + // The side data contains both the cue id and cue settings,
|
| + // each terminated with a NUL.
|
| + const char* id_ptr = reinterpret_cast<const char*>(input->side_data());
|
| + size_t id_len = strlen(id_ptr);
|
| + std::string id(id_ptr, id_len);
|
| +
|
| + const char* settings_ptr = id_ptr + id_len + 1;
|
| + size_t settings_len = strlen(settings_ptr);
|
| + std::string settings(settings_ptr, settings_len);
|
| +
|
| + // The cue payload is stored in the data-part of the input buffer.
|
| + std::string text(input->data(), input->data() + input->data_size());
|
| +
|
| + scoped_refptr<TextCue> text_cue(
|
| + new TextCue(input->timestamp(),
|
| + input->duration(),
|
| + id,
|
| + settings,
|
| + text));
|
| +
|
| + base::ResetAndReturn(&read_cb).Run(stream, text_cue);
|
| +}
|
| +
|
| +} // namespace media
|
|
|