1 // Copyright 2018 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/cdm/cdm_type_conversion.h"
6
7 #include <stdint.h>
8
9 #include "base/logging.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "ui/gfx/color_space.h"
12 #include "ui/gfx/geometry/size.h"
13
14 // Note: Unexpected values must be handled explicitly since some of these
15 // functions may be used at either side of the CDM interface, and it's possible
16 // invalid values are passed in. For example, Chromium loading an older CDM, or
17 // the CDM is loaded by a non-Chromium browser.
18
19 namespace media {
20
21 namespace {
22
ToCdmColorRange(gfx::ColorSpace::RangeID range)23 cdm::ColorRange ToCdmColorRange(gfx::ColorSpace::RangeID range) {
24 switch (range) {
25 case gfx::ColorSpace::RangeID::INVALID:
26 return cdm::ColorRange::kInvalid;
27 case gfx::ColorSpace::RangeID::LIMITED:
28 return cdm::ColorRange::kLimited;
29 case gfx::ColorSpace::RangeID::FULL:
30 return cdm::ColorRange::kFull;
31 case gfx::ColorSpace::RangeID::DERIVED:
32 return cdm::ColorRange::kDerived;
33 }
34
35 NOTREACHED() << "Unexpected color range";
36 return cdm::ColorRange::kInvalid;
37 }
38
ToGfxColorRange(cdm::ColorRange range)39 gfx::ColorSpace::RangeID ToGfxColorRange(cdm::ColorRange range) {
40 switch (range) {
41 case cdm::ColorRange::kInvalid:
42 return gfx::ColorSpace::RangeID::INVALID;
43 case cdm::ColorRange::kLimited:
44 return gfx::ColorSpace::RangeID::LIMITED;
45 case cdm::ColorRange::kFull:
46 return gfx::ColorSpace::RangeID::FULL;
47 case cdm::ColorRange::kDerived:
48 return gfx::ColorSpace::RangeID::DERIVED;
49 }
50
51 NOTREACHED() << "Unexpected color range";
52 return gfx::ColorSpace::RangeID::INVALID;
53 }
54
55 } // namespace
56
57 // Color Converters
58
ToCdmColorSpace(const VideoColorSpace & color_space)59 cdm::ColorSpace ToCdmColorSpace(const VideoColorSpace& color_space) {
60 // Cast is okay because both VideoColorSpace and cdm::ColorSpace follow the
61 // standard ISO 23001-8:2016.
62 return {base::checked_cast<uint8_t>(color_space.primaries),
63 base::checked_cast<uint8_t>(color_space.transfer),
64 base::checked_cast<uint8_t>(color_space.matrix),
65 ToCdmColorRange(color_space.range)};
66 }
67
ToMediaColorSpace(const cdm::ColorSpace & color_space)68 VideoColorSpace ToMediaColorSpace(const cdm::ColorSpace& color_space) {
69 return VideoColorSpace(color_space.primary_id, color_space.transfer_id,
70 color_space.matrix_id,
71 ToGfxColorRange(color_space.range));
72 }
73
74 // CDM Converters
75
ToCdmHdcpVersion(HdcpVersion hdcp_version)76 cdm::HdcpVersion ToCdmHdcpVersion(HdcpVersion hdcp_version) {
77 switch (hdcp_version) {
78 case HdcpVersion::kHdcpVersionNone:
79 return cdm::kHdcpVersionNone;
80 case HdcpVersion::kHdcpVersion1_0:
81 return cdm::kHdcpVersion1_0;
82 case HdcpVersion::kHdcpVersion1_1:
83 return cdm::kHdcpVersion1_1;
84 case HdcpVersion::kHdcpVersion1_2:
85 return cdm::kHdcpVersion1_2;
86 case HdcpVersion::kHdcpVersion1_3:
87 return cdm::kHdcpVersion1_3;
88 case HdcpVersion::kHdcpVersion1_4:
89 return cdm::kHdcpVersion1_4;
90 case HdcpVersion::kHdcpVersion2_0:
91 return cdm::kHdcpVersion2_0;
92 case HdcpVersion::kHdcpVersion2_1:
93 return cdm::kHdcpVersion2_1;
94 case HdcpVersion::kHdcpVersion2_2:
95 return cdm::kHdcpVersion2_2;
96 case HdcpVersion::kHdcpVersion2_3:
97 return cdm::kHdcpVersion2_3;
98 }
99
100 NOTREACHED() << "Unexpected HdcpVersion";
101 return cdm::kHdcpVersion2_3;
102 }
103
ToCdmSessionType(CdmSessionType session_type)104 cdm::SessionType ToCdmSessionType(CdmSessionType session_type) {
105 switch (session_type) {
106 case CdmSessionType::kTemporary:
107 return cdm::kTemporary;
108 case CdmSessionType::kPersistentLicense:
109 return cdm::kPersistentLicense;
110 case CdmSessionType::kPersistentUsageRecord:
111 return cdm::kPersistentUsageRecord;
112 }
113
114 NOTREACHED() << "Unexpected session type " << static_cast<int>(session_type);
115 return cdm::kTemporary;
116 }
117
ToMediaSessionType(cdm::SessionType session_type)118 CdmSessionType ToMediaSessionType(cdm::SessionType session_type) {
119 switch (session_type) {
120 case cdm::kTemporary:
121 return CdmSessionType::kTemporary;
122 case cdm::kPersistentLicense:
123 return CdmSessionType::kPersistentLicense;
124 case cdm::kPersistentUsageRecord:
125 return CdmSessionType::kPersistentUsageRecord;
126 }
127
128 NOTREACHED() << "Unexpected cdm::SessionType " << session_type;
129 return CdmSessionType::kTemporary;
130 }
131
ToCdmInitDataType(EmeInitDataType init_data_type)132 cdm::InitDataType ToCdmInitDataType(EmeInitDataType init_data_type) {
133 switch (init_data_type) {
134 case EmeInitDataType::CENC:
135 return cdm::kCenc;
136 case EmeInitDataType::KEYIDS:
137 return cdm::kKeyIds;
138 case EmeInitDataType::WEBM:
139 return cdm::kWebM;
140 case EmeInitDataType::UNKNOWN:
141 break;
142 }
143
144 NOTREACHED() << "Unexpected EmeInitDataType";
145 return cdm::kKeyIds;
146 }
147
ToEmeInitDataType(cdm::InitDataType init_data_type)148 EmeInitDataType ToEmeInitDataType(cdm::InitDataType init_data_type) {
149 switch (init_data_type) {
150 case cdm::kCenc:
151 return EmeInitDataType::CENC;
152 case cdm::kKeyIds:
153 return EmeInitDataType::KEYIDS;
154 case cdm::kWebM:
155 return EmeInitDataType::WEBM;
156 }
157
158 NOTREACHED() << "Unexpected cdm::InitDataType " << init_data_type;
159 return EmeInitDataType::UNKNOWN;
160 }
161
ToMediaKeyStatus(cdm::KeyStatus status)162 CdmKeyInformation::KeyStatus ToMediaKeyStatus(cdm::KeyStatus status) {
163 switch (status) {
164 case cdm::kUsable:
165 return CdmKeyInformation::USABLE;
166 case cdm::kInternalError:
167 return CdmKeyInformation::INTERNAL_ERROR;
168 case cdm::kExpired:
169 return CdmKeyInformation::EXPIRED;
170 case cdm::kOutputRestricted:
171 return CdmKeyInformation::OUTPUT_RESTRICTED;
172 case cdm::kOutputDownscaled:
173 return CdmKeyInformation::OUTPUT_DOWNSCALED;
174 case cdm::kStatusPending:
175 return CdmKeyInformation::KEY_STATUS_PENDING;
176 case cdm::kReleased:
177 return CdmKeyInformation::RELEASED;
178 }
179
180 NOTREACHED() << "Unexpected cdm::KeyStatus " << status;
181 return CdmKeyInformation::INTERNAL_ERROR;
182 }
183
ToCdmKeyStatus(CdmKeyInformation::KeyStatus status)184 cdm::KeyStatus ToCdmKeyStatus(CdmKeyInformation::KeyStatus status) {
185 switch (status) {
186 case CdmKeyInformation::KeyStatus::USABLE:
187 return cdm::kUsable;
188 case CdmKeyInformation::KeyStatus::INTERNAL_ERROR:
189 return cdm::kInternalError;
190 case CdmKeyInformation::KeyStatus::EXPIRED:
191 return cdm::kExpired;
192 case CdmKeyInformation::KeyStatus::OUTPUT_RESTRICTED:
193 return cdm::kOutputRestricted;
194 case CdmKeyInformation::KeyStatus::OUTPUT_DOWNSCALED:
195 return cdm::kOutputDownscaled;
196 case CdmKeyInformation::KeyStatus::KEY_STATUS_PENDING:
197 return cdm::kStatusPending;
198 case CdmKeyInformation::KeyStatus::RELEASED:
199 return cdm::kReleased;
200 }
201
202 NOTREACHED() << "Unexpected CdmKeyInformation::KeyStatus " << status;
203 return cdm::kInternalError;
204 }
205
ToCdmEncryptionScheme(EncryptionScheme scheme)206 cdm::EncryptionScheme ToCdmEncryptionScheme(EncryptionScheme scheme) {
207 switch (scheme) {
208 case EncryptionScheme::kUnencrypted:
209 return cdm::EncryptionScheme::kUnencrypted;
210 case EncryptionScheme::kCenc:
211 return cdm::EncryptionScheme::kCenc;
212 case EncryptionScheme::kCbcs:
213 return cdm::EncryptionScheme::kCbcs;
214 }
215
216 NOTREACHED() << "Unexpected EncryptionScheme";
217 return cdm::EncryptionScheme::kUnencrypted;
218 }
219
ToMediaCdmPromiseException(cdm::Exception exception)220 CdmPromise::Exception ToMediaCdmPromiseException(cdm::Exception exception) {
221 switch (exception) {
222 case cdm::kExceptionTypeError:
223 return CdmPromise::Exception::TYPE_ERROR;
224 case cdm::kExceptionNotSupportedError:
225 return CdmPromise::Exception::NOT_SUPPORTED_ERROR;
226 case cdm::kExceptionInvalidStateError:
227 return CdmPromise::Exception::INVALID_STATE_ERROR;
228 case cdm::kExceptionQuotaExceededError:
229 return CdmPromise::Exception::QUOTA_EXCEEDED_ERROR;
230 }
231
232 NOTREACHED() << "Unexpected cdm::Exception " << exception;
233 return CdmPromise::Exception::INVALID_STATE_ERROR;
234 }
235
ToCdmException(CdmPromise::Exception exception)236 cdm::Exception ToCdmException(CdmPromise::Exception exception) {
237 switch (exception) {
238 case CdmPromise::Exception::NOT_SUPPORTED_ERROR:
239 return cdm::kExceptionNotSupportedError;
240 case CdmPromise::Exception::INVALID_STATE_ERROR:
241 return cdm::kExceptionInvalidStateError;
242 case CdmPromise::Exception::TYPE_ERROR:
243 return cdm::kExceptionTypeError;
244 case CdmPromise::Exception::QUOTA_EXCEEDED_ERROR:
245 return cdm::kExceptionQuotaExceededError;
246 }
247
248 NOTREACHED() << "Unexpected CdmPromise::Exception";
249 return cdm::kExceptionInvalidStateError;
250 }
251
ToMediaMessageType(cdm::MessageType message_type)252 CdmMessageType ToMediaMessageType(cdm::MessageType message_type) {
253 switch (message_type) {
254 case cdm::kLicenseRequest:
255 return CdmMessageType::LICENSE_REQUEST;
256 case cdm::kLicenseRenewal:
257 return CdmMessageType::LICENSE_RENEWAL;
258 case cdm::kLicenseRelease:
259 return CdmMessageType::LICENSE_RELEASE;
260 case cdm::kIndividualizationRequest:
261 return CdmMessageType::INDIVIDUALIZATION_REQUEST;
262 }
263
264 NOTREACHED() << "Unexpected cdm::MessageType " << message_type;
265 return CdmMessageType::LICENSE_REQUEST;
266 }
267
ToCdmMessageType(CdmMessageType message_type)268 cdm::MessageType ToCdmMessageType(CdmMessageType message_type) {
269 switch (message_type) {
270 case CdmMessageType::LICENSE_REQUEST:
271 return cdm::kLicenseRequest;
272 case CdmMessageType::LICENSE_RENEWAL:
273 return cdm::kLicenseRenewal;
274 case CdmMessageType::LICENSE_RELEASE:
275 return cdm::kLicenseRelease;
276 case CdmMessageType::INDIVIDUALIZATION_REQUEST:
277 return cdm::kIndividualizationRequest;
278 }
279
280 NOTREACHED() << "Unexpected CdmMessageType";
281 return cdm::kLicenseRequest;
282 }
283
ToCdmStreamType(Decryptor::StreamType stream_type)284 cdm::StreamType ToCdmStreamType(Decryptor::StreamType stream_type) {
285 switch (stream_type) {
286 case Decryptor::kAudio:
287 return cdm::kStreamTypeAudio;
288 case Decryptor::kVideo:
289 return cdm::kStreamTypeVideo;
290 }
291
292 NOTREACHED() << "Unexpected Decryptor::StreamType " << stream_type;
293 return cdm::kStreamTypeVideo;
294 }
295
ToMediaDecryptorStatus(cdm::Status status)296 Decryptor::Status ToMediaDecryptorStatus(cdm::Status status) {
297 switch (status) {
298 case cdm::kSuccess:
299 return Decryptor::kSuccess;
300 case cdm::kNoKey:
301 return Decryptor::kNoKey;
302 case cdm::kNeedMoreData:
303 return Decryptor::kNeedMoreData;
304 case cdm::kDecryptError:
305 return Decryptor::kError;
306 case cdm::kDecodeError:
307 return Decryptor::kError;
308 case cdm::kInitializationError:
309 case cdm::kDeferredInitialization:
310 break;
311 }
312
313 NOTREACHED() << "Unexpected cdm::Status " << status;
314 return Decryptor::kError;
315 }
316
317 // Audio Converters
318
ToCdmAudioCodec(AudioCodec codec)319 cdm::AudioCodec ToCdmAudioCodec(AudioCodec codec) {
320 switch (codec) {
321 case kCodecVorbis:
322 return cdm::kCodecVorbis;
323 case kCodecAAC:
324 return cdm::kCodecAac;
325 default:
326 DVLOG(1) << "Unsupported AudioCodec " << codec;
327 return cdm::kUnknownAudioCodec;
328 }
329 }
330
ToMediaSampleFormat(cdm::AudioFormat format)331 SampleFormat ToMediaSampleFormat(cdm::AudioFormat format) {
332 switch (format) {
333 case cdm::kAudioFormatU8:
334 return kSampleFormatU8;
335 case cdm::kAudioFormatS16:
336 return kSampleFormatS16;
337 case cdm::kAudioFormatS32:
338 return kSampleFormatS32;
339 case cdm::kAudioFormatF32:
340 return kSampleFormatF32;
341 case cdm::kAudioFormatPlanarS16:
342 return kSampleFormatPlanarS16;
343 case cdm::kAudioFormatPlanarF32:
344 return kSampleFormatPlanarF32;
345 case cdm::kUnknownAudioFormat:
346 return kUnknownSampleFormat;
347 }
348
349 NOTREACHED() << "Unexpected cdm::AudioFormat " << format;
350 return kUnknownSampleFormat;
351 }
352
353 // Video Converters
354
ToCdmVideoCodec(VideoCodec codec)355 cdm::VideoCodec ToCdmVideoCodec(VideoCodec codec) {
356 switch (codec) {
357 case kCodecVP8:
358 return cdm::kCodecVp8;
359 case kCodecH264:
360 return cdm::kCodecH264;
361 case kCodecVP9:
362 return cdm::kCodecVp9;
363 case kCodecAV1:
364 return cdm::kCodecAv1;
365 default:
366 DVLOG(1) << "Unsupported VideoCodec " << codec;
367 return cdm::kUnknownVideoCodec;
368 }
369 }
370
ToMediaVideoCodec(cdm::VideoCodec codec)371 VideoCodec ToMediaVideoCodec(cdm::VideoCodec codec) {
372 switch (codec) {
373 case cdm::kUnknownVideoCodec:
374 return kUnknownVideoCodec;
375 case cdm::kCodecVp8:
376 return kCodecVP8;
377 case cdm::kCodecH264:
378 return kCodecH264;
379 case cdm::kCodecVp9:
380 return kCodecVP9;
381 case cdm::kCodecAv1:
382 return kCodecAV1;
383 }
384
385 NOTREACHED() << "Unexpected cdm::VideoCodec " << codec;
386 return kUnknownVideoCodec;
387 }
388
ToCdmVideoCodecProfile(VideoCodecProfile profile)389 cdm::VideoCodecProfile ToCdmVideoCodecProfile(VideoCodecProfile profile) {
390 switch (profile) {
391 case VP8PROFILE_ANY:
392 return cdm::kProfileNotNeeded;
393 case VP9PROFILE_PROFILE0:
394 return cdm::kVP9Profile0;
395 case VP9PROFILE_PROFILE1:
396 return cdm::kVP9Profile1;
397 case VP9PROFILE_PROFILE2:
398 return cdm::kVP9Profile2;
399 case VP9PROFILE_PROFILE3:
400 return cdm::kVP9Profile3;
401 case H264PROFILE_BASELINE:
402 return cdm::kH264ProfileBaseline;
403 case H264PROFILE_MAIN:
404 return cdm::kH264ProfileMain;
405 case H264PROFILE_EXTENDED:
406 return cdm::kH264ProfileExtended;
407 case H264PROFILE_HIGH:
408 return cdm::kH264ProfileHigh;
409 case H264PROFILE_HIGH10PROFILE:
410 return cdm::kH264ProfileHigh10;
411 case H264PROFILE_HIGH422PROFILE:
412 return cdm::kH264ProfileHigh422;
413 case H264PROFILE_HIGH444PREDICTIVEPROFILE:
414 return cdm::kH264ProfileHigh444Predictive;
415 case AV1PROFILE_PROFILE_MAIN:
416 return cdm::kAv1ProfileMain;
417 case AV1PROFILE_PROFILE_HIGH:
418 return cdm::kAv1ProfileHigh;
419 case AV1PROFILE_PROFILE_PRO:
420 return cdm::kAv1ProfilePro;
421 default:
422 DVLOG(1) << "Unsupported VideoCodecProfile " << profile;
423 return cdm::kUnknownVideoCodecProfile;
424 }
425 }
426
ToMediaVideoCodecProfile(cdm::VideoCodecProfile profile)427 VideoCodecProfile ToMediaVideoCodecProfile(cdm::VideoCodecProfile profile) {
428 switch (profile) {
429 case cdm::kUnknownVideoCodecProfile:
430 return VIDEO_CODEC_PROFILE_UNKNOWN;
431 case cdm::kProfileNotNeeded:
432 // There's no corresponding value for "not needed". Given CdmAdapter only
433 // converts VP8PROFILE_ANY to cdm::kProfileNotNeeded, and this code is
434 // only used for testing, it's okay to convert it back to VP8PROFILE_ANY.
435 return VP8PROFILE_ANY;
436 case cdm::kVP9Profile0:
437 return VP9PROFILE_PROFILE0;
438 case cdm::kVP9Profile1:
439 return VP9PROFILE_PROFILE1;
440 case cdm::kVP9Profile2:
441 return VP9PROFILE_PROFILE2;
442 case cdm::kVP9Profile3:
443 return VP9PROFILE_PROFILE3;
444 case cdm::kH264ProfileBaseline:
445 return H264PROFILE_BASELINE;
446 case cdm::kH264ProfileMain:
447 return H264PROFILE_MAIN;
448 case cdm::kH264ProfileExtended:
449 return H264PROFILE_EXTENDED;
450 case cdm::kH264ProfileHigh:
451 return H264PROFILE_HIGH;
452 case cdm::kH264ProfileHigh10:
453 return H264PROFILE_HIGH10PROFILE;
454 case cdm::kH264ProfileHigh422:
455 return H264PROFILE_HIGH422PROFILE;
456 case cdm::kH264ProfileHigh444Predictive:
457 return H264PROFILE_HIGH444PREDICTIVEPROFILE;
458 case cdm::kAv1ProfileMain:
459 return AV1PROFILE_PROFILE_MAIN;
460 case cdm::kAv1ProfileHigh:
461 return AV1PROFILE_PROFILE_HIGH;
462 case cdm::kAv1ProfilePro:
463 return AV1PROFILE_PROFILE_PRO;
464 }
465
466 NOTREACHED() << "Unexpected cdm::VideoCodecProfile " << profile;
467 return VIDEO_CODEC_PROFILE_UNKNOWN;
468 }
469
ToCdmVideoFormat(VideoPixelFormat format)470 cdm::VideoFormat ToCdmVideoFormat(VideoPixelFormat format) {
471 switch (format) {
472 case PIXEL_FORMAT_YV12:
473 return cdm::kYv12;
474 case PIXEL_FORMAT_I420:
475 return cdm::kI420;
476 case PIXEL_FORMAT_YUV420P9:
477 return cdm::kYUV420P9;
478 case PIXEL_FORMAT_YUV420P10:
479 return cdm::kYUV420P10;
480 case PIXEL_FORMAT_YUV422P9:
481 return cdm::kYUV422P9;
482 case PIXEL_FORMAT_YUV422P10:
483 return cdm::kYUV422P10;
484 case PIXEL_FORMAT_YUV444P9:
485 return cdm::kYUV444P9;
486 case PIXEL_FORMAT_YUV444P10:
487 return cdm::kYUV444P10;
488 case PIXEL_FORMAT_YUV420P12:
489 return cdm::kYUV420P12;
490 case PIXEL_FORMAT_YUV422P12:
491 return cdm::kYUV422P12;
492 case PIXEL_FORMAT_YUV444P12:
493 return cdm::kYUV444P12;
494 default:
495 DVLOG(1) << "Unsupported VideoPixelFormat " << format;
496 return cdm::kUnknownVideoFormat;
497 }
498 }
499
ToMediaVideoFormat(cdm::VideoFormat format)500 VideoPixelFormat ToMediaVideoFormat(cdm::VideoFormat format) {
501 switch (format) {
502 case cdm::kYv12:
503 return PIXEL_FORMAT_YV12;
504 case cdm::kI420:
505 return PIXEL_FORMAT_I420;
506 case cdm::kYUV420P9:
507 return PIXEL_FORMAT_YUV420P9;
508 case cdm::kYUV420P10:
509 return PIXEL_FORMAT_YUV420P10;
510 case cdm::kYUV422P9:
511 return PIXEL_FORMAT_YUV422P9;
512 case cdm::kYUV422P10:
513 return PIXEL_FORMAT_YUV422P10;
514 case cdm::kYUV444P9:
515 return PIXEL_FORMAT_YUV444P9;
516 case cdm::kYUV444P10:
517 return PIXEL_FORMAT_YUV444P10;
518 case cdm::kYUV420P12:
519 return PIXEL_FORMAT_YUV420P12;
520 case cdm::kYUV422P12:
521 return PIXEL_FORMAT_YUV422P12;
522 case cdm::kYUV444P12:
523 return PIXEL_FORMAT_YUV444P12;
524 default:
525 DVLOG(1) << "Unsupported cdm::VideoFormat " << format;
526 return PIXEL_FORMAT_UNKNOWN;
527 }
528 }
529
530 // Aggregate Types
531
532 // Warning: The returned config contains raw pointers to the extra data in the
533 // input |config|. Hence, the caller must make sure the input |config| outlives
534 // the returned config.
ToCdmAudioDecoderConfig(const AudioDecoderConfig & config)535 cdm::AudioDecoderConfig_2 ToCdmAudioDecoderConfig(
536 const AudioDecoderConfig& config) {
537 cdm::AudioDecoderConfig_2 cdm_config = {};
538 cdm_config.codec = ToCdmAudioCodec(config.codec());
539 cdm_config.channel_count =
540 ChannelLayoutToChannelCount(config.channel_layout());
541 cdm_config.bits_per_channel = config.bits_per_channel();
542 cdm_config.samples_per_second = config.samples_per_second();
543 cdm_config.extra_data = const_cast<uint8_t*>(config.extra_data().data());
544 cdm_config.extra_data_size = config.extra_data().size();
545 cdm_config.encryption_scheme =
546 ToCdmEncryptionScheme(config.encryption_scheme());
547 return cdm_config;
548 }
549
550 // Warning: The returned config contains raw pointers to the extra data in the
551 // input |config|. Hence, the caller must make sure the input |config| outlives
552 // the returned config.
ToCdmVideoDecoderConfig(const VideoDecoderConfig & config)553 cdm::VideoDecoderConfig_3 ToCdmVideoDecoderConfig(
554 const VideoDecoderConfig& config) {
555 cdm::VideoDecoderConfig_3 cdm_config = {};
556 cdm_config.codec = ToCdmVideoCodec(config.codec());
557 cdm_config.profile = ToCdmVideoCodecProfile(config.profile());
558
559 // TODO(dalecurtis): CDM doesn't support alpha, so delete |format|.
560 DCHECK_EQ(config.alpha_mode(), VideoDecoderConfig::AlphaMode::kIsOpaque);
561 cdm_config.format = cdm::kI420;
562
563 cdm_config.color_space = ToCdmColorSpace(config.color_space_info());
564 cdm_config.coded_size.width = config.coded_size().width();
565 cdm_config.coded_size.height = config.coded_size().height();
566 cdm_config.extra_data = const_cast<uint8_t*>(config.extra_data().data());
567 cdm_config.extra_data_size = config.extra_data().size();
568 cdm_config.encryption_scheme =
569 ToCdmEncryptionScheme(config.encryption_scheme());
570 return cdm_config;
571 }
572
573 // Fill |input_buffer| based on the values in |encrypted|. |subsamples|
574 // is used to hold some of the data. |input_buffer| will contain pointers
575 // to data contained in |encrypted| and |subsamples|, so the lifetime of
576 // |input_buffer| must be <= the lifetime of |encrypted| and |subsamples|.
ToCdmInputBuffer(const DecoderBuffer & encrypted_buffer,std::vector<cdm::SubsampleEntry> * subsamples,cdm::InputBuffer_2 * input_buffer)577 void ToCdmInputBuffer(const DecoderBuffer& encrypted_buffer,
578 std::vector<cdm::SubsampleEntry>* subsamples,
579 cdm::InputBuffer_2* input_buffer) {
580 // End of stream buffers are represented as empty resources.
581 DCHECK(!input_buffer->data);
582 if (encrypted_buffer.end_of_stream())
583 return;
584
585 input_buffer->data = encrypted_buffer.data();
586 input_buffer->data_size = encrypted_buffer.data_size();
587 input_buffer->timestamp = encrypted_buffer.timestamp().InMicroseconds();
588
589 const DecryptConfig* decrypt_config = encrypted_buffer.decrypt_config();
590 if (!decrypt_config) {
591 DVLOG(2) << __func__ << ": Clear buffer.";
592 return;
593 }
594
595 input_buffer->key_id =
596 reinterpret_cast<const uint8_t*>(decrypt_config->key_id().data());
597 input_buffer->key_id_size = decrypt_config->key_id().size();
598 input_buffer->iv =
599 reinterpret_cast<const uint8_t*>(decrypt_config->iv().data());
600 input_buffer->iv_size = decrypt_config->iv().size();
601
602 DCHECK(subsamples->empty());
603 size_t num_subsamples = decrypt_config->subsamples().size();
604 if (num_subsamples > 0) {
605 subsamples->reserve(num_subsamples);
606 for (const auto& sample : decrypt_config->subsamples()) {
607 subsamples->push_back({sample.clear_bytes, sample.cypher_bytes});
608 }
609 }
610
611 input_buffer->subsamples = subsamples->data();
612 input_buffer->num_subsamples = num_subsamples;
613
614 input_buffer->encryption_scheme =
615 ToCdmEncryptionScheme(decrypt_config->encryption_scheme());
616 if (decrypt_config->HasPattern()) {
617 input_buffer->pattern = {
618 decrypt_config->encryption_pattern()->crypt_byte_block(),
619 decrypt_config->encryption_pattern()->skip_byte_block()};
620 }
621 }
622
623 } // namespace media
624