diff options
-rw-r--r-- | chrome/renderer/media/chrome_key_systems.cc | 3 | ||||
-rw-r--r-- | components/cdm/common/cdm_messages_android.h | 2 | ||||
-rw-r--r-- | components/cdm/renderer/DEPS | 1 | ||||
-rw-r--r-- | components/cdm/renderer/android_key_systems.cc | 10 | ||||
-rw-r--r-- | components/cdm/renderer/widevine_key_systems.cc | 11 | ||||
-rw-r--r-- | content/content_common.gypi | 2 | ||||
-rw-r--r-- | content/public/common/eme_constants.h (renamed from content/public/common/eme_codec.h) | 24 | ||||
-rw-r--r-- | content/public/renderer/key_system_info.cc | 2 | ||||
-rw-r--r-- | content/public/renderer/key_system_info.h | 5 | ||||
-rw-r--r-- | content/renderer/media/crypto/key_systems.cc | 240 | ||||
-rw-r--r-- | content/renderer/media/crypto/key_systems.h | 18 | ||||
-rw-r--r-- | content/renderer/media/crypto/key_systems_unittest.cc | 4 |
12 files changed, 250 insertions, 72 deletions
diff --git a/chrome/renderer/media/chrome_key_systems.cc b/chrome/renderer/media/chrome_key_systems.cc index c15d493..e23e360 100644 --- a/chrome/renderer/media/chrome_key_systems.cc +++ b/chrome/renderer/media/chrome_key_systems.cc @@ -13,6 +13,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/common/render_messages.h" #include "components/cdm/renderer/widevine_key_systems.h" +#include "content/public/common/eme_constants.h" #include "content/public/renderer/render_thread.h" #if defined(OS_ANDROID) @@ -74,8 +75,10 @@ static void AddExternalClearKey( KeySystemInfo info(kExternalClearKeyKeySystem); info.supported_codecs = content::EME_CODEC_WEBM_ALL; + info.supported_init_data_types = content::EME_INIT_DATA_TYPE_WEBM; #if defined(USE_PROPRIETARY_CODECS) info.supported_codecs |= content::EME_CODEC_MP4_ALL; + info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_CENC; #endif // defined(USE_PROPRIETARY_CODECS) info.pepper_type = kExternalClearKeyPepperType; diff --git a/components/cdm/common/cdm_messages_android.h b/components/cdm/common/cdm_messages_android.h index f78674d..8e0ad1c 100644 --- a/components/cdm/common/cdm_messages_android.h +++ b/components/cdm/common/cdm_messages_android.h @@ -7,7 +7,7 @@ #include <vector> -#include "content/public/common/eme_codec.h" +#include "content/public/common/eme_constants.h" #include "ipc/ipc_message_macros.h" #define IPC_MESSAGE_START EncryptedMediaMsgStart diff --git a/components/cdm/renderer/DEPS b/components/cdm/renderer/DEPS index 725e151..dbd28cf 100644 --- a/components/cdm/renderer/DEPS +++ b/components/cdm/renderer/DEPS @@ -1,3 +1,4 @@ include_rules = [ + "+content/public/common", "+content/public/renderer", ] diff --git a/components/cdm/renderer/android_key_systems.cc b/components/cdm/renderer/android_key_systems.cc index 99bc2bb..c6adc80 100644 --- a/components/cdm/renderer/android_key_systems.cc +++ b/components/cdm/renderer/android_key_systems.cc @@ -10,6 +10,7 @@ #include "base/logging.h" #include "components/cdm/common/cdm_messages_android.h" #include "components/cdm/renderer/widevine_key_systems.h" +#include "content/public/common/eme_constants.h" #include "content/public/renderer/render_thread.h" #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. @@ -65,6 +66,15 @@ void AddAndroidPlatformKeySystems( if (response.compositing_codecs != content::EME_CODEC_NONE) { KeySystemInfo info(*it); info.supported_codecs = response.compositing_codecs; + // Here we assume that support for a container implies support for the + // associated initialization data type. KeySystems handles validating + // |init_data_type| x |container| pairings. + if (response.compositing_codecs & content::EME_CODEC_WEBM_ALL) + info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_WEBM; +#if defined(USE_PROPRIETARY_CODECS) + if (response.compositing_codecs & content::EME_CODEC_MP4_ALL) + info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_CENC; +#endif // defined(USE_PROPRIETARY_CODECS) concrete_key_systems->push_back(info); } } diff --git a/components/cdm/renderer/widevine_key_systems.cc b/components/cdm/renderer/widevine_key_systems.cc index 2a41322..d08b6ad 100644 --- a/components/cdm/renderer/widevine_key_systems.cc +++ b/components/cdm/renderer/widevine_key_systems.cc @@ -8,6 +8,7 @@ #include <vector> #include "base/logging.h" +#include "content/public/common/eme_constants.h" #include "widevine_cdm_version.h" // In SHARED_INTERMEDIATE_DIR. @@ -49,6 +50,16 @@ void AddWidevineWithCodecs(WidevineCdmType widevine_cdm_type, // initDataType. info.supported_codecs = supported_codecs; + // Here we assume that support for a container imples support for the + // associated initialization data type. KeySystems handles validating + // |init_data_type| x |container| pairings. + if (supported_codecs & content::EME_CODEC_WEBM_ALL) + info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_WEBM; +#if defined(USE_PROPRIETARY_CODECS) + if (supported_codecs & content::EME_CODEC_MP4_ALL) + info.supported_init_data_types |= content::EME_INIT_DATA_TYPE_CENC; +#endif // defined(USE_PROPRIETARY_CODECS) + #if defined(ENABLE_PEPPER_CDMS) info.pepper_type = kWidevineCdmPluginMimeType; #endif // defined(ENABLE_PEPPER_CDMS) diff --git a/content/content_common.gypi b/content/content_common.gypi index 53321cb..b715ea9 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -57,7 +57,7 @@ 'public/common/context_menu_params.h', 'public/common/drop_data.cc', 'public/common/drop_data.h', - 'public/common/eme_codec.h', + 'public/common/eme_constants.h', 'public/common/favicon_url.cc', 'public/common/favicon_url.h', 'public/common/file_chooser_params.cc', diff --git a/content/public/common/eme_codec.h b/content/public/common/eme_constants.h index 54ed0e6..aaf183e 100644 --- a/content/public/common/eme_codec.h +++ b/content/public/common/eme_constants.h @@ -2,15 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_PUBLIC_COMMON_EME_CODEC_H_ -#define CONTENT_PUBLIC_COMMON_EME_CODEC_H_ +#ifndef CONTENT_PUBLIC_COMMON_EME_CONSTANTS_H_ +#define CONTENT_PUBLIC_COMMON_EME_CONSTANTS_H_ + +#include <stdint.h> namespace content { +// Defines bitmask values that specify registered initialization data types used +// in Encrypted Media Extensions (EME). +// The mask values are stored in a SupportedInitDataTypes. +enum EmeInitDataType { + EME_INIT_DATA_TYPE_NONE = 0, + EME_INIT_DATA_TYPE_WEBM = 1 << 0, +#if defined(USE_PROPRIETARY_CODECS) + EME_INIT_DATA_TYPE_CENC = 1 << 1, +#endif // defined(USE_PROPRIETARY_CODECS) +}; + // Defines bitmask values that specify codecs used in Encrypted Media Extension // (EME). Each value represents a codec within a specific container. // The mask values are stored in a SupportedCodecs. enum EmeCodec { + // *_ALL values should only be used for masking, do not use them to specify + // codec support because they may be extended to include more codecs. EME_CODEC_NONE = 0, EME_CODEC_WEBM_VORBIS = 1 << 0, EME_CODEC_WEBM_AUDIO_ALL = EME_CODEC_WEBM_VORBIS, @@ -30,8 +45,9 @@ enum EmeCodec { #endif // defined(USE_PROPRIETARY_CODECS) }; -typedef uint32 SupportedCodecs; +typedef uint32_t SupportedInitDataTypes; +typedef uint32_t SupportedCodecs; } // namespace content -#endif // CONTENT_PUBLIC_COMMON_EME_CODEC_H_ +#endif // CONTENT_PUBLIC_COMMON_EME_CONSTANTS_H_ diff --git a/content/public/renderer/key_system_info.cc b/content/public/renderer/key_system_info.cc index 6a64fdb..9578ebf 100644 --- a/content/public/renderer/key_system_info.cc +++ b/content/public/renderer/key_system_info.cc @@ -8,6 +8,8 @@ namespace content { KeySystemInfo::KeySystemInfo(const std::string& key_system) : key_system(key_system), + supported_init_data_types(EME_INIT_DATA_TYPE_NONE), + supported_codecs(EME_CODEC_NONE), use_aes_decryptor(false) { } diff --git a/content/public/renderer/key_system_info.h b/content/public/renderer/key_system_info.h index 8eb2e57..9ec317d 100644 --- a/content/public/renderer/key_system_info.h +++ b/content/public/renderer/key_system_info.h @@ -11,7 +11,7 @@ #include "base/basictypes.h" #include "base/containers/hash_tables.h" #include "content/common/content_export.h" -#include "content/public/common/eme_codec.h" +#include "content/public/common/eme_constants.h" // Definitions: // * Key system @@ -38,6 +38,9 @@ struct CONTENT_EXPORT KeySystemInfo { std::string key_system; + // Specifies registered initialization data types supported by |key_system|. + SupportedInitDataTypes supported_init_data_types; + // Specifies codecs supported by |key_system|. SupportedCodecs supported_codecs; diff --git a/content/renderer/media/crypto/key_systems.cc b/content/renderer/media/crypto/key_systems.cc index a15e0b3..7435d69 100644 --- a/content/renderer/media/crypto/key_systems.cc +++ b/content/renderer/media/crypto/key_systems.cc @@ -13,7 +13,7 @@ #include "base/threading/thread_checker.h" #include "base/time/time.h" #include "content/public/common/content_client.h" -#include "content/public/common/eme_codec.h" +#include "content/public/common/eme_constants.h" #include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/key_system_info.h" #include "content/renderer/media/crypto/key_systems_support_uma.h" @@ -30,15 +30,29 @@ const char kClearKeyKeySystem[] = "org.w3.clearkey"; const char kPrefixedClearKeyKeySystem[] = "webkit-org.w3.clearkey"; const char kUnsupportedClearKeyKeySystem[] = "unsupported-org.w3.clearkey"; -struct CodecMask { - const char* type; - EmeCodec mask; +struct NamedInitDataType { + const char* name; + EmeInitDataType type; }; -// Mapping between container types and the masks of associated codecs. +// Mapping between initialization data types names and enum values. When adding +// entries, make sure to update IsSaneInitDataTypeWithContainer(). +static NamedInitDataType kInitDataTypeNames[] = { + {"webm", EME_INIT_DATA_TYPE_WEBM}, +#if defined(USE_PROPRIETARY_CODECS) + {"cenc", EME_INIT_DATA_TYPE_CENC} +#endif // defined(USE_PROPRIETARY_CODECS) +}; + +struct NamedCodec { + const char* name; + EmeCodec type; +}; + +// Mapping between containers and their codecs. // Only audio codec can belong to a "audio/*" container. Both audio and video // codecs can belong to a "video/*" container. -CodecMask kContainerCodecMasks[] = { +static NamedCodec kContainerToCodecMasks[] = { {"audio/webm", EME_CODEC_WEBM_AUDIO_ALL}, {"video/webm", EME_CODEC_WEBM_ALL}, #if defined(USE_PROPRIETARY_CODECS) @@ -47,8 +61,8 @@ CodecMask kContainerCodecMasks[] = { #endif // defined(USE_PROPRIETARY_CODECS) }; -// Mapping between codec types and their masks. -CodecMask kCodecMasks[] = { +// Mapping between codec names and enum values. +static NamedCodec kCodecStrings[] = { {"vorbis", EME_CODEC_WEBM_VORBIS}, {"vp8", EME_CODEC_WEBM_VP8}, {"vp8.0", EME_CODEC_WEBM_VP8}, @@ -68,6 +82,7 @@ static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) { // http://developer.android.com/guide/appendix/media-formats.html // VP9 support is device dependent. + info.supported_init_data_types = EME_INIT_DATA_TYPE_WEBM; info.supported_codecs = EME_CODEC_WEBM_ALL; #if defined(OS_ANDROID) @@ -77,6 +92,7 @@ static void AddClearKey(std::vector<KeySystemInfo>* concrete_key_systems) { #endif // defined(OS_ANDROID) #if defined(USE_PROPRIETARY_CODECS) + info.supported_init_data_types |= EME_INIT_DATA_TYPE_CENC; info.supported_codecs |= EME_CODEC_MP4_ALL; #endif // defined(USE_PROPRIETARY_CODECS) @@ -93,6 +109,12 @@ class KeySystems { bool IsConcreteSupportedKeySystem(const std::string& key_system); + bool IsSupportedKeySystem(const std::string& key_system); + + bool IsSupportedKeySystemWithInitDataType( + const std::string& key_system, + const std::string& init_data_type); + bool IsSupportedKeySystemWithMediaMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, @@ -119,6 +141,7 @@ class KeySystems { #if defined(ENABLE_PEPPER_CDMS) const std::string& pepper_type, #endif + SupportedInitDataTypes supported_init_data_types, SupportedCodecs supported_codecs, const std::string& parent_key_system); @@ -132,17 +155,31 @@ class KeySystems { #if defined(ENABLE_PEPPER_CDMS) std::string pepper_type; #endif + SupportedInitDataTypes supported_init_data_types; SupportedCodecs supported_codecs; }; typedef base::hash_map<std::string, KeySystemProperties> KeySystemPropertiesMap; typedef base::hash_map<std::string, std::string> ParentKeySystemMap; - typedef base::hash_map<std::string, EmeCodec> CodecMaskMap; + typedef base::hash_map<std::string, SupportedCodecs> ContainerCodecsMap; + typedef base::hash_map<std::string, EmeCodec> CodecsMap; + typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; KeySystems(); ~KeySystems() {} + EmeInitDataType GetInitDataTypeForName( + const std::string& init_data_type) const; + // TODO(sandersd): Separate container enum from codec mask value. + // http://crbug.com/417440 + SupportedCodecs GetCodecMaskForContainer( + const std::string& container) const; + EmeCodec GetCodecForString(const std::string& codec) const; + + const std::string& GetConcreteKeySystemName( + const std::string& key_system) const; + // Returns whether a |container| type is supported by checking // |key_system_supported_codecs|. // TODO(xhwang): Update this to actually check initDataType support. @@ -165,8 +202,9 @@ class KeySystems { KeySystemsSupportUMA key_systems_support_uma_; - CodecMaskMap container_codec_masks_; - CodecMaskMap codec_masks_; + InitDataTypesMap init_data_type_name_map_; + ContainerCodecsMap container_to_codec_mask_map_; + CodecsMap codec_string_map_; bool needs_update_; base::Time last_update_time_; @@ -188,18 +226,20 @@ KeySystems& KeySystems::GetInstance() { // Because we use a LazyInstance, the key systems info must be populated when // the instance is lazily initiated. KeySystems::KeySystems() : needs_update_(true) { - // Build container and codec masks for quick look up. - for (size_t i = 0; i < arraysize(kContainerCodecMasks); ++i) { - const CodecMask& container_codec_mask = kContainerCodecMasks[i]; - DCHECK(container_codec_masks_.find(container_codec_mask.type) == - container_codec_masks_.end()); - container_codec_masks_[container_codec_mask.type] = - container_codec_mask.mask; + for (size_t i = 0; i < arraysize(kInitDataTypeNames); ++i) { + const std::string& name = kInitDataTypeNames[i].name; + DCHECK(!init_data_type_name_map_.count(name)); + init_data_type_name_map_[name] = kInitDataTypeNames[i].type; + } + for (size_t i = 0; i < arraysize(kContainerToCodecMasks); ++i) { + const std::string& name = kContainerToCodecMasks[i].name; + DCHECK(!container_to_codec_mask_map_.count(name)); + container_to_codec_mask_map_[name] = kContainerToCodecMasks[i].type; } - for (size_t i = 0; i < arraysize(kCodecMasks); ++i) { - const CodecMask& codec_mask = kCodecMasks[i]; - DCHECK(codec_masks_.find(codec_mask.type) == codec_masks_.end()); - codec_masks_[codec_mask.type] = codec_mask.mask; + for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { + const std::string& name = kCodecStrings[i].name; + DCHECK(!codec_string_map_.count(name)); + codec_string_map_[name] = kCodecStrings[i].type; } UpdateSupportedKeySystems(); @@ -209,6 +249,40 @@ KeySystems::KeySystems() : needs_update_(true) { #endif // defined(WIDEVINE_CDM_AVAILABLE) } +EmeInitDataType KeySystems::GetInitDataTypeForName( + const std::string& init_data_type) const { + InitDataTypesMap::const_iterator iter = + init_data_type_name_map_.find(init_data_type); + if (iter != init_data_type_name_map_.end()) + return iter->second; + return EME_INIT_DATA_TYPE_NONE; +} + +SupportedCodecs KeySystems::GetCodecMaskForContainer( + const std::string& container) const { + ContainerCodecsMap::const_iterator iter = + container_to_codec_mask_map_.find(container); + if (iter != container_to_codec_mask_map_.end()) + return iter->second; + return EME_CODEC_NONE; +} + +EmeCodec KeySystems::GetCodecForString(const std::string& codec) const { + CodecsMap::const_iterator iter = codec_string_map_.find(codec); + if (iter != codec_string_map_.end()) + return iter->second; + return EME_CODEC_NONE; +} + +const std::string& KeySystems::GetConcreteKeySystemName( + const std::string& key_system) const { + ParentKeySystemMap::const_iterator iter = + parent_key_system_map_.find(key_system); + if (iter != parent_key_system_map_.end()) + return iter->second; + return key_system; +} + void KeySystems::UpdateIfNeeded() { #if defined(WIDEVINE_CDM_AVAILABLE) DCHECK(thread_checker_.CalledOnValidThread()); @@ -263,6 +337,7 @@ void KeySystems::AddConcreteSupportedKeySystems( #if defined(ENABLE_PEPPER_CDMS) key_system_info.pepper_type, #endif + key_system_info.supported_init_data_types, key_system_info.supported_codecs, key_system_info.parent_key_system); } @@ -274,13 +349,13 @@ void KeySystems::AddConcreteSupportedKeySystem( #if defined(ENABLE_PEPPER_CDMS) const std::string& pepper_type, #endif + SupportedInitDataTypes supported_init_data_types, SupportedCodecs supported_codecs, const std::string& parent_key_system) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!IsConcreteSupportedKeySystem(concrete_key_system)) << "Key system '" << concrete_key_system << "' already registered"; - DCHECK(parent_key_system_map_.find(concrete_key_system) == - parent_key_system_map_.end()) + DCHECK(!parent_key_system_map_.count(concrete_key_system)) << "'" << concrete_key_system << " is already registered as a parent"; KeySystemProperties properties; @@ -290,6 +365,7 @@ void KeySystems::AddConcreteSupportedKeySystem( properties.pepper_type = pepper_type; #endif + properties.supported_init_data_types = supported_init_data_types; properties.supported_codecs = supported_codecs; concrete_key_system_map_[concrete_key_system] = properties; @@ -297,8 +373,7 @@ void KeySystems::AddConcreteSupportedKeySystem( if (!parent_key_system.empty()) { DCHECK(!IsConcreteSupportedKeySystem(parent_key_system)) << "Parent '" << parent_key_system << "' already registered concrete"; - DCHECK(parent_key_system_map_.find(parent_key_system) == - parent_key_system_map_.end()) + DCHECK(!parent_key_system_map_.count(parent_key_system)) << "Parent '" << parent_key_system << "' already registered"; parent_key_system_map_[parent_key_system] = concrete_key_system; } @@ -306,8 +381,7 @@ void KeySystems::AddConcreteSupportedKeySystem( bool KeySystems::IsConcreteSupportedKeySystem(const std::string& key_system) { DCHECK(thread_checker_.CalledOnValidThread()); - return concrete_key_system_map_.find(key_system) != - concrete_key_system_map_.end(); + return concrete_key_system_map_.count(key_system) != 0; } bool KeySystems::IsSupportedContainer( @@ -324,16 +398,11 @@ bool KeySystems::IsSupportedContainer( if (container.find("audio/") == 0) canonical_container.replace(0, 6, "video/"); - CodecMaskMap::const_iterator container_iter = - container_codec_masks_.find(canonical_container); - // Unrecognized container. - if (container_iter == container_codec_masks_.end()) - return false; - - EmeCodec container_codec_mask = container_iter->second; // A container is supported iif at least one codec in that container is // supported. - return (container_codec_mask & key_system_supported_codecs) != 0; + SupportedCodecs supported_codecs = + GetCodecMaskForContainer(canonical_container); + return (supported_codecs & key_system_supported_codecs) != 0; } bool KeySystems::IsSupportedContainerAndCodecs( @@ -345,45 +414,66 @@ bool KeySystems::IsSupportedContainerAndCodecs( DCHECK(!codecs.empty()); DCHECK(IsSupportedContainer(container, key_system_supported_codecs)); - CodecMaskMap::const_iterator container_iter = - container_codec_masks_.find(container); - EmeCodec container_codec_mask = container_iter->second; + SupportedCodecs container_supported_codecs = + GetCodecMaskForContainer(container); for (size_t i = 0; i < codecs.size(); ++i) { - const std::string& codec = codecs[i]; - if (codec.empty()) + // TODO(sandersd): This should fail for isTypeSupported(). + // http://crbug.com/417461 + if (codecs[i].empty()) continue; - CodecMaskMap::const_iterator codec_iter = codec_masks_.find(codec); - if (codec_iter == codec_masks_.end()) // Unrecognized codec. - return false; - EmeCodec codec_mask = codec_iter->second; - if (!(codec_mask & key_system_supported_codecs)) // Unsupported codec. + EmeCodec codec = GetCodecForString(codecs[i]); + + // Unsupported codec. + if (!(codec & key_system_supported_codecs)) return false; // Unsupported codec/container combination, e.g. "video/webm" and "avc1". - if (!(codec_mask & container_codec_mask)) + if (!(codec & container_supported_codecs)) return false; } return true; } +bool KeySystems::IsSupportedKeySystem(const std::string& key_system) { + DCHECK(thread_checker_.CalledOnValidThread()); + return (concrete_key_system_map_.count(key_system) || + parent_key_system_map_.count(key_system)); +} + +bool KeySystems::IsSupportedKeySystemWithInitDataType( + const std::string& key_system, + const std::string& init_data_type) { + DCHECK(thread_checker_.CalledOnValidThread()); + + // If |key_system| is a parent key system, use its concrete child. + const std::string& concrete_key_system = GetConcreteKeySystemName(key_system); + + // Locate |concrete_key_system|. + KeySystemPropertiesMap::const_iterator key_system_iter = + concrete_key_system_map_.find(concrete_key_system); + if (key_system_iter == concrete_key_system_map_.end()) + return false; + + // Check |init_data_type| and |key_system| x |init_data_type|. + const KeySystemProperties& properties = key_system_iter->second; + EmeInitDataType eme_init_data_type = GetInitDataTypeForName(init_data_type); + return (properties.supported_init_data_types & eme_init_data_type) != 0; +} + +// TODO(sandersd): Reorganize to be more similar to +// IsKeySystemSupportedWithInitDataType(). Note that a fork may still be +// required; http://crbug.com/417461. bool KeySystems::IsSupportedKeySystemWithMediaMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, const std::string& key_system) { DCHECK(thread_checker_.CalledOnValidThread()); - // If |key_system| is a parent key_system, use its concrete child. - // Otherwise, use |key_system|. - std::string concrete_key_system; - ParentKeySystemMap::iterator parent_key_system_iter = - parent_key_system_map_.find(key_system); - if (parent_key_system_iter != parent_key_system_map_.end()) - concrete_key_system = parent_key_system_iter->second; - else - concrete_key_system = key_system; + // If |key_system| is a parent key system, use its concrete child. + const std::string& concrete_key_system = GetConcreteKeySystemName(key_system); bool has_type = !mime_type.empty(); @@ -421,7 +511,7 @@ bool KeySystems::IsSupportedKeySystemWithMediaMimeType( bool KeySystems::UseAesDecryptor(const std::string& concrete_key_system) { DCHECK(thread_checker_.CalledOnValidThread()); - KeySystemPropertiesMap::iterator key_system_iter = + KeySystemPropertiesMap::const_iterator key_system_iter = concrete_key_system_map_.find(concrete_key_system); if (key_system_iter == concrete_key_system_map_.end()) { DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; @@ -435,7 +525,7 @@ bool KeySystems::UseAesDecryptor(const std::string& concrete_key_system) { std::string KeySystems::GetPepperType(const std::string& concrete_key_system) { DCHECK(thread_checker_.CalledOnValidThread()); - KeySystemPropertiesMap::iterator key_system_iter = + KeySystemPropertiesMap::const_iterator key_system_iter = concrete_key_system_map_.find(concrete_key_system); if (key_system_iter == concrete_key_system_map_.end()) { DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; @@ -450,17 +540,14 @@ std::string KeySystems::GetPepperType(const std::string& concrete_key_system) { void KeySystems::AddContainerMask(const std::string& container, uint32 mask) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(container_codec_masks_.find(container) == - container_codec_masks_.end()); - - container_codec_masks_[container] = static_cast<EmeCodec>(mask); + DCHECK(!container_to_codec_mask_map_.count(container)); + container_to_codec_mask_map_[container] = static_cast<EmeCodec>(mask); } void KeySystems::AddCodecMask(const std::string& codec, uint32 mask) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(codec_masks_.find(codec) == codec_masks_.end()); - - codec_masks_[codec] = static_cast<EmeCodec>(mask); + DCHECK(!codec_string_map_.count(codec)); + codec_string_map_[codec] = static_cast<EmeCodec>(mask); } //------------------------------------------------------------------------------ @@ -484,10 +571,33 @@ std::string GetPrefixedKeySystemName(const std::string& key_system) { return key_system; } +bool IsSaneInitDataTypeWithContainer( + const std::string& init_data_type, + const std::string& container) { + if (init_data_type == "cenc") { + return container == "audio/mp4" || container == "video/mp4"; + } else if (init_data_type == "webm") { + return container == "audio/webm" || container == "video/webm"; + } else { + return true; + } +} + bool IsConcreteSupportedKeySystem(const std::string& key_system) { return KeySystems::GetInstance().IsConcreteSupportedKeySystem(key_system); } +bool IsSupportedKeySystem(const std::string& key_system) { + return KeySystems::GetInstance().IsSupportedKeySystem(key_system); +} + +bool IsSupportedKeySystemWithInitDataType( + const std::string& key_system, + const std::string& init_data_type) { + return KeySystems::GetInstance().IsSupportedKeySystemWithInitDataType( + key_system, init_data_type); +} + bool IsSupportedKeySystemWithMediaMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, diff --git a/content/renderer/media/crypto/key_systems.h b/content/renderer/media/crypto/key_systems.h index 99825d1..03d4002 100644 --- a/content/renderer/media/crypto/key_systems.h +++ b/content/renderer/media/crypto/key_systems.h @@ -24,6 +24,24 @@ std::string GetUnprefixedKeySystemName(const std::string& key_system); // Gets the prefixed key system name for |key_system|. std::string GetPrefixedKeySystemName(const std::string& key_system); +// Returns false if a container-specific |init_data_type| is specified with an +// inappropriate container. +// TODO(sandersd): Remove this essentially internal detail if the spec is +// updated to not convolve the two in a single method call. +// TODO(sandersd): Use enum values instead of strings. http://crbug.com/417440 +bool IsSaneInitDataTypeWithContainer( + const std::string& init_data_type, + const std::string& container); + +// Note: Shouldn't be used for prefixed API as the original +// IsSupportedKeySystemWithMediaMimeType() path reports UMAs, but this path does +// not. +bool IsSupportedKeySystem(const std::string& key_system); + +bool IsSupportedKeySystemWithInitDataType( + const std::string& key_system, + const std::string& init_data_type); + // Returns whether |key_system| is a real supported key system that can be // instantiated. // Abstract parent |key_system| strings will return false. diff --git a/content/renderer/media/crypto/key_systems_unittest.cc b/content/renderer/media/crypto/key_systems_unittest.cc index e52d361..d15b730 100644 --- a/content/renderer/media/crypto/key_systems_unittest.cc +++ b/content/renderer/media/crypto/key_systems_unittest.cc @@ -6,6 +6,7 @@ #include <vector> #include "content/public/common/content_client.h" +#include "content/public/common/eme_constants.h" #include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/key_system_info.h" #include "content/renderer/media/crypto/key_systems.h" @@ -100,12 +101,14 @@ void TestContentRendererClient::AddKeySystems( KeySystemInfo aes(kUsesAes); aes.supported_codecs = EME_CODEC_WEBM_ALL; aes.supported_codecs |= TEST_CODEC_FOO_ALL; + aes.supported_init_data_types = EME_INIT_DATA_TYPE_WEBM; aes.use_aes_decryptor = true; key_systems->push_back(aes); KeySystemInfo ext(kExternal); ext.supported_codecs = EME_CODEC_WEBM_ALL; ext.supported_codecs |= TEST_CODEC_FOO_ALL; + ext.supported_init_data_types = EME_INIT_DATA_TYPE_WEBM; ext.parent_key_system = kExternalParent; #if defined(ENABLE_PEPPER_CDMS) ext.pepper_type = "application/x-ppapi-external-cdm"; @@ -113,6 +116,7 @@ void TestContentRendererClient::AddKeySystems( key_systems->push_back(ext); } +// TODO(sandersd): Refactor. http://crbug.com/417444 class KeySystemsTest : public testing::Test { protected: KeySystemsTest() { |