Commit 164391c5 authored by Xiaohan Wang's avatar Xiaohan Wang Committed by Commit Bot

media: Move library CDM type converters to a central file

Adds cdm_type_converters.{h,cc} which collects all type converters
between cdm:: and media:: types.

Some conversion functions are renamed for consistency.

Bug: 707128
Test: No functionality change.
Change-Id: I0ac755f8820d4cf719f3b2c6c6885ec21f45f129
Reviewed-on: https://chromium-review.googlesource.com/c/1260488
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Reviewed-by: default avatarJohn Rummell <jrummell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#597347}
parent 88206a41
...@@ -86,6 +86,8 @@ source_set("cdm") { ...@@ -86,6 +86,8 @@ source_set("cdm") {
"cdm_helpers.h", "cdm_helpers.h",
"cdm_module.cc", "cdm_module.cc",
"cdm_module.h", "cdm_module.h",
"cdm_type_conversion.cc",
"cdm_type_conversion.h",
"cdm_wrapper.h", "cdm_wrapper.h",
"output_protection.h", "output_protection.h",
"platform_verification.h", "platform_verification.h",
......
...@@ -22,19 +22,16 @@ ...@@ -22,19 +22,16 @@
#include "media/base/callback_registry.h" #include "media/base/callback_registry.h"
#include "media/base/cdm_initialized_promise.h" #include "media/base/cdm_initialized_promise.h"
#include "media/base/cdm_key_information.h" #include "media/base/cdm_key_information.h"
#include "media/base/channel_layout.h"
#include "media/base/decoder_buffer.h" #include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h" #include "media/base/decrypt_config.h"
#include "media/base/key_systems.h" #include "media/base/key_systems.h"
#include "media/base/limits.h" #include "media/base/limits.h"
#include "media/base/sample_format.h"
#include "media/base/video_codecs.h"
#include "media/base/video_decoder_config.h" #include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h" #include "media/base/video_frame.h"
#include "media/base/video_types.h"
#include "media/base/video_util.h" #include "media/base/video_util.h"
#include "media/cdm/cdm_auxiliary_helper.h" #include "media/cdm/cdm_auxiliary_helper.h"
#include "media/cdm/cdm_helpers.h" #include "media/cdm/cdm_helpers.h"
#include "media/cdm/cdm_type_conversion.h"
#include "media/cdm/cdm_wrapper.h" #include "media/cdm/cdm_wrapper.h"
#include "ui/gfx/color_space.h" #include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
...@@ -58,252 +55,26 @@ constexpr uint32_t kCurrentStorageIdVersion = 1; ...@@ -58,252 +55,26 @@ constexpr uint32_t kCurrentStorageIdVersion = 1;
static_assert(kCurrentStorageIdVersion < 0x80000000, static_assert(kCurrentStorageIdVersion < 0x80000000,
"Versions 0x80000000 and above are reserved."); "Versions 0x80000000 and above are reserved.");
cdm::HdcpVersion ToCdmHdcpVersion(HdcpVersion hdcp_version) { // Verify that OutputProtection types matches those in CDM interface.
switch (hdcp_version) { // Cannot use conversion function because these are used in bit masks.
case HdcpVersion::kHdcpVersionNone: // See CdmAdapter::EnableOutputProtection and
return cdm::kHdcpVersionNone; // CdmAdapter::OnQueryOutputProtectionStatusDone() below.
case HdcpVersion::kHdcpVersion1_0: #define ASSERT_ENUM_EQ(media_enum, cdm_enum) \
return cdm::kHdcpVersion1_0; static_assert( \
case HdcpVersion::kHdcpVersion1_1: static_cast<int32_t>(media_enum) == static_cast<int32_t>(cdm_enum), \
return cdm::kHdcpVersion1_1; "Mismatched enum: " #media_enum " != " #cdm_enum)
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();
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;
}
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();
return cdm::kKeyIds;
}
CdmPromise::Exception ToMediaExceptionType(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;
}
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;
}
CdmKeyInformation::KeyStatus ToCdmKeyInformationKeyStatus(
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::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;
}
}
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;
}
}
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;
}
}
cdm::VideoFormat ToCdmVideoFormat(VideoPixelFormat format) {
switch (format) {
case PIXEL_FORMAT_YV12:
return cdm::kYv12;
case PIXEL_FORMAT_I420:
return cdm::kI420;
default:
DVLOG(1) << "Unsupported VideoPixelFormat " << format;
return cdm::kUnknownVideoFormat;
}
}
cdm::ColorRange ToCdmColorRange(gfx::ColorSpace::RangeID range) {
switch (range) {
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;
default:
DVLOG(1) << "Invalid color range";
return cdm::ColorRange::kInvalid;
}
}
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)};
}
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; ASSERT_ENUM_EQ(OutputProtection::LinkTypes::NONE, cdm::kLinkTypeNone);
return Decryptor::kError; ASSERT_ENUM_EQ(OutputProtection::LinkTypes::UNKNOWN, cdm::kLinkTypeUnknown);
} ASSERT_ENUM_EQ(OutputProtection::LinkTypes::INTERNAL, cdm::kLinkTypeInternal);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::VGA, cdm::kLinkTypeVGA);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::HDMI, cdm::kLinkTypeHDMI);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::DVI, cdm::kLinkTypeDVI);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::DISPLAYPORT,
cdm::kLinkTypeDisplayPort);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::NETWORK, cdm::kLinkTypeNetwork);
ASSERT_ENUM_EQ(OutputProtection::ProtectionType::NONE, cdm::kProtectionNone);
ASSERT_ENUM_EQ(OutputProtection::ProtectionType::HDCP, cdm::kProtectionHDCP);
inline std::ostream& operator<<(std::ostream& out, cdm::Status status) { inline std::ostream& operator<<(std::ostream& out, cdm::Status status) {
switch (status) { switch (status) {
...@@ -326,162 +97,6 @@ inline std::ostream& operator<<(std::ostream& out, cdm::Status status) { ...@@ -326,162 +97,6 @@ inline std::ostream& operator<<(std::ostream& out, cdm::Status status) {
return out << "Invalid Status!"; return out << "Invalid Status!";
} }
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;
}
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();
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();
return cdm::EncryptionScheme::kUnencrypted;
}
// 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 media::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 media::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;
}
// Verify that OutputProtection types matches those in CDM interface.
// Cannot use conversion function because these are used in bit masks.
#define ASSERT_ENUM_EQ(media_enum, cdm_enum) \
static_assert( \
static_cast<int32_t>(media_enum) == static_cast<int32_t>(cdm_enum), \
"Mismatched enum: " #media_enum " != " #cdm_enum)
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::NONE, cdm::kLinkTypeNone);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::UNKNOWN, cdm::kLinkTypeUnknown);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::INTERNAL, cdm::kLinkTypeInternal);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::VGA, cdm::kLinkTypeVGA);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::HDMI, cdm::kLinkTypeHDMI);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::DVI, cdm::kLinkTypeDVI);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::DISPLAYPORT,
cdm::kLinkTypeDisplayPort);
ASSERT_ENUM_EQ(OutputProtection::LinkTypes::NETWORK, cdm::kLinkTypeNetwork);
ASSERT_ENUM_EQ(OutputProtection::ProtectionType::NONE, cdm::kProtectionNone);
ASSERT_ENUM_EQ(OutputProtection::ProtectionType::HDCP, cdm::kProtectionHDCP);
// 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()};
}
}
void* GetCdmHost(int host_interface_version, void* user_data) { void* GetCdmHost(int host_interface_version, void* user_data) {
if (!host_interface_version || !user_data) if (!host_interface_version || !user_data)
return nullptr; return nullptr;
...@@ -1015,8 +630,7 @@ void CdmAdapter::OnResolveKeyStatusPromise(uint32_t promise_id, ...@@ -1015,8 +630,7 @@ void CdmAdapter::OnResolveKeyStatusPromise(uint32_t promise_id,
DVLOG(2) << __func__ << ": promise_id = " << promise_id DVLOG(2) << __func__ << ": promise_id = " << promise_id
<< ", key_status = " << key_status; << ", key_status = " << key_status;
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
cdm_promise_adapter_.ResolvePromise(promise_id, cdm_promise_adapter_.ResolvePromise(promise_id, ToMediaKeyStatus(key_status));
ToCdmKeyInformationKeyStatus(key_status));
} }
void CdmAdapter::OnResolvePromise(uint32_t promise_id) { void CdmAdapter::OnResolvePromise(uint32_t promise_id) {
...@@ -1058,7 +672,7 @@ void CdmAdapter::OnRejectPromise(uint32_t promise_id, ...@@ -1058,7 +672,7 @@ void CdmAdapter::OnRejectPromise(uint32_t promise_id,
DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(task_runner_->BelongsToCurrentThread());
cdm_promise_adapter_.RejectPromise(promise_id, cdm_promise_adapter_.RejectPromise(promise_id,
ToMediaExceptionType(exception), ToMediaCdmPromiseException(exception),
system_code, error_message_str); system_code, error_message_str);
} }
...@@ -1091,8 +705,8 @@ void CdmAdapter::OnSessionKeysChange(const char* session_id, ...@@ -1091,8 +705,8 @@ void CdmAdapter::OnSessionKeysChange(const char* session_id,
for (uint32_t i = 0; i < keys_info_count; ++i) { for (uint32_t i = 0; i < keys_info_count; ++i) {
const auto& info = keys_info[i]; const auto& info = keys_info[i];
keys.push_back(std::make_unique<CdmKeyInformation>( keys.push_back(std::make_unique<CdmKeyInformation>(
info.key_id, info.key_id_size, info.key_id, info.key_id_size, ToMediaKeyStatus(info.status),
ToCdmKeyInformationKeyStatus(info.status), info.system_code)); info.system_code));
} }
// TODO(jrummell): Handling resume playback should be done in the media // TODO(jrummell): Handling resume playback should be done in the media
......
// 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;
}
// TODO(xhwang): Support all media video formats.
cdm::VideoFormat ToCdmVideoFormat(VideoPixelFormat format) {
switch (format) {
case PIXEL_FORMAT_YV12:
return cdm::kYv12;
case PIXEL_FORMAT_I420:
return cdm::kI420;
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;
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
// 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.
#ifndef MEDIA_CDM_CDM_TYPE_CONVERSION_H_
#define MEDIA_CDM_CDM_TYPE_CONVERSION_H_
#include <vector>
#include "media/base/audio_codecs.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/cdm_key_information.h"
#include "media/base/cdm_promise.h"
#include "media/base/channel_layout.h"
#include "media/base/content_decryption_module.h"
#include "media/base/decoder_buffer.h"
#include "media/base/decrypt_config.h"
#include "media/base/decryptor.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_export.h"
#include "media/base/sample_format.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_types.h"
#include "media/cdm/api/content_decryption_module.h"
namespace media {
// Color Converters
MEDIA_EXPORT cdm::ColorSpace ToCdmColorSpace(
const VideoColorSpace& color_space);
MEDIA_EXPORT VideoColorSpace
ToMediaColorSpace(const cdm::ColorSpace& color_space);
// CDM Converters
MEDIA_EXPORT cdm::HdcpVersion ToCdmHdcpVersion(HdcpVersion hdcp_version);
MEDIA_EXPORT cdm::SessionType ToCdmSessionType(CdmSessionType session_type);
MEDIA_EXPORT CdmSessionType ToMediaSessionType(cdm::SessionType session_type);
MEDIA_EXPORT cdm::InitDataType ToCdmInitDataType(
EmeInitDataType init_data_type);
MEDIA_EXPORT EmeInitDataType
ToEmeInitDataType(cdm::InitDataType init_data_type);
MEDIA_EXPORT CdmKeyInformation::KeyStatus ToMediaKeyStatus(
cdm::KeyStatus status);
MEDIA_EXPORT cdm::KeyStatus ToCdmKeyStatus(CdmKeyInformation::KeyStatus status);
MEDIA_EXPORT cdm::EncryptionScheme ToCdmEncryptionScheme(
const EncryptionScheme& scheme);
MEDIA_EXPORT cdm::EncryptionScheme ToCdmEncryptionScheme(
const EncryptionMode& mode);
MEDIA_EXPORT CdmPromise::Exception ToMediaCdmPromiseException(
cdm::Exception exception);
MEDIA_EXPORT cdm::Exception ToCdmException(CdmPromise::Exception exception);
MEDIA_EXPORT CdmMessageType ToMediaMessageType(cdm::MessageType message_type);
MEDIA_EXPORT cdm::MessageType ToCdmMessageType(CdmMessageType message_type);
MEDIA_EXPORT cdm::StreamType ToCdmStreamType(Decryptor::StreamType stream_type);
MEDIA_EXPORT Decryptor::Status ToMediaDecryptorStatus(cdm::Status status);
// Audio Converters
MEDIA_EXPORT cdm::AudioCodec ToCdmAudioCodec(AudioCodec codec);
MEDIA_EXPORT SampleFormat ToMediaSampleFormat(cdm::AudioFormat format);
// Video Converters
MEDIA_EXPORT cdm::VideoCodec ToCdmVideoCodec(VideoCodec codec);
MEDIA_EXPORT VideoCodec ToMediaVideoCodec(cdm::VideoCodec codec);
MEDIA_EXPORT cdm::VideoCodecProfile ToCdmVideoCodecProfile(
VideoCodecProfile profile);
MEDIA_EXPORT VideoCodecProfile
ToMediaVideoCodecProfile(cdm::VideoCodecProfile profile);
MEDIA_EXPORT cdm::VideoFormat ToCdmVideoFormat(VideoPixelFormat format);
MEDIA_EXPORT VideoPixelFormat ToMediaVideoFormat(cdm::VideoFormat format);
// Aggregated 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.
MEDIA_EXPORT cdm::AudioDecoderConfig_2 ToCdmAudioDecoderConfig(
const AudioDecoderConfig& 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.
MEDIA_EXPORT cdm::VideoDecoderConfig_3 ToCdmVideoDecoderConfig(
const VideoDecoderConfig& 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|.
MEDIA_EXPORT void ToCdmInputBuffer(const DecoderBuffer& encrypted_buffer,
std::vector<cdm::SubsampleEntry>* subsamples,
cdm::InputBuffer_2* input_buffer);
} // namespace media
#endif // MEDIA_CDM_CDM_TYPE_CONVERSION_H_
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "media/base/decode_status.h" #include "media/base/decode_status.h"
#include "media/base/media_util.h" #include "media/base/media_util.h"
#include "media/cdm/cdm_type_conversion.h"
#include "media/cdm/library_cdm/cdm_host_proxy.h" #include "media/cdm/library_cdm/cdm_host_proxy.h"
#include "media/media_buildflags.h" #include "media/media_buildflags.h"
#include "third_party/libyuv/include/libyuv/planar_functions.h" #include "third_party/libyuv/include/libyuv/planar_functions.h"
...@@ -37,93 +38,6 @@ namespace media { ...@@ -37,93 +38,6 @@ namespace media {
namespace { namespace {
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;
}
}
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;
}
}
// TODO(xhwang): Support all media video formats.
VideoPixelFormat ToMediaVideoFormat(cdm::VideoFormat format) {
switch (format) {
case cdm::kYv12:
return PIXEL_FORMAT_YV12;
case cdm::kI420:
return PIXEL_FORMAT_I420;
default:
DVLOG(1) << "Unsupported VideoFormat " << format;
return PIXEL_FORMAT_UNKNOWN;
}
}
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;
}
}
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));
}
media::VideoDecoderConfig ToClearMediaVideoDecoderConfig( media::VideoDecoderConfig ToClearMediaVideoDecoderConfig(
const cdm::VideoDecoderConfig_3& config) { const cdm::VideoDecoderConfig_3& config) {
gfx::Size coded_size(config.coded_size.width, config.coded_size.width); gfx::Size coded_size(config.coded_size.width, config.coded_size.width);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "media/base/decrypt_config.h" #include "media/base/decrypt_config.h"
#include "media/base/encryption_pattern.h" #include "media/base/encryption_pattern.h"
#include "media/cdm/api/content_decryption_module_ext.h" #include "media/cdm/api/content_decryption_module_ext.h"
#include "media/cdm/cdm_type_conversion.h"
#include "media/cdm/json_web_key.h" #include "media/cdm/json_web_key.h"
#include "media/cdm/library_cdm/cdm_host_proxy.h" #include "media/cdm/library_cdm/cdm_host_proxy.h"
#include "media/cdm/library_cdm/cdm_host_proxy_impl.h" #include "media/cdm/library_cdm/cdm_host_proxy_impl.h"
...@@ -132,86 +133,6 @@ static std::string GetUnitTestResultMessage(bool success) { ...@@ -132,86 +133,6 @@ static std::string GetUnitTestResultMessage(bool success) {
return message; return message;
} }
static cdm::Exception ConvertException(
media::CdmPromise::Exception exception_code) {
switch (exception_code) {
case media::CdmPromise::Exception::NOT_SUPPORTED_ERROR:
return cdm::kExceptionNotSupportedError;
case media::CdmPromise::Exception::INVALID_STATE_ERROR:
return cdm::kExceptionInvalidStateError;
case media::CdmPromise::Exception::TYPE_ERROR:
return cdm::kExceptionTypeError;
case media::CdmPromise::Exception::QUOTA_EXCEEDED_ERROR:
return cdm::kExceptionQuotaExceededError;
}
NOTREACHED();
return cdm::kExceptionInvalidStateError;
}
static media::CdmSessionType ConvertSessionType(cdm::SessionType session_type) {
switch (session_type) {
case cdm::kTemporary:
return media::CdmSessionType::kTemporary;
case cdm::kPersistentLicense:
return media::CdmSessionType::kPersistentLicense;
case cdm::kPersistentUsageRecord:
return media::CdmSessionType::kPersistentUsageRecord;
}
NOTREACHED();
return media::CdmSessionType::kTemporary;
}
static media::EmeInitDataType ConvertInitDataType(
cdm::InitDataType init_data_type) {
switch (init_data_type) {
case cdm::kCenc:
return media::EmeInitDataType::CENC;
case cdm::kKeyIds:
return media::EmeInitDataType::KEYIDS;
case cdm::kWebM:
return media::EmeInitDataType::WEBM;
}
NOTREACHED();
return media::EmeInitDataType::UNKNOWN;
}
cdm::KeyStatus ConvertKeyStatus(media::CdmKeyInformation::KeyStatus status) {
switch (status) {
case media::CdmKeyInformation::KeyStatus::USABLE:
return cdm::kUsable;
case media::CdmKeyInformation::KeyStatus::INTERNAL_ERROR:
return cdm::kInternalError;
case media::CdmKeyInformation::KeyStatus::EXPIRED:
return cdm::kExpired;
case media::CdmKeyInformation::KeyStatus::OUTPUT_RESTRICTED:
return cdm::kOutputRestricted;
case media::CdmKeyInformation::KeyStatus::OUTPUT_DOWNSCALED:
return cdm::kOutputDownscaled;
case media::CdmKeyInformation::KeyStatus::KEY_STATUS_PENDING:
return cdm::kStatusPending;
case media::CdmKeyInformation::KeyStatus::RELEASED:
return cdm::kReleased;
}
NOTREACHED();
return cdm::kInternalError;
}
cdm::MessageType ConvertMessageType(media::CdmMessageType message_type) {
switch (message_type) {
case media::CdmMessageType::LICENSE_REQUEST:
return cdm::kLicenseRequest;
case media::CdmMessageType::LICENSE_RENEWAL:
return cdm::kLicenseRenewal;
case media::CdmMessageType::LICENSE_RELEASE:
return cdm::kLicenseRelease;
case media::CdmMessageType::INDIVIDUALIZATION_REQUEST:
return cdm::kIndividualizationRequest;
}
NOTREACHED();
return cdm::kLicenseRequest;
}
// Shallow copy all the key information from |keys_info| into |keys_vector|. // Shallow copy all the key information from |keys_info| into |keys_vector|.
// |keys_vector| is only valid for the lifetime of |keys_info| because it // |keys_vector| is only valid for the lifetime of |keys_info| because it
// contains pointers into the latter. // contains pointers into the latter.
...@@ -222,7 +143,7 @@ void ConvertCdmKeysInfo(const media::CdmKeysInfo& keys_info, ...@@ -222,7 +143,7 @@ void ConvertCdmKeysInfo(const media::CdmKeysInfo& keys_info,
cdm::KeyInformation key = {}; cdm::KeyInformation key = {};
key.key_id = key_info->key_id.data(); key.key_id = key_info->key_id.data();
key.key_id_size = key_info->key_id.size(); key.key_id_size = key_info->key_id.size();
key.status = ConvertKeyStatus(key_info->status); key.status = ToCdmKeyStatus(key_info->status);
key.system_code = key_info->system_code; key.system_code = key_info->system_code;
keys_vector->push_back(key); keys_vector->push_back(key);
} }
...@@ -520,7 +441,7 @@ void ClearKeyCdm::CreateSessionAndGenerateRequest( ...@@ -520,7 +441,7 @@ void ClearKeyCdm::CreateSessionAndGenerateRequest(
base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this),
promise_id))); promise_id)));
cdm_->CreateSessionAndGenerateRequest( cdm_->CreateSessionAndGenerateRequest(
ConvertSessionType(session_type), ConvertInitDataType(init_data_type), ToMediaSessionType(session_type), ToEmeInitDataType(init_data_type),
std::vector<uint8_t>(init_data, init_data + init_data_size), std::vector<uint8_t>(init_data, init_data + init_data_size),
std::move(promise)); std::move(promise));
...@@ -555,7 +476,7 @@ void ClearKeyCdm::LoadSession(uint32_t promise_id, ...@@ -555,7 +476,7 @@ void ClearKeyCdm::LoadSession(uint32_t promise_id,
promise_id), promise_id),
base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this), base::Bind(&ClearKeyCdm::OnPromiseFailed, base::Unretained(this),
promise_id))); promise_id)));
cdm_->LoadSession(ConvertSessionType(session_type), cdm_->LoadSession(ToMediaSessionType(session_type),
std::move(web_session_str), std::move(promise)); std::move(web_session_str), std::move(promise));
} }
...@@ -1056,7 +977,7 @@ void ClearKeyCdm::OnSessionMessage(const std::string& session_id, ...@@ -1056,7 +977,7 @@ void ClearKeyCdm::OnSessionMessage(const std::string& session_id,
DVLOG(1) << __func__ << ": size = " << message.size(); DVLOG(1) << __func__ << ": size = " << message.size();
cdm_host_proxy_->OnSessionMessage( cdm_host_proxy_->OnSessionMessage(
session_id.data(), session_id.length(), ConvertMessageType(message_type), session_id.data(), session_id.length(), ToCdmMessageType(message_type),
reinterpret_cast<const char*>(message.data()), message.size()); reinterpret_cast<const char*>(message.data()), message.size());
} }
...@@ -1108,7 +1029,7 @@ void ClearKeyCdm::OnPromiseFailed(uint32_t promise_id, ...@@ -1108,7 +1029,7 @@ void ClearKeyCdm::OnPromiseFailed(uint32_t promise_id,
uint32_t system_code, uint32_t system_code,
const std::string& error_message) { const std::string& error_message) {
DVLOG(1) << __func__ << ": error = " << error_message; DVLOG(1) << __func__ << ": error = " << error_message;
cdm_host_proxy_->OnRejectPromise(promise_id, ConvertException(exception_code), cdm_host_proxy_->OnRejectPromise(promise_id, ToCdmException(exception_code),
system_code, error_message.data(), system_code, error_message.data(),
error_message.length()); error_message.length());
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/numerics/safe_math.h" #include "base/numerics/safe_math.h"
#include "media/cdm/api/content_decryption_module.h" #include "media/cdm/api/content_decryption_module.h"
#include "media/cdm/cdm_helpers.h" #include "media/cdm/cdm_helpers.h"
#include "media/cdm/cdm_type_conversion.h"
#include "media/mojo/common/mojo_shared_buffer_video_frame.h" #include "media/mojo/common/mojo_shared_buffer_video_frame.h"
#include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/buffer.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
...@@ -27,18 +28,6 @@ typedef base::Callback<void(mojo::ScopedSharedBufferHandle buffer, ...@@ -27,18 +28,6 @@ typedef base::Callback<void(mojo::ScopedSharedBufferHandle buffer,
size_t capacity)> size_t capacity)>
MojoSharedBufferDoneCB; MojoSharedBufferDoneCB;
VideoPixelFormat CdmVideoFormatToVideoPixelFormat(cdm::VideoFormat format) {
switch (format) {
case cdm::kYv12:
return PIXEL_FORMAT_YV12;
case cdm::kI420:
return PIXEL_FORMAT_I420;
default:
NOTREACHED();
return PIXEL_FORMAT_UNKNOWN;
}
}
// cdm::Buffer implementation that provides access to mojo shared memory. // cdm::Buffer implementation that provides access to mojo shared memory.
// It owns the memory until Destroy() is called. // It owns the memory until Destroy() is called.
class MojoCdmBuffer : public cdm::Buffer { class MojoCdmBuffer : public cdm::Buffer {
...@@ -143,8 +132,8 @@ class MojoCdmVideoFrame : public VideoFrameImpl { ...@@ -143,8 +132,8 @@ class MojoCdmVideoFrame : public VideoFrameImpl {
scoped_refptr<MojoSharedBufferVideoFrame> frame = scoped_refptr<MojoSharedBufferVideoFrame> frame =
media::MojoSharedBufferVideoFrame::Create( media::MojoSharedBufferVideoFrame::Create(
CdmVideoFormatToVideoPixelFormat(Format()), frame_size, ToMediaVideoFormat(Format()), frame_size, gfx::Rect(frame_size),
gfx::Rect(frame_size), natural_size, std::move(handle), buffer_size, natural_size, std::move(handle), buffer_size,
PlaneOffset(cdm::kYPlane), PlaneOffset(cdm::kUPlane), PlaneOffset(cdm::kYPlane), PlaneOffset(cdm::kUPlane),
PlaneOffset(cdm::kVPlane), Stride(cdm::kYPlane), PlaneOffset(cdm::kVPlane), Stride(cdm::kYPlane),
Stride(cdm::kUPlane), Stride(cdm::kVPlane), Stride(cdm::kUPlane), Stride(cdm::kVPlane),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment