Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromecast / media / cma / ipc_streamer / decoder_buffer_base_marshaller.cc
blob1bc97a573305dad567ccf2fb8e22e91bd4d07698
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/cast_decrypt_config_impl.h"
9 #include "chromecast/media/cma/base/decoder_buffer_base.h"
10 #include "chromecast/media/cma/ipc/media_message.h"
11 #include "chromecast/media/cma/ipc/media_message_type.h"
12 #include "chromecast/media/cma/ipc_streamer/decrypt_config_marshaller.h"
13 #include "chromecast/public/media/cast_decrypt_config.h"
14 #include "media/base/decrypt_config.h"
16 namespace chromecast {
17 namespace media {
19 namespace {
20 const size_t kMaxFrameSize = 4 * 1024 * 1024;
22 class DecoderBufferFromMsg : public DecoderBufferBase {
23 public:
24 explicit DecoderBufferFromMsg(scoped_ptr<MediaMessage> msg);
26 void Initialize();
28 // DecoderBufferBase implementation.
29 StreamId stream_id() const override;
30 base::TimeDelta timestamp() const override;
31 void set_timestamp(base::TimeDelta timestamp) override;
32 const uint8* data() const override;
33 uint8* writable_data() const override;
34 size_t data_size() const override;
35 const CastDecryptConfig* decrypt_config() const override;
36 bool end_of_stream() const override;
38 private:
39 ~DecoderBufferFromMsg() override;
41 // Indicates whether this is an end of stream frame.
42 bool is_eos_;
44 // Stream Id this decoder buffer belongs to.
45 StreamId stream_id_;
47 // Frame timestamp.
48 base::TimeDelta pts_;
50 // CENC parameters.
51 scoped_ptr<CastDecryptConfig> decrypt_config_;
53 // Size of the frame.
54 size_t data_size_;
56 // Keeps the message since frame data is not copied.
57 scoped_ptr<MediaMessage> msg_;
58 uint8* data_;
60 DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg);
63 DecoderBufferFromMsg::DecoderBufferFromMsg(
64 scoped_ptr<MediaMessage> msg)
65 : is_eos_(true),
66 stream_id_(kPrimary),
67 msg_(msg.Pass()),
68 data_(NULL) {
69 CHECK(msg_);
72 DecoderBufferFromMsg::~DecoderBufferFromMsg() {
75 void DecoderBufferFromMsg::Initialize() {
76 CHECK_EQ(msg_->type(), FrameMediaMsg);
78 CHECK(msg_->ReadPod(&is_eos_));
79 if (is_eos_)
80 return;
82 CHECK(msg_->ReadPod(&stream_id_));
84 int64 pts_internal = 0;
85 CHECK(msg_->ReadPod(&pts_internal));
86 pts_ = base::TimeDelta::FromMicroseconds(pts_internal);
88 bool has_decrypt_config = false;
89 CHECK(msg_->ReadPod(&has_decrypt_config));
90 if (has_decrypt_config)
91 decrypt_config_.reset(DecryptConfigMarshaller::Read(msg_.get()).release());
93 CHECK(msg_->ReadPod(&data_size_));
94 CHECK_GT(data_size_, 0u);
95 CHECK_LT(data_size_, kMaxFrameSize);
97 // Get a pointer to the frame data inside the message.
98 // Avoid copying the frame data here.
99 data_ = static_cast<uint8*>(msg_->GetWritableBuffer(data_size_));
100 CHECK(data_);
102 if (decrypt_config_) {
103 uint32 subsample_total_size = 0;
104 for (size_t k = 0; k < decrypt_config_->subsamples().size(); k++) {
105 subsample_total_size += decrypt_config_->subsamples()[k].clear_bytes;
106 subsample_total_size += decrypt_config_->subsamples()[k].cypher_bytes;
108 CHECK_EQ(subsample_total_size, data_size_);
112 StreamId DecoderBufferFromMsg::stream_id() const {
113 return stream_id_;
116 base::TimeDelta DecoderBufferFromMsg::timestamp() const {
117 return pts_;
120 void DecoderBufferFromMsg::set_timestamp(base::TimeDelta timestamp) {
121 pts_ = timestamp;
124 const uint8* DecoderBufferFromMsg::data() const {
125 CHECK(msg_->IsSerializedMsgAvailable());
126 return data_;
129 uint8* DecoderBufferFromMsg::writable_data() const {
130 CHECK(msg_->IsSerializedMsgAvailable());
131 return data_;
134 size_t DecoderBufferFromMsg::data_size() const {
135 return data_size_;
138 const CastDecryptConfig* DecoderBufferFromMsg::decrypt_config() const {
139 return decrypt_config_.get();
142 bool DecoderBufferFromMsg::end_of_stream() const {
143 return is_eos_;
146 } // namespace
148 // static
149 void DecoderBufferBaseMarshaller::Write(
150 const scoped_refptr<DecoderBufferBase>& buffer,
151 MediaMessage* msg) {
152 CHECK(msg->WritePod(buffer->end_of_stream()));
153 if (buffer->end_of_stream())
154 return;
156 CHECK(msg->WritePod(buffer->stream_id()));
157 CHECK(msg->WritePod(buffer->timestamp().InMicroseconds()));
159 bool has_decrypt_config =
160 (buffer->decrypt_config() != NULL &&
161 buffer->decrypt_config()->iv().size() > 0);
162 CHECK(msg->WritePod(has_decrypt_config));
164 if (has_decrypt_config) {
165 // DecryptConfig may contain 0 subsamples if all content is encrypted.
166 // Map this case to a single fully-encrypted "subsample" for more consistent
167 // backend handling.
168 if (buffer->decrypt_config()->subsamples().empty()) {
169 std::vector<SubsampleEntry> encrypted_subsample_list(1);
170 encrypted_subsample_list[0].clear_bytes = 0;
171 encrypted_subsample_list[0].cypher_bytes = buffer->data_size();
172 CastDecryptConfigImpl full_sample_config(
173 buffer->decrypt_config()->key_id(), buffer->decrypt_config()->iv(),
174 encrypted_subsample_list);
175 DecryptConfigMarshaller::Write(full_sample_config, msg);
176 } else {
177 DecryptConfigMarshaller::Write(*buffer->decrypt_config(), msg);
181 CHECK(msg->WritePod(buffer->data_size()));
182 CHECK(msg->WriteBuffer(buffer->data(), buffer->data_size()));
185 // static
186 scoped_refptr<DecoderBufferBase> DecoderBufferBaseMarshaller::Read(
187 scoped_ptr<MediaMessage> msg) {
188 scoped_refptr<DecoderBufferFromMsg> buffer(
189 new DecoderBufferFromMsg(msg.Pass()));
190 buffer->Initialize();
191 return buffer;
194 } // namespace media
195 } // namespace chromecast