| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "media/cdm/cdm_type_conversion.h" |
| |
| #include <stdint.h> |
| |
| #include "base/logging.h" |
| #include "base/numerics/safe_conversions.h" |
| #include "ui/gfx/color_space.h" |
| #include "ui/gfx/geometry/size.h" |
| |
| // Note: Unexpected values must be handled explicitly since some of these |
| // functions may be used at either side of the CDM interface, and it's possible |
| // invalid values are passed in. For example, Chromium loading an older CDM, or |
| // the CDM is loaded by a non-Chromium browser. |
| |
| namespace media { |
| |
| namespace { |
| |
| cdm::ColorRange ToCdmColorRange(gfx::ColorSpace::RangeID range) { |
| switch (range) { |
| case gfx::ColorSpace::RangeID::INVALID: |
| return cdm::ColorRange::kInvalid; |
| case gfx::ColorSpace::RangeID::LIMITED: |
| return cdm::ColorRange::kLimited; |
| case gfx::ColorSpace::RangeID::FULL: |
| return cdm::ColorRange::kFull; |
| case gfx::ColorSpace::RangeID::DERIVED: |
| return cdm::ColorRange::kDerived; |
| } |
| |
| NOTREACHED() << "Unexpected color range"; |
| return cdm::ColorRange::kInvalid; |
| } |
| |
| gfx::ColorSpace::RangeID ToGfxColorRange(cdm::ColorRange range) { |
| switch (range) { |
| case cdm::ColorRange::kInvalid: |
| return gfx::ColorSpace::RangeID::INVALID; |
| case cdm::ColorRange::kLimited: |
| return gfx::ColorSpace::RangeID::LIMITED; |
| case cdm::ColorRange::kFull: |
| return gfx::ColorSpace::RangeID::FULL; |
| case cdm::ColorRange::kDerived: |
| return gfx::ColorSpace::RangeID::DERIVED; |
| } |
| |
| NOTREACHED() << "Unexpected color range"; |
| return gfx::ColorSpace::RangeID::INVALID; |
| } |
| |
| } // namespace |
| |
| // Color Converters |
| |
| cdm::ColorSpace ToCdmColorSpace(const VideoColorSpace& color_space) { |
| // Cast is okay because both VideoColorSpace and cdm::ColorSpace follow the |
| // standard ISO 23001-8:2016. |
| return {base::checked_cast<uint8_t>(color_space.primaries), |
| base::checked_cast<uint8_t>(color_space.transfer), |
| base::checked_cast<uint8_t>(color_space.matrix), |
| ToCdmColorRange(color_space.range)}; |
| } |
| |
| VideoColorSpace ToMediaColorSpace(const cdm::ColorSpace& color_space) { |
| return VideoColorSpace(color_space.primary_id, color_space.transfer_id, |
| color_space.matrix_id, |
| ToGfxColorRange(color_space.range)); |
| } |
| |
| // CDM Converters |
| |
| cdm::HdcpVersion ToCdmHdcpVersion(HdcpVersion hdcp_version) { |
| switch (hdcp_version) { |
| case HdcpVersion::kHdcpVersionNone: |
| return cdm::kHdcpVersionNone; |
| case HdcpVersion::kHdcpVersion1_0: |
| return cdm::kHdcpVersion1_0; |
| case HdcpVersion::kHdcpVersion1_1: |
| return cdm::kHdcpVersion1_1; |
| case HdcpVersion::kHdcpVersion1_2: |
| return cdm::kHdcpVersion1_2; |
| case HdcpVersion::kHdcpVersion1_3: |
| return cdm::kHdcpVersion1_3; |
| case HdcpVersion::kHdcpVersion1_4: |
| return cdm::kHdcpVersion1_4; |
| case HdcpVersion::kHdcpVersion2_0: |
| return cdm::kHdcpVersion2_0; |
| case HdcpVersion::kHdcpVersion2_1: |
| return cdm::kHdcpVersion2_1; |
| case HdcpVersion::kHdcpVersion2_2: |
| return cdm::kHdcpVersion2_2; |
| case HdcpVersion::kHdcpVersion2_3: |
| return cdm::kHdcpVersion2_3; |
| } |
| |
| NOTREACHED() << "Unexpected HdcpVersion"; |
| return cdm::kHdcpVersion2_3; |
| } |
| |
| cdm::SessionType ToCdmSessionType(CdmSessionType session_type) { |
| switch (session_type) { |
| case CdmSessionType::kTemporary: |
| return cdm::kTemporary; |
| case CdmSessionType::kPersistentLicense: |
| return cdm::kPersistentLicense; |
| case CdmSessionType::kPersistentUsageRecord: |
| return cdm::kPersistentUsageRecord; |
| } |
| |
| NOTREACHED() << "Unexpected session type " << static_cast<int>(session_type); |
| return cdm::kTemporary; |
| } |
| |
| CdmSessionType ToMediaSessionType(cdm::SessionType session_type) { |
| switch (session_type) { |
| case cdm::kTemporary: |
| return CdmSessionType::kTemporary; |
| case cdm::kPersistentLicense: |
| return CdmSessionType::kPersistentLicense; |
| case cdm::kPersistentUsageRecord: |
| return CdmSessionType::kPersistentUsageRecord; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::SessionType " << session_type; |
| return CdmSessionType::kTemporary; |
| } |
| |
| cdm::InitDataType ToCdmInitDataType(EmeInitDataType init_data_type) { |
| switch (init_data_type) { |
| case EmeInitDataType::CENC: |
| return cdm::kCenc; |
| case EmeInitDataType::KEYIDS: |
| return cdm::kKeyIds; |
| case EmeInitDataType::WEBM: |
| return cdm::kWebM; |
| case EmeInitDataType::UNKNOWN: |
| break; |
| } |
| |
| NOTREACHED() << "Unexpected EmeInitDataType"; |
| return cdm::kKeyIds; |
| } |
| |
| EmeInitDataType ToEmeInitDataType(cdm::InitDataType init_data_type) { |
| switch (init_data_type) { |
| case cdm::kCenc: |
| return EmeInitDataType::CENC; |
| case cdm::kKeyIds: |
| return EmeInitDataType::KEYIDS; |
| case cdm::kWebM: |
| return EmeInitDataType::WEBM; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::InitDataType " << init_data_type; |
| return EmeInitDataType::UNKNOWN; |
| } |
| |
| CdmKeyInformation::KeyStatus ToMediaKeyStatus(cdm::KeyStatus status) { |
| switch (status) { |
| case cdm::kUsable: |
| return CdmKeyInformation::USABLE; |
| case cdm::kInternalError: |
| return CdmKeyInformation::INTERNAL_ERROR; |
| case cdm::kExpired: |
| return CdmKeyInformation::EXPIRED; |
| case cdm::kOutputRestricted: |
| return CdmKeyInformation::OUTPUT_RESTRICTED; |
| case cdm::kOutputDownscaled: |
| return CdmKeyInformation::OUTPUT_DOWNSCALED; |
| case cdm::kStatusPending: |
| return CdmKeyInformation::KEY_STATUS_PENDING; |
| case cdm::kReleased: |
| return CdmKeyInformation::RELEASED; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::KeyStatus " << status; |
| return CdmKeyInformation::INTERNAL_ERROR; |
| } |
| |
| cdm::KeyStatus ToCdmKeyStatus(CdmKeyInformation::KeyStatus status) { |
| switch (status) { |
| case CdmKeyInformation::KeyStatus::USABLE: |
| return cdm::kUsable; |
| case CdmKeyInformation::KeyStatus::INTERNAL_ERROR: |
| return cdm::kInternalError; |
| case CdmKeyInformation::KeyStatus::EXPIRED: |
| return cdm::kExpired; |
| case CdmKeyInformation::KeyStatus::OUTPUT_RESTRICTED: |
| return cdm::kOutputRestricted; |
| case CdmKeyInformation::KeyStatus::OUTPUT_DOWNSCALED: |
| return cdm::kOutputDownscaled; |
| case CdmKeyInformation::KeyStatus::KEY_STATUS_PENDING: |
| return cdm::kStatusPending; |
| case CdmKeyInformation::KeyStatus::RELEASED: |
| return cdm::kReleased; |
| } |
| |
| NOTREACHED() << "Unexpected CdmKeyInformation::KeyStatus " << status; |
| return cdm::kInternalError; |
| } |
| |
| cdm::EncryptionScheme ToCdmEncryptionScheme(const EncryptionScheme& scheme) { |
| switch (scheme.mode()) { |
| case EncryptionScheme::CIPHER_MODE_UNENCRYPTED: |
| return cdm::EncryptionScheme::kUnencrypted; |
| case EncryptionScheme::CIPHER_MODE_AES_CTR: |
| return cdm::EncryptionScheme::kCenc; |
| case EncryptionScheme::CIPHER_MODE_AES_CBC: |
| return cdm::EncryptionScheme::kCbcs; |
| } |
| |
| NOTREACHED() << "Unexpected EncryptionScheme mode " << scheme.mode(); |
| return cdm::EncryptionScheme::kUnencrypted; |
| } |
| |
| cdm::EncryptionScheme ToCdmEncryptionScheme(const EncryptionMode& mode) { |
| switch (mode) { |
| case EncryptionMode::kUnencrypted: |
| return cdm::EncryptionScheme::kUnencrypted; |
| case EncryptionMode::kCenc: |
| return cdm::EncryptionScheme::kCenc; |
| case EncryptionMode::kCbcs: |
| return cdm::EncryptionScheme::kCbcs; |
| } |
| |
| NOTREACHED() << "Unexpected EncryptionMode"; |
| return cdm::EncryptionScheme::kUnencrypted; |
| } |
| |
| CdmPromise::Exception ToMediaCdmPromiseException(cdm::Exception exception) { |
| switch (exception) { |
| case cdm::kExceptionTypeError: |
| return CdmPromise::Exception::TYPE_ERROR; |
| case cdm::kExceptionNotSupportedError: |
| return CdmPromise::Exception::NOT_SUPPORTED_ERROR; |
| case cdm::kExceptionInvalidStateError: |
| return CdmPromise::Exception::INVALID_STATE_ERROR; |
| case cdm::kExceptionQuotaExceededError: |
| return CdmPromise::Exception::QUOTA_EXCEEDED_ERROR; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::Exception " << exception; |
| return CdmPromise::Exception::INVALID_STATE_ERROR; |
| } |
| |
| cdm::Exception ToCdmException(CdmPromise::Exception exception) { |
| switch (exception) { |
| case CdmPromise::Exception::NOT_SUPPORTED_ERROR: |
| return cdm::kExceptionNotSupportedError; |
| case CdmPromise::Exception::INVALID_STATE_ERROR: |
| return cdm::kExceptionInvalidStateError; |
| case CdmPromise::Exception::TYPE_ERROR: |
| return cdm::kExceptionTypeError; |
| case CdmPromise::Exception::QUOTA_EXCEEDED_ERROR: |
| return cdm::kExceptionQuotaExceededError; |
| } |
| |
| NOTREACHED() << "Unexpected CdmPromise::Exception"; |
| return cdm::kExceptionInvalidStateError; |
| } |
| |
| CdmMessageType ToMediaMessageType(cdm::MessageType message_type) { |
| switch (message_type) { |
| case cdm::kLicenseRequest: |
| return CdmMessageType::LICENSE_REQUEST; |
| case cdm::kLicenseRenewal: |
| return CdmMessageType::LICENSE_RENEWAL; |
| case cdm::kLicenseRelease: |
| return CdmMessageType::LICENSE_RELEASE; |
| case cdm::kIndividualizationRequest: |
| return CdmMessageType::INDIVIDUALIZATION_REQUEST; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::MessageType " << message_type; |
| return CdmMessageType::LICENSE_REQUEST; |
| } |
| |
| cdm::MessageType ToCdmMessageType(CdmMessageType message_type) { |
| switch (message_type) { |
| case CdmMessageType::LICENSE_REQUEST: |
| return cdm::kLicenseRequest; |
| case CdmMessageType::LICENSE_RENEWAL: |
| return cdm::kLicenseRenewal; |
| case CdmMessageType::LICENSE_RELEASE: |
| return cdm::kLicenseRelease; |
| case CdmMessageType::INDIVIDUALIZATION_REQUEST: |
| return cdm::kIndividualizationRequest; |
| } |
| |
| NOTREACHED() << "Unexpected CdmMessageType"; |
| return cdm::kLicenseRequest; |
| } |
| |
| cdm::StreamType ToCdmStreamType(Decryptor::StreamType stream_type) { |
| switch (stream_type) { |
| case Decryptor::kAudio: |
| return cdm::kStreamTypeAudio; |
| case Decryptor::kVideo: |
| return cdm::kStreamTypeVideo; |
| } |
| |
| NOTREACHED() << "Unexpected Decryptor::StreamType " << stream_type; |
| return cdm::kStreamTypeVideo; |
| } |
| |
| Decryptor::Status ToMediaDecryptorStatus(cdm::Status status) { |
| switch (status) { |
| case cdm::kSuccess: |
| return Decryptor::kSuccess; |
| case cdm::kNoKey: |
| return Decryptor::kNoKey; |
| case cdm::kNeedMoreData: |
| return Decryptor::kNeedMoreData; |
| case cdm::kDecryptError: |
| return Decryptor::kError; |
| case cdm::kDecodeError: |
| return Decryptor::kError; |
| case cdm::kInitializationError: |
| case cdm::kDeferredInitialization: |
| break; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::Status " << status; |
| return Decryptor::kError; |
| } |
| |
| // Audio Converters |
| |
| cdm::AudioCodec ToCdmAudioCodec(AudioCodec codec) { |
| switch (codec) { |
| case kCodecVorbis: |
| return cdm::kCodecVorbis; |
| case kCodecAAC: |
| return cdm::kCodecAac; |
| default: |
| DVLOG(1) << "Unsupported AudioCodec " << codec; |
| return cdm::kUnknownAudioCodec; |
| } |
| } |
| |
| SampleFormat ToMediaSampleFormat(cdm::AudioFormat format) { |
| switch (format) { |
| case cdm::kAudioFormatU8: |
| return kSampleFormatU8; |
| case cdm::kAudioFormatS16: |
| return kSampleFormatS16; |
| case cdm::kAudioFormatS32: |
| return kSampleFormatS32; |
| case cdm::kAudioFormatF32: |
| return kSampleFormatF32; |
| case cdm::kAudioFormatPlanarS16: |
| return kSampleFormatPlanarS16; |
| case cdm::kAudioFormatPlanarF32: |
| return kSampleFormatPlanarF32; |
| case cdm::kUnknownAudioFormat: |
| return kUnknownSampleFormat; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::AudioFormat " << format; |
| return kUnknownSampleFormat; |
| } |
| |
| // Video Converters |
| |
| cdm::VideoCodec ToCdmVideoCodec(VideoCodec codec) { |
| switch (codec) { |
| case kCodecVP8: |
| return cdm::kCodecVp8; |
| case kCodecH264: |
| return cdm::kCodecH264; |
| case kCodecVP9: |
| return cdm::kCodecVp9; |
| case kCodecAV1: |
| return cdm::kCodecAv1; |
| default: |
| DVLOG(1) << "Unsupported VideoCodec " << codec; |
| return cdm::kUnknownVideoCodec; |
| } |
| } |
| |
| VideoCodec ToMediaVideoCodec(cdm::VideoCodec codec) { |
| switch (codec) { |
| case cdm::kUnknownVideoCodec: |
| return kUnknownVideoCodec; |
| case cdm::kCodecVp8: |
| return kCodecVP8; |
| case cdm::kCodecH264: |
| return kCodecH264; |
| case cdm::kCodecVp9: |
| return kCodecVP9; |
| case cdm::kCodecAv1: |
| return kCodecAV1; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::VideoCodec " << codec; |
| return kUnknownVideoCodec; |
| } |
| |
| cdm::VideoCodecProfile ToCdmVideoCodecProfile(VideoCodecProfile profile) { |
| switch (profile) { |
| case VP8PROFILE_ANY: |
| return cdm::kProfileNotNeeded; |
| case VP9PROFILE_PROFILE0: |
| return cdm::kVP9Profile0; |
| case VP9PROFILE_PROFILE1: |
| return cdm::kVP9Profile1; |
| case VP9PROFILE_PROFILE2: |
| return cdm::kVP9Profile2; |
| case VP9PROFILE_PROFILE3: |
| return cdm::kVP9Profile3; |
| case H264PROFILE_BASELINE: |
| return cdm::kH264ProfileBaseline; |
| case H264PROFILE_MAIN: |
| return cdm::kH264ProfileMain; |
| case H264PROFILE_EXTENDED: |
| return cdm::kH264ProfileExtended; |
| case H264PROFILE_HIGH: |
| return cdm::kH264ProfileHigh; |
| case H264PROFILE_HIGH10PROFILE: |
| return cdm::kH264ProfileHigh10; |
| case H264PROFILE_HIGH422PROFILE: |
| return cdm::kH264ProfileHigh422; |
| case H264PROFILE_HIGH444PREDICTIVEPROFILE: |
| return cdm::kH264ProfileHigh444Predictive; |
| case AV1PROFILE_PROFILE_MAIN: |
| return cdm::kAv1ProfileMain; |
| case AV1PROFILE_PROFILE_HIGH: |
| return cdm::kAv1ProfileHigh; |
| case AV1PROFILE_PROFILE_PRO: |
| return cdm::kAv1ProfilePro; |
| default: |
| DVLOG(1) << "Unsupported VideoCodecProfile " << profile; |
| return cdm::kUnknownVideoCodecProfile; |
| } |
| } |
| |
| VideoCodecProfile ToMediaVideoCodecProfile(cdm::VideoCodecProfile profile) { |
| switch (profile) { |
| case cdm::kUnknownVideoCodecProfile: |
| return VIDEO_CODEC_PROFILE_UNKNOWN; |
| case cdm::kProfileNotNeeded: |
| // There's no corresponding value for "not needed". Given CdmAdapter only |
| // converts VP8PROFILE_ANY to cdm::kProfileNotNeeded, and this code is |
| // only used for testing, it's okay to convert it back to VP8PROFILE_ANY. |
| return VP8PROFILE_ANY; |
| case cdm::kVP9Profile0: |
| return VP9PROFILE_PROFILE0; |
| case cdm::kVP9Profile1: |
| return VP9PROFILE_PROFILE1; |
| case cdm::kVP9Profile2: |
| return VP9PROFILE_PROFILE2; |
| case cdm::kVP9Profile3: |
| return VP9PROFILE_PROFILE3; |
| case cdm::kH264ProfileBaseline: |
| return H264PROFILE_BASELINE; |
| case cdm::kH264ProfileMain: |
| return H264PROFILE_MAIN; |
| case cdm::kH264ProfileExtended: |
| return H264PROFILE_EXTENDED; |
| case cdm::kH264ProfileHigh: |
| return H264PROFILE_HIGH; |
| case cdm::kH264ProfileHigh10: |
| return H264PROFILE_HIGH10PROFILE; |
| case cdm::kH264ProfileHigh422: |
| return H264PROFILE_HIGH422PROFILE; |
| case cdm::kH264ProfileHigh444Predictive: |
| return H264PROFILE_HIGH444PREDICTIVEPROFILE; |
| case cdm::kAv1ProfileMain: |
| return AV1PROFILE_PROFILE_MAIN; |
| case cdm::kAv1ProfileHigh: |
| return AV1PROFILE_PROFILE_HIGH; |
| case cdm::kAv1ProfilePro: |
| return AV1PROFILE_PROFILE_PRO; |
| } |
| |
| NOTREACHED() << "Unexpected cdm::VideoCodecProfile " << profile; |
| return VIDEO_CODEC_PROFILE_UNKNOWN; |
| } |
| |
| cdm::VideoFormat ToCdmVideoFormat(VideoPixelFormat format) { |
| switch (format) { |
| case PIXEL_FORMAT_YV12: |
| return cdm::kYv12; |
| case PIXEL_FORMAT_I420: |
| return cdm::kI420; |
| case PIXEL_FORMAT_YUV420P9: |
| return cdm::kYUV420P9; |
| case PIXEL_FORMAT_YUV420P10: |
| return cdm::kYUV420P10; |
| case PIXEL_FORMAT_YUV422P9: |
| return cdm::kYUV422P9; |
| case PIXEL_FORMAT_YUV422P10: |
| return cdm::kYUV422P10; |
| case PIXEL_FORMAT_YUV444P9: |
| return cdm::kYUV444P9; |
| case PIXEL_FORMAT_YUV444P10: |
| return cdm::kYUV444P10; |
| case PIXEL_FORMAT_YUV420P12: |
| return cdm::kYUV420P12; |
| case PIXEL_FORMAT_YUV422P12: |
| return cdm::kYUV422P12; |
| case PIXEL_FORMAT_YUV444P12: |
| return cdm::kYUV444P12; |
| default: |
| DVLOG(1) << "Unsupported VideoPixelFormat " << format; |
| return cdm::kUnknownVideoFormat; |
| } |
| } |
| |
| VideoPixelFormat ToMediaVideoFormat(cdm::VideoFormat format) { |
| switch (format) { |
| case cdm::kYv12: |
| return PIXEL_FORMAT_YV12; |
| case cdm::kI420: |
| return PIXEL_FORMAT_I420; |
| case cdm::kYUV420P9: |
| return PIXEL_FORMAT_YUV420P9; |
| case cdm::kYUV420P10: |
| return PIXEL_FORMAT_YUV420P10; |
| case cdm::kYUV422P9: |
| return PIXEL_FORMAT_YUV422P9; |
| case cdm::kYUV422P10: |
| return PIXEL_FORMAT_YUV422P10; |
| case cdm::kYUV444P9: |
| return PIXEL_FORMAT_YUV444P9; |
| case cdm::kYUV444P10: |
| return PIXEL_FORMAT_YUV444P10; |
| case cdm::kYUV420P12: |
| return PIXEL_FORMAT_YUV420P12; |
| case cdm::kYUV422P12: |
| return PIXEL_FORMAT_YUV422P12; |
| case cdm::kYUV444P12: |
| return PIXEL_FORMAT_YUV444P12; |
| default: |
| DVLOG(1) << "Unsupported cdm::VideoFormat " << format; |
| return PIXEL_FORMAT_UNKNOWN; |
| } |
| } |
| |
| // Aggregate Types |
| |
| // Warning: The returned config contains raw pointers to the extra data in the |
| // input |config|. Hence, the caller must make sure the input |config| outlives |
| // the returned config. |
| cdm::AudioDecoderConfig_2 ToCdmAudioDecoderConfig( |
| const AudioDecoderConfig& config) { |
| cdm::AudioDecoderConfig_2 cdm_config = {}; |
| cdm_config.codec = ToCdmAudioCodec(config.codec()); |
| cdm_config.channel_count = |
| ChannelLayoutToChannelCount(config.channel_layout()); |
| cdm_config.bits_per_channel = config.bits_per_channel(); |
| cdm_config.samples_per_second = config.samples_per_second(); |
| cdm_config.extra_data = const_cast<uint8_t*>(config.extra_data().data()); |
| cdm_config.extra_data_size = config.extra_data().size(); |
| cdm_config.encryption_scheme = |
| ToCdmEncryptionScheme(config.encryption_scheme()); |
| return cdm_config; |
| } |
| |
| // Warning: The returned config contains raw pointers to the extra data in the |
| // input |config|. Hence, the caller must make sure the input |config| outlives |
| // the returned config. |
| cdm::VideoDecoderConfig_3 ToCdmVideoDecoderConfig( |
| const VideoDecoderConfig& config) { |
| cdm::VideoDecoderConfig_3 cdm_config = {}; |
| cdm_config.codec = ToCdmVideoCodec(config.codec()); |
| cdm_config.profile = ToCdmVideoCodecProfile(config.profile()); |
| cdm_config.format = ToCdmVideoFormat(config.format()); |
| cdm_config.color_space = ToCdmColorSpace(config.color_space_info()); |
| cdm_config.coded_size.width = config.coded_size().width(); |
| cdm_config.coded_size.height = config.coded_size().height(); |
| cdm_config.extra_data = const_cast<uint8_t*>(config.extra_data().data()); |
| cdm_config.extra_data_size = config.extra_data().size(); |
| cdm_config.encryption_scheme = |
| ToCdmEncryptionScheme(config.encryption_scheme()); |
| return cdm_config; |
| } |
| |
| // Fill |input_buffer| based on the values in |encrypted|. |subsamples| |
| // is used to hold some of the data. |input_buffer| will contain pointers |
| // to data contained in |encrypted| and |subsamples|, so the lifetime of |
| // |input_buffer| must be <= the lifetime of |encrypted| and |subsamples|. |
| void ToCdmInputBuffer(const DecoderBuffer& encrypted_buffer, |
| std::vector<cdm::SubsampleEntry>* subsamples, |
| cdm::InputBuffer_2* input_buffer) { |
| // End of stream buffers are represented as empty resources. |
| DCHECK(!input_buffer->data); |
| if (encrypted_buffer.end_of_stream()) |
| return; |
| |
| input_buffer->data = encrypted_buffer.data(); |
| input_buffer->data_size = encrypted_buffer.data_size(); |
| input_buffer->timestamp = encrypted_buffer.timestamp().InMicroseconds(); |
| |
| const DecryptConfig* decrypt_config = encrypted_buffer.decrypt_config(); |
| if (!decrypt_config) { |
| DVLOG(2) << __func__ << ": Clear buffer."; |
| return; |
| } |
| |
| input_buffer->key_id = |
| reinterpret_cast<const uint8_t*>(decrypt_config->key_id().data()); |
| input_buffer->key_id_size = decrypt_config->key_id().size(); |
| input_buffer->iv = |
| reinterpret_cast<const uint8_t*>(decrypt_config->iv().data()); |
| input_buffer->iv_size = decrypt_config->iv().size(); |
| |
| DCHECK(subsamples->empty()); |
| size_t num_subsamples = decrypt_config->subsamples().size(); |
| if (num_subsamples > 0) { |
| subsamples->reserve(num_subsamples); |
| for (const auto& sample : decrypt_config->subsamples()) { |
| subsamples->push_back({sample.clear_bytes, sample.cypher_bytes}); |
| } |
| } |
| |
| input_buffer->subsamples = subsamples->data(); |
| input_buffer->num_subsamples = num_subsamples; |
| |
| input_buffer->encryption_scheme = |
| ToCdmEncryptionScheme(decrypt_config->encryption_mode()); |
| if (decrypt_config->HasPattern()) { |
| input_buffer->pattern = { |
| decrypt_config->encryption_pattern()->crypt_byte_block(), |
| decrypt_config->encryption_pattern()->skip_byte_block()}; |
| } |
| } |
| |
| } // namespace media |