Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(345)

Side by Side Diff: media/remoting/rpc/proto_utils.cc

Issue 2643253003: Media Remoting Clean-up: Less-redundant naming, style consistency, etc. (Closed)
Patch Set: REBASE Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/remoting/rpc/proto_utils.h ('k') | media/remoting/rpc/proto_utils_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 "media/remoting/rpc/proto_utils.h"
6
7 #include <algorithm>
8
9 #include "base/big_endian.h"
10 #include "base/logging.h"
11 #include "base/time/time.h"
12 #include "base/values.h"
13 #include "media/base/encryption_scheme.h"
14 #include "media/remoting/rpc/proto_enum_utils.h"
15
16 namespace media {
17 namespace remoting {
18
19 namespace {
20
21 constexpr size_t kPayloadVersionFieldSize = sizeof(uint8_t);
22 constexpr size_t kProtoBufferHeaderSize = sizeof(uint16_t);
23 constexpr size_t kDataBufferHeaderSize = sizeof(uint32_t);
24
25 std::unique_ptr<::media::DecryptConfig> ConvertProtoToDecryptConfig(
26 const pb::DecryptConfig& config_message) {
27 if (!config_message.has_key_id())
28 return nullptr;
29 if (!config_message.has_iv())
30 return nullptr;
31
32 std::vector<::media::SubsampleEntry> entries(
33 config_message.sub_samples_size());
34 for (int i = 0; i < config_message.sub_samples_size(); ++i) {
35 entries.push_back(
36 ::media::SubsampleEntry(config_message.sub_samples(i).clear_bytes(),
37 config_message.sub_samples(i).cypher_bytes()));
38 }
39
40 std::unique_ptr<::media::DecryptConfig> decrypt_config(
41 new ::media::DecryptConfig(config_message.key_id(), config_message.iv(),
42 entries));
43 return decrypt_config;
44 }
45
46 scoped_refptr<::media::DecoderBuffer> ConvertProtoToDecoderBuffer(
47 const pb::DecoderBuffer& buffer_message,
48 scoped_refptr<::media::DecoderBuffer> buffer) {
49 if (buffer_message.is_eos()) {
50 VLOG(1) << "EOS data";
51 return ::media::DecoderBuffer::CreateEOSBuffer();
52 }
53
54 if (buffer_message.has_timestamp_usec()) {
55 buffer->set_timestamp(
56 base::TimeDelta::FromMicroseconds(buffer_message.timestamp_usec()));
57 }
58
59 if (buffer_message.has_duration_usec()) {
60 buffer->set_duration(
61 base::TimeDelta::FromMicroseconds(buffer_message.duration_usec()));
62 }
63 VLOG(3) << "timestamp:" << buffer_message.timestamp_usec()
64 << " duration:" << buffer_message.duration_usec();
65
66 if (buffer_message.has_is_key_frame())
67 buffer->set_is_key_frame(buffer_message.is_key_frame());
68
69 if (buffer_message.has_decrypt_config()) {
70 buffer->set_decrypt_config(
71 ConvertProtoToDecryptConfig(buffer_message.decrypt_config()));
72 }
73
74 bool has_discard = false;
75 base::TimeDelta front_discard;
76 if (buffer_message.has_front_discard_usec()) {
77 has_discard = true;
78 front_discard =
79 base::TimeDelta::FromMicroseconds(buffer_message.front_discard_usec());
80 }
81 base::TimeDelta back_discard;
82 if (buffer_message.has_back_discard_usec()) {
83 has_discard = true;
84 back_discard =
85 base::TimeDelta::FromMicroseconds(buffer_message.back_discard_usec());
86 }
87
88 if (has_discard) {
89 buffer->set_discard_padding(
90 ::media::DecoderBuffer::DiscardPadding(front_discard, back_discard));
91 }
92
93 if (buffer_message.has_splice_timestamp_usec()) {
94 buffer->set_splice_timestamp(base::TimeDelta::FromMicroseconds(
95 buffer_message.splice_timestamp_usec()));
96 }
97
98 if (buffer_message.has_side_data()) {
99 buffer->CopySideDataFrom(
100 reinterpret_cast<const uint8_t*>(buffer_message.side_data().data()),
101 buffer_message.side_data().size());
102 }
103
104 return buffer;
105 }
106
107 void ConvertDecryptConfigToProto(const ::media::DecryptConfig& decrypt_config,
108 pb::DecryptConfig* config_message) {
109 DCHECK(config_message);
110
111 config_message->set_key_id(decrypt_config.key_id());
112 config_message->set_iv(decrypt_config.iv());
113
114 for (const auto& entry : decrypt_config.subsamples()) {
115 pb::DecryptConfig::SubSample* sub_sample =
116 config_message->add_sub_samples();
117 sub_sample->set_clear_bytes(entry.clear_bytes);
118 sub_sample->set_cypher_bytes(entry.cypher_bytes);
119 }
120 }
121
122 void ConvertDecoderBufferToProto(
123 const scoped_refptr<::media::DecoderBuffer>& decoder_buffer,
124 pb::DecoderBuffer* buffer_message) {
125 if (decoder_buffer->end_of_stream()) {
126 buffer_message->set_is_eos(true);
127 return;
128 }
129
130 VLOG(3) << "timestamp:" << decoder_buffer->timestamp().InMicroseconds()
131 << " duration:" << decoder_buffer->duration().InMicroseconds();
132 buffer_message->set_timestamp_usec(
133 decoder_buffer->timestamp().InMicroseconds());
134 buffer_message->set_duration_usec(
135 decoder_buffer->duration().InMicroseconds());
136 buffer_message->set_is_key_frame(decoder_buffer->is_key_frame());
137
138 if (decoder_buffer->decrypt_config()) {
139 ConvertDecryptConfigToProto(*decoder_buffer->decrypt_config(),
140 buffer_message->mutable_decrypt_config());
141 }
142
143 buffer_message->set_front_discard_usec(
144 decoder_buffer->discard_padding().first.InMicroseconds());
145 buffer_message->set_back_discard_usec(
146 decoder_buffer->discard_padding().second.InMicroseconds());
147 buffer_message->set_splice_timestamp_usec(
148 decoder_buffer->splice_timestamp().InMicroseconds());
149
150 if (decoder_buffer->side_data_size()) {
151 buffer_message->set_side_data(decoder_buffer->side_data(),
152 decoder_buffer->side_data_size());
153 }
154 }
155
156 } // namespace
157
158 scoped_refptr<::media::DecoderBuffer> ByteArrayToDecoderBuffer(
159 const uint8_t* data,
160 uint32_t size) {
161 base::BigEndianReader reader(reinterpret_cast<const char*>(data), size);
162 uint8_t payload_version = 0;
163 uint16_t proto_size = 0;
164 pb::DecoderBuffer segment;
165 uint32_t buffer_size = 0;
166 if (reader.ReadU8(&payload_version) && payload_version == 0 &&
167 reader.ReadU16(&proto_size) &&
168 static_cast<int>(proto_size) < reader.remaining() &&
169 segment.ParseFromArray(reader.ptr(), proto_size) &&
170 reader.Skip(proto_size) && reader.ReadU32(&buffer_size) &&
171 static_cast<int64_t>(buffer_size) <= reader.remaining()) {
172 // Deserialize proto buffer. It passes the pre allocated DecoderBuffer into
173 // the function because the proto buffer may overwrite DecoderBuffer since
174 // it may be EOS buffer.
175 scoped_refptr<media::DecoderBuffer> decoder_buffer =
176 ConvertProtoToDecoderBuffer(
177 segment,
178 DecoderBuffer::CopyFrom(
179 reinterpret_cast<const uint8_t*>(reader.ptr()), buffer_size));
180 return decoder_buffer;
181 }
182
183 LOG(ERROR) << "Not able to convert byte array to ::media::DecoderBuffer";
184 return nullptr;
185 }
186
187 std::vector<uint8_t> DecoderBufferToByteArray(
188 const scoped_refptr<::media::DecoderBuffer>& decoder_buffer) {
189 pb::DecoderBuffer decoder_buffer_message;
190 ConvertDecoderBufferToProto(decoder_buffer, &decoder_buffer_message);
191
192 size_t decoder_buffer_size =
193 decoder_buffer->end_of_stream() ? 0 : decoder_buffer->data_size();
194 size_t size = kPayloadVersionFieldSize + kProtoBufferHeaderSize +
195 decoder_buffer_message.ByteSize() + kDataBufferHeaderSize +
196 decoder_buffer_size;
197 std::vector<uint8_t> buffer(size);
198 base::BigEndianWriter writer(reinterpret_cast<char*>(buffer.data()),
199 buffer.size());
200 if (writer.WriteU8(0) &&
201 writer.WriteU16(
202 static_cast<uint16_t>(decoder_buffer_message.GetCachedSize())) &&
203 decoder_buffer_message.SerializeToArray(
204 writer.ptr(), decoder_buffer_message.GetCachedSize()) &&
205 writer.Skip(decoder_buffer_message.GetCachedSize()) &&
206 writer.WriteU32(decoder_buffer_size)) {
207 if (decoder_buffer_size) {
208 // DecoderBuffer frame data.
209 writer.WriteBytes(reinterpret_cast<const void*>(decoder_buffer->data()),
210 decoder_buffer->data_size());
211 }
212 return buffer;
213 }
214
215 // Reset buffer since serialization of the data failed.
216 LOG(ERROR) << "Not able to convert ::media::DecoderBuffer to byte array";
217 buffer.clear();
218 return buffer;
219 }
220
221 void ConvertEncryptionSchemeToProto(
222 const ::media::EncryptionScheme& encryption_scheme,
223 pb::EncryptionScheme* message) {
224 DCHECK(message);
225 message->set_mode(
226 ToProtoEncryptionSchemeCipherMode(encryption_scheme.mode()).value());
227 message->set_encrypt_blocks(encryption_scheme.pattern().encrypt_blocks());
228 message->set_skip_blocks(encryption_scheme.pattern().skip_blocks());
229 }
230
231 ::media::EncryptionScheme ConvertProtoToEncryptionScheme(
232 const pb::EncryptionScheme& message) {
233 return ::media::EncryptionScheme(
234 ToMediaEncryptionSchemeCipherMode(message.mode()).value(),
235 ::media::EncryptionScheme::Pattern(message.encrypt_blocks(),
236 message.skip_blocks()));
237 }
238
239 void ConvertAudioDecoderConfigToProto(
240 const ::media::AudioDecoderConfig& audio_config,
241 pb::AudioDecoderConfig* audio_message) {
242 DCHECK(audio_config.IsValidConfig());
243 DCHECK(audio_message);
244
245 audio_message->set_codec(
246 ToProtoAudioDecoderConfigCodec(audio_config.codec()).value());
247 audio_message->set_sample_format(
248 ToProtoAudioDecoderConfigSampleFormat(audio_config.sample_format())
249 .value());
250 audio_message->set_channel_layout(
251 ToProtoAudioDecoderConfigChannelLayout(audio_config.channel_layout())
252 .value());
253 audio_message->set_samples_per_second(audio_config.samples_per_second());
254 audio_message->set_seek_preroll_usec(
255 audio_config.seek_preroll().InMicroseconds());
256 audio_message->set_codec_delay(audio_config.codec_delay());
257
258 if (!audio_config.extra_data().empty()) {
259 audio_message->set_extra_data(audio_config.extra_data().data(),
260 audio_config.extra_data().size());
261 }
262
263 if (audio_config.is_encrypted()) {
264 pb::EncryptionScheme* encryption_scheme_message =
265 audio_message->mutable_encryption_scheme();
266 ConvertEncryptionSchemeToProto(audio_config.encryption_scheme(),
267 encryption_scheme_message);
268 }
269 }
270
271 bool ConvertProtoToAudioDecoderConfig(
272 const pb::AudioDecoderConfig& audio_message,
273 ::media::AudioDecoderConfig* audio_config) {
274 DCHECK(audio_config);
275 audio_config->Initialize(
276 ToMediaAudioCodec(audio_message.codec()).value(),
277 ToMediaSampleFormat(audio_message.sample_format()).value(),
278 ToMediaChannelLayout(audio_message.channel_layout()).value(),
279 audio_message.samples_per_second(),
280 std::vector<uint8_t>(audio_message.extra_data().begin(),
281 audio_message.extra_data().end()),
282 ConvertProtoToEncryptionScheme(audio_message.encryption_scheme()),
283 base::TimeDelta::FromMicroseconds(audio_message.seek_preroll_usec()),
284 audio_message.codec_delay());
285 return audio_config->IsValidConfig();
286 }
287
288 void ConvertVideoDecoderConfigToProto(
289 const ::media::VideoDecoderConfig& video_config,
290 pb::VideoDecoderConfig* video_message) {
291 DCHECK(video_config.IsValidConfig());
292 DCHECK(video_message);
293
294 video_message->set_codec(
295 ToProtoVideoDecoderConfigCodec(video_config.codec()).value());
296 video_message->set_profile(
297 ToProtoVideoDecoderConfigProfile(video_config.profile()).value());
298 video_message->set_format(
299 ToProtoVideoDecoderConfigFormat(video_config.format()).value());
300 video_message->set_color_space(
301 ToProtoVideoDecoderConfigColorSpace(video_config.color_space()).value());
302
303 pb::Size* coded_size_message = video_message->mutable_coded_size();
304 coded_size_message->set_width(video_config.coded_size().width());
305 coded_size_message->set_height(video_config.coded_size().height());
306
307 pb::Rect* visible_rect_message = video_message->mutable_visible_rect();
308 visible_rect_message->set_x(video_config.visible_rect().x());
309 visible_rect_message->set_y(video_config.visible_rect().y());
310 visible_rect_message->set_width(video_config.visible_rect().width());
311 visible_rect_message->set_height(video_config.visible_rect().height());
312
313 pb::Size* natural_size_message = video_message->mutable_natural_size();
314 natural_size_message->set_width(video_config.natural_size().width());
315 natural_size_message->set_height(video_config.natural_size().height());
316
317 if (!video_config.extra_data().empty()) {
318 video_message->set_extra_data(video_config.extra_data().data(),
319 video_config.extra_data().size());
320 }
321
322 if (video_config.is_encrypted()) {
323 pb::EncryptionScheme* encryption_scheme_message =
324 video_message->mutable_encryption_scheme();
325 ConvertEncryptionSchemeToProto(video_config.encryption_scheme(),
326 encryption_scheme_message);
327 }
328 }
329
330 bool ConvertProtoToVideoDecoderConfig(
331 const pb::VideoDecoderConfig& video_message,
332 ::media::VideoDecoderConfig* video_config) {
333 DCHECK(video_config);
334 ::media::EncryptionScheme encryption_scheme;
335 video_config->Initialize(
336 ToMediaVideoCodec(video_message.codec()).value(),
337 ToMediaVideoCodecProfile(video_message.profile()).value(),
338 ToMediaVideoPixelFormat(video_message.format()).value(),
339 ToMediaColorSpace(video_message.color_space()).value(),
340 gfx::Size(video_message.coded_size().width(),
341 video_message.coded_size().height()),
342 gfx::Rect(video_message.visible_rect().x(),
343 video_message.visible_rect().y(),
344 video_message.visible_rect().width(),
345 video_message.visible_rect().height()),
346 gfx::Size(video_message.natural_size().width(),
347 video_message.natural_size().height()),
348 std::vector<uint8_t>(video_message.extra_data().begin(),
349 video_message.extra_data().end()),
350 ConvertProtoToEncryptionScheme(video_message.encryption_scheme()));
351 return video_config->IsValidConfig();
352 }
353
354 void ConvertCdmKeyInfoToProto(
355 const ::media::CdmKeysInfo& keys_information,
356 pb::CdmClientOnSessionKeysChange* key_change_message) {
357 for (const auto& info : keys_information) {
358 pb::CdmKeyInformation* key = key_change_message->add_key_information();
359 key->set_key_id(info->key_id.data(), info->key_id.size());
360 key->set_status(ToProtoCdmKeyInformation(info->status).value());
361 key->set_system_code(info->system_code);
362 }
363 }
364
365 void ConvertProtoToCdmKeyInfo(
366 const pb::CdmClientOnSessionKeysChange keychange_message,
367 CdmKeysInfo* key_information) {
368 DCHECK(key_information);
369 key_information->reserve(keychange_message.key_information_size());
370 for (int i = 0; i < keychange_message.key_information_size(); ++i) {
371 const pb::CdmKeyInformation key_info_msg =
372 keychange_message.key_information(i);
373
374 std::unique_ptr<::media::CdmKeyInformation> key(
375 new ::media::CdmKeyInformation(
376 key_info_msg.key_id(),
377 ToMediaCdmKeyInformationKeyStatus(key_info_msg.status()).value(),
378 key_info_msg.system_code()));
379 key_information->push_back(std::move(key));
380 }
381 }
382
383 void ConvertCdmPromiseToProto(const CdmPromiseResult& result,
384 pb::CdmPromise* promise_message) {
385 promise_message->set_success(result.success());
386 if (!result.success()) {
387 promise_message->set_exception(
388 ToProtoCdmException(result.exception()).value());
389 promise_message->set_system_code(result.system_code());
390 promise_message->set_error_message(result.error_message());
391 }
392 }
393
394 void ConvertCdmPromiseWithSessionIdToProto(const CdmPromiseResult& result,
395 const std::string& session_id,
396 pb::CdmPromise* promise_message) {
397 ConvertCdmPromiseToProto(result, promise_message);
398 promise_message->set_session_id(session_id);
399 }
400
401 void ConvertCdmPromiseWithCdmIdToProto(const CdmPromiseResult& result,
402 int cdm_id,
403 pb::CdmPromise* promise_message) {
404 ConvertCdmPromiseToProto(result, promise_message);
405 promise_message->set_cdm_id(cdm_id);
406 }
407
408 bool ConvertProtoToCdmPromise(const pb::CdmPromise& promise_message,
409 CdmPromiseResult* result) {
410 if (!promise_message.has_success())
411 return false;
412
413 bool success = promise_message.success();
414 if (success) {
415 *result = CdmPromiseResult::SuccessResult();
416 return true;
417 }
418
419 ::media::CdmPromise::Exception exception = ::media::CdmPromise::UNKNOWN_ERROR;
420 uint32_t system_code = 0;
421 std::string error_message;
422
423 exception = ToCdmPromiseException(promise_message.exception()).value();
424 system_code = promise_message.system_code();
425 error_message = promise_message.error_message();
426 *result = CdmPromiseResult(exception, system_code, error_message);
427 return true;
428 }
429
430 bool ConvertProtoToCdmPromiseWithCdmIdSessionId(const pb::RpcMessage& message,
431 CdmPromiseResult* result,
432 int* cdm_id,
433 std::string* session_id) {
434 if (!message.has_cdm_promise_rpc())
435 return false;
436
437 const auto& promise_message = message.cdm_promise_rpc();
438 if (!ConvertProtoToCdmPromise(promise_message, result))
439 return false;
440
441 if (cdm_id)
442 *cdm_id = promise_message.cdm_id();
443 if (session_id)
444 *session_id = promise_message.session_id();
445
446 return true;
447 }
448
449 //==============================================================================
450 CdmPromiseResult::CdmPromiseResult()
451 : CdmPromiseResult(::media::CdmPromise::UNKNOWN_ERROR, 0, "") {}
452
453 CdmPromiseResult::CdmPromiseResult(::media::CdmPromise::Exception exception,
454 uint32_t system_code,
455 std::string error_message)
456 : success_(false),
457 exception_(exception),
458 system_code_(system_code),
459 error_message_(error_message) {}
460
461 CdmPromiseResult::CdmPromiseResult(const CdmPromiseResult& other) = default;
462
463 CdmPromiseResult::~CdmPromiseResult() = default;
464
465 CdmPromiseResult CdmPromiseResult::SuccessResult() {
466 CdmPromiseResult result(static_cast<::media::CdmPromise::Exception>(0), 0,
467 "");
468 result.success_ = true;
469 return result;
470 }
471
472 } // namespace remoting
473 } // namespace media
OLDNEW
« no previous file with comments | « media/remoting/rpc/proto_utils.h ('k') | media/remoting/rpc/proto_utils_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698