summaryrefslogtreecommitdiff
path: root/chromium/media/base/mime_util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/base/mime_util.cc')
-rw-r--r--chromium/media/base/mime_util.cc145
1 files changed, 102 insertions, 43 deletions
diff --git a/chromium/media/base/mime_util.cc b/chromium/media/base/mime_util.cc
index 535837c1474..367953946d0 100644
--- a/chromium/media/base/mime_util.cc
+++ b/chromium/media/base/mime_util.cc
@@ -36,6 +36,7 @@ class MimeUtil {
H264_BASELINE,
H264_MAIN,
H264_HIGH,
+ HEVC_MAIN,
VP8,
VP9,
THEORA
@@ -173,6 +174,8 @@ static const char* const proprietary_media_types[] = {
"audio/mp3",
"audio/x-mp3",
"audio/mpeg",
+
+ // AAC / ADTS
"audio/aac",
#if defined(ENABLE_MPEG2TS_STREAM_PARSER)
@@ -199,6 +202,15 @@ static bool IsCodecSupportedOnAndroid(MimeUtil::Codec codec) {
case MimeUtil::VORBIS:
return true;
+ case MimeUtil::HEVC_MAIN:
+#if defined(ENABLE_HEVC_DEMUXING)
+ // HEVC/H.265 is supported in Lollipop+ (API Level 21), according to
+ // http://developer.android.com/reference/android/media/MediaFormat.html
+ return base::android::BuildInfo::GetInstance()->sdk_int() >= 21;
+#else
+ return false;
+#endif
+
case MimeUtil::MPEG2_AAC_LC:
case MimeUtil::MPEG2_AAC_MAIN:
case MimeUtil::MPEG2_AAC_SSR:
@@ -253,6 +265,11 @@ static const char kMP4VideoCodecsExpression[] =
// kUnambiguousCodecStringMap/kAmbiguousCodecStringMap should be the only
// mapping from strings to codecs. See crbug.com/461009.
"avc1.42E00A,avc1.4D400A,avc1.64000A,"
+#if defined(ENABLE_HEVC_DEMUXING)
+ // Any valid unambiguous HEVC codec id will work here, since these strings
+ // are parsed and mapped to MimeUtil::Codec enum values.
+ "hev1.1.6.L93.B0,"
+#endif
"mp4a.66,mp4a.67,mp4a.68,mp4a.69,mp4a.6B,mp4a.40.2,mp4a.40.02,mp4a.40.5,"
"mp4a.40.05,mp4a.40.29";
@@ -276,6 +293,7 @@ static const MediaFormatStrict format_codec_mappings[] = {
{"audio/mpeg", "mp3"},
{"audio/mp3", ""},
{"audio/x-mp3", ""},
+ {"audio/aac", ""},
{"audio/mp4", kMP4AudioCodecsExpression},
{"audio/x-m4a", kMP4AudioCodecsExpression},
{"video/mp4", kMP4VideoCodecsExpression},
@@ -396,8 +414,7 @@ void MimeUtil::InitializeMimeTypeMaps() {
}
bool MimeUtil::IsSupportedMediaMimeType(const std::string& mime_type) const {
- return media_map_.find(base::StringToLowerASCII(mime_type)) !=
- media_map_.end();
+ return media_map_.find(base::ToLowerASCII(mime_type)) != media_map_.end();
}
@@ -417,9 +434,13 @@ bool MimeUtil::AreSupportedMediaCodecs(
void MimeUtil::ParseCodecString(const std::string& codecs,
std::vector<std::string>* codecs_out,
bool strip) {
- std::string no_quote_codecs;
- base::TrimString(codecs, "\"", &no_quote_codecs);
- base::SplitString(no_quote_codecs, ',', codecs_out);
+ *codecs_out = base::SplitString(
+ base::TrimString(codecs, "\"", base::TRIM_ALL),
+ ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ // Convert empty or all-whitespace input to 0 results.
+ if (codecs_out->size() == 1 && (*codecs_out)[0].empty())
+ codecs_out->clear();
if (!strip)
return;
@@ -435,14 +456,14 @@ void MimeUtil::ParseCodecString(const std::string& codecs,
}
bool MimeUtil::IsStrictMediaMimeType(const std::string& mime_type) const {
- return strict_format_map_.find(base::StringToLowerASCII(mime_type)) !=
+ return strict_format_map_.find(base::ToLowerASCII(mime_type)) !=
strict_format_map_.end();
}
SupportsType MimeUtil::IsSupportedStrictMediaMimeType(
const std::string& mime_type,
const std::vector<std::string>& codecs) const {
- const std::string mime_type_lower_case = base::StringToLowerASCII(mime_type);
+ const std::string mime_type_lower_case = base::ToLowerASCII(mime_type);
StrictMappings::const_iterator it_strict_map =
strict_format_map_.find(mime_type_lower_case);
if (it_strict_map == strict_format_map_.end())
@@ -477,28 +498,6 @@ void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() {
allow_proprietary_codecs_ = false;
}
-// Returns true iff |profile_str| conforms to hex string "42y0".
-//
-// |profile_str| is the first four characters of the H.264 suffix string. From
-// ISO-14496-10 7.3.2.1, it consists of:
-// 8 bits: profile_idc; required to be 0x42 here.
-// 1 bit: constraint_set0_flag; ignored here.
-// 1 bit: constraint_set1_flag; ignored here.
-// 1 bit: constraint_set2_flag; ignored here.
-// 1 bit: constraint_set3_flag; ignored here.
-// 4 bits: reserved; required to be 0 here.
-//
-// The spec indicates other ways, not implemented here, that a |profile_str|
-// can indicate a baseline conforming decoder is sufficient for decode in Annex
-// A.2.1: "[profile_idc not necessarily 0x42] with constraint_set0_flag set and
-// in which level_idc and constraint_set3_flag represent a level less than or
-// equal to the specified level."
-static bool IsValidH264BaselineProfile(const std::string& profile_str) {
- return (profile_str.size() == 4 && profile_str[0] == '4' &&
- profile_str[1] == '2' && base::IsHexDigit(profile_str[2]) &&
- profile_str[3] == '0');
-}
-
static bool IsValidH264Level(const std::string& level_str) {
uint32 level;
if (level_str.size() != 2 || !base::HexStringToUInt(level_str, &level))
@@ -514,9 +513,9 @@ static bool IsValidH264Level(const std::string& level_str) {
}
// Handle parsing H.264 codec IDs as outlined in RFC 6381 and ISO-14496-10.
-// avc1.42y0xx, y >= 8 - H.264 Baseline
-// avc1.4D40xx - H.264 Main
-// avc1.6400xx - H.264 High
+// avc1.42x0yy - H.264 Baseline
+// avc1.4Dx0yy - H.264 Main
+// avc1.64x0yy - H.264 High
//
// avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that are trying to
// signal H.264 Baseline. For example, the idc_level, profile_idc and
@@ -526,19 +525,32 @@ static bool IsValidH264Level(const std::string& level_str) {
static bool ParseH264CodecID(const std::string& codec_id,
MimeUtil::Codec* codec,
bool* is_ambiguous) {
- // Make sure we have avc1.xxxxxx or avc3.xxxxxx
+ // Make sure we have avc1.xxxxxx or avc3.xxxxxx , where xxxxxx are hex digits
+ if (!base::StartsWith(codec_id, "avc1.", base::CompareCase::SENSITIVE) &&
+ !base::StartsWith(codec_id, "avc3.", base::CompareCase::SENSITIVE)) {
+ return false;
+ }
if (codec_id.size() != 11 ||
- (!base::StartsWithASCII(codec_id, "avc1.", true) &&
- !base::StartsWithASCII(codec_id, "avc3.", true))) {
+ !base::IsHexDigit(codec_id[5]) || !base::IsHexDigit(codec_id[6]) ||
+ !base::IsHexDigit(codec_id[7]) || !base::IsHexDigit(codec_id[8]) ||
+ !base::IsHexDigit(codec_id[9]) || !base::IsHexDigit(codec_id[10])) {
return false;
}
- std::string profile = base::StringToUpperASCII(codec_id.substr(5, 4));
- if (IsValidH264BaselineProfile(profile)) {
+ // Validate constraint flags and reserved bits.
+ if (!base::IsHexDigit(codec_id[7]) || codec_id[8] != '0') {
+ *codec = MimeUtil::H264_BASELINE;
+ *is_ambiguous = true;
+ return true;
+ }
+
+ // Extract the profile.
+ std::string profile = base::ToUpperASCII(codec_id.substr(5, 2));
+ if (profile == "42") {
*codec = MimeUtil::H264_BASELINE;
- } else if (profile == "4D40") {
+ } else if (profile == "4D") {
*codec = MimeUtil::H264_MAIN;
- } else if (profile == "6400") {
+ } else if (profile == "64") {
*codec = MimeUtil::H264_HIGH;
} else {
*codec = MimeUtil::H264_BASELINE;
@@ -546,11 +558,47 @@ static bool ParseH264CodecID(const std::string& codec_id,
return true;
}
- *is_ambiguous =
- !IsValidH264Level(base::StringToUpperASCII(codec_id.substr(9)));
+ // Validate level.
+ *is_ambiguous = !IsValidH264Level(base::ToUpperASCII(codec_id.substr(9)));
return true;
}
+#if defined(ENABLE_HEVC_DEMUXING)
+// ISO/IEC FDIS 14496-15 standard section E.3 describes the syntax of codec ids
+// reserved for HEVC. According to that spec HEVC codec id must start with
+// either "hev1." or "hvc1.". We don't yet support full parsing of HEVC codec
+// ids, but since no other codec id starts with those string we'll just treat
+// any string starting with "hev1." or "hvc1." as valid HEVC codec ids.
+// crbug.com/482761
+static bool ParseHEVCCodecID(const std::string& codec_id,
+ MimeUtil::Codec* codec,
+ bool* is_ambiguous) {
+ if (base::StartsWith(codec_id, "hev1.", base::CompareCase::SENSITIVE) ||
+ base::StartsWith(codec_id, "hvc1.", base::CompareCase::SENSITIVE)) {
+ *codec = MimeUtil::HEVC_MAIN;
+
+ // TODO(servolk): Full HEVC codec id parsing is not implemented yet (see
+ // crbug.com/482761). So treat HEVC codec ids as ambiguous for now.
+ *is_ambiguous = true;
+
+ // TODO(servolk): Most HEVC codec ids are treated as ambiguous (see above),
+ // but we need to recognize at least one valid unambiguous HEVC codec id,
+ // which is added into kMP4VideoCodecsExpression. We need it to be
+ // unambiguous to avoid DCHECK(!is_ambiguous) in InitializeMimeTypeMaps. We
+ // also use these in unit tests (see
+ // content/browser/media/media_canplaytype_browsertest.cc).
+ // Remove this workaround after crbug.com/482761 is fixed.
+ if (codec_id == "hev1.1.6.L93.B0" || codec_id == "hvc1.1.6.L93.B0") {
+ *is_ambiguous = false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+#endif
+
bool MimeUtil::StringToCodec(const std::string& codec_id,
Codec* codec,
bool* is_ambiguous) const {
@@ -563,8 +611,13 @@ bool MimeUtil::StringToCodec(const std::string& codec_id,
}
// 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.
+ // either H.264 or HEVC/H.265 codec ID because currently those are the only
+ // ones that are not added to the |string_to_codec_map_| and require parsing.
+#if defined(ENABLE_HEVC_DEMUXING)
+ if (ParseHEVCCodecID(codec_id, codec, is_ambiguous)) {
+ return true;
+ }
+#endif
return ParseH264CodecID(codec_id, codec, is_ambiguous);
}
@@ -592,6 +645,7 @@ bool MimeUtil::IsCodecProprietary(Codec codec) const {
case H264_BASELINE:
case H264_MAIN:
case H264_HIGH:
+ case HEVC_MAIN:
return true;
case PCM:
@@ -615,6 +669,11 @@ bool MimeUtil::GetDefaultCodecLowerCase(const std::string& mime_type_lower_case,
return true;
}
+ if (mime_type_lower_case == "audio/aac") {
+ *default_codec = MimeUtil::MPEG4_AAC_LC;
+ return true;
+ }
+
return false;
}