OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "chromecast/media/cma/ipc_streamer/decoder_buffer_base_marshaller.h" | |
6 | |
7 #include <stddef.h> | |
8 #include <stdint.h> | |
9 #include <utility> | |
10 | |
11 #include "base/logging.h" | |
12 #include "base/macros.h" | |
13 #include "chromecast/media/cma/base/cast_decrypt_config_impl.h" | |
14 #include "chromecast/media/cma/base/decoder_buffer_base.h" | |
15 #include "chromecast/media/cma/ipc/media_message.h" | |
16 #include "chromecast/media/cma/ipc/media_message_type.h" | |
17 #include "chromecast/media/cma/ipc_streamer/decrypt_config_marshaller.h" | |
18 #include "chromecast/public/media/cast_decrypt_config.h" | |
19 #include "media/base/decoder_buffer.h" | |
20 #include "media/base/decrypt_config.h" | |
21 | |
22 namespace chromecast { | |
23 namespace media { | |
24 | |
25 namespace { | |
26 const size_t kMaxFrameSize = 4 * 1024 * 1024; | |
27 | |
28 class DecoderBufferFromMsg : public DecoderBufferBase { | |
29 public: | |
30 explicit DecoderBufferFromMsg(std::unique_ptr<MediaMessage> msg); | |
31 | |
32 void Initialize(); | |
33 | |
34 // DecoderBufferBase implementation. | |
35 StreamId stream_id() const override; | |
36 int64_t timestamp() const override; | |
37 void set_timestamp(base::TimeDelta timestamp) override; | |
38 const uint8_t* data() const override; | |
39 uint8_t* writable_data() const override; | |
40 size_t data_size() const override; | |
41 const CastDecryptConfig* decrypt_config() const override; | |
42 bool end_of_stream() const override; | |
43 scoped_refptr<::media::DecoderBuffer> ToMediaBuffer() const override; | |
44 | |
45 private: | |
46 ~DecoderBufferFromMsg() override; | |
47 | |
48 // Indicates whether this is an end of stream frame. | |
49 bool is_eos_; | |
50 | |
51 // Stream Id this decoder buffer belongs to. | |
52 StreamId stream_id_; | |
53 | |
54 // Frame timestamp. | |
55 base::TimeDelta pts_; | |
56 | |
57 // CENC parameters. | |
58 std::unique_ptr<CastDecryptConfig> decrypt_config_; | |
59 | |
60 // Size of the frame. | |
61 size_t data_size_; | |
62 | |
63 // Keeps the message since frame data is not copied. | |
64 std::unique_ptr<MediaMessage> msg_; | |
65 uint8_t* data_; | |
66 | |
67 DISALLOW_COPY_AND_ASSIGN(DecoderBufferFromMsg); | |
68 }; | |
69 | |
70 DecoderBufferFromMsg::DecoderBufferFromMsg(std::unique_ptr<MediaMessage> msg) | |
71 : is_eos_(true), stream_id_(kPrimary), msg_(std::move(msg)), data_(NULL) { | |
72 CHECK(msg_); | |
73 } | |
74 | |
75 DecoderBufferFromMsg::~DecoderBufferFromMsg() { | |
76 } | |
77 | |
78 void DecoderBufferFromMsg::Initialize() { | |
79 CHECK_EQ(msg_->type(), FrameMediaMsg); | |
80 | |
81 CHECK(msg_->ReadPod(&is_eos_)); | |
82 if (is_eos_) | |
83 return; | |
84 | |
85 CHECK(msg_->ReadPod(&stream_id_)); | |
86 | |
87 int64_t pts_internal = 0; | |
88 CHECK(msg_->ReadPod(&pts_internal)); | |
89 pts_ = base::TimeDelta::FromMicroseconds(pts_internal); | |
90 | |
91 bool has_decrypt_config = false; | |
92 CHECK(msg_->ReadPod(&has_decrypt_config)); | |
93 if (has_decrypt_config) | |
94 decrypt_config_.reset(DecryptConfigMarshaller::Read(msg_.get()).release()); | |
95 | |
96 CHECK(msg_->ReadPod(&data_size_)); | |
97 CHECK_GT(data_size_, 0u); | |
98 CHECK_LT(data_size_, kMaxFrameSize); | |
99 | |
100 // Get a pointer to the frame data inside the message. | |
101 // Avoid copying the frame data here. | |
102 data_ = static_cast<uint8_t*>(msg_->GetWritableBuffer(data_size_)); | |
103 CHECK(data_); | |
104 | |
105 if (decrypt_config_) { | |
106 uint32_t subsample_total_size = 0; | |
107 for (size_t k = 0; k < decrypt_config_->subsamples().size(); k++) { | |
108 subsample_total_size += decrypt_config_->subsamples()[k].clear_bytes; | |
109 subsample_total_size += decrypt_config_->subsamples()[k].cypher_bytes; | |
110 } | |
111 CHECK_EQ(subsample_total_size, data_size_); | |
112 } | |
113 } | |
114 | |
115 StreamId DecoderBufferFromMsg::stream_id() const { | |
116 return stream_id_; | |
117 } | |
118 | |
119 int64_t DecoderBufferFromMsg::timestamp() const { | |
120 return pts_.InMicroseconds(); | |
121 } | |
122 | |
123 void DecoderBufferFromMsg::set_timestamp(base::TimeDelta timestamp) { | |
124 pts_ = timestamp; | |
125 } | |
126 | |
127 const uint8_t* DecoderBufferFromMsg::data() const { | |
128 CHECK(msg_->IsSerializedMsgAvailable()); | |
129 return data_; | |
130 } | |
131 | |
132 uint8_t* DecoderBufferFromMsg::writable_data() const { | |
133 CHECK(msg_->IsSerializedMsgAvailable()); | |
134 return data_; | |
135 } | |
136 | |
137 size_t DecoderBufferFromMsg::data_size() const { | |
138 return data_size_; | |
139 } | |
140 | |
141 const CastDecryptConfig* DecoderBufferFromMsg::decrypt_config() const { | |
142 return decrypt_config_.get(); | |
143 } | |
144 | |
145 bool DecoderBufferFromMsg::end_of_stream() const { | |
146 return is_eos_; | |
147 } | |
148 | |
149 scoped_refptr<::media::DecoderBuffer> | |
150 DecoderBufferFromMsg::ToMediaBuffer() const { | |
151 if (is_eos_) | |
152 return ::media::DecoderBuffer::CreateEOSBuffer(); | |
153 | |
154 scoped_refptr<::media::DecoderBuffer> copy = | |
155 ::media::DecoderBuffer::CopyFrom(data(), data_size()); | |
156 copy->set_timestamp(base::TimeDelta::FromMicroseconds(timestamp())); | |
157 return copy; | |
158 } | |
159 | |
160 } // namespace | |
161 | |
162 // static | |
163 void DecoderBufferBaseMarshaller::Write( | |
164 const scoped_refptr<DecoderBufferBase>& buffer, | |
165 MediaMessage* msg) { | |
166 CHECK(msg->WritePod(buffer->end_of_stream())); | |
167 if (buffer->end_of_stream()) | |
168 return; | |
169 | |
170 CHECK(msg->WritePod(buffer->stream_id())); | |
171 CHECK(msg->WritePod(buffer->timestamp())); | |
172 | |
173 bool has_decrypt_config = buffer->decrypt_config() != nullptr; | |
174 CHECK(msg->WritePod(has_decrypt_config)); | |
175 | |
176 if (has_decrypt_config) | |
177 DecryptConfigMarshaller::Write(*buffer->decrypt_config(), msg); | |
178 | |
179 CHECK(msg->WritePod(buffer->data_size())); | |
180 CHECK(msg->WriteBuffer(buffer->data(), buffer->data_size())); | |
181 } | |
182 | |
183 // static | |
184 scoped_refptr<DecoderBufferBase> DecoderBufferBaseMarshaller::Read( | |
185 std::unique_ptr<MediaMessage> msg) { | |
186 scoped_refptr<DecoderBufferFromMsg> buffer( | |
187 new DecoderBufferFromMsg(std::move(msg))); | |
188 buffer->Initialize(); | |
189 return buffer; | |
190 } | |
191 | |
192 } // namespace media | |
193 } // namespace chromecast | |
OLD | NEW |