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

Unified Diff: net/base/mime_util.cc

Issue 336213011: Fix: Changing canPlayType behaviour for MP4 containers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changing method names 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 9d15256172ff9fc99f2a5c9e27021cfd785a6263..893edd308ad582152c9694f2cb9f39bf4b5704e7 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -93,7 +93,6 @@ 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>
@@ -103,14 +102,17 @@ class MimeUtil : public PlatformMimeUtil {
// 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(
+ static bool AreCodecsListedInSingleLookupTable(
const MimeExpressionMappings& supported_codecs,
const std::vector<std::string>& codecs);
+ // Returns true if |codecs| is nonempty and all the items in it are present in
+ // either |confirmed_supported_codecs| or |mightbe_supported_codecs|.
+ static bool AreCodecsListedInMultipleLookupTables(
+ const MimeExpressionMappings& confirmed_supported_codecs,
+ const MimeExpressionMappings& mightbe_supported_codecs,
+ const std::vector<std::string>& codecs);
+
// For faster lookup, keep hash sets.
void InitializeMimeTypeMaps();
@@ -123,13 +125,14 @@ class MimeUtil : public PlatformMimeUtil {
MimeMappings non_image_map_;
MimeMappings unsupported_text_map_;
MimeMappings javascript_map_;
- MimeMappings codecs_map_;
+ MimeExpressionMappings 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_;
+ StrictExpressionMappings strict_format_map_;
+ // A map of mime_types, which expect codecs which are RFC compliant but do not
+ // have sufficient informatation whether they are supported or not, and vector
+ // of supported codecs expressions for the mime_type.
+ StrictExpressionMappings inconclusive_format_map_;
}; // class MimeUtil
// This variable is Leaky because we need to access it from WorkerPool threads.
@@ -286,13 +289,12 @@ static const char* const supported_image_types[] = {
// A list of media types: http://en.wikipedia.org/wiki/Internet_media_type
// A comprehensive mime type list: http://plugindoc.mozdev.org/winmime.php
// This set of codecs is supported by all variations of Chromium.
+// (Except for 'video/ogg', which is not supported by Android.)
static const char* const common_media_types[] = {
// Ogg.
"audio/ogg",
"application/ogg",
-#if !defined(OS_ANDROID) // Android doesn't support Ogg Theora.
"video/ogg",
-#endif
// WebM.
"video/webm",
@@ -325,6 +327,8 @@ static const char* const proprietary_media_types[] = {
// List of supported codecs when passed in with <source type="...">.
// This set of codecs is supported by all variations of Chromium.
+// (Except for 'theora' and 'opus' (http://crbug.com/318436), which are not
+// supported by Android.)
//
// Refer to http://wiki.whatwg.org/wiki/Video_type_parameters#Browser_Support
// for more information.
@@ -332,9 +336,7 @@ static const char* const proprietary_media_types[] = {
// 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",
@@ -443,19 +445,35 @@ static bool IsCodecSupportedOnAndroid(const std::string& codec) {
// TODO(vigneshv): Change this similar to the VP9 check once Opus is
// supported on Android (http://crbug.com/318436).
- if (!codec.compare("opus")) {
+ if (!codec.compare("opus"))
+ return false;
+
+ // MPEG-2 AAC is not supported on Android
+ if (!codec.compare("mp4a.67"))
+ return false;
+
+ // H.264 Main and High profiles are not supported on Android
+ if (!codec.compare("avc1.4d40??") || !codec.compare("avc3.4d40??") ||
+ !codec.compare("avc1.4D40??") || !codec.compare("avc3.4D40??") ||
+ !codec.compare("avc1.6400??") || !codec.compare("avc3.6400??")) {
return false;
}
+
return true;
}
static bool IsMimeTypeSupportedOnAndroid(const std::string& mimeType) {
+ // Ogg Theora is not supported on Android
+ if (!mimeType.compare("video/ogg"))
+ return false;
+
// HLS codecs are supported in ICS and above (API level 14)
if ((!mimeType.compare("application/vnd.apple.mpegurl") ||
!mimeType.compare("application/x-mpegurl")) &&
base::android::BuildInfo::GetInstance()->sdk_int() < 14) {
return false;
}
+
return true;
}
#endif
@@ -465,48 +483,64 @@ struct MediaFormatStrict {
const char* codecs_list;
};
-static const MediaFormatStrict format_codec_mappings[] = {
- { "video/webm", "opus,vorbis,vp8,vp8.0,vp9,vp9.0" },
- { "audio/webm", "opus,vorbis" },
- { "audio/wav", "1" },
- { "audio/x-wav", "1" },
- { "video/ogg", "opus,theora,vorbis" },
- { "audio/ogg", "opus,vorbis" },
- { "application/ogg", "opus,theora,vorbis" },
- { "audio/mpeg", "" },
- { "audio/mp3", "" },
- { "audio/x-mp3", "" }
-};
-
// 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
+// mp4a.40.5 - MPEG-4 HE-AACv1
//
// avc1.42E0xx - H.264 Baseline
// avc1.4D40xx - H.264 Main
// avc1.6400xx - H.264 High
+static const char kProprietaryAudioCodecsExpression[] =
+ "mp4a.6B,mp4a.69,mp4a.67,mp4a.40.2,mp4a.40.5";
+static const char kProprietaryCodecsExpression[] =
+ "avc1.42E0??,avc1.42e0??,avc1.4D40??,avc1.4d40??,avc1.6400??,"
+ "avc3.42E0??,avc3.42e0??,avc3.4D40??,avc3.4d40??,avc3.6400??,"
+ "mp4a.6B,mp4a.69,mp4a.67,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"},
+ {"audio/wav", "1"},
+ {"audio/x-wav", "1"},
+ {"video/ogg", "opus,theora,vorbis"},
+ {"audio/ogg", "opus,vorbis"},
+ {"application/ogg", "opus,theora,vorbis"},
+ {"audio/mpeg", ""},
+ {"audio/mp3", ""},
+ {"audio/x-mp3", ""},
+ {"audio/mp4", kProprietaryAudioCodecsExpression},
+ {"audio/x-m4a", kProprietaryAudioCodecsExpression},
+ {"video/mp4", kProprietaryCodecsExpression},
+ {"video/x-m4v", kProprietaryCodecsExpression},
+ {"application/x-mpegurl", kProprietaryCodecsExpression},
+ {"application/vnd.apple.mpegurl", kProprietaryCodecsExpression}
+};
+
+// Following is the list of codecs that are RFC 6381 compliant, but support for
+// which varies with platform and cannot be determined beforehand.
+// mp4a.40
+// avc1
+// avc3
//
// 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 }
+static const char kInconclusiveProprietaryAudioCodecsExpression[] =
+ "mp4a.40,mp4a.66,mp4a.68";
+static const char kInconclusiveProprietaryCodecsExpression[] =
+ "avc1,avc1.??????,avc3,avc3.??????,mp4a.40,mp4a.66,mp4a.68";
+
+static const MediaFormatStrict format_inconclusive_codec_mappings[] = {
+ {"audio/mp4", kInconclusiveProprietaryAudioCodecsExpression},
+ {"audio/x-m4a", kInconclusiveProprietaryAudioCodecsExpression},
+ {"video/mp4", kInconclusiveProprietaryCodecsExpression},
+ {"video/x-m4v", kInconclusiveProprietaryCodecsExpression},
+ {"application/x-mpegurl", kInconclusiveProprietaryCodecsExpression},
+ {"application/vnd.apple.mpegurl", kInconclusiveProprietaryCodecsExpression},
};
MimeUtil::MimeUtil() {
@@ -514,37 +548,53 @@ MimeUtil::MimeUtil() {
}
// static
-bool MimeUtil::AreSupportedCodecs(const MimeMappings& supported_codecs,
- const std::vector<std::string>& codecs) {
- if (supported_codecs.empty())
- return codecs.empty();
-
- for (size_t i = 0; i < codecs.size(); ++i) {
- if (supported_codecs.find(codecs[i]) == supported_codecs.end())
- return false;
- }
- return !codecs.empty();
-}
-
// 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(
+bool MimeUtil::AreCodecsListedInSingleLookupTable(
const MimeExpressionMappings& supported_codecs,
const std::vector<std::string>& codecs) {
- DCHECK(!supported_codecs.empty());
+ MimeExpressionMappings empty_vector;
+ return AreCodecsListedInMultipleLookupTables(
+ supported_codecs, empty_vector, codecs);
+}
+
+// static
+// 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 expression in either |confirmed_supported_codecs| or
+// |mightbe_supported_codecs|.
+bool MimeUtil::AreCodecsListedInMultipleLookupTables(
+ const MimeExpressionMappings& confirmed_supported_codecs,
+ const MimeExpressionMappings& mightbe_supported_codecs,
+ const std::vector<std::string>& codecs) {
+ if (confirmed_supported_codecs.empty() && mightbe_supported_codecs.empty())
+ return 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;
+ std::string matched_codec;
+ for (size_t j = 0; j < confirmed_supported_codecs.size(); ++j) {
+ if (MatchPattern(base::StringPiece(codecs[i]),
+ base::StringPiece(confirmed_supported_codecs[j]))) {
+ matched_codec = confirmed_supported_codecs[j];
+ break;
+ }
+ }
+ for (size_t j = 0;
+ j < mightbe_supported_codecs.size() && matched_codec.empty();
+ ++j) {
+ if (MatchPattern(base::StringPiece(codecs[i]),
+ base::StringPiece(mightbe_supported_codecs[j]))) {
+ matched_codec = mightbe_supported_codecs[j];
+ break;
}
+ }
+ if (!matched_codec.empty()) {
// If suffix exists, check whether it is hexadecimal.
- for (size_t wildcard_pos = supported_codecs[j].find('?');
+ for (size_t wildcard_pos = matched_codec.find('?');
wildcard_pos != std::string::npos &&
- wildcard_pos < supported_codecs[j].length();
- wildcard_pos = supported_codecs[j].find('?', wildcard_pos + 1)) {
+ wildcard_pos < matched_codec.length();
+ wildcard_pos = matched_codec.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() ||
@@ -552,12 +602,11 @@ bool MimeUtil::AreSupportedCodecsWithProfile(
return false;
}
}
- codec_matched = true;
- break;
- }
- if (!codec_matched)
+ } else {
return false;
+ }
}
+
return !codecs.empty();
}
@@ -607,11 +656,11 @@ void MimeUtil::InitializeMimeTypeMaps() {
if (!IsCodecSupportedOnAndroid(common_media_codecs[i]))
continue;
#endif
- codecs_map_.insert(common_media_codecs[i]);
+ codecs_map_.push_back(common_media_codecs[i]);
}
#if defined(USE_PROPRIETARY_CODECS)
for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i)
- codecs_map_.insert(proprietary_media_codecs[i]);
+ codecs_map_.push_back(proprietary_media_codecs[i]);
#endif
// Initialize the strict supported media types.
@@ -621,25 +670,32 @@ void MimeUtil::InitializeMimeTypeMaps() {
&mime_type_codecs,
false);
- MimeMappings codecs;
+ MimeExpressionMappings 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]);
+ codecs.push_back(mime_type_codecs[j]);
}
strict_format_map_[format_codec_mappings[i].mime_type] = codecs;
}
- for (size_t i = 0; i < arraysize(format_mp4_codec_mappings); ++i) {
+ for (size_t i = 0; i < arraysize(format_inconclusive_codec_mappings); ++i) {
std::vector<std::string> mime_type_codecs;
- ParseCodecString(
- format_mp4_codec_mappings[i].codecs_list, &mime_type_codecs, false);
+ ParseCodecString(format_inconclusive_codec_mappings[i].codecs_list,
+ &mime_type_codecs,
+ false);
MimeExpressionMappings codecs;
- for (size_t j = 0; j < mime_type_codecs.size(); ++j)
+ for (size_t j = 0; j < mime_type_codecs.size(); ++j) {
+#if defined(OS_ANDROID)
+ if (!IsCodecSupportedOnAndroid(mime_type_codecs[j]))
+ continue;
+#endif
codecs.push_back(mime_type_codecs[j]);
- strict_mp4_format_map_[format_mp4_codec_mappings[i].mime_type] = codecs;
+ }
+ inconclusive_format_map_[format_inconclusive_codec_mappings[i].mime_type] =
+ codecs;
}
}
@@ -797,7 +853,7 @@ bool MimeUtil::IsValidTopLevelMimeType(const std::string& type_string) const {
bool MimeUtil::AreSupportedMediaCodecs(
const std::vector<std::string>& codecs) const {
- return AreSupportedCodecs(codecs_map_, codecs);
+ return AreCodecsListedInSingleLookupTable(codecs_map_, codecs);
}
void MimeUtil::ParseCodecString(const std::string& codecs,
@@ -821,8 +877,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())
+ if (strict_format_map_.find(mime_type) == strict_format_map_.end())
return false;
return true;
}
@@ -830,18 +885,28 @@ bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const {
SupportsType MimeUtil::IsSupportedStrictMediaMimeType(
const std::string& mime_type,
const std::vector<std::string>& codecs) const {
- StrictMappings::const_iterator it_strict_map =
+ StrictExpressionMappings::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)) {
+ AreCodecsListedInSingleLookupTable(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;
+ inconclusive_format_map_.find(mime_type);
+ if (it_expression_map != inconclusive_format_map_.end()) {
+ bool maybe = false;
+ if (it_strict_map != strict_format_map_.end()) {
+ maybe = AreCodecsListedInMultipleLookupTables(it_strict_map->second,
+ it_expression_map->second,
+ codecs);
+ } else {
+ maybe = AreCodecsListedInSingleLookupTable(it_expression_map->second,
+ codecs);
+ }
+
+ if (maybe)
+ return MayBeSupported;
}
if (codecs.empty())
@@ -855,8 +920,12 @@ 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]);
+ for (size_t i = 0; i < arraysize(proprietary_media_codecs); ++i) {
+ codecs_map_.erase(std::remove(codecs_map_.begin(),
+ codecs_map_.end(),
+ proprietary_media_codecs[i]),
+ codecs_map_.end());
+ }
}
//----------------------------------------------------------------------------
« 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