blob: 6d34554c08f34dfa16f8f1f0a1db7249e17cc62f [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 &&
Raul Tambref191b592019-01-21 23:56:29187 reader.ReadU16(&proto_size) && proto_size < reader.remaining() &&
erickung1fc58a42016-09-24 03:00:07188 segment.ParseFromArray(reader.ptr(), proto_size) &&
189 reader.Skip(proto_size) && reader.ReadU32(&buffer_size) &&
Raul Tambref191b592019-01-21 23:56:29190 buffer_size <= reader.remaining()) {
erickung1fc58a42016-09-24 03:00:07191 // Deserialize proto buffer. It passes the pre allocated DecoderBuffer into
192 // the function because the proto buffer may overwrite DecoderBuffer since
193 // it may be EOS buffer.
miu9f7788e2017-01-25 00:46:09194 scoped_refptr<DecoderBuffer> decoder_buffer = ConvertProtoToDecoderBuffer(
195 segment,
196 DecoderBuffer::CopyFrom(reinterpret_cast<const uint8_t*>(reader.ptr()),
197 buffer_size));
erickung1fc58a42016-09-24 03:00:07198 return decoder_buffer;
199 }
200
erickung1fc58a42016-09-24 03:00:07201 return nullptr;
202}
203
204std::vector<uint8_t> DecoderBufferToByteArray(
miu9f7788e2017-01-25 00:46:09205 const DecoderBuffer& decoder_buffer) {
erickung1fc58a42016-09-24 03:00:07206 pb::DecoderBuffer decoder_buffer_message;
207 ConvertDecoderBufferToProto(decoder_buffer, &decoder_buffer_message);
208
209 size_t decoder_buffer_size =
miu9f7788e2017-01-25 00:46:09210 decoder_buffer.end_of_stream() ? 0 : decoder_buffer.data_size();
erickung1fc58a42016-09-24 03:00:07211 size_t size = kPayloadVersionFieldSize + kProtoBufferHeaderSize +
212 decoder_buffer_message.ByteSize() + kDataBufferHeaderSize +
213 decoder_buffer_size;
214 std::vector<uint8_t> buffer(size);
215 base::BigEndianWriter writer(reinterpret_cast<char*>(buffer.data()),
216 buffer.size());
217 if (writer.WriteU8(0) &&
218 writer.WriteU16(
219 static_cast<uint16_t>(decoder_buffer_message.GetCachedSize())) &&
220 decoder_buffer_message.SerializeToArray(
221 writer.ptr(), decoder_buffer_message.GetCachedSize()) &&
222 writer.Skip(decoder_buffer_message.GetCachedSize()) &&
223 writer.WriteU32(decoder_buffer_size)) {
224 if (decoder_buffer_size) {
225 // DecoderBuffer frame data.
miu9f7788e2017-01-25 00:46:09226 writer.WriteBytes(reinterpret_cast<const void*>(decoder_buffer.data()),
227 decoder_buffer.data_size());
erickung1fc58a42016-09-24 03:00:07228 }
229 return buffer;
230 }
231
miu9f7788e2017-01-25 00:46:09232 NOTREACHED();
erickung1fc58a42016-09-24 03:00:07233 // Reset buffer since serialization of the data failed.
erickung1fc58a42016-09-24 03:00:07234 buffer.clear();
235 return buffer;
236}
237
miu9f7788e2017-01-25 00:46:09238void ConvertEncryptionSchemeToProto(const EncryptionScheme& encryption_scheme,
239 pb::EncryptionScheme* message) {
erickung1fc58a42016-09-24 03:00:07240 DCHECK(message);
241 message->set_mode(
242 ToProtoEncryptionSchemeCipherMode(encryption_scheme.mode()).value());
John Rummell25a00c762018-03-20 18:01:30243 message->set_encrypt_blocks(encryption_scheme.pattern().crypt_byte_block());
244 message->set_skip_blocks(encryption_scheme.pattern().skip_byte_block());
erickung1fc58a42016-09-24 03:00:07245}
246
miu9f7788e2017-01-25 00:46:09247EncryptionScheme ConvertProtoToEncryptionScheme(
erickung1fc58a42016-09-24 03:00:07248 const pb::EncryptionScheme& message) {
miu9f7788e2017-01-25 00:46:09249 return EncryptionScheme(
erickung1fc58a42016-09-24 03:00:07250 ToMediaEncryptionSchemeCipherMode(message.mode()).value(),
John Rummell25a00c762018-03-20 18:01:30251 EncryptionPattern(message.encrypt_blocks(), message.skip_blocks()));
erickung1fc58a42016-09-24 03:00:07252}
253
miu9f7788e2017-01-25 00:46:09254void ConvertAudioDecoderConfigToProto(const AudioDecoderConfig& audio_config,
255 pb::AudioDecoderConfig* audio_message) {
erickung1fc58a42016-09-24 03:00:07256 DCHECK(audio_config.IsValidConfig());
257 DCHECK(audio_message);
258
259 audio_message->set_codec(
260 ToProtoAudioDecoderConfigCodec(audio_config.codec()).value());
261 audio_message->set_sample_format(
262 ToProtoAudioDecoderConfigSampleFormat(audio_config.sample_format())
263 .value());
264 audio_message->set_channel_layout(
265 ToProtoAudioDecoderConfigChannelLayout(audio_config.channel_layout())
266 .value());
267 audio_message->set_samples_per_second(audio_config.samples_per_second());
268 audio_message->set_seek_preroll_usec(
269 audio_config.seek_preroll().InMicroseconds());
270 audio_message->set_codec_delay(audio_config.codec_delay());
271
272 if (!audio_config.extra_data().empty()) {
273 audio_message->set_extra_data(audio_config.extra_data().data(),
274 audio_config.extra_data().size());
275 }
276
277 if (audio_config.is_encrypted()) {
278 pb::EncryptionScheme* encryption_scheme_message =
279 audio_message->mutable_encryption_scheme();
280 ConvertEncryptionSchemeToProto(audio_config.encryption_scheme(),
281 encryption_scheme_message);
282 }
283}
284
285bool ConvertProtoToAudioDecoderConfig(
286 const pb::AudioDecoderConfig& audio_message,
miu9f7788e2017-01-25 00:46:09287 AudioDecoderConfig* audio_config) {
erickung1fc58a42016-09-24 03:00:07288 DCHECK(audio_config);
289 audio_config->Initialize(
290 ToMediaAudioCodec(audio_message.codec()).value(),
291 ToMediaSampleFormat(audio_message.sample_format()).value(),
292 ToMediaChannelLayout(audio_message.channel_layout()).value(),
293 audio_message.samples_per_second(),
294 std::vector<uint8_t>(audio_message.extra_data().begin(),
295 audio_message.extra_data().end()),
296 ConvertProtoToEncryptionScheme(audio_message.encryption_scheme()),
297 base::TimeDelta::FromMicroseconds(audio_message.seek_preroll_usec()),
298 audio_message.codec_delay());
299 return audio_config->IsValidConfig();
300}
301
miu9f7788e2017-01-25 00:46:09302void ConvertVideoDecoderConfigToProto(const VideoDecoderConfig& video_config,
303 pb::VideoDecoderConfig* video_message) {
erickung1fc58a42016-09-24 03:00:07304 DCHECK(video_config.IsValidConfig());
305 DCHECK(video_message);
306
307 video_message->set_codec(
308 ToProtoVideoDecoderConfigCodec(video_config.codec()).value());
309 video_message->set_profile(
310 ToProtoVideoDecoderConfigProfile(video_config.profile()).value());
Dale Curtis6b3b3baa2019-06-26 22:15:18311 // TODO(dalecurtis): Remove |format| it's now unused.
312 video_message->set_format(video_config.alpha_mode() ==
313 VideoDecoderConfig::AlphaMode::kHasAlpha
314 ? pb::VideoDecoderConfig::PIXEL_FORMAT_I420A
315 : pb::VideoDecoderConfig::PIXEL_FORMAT_I420);
Fredrik Hubinette5adeaff2018-10-23 21:42:04316
317 // TODO(hubbe): Update proto to use color_space_info()
318 if (video_config.color_space_info() == VideoColorSpace::JPEG()) {
Fredrik Hubinette7a83b05c2018-11-07 23:45:05319 video_message->set_color_space(pb::VideoDecoderConfig::COLOR_SPACE_JPEG);
Fredrik Hubinette5adeaff2018-10-23 21:42:04320 } else if (video_config.color_space_info() == VideoColorSpace::REC709()) {
321 video_message->set_color_space(
Fredrik Hubinette7a83b05c2018-11-07 23:45:05322 pb::VideoDecoderConfig::COLOR_SPACE_HD_REC709);
Fredrik Hubinette5adeaff2018-10-23 21:42:04323 } else if (video_config.color_space_info() == VideoColorSpace::REC601()) {
324 video_message->set_color_space(
Fredrik Hubinette7a83b05c2018-11-07 23:45:05325 pb::VideoDecoderConfig::COLOR_SPACE_SD_REC601);
Fredrik Hubinette5adeaff2018-10-23 21:42:04326 } else {
327 video_message->set_color_space(
Fredrik Hubinette7a83b05c2018-11-07 23:45:05328 pb::VideoDecoderConfig::COLOR_SPACE_SD_REC601);
Fredrik Hubinette5adeaff2018-10-23 21:42:04329 }
erickung1fc58a42016-09-24 03:00:07330
331 pb::Size* coded_size_message = video_message->mutable_coded_size();
332 coded_size_message->set_width(video_config.coded_size().width());
333 coded_size_message->set_height(video_config.coded_size().height());
334
335 pb::Rect* visible_rect_message = video_message->mutable_visible_rect();
336 visible_rect_message->set_x(video_config.visible_rect().x());
337 visible_rect_message->set_y(video_config.visible_rect().y());
338 visible_rect_message->set_width(video_config.visible_rect().width());
339 visible_rect_message->set_height(video_config.visible_rect().height());
340
341 pb::Size* natural_size_message = video_message->mutable_natural_size();
342 natural_size_message->set_width(video_config.natural_size().width());
343 natural_size_message->set_height(video_config.natural_size().height());
344
345 if (!video_config.extra_data().empty()) {
346 video_message->set_extra_data(video_config.extra_data().data(),
347 video_config.extra_data().size());
348 }
349
350 if (video_config.is_encrypted()) {
351 pb::EncryptionScheme* encryption_scheme_message =
352 video_message->mutable_encryption_scheme();
353 ConvertEncryptionSchemeToProto(video_config.encryption_scheme(),
354 encryption_scheme_message);
355 }
356}
357
358bool ConvertProtoToVideoDecoderConfig(
359 const pb::VideoDecoderConfig& video_message,
miu9f7788e2017-01-25 00:46:09360 VideoDecoderConfig* video_config) {
erickung1fc58a42016-09-24 03:00:07361 DCHECK(video_config);
miu9f7788e2017-01-25 00:46:09362 EncryptionScheme encryption_scheme;
Fredrik Hubinette52583b62018-11-02 23:03:02363
364 // TODO(hubbe): Update pb to use VideoColorSpace
365 VideoColorSpace color_space;
366 switch (video_message.color_space()) {
367 case pb::VideoDecoderConfig::COLOR_SPACE_UNSPECIFIED:
368 break;
369 case pb::VideoDecoderConfig::COLOR_SPACE_JPEG:
370 color_space = VideoColorSpace::JPEG();
371 break;
372 case pb::VideoDecoderConfig::COLOR_SPACE_HD_REC709:
373 color_space = VideoColorSpace::REC709();
374 break;
375 case pb::VideoDecoderConfig::COLOR_SPACE_SD_REC601:
376 color_space = VideoColorSpace::REC601();
377 break;
378 }
erickung1fc58a42016-09-24 03:00:07379 video_config->Initialize(
380 ToMediaVideoCodec(video_message.codec()).value(),
381 ToMediaVideoCodecProfile(video_message.profile()).value(),
Dale Curtis6b3b3baa2019-06-26 22:15:18382 IsOpaque(ToMediaVideoPixelFormat(video_message.format()).value())
383 ? VideoDecoderConfig::AlphaMode::kIsOpaque
384 : VideoDecoderConfig::AlphaMode::kHasAlpha,
385 color_space, kNoTransformation,
erickung1fc58a42016-09-24 03:00:07386 gfx::Size(video_message.coded_size().width(),
387 video_message.coded_size().height()),
388 gfx::Rect(video_message.visible_rect().x(),
389 video_message.visible_rect().y(),
390 video_message.visible_rect().width(),
391 video_message.visible_rect().height()),
392 gfx::Size(video_message.natural_size().width(),
393 video_message.natural_size().height()),
394 std::vector<uint8_t>(video_message.extra_data().begin(),
395 video_message.extra_data().end()),
396 ConvertProtoToEncryptionScheme(video_message.encryption_scheme()));
397 return video_config->IsValidConfig();
398}
399
miu9f7788e2017-01-25 00:46:09400void ConvertProtoToPipelineStatistics(
401 const pb::PipelineStatistics& stats_message,
402 PipelineStatistics* stats) {
403 stats->audio_bytes_decoded = stats_message.audio_bytes_decoded();
404 stats->video_bytes_decoded = stats_message.video_bytes_decoded();
405 stats->video_frames_decoded = stats_message.video_frames_decoded();
406 stats->video_frames_dropped = stats_message.video_frames_dropped();
407 stats->audio_memory_usage = stats_message.audio_memory_usage();
408 stats->video_memory_usage = stats_message.video_memory_usage();
409 // HACK: Set the following to prevent "disable video when hidden" logic in
410 // media::blink::WebMediaPlayerImpl.
411 stats->video_keyframe_distance_average = base::TimeDelta::Max();
Chris Cunninghamfe34199b2017-07-07 20:06:45412
Mounir Lamouria8d3ca062017-11-06 16:11:19413 // This field is not used by the rpc field.
414 stats->video_frames_decoded_power_efficient = 0;
415
Dale Curtisc7d2a7d22018-01-11 20:01:05416 // The following fields were added after the initial message definition. Check
417 // that sender provided the values.
Ted Meyerd5885f82019-07-16 19:19:17418 if (stats_message.has_audio_decoder_info()) {
419 auto audio_info = stats_message.audio_decoder_info();
420 stats->audio_decoder_info.decoder_name = audio_info.decoder_name();
421 stats->audio_decoder_info.is_platform_decoder =
422 audio_info.is_platform_decoder();
423 stats->audio_decoder_info.is_decrypting_demuxer_stream =
424 audio_info.is_decrypting_demuxer_stream();
425 }
426 if (stats_message.has_video_decoder_info()) {
427 auto video_info = stats_message.video_decoder_info();
428 stats->video_decoder_info.decoder_name = video_info.decoder_name();
429 stats->video_decoder_info.is_platform_decoder =
430 video_info.is_platform_decoder();
431 stats->video_decoder_info.is_decrypting_demuxer_stream =
432 video_info.is_decrypting_demuxer_stream();
433 }
Chris Cunninghamfe34199b2017-07-07 20:06:45434 if (stats_message.has_video_frame_duration_average_usec()) {
435 stats->video_frame_duration_average = base::TimeDelta::FromMicroseconds(
436 stats_message.video_frame_duration_average_usec());
437 }
miu9f7788e2017-01-25 00:46:09438}
439
erickung1fc58a42016-09-24 03:00:07440void ConvertCdmKeyInfoToProto(
miu9f7788e2017-01-25 00:46:09441 const CdmKeysInfo& keys_information,
erickung1fc58a42016-09-24 03:00:07442 pb::CdmClientOnSessionKeysChange* key_change_message) {
xiaofeng.zhang8235be22017-05-21 11:39:34443 for (auto& info : keys_information) {
erickung1fc58a42016-09-24 03:00:07444 pb::CdmKeyInformation* key = key_change_message->add_key_information();
445 key->set_key_id(info->key_id.data(), info->key_id.size());
446 key->set_status(ToProtoCdmKeyInformation(info->status).value());
447 key->set_system_code(info->system_code);
448 }
449}
450
451void ConvertProtoToCdmKeyInfo(
452 const pb::CdmClientOnSessionKeysChange keychange_message,
453 CdmKeysInfo* key_information) {
454 DCHECK(key_information);
455 key_information->reserve(keychange_message.key_information_size());
456 for (int i = 0; i < keychange_message.key_information_size(); ++i) {
457 const pb::CdmKeyInformation key_info_msg =
458 keychange_message.key_information(i);
459
miu9f7788e2017-01-25 00:46:09460 std::unique_ptr<CdmKeyInformation> key(new CdmKeyInformation(
461 key_info_msg.key_id(),
462 ToMediaCdmKeyInformationKeyStatus(key_info_msg.status()).value(),
463 key_info_msg.system_code()));
erickung1fc58a42016-09-24 03:00:07464 key_information->push_back(std::move(key));
465 }
466}
467
468void ConvertCdmPromiseToProto(const CdmPromiseResult& result,
469 pb::CdmPromise* promise_message) {
470 promise_message->set_success(result.success());
471 if (!result.success()) {
472 promise_message->set_exception(
xhwang79b193042016-12-13 18:52:43473 ToProtoCdmException(result.exception()).value());
erickung1fc58a42016-09-24 03:00:07474 promise_message->set_system_code(result.system_code());
475 promise_message->set_error_message(result.error_message());
476 }
477}
478
479void ConvertCdmPromiseWithSessionIdToProto(const CdmPromiseResult& result,
480 const std::string& session_id,
481 pb::CdmPromise* promise_message) {
482 ConvertCdmPromiseToProto(result, promise_message);
483 promise_message->set_session_id(session_id);
484}
485
486void ConvertCdmPromiseWithCdmIdToProto(const CdmPromiseResult& result,
487 int cdm_id,
488 pb::CdmPromise* promise_message) {
489 ConvertCdmPromiseToProto(result, promise_message);
490 promise_message->set_cdm_id(cdm_id);
491}
492
493bool ConvertProtoToCdmPromise(const pb::CdmPromise& promise_message,
494 CdmPromiseResult* result) {
495 if (!promise_message.has_success())
496 return false;
497
498 bool success = promise_message.success();
499 if (success) {
500 *result = CdmPromiseResult::SuccessResult();
501 return true;
502 }
503
John Rummell4ec584b912017-08-15 22:54:25504 CdmPromise::Exception exception = CdmPromise::Exception::NOT_SUPPORTED_ERROR;
erickung1fc58a42016-09-24 03:00:07505 uint32_t system_code = 0;
506 std::string error_message;
507
corona101f1c7d32016-10-27 17:08:10508 exception = ToCdmPromiseException(promise_message.exception()).value();
erickung1fc58a42016-09-24 03:00:07509 system_code = promise_message.system_code();
510 error_message = promise_message.error_message();
511 *result = CdmPromiseResult(exception, system_code, error_message);
512 return true;
513}
514
515bool ConvertProtoToCdmPromiseWithCdmIdSessionId(const pb::RpcMessage& message,
516 CdmPromiseResult* result,
517 int* cdm_id,
518 std::string* session_id) {
519 if (!message.has_cdm_promise_rpc())
520 return false;
521
522 const auto& promise_message = message.cdm_promise_rpc();
523 if (!ConvertProtoToCdmPromise(promise_message, result))
524 return false;
525
526 if (cdm_id)
527 *cdm_id = promise_message.cdm_id();
528 if (session_id)
529 *session_id = promise_message.session_id();
530
531 return true;
532}
533
534//==============================================================================
535CdmPromiseResult::CdmPromiseResult()
John Rummell4ec584b912017-08-15 22:54:25536 : CdmPromiseResult(CdmPromise::Exception::NOT_SUPPORTED_ERROR, 0, "") {}
erickung1fc58a42016-09-24 03:00:07537
miu9f7788e2017-01-25 00:46:09538CdmPromiseResult::CdmPromiseResult(CdmPromise::Exception exception,
erickung1fc58a42016-09-24 03:00:07539 uint32_t system_code,
540 std::string error_message)
541 : success_(false),
542 exception_(exception),
543 system_code_(system_code),
544 error_message_(error_message) {}
545
546CdmPromiseResult::CdmPromiseResult(const CdmPromiseResult& other) = default;
547
548CdmPromiseResult::~CdmPromiseResult() = default;
549
550CdmPromiseResult CdmPromiseResult::SuccessResult() {
miu9f7788e2017-01-25 00:46:09551 CdmPromiseResult result(static_cast<CdmPromise::Exception>(0), 0, "");
erickung1fc58a42016-09-24 03:00:07552 result.success_ = true;
553 return result;
554}
555
556} // namespace remoting
557} // namespace media