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