Index: net/base/mime_util.cc |
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc |
index b1bd3ab27570748fd46ef8d492f6f5290370ccd1..a97bbfab8befeabeaf3c5785195fb84d0d44ab21 100644 |
--- a/net/base/mime_util.cc |
+++ b/net/base/mime_util.cc |
@@ -11,6 +11,7 @@ |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
#include "base/stl_util.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_split.h" |
#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
@@ -50,6 +51,25 @@ namespace net { |
// Singleton utility class for mime types. |
class MimeUtil : public PlatformMimeUtil { |
public: |
+ enum Codec { |
+ INVALID_CODEC, |
+ PCM, |
+ MP3, |
+ MPEG2_AAC_LC, |
+ MPEG2_AAC_MAIN, |
+ MPEG2_AAC_SSR, |
+ MPEG4_AAC_LC, |
+ MPEG4_AAC_SBRv1, |
+ VORBIS, |
+ OPUS, |
+ H264_BASELINE, |
+ H264_MAIN, |
+ H264_HIGH, |
+ VP8, |
+ VP9, |
+ THEORA |
+ }; |
+ |
bool GetMimeTypeFromExtension(const base::FilePath::StringType& ext, |
std::string* mime_type) const; |
@@ -93,23 +113,27 @@ class MimeUtil : public PlatformMimeUtil { |
friend struct base::DefaultLazyInstanceTraits<MimeUtil>; |
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; |
+ typedef base::hash_set<int> CodecSet; |
+ typedef std::map<std::string, CodecSet> StrictMappings; |
+ struct CodecEntry { |
+ CodecEntry() : codec(INVALID_CODEC), is_ambiguous(true) {} |
+ CodecEntry(Codec c, bool ambiguous) : codec(c), is_ambiguous(ambiguous) {} |
+ Codec codec; |
+ bool is_ambiguous; |
+ }; |
+ typedef std::map<std::string, CodecEntry> StringToCodecMappings; |
Ryan Sleevi
2014/07/29 01:14:48
nit: delete space
acolwell GONE FROM CHROMIUM
2014/07/29 01:33:26
Done.
|
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); |
- // Returns true is |codecs| is nonempty and all the items in it match with the |
- // codecs expression in |supported_codecs|. |
- static bool AreSupportedCodecsWithProfile( |
- const MimeExpressionMappings& supported_codecs, |
- const std::vector<std::string>& codecs); |
+ // Returns IsSupported if all codec IDs in |codecs| are unambiguous |
+ // and are supported by the platform. MayBeSupported is returned if |
+ // at least one codec ID in |codecs| is ambiguous but all the codecs |
+ // are supported by the platform. IsNotSupported is returned if at |
+ // least one codec ID is not supported by the platform. |
+ SupportsType AreSupportedCodecs( |
+ const CodecSet& supported_codecs, |
+ const std::vector<std::string>& codecs) const; |
// For faster lookup, keep hash sets. |
void InitializeMimeTypeMaps(); |
@@ -118,18 +142,50 @@ class MimeUtil : public PlatformMimeUtil { |
bool include_platform_types, |
std::string* mime_type) const; |
+ // Converts a codec ID into an Codec enum value and indicates |
+ // whether the conversion was ambiguous. |
+ // Returns true if this method was able to map |codec_id| to a specific |
+ // Codec enum value. |codec| and |is_ambiguous| are only valid if true |
+ // is returned. Otherwise their value is undefined after the call. |
+ // |is_ambiguous| is true if |codec_id| did not have enough information to |
+ // unambiguously determine the proper Codec enum value. If |is_ambiguous| |
+ // is true |codec| contains the best guess for the intended Codec enum value. |
+ bool StringToCodec(const std::string& codec_id, |
+ Codec* codec, |
+ bool* is_ambiguous) const; |
+ // Returns true if |codec| is supported by the platform. |
+ // Note: This method will return false if the platform supports proprietary |
+ // codecs but |allow_proprietary_codecs_| is set to false. |
+ bool IsCodecSupported(Codec codec) const; |
+ |
+ // Returns true if |codec| refers to a proprietary codec. |
+ bool IsCodecProprietary(Codec codec) const; |
+ |
+ // Returns true and set |*default_codec| if |mime_type| has a |
+ // default codec associated with it. |
+ // Returns false otherwise and the value of |*default_codec| is undefined. |
+ bool GetDefaultCodec(const std::string& mime_type, |
+ Codec* default_codec) const; |
+ |
+ // Returns true if |mime_type| has a default codec associated with it |
+ // and IsCodecSupported() returns true for that particular codec. |
+ bool IsDefaultCodecSupported(const std::string& mime_type) const; |
+ |
MimeMappings image_map_; |
MimeMappings media_map_; |
MimeMappings non_image_map_; |
MimeMappings unsupported_text_map_; |
MimeMappings javascript_map_; |
- MimeMappings codecs_map_; |
// A map of mime_types and hash map of the supported codecs for the mime_type. |
StrictMappings strict_format_map_; |
- // A map of MP4 mime_types which expect codecs with profile parameter and |
- // vector of supported codecs expressions for the mime_type. |
- StrictExpressionMappings strict_mp4_format_map_; |
+ |
+ // Keeps track of whether proprietary codec support should be |
+ // advertised to callers. |
+ bool allow_proprietary_codecs_; |
+ |
+ // Lookup table for string compare based string -> Codec mappings. |
+ StringToCodecMappings string_to_codec_map_; |
}; // class MimeUtil |
// This variable is Leaky because we need to access it from WorkerPool threads. |
@@ -323,32 +379,6 @@ static const char* const proprietary_media_types[] = { |
"audio/mpeg", |
}; |
-// List of supported codecs when passed in with <source type="...">. |
-// This set of codecs is supported by all variations of Chromium. |
-// |
-// Refer to http://wiki.whatwg.org/wiki/Video_type_parameters#Browser_Support |
-// for more information. |
-// |
-// The codecs for WAV are integers as defined in Appendix A of RFC2361: |
-// http://tools.ietf.org/html/rfc2361 |
-static const char* const common_media_codecs[] = { |
-#if !defined(OS_ANDROID) // Android doesn't support Ogg Theora. |
- "theora", |
-#endif |
- "opus", |
- "vorbis", |
- "vp8", |
- "vp9", |
- "1" // WAVE_FORMAT_PCM. |
-}; |
- |
-// List of proprietary codecs only supported by Google Chrome. |
-static const char* const proprietary_media_codecs[] = { |
- "avc1", |
- "avc3", |
- "mp4a" |
-}; |
- |
// Note: |
// - does not include javascript types list (see supported_javascript_types) |
// - does not include types starting with "text/" (see |
@@ -430,23 +460,45 @@ static const char* const supported_javascript_types[] = { |
}; |
#if defined(OS_ANDROID) |
-static bool IsCodecSupportedOnAndroid(const std::string& codec) { |
- // Theora is not supported in Android |
- if (!codec.compare("theora")) |
- return false; |
+static bool IsCodecSupportedOnAndroid(MimeUtil::Codec codec) { |
+ switch (codec) { |
+ case MimeUtil::INVALID_CODEC: |
+ return false; |
- // VP9 is supported only in KitKat+ (API Level 19). |
- if ((!codec.compare("vp9") || !codec.compare("vp9.0")) && |
- base::android::BuildInfo::GetInstance()->sdk_int() < 19) { |
- return false; |
- } |
+ case MimeUtil::PCM: |
+ case MimeUtil::MP3: |
+ case MimeUtil::MPEG4_AAC_LC: |
+ case MimeUtil::MPEG4_AAC_SBRv1: |
+ case MimeUtil::H264_BASELINE: |
+ case MimeUtil::VP8: |
+ case MimeUtil::VORBIS: |
+ return true; |
- // TODO(vigneshv): Change this similar to the VP9 check once Opus is |
- // supported on Android (http://crbug.com/318436). |
- if (!codec.compare("opus")) { |
- return false; |
+ case MimeUtil::MPEG2_AAC_LC: |
+ case MimeUtil::MPEG2_AAC_MAIN: |
+ case MimeUtil::MPEG2_AAC_SSR: |
+ // MPEG-2 variants of AAC are not supported on Android. |
+ return false; |
+ |
+ case MimeUtil::H264_MAIN: |
+ case MimeUtil::H264_HIGH: |
+ // H.264 Main and High profiles are not supported on Android |
+ return false; |
+ |
+ case MimeUtil::VP9: |
+ // VP9 is supported only in KitKat+ (API Level 19). |
+ return base::android::BuildInfo::GetInstance()->sdk_int() >= 19; |
+ |
+ case MimeUtil::OPUS: |
+ // TODO(vigneshv): Change this similar to the VP9 check once Opus is |
+ // supported on Android (http://crbug.com/318436). |
+ return false; |
+ |
+ case MimeUtil::THEORA: |
+ return false; |
} |
- return true; |
+ |
+ return false; |
} |
static bool IsMimeTypeSupportedOnAndroid(const std::string& mimeType) { |
@@ -465,6 +517,24 @@ struct MediaFormatStrict { |
const char* codecs_list; |
}; |
+// Following is the list of RFC 6381 compliant codecs: |
+// mp4a.66 - MPEG-2 AAC MAIN |
+// mp4a.67 - MPEG-2 AAC LC |
+// mp4a.68 - MPEG-2 AAC SSR |
+// mp4a.69 - MPEG-2 extension to MPEG-1 |
+// mp4a.6B - MPEG-1 audio |
+// mp4a.40.2 - MPEG-4 AAC LC |
+// mp4a.40.5 - MPEG-4 AAC SBRv1 |
+// |
+// avc1.42E0xx - H.264 Baseline |
+// avc1.4D40xx - H.264 Main |
+// avc1.6400xx - H.264 High |
+static const char kMP4AudioCodecsExpression[] = |
+ "mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.5"; |
+static const char kMP4VideoCodecsExpression[] = |
+ "avc1.42E00A,avc1.4D400A,avc1.64000A," \ |
+ "mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.5"; |
+ |
static const MediaFormatStrict format_codec_mappings[] = { |
{ "video/webm", "opus,vorbis,vp8,vp8.0,vp9,vp9.0" }, |
{ "audio/webm", "opus,vorbis" }, |
@@ -473,105 +543,82 @@ static const MediaFormatStrict format_codec_mappings[] = { |
{ "video/ogg", "opus,theora,vorbis" }, |
{ "audio/ogg", "opus,vorbis" }, |
{ "application/ogg", "opus,theora,vorbis" }, |
- { "audio/mpeg", ",mp3" }, // Note: The comma before the 'mp3'results in an |
- // empty string codec ID and indicates |
- // a missing codecs= parameter is also valid. |
- // The presense of 'mp3' is not RFC compliant, |
- // but is common in the wild so it is a defacto |
- // standard. |
+ { "audio/mpeg", "mp3" }, |
{ "audio/mp3", "" }, |
- { "audio/x-mp3", "" } |
+ { "audio/x-mp3", "" }, |
+ { "audio/mp4", kMP4AudioCodecsExpression }, |
+ { "audio/x-m4a", kMP4AudioCodecsExpression }, |
+ { "video/mp4", kMP4VideoCodecsExpression }, |
+ { "video/x-m4v", kMP4VideoCodecsExpression }, |
+ { "application/x-mpegurl", kMP4VideoCodecsExpression }, |
+ { "application/vnd.apple.mpegurl", kMP4VideoCodecsExpression } |
}; |
-// Following is the list of RFC 6381 compliant codecs: |
-// mp4a.6B - MPEG-1 audio |
-// mp4a.69 - MPEG-2 extension to MPEG-1 |
-// mp4a.67 - MPEG-2 AAC |
-// mp4a.40.2 - MPEG-4 AAC |
-// mp4a.40.5 - MPEG-4 HE-AAC |
-// |
-// avc1.42E0xx - H.264 Baseline |
-// avc1.4D40xx - H.264 Main |
-// avc1.6400xx - H.264 High |
+struct CodecIDMappings { |
+ const char* const codec_id; |
+ MimeUtil::Codec codec; |
+}; |
+ |
+// List of codec IDs that provide enough information to determine the |
+// codec and profile being requested. |
// |
-// Additionally, several non-RFC compliant codecs are allowed, due to their |
-// existing use on web. |
-// mp4a.40 |
-// avc1.xxxxxx |
-// avc3.xxxxxx |
-// mp4a.6x |
-static const char kProprietaryAudioCodecsExpression[] = |
- "mp4a.6?,mp4a.40,mp4a.40.?"; |
-static const char kProprietaryCodecsExpression[] = |
- "avc1,avc3,avc1.??????,avc3.??????,mp4a.6?,mp4a.40,mp4a.40.?"; |
- |
-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 } |
+// The "mp4a" strings come from RFC 6381. |
+static const CodecIDMappings kUnambiguousCodecIDs[] = { |
+ { "1", MimeUtil::PCM }, // We only allow this for WAV so it isn't ambiguous. |
+ { "mp3", MimeUtil::MP3 }, |
+ { "mp4a.66", MimeUtil::MPEG2_AAC_MAIN }, |
+ { "mp4a.67", MimeUtil::MPEG2_AAC_LC }, |
+ { "mp4a.68", MimeUtil::MPEG2_AAC_SSR }, |
+ { "mp4a.69", MimeUtil::MP3 }, |
+ { "mp4a.6B", MimeUtil::MP3 }, |
+ { "mp4a.40.2", MimeUtil::MPEG4_AAC_LC }, |
+ { "mp4a.40.5", MimeUtil::MPEG4_AAC_SBRv1 }, |
+ { "vorbis", MimeUtil::VORBIS }, |
+ { "opus", MimeUtil::OPUS }, |
+ { "vp8", MimeUtil::VP8 }, |
+ { "vp8.0", MimeUtil::VP8 }, |
+ { "vp9", MimeUtil::VP9 }, |
+ { "vp9.0", MimeUtil::VP9 }, |
+ { "theora", MimeUtil::THEORA } |
}; |
-MimeUtil::MimeUtil() { |
+// List of codec IDs that are ambiguous and don't provide |
+// enough information to determine the codec and profile. |
+// The codec in these entries indicate the codec and profile |
+// we assume the user is trying to indicate. |
+static const CodecIDMappings kAmbiguousCodecIDs[] = { |
+ { "mp4a.40", MimeUtil::MPEG4_AAC_LC }, |
+ { "avc1", MimeUtil::H264_BASELINE }, |
+ { "avc3", MimeUtil::H264_BASELINE }, |
+}; |
+ |
+MimeUtil::MimeUtil() : allow_proprietary_codecs_(false) { |
InitializeMimeTypeMaps(); |
} |
-// static |
-bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs, |
- const std::vector<std::string>& codecs) { |
- if (supported_codecs.empty()) |
- return codecs.empty(); |
- |
- // If no codecs are specified in the mimetype, check to see if a missing |
- // codecs parameter is allowed. |
- if (codecs.empty()) |
- return supported_codecs.find(std::string()) != supported_codecs.end(); |
+SupportsType MimeUtil::AreSupportedCodecs( |
+ const CodecSet& supported_codecs, |
+ const std::vector<std::string>& codecs) const { |
+ DCHECK(!supported_codecs.empty()); |
+ DCHECK(!codecs.empty()); |
+ SupportsType result = IsSupported; |
for (size_t i = 0; i < codecs.size(); ++i) { |
- if (codecs[i].empty() || |
- supported_codecs.find(codecs[i]) == supported_codecs.end()) { |
- return false; |
+ bool is_ambiguous = true; |
+ Codec codec = INVALID_CODEC; |
+ if (!StringToCodec(codecs[i], &codec, &is_ambiguous)) |
+ return IsNotSupported; |
+ |
+ if (!IsCodecSupported(codec) || |
+ supported_codecs.find(codec) == supported_codecs.end()) { |
+ return IsNotSupported; |
} |
- } |
- return true; |
-} |
- |
-// Checks all the codecs present in the |codecs| against the entries in |
-// |supported_codecs|. Returns true only if |codecs| is non-empty and all the |
-// codecs match |supported_codecs| expressions. |
-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(base::StringPiece(codecs[i]), |
- base::StringPiece(supported_codecs[j]))) { |
- continue; |
- } |
- // If suffix exists, check whether it is hexadecimal. |
- for (size_t wildcard_pos = supported_codecs[j].find('?'); |
- wildcard_pos != std::string::npos && |
- wildcard_pos < supported_codecs[j].length(); |
- wildcard_pos = supported_codecs[j].find('?', wildcard_pos + 1)) { |
- // Don't enforce case sensitivity, even though it's called for, as it |
- // would break some websites. |
- if (wildcard_pos >= codecs[i].length() || |
- !IsHexDigit(codecs[i].at(wildcard_pos))) { |
- return false; |
- } |
- } |
- codec_matched = true; |
- break; |
- } |
- if (!codec_matched) |
- return false; |
+ if (is_ambiguous) |
+ result = MayBeSupported; |
} |
- return !codecs.empty(); |
+ |
+ return result; |
} |
void MimeUtil::InitializeMimeTypeMaps() { |
@@ -595,6 +642,8 @@ void MimeUtil::InitializeMimeTypeMaps() { |
non_image_map_.insert(common_media_types[i]); |
} |
#if defined(USE_PROPRIETARY_CODECS) |
+ allow_proprietary_codecs_ = true; |
+ |
for (size_t i = 0; i < arraysize(proprietary_media_types); ++i) |
non_image_map_.insert(proprietary_media_types[i]); |
#endif |
@@ -615,17 +664,15 @@ void MimeUtil::InitializeMimeTypeMaps() { |
for (size_t i = 0; i < arraysize(supported_javascript_types); ++i) |
javascript_map_.insert(supported_javascript_types[i]); |
- for (size_t i = 0; i < arraysize(common_media_codecs); ++i) { |
-#if defined(OS_ANDROID) |
- if (!IsCodecSupportedOnAndroid(common_media_codecs[i])) |
- continue; |
-#endif |
- codecs_map_.insert(common_media_codecs[i]); |
+ for (size_t i = 0; i < arraysize(kUnambiguousCodecIDs); ++i) { |
+ string_to_codec_map_[kUnambiguousCodecIDs[i].codec_id] = |
+ CodecEntry(kUnambiguousCodecIDs[i].codec, false); |
+ } |
+ |
+ for (size_t i = 0; i < arraysize(kAmbiguousCodecIDs); ++i) { |
+ string_to_codec_map_[kAmbiguousCodecIDs[i].codec_id] = |
+ CodecEntry(kAmbiguousCodecIDs[i].codec, true); |
} |
-#if defined(USE_PROPRIETARY_CODECS) |
- for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i) |
- codecs_map_.insert(proprietary_media_codecs[i]); |
-#endif |
// Initialize the strict supported media types. |
for (size_t i = 0; i < arraysize(format_codec_mappings); ++i) { |
@@ -634,25 +681,16 @@ void MimeUtil::InitializeMimeTypeMaps() { |
&mime_type_codecs, |
false); |
- MimeMappings codecs; |
+ CodecSet codecs; |
for (size_t j = 0; j < mime_type_codecs.size(); ++j) { |
-#if defined(OS_ANDROID) |
- if (!IsCodecSupportedOnAndroid(mime_type_codecs[j])) |
- continue; |
-#endif |
- codecs.insert(mime_type_codecs[j]); |
+ Codec codec = INVALID_CODEC; |
+ bool is_ambiguous = true; |
+ CHECK(StringToCodec(mime_type_codecs[j], &codec, &is_ambiguous)); |
+ DCHECK(!is_ambiguous); |
+ codecs.insert(codec); |
} |
- 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; |
+ strict_format_map_[format_codec_mappings[i].mime_type] = codecs; |
} |
} |
@@ -810,7 +848,15 @@ bool MimeUtil::IsValidTopLevelMimeType(const std::string& type_string) const { |
bool MimeUtil::AreSupportedMediaCodecs( |
const std::vector<std::string>& codecs) const { |
- return AreSupportedCodecs(codecs_map_, codecs); |
+ for (size_t i = 0; i < codecs.size(); ++i) { |
+ Codec codec = INVALID_CODEC; |
+ bool is_ambiguous = true; |
+ if (!StringToCodec(codecs[i], &codec, &is_ambiguous) || |
+ !IsCodecSupported(codec)) { |
+ return false; |
+ } |
+ } |
+ return true; |
} |
void MimeUtil::ParseCodecString(const std::string& codecs, |
@@ -834,10 +880,7 @@ 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() && |
- strict_mp4_format_map_.find(mime_type) == strict_mp4_format_map_.end()) |
- return false; |
- return true; |
+ return strict_format_map_.find(mime_type) != strict_format_map_.end(); |
} |
SupportsType MimeUtil::IsSupportedStrictMediaMimeType( |
@@ -845,22 +888,28 @@ SupportsType MimeUtil::IsSupportedStrictMediaMimeType( |
const std::vector<std::string>& codecs) const { |
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; |
- } |
+ if (it_strict_map == strict_format_map_.end()) |
+ return codecs.empty() ? MayBeSupported : IsNotSupported; |
- 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 (it_strict_map->second.empty()) { |
+ // We get here if the mimetype does not expect a codecs parameter. |
+ return (codecs.empty() && IsDefaultCodecSupported(mime_type)) ? |
+ IsSupported : IsNotSupported; |
} |
- if (codecs.empty()) |
- return MayBeSupported; |
+ if (codecs.empty()) { |
+ // We get here if the mimetype expects to get a codecs parameter, |
+ // but didn't get one. If |mime_type| does not have a default codec |
+ // the best we can do is say "maybe" because we don't have enough |
+ // information. |
+ Codec default_codec = INVALID_CODEC; |
+ if (!GetDefaultCodec(mime_type, &default_codec)) |
+ return MayBeSupported; |
+ |
+ return IsCodecSupported(default_codec) ? IsSupported : IsNotSupported; |
+ } |
- return IsNotSupported; |
+ return AreSupportedCodecs(it_strict_map->second, codecs); |
} |
void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { |
@@ -868,8 +917,130 @@ void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { |
non_image_map_.erase(proprietary_media_types[i]); |
media_map_.erase(proprietary_media_types[i]); |
} |
- for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i) |
- codecs_map_.erase(proprietary_media_codecs[i]); |
+ allow_proprietary_codecs_ = false; |
+} |
+ |
+static bool IsValidH264Level(const std::string& level_str) { |
+ uint32 level; |
+ if (level_str.size() != 2 || !base::HexStringToUInt(level_str, &level)) |
+ return false; |
+ |
+ // Valid levels taken from Table A-1 in ISO-14496-10. |
+ // Essentially |level_str| is toHex(10 * level). |
+ return ((level >= 10 && level <= 13) || |
+ (level >= 20 && level <= 22) || |
+ (level >= 30 && level <= 32) || |
+ (level >= 40 && level <= 42) || |
+ (level >= 50 && level <= 51)); |
+} |
+ |
+// Handle parsing H.264 codec IDs as outlined in RFC 6381 |
+// avc1.42E0xx - H.264 Baseline |
+// avc1.4D40xx - H.264 Main |
+// avc1.6400xx - H.264 High |
+// |
+// avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that |
+// are trying to signal H.264 Baseline. |
+static bool ParseH264CodecID(const std::string& codec_id, |
+ MimeUtil::Codec* codec, |
+ bool* is_ambiguous) { |
+ // Make sure we have avc1.xxxxxx or avc3.xxxxxx |
+ if (codec_id.size() != 11 || |
+ (!StartsWithASCII(codec_id, "avc1.", true) && |
+ !StartsWithASCII(codec_id, "avc3.", true))) { |
+ return false; |
+ } |
+ |
+ std::string profile = StringToUpperASCII(codec_id.substr(5, 4)); |
+ std::string level = StringToUpperASCII(codec_id.substr(9)); |
+ if (profile == "42E0") { |
+ *codec = MimeUtil::H264_BASELINE; |
+ } else if (profile == "4D40") { |
+ *codec = MimeUtil::H264_MAIN; |
+ } else if (profile == "6400") { |
+ *codec = MimeUtil::H264_HIGH; |
+ } else { |
+ *codec = MimeUtil::H264_BASELINE; |
+ *is_ambiguous = true; |
+ return true; |
+ } |
+ |
Ryan Sleevi
2014/07/29 01:14:48
Could move line 955 down here. For SPEED! :D
acolwell GONE FROM CHROMIUM
2014/07/29 01:33:26
Done.
|
+ *is_ambiguous = !IsValidH264Level(level); |
+ return true; |
+} |
+ |
+bool MimeUtil::StringToCodec(const std::string& codec_id, |
+ Codec* codec, |
+ bool* is_ambiguous) const { |
+ StringToCodecMappings::const_iterator itr = |
+ string_to_codec_map_.find(codec_id); |
+ if (itr != string_to_codec_map_.end()) { |
+ *codec = itr->second.codec; |
+ *is_ambiguous = itr->second.is_ambiguous; |
+ return true; |
+ } |
+ |
+ // If |codec_id| is not in |string_to_codec_map_|, then we assume that it is |
+ // an H.264 codec ID because currently those are the only ones that can't be |
+ // stored in the |string_to_codec_map_| and require parsing. |
+ return ParseH264CodecID(codec_id, codec, is_ambiguous); |
+} |
+ |
+bool MimeUtil::IsCodecSupported(Codec codec) const { |
+ DCHECK_NE(codec, INVALID_CODEC); |
+ |
+#if defined(OS_ANDROID) |
+ if (!IsCodecSupportedOnAndroid(codec)) |
+ return false; |
+#endif |
+ |
+ return allow_proprietary_codecs_ || !IsCodecProprietary(codec); |
+} |
+ |
+bool MimeUtil::IsCodecProprietary(Codec codec) const { |
+ switch (codec) { |
+ case INVALID_CODEC: |
+ case MP3: |
+ case MPEG2_AAC_LC: |
+ case MPEG2_AAC_MAIN: |
+ case MPEG2_AAC_SSR: |
+ case MPEG4_AAC_LC: |
+ case MPEG4_AAC_SBRv1: |
+ case H264_BASELINE: |
+ case H264_MAIN: |
+ case H264_HIGH: |
+ return true; |
+ |
+ case PCM: |
+ case VORBIS: |
+ case OPUS: |
+ case VP8: |
+ case VP9: |
+ case THEORA: |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+bool MimeUtil::GetDefaultCodec(const std::string& mime_type, |
+ Codec* default_codec) const { |
+ if (mime_type == "audio/mpeg" || |
+ mime_type == "audio/mp3" || |
+ mime_type == "audio/x-mp3") { |
+ *default_codec = MimeUtil::MP3; |
+ return true; |
+ } |
+ |
+ return false; |
+} |
+ |
+ |
+bool MimeUtil::IsDefaultCodecSupported(const std::string& mime_type) const { |
+ Codec default_codec = Codec::INVALID_CODEC; |
+ if (!GetDefaultCodec(mime_type, &default_codec)) |
+ return false; |
+ return IsCodecSupported(default_codec); |
} |
//---------------------------------------------------------------------------- |