summaryrefslogtreecommitdiff
path: root/chromium/media/base/video_codecs.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-04-05 17:15:33 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-04-11 07:47:18 +0000
commit7324afb043a0b1e623d8e8eb906cdc53bdeb4685 (patch)
treea3fe2d74ea9c9e142c390dac4ca0e219382ace46 /chromium/media/base/video_codecs.cc
parent6a4cabb866f66d4128a97cdc6d9d08ce074f1247 (diff)
downloadqtwebengine-chromium-7324afb043a0b1e623d8e8eb906cdc53bdeb4685.tar.gz
BASELINE: Update Chromium to 58.0.3029.54
Change-Id: I67f57065a7afdc8e4614adb5c0230281428df4d1 Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'chromium/media/base/video_codecs.cc')
-rw-r--r--chromium/media/base/video_codecs.cc165
1 files changed, 165 insertions, 0 deletions
diff --git a/chromium/media/base/video_codecs.cc b/chromium/media/base/video_codecs.cc
index d1b9b6974e4..e68e4337693 100644
--- a/chromium/media/base/video_codecs.cc
+++ b/chromium/media/base/video_codecs.cc
@@ -20,6 +20,8 @@ std::string GetCodecName(VideoCodec codec) {
return "h264";
case kCodecHEVC:
return "hevc";
+ case kCodecDolbyVision:
+ return "dolbyvision";
case kCodecVC1:
return "vc1";
case kCodecMPEG2:
@@ -79,6 +81,14 @@ std::string GetProfileName(VideoCodecProfile profile) {
return "vp9 profile2";
case VP9PROFILE_PROFILE3:
return "vp9 profile3";
+ case DOLBYVISION_PROFILE0:
+ return "dolby vision profile 0";
+ case DOLBYVISION_PROFILE4:
+ return "dolby vision profile 4";
+ case DOLBYVISION_PROFILE5:
+ return "dolby vision profile 5";
+ case DOLBYVISION_PROFILE7:
+ return "dolby vision profile 7";
}
NOTREACHED();
return "";
@@ -260,6 +270,55 @@ bool ParseAVCCodecId(const std::string& codec_id,
return true;
}
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
+static const char kHexString[] = "0123456789ABCDEF";
+static char IntToHex(int i) {
+ DCHECK_GE(i, 0) << i << " not a hex value";
+ DCHECK_LE(i, 15) << i << " not a hex value";
+ return kHexString[i];
+}
+
+std::string TranslateLegacyAvc1CodecIds(const std::string& codec_id) {
+ // Special handling for old, pre-RFC 6381 format avc1 strings, which are still
+ // being used by some HLS apps to preserve backward compatibility with older
+ // iOS devices. The old format was avc1.<profile>.<level>
+ // Where <profile> is H.264 profile_idc encoded as a decimal number, i.e.
+ // 66 is baseline profile (0x42)
+ // 77 is main profile (0x4d)
+ // 100 is high profile (0x64)
+ // And <level> is H.264 level multiplied by 10, also encoded as decimal number
+ // E.g. <level> 31 corresponds to H.264 level 3.1
+ // See, for example, http://qtdevseed.apple.com/qadrift/testcases/tc-0133.php
+ uint32_t level_start = 0;
+ std::string result;
+ if (base::StartsWith(codec_id, "avc1.66.", base::CompareCase::SENSITIVE)) {
+ level_start = 8;
+ result = "avc1.4200";
+ } else if (base::StartsWith(codec_id, "avc1.77.",
+ base::CompareCase::SENSITIVE)) {
+ level_start = 8;
+ result = "avc1.4D00";
+ } else if (base::StartsWith(codec_id, "avc1.100.",
+ base::CompareCase::SENSITIVE)) {
+ level_start = 9;
+ result = "avc1.6400";
+ }
+
+ uint32_t level = 0;
+ if (level_start > 0 &&
+ base::StringToUint(codec_id.substr(level_start), &level) && level < 256) {
+ // This is a valid legacy avc1 codec id - return the codec id translated
+ // into RFC 6381 format.
+ result.push_back(IntToHex(level >> 4));
+ result.push_back(IntToHex(level & 0xf));
+ return result;
+ }
+
+ // This is not a valid legacy avc1 codec id - return the original codec id.
+ return codec_id;
+}
+#endif
+
#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
// The specification for HEVC codec id strings can be found in ISO IEC 14496-15
// dated 2012 or newer in the Annex E.3
@@ -370,6 +429,104 @@ bool ParseHEVCCodecId(const std::string& codec_id,
}
#endif
+#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
+bool IsDolbyVisionAVCCodecId(const std::string& codec_id) {
+ return base::StartsWith(codec_id, "dva1.", base::CompareCase::SENSITIVE) ||
+ base::StartsWith(codec_id, "dvav.", base::CompareCase::SENSITIVE);
+}
+
+bool IsDolbyVisionHEVCCodecId(const std::string& codec_id) {
+ return base::StartsWith(codec_id, "dvh1.", base::CompareCase::SENSITIVE) ||
+ base::StartsWith(codec_id, "dvhe.", base::CompareCase::SENSITIVE);
+}
+
+// The specification for Dolby Vision codec id strings can be found in Dolby
+// Vision streams within the MPEG-DASH format.
+bool ParseDolbyVisionCodecId(const std::string& codec_id,
+ VideoCodecProfile* profile,
+ uint8_t* level_idc) {
+ if (!IsDolbyVisionAVCCodecId(codec_id) &&
+ !IsDolbyVisionHEVCCodecId(codec_id)) {
+ return false;
+ }
+
+ const int kMaxDvCodecIdLength = 5 // FOURCC string
+ + 1 // delimiting period
+ + 2 // profile id as 2 digit string
+ + 1 // delimiting period
+ + 2; // level id as 2 digit string.
+
+ if (codec_id.size() > kMaxDvCodecIdLength) {
+ DVLOG(4) << __func__ << ": Codec id is too long (" << codec_id << ")";
+ return false;
+ }
+
+ std::vector<std::string> elem = base::SplitString(
+ codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ DCHECK(elem[0] == "dvh1" || elem[0] == "dvhe" || elem[0] == "dva1" ||
+ elem[0] == "dvav");
+
+ if (elem.size() != 3) {
+ DVLOG(4) << __func__ << ": invalid dolby vision codec id " << codec_id;
+ return false;
+ }
+
+ // Profile string should be two digits.
+ unsigned profile_id = 0;
+ if (elem[1].size() != 2 || !base::StringToUint(elem[1], &profile_id) ||
+ profile_id > 7) {
+ DVLOG(4) << __func__ << ": invalid format or profile_id=" << elem[1];
+ return false;
+ }
+
+ // Only profiles 0, 4, 5 and 7 are valid. Profile 0 is encoded based on AVC
+ // while profile 4, 5 and 7 are based on HEVC.
+ switch (profile_id) {
+ case 0:
+ if (!IsDolbyVisionAVCCodecId(codec_id)) {
+ DVLOG(4) << __func__
+ << ": codec id is mismatched with profile_id=" << profile_id;
+ return false;
+ }
+ *profile = DOLBYVISION_PROFILE0;
+ break;
+#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
+ case 4:
+ case 5:
+ case 7:
+ if (!IsDolbyVisionHEVCCodecId(codec_id)) {
+ DVLOG(4) << __func__
+ << ": codec id is mismatched with profile_id=" << profile_id;
+ return false;
+ }
+ if (profile_id == 4)
+ *profile = DOLBYVISION_PROFILE4;
+ else if (profile_id == 5)
+ *profile = DOLBYVISION_PROFILE5;
+ else if (profile_id == 7)
+ *profile = DOLBYVISION_PROFILE7;
+ break;
+#endif
+ default:
+ DVLOG(4) << __func__
+ << ": depecrated and not supported profile_id=" << profile_id;
+ return false;
+ }
+
+ // Level string should be two digits.
+ unsigned level_id = 0;
+ if (elem[2].size() != 2 || !base::StringToUint(elem[2], &level_id) ||
+ level_id > 9 || level_id < 1) {
+ DVLOG(4) << __func__ << ": invalid format level_id=" << elem[2];
+ return false;
+ }
+
+ *level_idc = level_id;
+
+ return true;
+}
+#endif
+
VideoCodec StringToVideoCodec(const std::string& codec_id) {
std::vector<std::string> elem = base::SplitString(
codec_id, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
@@ -387,10 +544,18 @@ VideoCodec StringToVideoCodec(const std::string& codec_id) {
return kCodecTheora;
if (ParseAVCCodecId(codec_id, &profile, &level))
return kCodecH264;
+#if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER)
+ if (ParseAVCCodecId(TranslateLegacyAvc1CodecIds(codec_id), &profile, &level))
+ return kCodecH264;
+#endif
#if BUILDFLAG(ENABLE_HEVC_DEMUXING)
if (ParseHEVCCodecId(codec_id, &profile, &level))
return kCodecHEVC;
#endif
+#if BUILDFLAG(ENABLE_DOLBY_VISION_DEMUXING)
+ if (ParseDolbyVisionCodecId(codec_id, &profile, &level))
+ return kCodecDolbyVision;
+#endif
return kUnknownVideoCodec;
}