blob: d08f4e22897f057b38d59f3478074aa250812ee2 [file] [log] [blame]
erickung1fc58a42016-09-24 03:00:071// 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
miu9f7788e2017-01-25 00:46:095#include "media/remoting/proto_utils.h"
erickung1fc58a42016-09-24 03:00:076
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"
John Rummell9044a762018-04-19 01:24:0713#include "media/base/decrypt_config.h"
John Rummell25a00c762018-03-20 18:01:3014#include "media/base/encryption_pattern.h"
erickung1fc58a42016-09-24 03:00:0715#include "media/base/encryption_scheme.h"
Chris Cunninghamfe34199b2017-07-07 20:06:4516#include "media/base/timestamp_constants.h"
miu9f7788e2017-01-25 00:46:0917#include "media/remoting/proto_enum_utils.h"
erickung1fc58a42016-09-24 03:00:0718
19namespace media {
20namespace remoting {
21
22namespace {
23
24constexpr size_t kPayloadVersionFieldSize = sizeof(uint8_t);
25constexpr size_t kProtoBufferHeaderSize = sizeof(uint16_t);
26constexpr size_t kDataBufferHeaderSize = sizeof(uint32_t);
27
miu9f7788e2017-01-25 00:46:0928std::unique_ptr<DecryptConfig> ConvertProtoToDecryptConfig(
erickung1fc58a42016-09-24 03:00:0729 const pb::DecryptConfig& config_message) {
30 if (!config_message.has_key_id())
31 return nullptr;
32 if (!config_message.has_iv())
33 return nullptr;
34
John Rummell9044a762018-04-19 01:24:0735 if (!config_message.has_mode()) {
36 // Assume it's unencrypted.
37 return nullptr;
38 }
39
miu9f7788e2017-01-25 00:46:0940 std::vector<SubsampleEntry> entries(config_message.sub_samples_size());
erickung1fc58a42016-09-24 03:00:0741 for (int i = 0; i < config_message.sub_samples_size(); ++i) {
42 entries.push_back(
miu9f7788e2017-01-25 00:46:0943 SubsampleEntry(config_message.sub_samples(i).clear_bytes(),
44 config_message.sub_samples(i).cypher_bytes()));
erickung1fc58a42016-09-24 03:00:0745 }
46
John Rummell9044a762018-04-19 01:24:0747 if (config_message.mode() == pb::EncryptionMode::kCenc) {
48 return DecryptConfig::CreateCencConfig(config_message.key_id(),
49 config_message.iv(), entries);
50 }
51
52 base::Optional<EncryptionPattern> pattern;
53 if (config_message.has_crypt_byte_block()) {
54 pattern = EncryptionPattern(config_message.crypt_byte_block(),
55 config_message.skip_byte_block());
56 }
57
58 if (config_message.mode() == pb::EncryptionMode::kCbcs) {
59 return DecryptConfig::CreateCbcsConfig(config_message.key_id(),
60 config_message.iv(), entries,
61 std::move(pattern));
62 }
63
64 return nullptr;
erickung1fc58a42016-09-24 03:00:0765}
66
miu9f7788e2017-01-25 00:46:0967scoped_refptr<DecoderBuffer> ConvertProtoToDecoderBuffer(
erickung1fc58a42016-09-24 03:00:0768 const pb::DecoderBuffer& buffer_message,
miu9f7788e2017-01-25 00:46:0969 scoped_refptr<DecoderBuffer> buffer) {
erickung1fc58a42016-09-24 03:00:0770 if (buffer_message.is_eos()) {
71 VLOG(1) << "EOS data";
miu9f7788e2017-01-25 00:46:0972 return DecoderBuffer::CreateEOSBuffer();
erickung1fc58a42016-09-24 03:00:0773 }
74
75 if (buffer_message.has_timestamp_usec()) {
76 buffer->set_timestamp(
77 base::TimeDelta::FromMicroseconds(buffer_message.timestamp_usec()));
78 }
79
80 if (buffer_message.has_duration_usec()) {
81 buffer->set_duration(
82 base::TimeDelta::FromMicroseconds(buffer_message.duration_usec()));
83 }
84 VLOG(3) << "timestamp:" << buffer_message.timestamp_usec()
85 << " duration:" << buffer_message.duration_usec();
86
87 if (buffer_message.has_is_key_frame())
88 buffer->set_is_key_frame(buffer_message.is_key_frame());
89
90 if (buffer_message.has_decrypt_config()) {
91 buffer->set_decrypt_config(
92 ConvertProtoToDecryptConfig(buffer_message.decrypt_config()));
93 }
94
95 bool has_discard = false;
96 base::TimeDelta front_discard;
97 if (buffer_message.has_front_discard_usec()) {
98 has_discard = true;
99 front_discard =
100 base::TimeDelta::FromMicroseconds(buffer_message.front_discard_usec());
101 }
102 base::TimeDelta back_discard;
103 if (buffer_message.has_back_discard_usec()) {
104 has_discard = true;
105 back_discard =
106 base::TimeDelta::FromMicroseconds(buffer_message.back_discard_usec());
107 }
108
109 if (has_discard) {
110 buffer->set_discard_padding(
miu9f7788e2017-01-25 00:46:09111 DecoderBuffer::DiscardPadding(front_discard, back_discard));
erickung1fc58a42016-09-24 03:00:07112 }
113
erickung1fc58a42016-09-24 03:00:07114 if (buffer_message.has_side_data()) {
115 buffer->CopySideDataFrom(
116 reinterpret_cast<const uint8_t*>(buffer_message.side_data().data()),
117 buffer_message.side_data().size());
118 }
119
120 return buffer;
121}
122
miu9f7788e2017-01-25 00:46:09123void ConvertDecryptConfigToProto(const DecryptConfig& decrypt_config,
erickung1fc58a42016-09-24 03:00:07124 pb::DecryptConfig* config_message) {
125 DCHECK(config_message);
126
127 config_message->set_key_id(decrypt_config.key_id());
128 config_message->set_iv(decrypt_config.iv());
129
130 for (const auto& entry : decrypt_config.subsamples()) {
131 pb::DecryptConfig::SubSample* sub_sample =
132 config_message->add_sub_samples();
133 sub_sample->set_clear_bytes(entry.clear_bytes);
134 sub_sample->set_cypher_bytes(entry.cypher_bytes);
135 }
John Rummell9044a762018-04-19 01:24:07136
137 config_message->set_mode(
138 ToProtoEncryptionMode(decrypt_config.encryption_mode()).value());
139 if (decrypt_config.HasPattern()) {
140 config_message->set_crypt_byte_block(
141 decrypt_config.encryption_pattern()->crypt_byte_block());
142 config_message->set_skip_byte_block(
143 decrypt_config.encryption_pattern()->skip_byte_block());
144 }
erickung1fc58a42016-09-24 03:00:07145}
146
miu9f7788e2017-01-25 00:46:09147void ConvertDecoderBufferToProto(const DecoderBuffer& decoder_buffer,
148 pb::DecoderBuffer* buffer_message) {
149 if (decoder_buffer.end_of_stream()) {
erickung1fc58a42016-09-24 03:00:07150 buffer_message->set_is_eos(true);
151 return;
152 }
153
miu9f7788e2017-01-25 00:46:09154 VLOG(3) << "timestamp:" << decoder_buffer.timestamp().InMicroseconds()
155 << " duration:" << decoder_buffer.duration().InMicroseconds();
erickung1fc58a42016-09-24 03:00:07156 buffer_message->set_timestamp_usec(
miu9f7788e2017-01-25 00:46:09157 decoder_buffer.timestamp().InMicroseconds());
158 buffer_message->set_duration_usec(decoder_buffer.duration().InMicroseconds());
159 buffer_message->set_is_key_frame(decoder_buffer.is_key_frame());
erickung1fc58a42016-09-24 03:00:07160
miu9f7788e2017-01-25 00:46:09161 if (decoder_buffer.decrypt_config()) {
162 ConvertDecryptConfigToProto(*decoder_buffer.decrypt_config(),
erickung1fc58a42016-09-24 03:00:07163 buffer_message->mutable_decrypt_config());
164 }
165
166 buffer_message->set_front_discard_usec(
miu9f7788e2017-01-25 00:46:09167 decoder_buffer.discard_padding().first.InMicroseconds());
erickung1fc58a42016-09-24 03:00:07168 buffer_message->set_back_discard_usec(
miu9f7788e2017-01-25 00:46:09169 decoder_buffer.discard_padding().second.InMicroseconds());
erickung1fc58a42016-09-24 03:00:07170
miu9f7788e2017-01-25 00:46:09171 if (decoder_buffer.side_data_size()) {
172 buffer_message->set_side_data(decoder_buffer.side_data(),
173 decoder_buffer.side_data_size());
erickung1fc58a42016-09-24 03:00:07174 }
175}
176
177} // namespace
178
miu9f7788e2017-01-25 00:46:09179scoped_refptr<DecoderBuffer> ByteArrayToDecoderBuffer(const uint8_t* data,
180 uint32_t size) {
erickung1fc58a42016-09-24 03:00:07181 base::BigEndianReader reader(reinterpret_cast<const char*>(data), size);
182 uint8_t payload_version = 0;
183 uint16_t proto_size = 0;
184 pb::DecoderBuffer segment;
185 uint32_t buffer_size = 0;
186 if (reader.ReadU8(&payload_version) && payload_version == 0 &&
187 reader.ReadU16(&proto_size) &&
188 static_cast<int>(proto_size) < reader.remaining() &&
189 segment.ParseFromArray(reader.ptr(), proto_size) &&
190 reader.Skip(proto_size) && reader.ReadU32(&buffer_size) &&
191 static_cast<int64_t>(buffer_size) <= reader.remaining()) {
192 // Deserialize proto buffer. It passes the pre allocated DecoderBuffer into
193 // the function because the proto buffer may overwrite DecoderBuffer since
194 // it may be EOS buffer.
miu9f7788e2017-01-25 00:46:09195 scoped_refptr<DecoderBuffer> decoder_buffer = ConvertProtoToDecoderBuffer(
196 segment,
197 DecoderBuffer::CopyFrom(reinterpret_cast<const uint8_t*>(reader.ptr()),
198 buffer_size));
erickung1fc58a42016-09-24 03:00:07199 return decoder_buffer;
200 }
201
erickung1fc58a42016-09-24 03:00:07202 return nullptr;
203}
204
205std::vector<uint8_t> DecoderBufferToByteArray(
miu9f7788e2017-01-25 00:46:09206 const DecoderBuffer& decoder_buffer) {
erickung1fc58a42016-09-24 03:00:07207 pb::DecoderBuffer decoder_buffer_message;
208 ConvertDecoderBufferToProto(decoder_buffer, &decoder_buffer_message);
209
210 size_t decoder_buffer_size =
miu9f7788e2017-01-25 00:46:09211 decoder_buffer.end_of_stream() ? 0 : decoder_buffer.data_size();
erickung1fc58a42016-09-24 03:00:07212 size_t size = kPayloadVersionFieldSize + kProtoBufferHeaderSize +
213 decoder_buffer_message.ByteSize() + kDataBufferHeaderSize +
214 decoder_buffer_size;
215 std::vector<uint8_t> buffer(size);
216 base::BigEndianWriter writer(reinterpret_cast<char*>(buffer.data()),
217 buffer.size());
218 if (writer.WriteU8(0) &&
219 writer.WriteU16(
220 static_cast<uint16_t>(decoder_buffer_message.GetCachedSize())) &&
221 decoder_buffer_message.SerializeToArray(
222 writer.ptr(), decoder_buffer_message.GetCachedSize()) &&
223 writer.Skip(decoder_buffer_message.GetCachedSize()) &&
224 writer.WriteU32(decoder_buffer_size)) {
225 if (decoder_buffer_size) {
226 // DecoderBuffer frame data.
miu9f7788e2017-01-25 00:46:09227 writer.WriteBytes(reinterpret_cast<const void*>(decoder_buffer.data()),
228 decoder_buffer.data_size());
erickung1fc58a42016-09-24 03:00:07229 }
230 return buffer;
231 }
232
miu9f7788e2017-01-25 00:46:09233 NOTREACHED();
erickung1fc58a42016-09-24 03:00:07234 // Reset buffer since serialization of the data failed.
erickung1fc58a42016-09-24 03:00:07235 buffer.clear();
236 return buffer;
237}
238
miu9f7788e2017-01-25 00:46:09239void ConvertEncryptionSchemeToProto(const EncryptionScheme& encryption_scheme,
240 pb::EncryptionScheme* message) {
erickung1fc58a42016-09-24 03:00:07241 DCHECK(message);
242 message->set_mode(
243 ToProtoEncryptionSchemeCipherMode(encryption_scheme.mode()).value());
John Rummell25a00c762018-03-20 18:01:30244 message->set_encrypt_blocks(encryption_scheme.pattern().crypt_byte_block());
245 message->set_skip_blocks(encryption_scheme.pattern().skip_byte_block());
erickung1fc58a42016-09-24 03:00:07246}
247
miu9f7788e2017-01-25 00:46:09248EncryptionScheme ConvertProtoToEncryptionScheme(
erickung1fc58a42016-09-24 03:00:07249 const pb::EncryptionScheme& message) {
miu9f7788e2017-01-25 00:46:09250 return EncryptionScheme(
erickung1fc58a42016-09-24 03:00:07251 ToMediaEncryptionSchemeCipherMode(message.mode()).value(),
John Rummell25a00c762018-03-20 18:01:30252 EncryptionPattern(message.encrypt_blocks(), message.skip_blocks()));
erickung1fc58a42016-09-24 03:00:07253}
254
miu9f7788e2017-01-25 00:46:09255void ConvertAudioDecoderConfigToProto(const AudioDecoderConfig& audio_config,
256 pb::AudioDecoderConfig* audio_message) {
erickung1fc58a42016-09-24 03:00:07257 DCHECK(audio_config.IsValidConfig());
258 DCHECK(audio_message);
259
260 audio_message->set_codec(
261 ToProtoAudioDecoderConfigCodec(audio_config.codec()).value());
262 audio_message->set_sample_format(
263 ToProtoAudioDecoderConfigSampleFormat(audio_config.sample_format())
264 .value());
265 audio_message->set_channel_layout(
266 ToProtoAudioDecoderConfigChannelLayout(audio_config.channel_layout())
267 .value());
268 audio_message->set_samples_per_second(audio_config.samples_per_second());
269 audio_message->set_seek_preroll_usec(
270 audio_config.seek_preroll().InMicroseconds());
271 audio_message->set_codec_delay(audio_config.codec_delay());
272
273 if (!audio_config.extra_data().empty()) {
274 audio_message->set_extra_data(audio_config.extra_data().data(),
275 audio_config.extra_data().size());
276 }
277
278 if (audio_config.is_encrypted()) {
279 pb::EncryptionScheme* encryption_scheme_message =
280 audio_message->mutable_encryption_scheme();
281 ConvertEncryptionSchemeToProto(audio_config.encryption_scheme(),
282 encryption_scheme_message);
283 }
284}
285
286bool ConvertProtoToAudioDecoderConfig(
287 const pb::AudioDecoderConfig& audio_message,
miu9f7788e2017-01-25 00:46:09288 AudioDecoderConfig* audio_config) {
erickung1fc58a42016-09-24 03:00:07289 DCHECK(audio_config);
290 audio_config->Initialize(
291 ToMediaAudioCodec(audio_message.codec()).value(),
292 ToMediaSampleFormat(audio_message.sample_format()).value(),
293 ToMediaChannelLayout(audio_message.channel_layout()).value(),
294 audio_message.samples_per_second(),
295 std::vector<uint8_t>(audio_message.extra_data().begin(),
296 audio_message.extra_data().end()),
297 ConvertProtoToEncryptionScheme(audio_message.encryption_scheme()),
298 base::TimeDelta::FromMicroseconds(audio_message.seek_preroll_usec()),
299 audio_message.codec_delay());
300 return audio_config->IsValidConfig();
301}
302
miu9f7788e2017-01-25 00:46:09303void ConvertVideoDecoderConfigToProto(const VideoDecoderConfig& video_config,
304 pb::VideoDecoderConfig* video_message) {
erickung1fc58a42016-09-24 03:00:07305 DCHECK(video_config.IsValidConfig());
306 DCHECK(video_message);
307
308 video_message->set_codec(
309 ToProtoVideoDecoderConfigCodec(video_config.codec()).value());
310 video_message->set_profile(
311 ToProtoVideoDecoderConfigProfile(video_config.profile()).value());
312 video_message->set_format(
313 ToProtoVideoDecoderConfigFormat(video_config.format()).value());
Fredrik Hubinette5adeaff2018-10-23 21:42:04314
315 // TODO(hubbe): Update proto to use color_space_info()
316 if (video_config.color_space_info() == VideoColorSpace::JPEG()) {
317 video_message->set_color_space(
318 ToProtoVideoDecoderConfigColorSpace(ColorSpace::COLOR_SPACE_JPEG)
319 .value());
320 } else if (video_config.color_space_info() == VideoColorSpace::REC709()) {
321 video_message->set_color_space(
322 ToProtoVideoDecoderConfigColorSpace(ColorSpace::COLOR_SPACE_HD_REC709)
323 .value());
324 } else if (video_config.color_space_info() == VideoColorSpace::REC601()) {
325 video_message->set_color_space(
326 ToProtoVideoDecoderConfigColorSpace(ColorSpace::COLOR_SPACE_SD_REC601)
327 .value());
328 } else {
329 video_message->set_color_space(
330 ToProtoVideoDecoderConfigColorSpace(ColorSpace::COLOR_SPACE_UNSPECIFIED)
331 .value());
332 }
erickung1fc58a42016-09-24 03:00:07333
334 pb::Size* coded_size_message = video_message->mutable_coded_size();
335 coded_size_message->set_width(video_config.coded_size().width());
336 coded_size_message->set_height(video_config.coded_size().height());
337
338 pb::Rect* visible_rect_message = video_message->mutable_visible_rect();
339 visible_rect_message->set_x(video_config.visible_rect().x());
340 visible_rect_message->set_y(video_config.visible_rect().y());
341 visible_rect_message->set_width(video_config.visible_rect().width());
342 visible_rect_message->set_height(video_config.visible_rect().height());
343
344 pb::Size* natural_size_message = video_message->mutable_natural_size();
345 natural_size_message->set_width(video_config.natural_size().width());
346 natural_size_message->set_height(video_config.natural_size().height());
347
348 if (!video_config.extra_data().empty()) {
349 video_message->set_extra_data(video_config.extra_data().data(),
350 video_config.extra_data().size());
351 }
352
353 if (video_config.is_encrypted()) {
354 pb::EncryptionScheme* encryption_scheme_message =
355 video_message->mutable_encryption_scheme();
356 ConvertEncryptionSchemeToProto(video_config.encryption_scheme(),
357 encryption_scheme_message);
358 }
359}
360
361bool ConvertProtoToVideoDecoderConfig(
362 const pb::VideoDecoderConfig& video_message,
miu9f7788e2017-01-25 00:46:09363 VideoDecoderConfig* video_config) {
erickung1fc58a42016-09-24 03:00:07364 DCHECK(video_config);
miu9f7788e2017-01-25 00:46:09365 EncryptionScheme encryption_scheme;
Fredrik Hubinette52583b62018-11-02 23:03:02366
367 // TODO(hubbe): Update pb to use VideoColorSpace
368 VideoColorSpace color_space;
369 switch (video_message.color_space()) {
370 case pb::VideoDecoderConfig::COLOR_SPACE_UNSPECIFIED:
371 break;
372 case pb::VideoDecoderConfig::COLOR_SPACE_JPEG:
373 color_space = VideoColorSpace::JPEG();
374 break;
375 case pb::VideoDecoderConfig::COLOR_SPACE_HD_REC709:
376 color_space = VideoColorSpace::REC709();
377 break;
378 case pb::VideoDecoderConfig::COLOR_SPACE_SD_REC601:
379 color_space = VideoColorSpace::REC601();
380 break;
381 }
erickung1fc58a42016-09-24 03:00:07382 video_config->Initialize(
383 ToMediaVideoCodec(video_message.codec()).value(),
384 ToMediaVideoCodecProfile(video_message.profile()).value(),
Fredrik Hubinette52583b62018-11-02 23:03:02385 ToMediaVideoPixelFormat(video_message.format()).value(), color_space,
386 VIDEO_ROTATION_0,
erickung1fc58a42016-09-24 03:00:07387 gfx::Size(video_message.coded_size().width(),
388 video_message.coded_size().height()),
389 gfx::Rect(video_message.visible_rect().x(),
390 video_message.visible_rect().y(),
391 video_message.visible_rect().width(),
392 video_message.visible_rect().height()),
393 gfx::Size(video_message.natural_size().width(),
394 video_message.natural_size().height()),
395 std::vector<uint8_t>(video_message.extra_data().begin(),
396 video_message.extra_data().end()),
397 ConvertProtoToEncryptionScheme(video_message.encryption_scheme()));
398 return video_config->IsValidConfig();
399}
400
miu9f7788e2017-01-25 00:46:09401void ConvertProtoToPipelineStatistics(
402 const pb::PipelineStatistics& stats_message,
403 PipelineStatistics* stats) {
404 stats->audio_bytes_decoded = stats_message.audio_bytes_decoded();
405 stats->video_bytes_decoded = stats_message.video_bytes_decoded();
406 stats->video_frames_decoded = stats_message.video_frames_decoded();
407 stats->video_frames_dropped = stats_message.video_frames_dropped();
408 stats->audio_memory_usage = stats_message.audio_memory_usage();
409 stats->video_memory_usage = stats_message.video_memory_usage();
410 // HACK: Set the following to prevent "disable video when hidden" logic in
411 // media::blink::WebMediaPlayerImpl.
412 stats->video_keyframe_distance_average = base::TimeDelta::Max();
Chris Cunninghamfe34199b2017-07-07 20:06:45413
Mounir Lamouria8d3ca062017-11-06 16:11:19414 // This field is not used by the rpc field.
415 stats->video_frames_decoded_power_efficient = 0;
416
Dale Curtisc7d2a7d22018-01-11 20:01:05417 // The following fields were added after the initial message definition. Check
418 // that sender provided the values.
419 if (stats_message.has_audio_decoder_name())
420 stats->audio_decoder_name = stats_message.audio_decoder_name();
421 if (stats_message.has_video_decoder_name())
422 stats->video_decoder_name = stats_message.video_decoder_name();
Chris Cunninghamfe34199b2017-07-07 20:06:45423 if (stats_message.has_video_frame_duration_average_usec()) {
424 stats->video_frame_duration_average = base::TimeDelta::FromMicroseconds(
425 stats_message.video_frame_duration_average_usec());
426 }
miu9f7788e2017-01-25 00:46:09427}
428
erickung1fc58a42016-09-24 03:00:07429void ConvertCdmKeyInfoToProto(
miu9f7788e2017-01-25 00:46:09430 const CdmKeysInfo& keys_information,
erickung1fc58a42016-09-24 03:00:07431 pb::CdmClientOnSessionKeysChange* key_change_message) {
xiaofeng.zhang8235be22017-05-21 11:39:34432 for (auto& info : keys_information) {
erickung1fc58a42016-09-24 03:00:07433 pb::CdmKeyInformation* key = key_change_message->add_key_information();
434 key->set_key_id(info->key_id.data(), info->key_id.size());
435 key->set_status(ToProtoCdmKeyInformation(info->status).value());
436 key->set_system_code(info->system_code);
437 }
438}
439
440void ConvertProtoToCdmKeyInfo(
441 const pb::CdmClientOnSessionKeysChange keychange_message,
442 CdmKeysInfo* key_information) {
443 DCHECK(key_information);
444 key_information->reserve(keychange_message.key_information_size());
445 for (int i = 0; i < keychange_message.key_information_size(); ++i) {
446 const pb::CdmKeyInformation key_info_msg =
447 keychange_message.key_information(i);
448
miu9f7788e2017-01-25 00:46:09449 std::unique_ptr<CdmKeyInformation> key(new CdmKeyInformation(
450 key_info_msg.key_id(),
451 ToMediaCdmKeyInformationKeyStatus(key_info_msg.status()).value(),
452 key_info_msg.system_code()));
erickung1fc58a42016-09-24 03:00:07453 key_information->push_back(std::move(key));
454 }
455}
456
457void ConvertCdmPromiseToProto(const CdmPromiseResult& result,
458 pb::CdmPromise* promise_message) {
459 promise_message->set_success(result.success());
460 if (!result.success()) {
461 promise_message->set_exception(
xhwang79b193042016-12-13 18:52:43462 ToProtoCdmException(result.exception()).value());
erickung1fc58a42016-09-24 03:00:07463 promise_message->set_system_code(result.system_code());
464 promise_message->set_error_message(result.error_message());
465 }
466}
467
468void ConvertCdmPromiseWithSessionIdToProto(const CdmPromiseResult& result,
469 const std::string& session_id,
470 pb::CdmPromise* promise_message) {
471 ConvertCdmPromiseToProto(result, promise_message);
472 promise_message->set_session_id(session_id);
473}
474
475void ConvertCdmPromiseWithCdmIdToProto(const CdmPromiseResult& result,
476 int cdm_id,
477 pb::CdmPromise* promise_message) {
478 ConvertCdmPromiseToProto(result, promise_message);
479 promise_message->set_cdm_id(cdm_id);
480}
481
482bool ConvertProtoToCdmPromise(const pb::CdmPromise& promise_message,
483 CdmPromiseResult* result) {
484 if (!promise_message.has_success())
485 return false;
486
487 bool success = promise_message.success();
488 if (success) {
489 *result = CdmPromiseResult::SuccessResult();
490 return true;
491 }
492
John Rummell4ec584b912017-08-15 22:54:25493 CdmPromise::Exception exception = CdmPromise::Exception::NOT_SUPPORTED_ERROR;
erickung1fc58a42016-09-24 03:00:07494 uint32_t system_code = 0;
495 std::string error_message;
496
corona101f1c7d32016-10-27 17:08:10497 exception = ToCdmPromiseException(promise_message.exception()).value();
erickung1fc58a42016-09-24 03:00:07498 system_code = promise_message.system_code();
499 error_message = promise_message.error_message();
500 *result = CdmPromiseResult(exception, system_code, error_message);
501 return true;
502}
503
504bool ConvertProtoToCdmPromiseWithCdmIdSessionId(const pb::RpcMessage& message,
505 CdmPromiseResult* result,
506 int* cdm_id,
507 std::string* session_id) {
508 if (!message.has_cdm_promise_rpc())
509 return false;
510
511 const auto& promise_message = message.cdm_promise_rpc();
512 if (!ConvertProtoToCdmPromise(promise_message, result))
513 return false;
514
515 if (cdm_id)
516 *cdm_id = promise_message.cdm_id();
517 if (session_id)
518 *session_id = promise_message.session_id();
519
520 return true;
521}
522
523//==============================================================================
524CdmPromiseResult::CdmPromiseResult()
John Rummell4ec584b912017-08-15 22:54:25525 : CdmPromiseResult(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "") {}
erickung1fc58a42016-09-24 03:00:07526
miu9f7788e2017-01-25 00:46:09527CdmPromiseResult::CdmPromiseResult(CdmPromise::Exception exception,
erickung1fc58a42016-09-24 03:00:07528 uint32_t system_code,
529 std::string error_message)
530 : success_(false),
531 exception_(exception),
532 system_code_(system_code),
533 error_message_(error_message) {}
534
535CdmPromiseResult::CdmPromiseResult(const CdmPromiseResult& other) = default;
536
537CdmPromiseResult::~CdmPromiseResult() = default;
538
539CdmPromiseResult CdmPromiseResult::SuccessResult() {
miu9f7788e2017-01-25 00:46:09540 CdmPromiseResult result(static_cast<CdmPromise::Exception>(0), 0, "");
erickung1fc58a42016-09-24 03:00:07541 result.success_ = true;
542 return result;
543}
544
545} // namespace remoting
546} // namespace media