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[] = ...@@ -115,11 +115,14 @@ const char kCdmSupportedCdmProxyProtocolsName[] =
// The following strings are used to specify supported codecs in the // The following strings are used to specify supported codecs in the
// parameter |kCdmCodecsListName|. // parameter |kCdmCodecsListName|.
const char kCdmSupportedCodecVp8[] = "vp8"; 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"; const char kCdmSupportedCodecAv1[] = "av01";
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
const char kCdmSupportedCodecAvc1[] = "avc1"; const char kCdmSupportedCodecAvc1[] = "avc1";
#endif
// The following strings are used to specify supported encryption schemes in // The following strings are used to specify supported encryption schemes in
// the parameter |kCdmSupportedEncryptionSchemesName|. // the parameter |kCdmSupportedEncryptionSchemesName|.
...@@ -183,10 +186,12 @@ bool IsCompatibleWithChrome(const base::DictionaryValue& manifest) { ...@@ -183,10 +186,12 @@ bool IsCompatibleWithChrome(const base::DictionaryValue& manifest) {
} }
// Returns true and updates |video_codecs| if the appropriate manifest entry is // 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 // valid. When VP9 is supported, sets |supports_vp9_profile2| if profile 2 is
// is incorrectly formatted. // 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, 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); DCHECK(video_codecs);
const base::Value* value = manifest.FindKey(kCdmCodecsListName); const base::Value* value = manifest.FindKey(kCdmCodecsListName);
...@@ -212,17 +217,23 @@ bool GetCodecs(const base::DictionaryValue& manifest, ...@@ -212,17 +217,23 @@ bool GetCodecs(const base::DictionaryValue& manifest,
base::SplitStringPiece(codecs, kCdmValueDelimiter, base::TRIM_WHITESPACE, base::SplitStringPiece(codecs, kCdmValueDelimiter, base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY); 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) { for (const auto& codec : supported_codecs) {
if (codec == kCdmSupportedCodecVp8) if (codec == kCdmSupportedCodecVp8) {
result.push_back(media::VideoCodec::kCodecVP8); result.push_back(media::VideoCodec::kCodecVP8);
else if (codec == kCdmSupportedCodecVp9) } else if (codec == kCdmSupportedCodecLegacyVp9) {
result.push_back(media::VideoCodec::kCodecVP9); 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); 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); result.push_back(media::VideoCodec::kCodecH264);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) }
} }
video_codecs->swap(result); video_codecs->swap(result);
...@@ -354,7 +365,8 @@ bool GetCdmProxyProtocols( ...@@ -354,7 +365,8 @@ bool GetCdmProxyProtocols(
// may or may not be updated. // may or may not be updated.
bool ParseManifest(const base::DictionaryValue& manifest, bool ParseManifest(const base::DictionaryValue& manifest,
content::CdmCapability* capability) { content::CdmCapability* capability) {
return GetCodecs(manifest, &capability->video_codecs) && return GetCodecs(manifest, &capability->video_codecs,
&capability->supports_vp9_profile2) &&
GetEncryptionSchemes(manifest, &capability->encryption_schemes) && GetEncryptionSchemes(manifest, &capability->encryption_schemes) &&
GetSessionTypes(manifest, &capability->session_types) && GetSessionTypes(manifest, &capability->session_types) &&
GetCdmProxyProtocols(manifest, &capability->cdm_proxy_protocols); GetCdmProxyProtocols(manifest, &capability->cdm_proxy_protocols);
......
...@@ -364,6 +364,9 @@ bool IsWidevineAvailable(base::FilePath* cdm_path, ...@@ -364,6 +364,9 @@ bool IsWidevineAvailable(base::FilePath* cdm_path,
// This list must match the CDM that is being bundled with Chrome. // 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::kCodecVP8);
capability->video_codecs.push_back(media::VideoCodec::kCodecVP9); 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) #if BUILDFLAG(USE_PROPRIETARY_CODECS)
capability->video_codecs.push_back(media::VideoCodec::kCodecH264); capability->video_codecs.push_back(media::VideoCodec::kCodecH264);
#endif // BUILDFLAG(USE_PROPRIETARY_CODECS) #endif // BUILDFLAG(USE_PROPRIETARY_CODECS)
......
...@@ -144,6 +144,7 @@ static void AddExternalClearKey( ...@@ -144,6 +144,7 @@ static void AddExternalClearKey(
#if BUILDFLAG(ENABLE_WIDEVINE) #if BUILDFLAG(ENABLE_WIDEVINE)
static SupportedCodecs GetSupportedCodecs( static SupportedCodecs GetSupportedCodecs(
const std::vector<media::VideoCodec>& supported_video_codecs, const std::vector<media::VideoCodec>& supported_video_codecs,
bool supports_vp9_profile2,
bool is_secure) { bool is_secure) {
SupportedCodecs supported_codecs = media::EME_CODEC_NONE; SupportedCodecs supported_codecs = media::EME_CODEC_NONE;
...@@ -169,8 +170,9 @@ static SupportedCodecs GetSupportedCodecs( ...@@ -169,8 +170,9 @@ static SupportedCodecs GetSupportedCodecs(
supported_codecs |= media::EME_CODEC_VP8; supported_codecs |= media::EME_CODEC_VP8;
break; break;
case media::VideoCodec::kCodecVP9: case media::VideoCodec::kCodecVP9:
// TODO(crbug.com/707127): Support VP9 higher profiles.
supported_codecs |= media::EME_CODEC_VP9_PROFILE0; supported_codecs |= media::EME_CODEC_VP9_PROFILE0;
if (supports_vp9_profile2)
supported_codecs |= media::EME_CODEC_VP9_PROFILE2;
break; break;
case media::VideoCodec::kCodecAV1: case media::VideoCodec::kCodecAV1:
supported_codecs |= media::EME_CODEC_AV1; supported_codecs |= media::EME_CODEC_AV1;
...@@ -251,10 +253,13 @@ static void AddWidevine( ...@@ -251,10 +253,13 @@ static void AddWidevine(
} }
// Codecs and encryption schemes. // Codecs and encryption schemes.
auto codecs = auto codecs = GetSupportedCodecs(capability->video_codecs,
GetSupportedCodecs(capability->video_codecs, /*is_secure=*/false); capability->supports_vp9_profile2,
/*is_secure=*/false);
const auto& encryption_schemes = capability->encryption_schemes; 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, auto hw_secure_codecs = GetSupportedCodecs(capability->hw_secure_video_codecs,
/*supports_vp9_profile2=*/false,
/*is_secure=*/true); /*is_secure=*/true);
const auto& hw_secure_encryption_schemes = const auto& hw_secure_encryption_schemes =
capability->hw_secure_encryption_schemes; capability->hw_secure_encryption_schemes;
......
...@@ -178,6 +178,8 @@ void KeySystemSupportImpl::IsKeySystemSupported( ...@@ -178,6 +178,8 @@ void KeySystemSupportImpl::IsKeySystemSupported(
// Supported codecs and encryption schemes. // Supported codecs and encryption schemes.
auto capability = media::mojom::KeySystemCapability::New(); auto capability = media::mojom::KeySystemCapability::New();
capability->video_codecs = cdm_info->capability.video_codecs; capability->video_codecs = cdm_info->capability.video_codecs;
capability->supports_vp9_profile2 =
cdm_info->capability.supports_vp9_profile2;
capability->encryption_schemes = capability->encryption_schemes =
SetToVector(cdm_info->capability.encryption_schemes); SetToVector(cdm_info->capability.encryption_schemes);
......
...@@ -38,6 +38,12 @@ struct CONTENT_EXPORT CdmCapability { ...@@ -38,6 +38,12 @@ struct CONTENT_EXPORT CdmCapability {
// TODO(crbug.com/796725) Find a way to include profiles and levels. // TODO(crbug.com/796725) Find a way to include profiles and levels.
std::vector<media::VideoCodec> video_codecs; 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). // List of encryption schemes supported by the CDM (e.g. cenc).
base::flat_set<media::EncryptionMode> encryption_schemes; base::flat_set<media::EncryptionMode> encryption_schemes;
......
...@@ -13,6 +13,7 @@ import "media/mojo/interfaces/media_types.mojom"; ...@@ -13,6 +13,7 @@ import "media/mojo/interfaces/media_types.mojom";
struct KeySystemCapability { struct KeySystemCapability {
// Software secure codecs and encryption schemes supported by the CDM. // Software secure codecs and encryption schemes supported by the CDM.
array<VideoCodec> video_codecs; array<VideoCodec> video_codecs;
bool supports_vp9_profile2;
array<EncryptionMode> encryption_schemes; array<EncryptionMode> encryption_schemes;
// Hardware secure codecs and encryption schemes supported by the CDM, // 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