diff options
author | ddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-10 02:52:25 +0000 |
---|---|---|
committer | ddorwin@chromium.org <ddorwin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-10 02:52:25 +0000 |
commit | c470860e23bcd9c1567437a6dee7cf13ec536535 (patch) | |
tree | 7af8c08ad1a830fb7c4c99fba5a6b60ebff84763 /webkit/media | |
parent | 4c87dd507a5c2cbb95d936e9bfbaef7b00ec3f8e (diff) | |
download | chromium_src-c470860e23bcd9c1567437a6dee7cf13ec536535.zip chromium_src-c470860e23bcd9c1567437a6dee7cf13ec536535.tar.gz chromium_src-c470860e23bcd9c1567437a6dee7cf13ec536535.tar.bz2 |
Build the list of key system/container/codec combinations at runtime.
This is more similar to how net/base/mime_util.cc works and avoids combinatorial explosion.
TEST=encrypted-media-can-play-type*.html
Review URL: https://chromiumcodereview.appspot.com/11081005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161026 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/media')
-rw-r--r-- | webkit/media/crypto/key_systems.cc | 148 |
1 files changed, 116 insertions, 32 deletions
diff --git a/webkit/media/crypto/key_systems.cc b/webkit/media/crypto/key_systems.cc index b85c9c4..1b571d8 100644 --- a/webkit/media/crypto/key_systems.cc +++ b/webkit/media/crypto/key_systems.cc @@ -2,20 +2,32 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <map> + #include "webkit/media/crypto/key_systems.h" +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/string_util.h" +#include "net/base/mime_util.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" namespace webkit_media { +// Convert a WebString to ASCII, falling back on an empty string in the case +// of a non-ASCII string. +static std::string ToASCIIOrEmpty(const WebKit::WebString& string) { + return IsStringASCII(string) ? UTF16ToASCII(string) : std::string(); +} + static const char kClearKeyKeySystem[] = "webkit-org.w3.clearkey"; static const char kExternalClearKeyKeySystem[] = "org.chromium.externalclearkey"; struct MediaFormatAndKeySystem { const char* mime_type; - const char* codec; + const char* codecs_list; const char* key_system; }; @@ -24,26 +36,19 @@ struct KeySystemPluginTypePair { const char* plugin_type; }; +// Specifies the container and codec combinations supported by individual +// key systems. Each line is a container-codecs combination and the key system +// that supports it. Multiple codecs can be listed. A trailing commas in +// the |codecs_list| allows the container to be specified without a codec. +// This list is converted at runtime into individual container-codec-key system +// entries in KeySystems::key_system_map_. static const MediaFormatAndKeySystem supported_format_key_system_combinations[] = { - // TODO(ddorwin): Reconsider based on how usage of this class evolves. - // For now, this class is stateless, so we do not have the opportunity to - // build a list using ParseCodecString() like - // net::MimeUtil::InitializeMimeTypeMaps(). Therefore, the following line must - // be separate entries. - // { "video/webm", "vorbis,vp8,vp8.0", kClearKeyKeySystem }, - { "video/webm", "vorbis", kClearKeyKeySystem }, - { "video/webm", "vp8", kClearKeyKeySystem }, - { "video/webm", "vp8.0", kClearKeyKeySystem }, - { "audio/webm", "vorbis", kClearKeyKeySystem }, - { "video/webm", "", kClearKeyKeySystem }, - { "audio/webm", "", kClearKeyKeySystem }, - { "video/webm", "vorbis", kExternalClearKeyKeySystem }, - { "video/webm", "vp8", kExternalClearKeyKeySystem }, - { "video/webm", "vp8.0", kExternalClearKeyKeySystem }, - { "audio/webm", "vorbis", kExternalClearKeyKeySystem }, - { "video/webm", "", kExternalClearKeyKeySystem }, - { "audio/webm", "", kExternalClearKeyKeySystem } + { "video/webm", "vorbis,vp8,vp8.0,", kClearKeyKeySystem }, + { "audio/webm", "vorbis,", kClearKeyKeySystem }, + + { "video/webm", "vorbis,vp8,vp8.0,", kExternalClearKeyKeySystem }, + { "audio/webm", "vorbis,", kExternalClearKeyKeySystem }, }; static const KeySystemPluginTypePair key_system_to_plugin_type_mapping[] = { @@ -51,30 +56,97 @@ static const KeySystemPluginTypePair key_system_to_plugin_type_mapping[] = { { kExternalClearKeyKeySystem, "application/x-ppapi-clearkey-cdm" } }; -static bool IsSupportedKeySystemWithContainerAndCodec( - const std::string& mime_type, - const std::string& codec, - const std::string& key_system) { +class KeySystems { + public: + bool IsSupportedKeySystem(const std::string& key_system); + + bool IsSupportedKeySystemWithMediaMimeType( + const std::string& mime_type, + const std::vector<std::string>& codecs, + const std::string& key_system); + + private: + friend struct base::DefaultLazyInstanceTraits<KeySystems>; + + typedef base::hash_set<std::string> CodecMappings; + typedef std::map<std::string, CodecMappings> MimeTypeMappings; + typedef std::map<std::string, MimeTypeMappings> KeySystemMappings; + + KeySystems(); + + bool IsSupportedKeySystemWithContainerAndCodec( + const std::string& mime_type, + const std::string& codec, + const std::string& key_system); + + KeySystemMappings key_system_map_; +}; + +static base::LazyInstance<KeySystems> g_key_systems = LAZY_INSTANCE_INITIALIZER; + +KeySystems::KeySystems() { + // Initialize the supported media type/key system combinations. for (size_t i = 0; i < arraysize(supported_format_key_system_combinations); ++i) { const MediaFormatAndKeySystem& combination = supported_format_key_system_combinations[i]; - if (combination.mime_type == mime_type && - combination.codec == codec && - combination.key_system == key_system) - return true; + std::vector<std::string> mime_type_codecs; + net::ParseCodecString(combination.codecs_list, + &mime_type_codecs, + false); + + CodecMappings codecs; + for (size_t j = 0; j < mime_type_codecs.size(); ++j) + codecs.insert(mime_type_codecs[j]); + + // Key systems can be repeated, so there may already be an entry. + KeySystemMappings::iterator key_system_iter = + key_system_map_.find(combination.key_system); + if (key_system_iter == key_system_map_.end()) { + MimeTypeMappings mime_types_map; + mime_types_map[combination.mime_type] = codecs; + key_system_map_[combination.key_system] = mime_types_map; + } else { + MimeTypeMappings& mime_types_map = key_system_iter->second; + // mime_types_map may not be repeated for a given key system. + DCHECK(mime_types_map.find(combination.mime_type) == + mime_types_map.end()); + mime_types_map[combination.mime_type] = codecs; + } } +} + +bool KeySystems::IsSupportedKeySystem(const std::string& key_system) { + bool is_supported = key_system_map_.find(key_system) != key_system_map_.end(); - return false; + DCHECK_EQ(is_supported, + (CanUseAesDecryptor(key_system) || + !GetPluginType(key_system).empty())) + << "key_system_map_ & key_system_to_plugin_type_mapping are inconsistent"; + return is_supported; } -bool IsSupportedKeySystem(const WebKit::WebString& key_system) { - return CanUseAesDecryptor(key_system.utf8().data()) || - !GetPluginType(key_system.utf8().data()).empty(); +bool KeySystems::IsSupportedKeySystemWithContainerAndCodec( + const std::string& mime_type, + const std::string& codec, + const std::string& key_system) { + + KeySystemMappings::const_iterator key_system_iter = + key_system_map_.find(key_system); + if (key_system_iter == key_system_map_.end()) + return false; + + const MimeTypeMappings& mime_types_map = key_system_iter->second; + MimeTypeMappings::const_iterator mime_iter = mime_types_map.find(mime_type); + if (mime_iter == mime_types_map.end()) + return false; + + const CodecMappings& codecs = mime_iter->second; + return (codecs.find(codec) != codecs.end()); } -bool IsSupportedKeySystemWithMediaMimeType( +bool KeySystems::IsSupportedKeySystemWithMediaMimeType( const std::string& mime_type, const std::vector<std::string>& codecs, const std::string& key_system) { @@ -90,6 +162,18 @@ bool IsSupportedKeySystemWithMediaMimeType( return true; } +bool IsSupportedKeySystem(const WebKit::WebString& key_system) { + return g_key_systems.Get().IsSupportedKeySystem(ToASCIIOrEmpty(key_system)); +} + +bool IsSupportedKeySystemWithMediaMimeType( + const std::string& mime_type, + const std::vector<std::string>& codecs, + const std::string& key_system) { + return g_key_systems.Get().IsSupportedKeySystemWithMediaMimeType( + mime_type, codecs, key_system); +} + bool CanUseAesDecryptor(const std::string& key_system) { return key_system == kClearKeyKeySystem; } |