Chromium Code Reviews| Index: net/base/mime_util.cc |
| diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc |
| index 9d15256172ff9fc99f2a5c9e27021cfd785a6263..ae0df51c7ed6ca1541b17b3e0cb63979161283d2 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,13 +102,8 @@ 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, |
| + static bool AreSupportedCodecs(const MimeExpressionMappings& 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); |
| // For faster lookup, keep hash sets. |
| void InitializeMimeTypeMaps(); |
| @@ -123,13 +117,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. |
| @@ -290,9 +285,7 @@ static const char* const common_media_types[] = { |
| // Ogg. |
| "audio/ogg", |
| "application/ogg", |
| -#if !defined(OS_ANDROID) // Android doesn't support Ogg Theora. |
| "video/ogg", |
|
Ryan Sleevi
2014/07/09 23:56:13
This is no longer consistent with the comment on l
|
| -#endif |
| // WebM. |
| "video/webm", |
| @@ -332,9 +325,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 +434,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 +472,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 browser |
| +// cannot be sure whether the platform supports them or not |
|
Ryan Sleevi
2014/07/09 23:56:13
grammar rewrite:
// The following is the list of
|
| +// 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,25 +537,15 @@ 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::AreSupportedCodecs( |
| const MimeExpressionMappings& supported_codecs, |
| const std::vector<std::string>& codecs) { |
| - DCHECK(!supported_codecs.empty()); |
| + if (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) { |
| @@ -558,6 +571,7 @@ bool MimeUtil::AreSupportedCodecsWithProfile( |
| if (!codec_matched) |
| return false; |
| } |
| + |
| return !codecs.empty(); |
| } |
| @@ -607,11 +621,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 +635,39 @@ 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); |
| + 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; |
| + } |
| + // Merge codecs from conclusive list into inconclusive list so that querries |
| + // with one conclusive and one inconclusive codec do not get an empty |
| + // string in reply. |
|
Ryan Sleevi
2014/07/09 23:56:13
This comment needs rewording, but unfortunately, i
amogh.bihani
2014/07/10 04:02:49
Here is the scenario... "type=video/mp4; codecs= a
Ryan Sleevi
2014/07/10 20:58:44
Both of the solutions you've describe involve sign
|
| + StrictExpressionMappings::const_iterator it = strict_format_map_.find( |
| + format_inconclusive_codec_mappings[i].mime_type); |
| + if (it != strict_format_map_.end()) |
| + codecs.insert(codecs.end(), it->second.begin(), it->second.end()); |
| + inconclusive_format_map_[format_inconclusive_codec_mappings[i].mime_type] = |
| + codecs; |
| } |
| } |
| @@ -821,8 +849,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,7 +857,7 @@ 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)) { |
| @@ -838,9 +865,9 @@ SupportsType MimeUtil::IsSupportedStrictMediaMimeType( |
| } |
| 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)) { |
| + inconclusive_format_map_.find(mime_type); |
| + if ((it_expression_map != inconclusive_format_map_.end()) && |
| + AreSupportedCodecs(it_expression_map->second, codecs)) { |
| return MayBeSupported; |
| } |
| @@ -855,8 +882,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()); |
| + } |
| } |
| //---------------------------------------------------------------------------- |