| Index: chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.cc
|
| diff --git a/chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.cc b/chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bfdb7c121ca3a36ec3fc1bdd600cca3694fb8c85
|
| --- /dev/null
|
| +++ b/chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.cc
|
| @@ -0,0 +1,161 @@
|
| +// Copyright 2014 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 "chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "chromecast/media/cma/base/decoder_buffer_base.h"
|
| +#include "chromecast/media/cma/ipc/media_message.h"
|
| +#include "chromecast/media/cma/ipc/media_message_type.h"
|
| +#include "chromecast/media/cma/ipc_streamer/decrypt_config_marshaller.h"
|
| +#include "media/base/decrypt_config.h"
|
| +
|
| +namespace chromecast {
|
| +namespace media {
|
| +
|
| +namespace {
|
| +const size_t kMaxFrameSize = 4 * 1024 * 1024;
|
| +
|
| +class DecoderBufferFromMsg : public DecoderBufferBase {
|
| + public:
|
| + explicit DecoderBufferFromMsg(scoped_ptr<MediaMessage> msg);
|
| +
|
| + void Initialize();
|
| +
|
| + // DecoderBufferBase implementation.
|
| + virtual base::TimeDelta timestamp() const OVERRIDE;
|
| + virtual const uint8* data() const OVERRIDE;
|
| + virtual uint8* writable_data() const OVERRIDE;
|
| + virtual int data_size() const OVERRIDE;
|
| + virtual const ::media::DecryptConfig* decrypt_config() const OVERRIDE;
|
| + virtual bool end_of_stream() const OVERRIDE;
|
| +
|
| + private:
|
| + virtual ~DecoderBufferFromMsg();
|
| +
|
| + // Indicates whether this is an end of stream frame.
|
| + bool is_eos_;
|
| +
|
| + // Frame timestamp.
|
| + base::TimeDelta pts_;
|
| +
|
| + // CENC parameters.
|
| + scoped_ptr< ::media::DecryptConfig> decrypt_config_;
|
| +
|
| + // Size of the frame.
|
| + int data_size_;
|
| +
|
| + // Keeps the message since frame data is not copied.
|
| + scoped_ptr<MediaMessage> msg_;
|
| + uint8* data_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg);
|
| +};
|
| +
|
| +DecoderBufferFromMsg::DecoderBufferFromMsg(
|
| + scoped_ptr<MediaMessage> msg)
|
| + : msg_(msg.Pass()),
|
| + is_eos_(true),
|
| + data_(NULL) {
|
| + CHECK(msg_);
|
| +}
|
| +
|
| +DecoderBufferFromMsg::~DecoderBufferFromMsg() {
|
| +}
|
| +
|
| +void DecoderBufferFromMsg::Initialize() {
|
| + CHECK_EQ(msg_->type(), FrameMediaMsg);
|
| +
|
| + CHECK(msg_->ReadPod(&is_eos_));
|
| + if (is_eos_)
|
| + return;
|
| +
|
| + int64 pts_internal = 0;
|
| + CHECK(msg_->ReadPod(&pts_internal));
|
| + pts_ = base::TimeDelta::FromInternalValue(pts_internal);
|
| +
|
| + bool has_decrypt_config = false;
|
| + CHECK(msg_->ReadPod(&has_decrypt_config));
|
| + if (has_decrypt_config)
|
| + decrypt_config_.reset(DecryptConfigMarshaller::Read(msg_.get()).release());
|
| +
|
| + CHECK(msg_->ReadPod(&data_size_));
|
| + CHECK_GT(data_size_, 0);
|
| + CHECK_LT(data_size_, kMaxFrameSize);
|
| +
|
| + // Get a pointer to the frame data inside the message.
|
| + // Avoid copying the frame data here.
|
| + data_ = static_cast<uint8*>(msg_->GetWritableBuffer(data_size_));
|
| + CHECK(data_);
|
| +
|
| + if (decrypt_config_) {
|
| + uint32 subsample_total_size = 0;
|
| + for (size_t k = 0; k < decrypt_config_->subsamples().size(); k++) {
|
| + subsample_total_size += decrypt_config_->subsamples()[k].clear_bytes;
|
| + subsample_total_size += decrypt_config_->subsamples()[k].cypher_bytes;
|
| + }
|
| + CHECK_EQ(subsample_total_size, data_size_);
|
| + }
|
| +}
|
| +
|
| +base::TimeDelta DecoderBufferFromMsg::timestamp() const {
|
| + return pts_;
|
| +}
|
| +
|
| +const uint8* DecoderBufferFromMsg::data() const {
|
| + CHECK(msg_->IsSerializedMsgAvailable());
|
| + return data_;
|
| +}
|
| +
|
| +uint8* DecoderBufferFromMsg::writable_data() const {
|
| + CHECK(msg_->IsSerializedMsgAvailable());
|
| + return data_;
|
| +}
|
| +
|
| +int DecoderBufferFromMsg::data_size() const {
|
| + return data_size_;
|
| +}
|
| +
|
| +const ::media::DecryptConfig* DecoderBufferFromMsg::decrypt_config() const {
|
| + return decrypt_config_.get();
|
| +}
|
| +
|
| +bool DecoderBufferFromMsg::end_of_stream() const {
|
| + return is_eos_;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +void DecoderBufferBaseMarshaller::Write(
|
| + const scoped_refptr<DecoderBufferBase>& buffer,
|
| + MediaMessage* msg) {
|
| + CHECK(msg->WritePod(buffer->end_of_stream()));
|
| + if (buffer->end_of_stream())
|
| + return;
|
| +
|
| + CHECK(msg->WritePod(buffer->timestamp().ToInternalValue()));
|
| +
|
| + bool has_decrypt_config =
|
| + (buffer->decrypt_config() != NULL &&
|
| + buffer->decrypt_config()->iv().size() > 0);
|
| + CHECK(msg->WritePod(has_decrypt_config));
|
| + if (has_decrypt_config)
|
| + DecryptConfigMarshaller::Write(*buffer->decrypt_config(), msg);
|
| +
|
| + CHECK(msg->WritePod(buffer->data_size()));
|
| + CHECK(msg->WriteBuffer(buffer->data(), buffer->data_size()));
|
| +}
|
| +
|
| +// static
|
| +scoped_refptr<DecoderBufferBase> DecoderBufferBaseMarshaller::Read(
|
| + scoped_ptr<MediaMessage> msg) {
|
| + scoped_refptr<DecoderBufferFromMsg> buffer(
|
| + new DecoderBufferFromMsg(msg.Pass()));
|
| + buffer->Initialize();
|
| + return buffer;
|
| +}
|
| +
|
| +} // namespace media
|
| +} // namespace chromecast
|
|
|