Commit 0a0cad0d authored by wolenetz's avatar wolenetz Committed by Commit bot

MSE: Relax H.264 Baseline mimetype profile recognition

This change lets "avc[13].42y0xx", where y >= 0x8 and xx is a valid
level, be an unambiguously matched H.264 Baseline profile. This relaxes
the previous requirement of a constrained baseline where y had to be
0xE.

CodecParameter | Before                            | Now
----------------------------------------------------------------------------------------------------
avc[13].42y0xx | probably if y==E, maybe otherwise | probably if y is in [89ABCDEF], maybe otherwise

BUG=408552
R=rsleevi@chromium.org,qinmin@chromium.org,dalecurtis@chromium.org
TBR=xhwang@chromium.org
TEST=Updated MediaCanPlayTypeTest.CodecSupportTest_*

Review URL: https://codereview.chromium.org/626163002

Cr-Commit-Position: refs/heads/master@{#298163}
parent b5a2021b
......@@ -404,6 +404,14 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc1.42E01E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc3.42E01E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc3.42801E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc3.42C01E\"'"));
EXPECT_EQ(kPropMaybe, CanPlay("'video/mp4; codecs=\"avc1.42E11E\"'"));
EXPECT_EQ(kPropMaybe, CanPlay("'video/mp4; codecs=\"avc1.42101E\"'"));
EXPECT_EQ(kPropMaybe, CanPlay("'video/mp4; codecs=\"avc1.42701E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"avc1.42F01E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/mp4; codecs=\"mp4a.40.2\"'"));
EXPECT_EQ(kPropProbably,
CanPlay("'video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"'"));
......@@ -430,6 +438,14 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_mp4) {
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc1.42E01E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc3.42E01E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc3.42801E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc3.42C01E\"'"));
EXPECT_EQ(kPropMaybe, CanPlay("'video/x-m4v; codecs=\"avc1.42E11E\"'"));
EXPECT_EQ(kPropMaybe, CanPlay("'video/x-m4v; codecs=\"avc1.42101E\"'"));
EXPECT_EQ(kPropMaybe, CanPlay("'video/x-m4v; codecs=\"avc1.42701E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"avc1.42F01E\"'"));
EXPECT_EQ(kPropProbably, CanPlay("'video/x-m4v; codecs=\"mp4a.40.2\"'"));
EXPECT_EQ(kPropProbably,
CanPlay("'video/x-m4v; codecs=\"avc1.42E01E, mp4a.40.2\"'"));
......@@ -501,6 +517,20 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_HLS) {
CanPlay("'application/x-mpegurl; codecs=\"avc1.42E01E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"avc3.42E01E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"avc3.42801E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"avc3.42C01E\"'"));
EXPECT_EQ(maybeCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"avc1.42E11E\"'"));
EXPECT_EQ(maybeCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"avc1.42101E\"'"));
EXPECT_EQ(maybeCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"avc1.42701E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"avc1.42F01E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/x-mpegurl; codecs=\"mp4a.40.2\"'"));
EXPECT_EQ(probablyCanPlayHLS,
......@@ -536,6 +566,20 @@ IN_PROC_BROWSER_TEST_F(MediaCanPlayTypeTest, CodecSupportTest_HLS) {
CanPlay("'application/vnd.apple.mpegurl; codecs=\"avc1.42E01E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/vnd.apple.mpegurl; codecs=\"avc3.42E01E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/vnd.apple.mpegurl; codecs=\"avc3.42801E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/vnd.apple.mpegurl; codecs=\"avc3.42C01E\"'"));
EXPECT_EQ(maybeCanPlayHLS,
CanPlay("'application/vnd.apple.mpegurl; codecs=\"avc1.42E11E\"'"));
EXPECT_EQ(maybeCanPlayHLS,
CanPlay("'application/vnd.apple.mpegurl; codecs=\"avc1.42101E\"'"));
EXPECT_EQ(maybeCanPlayHLS,
CanPlay("'application/vnd.apple.mpegurl; codecs=\"avc1.42701E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/vnd.apple.mpegurl; codecs=\"avc1.42F01E\"'"));
EXPECT_EQ(probablyCanPlayHLS,
CanPlay("'application/vnd.apple.mpegurl; codecs=\"mp4a.40.2\"'"));
......
......@@ -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
// 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment