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
{
18 const size_t kMaxFrameSize
= 4 * 1024 * 1024;
20 class DecoderBufferFromMsg
: public DecoderBufferBase
{
22 explicit DecoderBufferFromMsg(scoped_ptr
<MediaMessage
> msg
);
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
;
37 ~DecoderBufferFromMsg() override
;
39 // Indicates whether this is an end of stream frame.
42 // Stream Id this decoder buffer belongs to.
49 scoped_ptr
< ::media::DecryptConfig
> decrypt_config_
;
54 // Keeps the message since frame data is not copied.
55 scoped_ptr
<MediaMessage
> msg_
;
58 DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg
);
61 DecoderBufferFromMsg::DecoderBufferFromMsg(
62 scoped_ptr
<MediaMessage
> msg
)
70 DecoderBufferFromMsg::~DecoderBufferFromMsg() {
73 void DecoderBufferFromMsg::Initialize() {
74 CHECK_EQ(msg_
->type(), FrameMediaMsg
);
76 CHECK(msg_
->ReadPod(&is_eos_
));
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_
));
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 {
114 base::TimeDelta
DecoderBufferFromMsg::timestamp() const {
118 void DecoderBufferFromMsg::set_timestamp(const base::TimeDelta
& timestamp
) {
122 const uint8
* DecoderBufferFromMsg::data() const {
123 CHECK(msg_
->IsSerializedMsgAvailable());
127 uint8
* DecoderBufferFromMsg::writable_data() const {
128 CHECK(msg_
->IsSerializedMsgAvailable());
132 size_t DecoderBufferFromMsg::data_size() const {
136 const ::media::DecryptConfig
* DecoderBufferFromMsg::decrypt_config() const {
137 return decrypt_config_
.get();
140 bool DecoderBufferFromMsg::end_of_stream() const {
147 void DecoderBufferBaseMarshaller::Write(
148 const scoped_refptr
<DecoderBufferBase
>& buffer
,
150 CHECK(msg
->WritePod(buffer
->end_of_stream()));
151 if (buffer
->end_of_stream())
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
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
);
176 DecryptConfigMarshaller::Write(*buffer
->decrypt_config(), msg
);
180 CHECK(msg
->WritePod(buffer
->data_size()));
181 CHECK(msg
->WriteBuffer(buffer
->data(), buffer
->data_size()));
185 scoped_refptr
<DecoderBufferBase
> DecoderBufferBaseMarshaller::Read(
186 scoped_ptr
<MediaMessage
> msg
) {
187 scoped_refptr
<DecoderBufferFromMsg
> buffer(
188 new DecoderBufferFromMsg(msg
.Pass()));
189 buffer
->Initialize();
194 } // namespace chromecast