| Index: media/base/video_codecs.cc
|
| diff --git a/media/base/video_codecs.cc b/media/base/video_codecs.cc
|
| index eb7daa2c21be0f2127073ebab00f74b28c7ee2e9..e68e4337693b6fc816bb298430198ada750d0d6c 100644
|
| --- a/media/base/video_codecs.cc
|
| +++ b/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 "";
|
| @@ -419,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);
|
| @@ -444,6 +552,10 @@ VideoCodec StringToVideoCodec(const std::string& codec_id) {
|
| 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;
|
| }
|
|
|
|
|