diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-04-05 17:15:33 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-04-11 07:47:18 +0000 |
commit | 7324afb043a0b1e623d8e8eb906cdc53bdeb4685 (patch) | |
tree | a3fe2d74ea9c9e142c390dac4ca0e219382ace46 /chromium/media/base/video_codecs.cc | |
parent | 6a4cabb866f66d4128a97cdc6d9d08ce074f1247 (diff) | |
download | qtwebengine-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.cc | 165 |
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; } |