Index: net/base/mime_util.cc |
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc |
index 37e630fb031a1c0b2fa1eff1f29bc79c919a7000..27f3c7049ad2d8a6db333606a550ed28e2b17a03 100644 |
--- a/net/base/mime_util.cc |
+++ b/net/base/mime_util.cc |
@@ -924,6 +924,39 @@ void MimeUtil::RemoveProprietaryMediaTypesAndCodecsForTests() { |
allow_proprietary_codecs_ = false; |
} |
+// Returns true iff |profile_str| conforms to hex string "42y0", where y is one |
+// of [8..F]. Requiring constraint_set0_flag be set and profile_idc be 0x42 is |
+// taken from ISO-14496-10 7.3.2.1, 7.4.2.1, and Annex A.2.1. |
+// |
+// |profile_str| is the first four characters of the H.264 suffix string |
+// (ignoring the last 2 characters of the full 6 character suffix that are |
+// level_idc). 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 : required to be true 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) { |
+ uint32 constraint_set_bits; |
+ if (profile_str.size() != 4 || |
+ profile_str[0] != '4' || |
+ profile_str[1] != '2' || |
+ profile_str[3] != '0' || |
+ !base::HexStringToUInt(base::StringPiece(profile_str.c_str() + 2, 1), |
+ &constraint_set_bits)) { |
+ return false; |
+ } |
+ |
+ return constraint_set_bits >= 8; |
+} |
+ |
static bool IsValidH264Level(const std::string& level_str) { |
uint32 level; |
if (level_str.size() != 2 || !base::HexStringToUInt(level_str, &level)) |
@@ -938,13 +971,16 @@ static bool IsValidH264Level(const std::string& level_str) { |
(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 |
+// 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.xxxxxx & avc3.xxxxxx are considered ambiguous forms that |
-// are trying to signal H.264 Baseline. |
+// avc1.xxxxxx & avc3.xxxxxx are considered ambiguous forms that are trying to |
+// signal H.264 Baseline. For example, the idc_level, profile_idc and |
+// constraint_set3_flag pieces may explicitly require decoder to conform to |
+// baseline profile at the specified level (see Annex A and constraint_set0 in |
+// ISO-14496-10). |
static bool ParseH264CodecID(const std::string& codec_id, |
MimeUtil::Codec* codec, |
bool* is_ambiguous) { |
@@ -956,7 +992,7 @@ static bool ParseH264CodecID(const std::string& codec_id, |
} |
std::string profile = StringToUpperASCII(codec_id.substr(5, 4)); |
- if (profile == "42E0") { |
+ if (IsValidH264BaselineProfile(profile)) { |
*codec = MimeUtil::H264_BASELINE; |
} else if (profile == "4D40") { |
*codec = MimeUtil::H264_MAIN; |