Commit 4da3946d authored by Xiaohan Wang's avatar Xiaohan Wang

media: Support EME VP9 profile2 query for library CDMs

- Add "vp09" parsing in widevine_cdm_component_installer.cc
- Add |supports_vp9_profile2| in media::CdmCapability and
  media::mojom::KeySystemCapability.
- In chrome_key_system.cc, read |supports_vp9_profile2| and decide whether
  EME_CODEC_VP9_PROFILE2 is supported.

CDM supports VP9 profile 2.

Bug: 707127
Test: No functionality change for now. Will update test when Widevine
Change-Id: I2441e65dbf29bdc0d30cdb3f5d26e38afd0e90df
Reviewed-on: https://chromium-review.googlesource.com/c/1297462Reviewed-by: default avatarJohn Rummell <jrummell@chromium.org>
Reviewed-by: default avatarJoshua Pawlicki <waffles@chromium.org>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603195}
parent 4339da08
......@@ -115,11 +115,14 @@ const char kCdmSupportedCdmProxyProtocolsName[] =
// The following strings are used to specify supported codecs in the
// parameter |kCdmCodecsListName|.
const char kCdmSupportedCodecVp8[] = "vp8";
const char kCdmSupportedCodecVp9[] = "vp9.0";
// Legacy VP9, which is equivalent to VP9 profile 0.
// TODO(xhwang): Newer CDMs should support "vp09" below. Remove this after older
// CDMs are obsolete.
const char kCdmSupportedCodecLegacyVp9[] = "vp9.0";
// Supports at least VP9 profile 0 and profile 2.
const char kCdmSupportedCodecVp9[] = "vp09";
const char kCdmSupportedCodecAv1[] = "av01";
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
const char kCdmSupportedCodecAvc1[] = "avc1";
#endif
// The following strings are used to specify supported encryption schemes in
// the parameter |kCdmSupportedEncryptionSchemesName|.
......@@ -183,10 +186,12 @@ bool IsCompatibleWithChrome(const base::DictionaryValue& manifest) {
}
// Returns true and updates |video_codecs| if the appropriate manifest entry is
// valid. Returns false and does not modify |video_codecs| if the manifest entry
// is incorrectly formatted.
// valid. When VP9 is supported, sets |supports_vp9_profile2| if profile 2 is
// supported. Older CDMs may only support profile 0. Returns false and does not
// modify |video_codecs| if the manifest entry is incorrectly formatted.
bool GetCodecs(const base::DictionaryValue& manifest,
std::vector<media::VideoCodec>* video_codecs) {
std::vector<media::VideoCodec>* video_codecs,
bool* supports_vp9_profile2) {
DCHECK(video_codecs);
const base::Value* value = manifest.FindKey(kCdmCodecsListName);
......@@ -212,17 +217,23 @@ bool GetCodecs(const base::DictionaryValue& manifest,
base::SplitStringPiece(codecs, kCdmValueDelimiter, base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
// Assuming VP9 profile 2 is not supported by default. Will only be set when
// kCdmSupportedCodecVp9 is available below.
*supports_vp9_profile2 = false;
for (const auto& codec : supported_codecs) {
if (codec == kCdmSupportedCodecVp8)
if (codec == kCdmSupportedCodecVp8) {
result.push_back(media::VideoCodec::kCodecVP8);
else if (codec == kCdmSupportedCodecVp9)
} else if (codec == kCdmSupportedCodecLegacyVp9) {
result.push_back(media::VideoCodec::kCodecVP9);
else if (codec == kCdmSupportedCodecAv1)
} else if (codec == kCdmSupportedCodecVp9) {
result.push_back(media::VideoCodec::kCodecVP9);
*supports_vp9_profile2 = true;
} else if (codec == kCdmSupportedCodecAv1) {
result.push_back(media::VideoCodec::kCodecAV1);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
else if (codec == kCdmSupportedCodecAvc1)
} else if (codec == kCdmSupportedCodecAvc1) {
result.push_back(media::VideoCodec::kCodecH264);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
}
}
video_codecs->swap(result);
......@@ -354,7 +365,8 @@ bool GetCdmProxyProtocols(
// may or may not be updated.
bool ParseManifest(const base::DictionaryValue& manifest,
content::CdmCapability* capability) {
return GetCodecs(manifest, &capability->video_codecs) &&
return GetCodecs(manifest, &capability->video_codecs,
&capability->supports_vp9_profile2) &&
GetEncryptionSchemes(manifest, &capability->encryption_schemes) &&
GetSessionTypes(manifest, &capability->session_types) &&
GetCdmProxyProtocols(manifest, &capability->cdm_proxy_protocols);
......
......@@ -364,6 +364,9 @@ bool IsWidevineAvailable(base::FilePath* cdm_path,
// This list must match the CDM that is being bundled with Chrome.
capability->video_codecs.push_back(media::VideoCodec::kCodecVP8);
capability->video_codecs.push_back(media::VideoCodec::kCodecVP9);
// TODO(xhwang): Update this and tests after Widevine CDM supports VP9
// profile 2.
capability->supports_vp9_profile2 = false;
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
capability->video_codecs.push_back(media::VideoCodec::kCodecH264);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
......
......@@ -144,6 +144,7 @@ static void AddExternalClearKey(
#if BUILDFLAG(ENABLE_WIDEVINE)
static SupportedCodecs GetSupportedCodecs(
const std::vector<media::VideoCodec>& supported_video_codecs,
bool supports_vp9_profile2,
bool is_secure) {
SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
......@@ -169,8 +170,9 @@ static SupportedCodecs GetSupportedCodecs(
supported_codecs |= media::EME_CODEC_VP8;
break;
case media::VideoCodec::kCodecVP9:
// TODO(crbug.com/707127): Support VP9 higher profiles.
supported_codecs |= media::EME_CODEC_VP9_PROFILE0;
if (supports_vp9_profile2)
supported_codecs |= media::EME_CODEC_VP9_PROFILE2;
break;
case media::VideoCodec::kCodecAV1:
supported_codecs |= media::EME_CODEC_AV1;
......@@ -251,10 +253,13 @@ static void AddWidevine(
}
// Codecs and encryption schemes.
auto codecs =
GetSupportedCodecs(capability->video_codecs, /*is_secure=*/false);
auto codecs = GetSupportedCodecs(capability->video_codecs,
capability->supports_vp9_profile2,
/*is_secure=*/false);
const auto& encryption_schemes = capability->encryption_schemes;
// TODO(xhwang): Investigate whether hardware VP9 profile 2 is supported.
auto hw_secure_codecs = GetSupportedCodecs(capability->hw_secure_video_codecs,
/*supports_vp9_profile2=*/false,
/*is_secure=*/true);
const auto& hw_secure_encryption_schemes =
capability->hw_secure_encryption_schemes;
......
......@@ -178,6 +178,8 @@ void KeySystemSupportImpl::IsKeySystemSupported(
// Supported codecs and encryption schemes.
auto capability = media::mojom::KeySystemCapability::New();
capability->video_codecs = cdm_info->capability.video_codecs;
capability->supports_vp9_profile2 =
cdm_info->capability.supports_vp9_profile2;
capability->encryption_schemes =
SetToVector(cdm_info->capability.encryption_schemes);
......
......@@ -38,6 +38,12 @@ struct CONTENT_EXPORT CdmCapability {
// TODO(crbug.com/796725) Find a way to include profiles and levels.
std::vector<media::VideoCodec> video_codecs;
// When VP9 is supported in |video_codecs|, whether profile 2 is supported.
// This is needed because there are older CDMs that only supports profile 0.
// TODO(xhwang): Remove this after older CDMs that only supports VP9 profile 0
// are obsolete.
bool supports_vp9_profile2 = false;
// List of encryption schemes supported by the CDM (e.g. cenc).
base::flat_set<media::EncryptionMode> encryption_schemes;
......
......@@ -13,6 +13,7 @@ import "media/mojo/interfaces/media_types.mojom";
struct KeySystemCapability {
// Software secure codecs and encryption schemes supported by the CDM.
array<VideoCodec> video_codecs;
bool supports_vp9_profile2;
array<EncryptionMode> encryption_schemes;
// Hardware secure codecs and encryption schemes supported by the CDM,
......
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