[MediaRouter] Update MR-2-Extension's PostMessage to return boolean.
[chromium-blink-merge.git] / chromecast / media / cma / ipc_streamer / decoder_buffer_base_marshaller.cc
blobab3a25878511bdd89262f2f0397f45afddb4f886
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.h"
7 #include "base/logging.h"
8 #include "chromecast/media/cma/base/decoder_buffer_base.h"
9 #include "chromecast/media/cma/ipc/media_message.h"
10 #include "chromecast/media/cma/ipc/media_message_type.h"
11 #include "chromecast/media/cma/ipc_streamer/decrypt_config_marshaller.h"
12 #include "media/base/decrypt_config.h"
14 namespace chromecast {
15 namespace media {
17 namespace {
18 const size_t kMaxFrameSize = 4 * 1024 * 1024;
20 class DecoderBufferFromMsg : public DecoderBufferBase {
21 public:
22 explicit DecoderBufferFromMsg(scoped_ptr<MediaMessage> msg);
24 void Initialize();
26 // DecoderBufferBase implementation.
27 StreamId stream_id() const override;
28 base::TimeDelta timestamp() const override;
29 void set_timestamp(const base::TimeDelta& timestamp) override;
30 const uint8* data() const override;
31 uint8* writable_data() const override;
32 size_t data_size() const override;
33 const ::media::DecryptConfig* decrypt_config() const override;
34 bool end_of_stream() const override;
36 private:
37 ~DecoderBufferFromMsg() override;
39 // Indicates whether this is an end of stream frame.
40 bool is_eos_;
42 // Stream Id this decoder buffer belongs to.
43 StreamId stream_id_;
45 // Frame timestamp.
46 base::TimeDelta pts_;
48 // CENC parameters.
49 scoped_ptr< ::media::DecryptConfig> decrypt_config_;
51 // Size of the frame.
52 size_t data_size_;
54 // Keeps the message since frame data is not copied.
55 scoped_ptr<MediaMessage> msg_;
56 uint8* data_;
58 DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg);
61 DecoderBufferFromMsg::DecoderBufferFromMsg(
62 scoped_ptr<MediaMessage> msg)
63 : is_eos_(true),
64 stream_id_(kPrimary),
65 msg_(msg.Pass()),
66 data_(NULL) {
67 CHECK(msg_);
70 DecoderBufferFromMsg::~DecoderBufferFromMsg() {
73 void DecoderBufferFromMsg::Initialize() {
74 CHECK_EQ(msg_->type(), FrameMediaMsg);
76 CHECK(msg_->ReadPod(&is_eos_));
77 if (is_eos_)
78 return;
80 CHECK(msg_->ReadPod(&stream_id_));
82 int64 pts_internal = 0;
83 CHECK(msg_->ReadPod(&pts_internal));
84 pts_ = base::TimeDelta::FromInternalValue(pts_internal);
86 bool has_decrypt_config = false;
87 CHECK(msg_->ReadPod(&has_decrypt_config));
88 if (has_decrypt_config)
89 decrypt_config_.reset(DecryptConfigMarshaller::Read(msg_.get()).release());
91 CHECK(msg_->ReadPod(&data_size_));
92 CHECK_GT(data_size_, 0u);
93 CHECK_LT(data_size_, kMaxFrameSize);
95 // Get a pointer to the frame data inside the message.
96 // Avoid copying the frame data here.
97 data_ = static_cast<uint8*>(msg_->GetWritableBuffer(data_size_));
98 CHECK(data_);
100 if (decrypt_config_) {
101 uint32 subsample_total_size = 0;
102 for (size_t k = 0; k < decrypt_config_->subsamples().size(); k++) {
103 subsample_total_size += decrypt_config_->subsamples()[k].clear_bytes;
104 subsample_total_size += decrypt_config_->subsamples()[k].cypher_bytes;
106 CHECK_EQ(subsample_total_size, data_size_);
110 StreamId DecoderBufferFromMsg::stream_id() const {
111 return stream_id_;
114 base::TimeDelta DecoderBufferFromMsg::timestamp() const {
115 return pts_;
118 void DecoderBufferFromMsg::set_timestamp(const base::TimeDelta& timestamp) {
119 pts_ = timestamp;
122 const uint8* DecoderBufferFromMsg::data() const {
123 CHECK(msg_->IsSerializedMsgAvailable());
124 return data_;
127 uint8* DecoderBufferFromMsg::writable_data() const {
128 CHECK(msg_->IsSerializedMsgAvailable());
129 return data_;
132 size_t DecoderBufferFromMsg::data_size() const {
133 return data_size_;
136 const ::media::DecryptConfig* DecoderBufferFromMsg::decrypt_config() const {
137 return decrypt_config_.get();
140 bool DecoderBufferFromMsg::end_of_stream() const {
141 return is_eos_;
144 } // namespace
146 // static
147 void DecoderBufferBaseMarshaller::Write(
148 const scoped_refptr<DecoderBufferBase>& buffer,
149 MediaMessage* msg) {
150 CHECK(msg->WritePod(buffer->end_of_stream()));
151 if (buffer->end_of_stream())
152 return;
154 CHECK(msg->WritePod(buffer->stream_id()));
155 CHECK(msg->WritePod(buffer->timestamp().ToInternalValue()));
157 bool has_decrypt_config =
158 (buffer->decrypt_config() != NULL &&
159 buffer->decrypt_config()->iv().size() > 0);
160 CHECK(msg->WritePod(has_decrypt_config));
162 if (has_decrypt_config) {
163 // DecryptConfig may contain 0 subsamples if all content is encrypted.
164 // Map this case to a single fully-encrypted "subsample" for more consistent
165 // backend handling.
166 if (buffer->decrypt_config()->subsamples().empty()) {
167 std::vector< ::media::SubsampleEntry> encrypted_subsample_list(1);
168 encrypted_subsample_list[0].clear_bytes = 0;
169 encrypted_subsample_list[0].cypher_bytes = buffer->data_size();
170 ::media::DecryptConfig full_sample_config(
171 buffer->decrypt_config()->key_id(),
172 buffer->decrypt_config()->iv(),
173 encrypted_subsample_list);
174 DecryptConfigMarshaller::Write(full_sample_config, msg);
175 } else {
176 DecryptConfigMarshaller::Write(*buffer->decrypt_config(), msg);
180 CHECK(msg->WritePod(buffer->data_size()));
181 CHECK(msg->WriteBuffer(buffer->data(), buffer->data_size()));
184 // static
185 scoped_refptr<DecoderBufferBase> DecoderBufferBaseMarshaller::Read(
186 scoped_ptr<MediaMessage> msg) {
187 scoped_refptr<DecoderBufferFromMsg> buffer(
188 new DecoderBufferFromMsg(msg.Pass()));
189 buffer->Initialize();
190 return buffer;
193 } // namespace media
194 } // namespace chromecast