| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/base/key_systems.h" | 5 #include "media/base/key_systems.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 // These names are used by UMA. Do not change them! | 26 // These names are used by UMA. Do not change them! |
| 27 const char kClearKeyKeySystemNameForUMA[] = "ClearKey"; | 27 const char kClearKeyKeySystemNameForUMA[] = "ClearKey"; |
| 28 const char kUnknownKeySystemNameForUMA[] = "Unknown"; | 28 const char kUnknownKeySystemNameForUMA[] = "Unknown"; |
| 29 | 29 |
| 30 struct NamedCodec { | 30 struct NamedCodec { |
| 31 const char* name; | 31 const char* name; |
| 32 EmeCodec type; | 32 EmeCodec type; |
| 33 }; | 33 }; |
| 34 | 34 |
| 35 // Mapping between containers and their codecs. | 35 // Mapping between containers and their codecs. |
| 36 // Only audio codec can belong to a "audio/*" container. Both audio and video | 36 // Only audio codecs can belong to a "audio/*" mime_type, and only video codecs |
| 37 // codecs can belong to a "video/*" container. | 37 // can belong to a "video/*" mime_type. |
| 38 // TODO(sandersd): This definition only makes sense for prefixed EME. Change it | 38 static const NamedCodec kMimeTypeToCodecMasks[] = { |
| 39 // when prefixed EME is removed. http://crbug.com/249976 | |
| 40 static NamedCodec kContainerToCodecMasks[] = { | |
| 41 {"audio/webm", EME_CODEC_WEBM_AUDIO_ALL}, | 39 {"audio/webm", EME_CODEC_WEBM_AUDIO_ALL}, |
| 42 {"video/webm", EME_CODEC_WEBM_ALL}, | 40 {"video/webm", EME_CODEC_WEBM_VIDEO_ALL}, |
| 43 #if defined(USE_PROPRIETARY_CODECS) | 41 #if defined(USE_PROPRIETARY_CODECS) |
| 44 {"audio/mp4", EME_CODEC_MP4_AUDIO_ALL}, | 42 {"audio/mp4", EME_CODEC_MP4_AUDIO_ALL}, |
| 45 {"video/mp4", EME_CODEC_MP4_ALL} | 43 {"video/mp4", EME_CODEC_MP4_VIDEO_ALL} |
| 46 #endif // defined(USE_PROPRIETARY_CODECS) | 44 #endif // defined(USE_PROPRIETARY_CODECS) |
| 47 }; | 45 }; |
| 48 | 46 |
| 49 // Mapping between codec names and enum values. | 47 // Mapping between codec names and enum values. |
| 50 static NamedCodec kCodecStrings[] = { | 48 static const NamedCodec kCodecStrings[] = { |
| 51 {"opus", EME_CODEC_WEBM_OPUS}, | 49 {"opus", EME_CODEC_WEBM_OPUS}, // Opus. |
| 52 {"vorbis", EME_CODEC_WEBM_VORBIS}, | 50 {"vorbis", EME_CODEC_WEBM_VORBIS}, // Vorbis. |
| 53 {"vp8", EME_CODEC_WEBM_VP8}, | 51 {"vp8", EME_CODEC_WEBM_VP8}, // VP8. |
| 54 {"vp8.0", EME_CODEC_WEBM_VP8}, | 52 {"vp8.0", EME_CODEC_WEBM_VP8}, // VP8. |
| 55 {"vp9", EME_CODEC_WEBM_VP9}, | 53 {"vp9", EME_CODEC_WEBM_VP9}, // VP9. |
| 56 {"vp9.0", EME_CODEC_WEBM_VP9}, | 54 {"vp9.0", EME_CODEC_WEBM_VP9}, // VP9. |
| 57 #if defined(USE_PROPRIETARY_CODECS) | 55 #if defined(USE_PROPRIETARY_CODECS) |
| 58 {"mp4a", EME_CODEC_MP4_AAC}, | 56 {"mp4a", EME_CODEC_MP4_AAC}, // AAC. |
| 59 {"avc1", EME_CODEC_MP4_AVC1}, | 57 {"avc1", EME_CODEC_MP4_AVC1}, // AVC1. |
| 60 {"avc3", EME_CODEC_MP4_AVC1} | 58 {"avc3", EME_CODEC_MP4_AVC1} // AVC3. |
| 61 #endif // defined(USE_PROPRIETARY_CODECS) | 59 #endif // defined(USE_PROPRIETARY_CODECS) |
| 62 }; | 60 }; |
| 63 | 61 |
| 64 static EmeRobustness ConvertRobustness(const std::string& robustness) { | 62 static EmeRobustness ConvertRobustness(const std::string& robustness) { |
| 65 if (robustness.empty()) | 63 if (robustness.empty()) |
| 66 return EmeRobustness::EMPTY; | 64 return EmeRobustness::EMPTY; |
| 67 if (robustness == "SW_SECURE_CRYPTO") | 65 if (robustness == "SW_SECURE_CRYPTO") |
| 68 return EmeRobustness::SW_SECURE_CRYPTO; | 66 return EmeRobustness::SW_SECURE_CRYPTO; |
| 69 if (robustness == "SW_SECURE_DECODE") | 67 if (robustness == "SW_SECURE_DECODE") |
| 70 return EmeRobustness::SW_SECURE_DECODE; | 68 return EmeRobustness::SW_SECURE_DECODE; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 bool IsConcreteSupportedKeySystem(const std::string& key_system) const; | 175 bool IsConcreteSupportedKeySystem(const std::string& key_system) const; |
| 178 | 176 |
| 179 std::string GetKeySystemNameForUMA(const std::string& key_system) const; | 177 std::string GetKeySystemNameForUMA(const std::string& key_system) const; |
| 180 | 178 |
| 181 bool UseAesDecryptor(const std::string& concrete_key_system) const; | 179 bool UseAesDecryptor(const std::string& concrete_key_system) const; |
| 182 | 180 |
| 183 #if defined(ENABLE_PEPPER_CDMS) | 181 #if defined(ENABLE_PEPPER_CDMS) |
| 184 std::string GetPepperType(const std::string& concrete_key_system) const; | 182 std::string GetPepperType(const std::string& concrete_key_system) const; |
| 185 #endif | 183 #endif |
| 186 | 184 |
| 187 void AddContainerMask(const std::string& container, uint32_t mask); | 185 // These two functions are for testing purpose only. |
| 188 void AddCodecMask(EmeMediaType media_type, | 186 void AddCodecMask(EmeMediaType media_type, |
| 189 const std::string& codec, | 187 const std::string& codec, |
| 190 uint32_t mask); | 188 uint32_t mask); |
| 189 void AddMimeTypeCodecMask(const std::string& mime_type, uint32_t mask); |
| 191 | 190 |
| 192 // Implementation of KeySystems interface. | 191 // Implementation of KeySystems interface. |
| 193 bool IsSupportedKeySystem(const std::string& key_system) const override; | 192 bool IsSupportedKeySystem(const std::string& key_system) const override; |
| 194 | 193 |
| 195 bool IsSupportedInitDataType(const std::string& key_system, | 194 bool IsSupportedInitDataType(const std::string& key_system, |
| 196 EmeInitDataType init_data_type) const override; | 195 EmeInitDataType init_data_type) const override; |
| 197 | 196 |
| 198 EmeConfigRule GetContentTypeConfigRule( | 197 EmeConfigRule GetContentTypeConfigRule( |
| 199 const std::string& key_system, | 198 const std::string& key_system, |
| 200 EmeMediaType media_type, | 199 EmeMediaType media_type, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 222 KeySystemsImpl(); | 221 KeySystemsImpl(); |
| 223 ~KeySystemsImpl() override; | 222 ~KeySystemsImpl() override; |
| 224 | 223 |
| 225 void InitializeUMAInfo(); | 224 void InitializeUMAInfo(); |
| 226 | 225 |
| 227 void UpdateSupportedKeySystems(); | 226 void UpdateSupportedKeySystems(); |
| 228 | 227 |
| 229 void AddConcreteSupportedKeySystems( | 228 void AddConcreteSupportedKeySystems( |
| 230 const std::vector<KeySystemInfo>& concrete_key_systems); | 229 const std::vector<KeySystemInfo>& concrete_key_systems); |
| 231 | 230 |
| 231 void RegisterMimeType(const std::string& mime_type, EmeCodec codecs_mask); |
| 232 bool IsValidMimeTypeCodecsCombination(const std::string& mime_type, |
| 233 SupportedCodecs codecs_mask) const; |
| 234 |
| 232 friend struct base::DefaultLazyInstanceTraits<KeySystemsImpl>; | 235 friend struct base::DefaultLazyInstanceTraits<KeySystemsImpl>; |
| 233 | 236 |
| 234 typedef base::hash_map<std::string, KeySystemInfo> KeySystemInfoMap; | 237 typedef base::hash_map<std::string, KeySystemInfo> KeySystemInfoMap; |
| 235 typedef base::hash_map<std::string, std::string> ParentKeySystemMap; | 238 typedef base::hash_map<std::string, std::string> ParentKeySystemMap; |
| 236 typedef base::hash_map<std::string, SupportedCodecs> ContainerCodecsMap; | 239 typedef base::hash_map<std::string, SupportedCodecs> MimeTypeCodecsMap; |
| 237 typedef base::hash_map<std::string, EmeCodec> CodecsMap; | 240 typedef base::hash_map<std::string, EmeCodec> CodecsMap; |
| 238 typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; | 241 typedef base::hash_map<std::string, EmeInitDataType> InitDataTypesMap; |
| 239 typedef base::hash_map<std::string, std::string> KeySystemNameForUMAMap; | 242 typedef base::hash_map<std::string, std::string> KeySystemNameForUMAMap; |
| 240 | 243 |
| 241 // TODO(sandersd): Separate container enum from codec mask value. | 244 // TODO(sandersd): Separate container enum from codec mask value. |
| 242 // http://crbug.com/417440 | 245 // http://crbug.com/417440 |
| 243 SupportedCodecs GetCodecMaskForContainer( | 246 // Potentially pass EmeMediaType and a container enum. |
| 244 const std::string& container) const; | 247 SupportedCodecs GetCodecMaskForMimeType( |
| 248 const std::string& container_mime_type) const; |
| 245 EmeCodec GetCodecForString(const std::string& codec) const; | 249 EmeCodec GetCodecForString(const std::string& codec) const; |
| 246 | 250 |
| 247 // Returns whether a |container| type is supported by checking | |
| 248 // |key_system_supported_codecs|. | |
| 249 // TODO(xhwang): Update this to actually check initDataType support. | |
| 250 bool IsSupportedContainer(const std::string& container, | |
| 251 SupportedCodecs key_system_supported_codecs) const; | |
| 252 | |
| 253 // Returns true if all |codecs| are supported in |container| by checking | |
| 254 // |key_system_supported_codecs|. | |
| 255 bool IsSupportedContainerAndCodecs( | |
| 256 const std::string& container, | |
| 257 const std::vector<std::string>& codecs, | |
| 258 SupportedCodecs key_system_supported_codecs) const; | |
| 259 | |
| 260 // Map from key system string to capabilities. | 251 // Map from key system string to capabilities. |
| 261 KeySystemInfoMap concrete_key_system_map_; | 252 KeySystemInfoMap concrete_key_system_map_; |
| 262 | 253 |
| 263 // Map from parent key system to the concrete key system that should be used | 254 // Map from parent key system to the concrete key system that should be used |
| 264 // to represent its capabilities. | 255 // to represent its capabilities. |
| 265 ParentKeySystemMap parent_key_system_map_; | 256 ParentKeySystemMap parent_key_system_map_; |
| 266 | 257 |
| 267 ContainerCodecsMap container_to_codec_mask_map_; | 258 // This member should only be modified by RegisterMimeType(). |
| 259 MimeTypeCodecsMap mime_type_to_codec_mask_map_; |
| 268 CodecsMap codec_string_map_; | 260 CodecsMap codec_string_map_; |
| 269 KeySystemNameForUMAMap key_system_name_for_uma_map_; | 261 KeySystemNameForUMAMap key_system_name_for_uma_map_; |
| 270 | 262 |
| 271 SupportedCodecs audio_codec_mask_; | 263 SupportedCodecs audio_codec_mask_; |
| 272 SupportedCodecs video_codec_mask_; | 264 SupportedCodecs video_codec_mask_; |
| 273 | 265 |
| 274 // Makes sure all methods are called from the same thread. | 266 // Makes sure all methods are called from the same thread. |
| 275 base::ThreadChecker thread_checker_; | 267 base::ThreadChecker thread_checker_; |
| 276 | 268 |
| 277 DISALLOW_COPY_AND_ASSIGN(KeySystemsImpl); | 269 DISALLOW_COPY_AND_ASSIGN(KeySystemsImpl); |
| 278 }; | 270 }; |
| 279 | 271 |
| 280 static base::LazyInstance<KeySystemsImpl>::Leaky g_key_systems = | 272 static base::LazyInstance<KeySystemsImpl>::Leaky g_key_systems = |
| 281 LAZY_INSTANCE_INITIALIZER; | 273 LAZY_INSTANCE_INITIALIZER; |
| 282 | 274 |
| 283 KeySystemsImpl* KeySystemsImpl::GetInstance() { | 275 KeySystemsImpl* KeySystemsImpl::GetInstance() { |
| 284 KeySystemsImpl* key_systems = g_key_systems.Pointer(); | 276 KeySystemsImpl* key_systems = g_key_systems.Pointer(); |
| 285 key_systems->UpdateIfNeeded(); | 277 key_systems->UpdateIfNeeded(); |
| 286 return key_systems; | 278 return key_systems; |
| 287 } | 279 } |
| 288 | 280 |
| 289 // Because we use a LazyInstance, the key systems info must be populated when | 281 // Because we use a LazyInstance, the key systems info must be populated when |
| 290 // the instance is lazily initiated. | 282 // the instance is lazily initiated. |
| 291 KeySystemsImpl::KeySystemsImpl() : | 283 KeySystemsImpl::KeySystemsImpl() : |
| 292 audio_codec_mask_(EME_CODEC_AUDIO_ALL), | 284 audio_codec_mask_(EME_CODEC_AUDIO_ALL), |
| 293 video_codec_mask_(EME_CODEC_VIDEO_ALL) { | 285 video_codec_mask_(EME_CODEC_VIDEO_ALL) { |
| 294 for (size_t i = 0; i < arraysize(kContainerToCodecMasks); ++i) { | |
| 295 const std::string& name = kContainerToCodecMasks[i].name; | |
| 296 DCHECK(!container_to_codec_mask_map_.count(name)); | |
| 297 container_to_codec_mask_map_[name] = kContainerToCodecMasks[i].type; | |
| 298 } | |
| 299 for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { | 286 for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { |
| 300 const std::string& name = kCodecStrings[i].name; | 287 const std::string& name = kCodecStrings[i].name; |
| 301 DCHECK(!codec_string_map_.count(name)); | 288 DCHECK(!codec_string_map_.count(name)); |
| 302 codec_string_map_[name] = kCodecStrings[i].type; | 289 codec_string_map_[name] = kCodecStrings[i].type; |
| 303 } | 290 } |
| 291 for (size_t i = 0; i < arraysize(kMimeTypeToCodecMasks); ++i) { |
| 292 RegisterMimeType(kMimeTypeToCodecMasks[i].name, |
| 293 kMimeTypeToCodecMasks[i].type); |
| 294 } |
| 304 | 295 |
| 305 InitializeUMAInfo(); | 296 InitializeUMAInfo(); |
| 306 | 297 |
| 307 // Always update supported key systems during construction. | 298 // Always update supported key systems during construction. |
| 308 UpdateSupportedKeySystems(); | 299 UpdateSupportedKeySystems(); |
| 309 } | 300 } |
| 310 | 301 |
| 311 KeySystemsImpl::~KeySystemsImpl() { | 302 KeySystemsImpl::~KeySystemsImpl() { |
| 312 } | 303 } |
| 313 | 304 |
| 314 SupportedCodecs KeySystemsImpl::GetCodecMaskForContainer( | 305 SupportedCodecs KeySystemsImpl::GetCodecMaskForMimeType( |
| 315 const std::string& container) const { | 306 const std::string& container_mime_type) const { |
| 316 ContainerCodecsMap::const_iterator iter = | 307 MimeTypeCodecsMap::const_iterator iter = |
| 317 container_to_codec_mask_map_.find(container); | 308 mime_type_to_codec_mask_map_.find(container_mime_type); |
| 318 if (iter != container_to_codec_mask_map_.end()) | 309 if (iter == mime_type_to_codec_mask_map_.end()) |
| 319 return iter->second; | 310 return EME_CODEC_NONE; |
| 320 return EME_CODEC_NONE; | 311 |
| 312 DCHECK(IsValidMimeTypeCodecsCombination(container_mime_type, iter->second)); |
| 313 return iter->second; |
| 321 } | 314 } |
| 322 | 315 |
| 323 EmeCodec KeySystemsImpl::GetCodecForString(const std::string& codec) const { | 316 EmeCodec KeySystemsImpl::GetCodecForString(const std::string& codec) const { |
| 324 CodecsMap::const_iterator iter = codec_string_map_.find(codec); | 317 CodecsMap::const_iterator iter = codec_string_map_.find(codec); |
| 325 if (iter != codec_string_map_.end()) | 318 if (iter != codec_string_map_.end()) |
| 326 return iter->second; | 319 return iter->second; |
| 327 return EME_CODEC_NONE; | 320 return EME_CODEC_NONE; |
| 328 } | 321 } |
| 329 | 322 |
| 330 void KeySystemsImpl::InitializeUMAInfo() { | 323 void KeySystemsImpl::InitializeUMAInfo() { |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 DCHECK(!IsConcreteSupportedKeySystem(info.parent_key_system)) | 427 DCHECK(!IsConcreteSupportedKeySystem(info.parent_key_system)) |
| 435 << "Parent '" << info.parent_key_system << "' " | 428 << "Parent '" << info.parent_key_system << "' " |
| 436 << "already registered concrete"; | 429 << "already registered concrete"; |
| 437 DCHECK(!parent_key_system_map_.count(info.parent_key_system)) | 430 DCHECK(!parent_key_system_map_.count(info.parent_key_system)) |
| 438 << "Parent '" << info.parent_key_system << "' already registered"; | 431 << "Parent '" << info.parent_key_system << "' already registered"; |
| 439 parent_key_system_map_[info.parent_key_system] = info.key_system; | 432 parent_key_system_map_[info.parent_key_system] = info.key_system; |
| 440 } | 433 } |
| 441 } | 434 } |
| 442 } | 435 } |
| 443 | 436 |
| 437 // Adds the MIME type with the codec mask after verifying the validity. |
| 438 // Only this function should modify |mime_type_to_codec_mask_map_|. |
| 439 void KeySystemsImpl::RegisterMimeType(const std::string& mime_type, |
| 440 EmeCodec codecs_mask) { |
| 441 DCHECK(thread_checker_.CalledOnValidThread()); |
| 442 DCHECK(!mime_type_to_codec_mask_map_.count(mime_type)); |
| 443 DCHECK(IsValidMimeTypeCodecsCombination(mime_type, codecs_mask)); |
| 444 |
| 445 mime_type_to_codec_mask_map_[mime_type] = static_cast<EmeCodec>(codecs_mask); |
| 446 } |
| 447 |
| 448 // Returns whether |mime_type| follows a valid format and the specified codecs |
| 449 // are of the correct type based on |*_codec_mask_|. |
| 450 // Only audio/ or video/ MIME types with their respective codecs are allowed. |
| 451 bool KeySystemsImpl::IsValidMimeTypeCodecsCombination( |
| 452 const std::string& mime_type, |
| 453 SupportedCodecs codecs_mask) const { |
| 454 DCHECK(thread_checker_.CalledOnValidThread()); |
| 455 if (!codecs_mask) |
| 456 return false; |
| 457 if (base::StartsWith(mime_type, "audio/", base::CompareCase::SENSITIVE)) |
| 458 return !(codecs_mask & ~audio_codec_mask_); |
| 459 if (base::StartsWith(mime_type, "video/", base::CompareCase::SENSITIVE)) |
| 460 return !(codecs_mask & ~video_codec_mask_); |
| 461 |
| 462 return false; |
| 463 } |
| 464 |
| 444 bool KeySystemsImpl::IsConcreteSupportedKeySystem( | 465 bool KeySystemsImpl::IsConcreteSupportedKeySystem( |
| 445 const std::string& key_system) const { | 466 const std::string& key_system) const { |
| 446 DCHECK(thread_checker_.CalledOnValidThread()); | 467 DCHECK(thread_checker_.CalledOnValidThread()); |
| 447 return concrete_key_system_map_.count(key_system) != 0; | 468 return concrete_key_system_map_.count(key_system) != 0; |
| 448 } | 469 } |
| 449 | 470 |
| 450 bool KeySystemsImpl::IsSupportedContainer( | |
| 451 const std::string& container, | |
| 452 SupportedCodecs key_system_supported_codecs) const { | |
| 453 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 454 DCHECK(!container.empty()); | |
| 455 | |
| 456 // When checking container support for EME, "audio/foo" should be treated the | |
| 457 // same as "video/foo". Convert the |container| to achieve this. | |
| 458 // TODO(xhwang): Replace this with real checks against supported initDataTypes | |
| 459 // combined with supported demuxers. | |
| 460 std::string canonical_container = container; | |
| 461 if (container.find("audio/") == 0) | |
| 462 canonical_container.replace(0, 6, "video/"); | |
| 463 | |
| 464 // A container is supported iif at least one codec in that container is | |
| 465 // supported. | |
| 466 SupportedCodecs supported_codecs = | |
| 467 GetCodecMaskForContainer(canonical_container); | |
| 468 return (supported_codecs & key_system_supported_codecs) != 0; | |
| 469 } | |
| 470 | |
| 471 bool KeySystemsImpl::IsSupportedContainerAndCodecs( | |
| 472 const std::string& container, | |
| 473 const std::vector<std::string>& codecs, | |
| 474 SupportedCodecs key_system_supported_codecs) const { | |
| 475 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 476 DCHECK(!container.empty()); | |
| 477 DCHECK(!codecs.empty()); | |
| 478 DCHECK(IsSupportedContainer(container, key_system_supported_codecs)); | |
| 479 | |
| 480 SupportedCodecs container_supported_codecs = | |
| 481 GetCodecMaskForContainer(container); | |
| 482 | |
| 483 for (size_t i = 0; i < codecs.size(); ++i) { | |
| 484 if (codecs[i].empty()) | |
| 485 continue; | |
| 486 | |
| 487 EmeCodec codec = GetCodecForString(codecs[i]); | |
| 488 | |
| 489 // Unsupported codec. | |
| 490 if (!(codec & key_system_supported_codecs)) | |
| 491 return false; | |
| 492 | |
| 493 // Unsupported codec/container combination, e.g. "video/webm" and "avc1". | |
| 494 if (!(codec & container_supported_codecs)) | |
| 495 return false; | |
| 496 } | |
| 497 | |
| 498 return true; | |
| 499 } | |
| 500 | |
| 501 bool KeySystemsImpl::IsSupportedInitDataType( | 471 bool KeySystemsImpl::IsSupportedInitDataType( |
| 502 const std::string& key_system, | 472 const std::string& key_system, |
| 503 EmeInitDataType init_data_type) const { | 473 EmeInitDataType init_data_type) const { |
| 504 DCHECK(thread_checker_.CalledOnValidThread()); | 474 DCHECK(thread_checker_.CalledOnValidThread()); |
| 505 | 475 |
| 506 // Locate |key_system|. Only concrete key systems are supported. | 476 // Locate |key_system|. Only concrete key systems are supported. |
| 507 KeySystemInfoMap::const_iterator key_system_iter = | 477 KeySystemInfoMap::const_iterator key_system_iter = |
| 508 concrete_key_system_map_.find(key_system); | 478 concrete_key_system_map_.find(key_system); |
| 509 if (key_system_iter == concrete_key_system_map_.end()) { | 479 if (key_system_iter == concrete_key_system_map_.end()) { |
| 510 NOTREACHED(); | 480 NOTREACHED(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; | 535 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; |
| 566 return std::string(); | 536 return std::string(); |
| 567 } | 537 } |
| 568 | 538 |
| 569 const std::string& type = key_system_iter->second.pepper_type; | 539 const std::string& type = key_system_iter->second.pepper_type; |
| 570 DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based"; | 540 DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based"; |
| 571 return type; | 541 return type; |
| 572 } | 542 } |
| 573 #endif | 543 #endif |
| 574 | 544 |
| 575 void KeySystemsImpl::AddContainerMask(const std::string& container, | |
| 576 uint32_t mask) { | |
| 577 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 578 DCHECK(!container_to_codec_mask_map_.count(container)); | |
| 579 container_to_codec_mask_map_[container] = static_cast<EmeCodec>(mask); | |
| 580 } | |
| 581 | |
| 582 void KeySystemsImpl::AddCodecMask(EmeMediaType media_type, | 545 void KeySystemsImpl::AddCodecMask(EmeMediaType media_type, |
| 583 const std::string& codec, | 546 const std::string& codec, |
| 584 uint32_t mask) { | 547 uint32_t mask) { |
| 585 DCHECK(thread_checker_.CalledOnValidThread()); | 548 DCHECK(thread_checker_.CalledOnValidThread()); |
| 586 DCHECK(!codec_string_map_.count(codec)); | 549 DCHECK(!codec_string_map_.count(codec)); |
| 587 codec_string_map_[codec] = static_cast<EmeCodec>(mask); | 550 codec_string_map_[codec] = static_cast<EmeCodec>(mask); |
| 588 if (media_type == EmeMediaType::AUDIO) { | 551 if (media_type == EmeMediaType::AUDIO) { |
| 589 audio_codec_mask_ |= mask; | 552 audio_codec_mask_ |= mask; |
| 590 } else { | 553 } else { |
| 591 video_codec_mask_ |= mask; | 554 video_codec_mask_ |= mask; |
| 592 } | 555 } |
| 593 } | 556 } |
| 594 | 557 |
| 558 void KeySystemsImpl::AddMimeTypeCodecMask(const std::string& mime_type, |
| 559 uint32_t codecs_mask) { |
| 560 RegisterMimeType(mime_type, static_cast<EmeCodec>(codecs_mask)); |
| 561 } |
| 562 |
| 595 bool KeySystemsImpl::IsSupportedKeySystem(const std::string& key_system) const { | 563 bool KeySystemsImpl::IsSupportedKeySystem(const std::string& key_system) const { |
| 596 DCHECK(thread_checker_.CalledOnValidThread()); | 564 DCHECK(thread_checker_.CalledOnValidThread()); |
| 597 | 565 |
| 598 if (!IsConcreteSupportedKeySystem(key_system)) | 566 if (!IsConcreteSupportedKeySystem(key_system)) |
| 599 return false; | 567 return false; |
| 600 | 568 |
| 601 // TODO(ddorwin): Move this to where we add key systems when prefixed EME is | 569 // TODO(ddorwin): Move this to where we add key systems when prefixed EME is |
| 602 // removed (crbug.com/249976). | 570 // removed (crbug.com/249976). |
| 603 if (!IsPotentiallySupportedKeySystem(key_system)) { | 571 if (!IsPotentiallySupportedKeySystem(key_system)) { |
| 604 // If you encounter this path, see the comments for the above function. | 572 // If you encounter this path, see the comments for the above function. |
| 605 DLOG(ERROR) << "Unrecognized key system " << key_system | 573 DLOG(ERROR) << "Unrecognized key system " << key_system |
| 606 << ". See code comments."; | 574 << ". See code comments."; |
| 607 return false; | 575 return false; |
| 608 } | 576 } |
| 609 | 577 |
| 610 return true; | 578 return true; |
| 611 } | 579 } |
| 612 | 580 |
| 613 EmeConfigRule KeySystemsImpl::GetContentTypeConfigRule( | 581 EmeConfigRule KeySystemsImpl::GetContentTypeConfigRule( |
| 614 const std::string& key_system, | 582 const std::string& key_system, |
| 615 EmeMediaType media_type, | 583 EmeMediaType media_type, |
| 616 const std::string& container_mime_type, | 584 const std::string& container_mime_type, |
| 617 const std::vector<std::string>& codecs) const { | 585 const std::vector<std::string>& codecs) const { |
| 618 DCHECK(thread_checker_.CalledOnValidThread()); | 586 DCHECK(thread_checker_.CalledOnValidThread()); |
| 619 | 587 |
| 620 // Make sure the container matches |media_type|. | 588 // Make sure the container MIME type matches |media_type|. |
| 621 SupportedCodecs media_type_codec_mask = EME_CODEC_NONE; | |
| 622 switch (media_type) { | 589 switch (media_type) { |
| 623 case EmeMediaType::AUDIO: | 590 case EmeMediaType::AUDIO: |
| 624 if (!base::StartsWith(container_mime_type, "audio/", | 591 if (!base::StartsWith(container_mime_type, "audio/", |
| 625 base::CompareCase::SENSITIVE)) | 592 base::CompareCase::SENSITIVE)) |
| 626 return EmeConfigRule::NOT_SUPPORTED; | 593 return EmeConfigRule::NOT_SUPPORTED; |
| 627 media_type_codec_mask = audio_codec_mask_; | |
| 628 break; | 594 break; |
| 629 case EmeMediaType::VIDEO: | 595 case EmeMediaType::VIDEO: |
| 630 if (!base::StartsWith(container_mime_type, "video/", | 596 if (!base::StartsWith(container_mime_type, "video/", |
| 631 base::CompareCase::SENSITIVE)) | 597 base::CompareCase::SENSITIVE)) |
| 632 return EmeConfigRule::NOT_SUPPORTED; | 598 return EmeConfigRule::NOT_SUPPORTED; |
| 633 media_type_codec_mask = video_codec_mask_; | |
| 634 break; | 599 break; |
| 635 } | 600 } |
| 636 | 601 |
| 637 // Look up the key system's supported codecs. | 602 // Look up the key system's supported codecs. |
| 638 KeySystemInfoMap::const_iterator key_system_iter = | 603 KeySystemInfoMap::const_iterator key_system_iter = |
| 639 concrete_key_system_map_.find(key_system); | 604 concrete_key_system_map_.find(key_system); |
| 640 if (key_system_iter == concrete_key_system_map_.end()) { | 605 if (key_system_iter == concrete_key_system_map_.end()) { |
| 641 NOTREACHED(); | 606 NOTREACHED(); |
| 642 return EmeConfigRule::NOT_SUPPORTED; | 607 return EmeConfigRule::NOT_SUPPORTED; |
| 643 } | 608 } |
| 644 SupportedCodecs key_system_codec_mask = | 609 SupportedCodecs key_system_codec_mask = |
| 645 key_system_iter->second.supported_codecs; | 610 key_system_iter->second.supported_codecs; |
| 646 #if defined(OS_ANDROID) | 611 #if defined(OS_ANDROID) |
| 647 SupportedCodecs key_system_secure_codec_mask = | 612 SupportedCodecs key_system_secure_codec_mask = |
| 648 key_system_iter->second.supported_secure_codecs; | 613 key_system_iter->second.supported_secure_codecs; |
| 649 #endif // defined(OS_ANDROID) | 614 #endif // defined(OS_ANDROID) |
| 650 | 615 |
| 651 | 616 |
| 652 // Check that the container is supported by the key system. (This check is | 617 // Check that the container is supported by the key system. (This check is |
| 653 // necessary because |codecs| may be empty.) | 618 // necessary because |codecs| may be empty.) |
| 654 SupportedCodecs container_codec_mask = | 619 SupportedCodecs mime_type_codec_mask = |
| 655 GetCodecMaskForContainer(container_mime_type) & media_type_codec_mask; | 620 GetCodecMaskForMimeType(container_mime_type); |
| 656 if ((key_system_codec_mask & container_codec_mask) == 0) | 621 if ((key_system_codec_mask & mime_type_codec_mask) == 0) |
| 657 return EmeConfigRule::NOT_SUPPORTED; | 622 return EmeConfigRule::NOT_SUPPORTED; |
| 658 | 623 |
| 659 // Check that the codecs are supported by the key system and container. | 624 // Check that the codecs are supported by the key system and container. |
| 660 EmeConfigRule support = EmeConfigRule::SUPPORTED; | 625 EmeConfigRule support = EmeConfigRule::SUPPORTED; |
| 661 for (size_t i = 0; i < codecs.size(); i++) { | 626 for (size_t i = 0; i < codecs.size(); i++) { |
| 662 SupportedCodecs codec = GetCodecForString(codecs[i]); | 627 SupportedCodecs codec = GetCodecForString(codecs[i]); |
| 663 if ((codec & key_system_codec_mask & container_codec_mask) == 0) | 628 if ((codec & key_system_codec_mask & mime_type_codec_mask) == 0) |
| 664 return EmeConfigRule::NOT_SUPPORTED; | 629 return EmeConfigRule::NOT_SUPPORTED; |
| 665 #if defined(OS_ANDROID) | 630 #if defined(OS_ANDROID) |
| 666 // Check whether the codec supports a hardware-secure mode. The goal is to | 631 // Check whether the codec supports a hardware-secure mode. The goal is to |
| 667 // prevent mixing of non-hardware-secure codecs with hardware-secure codecs, | 632 // prevent mixing of non-hardware-secure codecs with hardware-secure codecs, |
| 668 // since the mode is fixed at CDM creation. | 633 // since the mode is fixed at CDM creation. |
| 669 // | 634 // |
| 670 // Because the check for regular codec support is early-exit, we don't have | 635 // Because the check for regular codec support is early-exit, we don't have |
| 671 // to consider codecs that are only supported in hardware-secure mode. We | 636 // to consider codecs that are only supported in hardware-secure mode. We |
| 672 // could do so, and make use of HW_SECURE_CODECS_REQUIRED, if it turns out | 637 // could do so, and make use of HW_SECURE_CODECS_REQUIRED, if it turns out |
| 673 // that hardware-secure-only codecs actually exist and are useful. | 638 // that hardware-secure-only codecs actually exist and are useful. |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 return KeySystemsImpl::GetInstance()->GetPepperType(concrete_key_system); | 792 return KeySystemsImpl::GetInstance()->GetPepperType(concrete_key_system); |
| 828 } | 793 } |
| 829 #endif | 794 #endif |
| 830 | 795 |
| 831 // These two functions are for testing purpose only. The declaration in the | 796 // These two functions are for testing purpose only. The declaration in the |
| 832 // header file is guarded by "#if defined(UNIT_TEST)" so that they can be used | 797 // header file is guarded by "#if defined(UNIT_TEST)" so that they can be used |
| 833 // by tests but not non-test code. However, this .cc file is compiled as part of | 798 // by tests but not non-test code. However, this .cc file is compiled as part of |
| 834 // "media" where "UNIT_TEST" is not defined. So we need to specify | 799 // "media" where "UNIT_TEST" is not defined. So we need to specify |
| 835 // "MEDIA_EXPORT" here again so that they are visible to tests. | 800 // "MEDIA_EXPORT" here again so that they are visible to tests. |
| 836 | 801 |
| 837 MEDIA_EXPORT void AddContainerMask(const std::string& container, | |
| 838 uint32_t mask) { | |
| 839 KeySystemsImpl::GetInstance()->AddContainerMask(container, mask); | |
| 840 } | |
| 841 | |
| 842 MEDIA_EXPORT void AddCodecMask(EmeMediaType media_type, | 802 MEDIA_EXPORT void AddCodecMask(EmeMediaType media_type, |
| 843 const std::string& codec, | 803 const std::string& codec, |
| 844 uint32_t mask) { | 804 uint32_t mask) { |
| 845 KeySystemsImpl::GetInstance()->AddCodecMask(media_type, codec, mask); | 805 KeySystemsImpl::GetInstance()->AddCodecMask(media_type, codec, mask); |
| 846 } | 806 } |
| 847 | 807 |
| 808 MEDIA_EXPORT void AddMimeTypeCodecMask(const std::string& mime_type, |
| 809 uint32_t mask) { |
| 810 KeySystemsImpl::GetInstance()->AddMimeTypeCodecMask(mime_type, mask); |
| 811 } |
| 812 |
| 848 } // namespace media | 813 } // namespace media |
| OLD | NEW |