Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Unified Diff: net/base/mime_util.cc

Issue 422573005: Refactor net::MimeUtil media code to return probably for codecs the platform likely supports. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comments. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/media/media_canplaytype_browsertest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/mime_util.cc
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index b1bd3ab27570748fd46ef8d492f6f5290370ccd1..0e799a64ccd32ea0b28027f5b64efd2f6b4d4bab 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;
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,51 @@ 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 sets |*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 +380,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 +461,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 +518,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 +544,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 +643,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 +665,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 +682,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 +849,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 +881,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 +889,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 +918,129 @@ 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));
+ 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;
+ }
+
+ *is_ambiguous = !IsValidH264Level(StringToUpperASCII(codec_id.substr(9)));
+ 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);
}
//----------------------------------------------------------------------------
« no previous file with comments | « content/browser/media/media_canplaytype_browsertest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698