Bug 1844169 - part6 : map normal Widevine key system to Widevine experiment key system. r=jolin

Our EME system works like this,

First, the content process stores some cached capabilities for different
key systems, which tells what codecs they support, and whether hw
decryption works or not.

Then in the content process, we would compare those capabilies to the
one that website requests by using EME API, to see if that is any
matching.

What this patch is going to do is, if website uses `com.widevine.alpha`
with hardware decryption request, then we would check those experiment
key system to see if they support (because they are used for hardware
decryption only).

Therefore, we would be able to support two cases for hardware
decryption, (1) use experiment key system explicitly (2) use normal key
system but requests an explicit robustness for hardware decryption [1].

[1] Example test page (you can add robustness on setting)
https://integration.widevine.com/player

Differential Revision: https://phabricator.services.mozilla.com/D190639
This commit is contained in:
alwu 2023-10-24 23:18:01 +00:00
Родитель f4560d9ac1
Коммит 89c1dfed16
11 изменённых файлов: 84 добавлений и 11 удалений

Просмотреть файл

@ -253,6 +253,8 @@ class CDMProxy {
virtual WMFCDMProxy* AsWMFCDMProxy() { return nullptr; }
#endif
virtual bool IsHardwareDecryptionSupported() const { return false; }
protected:
// Main thread only.
CDMProxy(dom::MediaKeys* aKeys, const nsAString& aKeySystem,

Просмотреть файл

@ -109,4 +109,23 @@ const char* ToMediaKeyStatusStr(dom::MediaKeyStatus aStatus) {
#undef ENUM_TO_STR
bool IsHardwareDecryptionSupported(
const dom::MediaKeySystemConfiguration& aConfig) {
bool supportHardwareDecryption = false;
for (const auto& capabilities : aConfig.mAudioCapabilities) {
if (capabilities.mRobustness.EqualsLiteral("HW_SECURE_ALL")) {
supportHardwareDecryption = true;
break;
}
}
for (const auto& capabilities : aConfig.mVideoCapabilities) {
if (capabilities.mRobustness.EqualsLiteral("3000") ||
capabilities.mRobustness.EqualsLiteral("HW_SECURE_ALL")) {
supportHardwareDecryption = true;
break;
}
}
return supportHardwareDecryption;
}
} // namespace mozilla

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/Logging.h"
#include "mozilla/dom/MediaKeyStatusMapBinding.h"
#include "mozilla/dom/MediaKeySystemAccessBinding.h"
#include "nsString.h"
#include "nsTArray.h"
@ -73,6 +74,10 @@ CDMType ToCDMTypeTelemetryEnum(const nsString& aKeySystem);
const char* ToMediaKeyStatusStr(dom::MediaKeyStatus aStatus);
// Return true if given config supports hardware decryption (SL3000 or L1).
bool IsHardwareDecryptionSupported(
const dom::MediaKeySystemConfiguration& aConfig);
} // namespace mozilla
#endif // EME_LOG_H_

Просмотреть файл

@ -199,6 +199,18 @@ bool KeySystemConfig::CreateKeySystemConfigs(
return false;
}
bool KeySystemConfig::IsSameKeySystem(const nsAString& aKeySystem) const {
#ifdef MOZ_WMF_CDM
// We want to map Widevine experiment key system to normal Widevine key system
// as well.
if (IsWidevineExperimentKeySystemAndSupported(mKeySystem)) {
return mKeySystem.Equals(aKeySystem) ||
aKeySystem.EqualsLiteral(kWidevineKeySystemName);
}
#endif
return mKeySystem.Equals(aKeySystem);
}
#ifdef DEBUG
nsString KeySystemConfig::GetDebugInfo() const {
nsString debugInfo;

Просмотреть файл

@ -159,6 +159,10 @@ struct KeySystemConfig {
nsString GetDebugInfo() const;
#endif
// Return true if the given key system is equal to `mKeySystem`, or it can be
// mapped to the same key system
bool IsSameKeySystem(const nsAString& aKeySystem) const;
nsString mKeySystem;
nsTArray<nsString> mInitDataTypes;
Requirement mPersistentState = Requirement::NotAllowed;

Просмотреть файл

@ -193,7 +193,7 @@ static bool GetKeySystemConfigs(
nsTArray<KeySystemConfig>& aOutKeySystemConfig) {
bool foundConfigs = false;
for (auto& config : GetSupportedKeySystems()) {
if (config.mKeySystem.Equals(aKeySystem)) {
if (config.IsSameKeySystem(aKeySystem)) {
aOutKeySystemConfig.AppendElement(std::move(config));
foundConfigs = true;
}
@ -729,6 +729,11 @@ static bool GetSupportedConfig(
MediaKeySystemConfiguration& aOutConfig,
DecoderDoctorDiagnostics* aDiagnostics, bool aInPrivateBrowsing,
const std::function<void(const char*)>& aDeprecationLogFn) {
#ifdef DEBUG
EME_LOG("Compare implementation '%s'\n with request '%s'",
NS_ConvertUTF16toUTF8(aKeySystem.GetDebugInfo()).get(),
ToCString(aCandidate).get());
#endif
// Let accumulated configuration be a new MediaKeySystemConfiguration
// dictionary.
MediaKeySystemConfiguration config;

Просмотреть файл

@ -428,7 +428,10 @@ class MediaKeysGMPCrashHelper : public GMPCrashHelper {
};
already_AddRefed<CDMProxy> MediaKeys::CreateCDMProxy() {
EME_LOG("MediaKeys[%p]::CreateCDMProxy()", this);
const bool isHardwareDecryptionSupported =
IsHardwareDecryptionSupported(mConfig);
EME_LOG("MediaKeys[%p]::CreateCDMProxy(), isHardwareDecryptionSupported=%d",
this, isHardwareDecryptionSupported);
RefPtr<CDMProxy> proxy;
#ifdef MOZ_WIDGET_ANDROID
if (IsWidevineKeySystem(mKeySystem)) {
@ -440,7 +443,8 @@ already_AddRefed<CDMProxy> MediaKeys::CreateCDMProxy() {
#endif
#ifdef MOZ_WMF_CDM
if (IsPlayReadyKeySystemAndSupported(mKeySystem) ||
IsWidevineExperimentKeySystemAndSupported(mKeySystem)) {
IsWidevineExperimentKeySystemAndSupported(mKeySystem) ||
(IsWidevineKeySystem(mKeySystem) && isHardwareDecryptionSupported)) {
proxy = new WMFCDMProxy(this, mKeySystem, mConfig);
} else
#endif

Просмотреть файл

@ -8,6 +8,7 @@
#include "mozilla/dom/MediaKeySession.h"
#include "mozilla/dom/MediaKeySystemAccessBinding.h"
#include "mozilla/EMEUtils.h"
#include "mozilla/WMFCDMProxyCallback.h"
#include "WMFCDMImpl.h"
#include "WMFCDMProxyCallback.h"
@ -103,6 +104,8 @@ WMFCDMProxy::GenerateMFCDMMediaCapabilities(
const dom::Sequence<dom::MediaKeySystemMediaCapability>& aCapabilities) {
CopyableTArray<MFCDMMediaCapability> outCapabilites;
for (const auto& capabilities : aCapabilities) {
EME_LOG("WMFCDMProxy::Init %p, robustness=%s", this,
NS_ConvertUTF16toUTF8(capabilities.mRobustness).get());
outCapabilites.AppendElement(MFCDMMediaCapability{
capabilities.mContentType, capabilities.mRobustness});
}
@ -308,6 +311,10 @@ void WMFCDMProxy::OnExpirationChange(const nsAString& aSessionId,
}
}
bool WMFCDMProxy::IsHardwareDecryptionSupported() const {
return mozilla::IsHardwareDecryptionSupported(mConfig);
}
uint64_t WMFCDMProxy::GetCDMProxyId() const {
MOZ_DIAGNOSTIC_ASSERT(mCDM);
return mCDM->Id();

Просмотреть файл

@ -110,6 +110,8 @@ class WMFCDMProxy : public CDMProxy {
WMFCDMProxy* AsWMFCDMProxy() override { return this; }
bool IsHardwareDecryptionSupported() const override;
// Can only be called after initialization succeeded.
uint64_t GetCDMProxyId() const;

Просмотреть файл

@ -286,6 +286,13 @@ static nsString GetOriginalKeySystem(const nsString& aKeySystem) {
return aKeySystem;
}
static nsString MapKeySystem(const nsString& aKeySystem) {
if (IsWidevineKeySystem(aKeySystem)) {
return nsString(u"com.widevine.alpha.experiment");
}
return aKeySystem;
}
void MFCDMParent::Register() {
MOZ_ASSERT(!sRegisteredCDMs.Contains(this->mId));
sRegisteredCDMs.InsertOrUpdate(this->mId, this);
@ -310,7 +317,8 @@ MFCDMParent::MFCDMParent(const nsAString& aKeySystem,
mExpirationEvents(aManagerThread) {
// TODO : add ClearKey CDM support
MOZ_ASSERT(IsPlayReadyKeySystemAndSupported(aKeySystem) ||
IsWidevineExperimentKeySystemAndSupported(aKeySystem));
IsWidevineExperimentKeySystemAndSupported(aKeySystem) ||
IsWidevineKeySystem(mKeySystem));
MOZ_ASSERT(aManager);
MOZ_ASSERT(aManagerThread);
MOZ_ASSERT(XRE_IsUtilityProcess());
@ -374,7 +382,8 @@ LPCWSTR MFCDMParent::GetCDMLibraryName() const {
if (IsPlayReadyKeySystemAndSupported(mKeySystem)) {
return L"";
}
if (IsWidevineExperimentKeySystemAndSupported(mKeySystem)) {
if (IsWidevineExperimentKeySystemAndSupported(mKeySystem) ||
IsWidevineKeySystem(mKeySystem)) {
// TODO : return real Widevine Dll name in bug 1858546
return L"";
}
@ -423,7 +432,8 @@ HRESULT MFCDMParent::LoadFactory() {
// "<key_system>.ContentDecryptionModuleFactory". In addition, when querying
// factory, need to use original Widevine key system name.
nsString stringId;
if (IsWidevineExperimentKeySystemAndSupported(mKeySystem)) {
if (IsWidevineExperimentKeySystemAndSupported(mKeySystem) ||
IsWidevineKeySystem(mKeySystem)) {
stringId.AppendLiteral("com.widevine.alpha.ContentDecryptionModuleFactory");
}
MFCDM_PARENT_LOG("Query factory by classId '%s",
@ -533,7 +543,8 @@ static bool IsKeySystemHWSecure(
}
}
}
if (IsWidevineExperimentKeySystemAndSupported(aKeySystem)) {
if (IsWidevineExperimentKeySystemAndSupported(aKeySystem) ||
IsWidevineKeySystem(aKeySystem)) {
// We only support Widevine HWDRM.
return true;
}
@ -696,9 +707,9 @@ mozilla::ipc::IPCResult MFCDMParent::RecvInit(
MOZ_ASSERT(mFactory->IsTypeSupported(GetOriginalKeySystem(mKeySystem).get(),
nullptr));
MFCDM_REJECT_IF_FAILED(
CreateContentDecryptionModule(mFactory, mKeySystem, aParams, mCDM),
NS_ERROR_FAILURE);
MFCDM_REJECT_IF_FAILED(CreateContentDecryptionModule(
mFactory, MapKeySystem(mKeySystem), aParams, mCDM),
NS_ERROR_FAILURE);
MOZ_ASSERT(mCDM);
MFCDM_PARENT_LOG("Created a CDM!");

Просмотреть файл

@ -799,7 +799,9 @@ void PDMFactory::SetCDMProxy(CDMProxy* aProxy) {
#endif
#ifdef MOZ_WMF_CDM
if (IsPlayReadyKeySystemAndSupported(aProxy->KeySystem()) ||
IsWidevineExperimentKeySystemAndSupported(aProxy->KeySystem())) {
IsWidevineExperimentKeySystemAndSupported(aProxy->KeySystem()) ||
(IsWidevineKeySystem(aProxy->KeySystem()) &&
aProxy->IsHardwareDecryptionSupported())) {
mEMEPDM = RemoteDecoderModule::Create(
RemoteDecodeIn::UtilityProcess_MFMediaEngineCDM);
return;