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 base::TimeDelta
timestamp() const override
;
28 const uint8
* data() const override
;
29 uint8
* writable_data() const override
;
30 int data_size() const override
;
31 const ::media::DecryptConfig
* decrypt_config() const override
;
32 bool end_of_stream() const override
;
35 ~DecoderBufferFromMsg() override
;
37 // Indicates whether this is an end of stream frame.
44 scoped_ptr
< ::media::DecryptConfig
> decrypt_config_
;
49 // Keeps the message since frame data is not copied.
50 scoped_ptr
<MediaMessage
> msg_
;
53 DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg
);
56 DecoderBufferFromMsg::DecoderBufferFromMsg(
57 scoped_ptr
<MediaMessage
> msg
)
64 DecoderBufferFromMsg::~DecoderBufferFromMsg() {
67 void DecoderBufferFromMsg::Initialize() {
68 CHECK_EQ(msg_
->type(), FrameMediaMsg
);
70 CHECK(msg_
->ReadPod(&is_eos_
));
74 int64 pts_internal
= 0;
75 CHECK(msg_
->ReadPod(&pts_internal
));
76 pts_
= base::TimeDelta::FromInternalValue(pts_internal
);
78 bool has_decrypt_config
= false;
79 CHECK(msg_
->ReadPod(&has_decrypt_config
));
80 if (has_decrypt_config
)
81 decrypt_config_
.reset(DecryptConfigMarshaller::Read(msg_
.get()).release());
83 CHECK(msg_
->ReadPod(&data_size_
));
84 CHECK_GT(data_size_
, 0);
85 CHECK_LT(data_size_
, kMaxFrameSize
);
87 // Get a pointer to the frame data inside the message.
88 // Avoid copying the frame data here.
89 data_
= static_cast<uint8
*>(msg_
->GetWritableBuffer(data_size_
));
92 if (decrypt_config_
) {
93 uint32 subsample_total_size
= 0;
94 for (size_t k
= 0; k
< decrypt_config_
->subsamples().size(); k
++) {
95 subsample_total_size
+= decrypt_config_
->subsamples()[k
].clear_bytes
;
96 subsample_total_size
+= decrypt_config_
->subsamples()[k
].cypher_bytes
;
98 CHECK_EQ(subsample_total_size
, data_size_
);
102 base::TimeDelta
DecoderBufferFromMsg::timestamp() const {
106 const uint8
* DecoderBufferFromMsg::data() const {
107 CHECK(msg_
->IsSerializedMsgAvailable());
111 uint8
* DecoderBufferFromMsg::writable_data() const {
112 CHECK(msg_
->IsSerializedMsgAvailable());
116 int DecoderBufferFromMsg::data_size() const {
120 const ::media::DecryptConfig
* DecoderBufferFromMsg::decrypt_config() const {
121 return decrypt_config_
.get();
124 bool DecoderBufferFromMsg::end_of_stream() const {
131 void DecoderBufferBaseMarshaller::Write(
132 const scoped_refptr
<DecoderBufferBase
>& buffer
,
134 CHECK(msg
->WritePod(buffer
->end_of_stream()));
135 if (buffer
->end_of_stream())
138 CHECK(msg
->WritePod(buffer
->timestamp().ToInternalValue()));
140 bool has_decrypt_config
=
141 (buffer
->decrypt_config() != NULL
&&
142 buffer
->decrypt_config()->iv().size() > 0);
143 CHECK(msg
->WritePod(has_decrypt_config
));
145 if (has_decrypt_config
) {
146 // DecryptConfig may contain 0 subsamples if all content is encrypted.
147 // Map this case to a single fully-encrypted "subsample" for more consistent
149 if (buffer
->decrypt_config()->subsamples().empty()) {
150 std::vector
< ::media::SubsampleEntry
> encrypted_subsample_list(1);
151 encrypted_subsample_list
[0].clear_bytes
= 0;
152 encrypted_subsample_list
[0].cypher_bytes
= buffer
->data_size();
153 ::media::DecryptConfig
full_sample_config(
154 buffer
->decrypt_config()->key_id(),
155 buffer
->decrypt_config()->iv(),
156 encrypted_subsample_list
);
157 DecryptConfigMarshaller::Write(full_sample_config
, msg
);
159 DecryptConfigMarshaller::Write(*buffer
->decrypt_config(), msg
);
163 CHECK(msg
->WritePod(buffer
->data_size()));
164 CHECK(msg
->WriteBuffer(buffer
->data(), buffer
->data_size()));
168 scoped_refptr
<DecoderBufferBase
> DecoderBufferBaseMarshaller::Read(
169 scoped_ptr
<MediaMessage
> msg
) {
170 scoped_refptr
<DecoderBufferFromMsg
> buffer(
171 new DecoderBufferFromMsg(msg
.Pass()));
172 buffer
->Initialize();
177 } // namespace chromecast