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 <string> | 7 #include <string> |
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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 }; | 44 }; |
45 | 45 |
46 struct NamedCodec { | 46 struct NamedCodec { |
47 const char* name; | 47 const char* name; |
48 EmeCodec type; | 48 EmeCodec type; |
49 }; | 49 }; |
50 | 50 |
51 // Mapping between containers and their codecs. | 51 // Mapping between containers and their codecs. |
52 // Only audio codec can belong to a "audio/*" container. Both audio and video | 52 // Only audio codec can belong to a "audio/*" container. Both audio and video |
53 // codecs can belong to a "video/*" container. | 53 // codecs can belong to a "video/*" container. |
54 // TODO(sandersd): This definition only makes sense for prefixed EME. | |
ddorwin
2015/03/24 22:36:35
Are you planning to deal with this before removing
sandersd (OOO until July 31)
2015/03/24 23:26:36
Done.
| |
54 static NamedCodec kContainerToCodecMasks[] = { | 55 static NamedCodec kContainerToCodecMasks[] = { |
55 {"audio/webm", EME_CODEC_WEBM_AUDIO_ALL}, | 56 {"audio/webm", EME_CODEC_WEBM_AUDIO_ALL}, |
56 {"video/webm", EME_CODEC_WEBM_ALL}, | 57 {"video/webm", EME_CODEC_WEBM_ALL}, |
57 #if defined(USE_PROPRIETARY_CODECS) | 58 #if defined(USE_PROPRIETARY_CODECS) |
58 {"audio/mp4", EME_CODEC_MP4_AUDIO_ALL}, | 59 {"audio/mp4", EME_CODEC_MP4_AUDIO_ALL}, |
59 {"video/mp4", EME_CODEC_MP4_ALL} | 60 {"video/mp4", EME_CODEC_MP4_ALL} |
60 #endif // defined(USE_PROPRIETARY_CODECS) | 61 #endif // defined(USE_PROPRIETARY_CODECS) |
61 }; | 62 }; |
62 | 63 |
63 // Mapping between codec names and enum values. | 64 // Mapping between codec names and enum values. |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 | 205 |
205 bool IsSupportedKeySystemWithInitDataType( | 206 bool IsSupportedKeySystemWithInitDataType( |
206 const std::string& key_system, | 207 const std::string& key_system, |
207 const std::string& init_data_type) const; | 208 const std::string& init_data_type) const; |
208 | 209 |
209 bool PrefixedIsSupportedKeySystemWithMediaMimeType( | 210 bool PrefixedIsSupportedKeySystemWithMediaMimeType( |
210 const std::string& mime_type, | 211 const std::string& mime_type, |
211 const std::vector<std::string>& codecs, | 212 const std::vector<std::string>& codecs, |
212 const std::string& key_system); | 213 const std::string& key_system); |
213 | 214 |
214 bool IsSupportedKeySystemWithMediaMimeType( | |
215 const std::string& mime_type, | |
216 const std::vector<std::string>& codecs, | |
217 const std::string& key_system) const; | |
218 | |
219 std::string GetKeySystemNameForUMA(const std::string& key_system) const; | 215 std::string GetKeySystemNameForUMA(const std::string& key_system) const; |
220 | 216 |
221 bool UseAesDecryptor(const std::string& concrete_key_system) const; | 217 bool UseAesDecryptor(const std::string& concrete_key_system) const; |
222 | 218 |
223 #if defined(ENABLE_PEPPER_CDMS) | 219 #if defined(ENABLE_PEPPER_CDMS) |
224 std::string GetPepperType(const std::string& concrete_key_system) const; | 220 std::string GetPepperType(const std::string& concrete_key_system) const; |
225 #endif | 221 #endif |
226 | 222 |
227 void AddContainerMask(const std::string& container, uint32 mask); | 223 void AddContainerMask(const std::string& container, uint32 mask); |
228 void AddCodecMask(const std::string& codec, uint32 mask); | 224 void AddCodecMask( |
225 EmeMediaType media_type, | |
226 const std::string& codec, | |
227 uint32 mask); | |
229 | 228 |
230 // Implementation of KeySystems interface. | 229 // Implementation of KeySystems interface. |
231 bool IsSupportedKeySystem(const std::string& key_system) const override; | 230 bool IsSupportedKeySystem(const std::string& key_system) const override; |
232 | 231 |
233 bool IsSupportedCodecCombination( | 232 bool IsSupportedCodecCombination( |
234 const std::string& key_system, | 233 const std::string& key_system, |
235 EmeMediaType media_type, | 234 EmeMediaType media_type, |
236 const std::string& container_mime_type, | 235 const std::string& container_mime_type, |
237 const std::vector<std::string>& codecs) const override; | 236 const std::vector<std::string>& codecs) const override; |
238 | 237 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 // to represent its capabilities. | 305 // to represent its capabilities. |
307 ParentKeySystemMap parent_key_system_map_; | 306 ParentKeySystemMap parent_key_system_map_; |
308 | 307 |
309 KeySystemsSupportUMA key_systems_support_uma_; | 308 KeySystemsSupportUMA key_systems_support_uma_; |
310 | 309 |
311 InitDataTypesMap init_data_type_name_map_; | 310 InitDataTypesMap init_data_type_name_map_; |
312 ContainerCodecsMap container_to_codec_mask_map_; | 311 ContainerCodecsMap container_to_codec_mask_map_; |
313 CodecsMap codec_string_map_; | 312 CodecsMap codec_string_map_; |
314 KeySystemNameForUMAMap key_system_name_for_uma_map_; | 313 KeySystemNameForUMAMap key_system_name_for_uma_map_; |
315 | 314 |
315 SupportedCodecs audio_codec_mask_; | |
316 SupportedCodecs video_codec_mask_; | |
317 | |
316 // Makes sure all methods are called from the same thread. | 318 // Makes sure all methods are called from the same thread. |
317 base::ThreadChecker thread_checker_; | 319 base::ThreadChecker thread_checker_; |
318 | 320 |
319 DISALLOW_COPY_AND_ASSIGN(KeySystemsImpl); | 321 DISALLOW_COPY_AND_ASSIGN(KeySystemsImpl); |
320 }; | 322 }; |
321 | 323 |
322 static base::LazyInstance<KeySystemsImpl> g_key_systems = | 324 static base::LazyInstance<KeySystemsImpl> g_key_systems = |
323 LAZY_INSTANCE_INITIALIZER; | 325 LAZY_INSTANCE_INITIALIZER; |
324 | 326 |
325 KeySystemsImpl& KeySystemsImpl::GetInstance() { | 327 KeySystemsImpl& KeySystemsImpl::GetInstance() { |
(...skipping 13 matching lines...) Expand all Loading... | |
339 for (size_t i = 0; i < arraysize(kContainerToCodecMasks); ++i) { | 341 for (size_t i = 0; i < arraysize(kContainerToCodecMasks); ++i) { |
340 const std::string& name = kContainerToCodecMasks[i].name; | 342 const std::string& name = kContainerToCodecMasks[i].name; |
341 DCHECK(!container_to_codec_mask_map_.count(name)); | 343 DCHECK(!container_to_codec_mask_map_.count(name)); |
342 container_to_codec_mask_map_[name] = kContainerToCodecMasks[i].type; | 344 container_to_codec_mask_map_[name] = kContainerToCodecMasks[i].type; |
343 } | 345 } |
344 for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { | 346 for (size_t i = 0; i < arraysize(kCodecStrings); ++i) { |
345 const std::string& name = kCodecStrings[i].name; | 347 const std::string& name = kCodecStrings[i].name; |
346 DCHECK(!codec_string_map_.count(name)); | 348 DCHECK(!codec_string_map_.count(name)); |
347 codec_string_map_[name] = kCodecStrings[i].type; | 349 codec_string_map_[name] = kCodecStrings[i].type; |
348 } | 350 } |
351 audio_codec_mask_ = EME_CODEC_AUDIO_ALL; | |
ddorwin
2015/03/24 22:36:35
Move to initializer list?
sandersd (OOO until July 31)
2015/03/24 23:26:36
Done.
| |
352 video_codec_mask_ = EME_CODEC_VIDEO_ALL; | |
349 | 353 |
350 InitializeUMAInfo(); | 354 InitializeUMAInfo(); |
351 | 355 |
352 // Always update supported key systems during construction. | 356 // Always update supported key systems during construction. |
353 UpdateSupportedKeySystems(); | 357 UpdateSupportedKeySystems(); |
354 } | 358 } |
355 | 359 |
356 EmeInitDataType KeySystemsImpl::GetInitDataTypeForName( | 360 EmeInitDataType KeySystemsImpl::GetInitDataTypeForName( |
357 const std::string& init_data_type) const { | 361 const std::string& init_data_type) const { |
358 InitDataTypesMap::const_iterator iter = | 362 InitDataTypesMap::const_iterator iter = |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
547 SupportedCodecs key_system_supported_codecs) const { | 551 SupportedCodecs key_system_supported_codecs) const { |
548 DCHECK(thread_checker_.CalledOnValidThread()); | 552 DCHECK(thread_checker_.CalledOnValidThread()); |
549 DCHECK(!container.empty()); | 553 DCHECK(!container.empty()); |
550 DCHECK(!codecs.empty()); | 554 DCHECK(!codecs.empty()); |
551 DCHECK(IsSupportedContainer(container, key_system_supported_codecs)); | 555 DCHECK(IsSupportedContainer(container, key_system_supported_codecs)); |
552 | 556 |
553 SupportedCodecs container_supported_codecs = | 557 SupportedCodecs container_supported_codecs = |
554 GetCodecMaskForContainer(container); | 558 GetCodecMaskForContainer(container); |
555 | 559 |
556 for (size_t i = 0; i < codecs.size(); ++i) { | 560 for (size_t i = 0; i < codecs.size(); ++i) { |
557 // TODO(sandersd): This should fail for isTypeSupported(). | |
558 // http://crbug.com/417461 | |
559 if (codecs[i].empty()) | 561 if (codecs[i].empty()) |
560 continue; | 562 continue; |
561 | 563 |
562 EmeCodec codec = GetCodecForString(codecs[i]); | 564 EmeCodec codec = GetCodecForString(codecs[i]); |
563 | 565 |
564 // Unsupported codec. | 566 // Unsupported codec. |
565 if (!(codec & key_system_supported_codecs)) | 567 if (!(codec & key_system_supported_codecs)) |
566 return false; | 568 return false; |
567 | 569 |
568 // Unsupported codec/container combination, e.g. "video/webm" and "avc1". | 570 // Unsupported codec/container combination, e.g. "video/webm" and "avc1". |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
626 !IsSupportedContainerAndCodecs( | 628 !IsSupportedContainerAndCodecs( |
627 mime_type, codecs, key_system_supported_codecs)) { | 629 mime_type, codecs, key_system_supported_codecs)) { |
628 return false; | 630 return false; |
629 } | 631 } |
630 | 632 |
631 key_systems_support_uma_.ReportKeySystemSupport(key_system, true); | 633 key_systems_support_uma_.ReportKeySystemSupport(key_system, true); |
632 | 634 |
633 return true; | 635 return true; |
634 } | 636 } |
635 | 637 |
636 bool KeySystemsImpl::IsSupportedKeySystemWithMediaMimeType( | |
637 const std::string& mime_type, | |
638 const std::vector<std::string>& codecs, | |
639 const std::string& key_system) const { | |
640 DCHECK(thread_checker_.CalledOnValidThread()); | |
641 | |
642 KeySystemInfoMap::const_iterator key_system_iter = | |
643 concrete_key_system_map_.find(key_system); | |
644 if (key_system_iter == concrete_key_system_map_.end()) | |
645 return false; | |
646 | |
647 if (mime_type.empty()) { | |
648 DCHECK(codecs.empty()); | |
649 return true; | |
650 } | |
651 | |
652 SupportedCodecs key_system_supported_codecs = | |
653 key_system_iter->second.supported_codecs; | |
654 | |
655 if (!IsSupportedContainer(mime_type, key_system_supported_codecs)) | |
656 return false; | |
657 | |
658 if (!codecs.empty() && | |
659 !IsSupportedContainerAndCodecs( | |
660 mime_type, codecs, key_system_supported_codecs)) { | |
661 return false; | |
662 } | |
663 | |
664 return true; | |
665 } | |
666 | |
667 std::string KeySystemsImpl::GetKeySystemNameForUMA( | 638 std::string KeySystemsImpl::GetKeySystemNameForUMA( |
668 const std::string& key_system) const { | 639 const std::string& key_system) const { |
669 DCHECK(thread_checker_.CalledOnValidThread()); | 640 DCHECK(thread_checker_.CalledOnValidThread()); |
670 | 641 |
671 KeySystemNameForUMAMap::const_iterator iter = | 642 KeySystemNameForUMAMap::const_iterator iter = |
672 key_system_name_for_uma_map_.find(key_system); | 643 key_system_name_for_uma_map_.find(key_system); |
673 if (iter == key_system_name_for_uma_map_.end()) | 644 if (iter == key_system_name_for_uma_map_.end()) |
674 return kUnknownKeySystemNameForUMA; | 645 return kUnknownKeySystemNameForUMA; |
675 | 646 |
676 return iter->second; | 647 return iter->second; |
(...skipping 24 matching lines...) Expand all Loading... | |
701 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; | 672 DLOG(FATAL) << concrete_key_system << " is not a known concrete system"; |
702 return std::string(); | 673 return std::string(); |
703 } | 674 } |
704 | 675 |
705 const std::string& type = key_system_iter->second.pepper_type; | 676 const std::string& type = key_system_iter->second.pepper_type; |
706 DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based"; | 677 DLOG_IF(FATAL, type.empty()) << concrete_key_system << " is not Pepper-based"; |
707 return type; | 678 return type; |
708 } | 679 } |
709 #endif | 680 #endif |
710 | 681 |
711 void KeySystemsImpl::AddContainerMask(const std::string& container, | 682 void KeySystemsImpl::AddContainerMask( |
712 uint32 mask) { | 683 const std::string& container, |
684 uint32 mask) { | |
713 DCHECK(thread_checker_.CalledOnValidThread()); | 685 DCHECK(thread_checker_.CalledOnValidThread()); |
714 DCHECK(!container_to_codec_mask_map_.count(container)); | 686 DCHECK(!container_to_codec_mask_map_.count(container)); |
715 container_to_codec_mask_map_[container] = static_cast<EmeCodec>(mask); | 687 container_to_codec_mask_map_[container] = static_cast<EmeCodec>(mask); |
716 } | 688 } |
717 | 689 |
718 void KeySystemsImpl::AddCodecMask(const std::string& codec, uint32 mask) { | 690 void KeySystemsImpl::AddCodecMask( |
691 EmeMediaType media_type, | |
692 const std::string& codec, | |
693 uint32 mask) { | |
719 DCHECK(thread_checker_.CalledOnValidThread()); | 694 DCHECK(thread_checker_.CalledOnValidThread()); |
720 DCHECK(!codec_string_map_.count(codec)); | 695 DCHECK(!codec_string_map_.count(codec)); |
721 codec_string_map_[codec] = static_cast<EmeCodec>(mask); | 696 codec_string_map_[codec] = static_cast<EmeCodec>(mask); |
697 if (media_type == EmeMediaType::AUDIO) { | |
698 audio_codec_mask_ |= mask; | |
699 } else { | |
700 video_codec_mask_ |= mask; | |
701 } | |
722 } | 702 } |
723 | 703 |
724 bool KeySystemsImpl::IsSupportedKeySystem(const std::string& key_system) const { | 704 bool KeySystemsImpl::IsSupportedKeySystem(const std::string& key_system) const { |
725 DCHECK(thread_checker_.CalledOnValidThread()); | 705 DCHECK(thread_checker_.CalledOnValidThread()); |
726 return concrete_key_system_map_.count(key_system) != 0; | 706 return concrete_key_system_map_.count(key_system) != 0; |
727 } | 707 } |
728 | 708 |
729 // TODO(sandersd): Make sure that the codecs also match the |media_type|. | |
730 // http://crbug.com/457386 | |
731 bool KeySystemsImpl::IsSupportedCodecCombination( | 709 bool KeySystemsImpl::IsSupportedCodecCombination( |
732 const std::string& key_system, | 710 const std::string& key_system, |
733 EmeMediaType media_type, | 711 EmeMediaType media_type, |
734 const std::string& container_mime_type, | 712 const std::string& container_mime_type, |
735 const std::vector<std::string>& codecs) const { | 713 const std::vector<std::string>& codecs) const { |
714 DCHECK(thread_checker_.CalledOnValidThread()); | |
715 | |
736 // Make sure the container matches |media_type|. | 716 // Make sure the container matches |media_type|. |
717 SupportedCodecs media_type_codec_mask = EME_CODEC_NONE; | |
737 switch (media_type) { | 718 switch (media_type) { |
738 case EmeMediaType::AUDIO: | 719 case EmeMediaType::AUDIO: |
739 if (!StartsWithASCII(container_mime_type, "audio/", true)) | 720 if (!StartsWithASCII(container_mime_type, "audio/", true)) |
740 return false; | 721 return false; |
722 media_type_codec_mask = audio_codec_mask_; | |
741 break; | 723 break; |
742 case EmeMediaType::VIDEO: | 724 case EmeMediaType::VIDEO: |
743 if (!StartsWithASCII(container_mime_type, "video/", true)) | 725 if (!StartsWithASCII(container_mime_type, "video/", true)) |
744 return false; | 726 return false; |
727 media_type_codec_mask = video_codec_mask_; | |
745 break; | 728 break; |
746 } | 729 } |
747 return IsSupportedKeySystemWithMediaMimeType( | 730 |
748 container_mime_type, codecs, key_system); | 731 // Look up the key system's supported codecs. |
732 KeySystemInfoMap::const_iterator key_system_iter = | |
733 concrete_key_system_map_.find(key_system); | |
734 if (key_system_iter == concrete_key_system_map_.end()) { | |
735 NOTREACHED(); | |
736 return false; | |
737 } | |
738 SupportedCodecs key_system_codec_mask = | |
739 key_system_iter->second.supported_codecs; | |
740 | |
741 // Check that the container is supported by the key system. (This check is | |
742 // necessary because |codecs| may be empty.) | |
743 SupportedCodecs container_codec_mask = | |
744 GetCodecMaskForContainer(container_mime_type) & media_type_codec_mask; | |
745 if ((key_system_codec_mask & container_codec_mask) == 0) | |
746 return false; | |
747 | |
748 // Check that the codecs are supported by the key system and container. | |
749 for (size_t i = 0; i < codecs.size(); i++) { | |
750 SupportedCodecs codec = GetCodecForString(codecs[i]); | |
751 if ((codec & key_system_codec_mask & container_codec_mask) == 0) | |
752 return false; | |
753 } | |
754 | |
755 return true; | |
749 } | 756 } |
750 | 757 |
751 EmeConfigRule KeySystemsImpl::GetRobustnessConfigRule( | 758 EmeConfigRule KeySystemsImpl::GetRobustnessConfigRule( |
752 const std::string& key_system, | 759 const std::string& key_system, |
753 EmeMediaType media_type, | 760 EmeMediaType media_type, |
754 const std::string& robustness) const { | 761 const std::string& robustness) const { |
755 DCHECK(thread_checker_.CalledOnValidThread()); | 762 DCHECK(thread_checker_.CalledOnValidThread()); |
756 | 763 |
757 EmeRobustness robustness_value = ConvertRobustness(robustness); | 764 EmeRobustness robustness_value = ConvertRobustness(robustness); |
758 if (robustness_value == EmeRobustness::INVALID) | 765 if (robustness_value == EmeRobustness::INVALID) |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
973 return true; | 980 return true; |
974 } | 981 } |
975 | 982 |
976 bool IsSupportedKeySystemWithInitDataType( | 983 bool IsSupportedKeySystemWithInitDataType( |
977 const std::string& key_system, | 984 const std::string& key_system, |
978 const std::string& init_data_type) { | 985 const std::string& init_data_type) { |
979 return KeySystemsImpl::GetInstance().IsSupportedKeySystemWithInitDataType( | 986 return KeySystemsImpl::GetInstance().IsSupportedKeySystemWithInitDataType( |
980 key_system, init_data_type); | 987 key_system, init_data_type); |
981 } | 988 } |
982 | 989 |
983 bool IsSupportedKeySystemWithMediaMimeType( | |
984 const std::string& mime_type, | |
985 const std::vector<std::string>& codecs, | |
986 const std::string& key_system) { | |
987 return KeySystemsImpl::GetInstance().IsSupportedKeySystemWithMediaMimeType( | |
988 mime_type, codecs, key_system); | |
989 } | |
990 | |
991 bool PrefixedIsSupportedKeySystemWithMediaMimeType( | 990 bool PrefixedIsSupportedKeySystemWithMediaMimeType( |
992 const std::string& mime_type, | 991 const std::string& mime_type, |
993 const std::vector<std::string>& codecs, | 992 const std::vector<std::string>& codecs, |
994 const std::string& key_system) { | 993 const std::string& key_system) { |
995 return KeySystemsImpl::GetInstance() | 994 return KeySystemsImpl::GetInstance() |
996 .PrefixedIsSupportedKeySystemWithMediaMimeType(mime_type, codecs, | 995 .PrefixedIsSupportedKeySystemWithMediaMimeType(mime_type, codecs, |
997 key_system); | 996 key_system); |
998 } | 997 } |
999 | 998 |
1000 std::string GetKeySystemNameForUMA(const std::string& key_system) { | 999 std::string GetKeySystemNameForUMA(const std::string& key_system) { |
(...skipping 13 matching lines...) Expand all Loading... | |
1014 // These two functions are for testing purpose only. The declaration in the | 1013 // These two functions are for testing purpose only. The declaration in the |
1015 // header file is guarded by "#if defined(UNIT_TEST)" so that they can be used | 1014 // header file is guarded by "#if defined(UNIT_TEST)" so that they can be used |
1016 // by tests but not non-test code. However, this .cc file is compiled as part of | 1015 // by tests but not non-test code. However, this .cc file is compiled as part of |
1017 // "media" where "UNIT_TEST" is not defined. So we need to specify | 1016 // "media" where "UNIT_TEST" is not defined. So we need to specify |
1018 // "MEDIA_EXPORT" here again so that they are visible to tests. | 1017 // "MEDIA_EXPORT" here again so that they are visible to tests. |
1019 | 1018 |
1020 MEDIA_EXPORT void AddContainerMask(const std::string& container, uint32 mask) { | 1019 MEDIA_EXPORT void AddContainerMask(const std::string& container, uint32 mask) { |
1021 KeySystemsImpl::GetInstance().AddContainerMask(container, mask); | 1020 KeySystemsImpl::GetInstance().AddContainerMask(container, mask); |
1022 } | 1021 } |
1023 | 1022 |
1024 MEDIA_EXPORT void AddCodecMask(const std::string& codec, uint32 mask) { | 1023 MEDIA_EXPORT void AddCodecMask( |
1025 KeySystemsImpl::GetInstance().AddCodecMask(codec, mask); | 1024 EmeMediaType media_type, |
1025 const std::string& codec, | |
1026 uint32 mask) { | |
1027 KeySystemsImpl::GetInstance().AddCodecMask(media_type, codec, mask); | |
1026 } | 1028 } |
1027 | 1029 |
1028 } // namespace media | 1030 } // namespace media |
OLD | NEW |