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
{
20 const size_t kMaxFrameSize
= 4 * 1024 * 1024;
22 class DecoderBufferFromMsg
: public DecoderBufferBase
{
24 explicit DecoderBufferFromMsg(scoped_ptr
<MediaMessage
> msg
);
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
;
39 ~DecoderBufferFromMsg() override
;
41 // Indicates whether this is an end of stream frame.
44 // Stream Id this decoder buffer belongs to.
51 scoped_ptr
<CastDecryptConfig
> decrypt_config_
;
56 // Keeps the message since frame data is not copied.
57 scoped_ptr
<MediaMessage
> msg_
;
60 DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg
);
63 DecoderBufferFromMsg::DecoderBufferFromMsg(
64 scoped_ptr
<MediaMessage
> msg
)
72 DecoderBufferFromMsg::~DecoderBufferFromMsg() {
75 void DecoderBufferFromMsg::Initialize() {
76 CHECK_EQ(msg_
->type(), FrameMediaMsg
);
78 CHECK(msg_
->ReadPod(&is_eos_
));
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_
));
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 {
116 base::TimeDelta
DecoderBufferFromMsg::timestamp() const {
120 void DecoderBufferFromMsg::set_timestamp(base::TimeDelta timestamp
) {
124 const uint8
* DecoderBufferFromMsg::data() const {
125 CHECK(msg_
->IsSerializedMsgAvailable());
129 uint8
* DecoderBufferFromMsg::writable_data() const {
130 CHECK(msg_
->IsSerializedMsgAvailable());
134 size_t DecoderBufferFromMsg::data_size() const {
138 const CastDecryptConfig
* DecoderBufferFromMsg::decrypt_config() const {
139 return decrypt_config_
.get();
142 bool DecoderBufferFromMsg::end_of_stream() const {
149 void DecoderBufferBaseMarshaller::Write(
150 const scoped_refptr
<DecoderBufferBase
>& buffer
,
152 CHECK(msg
->WritePod(buffer
->end_of_stream()));
153 if (buffer
->end_of_stream())
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
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
);
177 DecryptConfigMarshaller::Write(*buffer
->decrypt_config(), msg
);
181 CHECK(msg
->WritePod(buffer
->data_size()));
182 CHECK(msg
->WriteBuffer(buffer
->data(), buffer
->data_size()));
186 scoped_refptr
<DecoderBufferBase
> DecoderBufferBaseMarshaller::Read(
187 scoped_ptr
<MediaMessage
> msg
) {
188 scoped_refptr
<DecoderBufferFromMsg
> buffer(
189 new DecoderBufferFromMsg(msg
.Pass()));
190 buffer
->Initialize();
195 } // namespace chromecast