mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-26 02:17:34 +09:00
168 lines
5 KiB
C++
168 lines
5 KiB
C++
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||
|
|
|
||
|
|
#include "WidevineAdapter.h"
|
||
|
|
#include "content_decryption_module.h"
|
||
|
|
#include "VideoUtils.h"
|
||
|
|
#include "WidevineDecryptor.h"
|
||
|
|
#include "WidevineUtils.h"
|
||
|
|
#include "WidevineVideoDecoder.h"
|
||
|
|
#include "gmp-api/gmp-entrypoints.h"
|
||
|
|
#include "gmp-api/gmp-decryption.h"
|
||
|
|
#include "gmp-api/gmp-video-codec.h"
|
||
|
|
#include "gmp-api/gmp-platform.h"
|
||
|
|
|
||
|
|
static const GMPPlatformAPI* sPlatform = nullptr;
|
||
|
|
|
||
|
|
namespace mozilla {
|
||
|
|
|
||
|
|
GMPErr GMPGetCurrentTime(GMPTimestamp* aOutTime) {
|
||
|
|
return sPlatform->getcurrenttime(aOutTime);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Call on main thread only.
|
||
|
|
GMPErr GMPSetTimerOnMainThread(GMPTask* aTask, int64_t aTimeoutMS) {
|
||
|
|
return sPlatform->settimer(aTask, aTimeoutMS);
|
||
|
|
}
|
||
|
|
|
||
|
|
GMPErr GMPCreateRecord(const char* aRecordName,
|
||
|
|
uint32_t aRecordNameSize,
|
||
|
|
GMPRecord** aOutRecord,
|
||
|
|
GMPRecordClient* aClient)
|
||
|
|
{
|
||
|
|
return sPlatform->createrecord(aRecordName, aRecordNameSize, aOutRecord, aClient);
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
WidevineAdapter::SetAdaptee(PRLibrary* aLib)
|
||
|
|
{
|
||
|
|
mLib = aLib;
|
||
|
|
}
|
||
|
|
|
||
|
|
void* GetCdmHost(int aHostInterfaceVersion, void* aUserData)
|
||
|
|
{
|
||
|
|
Log("GetCdmHostFunc(%d, %p)", aHostInterfaceVersion, aUserData);
|
||
|
|
WidevineDecryptor* decryptor = reinterpret_cast<WidevineDecryptor*>(aUserData);
|
||
|
|
MOZ_ASSERT(decryptor);
|
||
|
|
return static_cast<cdm::Host_8*>(decryptor);
|
||
|
|
}
|
||
|
|
|
||
|
|
#define STRINGIFY(s) _STRINGIFY(s)
|
||
|
|
#define _STRINGIFY(s) #s
|
||
|
|
|
||
|
|
GMPErr
|
||
|
|
WidevineAdapter::GMPInit(const GMPPlatformAPI* aPlatformAPI)
|
||
|
|
{
|
||
|
|
#ifdef ENABLE_WIDEVINE_LOG
|
||
|
|
if (getenv("GMP_LOG_FILE")) {
|
||
|
|
// Clear log file.
|
||
|
|
FILE* f = fopen(getenv("GMP_LOG_FILE"), "w");
|
||
|
|
if (f) {
|
||
|
|
fclose(f);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
sPlatform = aPlatformAPI;
|
||
|
|
if (!mLib) {
|
||
|
|
return GMPGenericErr;
|
||
|
|
}
|
||
|
|
|
||
|
|
auto init = reinterpret_cast<decltype(::INITIALIZE_CDM_MODULE)*>(
|
||
|
|
PR_FindFunctionSymbol(mLib, STRINGIFY(INITIALIZE_CDM_MODULE)));
|
||
|
|
if (!init) {
|
||
|
|
return GMPGenericErr;
|
||
|
|
}
|
||
|
|
|
||
|
|
Log(STRINGIFY(INITIALIZE_CDM_MODULE)"()");
|
||
|
|
init();
|
||
|
|
|
||
|
|
return GMPNoErr;
|
||
|
|
}
|
||
|
|
|
||
|
|
GMPErr
|
||
|
|
WidevineAdapter::GMPGetAPI(const char* aAPIName,
|
||
|
|
void* aHostAPI,
|
||
|
|
void** aPluginAPI,
|
||
|
|
uint32_t aDecryptorId)
|
||
|
|
{
|
||
|
|
Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p",
|
||
|
|
aAPIName, aHostAPI, aPluginAPI, this, aDecryptorId);
|
||
|
|
if (!strcmp(aAPIName, GMP_API_DECRYPTOR)) {
|
||
|
|
if (WidevineDecryptor::GetInstance(aDecryptorId)) {
|
||
|
|
// We only support one CDM instance per PGMPDecryptor. Fail!
|
||
|
|
Log("WidevineAdapter::GMPGetAPI() Tried to create more than once CDM per IPDL actor! FAIL!");
|
||
|
|
return GMPQuotaExceededErr;
|
||
|
|
}
|
||
|
|
auto create = reinterpret_cast<decltype(::CreateCdmInstance)*>(
|
||
|
|
PR_FindFunctionSymbol(mLib, "CreateCdmInstance"));
|
||
|
|
if (!create) {
|
||
|
|
Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p FAILED to find CreateCdmInstance",
|
||
|
|
aAPIName, aHostAPI, aPluginAPI, this, aDecryptorId);
|
||
|
|
return GMPGenericErr;
|
||
|
|
}
|
||
|
|
|
||
|
|
WidevineDecryptor* decryptor = new WidevineDecryptor();
|
||
|
|
|
||
|
|
auto cdm = reinterpret_cast<cdm::ContentDecryptionModule*>(
|
||
|
|
create(cdm::ContentDecryptionModule::kVersion,
|
||
|
|
kEMEKeySystemWidevine.get(),
|
||
|
|
kEMEKeySystemWidevine.Length(),
|
||
|
|
&GetCdmHost,
|
||
|
|
decryptor));
|
||
|
|
if (!cdm) {
|
||
|
|
Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p FAILED to create cdm",
|
||
|
|
aAPIName, aHostAPI, aPluginAPI, this, aDecryptorId);
|
||
|
|
return GMPGenericErr;
|
||
|
|
}
|
||
|
|
Log("cdm: 0x%x", cdm);
|
||
|
|
RefPtr<CDMWrapper> wrapper(new CDMWrapper(cdm, decryptor));
|
||
|
|
decryptor->SetCDM(wrapper, aDecryptorId);
|
||
|
|
*aPluginAPI = decryptor;
|
||
|
|
|
||
|
|
} else if (!strcmp(aAPIName, GMP_API_VIDEO_DECODER)) {
|
||
|
|
RefPtr<CDMWrapper> wrapper = WidevineDecryptor::GetInstance(aDecryptorId);
|
||
|
|
if (!wrapper) {
|
||
|
|
Log("WidevineAdapter::GMPGetAPI(%s, 0x%p, 0x%p, %u) this=0x%p No cdm for video decoder",
|
||
|
|
aAPIName, aHostAPI, aPluginAPI, thiss, aDecryptorId);
|
||
|
|
return GMPGenericErr;
|
||
|
|
}
|
||
|
|
*aPluginAPI = new WidevineVideoDecoder(static_cast<GMPVideoHost*>(aHostAPI),
|
||
|
|
wrapper);
|
||
|
|
}
|
||
|
|
return *aPluginAPI ? GMPNoErr : GMPNotImplementedErr;
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
WidevineAdapter::GMPShutdown()
|
||
|
|
{
|
||
|
|
Log("WidevineAdapter::GMPShutdown()");
|
||
|
|
|
||
|
|
decltype(::DeinitializeCdmModule)* deinit;
|
||
|
|
deinit = (decltype(deinit))(PR_FindFunctionSymbol(mLib, "DeinitializeCdmModule"));
|
||
|
|
if (deinit) {
|
||
|
|
Log("DeinitializeCdmModule()");
|
||
|
|
deinit();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
WidevineAdapter::GMPSetNodeId(const char* aNodeId, uint32_t aLength)
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/* static */
|
||
|
|
bool
|
||
|
|
WidevineAdapter::Supports(int32_t aModuleVersion,
|
||
|
|
int32_t aInterfaceVersion,
|
||
|
|
int32_t aHostVersion)
|
||
|
|
{
|
||
|
|
return aModuleVersion == CDM_MODULE_VERSION &&
|
||
|
|
aInterfaceVersion == cdm::ContentDecryptionModule::kVersion &&
|
||
|
|
aHostVersion == cdm::Host_8::kVersion;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace mozilla
|