mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1271242 - Remove GMPDecryptorCallback::SetCapabilities(). r=jwwang
Now that GMPParent detects whether gmp-clearkey can decode using AAC/H.264 using WMF before reporting gmp-clearkey's GMPParent can decode AAC/H.264, we don't need the GMPDecryptorCallback::SetCapabilities() callback from the GMP to signal to the PDMFactory that the GMP can decode. We can now trust what the GMPService tells us. So we can remove the "waiting for CDM caps" step in the state machine's startup sequence. And all the plumbing. :) If we need more caps, like for an decode-and-render path, we can declare those as API strings in the info file. MozReview-Commit-ID: E0QhU4cYhjo --HG-- extra : rebase_source : 7d15ab6a45bac88c15c053f416d941b5fe0807b0
This commit is contained in:
parent
eb7204d3b6
commit
46a1552995
@ -1657,19 +1657,7 @@ MediaDecoder::SetCDMProxy(CDMProxy* aProxy)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<CDMProxy> proxy = aProxy;
|
||||
{
|
||||
CDMCaps::AutoLock caps(aProxy->Capabilites());
|
||||
if (!caps.AreCapsKnown()) {
|
||||
RefPtr<MediaDecoder> self = this;
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
|
||||
self->mCDMProxyPromiseHolder.ResolveIfExists(proxy, __func__);
|
||||
});
|
||||
caps.CallOnMainThreadWhenCapsAvailable(r);
|
||||
return;
|
||||
}
|
||||
}
|
||||
mCDMProxyPromiseHolder.ResolveIfExists(proxy, __func__);
|
||||
mCDMProxyPromiseHolder.ResolveIfExists(aProxy, __func__);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -302,15 +302,6 @@ CDMCallbackProxy::KeyStatusChanged(const nsCString& aSessionId,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CDMCallbackProxy::SetCaps(uint64_t aCaps)
|
||||
{
|
||||
MOZ_ASSERT(mProxy->IsOnGMPThread());
|
||||
|
||||
CDMCaps::AutoLock caps(mProxy->Capabilites());
|
||||
caps.SetCaps(aCaps);
|
||||
}
|
||||
|
||||
void
|
||||
CDMCallbackProxy::Decrypted(uint32_t aId,
|
||||
GMPErr aResult,
|
||||
|
@ -47,8 +47,6 @@ public:
|
||||
const nsTArray<uint8_t>& aKeyId,
|
||||
GMPMediaKeyStatus aStatus) override;
|
||||
|
||||
void SetCaps(uint64_t aCaps) override;
|
||||
|
||||
void Decrypted(uint32_t aId,
|
||||
GMPErr aResult,
|
||||
const nsTArray<uint8_t>& aDecryptedData) override;
|
||||
|
@ -13,7 +13,6 @@ namespace mozilla {
|
||||
|
||||
CDMCaps::CDMCaps()
|
||||
: mMonitor("CDMCaps")
|
||||
, mCaps(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -33,13 +32,6 @@ CDMCaps::Unlock()
|
||||
mMonitor.Unlock();
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::HasCap(uint64_t aCap)
|
||||
{
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
return (mCaps & aCap) == aCap;
|
||||
}
|
||||
|
||||
CDMCaps::AutoLock::AutoLock(CDMCaps& aInstance)
|
||||
: mData(aInstance)
|
||||
{
|
||||
@ -51,56 +43,6 @@ CDMCaps::AutoLock::~AutoLock()
|
||||
mData.Unlock();
|
||||
}
|
||||
|
||||
static void
|
||||
TestCap(uint64_t aFlag,
|
||||
uint64_t aCaps,
|
||||
const nsACString& aCapName,
|
||||
nsACString& aCapStr)
|
||||
{
|
||||
if (!(aFlag & aCaps)) {
|
||||
return;
|
||||
}
|
||||
if (!aCapStr.IsEmpty()) {
|
||||
aCapStr.AppendLiteral(",");
|
||||
}
|
||||
aCapStr.Append(aCapName);
|
||||
}
|
||||
|
||||
nsCString
|
||||
CapsToString(uint64_t aCaps)
|
||||
{
|
||||
nsCString capsStr;
|
||||
TestCap(GMP_EME_CAP_DECRYPT_AUDIO, aCaps, NS_LITERAL_CSTRING("DecryptAudio"), capsStr);
|
||||
TestCap(GMP_EME_CAP_DECRYPT_VIDEO, aCaps, NS_LITERAL_CSTRING("DecryptVideo"), capsStr);
|
||||
TestCap(GMP_EME_CAP_DECRYPT_AND_DECODE_AUDIO, aCaps, NS_LITERAL_CSTRING("DecryptAndDecodeAudio"), capsStr);
|
||||
TestCap(GMP_EME_CAP_DECRYPT_AND_DECODE_VIDEO, aCaps, NS_LITERAL_CSTRING("DecryptAndDecodeVideo"), capsStr);
|
||||
return capsStr;
|
||||
}
|
||||
|
||||
void
|
||||
CDMCaps::AutoLock::SetCaps(uint64_t aCaps)
|
||||
{
|
||||
EME_LOG("SetCaps() %s", CapsToString(aCaps).get());
|
||||
mData.mMonitor.AssertCurrentThreadOwns();
|
||||
mData.mCaps = aCaps;
|
||||
for (size_t i = 0; i < mData.mWaitForCaps.Length(); i++) {
|
||||
NS_DispatchToMainThread(mData.mWaitForCaps[i], NS_DISPATCH_NORMAL);
|
||||
}
|
||||
mData.mWaitForCaps.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
CDMCaps::AutoLock::CallOnMainThreadWhenCapsAvailable(nsIRunnable* aContinuation)
|
||||
{
|
||||
mData.mMonitor.AssertCurrentThreadOwns();
|
||||
if (mData.mCaps) {
|
||||
NS_DispatchToMainThread(aContinuation, NS_DISPATCH_NORMAL);
|
||||
MOZ_ASSERT(mData.mWaitForCaps.IsEmpty());
|
||||
} else {
|
||||
mData.mWaitForCaps.AppendElement(aContinuation);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId)
|
||||
{
|
||||
@ -177,49 +119,6 @@ CDMCaps::AutoLock::NotifyWhenKeyIdUsable(const CencKeyId& aKey,
|
||||
mData.mWaitForKeys.AppendElement(WaitForKeys(aKey, aListener));
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::AutoLock::AreCapsKnown()
|
||||
{
|
||||
mData.mMonitor.AssertCurrentThreadOwns();
|
||||
return mData.mCaps != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::AutoLock::CanRenderAudio()
|
||||
{
|
||||
return mData.HasCap(GMP_EME_CAP_RENDER_AUDIO);
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::AutoLock::CanRenderVideo()
|
||||
{
|
||||
return mData.HasCap(GMP_EME_CAP_RENDER_VIDEO);
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::AutoLock::CanDecryptAndDecodeAudio()
|
||||
{
|
||||
return mData.HasCap(GMP_EME_CAP_DECRYPT_AND_DECODE_AUDIO);
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::AutoLock::CanDecryptAndDecodeVideo()
|
||||
{
|
||||
return mData.HasCap(GMP_EME_CAP_DECRYPT_AND_DECODE_VIDEO);
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::AutoLock::CanDecryptAudio()
|
||||
{
|
||||
return mData.HasCap(GMP_EME_CAP_DECRYPT_AUDIO);
|
||||
}
|
||||
|
||||
bool
|
||||
CDMCaps::AutoLock::CanDecryptVideo()
|
||||
{
|
||||
return mData.HasCap(GMP_EME_CAP_DECRYPT_VIDEO);
|
||||
}
|
||||
|
||||
void
|
||||
CDMCaps::AutoLock::GetKeyStatusesForSession(const nsAString& aSessionId,
|
||||
nsTArray<KeyStatus>& aOutKeyStatuses)
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// CDM capabilities; what keys a CDMProxy can use, and whether it can decrypt, or
|
||||
// decrypt-and-decode on a per stream basis. Must be locked to access state.
|
||||
// CDM capabilities; what keys a CDMProxy can use.
|
||||
// Must be locked to access state.
|
||||
class CDMCaps {
|
||||
public:
|
||||
CDMCaps();
|
||||
@ -55,10 +55,6 @@ public:
|
||||
explicit AutoLock(CDMCaps& aKeyCaps);
|
||||
~AutoLock();
|
||||
|
||||
// Returns true if the capabilities of the CDM are known, i.e. they have
|
||||
// been reported by the CDM to Gecko.
|
||||
bool AreCapsKnown();
|
||||
|
||||
bool IsKeyUsable(const CencKeyId& aKeyId);
|
||||
|
||||
// Returns true if key status changed,
|
||||
@ -75,21 +71,6 @@ public:
|
||||
// Returns true if a key status was changed.
|
||||
bool RemoveKeysForSession(const nsString& aSessionId);
|
||||
|
||||
// Sets the capabilities of the CDM. aCaps is the logical OR of the
|
||||
// GMP_EME_CAP_* flags from gmp-decryption.h.
|
||||
void SetCaps(uint64_t aCaps);
|
||||
|
||||
bool CanRenderAudio();
|
||||
bool CanRenderVideo();
|
||||
|
||||
bool CanDecryptAndDecodeAudio();
|
||||
bool CanDecryptAndDecodeVideo();
|
||||
|
||||
bool CanDecryptAudio();
|
||||
bool CanDecryptVideo();
|
||||
|
||||
void CallOnMainThreadWhenCapsAvailable(nsIRunnable* aContinuation);
|
||||
|
||||
// Notifies the SamplesWaitingForKey when key become usable.
|
||||
void NotifyWhenKeyIdUsable(const CencKeyId& aKey,
|
||||
SamplesWaitingForKey* aSamplesWaiting);
|
||||
@ -101,7 +82,6 @@ public:
|
||||
private:
|
||||
void Lock();
|
||||
void Unlock();
|
||||
bool HasCap(uint64_t);
|
||||
|
||||
struct WaitForKeys {
|
||||
WaitForKeys(const CencKeyId& aKeyId,
|
||||
@ -119,9 +99,6 @@ private:
|
||||
|
||||
nsTArray<WaitForKeys> mWaitForKeys;
|
||||
|
||||
nsTArray<nsCOMPtr<nsIRunnable>> mWaitForCaps;
|
||||
uint64_t mCaps;
|
||||
|
||||
// It is not safe to copy this object.
|
||||
CDMCaps(const CDMCaps&) = delete;
|
||||
CDMCaps& operator=(const CDMCaps&) = delete;
|
||||
|
@ -193,7 +193,7 @@ GMPDecryptorChild::Decrypted(GMPBuffer* aBuffer, GMPErr aResult)
|
||||
void
|
||||
GMPDecryptorChild::SetCapabilities(uint64_t aCaps)
|
||||
{
|
||||
CALL_ON_GMP_THREAD(SendSetCaps, aCaps);
|
||||
// Deprecated.
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -343,19 +343,6 @@ GMPDecryptorParent::RecvKeyStatusChanged(const nsCString& aSessionId,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvSetCaps(const uint64_t& aCaps)
|
||||
{
|
||||
LOGD(("GMPDecryptorParent[%p]::RecvSetCaps(caps=0x%llx)", this, aCaps));
|
||||
|
||||
if (!mIsOpen) {
|
||||
NS_WARNING("Trying to use a dead GMP decrypter!");
|
||||
return false;
|
||||
}
|
||||
mCallback->SetCaps(aCaps);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPDecryptorParent::RecvDecrypted(const uint32_t& aId,
|
||||
const GMPErr& aErr,
|
||||
|
@ -102,8 +102,6 @@ private:
|
||||
const GMPErr& aErr,
|
||||
InfallibleTArray<uint8_t>&& aBuffer) override;
|
||||
|
||||
bool RecvSetCaps(const uint64_t& aCaps) override;
|
||||
|
||||
bool RecvShutdown() override;
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
@ -48,8 +48,6 @@ public:
|
||||
const nsTArray<uint8_t>& aKeyId,
|
||||
GMPMediaKeyStatus aStatus) = 0;
|
||||
|
||||
virtual void SetCaps(uint64_t aCaps) = 0;
|
||||
|
||||
virtual void Decrypted(uint32_t aId,
|
||||
GMPErr aResult,
|
||||
const nsTArray<uint8_t>& aDecryptedData) = 0;
|
||||
|
@ -81,8 +81,6 @@ parent:
|
||||
async KeyStatusChanged(nsCString aSessionId, uint8_t[] aKey,
|
||||
GMPMediaKeyStatus aStatus);
|
||||
|
||||
async SetCaps(uint64_t aCaps);
|
||||
|
||||
async Decrypted(uint32_t aId, GMPErr aResult, uint8_t[] aBuffer);
|
||||
|
||||
async Shutdown();
|
||||
|
@ -105,32 +105,6 @@ enum GMPMediaKeyStatus {
|
||||
// Time in milliseconds, as offset from epoch, 1 Jan 1970.
|
||||
typedef int64_t GMPTimestamp;
|
||||
|
||||
// Capability definitions. The capabilities of the EME GMP are reported
|
||||
// to Gecko by calling the GMPDecryptorCallback::SetCapabilities()
|
||||
// callback and specifying the logical OR of the GMP_EME_CAP_* flags below.
|
||||
//
|
||||
// Note the DECRYPT and the DECRYPT_AND_DECODE are mutually exclusive;
|
||||
// only one mode should be reported for each stream type, but different
|
||||
// modes can be reported for different stream types.
|
||||
//
|
||||
// Note: Gecko does not currently support the caps changing at runtime.
|
||||
// Set them once per plugin initialization, during the startup of
|
||||
// the GMPDecryptor.
|
||||
|
||||
// Capability; CDM can decrypt encrypted buffers and return still
|
||||
// compressed buffers back to Gecko for decompression there.
|
||||
#define GMP_EME_CAP_DECRYPT_AUDIO (uint64_t(1) << 0)
|
||||
#define GMP_EME_CAP_DECRYPT_VIDEO (uint64_t(1) << 1)
|
||||
|
||||
// Capability; CDM can decrypt and then decode encrypted buffers,
|
||||
// and return decompressed samples to Gecko for playback.
|
||||
#define GMP_EME_CAP_DECRYPT_AND_DECODE_AUDIO (uint64_t(1) << 2)
|
||||
#define GMP_EME_CAP_DECRYPT_AND_DECODE_VIDEO (uint64_t(1) << 3)
|
||||
|
||||
// Capability; CDM can decrypt and then decode and render encrypted buffers
|
||||
#define GMP_EME_CAP_RENDER_AUDIO (uint64_t(1) << 4)
|
||||
#define GMP_EME_CAP_RENDER_VIDEO (uint64_t(1) << 5)
|
||||
|
||||
// Callbacks to be called from the CDM. Threadsafe.
|
||||
class GMPDecryptorCallback {
|
||||
public:
|
||||
@ -212,12 +186,7 @@ public:
|
||||
uint32_t aKeyIdLength,
|
||||
GMPMediaKeyStatus aStatus) = 0;
|
||||
|
||||
// The CDM must report its capabilites of this CDM. aCaps should be a
|
||||
// logical OR of the GMP_EME_CAP_* flags. The CDM *MUST* call this
|
||||
// function and report whether it can decrypt and/or decode. Without
|
||||
// this, Gecko does not know how to use the CDM and will not send
|
||||
// samples to the CDM to decrypt or decrypt-and-decode mode. Note a
|
||||
// CDM cannot change modes once playback has begun.
|
||||
// DEPRECATED; this function has no affect.
|
||||
virtual void SetCapabilities(uint64_t aCaps) = 0;
|
||||
|
||||
// Returns decrypted buffer to Gecko, or reports failure.
|
||||
@ -258,13 +227,6 @@ public:
|
||||
|
||||
// Sets the callback to use with the decryptor to return results
|
||||
// to Gecko.
|
||||
//
|
||||
// The CDM must also call GMPDecryptorCallback::SetCapabilities()
|
||||
// exactly once during start up, to inform Gecko whether to use the CDM
|
||||
// in decrypt or decrypt-and-decode mode.
|
||||
//
|
||||
// Note: GMPDecryptorCallback::SetCapabilities() must be called before
|
||||
// Gecko will send any samples for decryption to the GMP.
|
||||
virtual void Init(GMPDecryptorCallback* aCallback) = 0;
|
||||
|
||||
// Initiates the creation of a session given |aType| and |aInitData|, and
|
||||
|
@ -39,8 +39,6 @@ WidevineDecryptor::Init(GMPDecryptorCallback* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(aCallback);
|
||||
mCallback = aCallback;
|
||||
mCallback->SetCapabilities(GMP_EME_CAP_DECRYPT_AND_DECODE_VIDEO |
|
||||
GMP_EME_CAP_DECRYPT_AUDIO);
|
||||
}
|
||||
|
||||
static SessionType
|
||||
|
@ -1349,7 +1349,6 @@ class GMPStorageTest : public GMPDecryptorProxyCallback
|
||||
void KeyStatusChanged(const nsCString& aSessionId,
|
||||
const nsTArray<uint8_t>& aKeyId,
|
||||
GMPMediaKeyStatus aStatus) override { }
|
||||
void SetCaps(uint64_t aCaps) override {}
|
||||
void Decrypted(uint32_t aId,
|
||||
GMPErr aResult,
|
||||
const nsTArray<uint8_t>& aDecryptedData) override { }
|
||||
|
@ -385,16 +385,8 @@ PDMFactory::GetDecoder(const nsACString& aMimeType,
|
||||
void
|
||||
PDMFactory::SetCDMProxy(CDMProxy* aProxy)
|
||||
{
|
||||
bool cdmDecodesAudio;
|
||||
bool cdmDecodesVideo;
|
||||
{
|
||||
CDMCaps::AutoLock caps(aProxy->Capabilites());
|
||||
cdmDecodesAudio = caps.CanDecryptAndDecodeAudio();
|
||||
cdmDecodesVideo = caps.CanDecryptAndDecodeVideo();
|
||||
}
|
||||
|
||||
RefPtr<PDMFactory> m = new PDMFactory();
|
||||
mEMEPDM = new EMEDecoderModule(aProxy, m, cdmDecodesAudio, cdmDecodesVideo);
|
||||
mEMEPDM = new EMEDecoderModule(aProxy, m);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -205,14 +205,9 @@ EMEMediaDataDecoderProxy::Shutdown()
|
||||
return rv;
|
||||
}
|
||||
|
||||
EMEDecoderModule::EMEDecoderModule(CDMProxy* aProxy,
|
||||
PDMFactory* aPDM,
|
||||
bool aCDMDecodesAudio,
|
||||
bool aCDMDecodesVideo)
|
||||
EMEDecoderModule::EMEDecoderModule(CDMProxy* aProxy, PDMFactory* aPDM)
|
||||
: mProxy(aProxy)
|
||||
, mPDM(aPDM)
|
||||
, mCDMDecodesAudio(aCDMDecodesAudio)
|
||||
, mCDMDecodesVideo(aCDMDecodesVideo)
|
||||
{
|
||||
}
|
||||
|
||||
@ -246,7 +241,8 @@ EMEDecoderModule::CreateVideoDecoder(const VideoInfo& aConfig,
|
||||
{
|
||||
MOZ_ASSERT(aConfig.mCrypto.mValid);
|
||||
|
||||
if (mCDMDecodesVideo) {
|
||||
if (SupportsMimeType(aConfig.mMimeType, nullptr)) {
|
||||
// GMP decodes. Assume that means it can decrypt too.
|
||||
RefPtr<MediaDataDecoderProxy> wrapper = CreateDecoderWrapper(aCallback, mProxy, aVideoTaskQueue);
|
||||
wrapper->SetProxyTarget(new EMEVideoDecoder(mProxy,
|
||||
aConfig,
|
||||
@ -284,7 +280,8 @@ EMEDecoderModule::CreateAudioDecoder(const AudioInfo& aConfig,
|
||||
{
|
||||
MOZ_ASSERT(aConfig.mCrypto.mValid);
|
||||
|
||||
if (mCDMDecodesAudio) {
|
||||
if (SupportsMimeType(aConfig.mMimeType, nullptr)) {
|
||||
// GMP decodes. Assume that means it can decrypt too.
|
||||
RefPtr<MediaDataDecoderProxy> wrapper = CreateDecoderWrapper(aCallback, mProxy, aAudioTaskQueue);
|
||||
wrapper->SetProxyTarget(new EMEAudioDecoder(mProxy,
|
||||
aConfig,
|
||||
|
@ -19,10 +19,7 @@ class EMEDecoderModule : public PlatformDecoderModule {
|
||||
private:
|
||||
|
||||
public:
|
||||
EMEDecoderModule(CDMProxy* aProxy,
|
||||
PDMFactory* aPDM,
|
||||
bool aCDMDecodesAudio,
|
||||
bool aCDMDecodesVideo);
|
||||
EMEDecoderModule(CDMProxy* aProxy, PDMFactory* aPDM);
|
||||
|
||||
virtual ~EMEDecoderModule();
|
||||
|
||||
@ -56,8 +53,6 @@ private:
|
||||
RefPtr<PDMFactory> mPDM;
|
||||
// We run the PDM on its own task queue.
|
||||
RefPtr<TaskQueue> mTaskQueue;
|
||||
bool mCDMDecodesAudio;
|
||||
bool mCDMDecodesVideo;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -24,11 +24,6 @@
|
||||
#include "ClearKeyStorage.h"
|
||||
#include "ClearKeyPersistence.h"
|
||||
#include "gmp-task-utils.h"
|
||||
#if defined(ENABLE_WMF)
|
||||
#include "WMFUtils.h"
|
||||
#include <versionhelpers.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
using namespace std;
|
||||
@ -50,28 +45,11 @@ ClearKeySessionManager::~ClearKeySessionManager()
|
||||
CK_LOGD("ClearKeySessionManager dtor %p", this);
|
||||
}
|
||||
|
||||
static bool
|
||||
CanDecode()
|
||||
{
|
||||
return
|
||||
#if defined(ENABLE_WMF)
|
||||
wmf::EnsureLibs() ||
|
||||
#endif
|
||||
false;
|
||||
}
|
||||
|
||||
void
|
||||
ClearKeySessionManager::Init(GMPDecryptorCallback* aCallback)
|
||||
{
|
||||
CK_LOGD("ClearKeySessionManager::Init");
|
||||
mCallback = aCallback;
|
||||
if (!CanDecode()) {
|
||||
mCallback->SetCapabilities(GMP_EME_CAP_DECRYPT_AUDIO |
|
||||
GMP_EME_CAP_DECRYPT_VIDEO);
|
||||
} else {
|
||||
mCallback->SetCapabilities(GMP_EME_CAP_DECRYPT_AND_DECODE_AUDIO |
|
||||
GMP_EME_CAP_DECRYPT_AND_DECODE_VIDEO);
|
||||
}
|
||||
ClearKeyPersistence::EnsureInitialized();
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ GMPGetAPI(const char* aApiName, void* aHostAPI, void** aPluginAPI)
|
||||
}
|
||||
#if defined(ENABLE_WMF)
|
||||
else if (!strcmp(aApiName, GMP_API_AUDIO_DECODER) &&
|
||||
wmf::EnsureLibs()) {
|
||||
wmf::EnsureLibs()) {
|
||||
*aPluginAPI = new AudioDecoder(static_cast<GMPAudioHost*>(aHostAPI));
|
||||
} else if (!strcmp(aApiName, GMP_API_VIDEO_DECODER) &&
|
||||
wmf::EnsureLibs()) {
|
||||
|
Loading…
Reference in New Issue
Block a user