Chromium Code Reviews| Index: net/base/mime_util.cc |
| diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc |
| index 442910b94c7abd536d0f92ffc4c86c55990f1128..61fc5c3d5f9200051725ea2c2375bffe1b4ddb5c 100644 |
| --- a/net/base/mime_util.cc |
| +++ b/net/base/mime_util.cc |
| @@ -78,7 +78,7 @@ class MimeUtil : public PlatformMimeUtil { |
| bool strip); |
| bool IsStrictMediaMimeType(const std::string& mime_type) const; |
| - bool IsSupportedStrictMediaMimeType( |
| + CanPlayType IsSupportedStrictMediaMimeType( |
| const std::string& mime_type, |
| const std::vector<std::string>& codecs) const; |
| @@ -90,12 +90,19 @@ class MimeUtil : public PlatformMimeUtil { |
| typedef base::hash_set<std::string> MimeMappings; |
| typedef std::map<std::string, MimeMappings> StrictMappings; |
| + typedef std::vector<std::string> MimeExpressionMappings; |
| + typedef std::map<std::string, MimeExpressionMappings> |
| + StrictExpressionMappings; |
| + |
| MimeUtil(); |
| // Returns true if |codecs| is nonempty and all the items in it are present in |
| // |supported_codecs|. |
| static bool AreSupportedCodecs(const MimeMappings& supported_codecs, |
| const std::vector<std::string>& codecs); |
| + static bool AreSupportedCodecsWithProfile( |
| + const MimeExpressionMappings& supported_codecs, |
| + const std::vector<std::string>& codecs); |
| // For faster lookup, keep hash sets. |
| void InitializeMimeTypeMaps(); |
| @@ -112,6 +119,7 @@ class MimeUtil : public PlatformMimeUtil { |
| MimeMappings codecs_map_; |
| StrictMappings strict_format_map_; |
| + StrictExpressionMappings strict_mp4_format_map_; |
| }; // class MimeUtil |
| // This variable is Leaky because we need to access it from WorkerPool threads. |
| @@ -460,6 +468,21 @@ static const MediaFormatStrict format_codec_mappings[] = { |
| { "audio/x-mp3", "" } |
| }; |
| +static const char* kProprietaryAudioCodecsExpression = |
| + "mp4a,mp4a.40,mp4a.67,mp4a.40.?,mp4a.67.?"; |
|
acolwell GONE FROM CHROMIUM
2014/05/22 20:21:42
mp4a is not RFC compliant.
|
| +static const char* kProprietaryCodecsExpression = |
| + "avc1,avc3,avc1.??????,avc3.??????," |
| + "mp4a,mp4a.40,mp4a.67,mp4a.40.?,mp4a.67.?"; |
|
acolwell GONE FROM CHROMIUM
2014/05/22 20:21:42
mp4a is not RFC compliant.
|
| + |
| +static const MediaFormatStrict format_mp4_codec_mappings[] = { |
| + { "audio/mp4", kProprietaryAudioCodecsExpression }, |
| + { "audio/x-m4a", kProprietaryAudioCodecsExpression }, |
| + { "video/mp4", kProprietaryCodecsExpression }, |
| + { "video/x-m4v", kProprietaryCodecsExpression }, |
| + { "application/x-mpegurl", kProprietaryCodecsExpression }, |
| + { "application/vnd.apple.mpegurl", kProprietaryCodecsExpression } |
| +}; |
| + |
| MimeUtil::MimeUtil() { |
| InitializeMimeTypeMaps(); |
| } |
| @@ -477,6 +500,41 @@ bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs, |
| return !codecs.empty(); |
| } |
| +bool MimeUtil::AreSupportedCodecsWithProfile( |
| + const MimeExpressionMappings& supported_codecs, |
| + const std::vector<std::string>& codecs) { |
| + DCHECK(!supported_codecs.empty()); |
| + for (size_t i = 0; i < codecs.size(); ++i) { |
| + bool codec_matched = false; |
| + for (size_t j = 0; j < supported_codecs.size(); ++j) { |
| + if (!MatchPattern(static_cast<base::StringPiece>(codecs[i]), |
|
acolwell GONE FROM CHROMIUM
2014/05/22 20:21:42
nit: static_cast doesn't seem like the right thing
|
| + static_cast<base::StringPiece>(supported_codecs[j]))) { |
| + continue; |
| + } |
| + if (codecs[i].find('.') != std::string::npos) { |
|
acolwell GONE FROM CHROMIUM
2014/05/22 20:21:42
You seem to be searching for '.' three different w
amogh.bihani
2014/05/23 10:57:29
Wow, the second approach is awesome. :)
|
| + if (EndsWith(codecs[i], ".", false)) |
| + return false; |
| + |
| + // Check whether the suffix is hexadecimal. |
| + std::vector<std::string> split_string; |
| + base::SplitString(codecs[i], '.', &split_string); |
| + const std::string& number = split_string.back(); |
| + for (size_t k = 0; k < number.length(); ++k) { |
| + // Don't enforce case sensitivity, even though it's called for, as it |
| + // would break some websites. |
| + if (!IsHexDigit(number.at(k))) |
| + return false; |
| + } |
| + } |
| + codec_matched = true; |
| + break; |
| + } |
| + if (!codec_matched) |
| + return false; |
| + } |
| + return !codecs.empty(); |
| +} |
| + |
| void MimeUtil::InitializeMimeTypeMaps() { |
| for (size_t i = 0; i < arraysize(supported_image_types); ++i) |
| image_map_.insert(supported_image_types[i]); |
| @@ -547,6 +605,17 @@ void MimeUtil::InitializeMimeTypeMaps() { |
| } |
| strict_format_map_[format_codec_mappings[i].mime_type] = codecs; |
| } |
| + for (size_t i = 0; i < arraysize(format_mp4_codec_mappings); ++i) { |
| + std::vector<std::string> mime_type_codecs; |
| + ParseCodecString( |
| + format_mp4_codec_mappings[i].codecs_list, &mime_type_codecs, false); |
| + |
| + MimeExpressionMappings codecs; |
| + for (size_t j = 0; j < mime_type_codecs.size(); ++j) { |
| + codecs.push_back(mime_type_codecs[j]); |
| + } |
| + strict_mp4_format_map_[format_mp4_codec_mappings[i].mime_type] = codecs; |
| + } |
| } |
| bool MimeUtil::IsSupportedImageMimeType(const std::string& mime_type) const { |
| @@ -729,17 +798,33 @@ void MimeUtil::ParseCodecString(const std::string& codecs, |
| } |
| bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const { |
| - if (strict_format_map_.find(mime_type) == strict_format_map_.end()) |
| + if (strict_format_map_.find(mime_type) == strict_format_map_.end() && |
| + strict_mp4_format_map_.find(mime_type) == strict_mp4_format_map_.end()) |
| return false; |
| return true; |
| } |
| -bool MimeUtil::IsSupportedStrictMediaMimeType( |
| +CanPlayType MimeUtil::IsSupportedStrictMediaMimeType( |
| const std::string& mime_type, |
| const std::vector<std::string>& codecs) const { |
| - StrictMappings::const_iterator it = strict_format_map_.find(mime_type); |
| - return (it != strict_format_map_.end()) && |
| - AreSupportedCodecs(it->second, codecs); |
| + StrictMappings::const_iterator it_strict_map = |
| + strict_format_map_.find(mime_type); |
| + if ((it_strict_map != strict_format_map_.end()) && |
| + AreSupportedCodecs(it_strict_map->second, codecs)) { |
| + return IsSupported; |
| + } |
| + |
| + StrictExpressionMappings::const_iterator it_expression_map = |
| + strict_mp4_format_map_.find(mime_type); |
| + if ((it_expression_map != strict_mp4_format_map_.end()) && |
| + AreSupportedCodecsWithProfile(it_expression_map->second, codecs)) { |
| + return MayBeSupported; |
| + } |
| + |
| + if (codecs.empty()) |
| + return MayBeSupported; |
| + |
| + return IsNotSupported; |
| } |
| void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { |
| @@ -817,8 +902,9 @@ bool IsStrictMediaMimeType(const std::string& mime_type) { |
| return g_mime_util.Get().IsStrictMediaMimeType(mime_type); |
| } |
| -bool IsSupportedStrictMediaMimeType(const std::string& mime_type, |
| - const std::vector<std::string>& codecs) { |
| +CanPlayType IsSupportedStrictMediaMimeType( |
| + const std::string& mime_type, |
| + const std::vector<std::string>& codecs) { |
| return g_mime_util.Get().IsSupportedStrictMediaMimeType(mime_type, codecs); |
| } |