diff options
author | Matt A. Tobin <email@mattatobin.com> | 2022-04-20 23:59:42 -0500 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2022-04-20 23:59:42 -0500 |
commit | d7e3c6e0f54c33a52a936efb7af0a6e7edae89bb (patch) | |
tree | a9ffdb811a2db2e06d3bf087c0e41716738cb2bf /dom | |
parent | df1c87d8a7cb7ad0efaec527dc370e63b654b6db (diff) | |
download | aura-central-d7e3c6e0f54c33a52a936efb7af0a6e7edae89bb.tar.gz |
Issue #25 - Part 5: Remove WidevineAdaptor from GMP
Diffstat (limited to 'dom')
21 files changed, 0 insertions, 4667 deletions
diff --git a/dom/media/gmp/GMPCDMCallbackProxy.cpp b/dom/media/gmp/GMPCDMCallbackProxy.cpp deleted file mode 100644 index a0b490849..000000000 --- a/dom/media/gmp/GMPCDMCallbackProxy.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; 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 "GMPCDMCallbackProxy.h" -#include "mozilla/CDMProxy.h" -#include "nsString.h" -#include "mozilla/dom/MediaKeys.h" -#include "mozilla/dom/MediaKeySession.h" -#include "mozIGeckoMediaPluginService.h" -#include "nsContentCID.h" -#include "nsServiceManagerUtils.h" -#include "MainThreadUtils.h" -#include "mozilla/EMEUtils.h" - -namespace mozilla { - -GMPCDMCallbackProxy::GMPCDMCallbackProxy(CDMProxy* aProxy) - : mProxy(aProxy) -{} - -void -GMPCDMCallbackProxy::SetDecryptorId(uint32_t aId) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - RefPtr<CDMProxy> proxy = mProxy; - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, aId] () - { - proxy->OnSetDecryptorId(aId); - }) - );} - -void -GMPCDMCallbackProxy::SetSessionId(uint32_t aToken, - const nsCString& aSessionId) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - RefPtr<CDMProxy> proxy = mProxy; - auto sid = NS_ConvertUTF8toUTF16(aSessionId); - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, - aToken, - sid] () - { - proxy->OnSetSessionId(aToken, sid); - }) - ); -} - -void -GMPCDMCallbackProxy::ResolveLoadSessionPromise(uint32_t aPromiseId, - bool aSuccess) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - RefPtr<CDMProxy> proxy = mProxy; - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, aPromiseId, aSuccess] () - { - proxy->OnResolveLoadSessionPromise(aPromiseId, aSuccess); - }) - ); -} - -void -GMPCDMCallbackProxy::ResolvePromise(uint32_t aPromiseId) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - // Note: CDMProxy proxies this from non-main threads to main thread. - mProxy->ResolvePromise(aPromiseId); -} - -void -GMPCDMCallbackProxy::RejectPromise(uint32_t aPromiseId, - nsresult aException, - const nsCString& aMessage) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - RefPtr<CDMProxy> proxy = mProxy; - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, - aPromiseId, - aException, - aMessage] () - { - proxy->OnRejectPromise(aPromiseId, aException, aMessage); - }) - ); -} - -void -GMPCDMCallbackProxy::SessionMessage(const nsCString& aSessionId, - dom::MediaKeyMessageType aMessageType, - const nsTArray<uint8_t>& aMessage) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - RefPtr<CDMProxy> proxy = mProxy; - auto sid = NS_ConvertUTF8toUTF16(aSessionId); - nsTArray<uint8_t> msg(aMessage); - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, - sid, - aMessageType, - msg] () mutable - { - proxy->OnSessionMessage(sid, aMessageType, msg); - }) - ); -} - -void -GMPCDMCallbackProxy::ExpirationChange(const nsCString& aSessionId, - GMPTimestamp aExpiryTime) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - RefPtr<CDMProxy> proxy = mProxy; - auto sid = NS_ConvertUTF8toUTF16(aSessionId); - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, - sid, - aExpiryTime] () - { - proxy->OnExpirationChange(sid, aExpiryTime); - }) - ); -} - -void -GMPCDMCallbackProxy::SessionClosed(const nsCString& aSessionId) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - bool keyStatusesChange = false; - auto sid = NS_ConvertUTF8toUTF16(aSessionId); - { - CDMCaps::AutoLock caps(mProxy->Capabilites()); - keyStatusesChange = caps.RemoveKeysForSession(NS_ConvertUTF8toUTF16(aSessionId)); - } - if (keyStatusesChange) { - RefPtr<CDMProxy> proxy = mProxy; - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, sid] () - { - proxy->OnKeyStatusesChange(sid); - }) - ); - } - - RefPtr<CDMProxy> proxy = mProxy; - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, sid] () - { - proxy->OnSessionClosed(sid); - }) - ); -} - -void -GMPCDMCallbackProxy::SessionError(const nsCString& aSessionId, - nsresult aException, - uint32_t aSystemCode, - const nsCString& aMessage) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - RefPtr<CDMProxy> proxy = mProxy; - auto sid = NS_ConvertUTF8toUTF16(aSessionId); - auto msg = NS_ConvertUTF8toUTF16(aMessage); - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, - sid, - aException, - aSystemCode, - msg] () - { - proxy->OnSessionError(sid, - aException, - aSystemCode, - msg); - }) - ); -} - -void -GMPCDMCallbackProxy::BatchedKeyStatusChanged(const nsCString& aSessionId, - const nsTArray<CDMKeyInfo>& aKeyInfos) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - BatchedKeyStatusChangedInternal(aSessionId, aKeyInfos); -} - -void -GMPCDMCallbackProxy::BatchedKeyStatusChangedInternal(const nsCString& aSessionId, - const nsTArray<CDMKeyInfo>& aKeyInfos) -{ - bool keyStatusesChange = false; - { - CDMCaps::AutoLock caps(mProxy->Capabilites()); - for (size_t i = 0; i < aKeyInfos.Length(); i++) { - keyStatusesChange |= - caps.SetKeyStatus(aKeyInfos[i].mKeyId, - NS_ConvertUTF8toUTF16(aSessionId), - aKeyInfos[i].mStatus); - } - } - if (keyStatusesChange) { - RefPtr<CDMProxy> proxy = mProxy; - auto sid = NS_ConvertUTF8toUTF16(aSessionId); - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy, sid] () - { - proxy->OnKeyStatusesChange(sid); - }) - ); - } -} - -void -GMPCDMCallbackProxy::Decrypted(uint32_t aId, - DecryptStatus aResult, - const nsTArray<uint8_t>& aDecryptedData) -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - mProxy->OnDecrypted(aId, aResult, aDecryptedData); -} - -void -GMPCDMCallbackProxy::Terminated() -{ - MOZ_ASSERT(mProxy->IsOnOwnerThread()); - - RefPtr<CDMProxy> proxy = mProxy; - NS_DispatchToMainThread( - NS_NewRunnableFunction([proxy] () - { - proxy->Terminated(); - }) - ); -} - -} // namespace mozilla diff --git a/dom/media/gmp/GMPCDMCallbackProxy.h b/dom/media/gmp/GMPCDMCallbackProxy.h deleted file mode 100644 index d2cc80682..000000000 --- a/dom/media/gmp/GMPCDMCallbackProxy.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; 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/. */ - -#ifndef GMPCDMCallbackProxy_h_ -#define GMPCDMCallbackProxy_h_ - -#include "mozilla/CDMProxy.h" -#include "gmp-decryption.h" -#include "GMPDecryptorProxy.h" - -namespace mozilla { - -// Proxies call backs from the CDM on the GMP thread back to the MediaKeys -// object on the main thread. -class GMPCDMCallbackProxy : public GMPDecryptorProxyCallback { -public: - - void SetDecryptorId(uint32_t aId) override; - - void SetSessionId(uint32_t aCreateSessionToken, - const nsCString& aSessionId) override; - - void ResolveLoadSessionPromise(uint32_t aPromiseId, - bool aSuccess) override; - - void ResolvePromise(uint32_t aPromiseId) override; - - void RejectPromise(uint32_t aPromiseId, - nsresult aException, - const nsCString& aSessionId) override; - - void SessionMessage(const nsCString& aSessionId, - dom::MediaKeyMessageType aMessageType, - const nsTArray<uint8_t>& aMessage) override; - - void ExpirationChange(const nsCString& aSessionId, - UnixTime aExpiryTime) override; - - void SessionClosed(const nsCString& aSessionId) override; - - void SessionError(const nsCString& aSessionId, - nsresult aException, - uint32_t aSystemCode, - const nsCString& aMessage) override; - - void Decrypted(uint32_t aId, - DecryptStatus aResult, - const nsTArray<uint8_t>& aDecryptedData) override; - - void BatchedKeyStatusChanged(const nsCString& aSessionId, - const nsTArray<CDMKeyInfo>& aKeyInfos) override; - - void Terminated() override; - - ~GMPCDMCallbackProxy() {} - -private: - friend class GMPCDMProxy; - explicit GMPCDMCallbackProxy(CDMProxy* aProxy); - - void BatchedKeyStatusChangedInternal(const nsCString& aSessionId, - const nsTArray<CDMKeyInfo>& aKeyInfos); - // Warning: Weak ref. - CDMProxy* mProxy; -}; - -} // namespace mozilla - -#endif // GMPCDMCallbackProxy_h_ diff --git a/dom/media/gmp/GMPCDMProxy.cpp b/dom/media/gmp/GMPCDMProxy.cpp deleted file mode 100644 index 0f1958632..000000000 --- a/dom/media/gmp/GMPCDMProxy.cpp +++ /dev/null @@ -1,798 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; 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 "GMPCDMProxy.h" -#include "mozilla/EMEUtils.h" -#include "mozilla/PodOperations.h" - -#include "mozilla/dom/MediaKeys.h" -#include "mozilla/dom/MediaKeySession.h" - -#include "mozIGeckoMediaPluginService.h" -#include "nsContentCID.h" -#include "nsIConsoleService.h" -#include "nsPrintfCString.h" -#include "nsServiceManagerUtils.h" -#include "nsString.h" -#include "prenv.h" -#include "GMPCDMCallbackProxy.h" -#include "GMPService.h" -#include "MainThreadUtils.h" -#include "MediaData.h" - -namespace mozilla { - -GMPCDMProxy::GMPCDMProxy(dom::MediaKeys* aKeys, - const nsAString& aKeySystem, - GMPCrashHelper* aCrashHelper, - bool aDistinctiveIdentifierRequired, - bool aPersistentStateRequired) - : CDMProxy(aKeys, - aKeySystem, - aDistinctiveIdentifierRequired, - aPersistentStateRequired) - , mCrashHelper(aCrashHelper) - , mCDM(nullptr) - , mDecryptionJobCount(0) - , mShutdownCalled(false) - , mDecryptorId(0) - , mCreatePromiseId(0) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_COUNT_CTOR(GMPCDMProxy); -} - -GMPCDMProxy::~GMPCDMProxy() -{ - MOZ_COUNT_DTOR(GMPCDMProxy); -} - -void -GMPCDMProxy::Init(PromiseId aPromiseId, - const nsAString& aOrigin, - const nsAString& aTopLevelOrigin, - const nsAString& aGMPName, - bool aInPrivateBrowsing) -{ - MOZ_ASSERT(NS_IsMainThread()); - NS_ENSURE_TRUE_VOID(!mKeys.IsNull()); - - EME_LOG("GMPCDMProxy::Init (%s, %s) %s", - NS_ConvertUTF16toUTF8(aOrigin).get(), - NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(), - (aInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing")); - - nsCString pluginVersion; - if (!mOwnerThread) { - nsCOMPtr<mozIGeckoMediaPluginService> mps = - do_GetService("@mozilla.org/gecko-media-plugin-service;1"); - if (!mps) { - RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::Init")); - return; - } - mps->GetThread(getter_AddRefs(mOwnerThread)); - if (!mOwnerThread) { - RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Couldn't get GMP thread GMPCDMProxy::Init")); - return; - } - } - - if (aGMPName.IsEmpty()) { - RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - nsPrintfCString("Unknown GMP for keysystem '%s'", NS_ConvertUTF16toUTF8(mKeySystem).get())); - return; - } - - nsAutoPtr<InitData> data(new InitData()); - data->mPromiseId = aPromiseId; - data->mOrigin = aOrigin; - data->mTopLevelOrigin = aTopLevelOrigin; - data->mGMPName = aGMPName; - data->mInPrivateBrowsing = aInPrivateBrowsing; - data->mCrashHelper = mCrashHelper; - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<nsAutoPtr<InitData>>(this, - &GMPCDMProxy::gmp_Init, - Move(data))); - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); -} - -#ifdef DEBUG -bool -GMPCDMProxy::IsOnOwnerThread() -{ - return NS_GetCurrentThread() == mOwnerThread; -} -#endif - -void -GMPCDMProxy::gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData) -{ - EME_LOG("GMPCDMProxy::gmp_InitDone"); - if (mShutdownCalled) { - if (aCDM) { - aCDM->Close(); - } - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("GMPCDMProxy was shut down before init could complete")); - return; - } - if (!aCDM) { - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("GetGMPDecryptor failed to return a CDM")); - return; - } - - mCDM = aCDM; - mCallback = new GMPCDMCallbackProxy(this); - mCDM->Init(mCallback, - mDistinctiveIdentifierRequired, - mPersistentStateRequired); - - // Await the OnSetDecryptorId callback. - mCreatePromiseId = aData->mPromiseId; -} - -void GMPCDMProxy::OnSetDecryptorId(uint32_t aId) -{ - MOZ_ASSERT(mCreatePromiseId); - mDecryptorId = aId; - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<uint32_t>(this, - &GMPCDMProxy::OnCDMCreated, - mCreatePromiseId)); - NS_DispatchToMainThread(task); -} - -class gmp_InitDoneCallback : public GetGMPDecryptorCallback -{ -public: - gmp_InitDoneCallback(GMPCDMProxy* aGMPCDMProxy, - nsAutoPtr<GMPCDMProxy::InitData>&& aData) - : mGMPCDMProxy(aGMPCDMProxy), - mData(Move(aData)) - { - } - - void Done(GMPDecryptorProxy* aCDM) - { - mGMPCDMProxy->gmp_InitDone(aCDM, Move(mData)); - } - -private: - RefPtr<GMPCDMProxy> mGMPCDMProxy; - nsAutoPtr<GMPCDMProxy::InitData> mData; -}; - -class gmp_InitGetGMPDecryptorCallback : public GetNodeIdCallback -{ -public: - gmp_InitGetGMPDecryptorCallback(GMPCDMProxy* aGMPCDMProxy, - nsAutoPtr<GMPCDMProxy::InitData>&& aData) - : mGMPCDMProxy(aGMPCDMProxy), - mData(aData) - { - } - - void Done(nsresult aResult, const nsACString& aNodeId) - { - mGMPCDMProxy->gmp_InitGetGMPDecryptor(aResult, aNodeId, Move(mData)); - } - -private: - RefPtr<GMPCDMProxy> mGMPCDMProxy; - nsAutoPtr<GMPCDMProxy::InitData> mData; -}; - -void -GMPCDMProxy::gmp_Init(nsAutoPtr<InitData>&& aData) -{ - MOZ_ASSERT(IsOnOwnerThread()); - - nsCOMPtr<mozIGeckoMediaPluginService> mps = - do_GetService("@mozilla.org/gecko-media-plugin-service;1"); - if (!mps) { - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::gmp_Init")); - return; - } - - // Make a copy before we transfer ownership of aData to the - // gmp_InitGetGMPDecryptorCallback. - InitData data(*aData); - UniquePtr<GetNodeIdCallback> callback( - new gmp_InitGetGMPDecryptorCallback(this, Move(aData))); - nsresult rv = mps->GetNodeId(data.mOrigin, - data.mTopLevelOrigin, - data.mGMPName, - data.mInPrivateBrowsing, - Move(callback)); - if (NS_FAILED(rv)) { - RejectPromise(data.mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Call to GetNodeId() failed early")); - } -} - -void -GMPCDMProxy::gmp_InitGetGMPDecryptor(nsresult aResult, - const nsACString& aNodeId, - nsAutoPtr<InitData>&& aData) -{ - uint32_t promiseID = aData->mPromiseId; - if (NS_FAILED(aResult)) { - RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("GetNodeId() called back, but with a failure result")); - return; - } - - mNodeId = aNodeId; - MOZ_ASSERT(!GetNodeId().IsEmpty()); - - nsCOMPtr<mozIGeckoMediaPluginService> mps = - do_GetService("@mozilla.org/gecko-media-plugin-service;1"); - if (!mps) { - RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Couldn't get MediaPluginService in GMPCDMProxy::gmp_InitGetGMPDecryptor")); - return; - } - - EME_LOG("GMPCDMProxy::gmp_Init (%s, %s) %s NodeId=%s", - NS_ConvertUTF16toUTF8(aData->mOrigin).get(), - NS_ConvertUTF16toUTF8(aData->mTopLevelOrigin).get(), - (aData->mInPrivateBrowsing ? "PrivateBrowsing" : "NonPrivateBrowsing"), - GetNodeId().get()); - - nsTArray<nsCString> tags; - tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem)); - - // Note: must capture helper refptr here, before the Move() - // when we create the GetGMPDecryptorCallback below. - RefPtr<GMPCrashHelper> crashHelper = Move(aData->mCrashHelper); - UniquePtr<GetGMPDecryptorCallback> callback(new gmp_InitDoneCallback(this, - Move(aData))); - nsresult rv = mps->GetGMPDecryptor(crashHelper, - &tags, - GetNodeId(), - Move(callback)); - if (NS_FAILED(rv)) { - RejectPromise(promiseID, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Call to GetGMPDecryptor() failed early")); - } -} - -void -GMPCDMProxy::OnCDMCreated(uint32_t aPromiseId) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (mKeys.IsNull()) { - return; - } - MOZ_ASSERT(!GetNodeId().IsEmpty()); - if (mCDM) { - mKeys->OnCDMCreated(aPromiseId, GetNodeId(), mCDM->GetPluginId()); - } else { - // No CDM? Just reject the promise. - mKeys->RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Null CDM in OnCDMCreated()")); - } -} - -void -GMPCDMProxy::CreateSession(uint32_t aCreateSessionToken, - dom::MediaKeySessionType aSessionType, - PromiseId aPromiseId, - const nsAString& aInitDataType, - nsTArray<uint8_t>& aInitData) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mOwnerThread); - - nsAutoPtr<CreateSessionData> data(new CreateSessionData()); - data->mSessionType = aSessionType; - data->mCreateSessionToken = aCreateSessionToken; - data->mPromiseId = aPromiseId; - data->mInitDataType = NS_ConvertUTF16toUTF8(aInitDataType); - data->mInitData = Move(aInitData); - - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<nsAutoPtr<CreateSessionData>>(this, &GMPCDMProxy::gmp_CreateSession, data)); - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); -} - -GMPSessionType -ToGMPSessionType(dom::MediaKeySessionType aSessionType) { - switch (aSessionType) { - case dom::MediaKeySessionType::Temporary: return kGMPTemporySession; - case dom::MediaKeySessionType::Persistent_license: return kGMPPersistentSession; - default: return kGMPTemporySession; - }; -}; - -void -GMPCDMProxy::gmp_CreateSession(nsAutoPtr<CreateSessionData> aData) -{ - MOZ_ASSERT(IsOnOwnerThread()); - if (!mCDM) { - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Null CDM in gmp_CreateSession")); - return; - } - mCDM->CreateSession(aData->mCreateSessionToken, - aData->mPromiseId, - aData->mInitDataType, - aData->mInitData, - ToGMPSessionType(aData->mSessionType)); -} - -void -GMPCDMProxy::LoadSession(PromiseId aPromiseId, - const nsAString& aSessionId) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mOwnerThread); - - nsAutoPtr<SessionOpData> data(new SessionOpData()); - data->mPromiseId = aPromiseId; - data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId); - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_LoadSession, data)); - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); -} - -void -GMPCDMProxy::gmp_LoadSession(nsAutoPtr<SessionOpData> aData) -{ - MOZ_ASSERT(IsOnOwnerThread()); - - if (!mCDM) { - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Null CDM in gmp_LoadSession")); - return; - } - mCDM->LoadSession(aData->mPromiseId, aData->mSessionId); -} - -void -GMPCDMProxy::SetServerCertificate(PromiseId aPromiseId, - nsTArray<uint8_t>& aCert) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mOwnerThread); - - nsAutoPtr<SetServerCertificateData> data(new SetServerCertificateData()); - data->mPromiseId = aPromiseId; - data->mCert = Move(aCert); - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<nsAutoPtr<SetServerCertificateData>>(this, &GMPCDMProxy::gmp_SetServerCertificate, data)); - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); -} - -void -GMPCDMProxy::gmp_SetServerCertificate(nsAutoPtr<SetServerCertificateData> aData) -{ - MOZ_ASSERT(IsOnOwnerThread()); - if (!mCDM) { - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Null CDM in gmp_SetServerCertificate")); - return; - } - mCDM->SetServerCertificate(aData->mPromiseId, aData->mCert); -} - -void -GMPCDMProxy::UpdateSession(const nsAString& aSessionId, - PromiseId aPromiseId, - nsTArray<uint8_t>& aResponse) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(mOwnerThread); - NS_ENSURE_TRUE_VOID(!mKeys.IsNull()); - - nsAutoPtr<UpdateSessionData> data(new UpdateSessionData()); - data->mPromiseId = aPromiseId; - data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId); - data->mResponse = Move(aResponse); - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<nsAutoPtr<UpdateSessionData>>(this, &GMPCDMProxy::gmp_UpdateSession, data)); - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); -} - -void -GMPCDMProxy::gmp_UpdateSession(nsAutoPtr<UpdateSessionData> aData) -{ - MOZ_ASSERT(IsOnOwnerThread()); - if (!mCDM) { - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Null CDM in gmp_UpdateSession")); - return; - } - mCDM->UpdateSession(aData->mPromiseId, - aData->mSessionId, - aData->mResponse); -} - -void -GMPCDMProxy::CloseSession(const nsAString& aSessionId, - PromiseId aPromiseId) -{ - MOZ_ASSERT(NS_IsMainThread()); - NS_ENSURE_TRUE_VOID(!mKeys.IsNull()); - - nsAutoPtr<SessionOpData> data(new SessionOpData()); - data->mPromiseId = aPromiseId; - data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId); - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_CloseSession, data)); - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); -} - -void -GMPCDMProxy::gmp_CloseSession(nsAutoPtr<SessionOpData> aData) -{ - MOZ_ASSERT(IsOnOwnerThread()); - if (!mCDM) { - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Null CDM in gmp_CloseSession")); - return; - } - mCDM->CloseSession(aData->mPromiseId, aData->mSessionId); -} - -void -GMPCDMProxy::RemoveSession(const nsAString& aSessionId, - PromiseId aPromiseId) -{ - MOZ_ASSERT(NS_IsMainThread()); - NS_ENSURE_TRUE_VOID(!mKeys.IsNull()); - - nsAutoPtr<SessionOpData> data(new SessionOpData()); - data->mPromiseId = aPromiseId; - data->mSessionId = NS_ConvertUTF16toUTF8(aSessionId); - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<nsAutoPtr<SessionOpData>>(this, &GMPCDMProxy::gmp_RemoveSession, data)); - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); -} - -void -GMPCDMProxy::gmp_RemoveSession(nsAutoPtr<SessionOpData> aData) -{ - MOZ_ASSERT(IsOnOwnerThread()); - if (!mCDM) { - RejectPromise(aData->mPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, - NS_LITERAL_CSTRING("Null CDM in gmp_RemoveSession")); - return; - } - mCDM->RemoveSession(aData->mPromiseId, aData->mSessionId); -} - -void -GMPCDMProxy::Shutdown() -{ - MOZ_ASSERT(NS_IsMainThread()); - mKeys.Clear(); - // Note: This may end up being the last owning reference to the GMPCDMProxy. - nsCOMPtr<nsIRunnable> task(NewRunnableMethod(this, &GMPCDMProxy::gmp_Shutdown)); - if (mOwnerThread) { - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); - } -} - -void -GMPCDMProxy::gmp_Shutdown() -{ - MOZ_ASSERT(IsOnOwnerThread()); - - mShutdownCalled = true; - - // Abort any pending decrypt jobs, to awaken any clients waiting on a job. - for (size_t i = 0; i < mDecryptionJobs.Length(); i++) { - DecryptJob* job = mDecryptionJobs[i]; - job->PostResult(AbortedErr); - } - mDecryptionJobs.Clear(); - - if (mCDM) { - mCDM->Close(); - mCDM = nullptr; - } -} - -void -GMPCDMProxy::RejectPromise(PromiseId aId, nsresult aCode, - const nsCString& aReason) -{ - if (NS_IsMainThread()) { - if (!mKeys.IsNull()) { - mKeys->RejectPromise(aId, aCode, aReason); - } - } else { - nsCOMPtr<nsIRunnable> task(new RejectPromiseTask(this, aId, aCode, - aReason)); - NS_DispatchToMainThread(task); - } -} - -void -GMPCDMProxy::ResolvePromise(PromiseId aId) -{ - if (NS_IsMainThread()) { - if (!mKeys.IsNull()) { - mKeys->ResolvePromise(aId); - } else { - NS_WARNING("GMPCDMProxy unable to resolve promise!"); - } - } else { - nsCOMPtr<nsIRunnable> task; - task = NewRunnableMethod<PromiseId>(this, - &GMPCDMProxy::ResolvePromise, - aId); - NS_DispatchToMainThread(task); - } -} - -const nsCString& -GMPCDMProxy::GetNodeId() const -{ - return mNodeId; -} - -void -GMPCDMProxy::OnSetSessionId(uint32_t aCreateSessionToken, - const nsAString& aSessionId) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (mKeys.IsNull()) { - return; - } - - RefPtr<dom::MediaKeySession> session(mKeys->GetPendingSession(aCreateSessionToken)); - if (session) { - session->SetSessionId(aSessionId); - } -} - -void -GMPCDMProxy::OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (mKeys.IsNull()) { - return; - } - mKeys->OnSessionLoaded(aPromiseId, aSuccess); -} - -void -GMPCDMProxy::OnSessionMessage(const nsAString& aSessionId, - dom::MediaKeyMessageType aMessageType, - nsTArray<uint8_t>& aMessage) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (mKeys.IsNull()) { - return; - } - RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId)); - if (session) { - session->DispatchKeyMessage(aMessageType, aMessage); - } -} - -void -GMPCDMProxy::OnKeyStatusesChange(const nsAString& aSessionId) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (mKeys.IsNull()) { - return; - } - RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId)); - if (session) { - session->DispatchKeyStatusesChange(); - } -} - -void -GMPCDMProxy::OnExpirationChange(const nsAString& aSessionId, - GMPTimestamp aExpiryTime) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (mKeys.IsNull()) { - return; - } - RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId)); - if (session) { - session->SetExpiration(static_cast<double>(aExpiryTime)); - } -} - -void -GMPCDMProxy::OnSessionClosed(const nsAString& aSessionId) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (mKeys.IsNull()) { - return; - } - RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId)); - if (session) { - session->OnClosed(); - } -} - -void -GMPCDMProxy::OnDecrypted(uint32_t aId, - DecryptStatus aResult, - const nsTArray<uint8_t>& aDecryptedData) -{ - MOZ_ASSERT(IsOnOwnerThread()); - gmp_Decrypted(aId, aResult, aDecryptedData); -} - -static void -LogToConsole(const nsAString& aMsg) -{ - nsCOMPtr<nsIConsoleService> console( - do_GetService("@mozilla.org/consoleservice;1")); - if (!console) { - NS_WARNING("Failed to log message to console."); - return; - } - nsAutoString msg(aMsg); - console->LogStringMessage(msg.get()); -} - -void -GMPCDMProxy::OnSessionError(const nsAString& aSessionId, - nsresult aException, - uint32_t aSystemCode, - const nsAString& aMsg) -{ - MOZ_ASSERT(NS_IsMainThread()); - if (mKeys.IsNull()) { - return; - } - RefPtr<dom::MediaKeySession> session(mKeys->GetSession(aSessionId)); - if (session) { - session->DispatchKeyError(aSystemCode); - } - LogToConsole(aMsg); -} - -void -GMPCDMProxy::OnRejectPromise(uint32_t aPromiseId, - nsresult aDOMException, - const nsCString& aMsg) -{ - MOZ_ASSERT(NS_IsMainThread()); - RejectPromise(aPromiseId, aDOMException, aMsg); -} - -const nsString& -GMPCDMProxy::KeySystem() const -{ - return mKeySystem; -} - -CDMCaps& -GMPCDMProxy::Capabilites() { - return mCapabilites; -} - -RefPtr<GMPCDMProxy::DecryptPromise> -GMPCDMProxy::Decrypt(MediaRawData* aSample) -{ - RefPtr<DecryptJob> job(new DecryptJob(aSample)); - RefPtr<DecryptPromise> promise(job->Ensure()); - - nsCOMPtr<nsIRunnable> task( - NewRunnableMethod<RefPtr<DecryptJob>>(this, &GMPCDMProxy::gmp_Decrypt, job)); - mOwnerThread->Dispatch(task, NS_DISPATCH_NORMAL); - return promise; -} - -void -GMPCDMProxy::gmp_Decrypt(RefPtr<DecryptJob> aJob) -{ - MOZ_ASSERT(IsOnOwnerThread()); - - if (!mCDM) { - aJob->PostResult(AbortedErr); - return; - } - - aJob->mId = ++mDecryptionJobCount; - nsTArray<uint8_t> data; - data.AppendElements(aJob->mSample->Data(), aJob->mSample->Size()); - mCDM->Decrypt(aJob->mId, aJob->mSample->mCrypto, data); - mDecryptionJobs.AppendElement(aJob.forget()); -} - -void -GMPCDMProxy::gmp_Decrypted(uint32_t aId, - DecryptStatus aResult, - const nsTArray<uint8_t>& aDecryptedData) -{ - MOZ_ASSERT(IsOnOwnerThread()); -#ifdef DEBUG - bool jobIdFound = false; -#endif - for (size_t i = 0; i < mDecryptionJobs.Length(); i++) { - DecryptJob* job = mDecryptionJobs[i]; - if (job->mId == aId) { -#ifdef DEBUG - jobIdFound = true; -#endif - job->PostResult(aResult, aDecryptedData); - mDecryptionJobs.RemoveElementAt(i); - } - } -#ifdef DEBUG - if (!jobIdFound) { - NS_WARNING("GMPDecryptorChild returned incorrect job ID"); - } -#endif -} - -void -GMPCDMProxy::DecryptJob::PostResult(DecryptStatus aResult) -{ - nsTArray<uint8_t> empty; - PostResult(aResult, empty); -} - -void -GMPCDMProxy::DecryptJob::PostResult(DecryptStatus aResult, - const nsTArray<uint8_t>& aDecryptedData) -{ - if (aDecryptedData.Length() != mSample->Size()) { - NS_WARNING("CDM returned incorrect number of decrypted bytes"); - } - if (aResult == Ok) { - nsAutoPtr<MediaRawDataWriter> writer(mSample->CreateWriter()); - PodCopy(writer->Data(), - aDecryptedData.Elements(), - std::min<size_t>(aDecryptedData.Length(), mSample->Size())); - } else if (aResult == NoKeyErr) { - NS_WARNING("CDM returned NoKeyErr"); - // We still have the encrypted sample, so we can re-enqueue it to be - // decrypted again once the key is usable again. - } else { - nsAutoCString str("CDM returned decode failure DecryptStatus="); - str.AppendInt(aResult); - NS_WARNING(str.get()); - } - mPromise.Resolve(DecryptResult(aResult, mSample), __func__); -} - -void -GMPCDMProxy::GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId, - nsTArray<nsCString>& aSessionIds) -{ - CDMCaps::AutoLock caps(Capabilites()); - caps.GetSessionIdsForKeyId(aKeyId, aSessionIds); -} - -void -GMPCDMProxy::Terminated() -{ - MOZ_ASSERT(NS_IsMainThread()); - NS_WARNING("CDM terminated"); - if (mCreatePromiseId) { - RejectPromise(mCreatePromiseId, - NS_ERROR_DOM_MEDIA_FATAL_ERR, - NS_LITERAL_CSTRING("Crashed waiting for CDM to initialize")); - mCreatePromiseId = 0; - } - if (!mKeys.IsNull()) { - mKeys->Terminated(); - } -} - -uint32_t -GMPCDMProxy::GetDecryptorId() -{ - return mDecryptorId; -} - -} // namespace mozilla diff --git a/dom/media/gmp/GMPCDMProxy.h b/dom/media/gmp/GMPCDMProxy.h deleted file mode 100644 index a7fae235b..000000000 --- a/dom/media/gmp/GMPCDMProxy.h +++ /dev/null @@ -1,265 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; 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/. */ - -#ifndef GMPCDMProxy_h_ -#define GMPCDMProxy_h_ - -#include "mozilla/CDMProxy.h" -#include "GMPCDMCallbackProxy.h" -#include "GMPDecryptorProxy.h" - -namespace mozilla { -class MediaRawData; - -// Implementation of CDMProxy which is based on GMP architecture. -class GMPCDMProxy : public CDMProxy { -public: - - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPCDMProxy, override) - - typedef MozPromise<DecryptResult, DecryptResult, /* IsExclusive = */ true> DecryptPromise; - - GMPCDMProxy(dom::MediaKeys* aKeys, - const nsAString& aKeySystem, - GMPCrashHelper* aCrashHelper, - bool aDistinctiveIdentifierRequired, - bool aPersistentStateRequired); - - void Init(PromiseId aPromiseId, - const nsAString& aOrigin, - const nsAString& aTopLevelOrigin, - const nsAString& aGMPName, - bool aInPrivateBrowsing) override; - - void OnSetDecryptorId(uint32_t aId) override; - - void CreateSession(uint32_t aCreateSessionToken, - dom::MediaKeySessionType aSessionType, - PromiseId aPromiseId, - const nsAString& aInitDataType, - nsTArray<uint8_t>& aInitData) override; - - void LoadSession(PromiseId aPromiseId, - const nsAString& aSessionId) override; - - void SetServerCertificate(PromiseId aPromiseId, - nsTArray<uint8_t>& aCert) override; - - void UpdateSession(const nsAString& aSessionId, - PromiseId aPromiseId, - nsTArray<uint8_t>& aResponse) override; - - void CloseSession(const nsAString& aSessionId, - PromiseId aPromiseId) override; - - void RemoveSession(const nsAString& aSessionId, - PromiseId aPromiseId) override; - - void Shutdown() override; - - void Terminated() override; - - const nsCString& GetNodeId() const override; - - void OnSetSessionId(uint32_t aCreateSessionToken, - const nsAString& aSessionId) override; - - void OnResolveLoadSessionPromise(uint32_t aPromiseId, bool aSuccess) override; - - void OnSessionMessage(const nsAString& aSessionId, - dom::MediaKeyMessageType aMessageType, - nsTArray<uint8_t>& aMessage) override; - - void OnExpirationChange(const nsAString& aSessionId, - GMPTimestamp aExpiryTime) override; - - void OnSessionClosed(const nsAString& aSessionId) override; - - void OnSessionError(const nsAString& aSessionId, - nsresult aException, - uint32_t aSystemCode, - const nsAString& aMsg) override; - - void OnRejectPromise(uint32_t aPromiseId, - nsresult aDOMException, - const nsCString& aMsg) override; - - RefPtr<DecryptPromise> Decrypt(MediaRawData* aSample) override; - - void OnDecrypted(uint32_t aId, - DecryptStatus aResult, - const nsTArray<uint8_t>& aDecryptedData) override; - - void RejectPromise(PromiseId aId, nsresult aExceptionCode, - const nsCString& aReason) override; - - void ResolvePromise(PromiseId aId) override; - - const nsString& KeySystem() const override; - - CDMCaps& Capabilites() override; - - void OnKeyStatusesChange(const nsAString& aSessionId) override; - - void GetSessionIdsForKeyId(const nsTArray<uint8_t>& aKeyId, - nsTArray<nsCString>& aSessionIds) override; - -#ifdef DEBUG - bool IsOnOwnerThread() override; -#endif - - uint32_t GetDecryptorId() override; - -private: - friend class gmp_InitDoneCallback; - friend class gmp_InitGetGMPDecryptorCallback; - - struct InitData { - uint32_t mPromiseId; - nsString mOrigin; - nsString mTopLevelOrigin; - nsString mGMPName; - RefPtr<GMPCrashHelper> mCrashHelper; - bool mInPrivateBrowsing; - }; - - // GMP thread only. - void gmp_Init(nsAutoPtr<InitData>&& aData); - void gmp_InitDone(GMPDecryptorProxy* aCDM, nsAutoPtr<InitData>&& aData); - void gmp_InitGetGMPDecryptor(nsresult aResult, - const nsACString& aNodeId, - nsAutoPtr<InitData>&& aData); - - // GMP thread only. - void gmp_Shutdown(); - - // Main thread only. - void OnCDMCreated(uint32_t aPromiseId); - - struct CreateSessionData { - dom::MediaKeySessionType mSessionType; - uint32_t mCreateSessionToken; - PromiseId mPromiseId; - nsCString mInitDataType; - nsTArray<uint8_t> mInitData; - }; - // GMP thread only. - void gmp_CreateSession(nsAutoPtr<CreateSessionData> aData); - - struct SessionOpData { - PromiseId mPromiseId; - nsCString mSessionId; - }; - // GMP thread only. - void gmp_LoadSession(nsAutoPtr<SessionOpData> aData); - - struct SetServerCertificateData { - PromiseId mPromiseId; - nsTArray<uint8_t> mCert; - }; - // GMP thread only. - void gmp_SetServerCertificate(nsAutoPtr<SetServerCertificateData> aData); - - struct UpdateSessionData { - PromiseId mPromiseId; - nsCString mSessionId; - nsTArray<uint8_t> mResponse; - }; - // GMP thread only. - void gmp_UpdateSession(nsAutoPtr<UpdateSessionData> aData); - - // GMP thread only. - void gmp_CloseSession(nsAutoPtr<SessionOpData> aData); - - // GMP thread only. - void gmp_RemoveSession(nsAutoPtr<SessionOpData> aData); - - class DecryptJob { - public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecryptJob) - - explicit DecryptJob(MediaRawData* aSample) - : mId(0) - , mSample(aSample) - { - } - - void PostResult(DecryptStatus aResult, - const nsTArray<uint8_t>& aDecryptedData); - void PostResult(DecryptStatus aResult); - - RefPtr<DecryptPromise> Ensure() { - return mPromise.Ensure(__func__); - } - - uint32_t mId; - RefPtr<MediaRawData> mSample; - private: - ~DecryptJob() {} - MozPromiseHolder<DecryptPromise> mPromise; - }; - // GMP thread only. - void gmp_Decrypt(RefPtr<DecryptJob> aJob); - - // GMP thread only. - void gmp_Decrypted(uint32_t aId, - DecryptStatus aResult, - const nsTArray<uint8_t>& aDecryptedData); - - class RejectPromiseTask : public Runnable { - public: - RejectPromiseTask(GMPCDMProxy* aProxy, - PromiseId aId, - nsresult aCode, - const nsCString& aReason) - : mProxy(aProxy) - , mId(aId) - , mCode(aCode) - , mReason(aReason) - { - } - NS_IMETHOD Run() override { - mProxy->RejectPromise(mId, mCode, mReason); - return NS_OK; - } - private: - RefPtr<GMPCDMProxy> mProxy; - PromiseId mId; - nsresult mCode; - nsCString mReason; - }; - - ~GMPCDMProxy(); - - GMPCrashHelper* mCrashHelper; - - GMPDecryptorProxy* mCDM; - - nsAutoPtr<GMPCDMCallbackProxy> mCallback; - - // Decryption jobs sent to CDM, awaiting result. - // GMP thread only. - nsTArray<RefPtr<DecryptJob>> mDecryptionJobs; - - // Number of buffers we've decrypted. Used to uniquely identify - // decryption jobs sent to CDM. Note we can't just use the length of - // mDecryptionJobs as that shrinks as jobs are completed and removed - // from it. - // GMP thread only. - uint32_t mDecryptionJobCount; - - // True if GMPCDMProxy::gmp_Shutdown was called. - // GMP thread only. - bool mShutdownCalled; - - uint32_t mDecryptorId; - - PromiseId mCreatePromiseId; -}; - - -} // namespace mozilla - -#endif // GMPCDMProxy_h_ diff --git a/dom/media/gmp/moz.build b/dom/media/gmp/moz.build index 52dc673cd..3ff90b2c8 100644 --- a/dom/media/gmp/moz.build +++ b/dom/media/gmp/moz.build @@ -70,12 +70,6 @@ EXPORTS += [ 'GMPVideoPlaneImpl.h', ] -if CONFIG['MOZ_EME']: - EXPORTS += [ - 'GMPCDMCallbackProxy.h', - 'GMPCDMProxy.h', - ] - SOURCES += [ 'GMPAudioDecoderChild.cpp', 'GMPAudioDecoderParent.cpp', @@ -111,17 +105,8 @@ SOURCES += [ 'GMPVideoPlaneImpl.cpp', ] -if CONFIG['MOZ_EME']: - SOURCES += [ - 'GMPCDMCallbackProxy.cpp', - 'GMPCDMProxy.cpp', - ] - DIRS += ['rlz'] -if CONFIG['MOZ_EME']: - DIRS += ['widevine-adapter'] - IPDL_SOURCES += [ 'GMPTypes.ipdlh', 'PGMP.ipdl', diff --git a/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp b/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp deleted file mode 100644 index 57d4ecec2..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineAdapter.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- 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_9*>(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_9*>( - create(cdm::ContentDecryptionModule_9::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_9::kVersion && - aHostVersion == cdm::Host_9::kVersion; -} - -} // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineAdapter.h b/dom/media/gmp/widevine-adapter/WidevineAdapter.h deleted file mode 100644 index 714e041be..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineAdapter.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- 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/. */ - -#ifndef WidevineAdapter_h_ -#define WidevineAdapter_h_ - -#include "GMPLoader.h" -#include "prlink.h" -#include "GMPUtils.h" - -struct GMPPlatformAPI; - -namespace mozilla { - -class WidevineAdapter : public gmp::GMPAdapter { -public: - - void SetAdaptee(PRLibrary* aLib) override; - - // These are called in place of the corresponding GMP API functions. - GMPErr GMPInit(const GMPPlatformAPI* aPlatformAPI) override; - GMPErr GMPGetAPI(const char* aAPIName, - void* aHostAPI, - void** aPluginAPI, - uint32_t aDecryptorId) override; - void GMPShutdown() override; - void GMPSetNodeId(const char* aNodeId, uint32_t aLength) override; - - static bool Supports(int32_t aModuleVersion, - int32_t aInterfaceVersion, - int32_t aHostVersion); - -private: - PRLibrary* mLib = nullptr; -}; - -GMPErr GMPCreateThread(GMPThread** aThread); -GMPErr GMPRunOnMainThread(GMPTask* aTask); -GMPErr GMPCreateMutex(GMPMutex** aMutex); - -// Call on main thread only. -GMPErr GMPCreateRecord(const char* aRecordName, - uint32_t aRecordNameSize, - GMPRecord** aOutRecord, - GMPRecordClient* aClient); - -// Call on main thread only. -GMPErr GMPSetTimerOnMainThread(GMPTask* aTask, int64_t aTimeoutMS); - -GMPErr GMPGetCurrentTime(GMPTimestamp* aOutTime); - -GMPErr GMPCreateRecordIterator(RecvGMPRecordIteratorPtr aRecvIteratorFunc, - void* aUserArg); - -} // namespace mozilla - -#endif // WidevineAdapter_h_ diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp b/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp deleted file mode 100644 index 4d3408804..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.cpp +++ /dev/null @@ -1,554 +0,0 @@ -/* -*- 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 "WidevineDecryptor.h" - -#include "WidevineAdapter.h" -#include "WidevineUtils.h" -#include "WidevineFileIO.h" -#include <mozilla/SizePrintfMacros.h> -#include <stdarg.h> -#include "base/time.h" - -using namespace cdm; -using namespace std; - -namespace mozilla { - -static map<uint32_t, RefPtr<CDMWrapper>> sDecryptors; - -/* static */ -RefPtr<CDMWrapper> -WidevineDecryptor::GetInstance(uint32_t aInstanceId) -{ - auto itr = sDecryptors.find(aInstanceId); - if (itr != sDecryptors.end()) { - return itr->second; - } - return nullptr; -} - - -WidevineDecryptor::WidevineDecryptor() - : mCallback(nullptr) -{ - Log("WidevineDecryptor created this=%p", this); - AddRef(); // Released in DecryptingComplete(). -} - -WidevineDecryptor::~WidevineDecryptor() -{ - Log("WidevineDecryptor destroyed this=%p", this); -} - -void -WidevineDecryptor::SetCDM(RefPtr<CDMWrapper> aCDM, uint32_t aInstanceId) -{ - mCDM = aCDM; - mInstanceId = aInstanceId; - sDecryptors[mInstanceId] = aCDM; -} - -void -WidevineDecryptor::Init(GMPDecryptorCallback* aCallback, - bool aDistinctiveIdentifierRequired, - bool aPersistentStateRequired) -{ - Log("WidevineDecryptor::Init() this=%p distinctiveId=%d persistentState=%d", - this, aDistinctiveIdentifierRequired, aPersistentStateRequired); - MOZ_ASSERT(aCallback); - mCallback = aCallback; - MOZ_ASSERT(mCDM); - mDistinctiveIdentifierRequired = aDistinctiveIdentifierRequired; - mPersistentStateRequired = aPersistentStateRequired; - if (CDM()) { - CDM()->Initialize(aDistinctiveIdentifierRequired, - aPersistentStateRequired); - } -} - -static SessionType -ToCDMSessionType(GMPSessionType aSessionType) -{ - switch (aSessionType) { - case kGMPTemporySession: return kTemporary; - case kGMPPersistentSession: return kPersistentLicense; - case kGMPSessionInvalid: return kTemporary; - // TODO: kPersistentKeyRelease - } - MOZ_ASSERT(false); // Not supposed to get here. - return kTemporary; -} - -void -WidevineDecryptor::CreateSession(uint32_t aCreateSessionToken, - uint32_t aPromiseId, - const char* aInitDataType, - uint32_t aInitDataTypeSize, - const uint8_t* aInitData, - uint32_t aInitDataSize, - GMPSessionType aSessionType) -{ - Log("Decryptor::CreateSession(token=%d, pid=%d)", aCreateSessionToken, aPromiseId); - InitDataType initDataType; - if (!strcmp(aInitDataType, "cenc")) { - initDataType = kCenc; - } else if (!strcmp(aInitDataType, "webm")) { - initDataType = kWebM; - } else if (!strcmp(aInitDataType, "keyids")) { - initDataType = kKeyIds; - } else { - // Invalid init data type - const char* errorMsg = "Invalid init data type when creating session."; - OnRejectPromise(aPromiseId, kExceptionNotSupportedError, 0, errorMsg, sizeof(errorMsg)); - return; - } - mPromiseIdToNewSessionTokens[aPromiseId] = aCreateSessionToken; - CDM()->CreateSessionAndGenerateRequest(aPromiseId, - ToCDMSessionType(aSessionType), - initDataType, - aInitData, aInitDataSize); -} - -void -WidevineDecryptor::LoadSession(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdLength) -{ - Log("Decryptor::LoadSession(pid=%d, %s)", aPromiseId, aSessionId); - // TODO: session type?? - CDM()->LoadSession(aPromiseId, kPersistentLicense, aSessionId, aSessionIdLength); -} - -void -WidevineDecryptor::UpdateSession(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdLength, - const uint8_t* aResponse, - uint32_t aResponseSize) -{ - Log("Decryptor::UpdateSession(pid=%d, session=%s)", aPromiseId, aSessionId); - CDM()->UpdateSession(aPromiseId, aSessionId, aSessionIdLength, aResponse, aResponseSize); -} - -void -WidevineDecryptor::CloseSession(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdLength) -{ - Log("Decryptor::CloseSession(pid=%d, session=%s)", aPromiseId, aSessionId); - CDM()->CloseSession(aPromiseId, aSessionId, aSessionIdLength); -} - -void -WidevineDecryptor::RemoveSession(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdLength) -{ - Log("Decryptor::RemoveSession(%s)", aSessionId); - CDM()->RemoveSession(aPromiseId, aSessionId, aSessionIdLength); -} - -void -WidevineDecryptor::SetServerCertificate(uint32_t aPromiseId, - const uint8_t* aServerCert, - uint32_t aServerCertSize) -{ - Log("Decryptor::SetServerCertificate()"); - CDM()->SetServerCertificate(aPromiseId, aServerCert, aServerCertSize); -} - -class WidevineDecryptedBlock : public cdm::DecryptedBlock { -public: - - WidevineDecryptedBlock() - : mBuffer(nullptr) - , mTimestamp(0) - { - } - - ~WidevineDecryptedBlock() { - if (mBuffer) { - mBuffer->Destroy(); - mBuffer = nullptr; - } - } - - void SetDecryptedBuffer(cdm::Buffer* aBuffer) override { - mBuffer = aBuffer; - } - - cdm::Buffer* DecryptedBuffer() override { - return mBuffer; - } - - void SetTimestamp(int64_t aTimestamp) override { - mTimestamp = aTimestamp; - } - - int64_t Timestamp() const override { - return mTimestamp; - } - -private: - cdm::Buffer* mBuffer; - int64_t mTimestamp; -}; - -void -WidevineDecryptor::Decrypt(GMPBuffer* aBuffer, - GMPEncryptedBufferMetadata* aMetadata) -{ - if (!mCallback) { - Log("WidevineDecryptor::Decrypt() this=%p FAIL; !mCallback", this); - return; - } - const GMPEncryptedBufferMetadata* crypto = aMetadata; - InputBuffer sample; - nsTArray<SubsampleEntry> subsamples; - InitInputBuffer(crypto, aBuffer->Id(), aBuffer->Data(), aBuffer->Size(), sample, subsamples); - WidevineDecryptedBlock decrypted; - Status rv = CDM()->Decrypt(sample, &decrypted); - Log("Decryptor::Decrypt(timestamp=%lld) rv=%d sz=%d", - sample.timestamp, rv, decrypted.DecryptedBuffer()->Size()); - if (rv == kSuccess) { - aBuffer->Resize(decrypted.DecryptedBuffer()->Size()); - memcpy(aBuffer->Data(), - decrypted.DecryptedBuffer()->Data(), - decrypted.DecryptedBuffer()->Size()); - } - mCallback->Decrypted(aBuffer, ToGMPErr(rv)); -} - -void -WidevineDecryptor::DecryptingComplete() -{ - Log("WidevineDecryptor::DecryptingComplete() this=%p", this); - // Drop our references to the CDMWrapper. When any other references - // held elsewhere are dropped (for example references held by a - // WidevineVideoDecoder, or a runnable), the CDMWrapper destroys - // the CDM. - mCDM = nullptr; - sDecryptors.erase(mInstanceId); - mCallback = nullptr; - Release(); -} - -class WidevineBuffer : public cdm::Buffer { -public: - explicit WidevineBuffer(size_t aSize) { - Log("WidevineBuffer(size=" PRIuSIZE ") created", aSize); - mBuffer.SetLength(aSize); - } - ~WidevineBuffer() { - Log("WidevineBuffer(size=" PRIuSIZE ") destroyed", Size()); - } - void Destroy() override { delete this; } - uint32_t Capacity() const override { return mBuffer.Length(); }; - uint8_t* Data() override { return mBuffer.Elements(); } - void SetSize(uint32_t aSize) override { mBuffer.SetLength(aSize); } - uint32_t Size() const override { return mBuffer.Length(); } - -private: - WidevineBuffer(const WidevineBuffer&); - void operator=(const WidevineBuffer&); - - nsTArray<uint8_t> mBuffer; -}; - -Buffer* -WidevineDecryptor::Allocate(uint32_t aCapacity) -{ - Log("Decryptor::Allocate(capacity=%u)", aCapacity); - return new WidevineBuffer(aCapacity); -} - -class TimerTask : public GMPTask { -public: - TimerTask(WidevineDecryptor* aDecryptor, - RefPtr<CDMWrapper> aCDM, - void* aContext) - : mDecryptor(aDecryptor) - , mCDM(aCDM) - , mContext(aContext) - { - } - ~TimerTask() override {} - void Run() override { - mCDM->GetCDM()->TimerExpired(mContext); - } - void Destroy() override { delete this; } -private: - RefPtr<WidevineDecryptor> mDecryptor; - RefPtr<CDMWrapper> mCDM; - void* mContext; -}; - -void -WidevineDecryptor::SetTimer(int64_t aDelayMs, void* aContext) -{ - Log("Decryptor::SetTimer(delay_ms=%lld, context=0x%x)", aDelayMs, aContext); - if (mCDM) { - GMPSetTimerOnMainThread(new TimerTask(this, mCDM, aContext), aDelayMs); - } -} - -Time -WidevineDecryptor::GetCurrentWallTime() -{ - return base::Time::Now().ToDoubleT(); -} - -void -WidevineDecryptor::OnResolveKeyStatusPromise(uint32_t aPromiseId, - cdm::KeyStatus aKeyStatus) { - //TODO: The callback of GetStatusForPolicy. See Mozilla bug 1404230. -} - -void -WidevineDecryptor::OnResolveNewSessionPromise(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdSize) -{ - if (!mCallback) { - Log("Decryptor::OnResolveNewSessionPromise(aPromiseId=0x%d) FAIL; !mCallback", aPromiseId); - return; - } - Log("Decryptor::OnResolveNewSessionPromise(aPromiseId=0x%d)", aPromiseId); - auto iter = mPromiseIdToNewSessionTokens.find(aPromiseId); - if (iter == mPromiseIdToNewSessionTokens.end()) { - Log("FAIL: Decryptor::OnResolveNewSessionPromise(aPromiseId=%d) unknown aPromiseId", aPromiseId); - return; - } - mCallback->SetSessionId(iter->second, aSessionId, aSessionIdSize); - mCallback->ResolvePromise(aPromiseId); - mPromiseIdToNewSessionTokens.erase(iter); -} - -void -WidevineDecryptor::OnResolvePromise(uint32_t aPromiseId) -{ - if (!mCallback) { - Log("Decryptor::OnResolvePromise(aPromiseId=0x%d) FAIL; !mCallback", aPromiseId); - return; - } - Log("Decryptor::OnResolvePromise(aPromiseId=%d)", aPromiseId); - mCallback->ResolvePromise(aPromiseId); -} - -static GMPDOMException -ConvertCDMExceptionToGMPDOMException(cdm::Exception aException) -{ - switch (aException) { - case kExceptionNotSupportedError: return kGMPNotSupportedError; - case kExceptionInvalidStateError: return kGMPInvalidStateError; - case kExceptionTypeError: return kGMPTypeError; - case kExceptionQuotaExceededError: return kGMPQuotaExceededError; - case kUnknownError: return kGMPInvalidModificationError; // Note: Unique placeholder. - case kClientError: return kGMPAbortError; // Note: Unique placeholder. - case kOutputError: return kGMPSecurityError; // Note: Unique placeholder. - }; - return kGMPInvalidStateError; // Note: Unique placeholder. -} - -// Align with spec, the Exceptions used by CDM to reject promises . -// https://w3c.github.io/encrypted-media/#exceptions -cdm::Exception -ConvertCDMErrorToCDMException(cdm::Error error) { - switch (error) { - case cdm::kNotSupportedError: - return cdm::Exception::kExceptionNotSupportedError; - case cdm::kInvalidStateError: - return cdm::Exception::kExceptionInvalidStateError; - case cdm::kInvalidAccessError: - return cdm::Exception::kExceptionTypeError; - case cdm::kQuotaExceededError: - return cdm::Exception::kExceptionQuotaExceededError; - - case cdm::kUnknownError: - case cdm::kClientError: - case cdm::kOutputError: - break; - } - - return cdm::Exception::kExceptionInvalidStateError; -} - -void -WidevineDecryptor::OnRejectPromise(uint32_t aPromiseId, - cdm::Exception aException, - uint32_t aSystemCode, - const char* aErrorMessage, - uint32_t aErrorMessageSize) -{ - if (!mCallback) { - Log("Decryptor::OnRejectPromise(aPromiseId=%d, err=%d, sysCode=%u, msg=%s) FAIL; !mCallback", - aPromiseId, (int)aException, aSystemCode, aErrorMessage); - return; - } - Log("Decryptor::OnRejectPromise(aPromiseId=%d, err=%d, sysCode=%u, msg=%s)", - aPromiseId, (int)aException, aSystemCode, aErrorMessage); - mCallback->RejectPromise(aPromiseId, - ConvertCDMExceptionToGMPDOMException(aException), - !aErrorMessageSize ? "" : aErrorMessage, - aErrorMessageSize); -} - -static GMPSessionMessageType -ToGMPMessageType(MessageType message_type) -{ - switch (message_type) { - case kLicenseRequest: return kGMPLicenseRequest; - case kLicenseRenewal: return kGMPLicenseRenewal; - case kLicenseRelease: return kGMPLicenseRelease; - } - return kGMPMessageInvalid; -} - -void -WidevineDecryptor::OnSessionMessage(const char* aSessionId, - uint32_t aSessionIdSize, - cdm::MessageType aMessageType, - const char* aMessage, - uint32_t aMessageSize) -{ - if (!mCallback) { - Log("Decryptor::OnSessionMessage() FAIL; !mCallback"); - return; - } - Log("Decryptor::OnSessionMessage()"); - mCallback->SessionMessage(aSessionId, - aSessionIdSize, - ToGMPMessageType(aMessageType), - reinterpret_cast<const uint8_t*>(aMessage), - aMessageSize); -} - -static GMPMediaKeyStatus -ToGMPKeyStatus(KeyStatus aStatus) -{ - switch (aStatus) { - case kUsable: return kGMPUsable; - case kInternalError: return kGMPInternalError; - case kExpired: return kGMPExpired; - case kOutputRestricted: return kGMPOutputRestricted; - case kOutputDownscaled: return kGMPOutputDownscaled; - case kStatusPending: return kGMPStatusPending; - case kReleased: return kGMPReleased; - } - return kGMPUnknown; -} - -void -WidevineDecryptor::OnSessionKeysChange(const char* aSessionId, - uint32_t aSessionIdSize, - bool aHasAdditionalUsableKey, - const KeyInformation* aKeysInfo, - uint32_t aKeysInfoCount) -{ - if (!mCallback) { - Log("Decryptor::OnSessionKeysChange() FAIL; !mCallback"); - return; - } - Log("Decryptor::OnSessionKeysChange()"); - - nsTArray<GMPMediaKeyInfo> key_infos; - for (uint32_t i = 0; i < aKeysInfoCount; i++) { - key_infos.AppendElement(GMPMediaKeyInfo(aKeysInfo[i].key_id, - aKeysInfo[i].key_id_size, - ToGMPKeyStatus(aKeysInfo[i].status))); - } - mCallback->BatchedKeyStatusChanged(aSessionId, aSessionIdSize, - key_infos.Elements(), key_infos.Length()); -} - -static GMPTimestamp -ToGMPTime(Time aCDMTime) -{ - return static_cast<GMPTimestamp>(aCDMTime * 1000); -} - -void -WidevineDecryptor::OnExpirationChange(const char* aSessionId, - uint32_t aSessionIdSize, - Time aNewExpiryTime) -{ - if (!mCallback) { - Log("Decryptor::OnExpirationChange(sid=%s) t=%lf FAIL; !mCallback", - aSessionId, aNewExpiryTime); - return; - } - Log("Decryptor::OnExpirationChange(sid=%s) t=%lf", aSessionId, aNewExpiryTime); - GMPTimestamp expiry = ToGMPTime(aNewExpiryTime); - if (aNewExpiryTime == 0) { - return; - } - mCallback->ExpirationChange(aSessionId, aSessionIdSize, expiry); -} - -void -WidevineDecryptor::OnSessionClosed(const char* aSessionId, - uint32_t aSessionIdSize) -{ - if (!mCallback) { - Log("Decryptor::OnSessionClosed(sid=%s) FAIL; !mCallback", aSessionId); - return; - } - Log("Decryptor::OnSessionClosed(sid=%s)", aSessionId); - mCallback->SessionClosed(aSessionId, aSessionIdSize); -} - -void -WidevineDecryptor::SendPlatformChallenge(const char* aServiceId, - uint32_t aServiceIdSize, - const char* aChallenge, - uint32_t aChallengeSize) -{ - Log("Decryptor::SendPlatformChallenge(service_id=%s)", aServiceId); -} - -void -WidevineDecryptor::EnableOutputProtection(uint32_t aDesiredProtectionMask) -{ - Log("Decryptor::EnableOutputProtection(mask=0x%x)", aDesiredProtectionMask); -} - -void -WidevineDecryptor::QueryOutputProtectionStatus() -{ - Log("Decryptor::QueryOutputProtectionStatus()"); -} - -void -WidevineDecryptor::OnDeferredInitializationDone(StreamType aStreamType, - Status aDecoderStatus) -{ - Log("Decryptor::OnDeferredInitializationDone()"); -} - -FileIO* -WidevineDecryptor::CreateFileIO(FileIOClient* aClient) -{ - Log("Decryptor::CreateFileIO()"); - if (!mPersistentStateRequired) { - return nullptr; - } - return new WidevineFileIO(aClient); -} - -void -WidevineDecryptor::RequestStorageId(uint32_t aVersion) -{ - Log("Decryptor::RequestStorageId() aVersion = %u", aVersion); - if (aVersion >= 0x80000000) { - mCDM->OnStorageId(aVersion, nullptr, 0); - return; - } - - //TODO: Need to provide a menaingful buffer instead of a dummy one. - mCDM->OnStorageId(aVersion, new uint8_t[1024*1024], 1024 * 1024); -} - -} // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineDecryptor.h b/dom/media/gmp/widevine-adapter/WidevineDecryptor.h deleted file mode 100644 index f291c321d..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineDecryptor.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- 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/. */ - -#ifndef WidevineDecryptor_h_ -#define WidevineDecryptor_h_ - -#include "stddef.h" -#include "content_decryption_module.h" -#include "gmp-api/gmp-decryption.h" -#include "mozilla/RefPtr.h" -#include "WidevineUtils.h" -#include <map> - -namespace mozilla { - -class WidevineDecryptor : public GMPDecryptor - , public cdm::Host_9 -{ -public: - - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WidevineDecryptor) - - WidevineDecryptor(); - - void SetCDM(RefPtr<CDMWrapper> aCDM, uint32_t aDecryptorId); - - static RefPtr<CDMWrapper> GetInstance(uint32_t aDecryptorId); - - // GMPDecryptor - void Init(GMPDecryptorCallback* aCallback, - bool aDistinctiveIdentifierRequired, - bool aPersistentStateRequired) override; - - void CreateSession(uint32_t aCreateSessionToken, - uint32_t aPromiseId, - const char* aInitDataType, - uint32_t aInitDataTypeSize, - const uint8_t* aInitData, - uint32_t aInitDataSize, - GMPSessionType aSessionType) override; - - void LoadSession(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdLength) override; - - void UpdateSession(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdLength, - const uint8_t* aResponse, - uint32_t aResponseSize) override; - - void CloseSession(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdLength) override; - - void RemoveSession(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdLength) override; - - void SetServerCertificate(uint32_t aPromiseId, - const uint8_t* aServerCert, - uint32_t aServerCertSize) override; - - void Decrypt(GMPBuffer* aBuffer, - GMPEncryptedBufferMetadata* aMetadata) override; - - void DecryptingComplete() override; - - - // cdm::Host_9 implementation - cdm::Buffer* Allocate(uint32_t aCapacity) override; - void SetTimer(int64_t aDelayMs, void* aContext) override; - cdm::Time GetCurrentWallTime() override; - // cdm::Host_9 interface - void OnResolveKeyStatusPromise(uint32_t aPromiseId, - cdm::KeyStatus aKeyStatus) override; - void OnResolveNewSessionPromise(uint32_t aPromiseId, - const char* aSessionId, - uint32_t aSessionIdSize) override; - void OnResolvePromise(uint32_t aPromiseId) override; - void OnRejectPromise(uint32_t aPromiseId, - cdm::Exception aException, - uint32_t aSystemCode, - const char* aErrorMessage, - uint32_t aErrorMessageSize) override; - void OnSessionMessage(const char* aSessionId, - uint32_t aSessionIdSize, - cdm::MessageType aMessageType, - const char* aMessage, - uint32_t aMessageSize) override; - void OnSessionKeysChange(const char* aSessionId, - uint32_t aSessionIdSize, - bool aHasAdditionalUsableKey, - const cdm::KeyInformation* aKeysInfo, - uint32_t aKeysInfoCount) override; - void OnExpirationChange(const char* aSessionId, - uint32_t aSessionIdSize, - cdm::Time aNewExpiryTime) override; - void OnSessionClosed(const char* aSessionId, - uint32_t aSessionIdSize) override; - void SendPlatformChallenge(const char* aServiceId, - uint32_t aServiceIdSize, - const char* aChallenge, - uint32_t aChallengeSize) override; - void EnableOutputProtection(uint32_t aDesiredProtectionMask) override; - void QueryOutputProtectionStatus() override; - void OnDeferredInitializationDone(cdm::StreamType aStreamType, - cdm::Status aDecoderStatus) override; - // cdm::Host_9 interface - // NOTE: the interface has changed upstream. - void RequestStorageId(uint32_t aVersion) override; - cdm::FileIO* CreateFileIO(cdm::FileIOClient* aClient) override; - - GMPDecryptorCallback* Callback() const { return mCallback; } - RefPtr<CDMWrapper> GetCDMWrapper() const { return mCDM; } -private: - ~WidevineDecryptor(); - RefPtr<CDMWrapper> mCDM; - cdm::ContentDecryptionModule_9* CDM() { return mCDM->GetCDM(); } - - GMPDecryptorCallback* mCallback; - std::map<uint32_t, uint32_t> mPromiseIdToNewSessionTokens; - bool mDistinctiveIdentifierRequired = false; - bool mPersistentStateRequired = false; - uint32_t mInstanceId = 0; -}; - -} // namespace mozilla - -#endif // WidevineDecryptor_h_ diff --git a/dom/media/gmp/widevine-adapter/WidevineFileIO.cpp b/dom/media/gmp/widevine-adapter/WidevineFileIO.cpp deleted file mode 100644 index b5fb1d705..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineFileIO.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "WidevineFileIO.h" -#include "WidevineUtils.h" -#include "WidevineAdapter.h" - -using namespace cdm; - -namespace mozilla { - -void -WidevineFileIO::Open(const char* aFilename, uint32_t aFilenameLength) -{ - mName = std::string(aFilename, aFilename + aFilenameLength); - GMPRecord* record = nullptr; - GMPErr err = GMPCreateRecord(aFilename, aFilenameLength, &record, static_cast<GMPRecordClient*>(this)); - if (GMP_FAILED(err)) { - Log("WidevineFileIO::Open() '%s' GMPCreateRecord failed", mName.c_str()); - mClient->OnOpenComplete(FileIOClient::kError); - return; - } - if (GMP_FAILED(record->Open())) { - Log("WidevineFileIO::Open() '%s' record open failed", mName.c_str()); - mClient->OnOpenComplete(FileIOClient::kError); - return; - } - - Log("WidevineFileIO::Open() '%s'", mName.c_str()); - mRecord = record; -} - -void -WidevineFileIO::Read() -{ - if (!mRecord) { - Log("WidevineFileIO::Read() '%s' used uninitialized!", mName.c_str()); - mClient->OnReadComplete(FileIOClient::kError, nullptr, 0); - return; - } - Log("WidevineFileIO::Read() '%s'", mName.c_str()); - mRecord->Read(); -} - -void -WidevineFileIO::Write(const uint8_t* aData, uint32_t aDataSize) -{ - if (!mRecord) { - Log("WidevineFileIO::Write() '%s' used uninitialized!", mName.c_str()); - mClient->OnWriteComplete(FileIOClient::kError); - return; - } - mRecord->Write(aData, aDataSize); -} - -void -WidevineFileIO::Close() -{ - Log("WidevineFileIO::Close() '%s'", mName.c_str()); - if (mRecord) { - mRecord->Close(); - mRecord = nullptr; - } - delete this; -} - -static FileIOClient::Status -GMPToWidevineFileStatus(GMPErr aStatus) -{ - switch (aStatus) { - case GMPRecordInUse: return FileIOClient::kInUse; - case GMPNoErr: return FileIOClient::kSuccess; - default: return FileIOClient::kError; - } -} - -void -WidevineFileIO::OpenComplete(GMPErr aStatus) -{ - Log("WidevineFileIO::OpenComplete() '%s' status=%d", mName.c_str(), aStatus); - mClient->OnOpenComplete(GMPToWidevineFileStatus(aStatus)); -} - -void -WidevineFileIO::ReadComplete(GMPErr aStatus, - const uint8_t* aData, - uint32_t aDataSize) -{ - Log("WidevineFileIO::OnReadComplete() '%s' status=%d", mName.c_str(), aStatus); - mClient->OnReadComplete(GMPToWidevineFileStatus(aStatus), aData, aDataSize); -} - -void -WidevineFileIO::WriteComplete(GMPErr aStatus) -{ - Log("WidevineFileIO::WriteComplete() '%s' status=%d", mName.c_str(), aStatus); - mClient->OnWriteComplete(GMPToWidevineFileStatus(aStatus)); -} - -} // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineFileIO.h b/dom/media/gmp/widevine-adapter/WidevineFileIO.h deleted file mode 100644 index 63003d9b6..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineFileIO.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- 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/. */ - -#ifndef WidevineFileIO_h_ -#define WidevineFileIO_h_ - -#include <stddef.h> -#include "content_decryption_module.h" -#include "gmp-api/gmp-storage.h" -#include <string> - -namespace mozilla { - -class WidevineFileIO : public cdm::FileIO - , public GMPRecordClient -{ -public: - explicit WidevineFileIO(cdm::FileIOClient* aClient) - : mClient(aClient) - , mRecord(nullptr) - {} - - // cdm::FileIO - void Open(const char* aFilename, uint32_t aFilenameLength) override; - void Read() override; - void Write(const uint8_t* aData, uint32_t aDataSize) override; - void Close() override; - - // GMPRecordClient - void OpenComplete(GMPErr aStatus) override; - void ReadComplete(GMPErr aStatus, - const uint8_t* aData, - uint32_t aDataSize) override; - void WriteComplete(GMPErr aStatus) override; - -private: - cdm::FileIOClient* mClient; - GMPRecord* mRecord; - std::string mName; -}; - -} // namespace mozilla - -#endif // WidevineFileIO_h_
\ No newline at end of file diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp b/dom/media/gmp/widevine-adapter/WidevineUtils.cpp deleted file mode 100644 index 10c6c2e18..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineUtils.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- 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 "WidevineUtils.h" -#include "WidevineDecryptor.h" - -#include "gmp-api/gmp-errors.h" -#include <stdarg.h> -#include <stdio.h> - -namespace mozilla { - -#ifdef ENABLE_WIDEVINE_LOG -void -Log(const char* aFormat, ...) -{ - va_list ap; - va_start(ap, aFormat); - const size_t len = 1024; - char buf[len]; - vsnprintf(buf, len, aFormat, ap); - va_end(ap); - if (getenv("GMP_LOG_FILE")) { - FILE* f = fopen(getenv("GMP_LOG_FILE"), "a"); - if (f) { - fprintf(f, "%s\n", buf); - fflush(f); - fclose(f); - f = nullptr; - } - } else { - printf("LOG: %s\n", buf); - } -} -#endif // ENABLE_WIDEVINE_LOG - -GMPErr -ToGMPErr(cdm::Status aStatus) -{ - switch (aStatus) { - case cdm::kSuccess: return GMPNoErr; - case cdm::kNeedMoreData: return GMPGenericErr; - case cdm::kNoKey: return GMPNoKeyErr; - case cdm::kInitializationError: return GMPGenericErr; - case cdm::kDecryptError: return GMPCryptoErr; - case cdm::kDecodeError: return GMPDecodeErr; - case cdm::kDeferredInitialization: return GMPGenericErr; - default: return GMPGenericErr; - } -} - -void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto, - int64_t aTimestamp, - const uint8_t* aData, - size_t aDataSize, - cdm::InputBuffer &aInputBuffer, - nsTArray<cdm::SubsampleEntry> &aSubsamples) -{ - if (aCrypto) { - aInputBuffer.key_id = aCrypto->KeyId(); - aInputBuffer.key_id_size = aCrypto->KeyIdSize(); - aInputBuffer.iv = aCrypto->IV(); - aInputBuffer.iv_size = aCrypto->IVSize(); - aInputBuffer.num_subsamples = aCrypto->NumSubsamples(); - aSubsamples.SetCapacity(aInputBuffer.num_subsamples); - const uint16_t* clear = aCrypto->ClearBytes(); - const uint32_t* cipher = aCrypto->CipherBytes(); - for (size_t i = 0; i < aCrypto->NumSubsamples(); i++) { - aSubsamples.AppendElement(cdm::SubsampleEntry(clear[i], cipher[i])); - } - } - aInputBuffer.data = aData; - aInputBuffer.data_size = aDataSize; - aInputBuffer.subsamples = aSubsamples.Elements(); - aInputBuffer.timestamp = aTimestamp; -} - -CDMWrapper::CDMWrapper(cdm::ContentDecryptionModule_9* aCDM, - WidevineDecryptor* aDecryptor) - : mCDM(aCDM) - , mDecryptor(aDecryptor) -{ - MOZ_ASSERT(mCDM); -} - -CDMWrapper::~CDMWrapper() -{ - Log("CDMWrapper destroying CDM=%p", mCDM); - mCDM->Destroy(); - mCDM = nullptr; -} - -} // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineUtils.h b/dom/media/gmp/widevine-adapter/WidevineUtils.h deleted file mode 100644 index 2f6137fe3..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineUtils.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- 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/. */ - -#ifndef WidevineUtils_h_ -#define WidevineUtils_h_ - -#include "stddef.h" -#include "content_decryption_module.h" -#include "gmp-api/gmp-decryption.h" -#include "gmp-api/gmp-platform.h" -#include "nsISupportsImpl.h" -#include "nsTArray.h" - -namespace mozilla { - -// Uncomment for logging... -//#define ENABLE_WIDEVINE_LOG 1 -#ifdef ENABLE_WIDEVINE_LOG -void -Log(const char* aFormat, ...); -#else -#define Log(...) -#endif // ENABLE_WIDEVINE_LOG - - -#define ENSURE_TRUE(condition, rv) { \ - if (!(condition)) {\ - Log("ENSURE_TRUE FAILED %s:%d", __FILE__, __LINE__); \ - return rv; \ - } \ -} \ - -#define ENSURE_GMP_SUCCESS(err, rv) { \ - if (GMP_FAILED(err)) {\ - Log("ENSURE_GMP_SUCCESS FAILED %s:%d", __FILE__, __LINE__); \ - return rv; \ - } \ -} \ - -GMPErr -ToGMPErr(cdm::Status aStatus); - -class WidevineDecryptor; - -class CDMWrapper { -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CDMWrapper) - - explicit CDMWrapper(cdm::ContentDecryptionModule_9* aCDM, - WidevineDecryptor* aDecryptor); - cdm::ContentDecryptionModule_9* GetCDM() const { return mCDM; } - void OnStorageId(uint32_t aVersion, const uint8_t* aStorageId, - uint32_t aStorageIdSize) { - mCDM->OnStorageId(aVersion, aStorageId, aStorageIdSize); - } -private: - ~CDMWrapper(); - cdm::ContentDecryptionModule_9* mCDM; - RefPtr<WidevineDecryptor> mDecryptor; -}; - -void InitInputBuffer(const GMPEncryptedBufferMetadata* aCrypto, - int64_t aTimestamp, - const uint8_t* aData, - size_t aDataSize, - cdm::InputBuffer &aInputBuffer, - nsTArray<cdm::SubsampleEntry> &aSubsamples); - -} // namespace mozilla - -#endif // WidevineUtils_h_ diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp deleted file mode 100644 index 70d2fd8e0..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.cpp +++ /dev/null @@ -1,400 +0,0 @@ -/* -*- 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 "WidevineVideoDecoder.h" - -#include "mp4_demuxer/AnnexB.h" -#include "WidevineUtils.h" -#include "WidevineVideoFrame.h" -#include "mozilla/Move.h" - -using namespace cdm; - -namespace mozilla { - -WidevineVideoDecoder::WidevineVideoDecoder(GMPVideoHost* aVideoHost, - RefPtr<CDMWrapper> aCDMWrapper) - : mVideoHost(aVideoHost) - , mCDMWrapper(Move(aCDMWrapper)) - , mExtraData(new MediaByteBuffer()) - , mSentInput(false) - , mCodecType(kGMPVideoCodecInvalid) - , mReturnOutputCallDepth(0) - , mDrainPending(false) - , mResetInProgress(false) -{ - // Expect to start with a CDM wrapper, will release it in DecodingComplete(). - MOZ_ASSERT(mCDMWrapper); - Log("WidevineVideoDecoder created this=%p", this); - - // Corresponding Release is in DecodingComplete(). - AddRef(); -} - -WidevineVideoDecoder::~WidevineVideoDecoder() -{ - Log("WidevineVideoDecoder destroyed this=%p", this); -} - -static -VideoDecoderConfig::VideoCodecProfile -ToCDMH264Profile(uint8_t aProfile) -{ - switch (aProfile) { - case 66: return VideoDecoderConfig::kH264ProfileBaseline; - case 77: return VideoDecoderConfig::kH264ProfileMain; - case 88: return VideoDecoderConfig::kH264ProfileExtended; - case 100: return VideoDecoderConfig::kH264ProfileHigh; - case 110: return VideoDecoderConfig::kH264ProfileHigh10; - case 122: return VideoDecoderConfig::kH264ProfileHigh422; - case 144: return VideoDecoderConfig::kH264ProfileHigh444Predictive; - } - return VideoDecoderConfig::kUnknownVideoCodecProfile; -} - -void -WidevineVideoDecoder::InitDecode(const GMPVideoCodec& aCodecSettings, - const uint8_t* aCodecSpecific, - uint32_t aCodecSpecificLength, - GMPVideoDecoderCallback* aCallback, - int32_t aCoreCount) -{ - mCallback = aCallback; - VideoDecoderConfig config; - mCodecType = aCodecSettings.mCodecType; - if (mCodecType == kGMPVideoCodecH264) { - config.codec = VideoDecoderConfig::kCodecH264; - const GMPVideoCodecH264* h264 = (const GMPVideoCodecH264*)(aCodecSpecific); - config.profile = ToCDMH264Profile(h264->mAVCC.mProfile); - } else if (mCodecType == kGMPVideoCodecVP8) { - config.codec = VideoDecoderConfig::kCodecVp8; - config.profile = VideoDecoderConfig::kProfileNotNeeded; - } else if (mCodecType == kGMPVideoCodecVP9) { - config.codec = VideoDecoderConfig::kCodecVp9; - config.profile = VideoDecoderConfig::kProfileNotNeeded; - } else { - mCallback->Error(GMPInvalidArgErr); - return; - } - config.format = kYv12; - config.coded_size = Size(aCodecSettings.mWidth, aCodecSettings.mHeight); - mExtraData->AppendElements(aCodecSpecific + 1, aCodecSpecificLength); - config.extra_data = mExtraData->Elements(); - config.extra_data_size = mExtraData->Length(); - Status rv = CDM()->InitializeVideoDecoder(config); - if (rv != kSuccess) { - mCallback->Error(ToGMPErr(rv)); - return; - } - Log("WidevineVideoDecoder::InitDecode() rv=%d", rv); - mAnnexB = mp4_demuxer::AnnexB::ConvertExtraDataToAnnexB(mExtraData); -} - -void -WidevineVideoDecoder::Decode(GMPVideoEncodedFrame* aInputFrame, - bool aMissingFrames, - const uint8_t* aCodecSpecificInfo, - uint32_t aCodecSpecificInfoLength, - int64_t aRenderTimeMs) -{ - // We should not be given new input if a drain has been initiated - MOZ_ASSERT(!mDrainPending); - // We may not get the same out of the CDM decoder as we put in, and there - // may be some latency, i.e. we may need to input (say) 30 frames before - // we receive output. So we need to store the durations of the frames input, - // and retrieve them on output. - mFrameDurations[aInputFrame->TimeStamp()] = aInputFrame->Duration(); - - mSentInput = true; - InputBuffer sample; - - RefPtr<MediaRawData> raw( - new MediaRawData(aInputFrame->Buffer(), aInputFrame->Size())); - if (aInputFrame->Size() && !raw->Data()) { - // OOM. - mCallback->Error(GMPAllocErr); - return; - } - raw->mExtraData = mExtraData; - raw->mKeyframe = (aInputFrame->FrameType() == kGMPKeyFrame); - if (mCodecType == kGMPVideoCodecH264) { - // Convert input from AVCC, which GMPAPI passes in, to AnnexB, which - // Chromium uses internally. - mp4_demuxer::AnnexB::ConvertSampleToAnnexB(raw); - } - - const GMPEncryptedBufferMetadata* crypto = aInputFrame->GetDecryptionData(); - nsTArray<SubsampleEntry> subsamples; - InitInputBuffer(crypto, aInputFrame->TimeStamp(), raw->Data(), raw->Size(), sample, subsamples); - - // For keyframes, ConvertSampleToAnnexB will stick the AnnexB extra data - // at the start of the input. So we need to account for that as clear data - // in the subsamples. - if (raw->mKeyframe && !subsamples.IsEmpty() && mCodecType == kGMPVideoCodecH264) { - subsamples[0].clear_bytes += mAnnexB->Length(); - } - - WidevineVideoFrame frame; - Status rv = CDM()->DecryptAndDecodeFrame(sample, &frame); - Log("WidevineVideoDecoder::Decode(timestamp=%lld) rv=%d", sample.timestamp, rv); - - // Destroy frame, so that the shmem is now free to be used to return - // output to the Gecko process. - aInputFrame->Destroy(); - aInputFrame = nullptr; - - if (rv == kSuccess) { - if (!ReturnOutput(frame)) { - Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()"); - mCallback->Error(GMPDecodeErr); - return; - } - // A reset should only be started at most at level mReturnOutputCallDepth 1, - // and if it's started it should be finished by that call by the time - // the it returns, so it should always be false by this point. - MOZ_ASSERT(!mResetInProgress); - // Only request more data if we don't have pending samples. - if (mFrameAllocationQueue.empty()) { - MOZ_ASSERT(mCDMWrapper); - mCallback->InputDataExhausted(); - } - } else if (rv == kNeedMoreData) { - MOZ_ASSERT(mCDMWrapper); - mCallback->InputDataExhausted(); - } else { - mCallback->Error(ToGMPErr(rv)); - } - // Finish a drain if pending and we have no pending ReturnOutput calls on the stack. - if (mDrainPending && mReturnOutputCallDepth == 0) { - Drain(); - } -} - -// Util class to assist with counting mReturnOutputCallDepth. -class CounterHelper { -public: - // RAII, increment counter - explicit CounterHelper(int32_t& counter) - : mCounter(counter) - { - mCounter++; - } - - // RAII, decrement counter - ~CounterHelper() - { - mCounter--; - } - -private: - int32_t& mCounter; -}; - -// Util class to make sure GMP frames are freed. Holds a GMPVideoi420Frame* -// and will destroy it when the helper is destroyed unless the held frame -// if forgotten with ForgetFrame. -class FrameDestroyerHelper { -public: - explicit FrameDestroyerHelper(GMPVideoi420Frame*& frame) - : frame(frame) - { - } - - // RAII, destroy frame if held. - ~FrameDestroyerHelper() - { - if (frame) { - frame->Destroy(); - } - frame = nullptr; - } - - // Forget the frame without destroying it. - void ForgetFrame() - { - frame = nullptr; - } - -private: - GMPVideoi420Frame* frame; -}; - - -// Special handing is needed around ReturnOutput as it spins the IPC message -// queue when creating an empty frame and can end up with reentrant calls into -// the class methods. -bool -WidevineVideoDecoder::ReturnOutput(WidevineVideoFrame& aCDMFrame) -{ - MOZ_ASSERT(mReturnOutputCallDepth >= 0); - CounterHelper counterHelper(mReturnOutputCallDepth); - mFrameAllocationQueue.push_back(Move(aCDMFrame)); - if (mReturnOutputCallDepth > 1) { - // In a reentrant call. - return true; - } - while (!mFrameAllocationQueue.empty()) { - MOZ_ASSERT(mReturnOutputCallDepth == 1); - // If we're at call level 1 a reset should not have been started. A - // reset may be received during CreateEmptyFrame below, but we should not - // be in a reset at this stage -- this would indicate receiving decode - // messages before completing our reset, which we should not. - MOZ_ASSERT(!mResetInProgress); - WidevineVideoFrame currentCDMFrame = Move(mFrameAllocationQueue.front()); - mFrameAllocationQueue.pop_front(); - GMPVideoFrame* f = nullptr; - auto err = mVideoHost->CreateFrame(kGMPI420VideoFrame, &f); - if (GMP_FAILED(err) || !f) { - Log("Failed to create i420 frame!\n"); - return false; - } - auto gmpFrame = static_cast<GMPVideoi420Frame*>(f); - FrameDestroyerHelper frameDestroyerHelper(gmpFrame); - Size size = currentCDMFrame.Size(); - const int32_t yStride = currentCDMFrame.Stride(VideoFrame::kYPlane); - const int32_t uStride = currentCDMFrame.Stride(VideoFrame::kUPlane); - const int32_t vStride = currentCDMFrame.Stride(VideoFrame::kVPlane); - const int32_t halfHeight = size.height / 2; - // This call can cause a shmem alloc, during this alloc other calls - // may be made to this class and placed on the stack. ***WARNING***: - // other IPC calls can happen during this call, resulting in calls - // being made to the CDM. After this call state can have changed, - // and should be reevaluated. - err = gmpFrame->CreateEmptyFrame(size.width, - size.height, - yStride, - uStride, - vStride); - // Assert possible reentrant calls or resets haven't altered level unexpectedly. - MOZ_ASSERT(mReturnOutputCallDepth == 1); - ENSURE_GMP_SUCCESS(err, false); - - // If a reset started we need to dump the current frame and complete the reset. - if (mResetInProgress) { - MOZ_ASSERT(mCDMWrapper); - MOZ_ASSERT(mFrameAllocationQueue.empty()); - CompleteReset(); - return true; - } - - err = gmpFrame->SetWidth(size.width); - ENSURE_GMP_SUCCESS(err, false); - - err = gmpFrame->SetHeight(size.height); - ENSURE_GMP_SUCCESS(err, false); - - Buffer* buffer = currentCDMFrame.FrameBuffer(); - uint8_t* outBuffer = gmpFrame->Buffer(kGMPYPlane); - ENSURE_TRUE(outBuffer != nullptr, false); - MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPYPlane) >= yStride*size.height); - memcpy(outBuffer, - buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kYPlane), - yStride * size.height); - - outBuffer = gmpFrame->Buffer(kGMPUPlane); - ENSURE_TRUE(outBuffer != nullptr, false); - MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPUPlane) >= uStride * halfHeight); - memcpy(outBuffer, - buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kUPlane), - uStride * halfHeight); - - outBuffer = gmpFrame->Buffer(kGMPVPlane); - ENSURE_TRUE(outBuffer != nullptr, false); - MOZ_ASSERT(gmpFrame->AllocatedSize(kGMPVPlane) >= vStride * halfHeight); - memcpy(outBuffer, - buffer->Data() + currentCDMFrame.PlaneOffset(VideoFrame::kVPlane), - vStride * halfHeight); - - gmpFrame->SetTimestamp(currentCDMFrame.Timestamp()); - - auto d = mFrameDurations.find(currentCDMFrame.Timestamp()); - if (d != mFrameDurations.end()) { - gmpFrame->SetDuration(d->second); - mFrameDurations.erase(d); - } - - // Forget frame so it's not deleted, call back taking ownership. - frameDestroyerHelper.ForgetFrame(); - mCallback->Decoded(gmpFrame); - } - - return true; -} - -void -WidevineVideoDecoder::Reset() -{ - Log("WidevineVideoDecoder::Reset() mSentInput=%d", mSentInput); - // We shouldn't reset if a drain is pending. - MOZ_ASSERT(!mDrainPending); - mResetInProgress = true; - if (mSentInput) { - CDM()->ResetDecoder(kStreamTypeVideo); - } - // Remove queued frames, but do not reset mReturnOutputCallDepth, let the - // ReturnOutput calls unwind and decrement the counter as needed. - mFrameAllocationQueue.clear(); - mFrameDurations.clear(); - // Only if no ReturnOutput calls are in progress can we complete, otherwise - // ReturnOutput needs to finalize the reset. - if (mReturnOutputCallDepth == 0) { - CompleteReset(); - } -} - -void -WidevineVideoDecoder::CompleteReset() -{ - mCallback->ResetComplete(); - mSentInput = false; - mResetInProgress = false; -} - -void -WidevineVideoDecoder::Drain() -{ - Log("WidevineVideoDecoder::Drain()"); - if (mReturnOutputCallDepth > 0) { - Log("Drain call is reentrant, postponing drain"); - mDrainPending = true; - return; - } - - Status rv = kSuccess; - while (rv == kSuccess) { - WidevineVideoFrame frame; - InputBuffer sample; - Status rv = CDM()->DecryptAndDecodeFrame(sample, &frame); - Log("WidevineVideoDecoder::Drain(); DecryptAndDecodeFrame() rv=%d", rv); - if (frame.Format() == kUnknownVideoFormat) { - break; - } - if (rv == kSuccess) { - if (!ReturnOutput(frame)) { - Log("WidevineVideoDecoder::Decode() Failed in ReturnOutput()"); - } - } - } - // Shouldn't be reset while draining. - MOZ_ASSERT(!mResetInProgress); - - CDM()->ResetDecoder(kStreamTypeVideo); - mDrainPending = false; - mCallback->DrainComplete(); -} - -void -WidevineVideoDecoder::DecodingComplete() -{ - Log("WidevineVideoDecoder::DecodingComplete()"); - if (mCDMWrapper) { - CDM()->DeinitializeDecoder(kStreamTypeVideo); - mCDMWrapper = nullptr; - } - // Release that corresponds to AddRef() in constructor. - Release(); -} - -} // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h b/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h deleted file mode 100644 index f5e63519b..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineVideoDecoder.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- 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/. */ - -#ifndef WidevineVideoDecoder_h_ -#define WidevineVideoDecoder_h_ - -#include "stddef.h" -#include "content_decryption_module.h" -#include "gmp-api/gmp-video-decode.h" -#include "gmp-api/gmp-video-host.h" -#include "MediaData.h" -#include "nsISupportsImpl.h" -#include "nsTArray.h" -#include "WidevineDecryptor.h" -#include "WidevineVideoFrame.h" -#include <map> -#include <deque> - -namespace mozilla { - -class WidevineVideoDecoder : public GMPVideoDecoder { -public: - - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WidevineVideoDecoder) - - WidevineVideoDecoder(GMPVideoHost* aVideoHost, - RefPtr<CDMWrapper> aCDMWrapper); - void InitDecode(const GMPVideoCodec& aCodecSettings, - const uint8_t* aCodecSpecific, - uint32_t aCodecSpecificLength, - GMPVideoDecoderCallback* aCallback, - int32_t aCoreCount) override; - void Decode(GMPVideoEncodedFrame* aInputFrame, - bool aMissingFrames, - const uint8_t* aCodecSpecificInfo, - uint32_t aCodecSpecificInfoLength, - int64_t aRenderTimeMs = -1) override; - void Reset() override; - void Drain() override; - void DecodingComplete() override; - -private: - - ~WidevineVideoDecoder(); - - cdm::ContentDecryptionModule_9* CDM() const { - // CDM should only be accessed before 'DecodingComplete'. - MOZ_ASSERT(mCDMWrapper); - // CDMWrapper ensure the CDM is non-null, no need to check again. - return mCDMWrapper->GetCDM(); - } - - bool ReturnOutput(WidevineVideoFrame& aFrame); - void CompleteReset(); - - GMPVideoHost* mVideoHost; - RefPtr<CDMWrapper> mCDMWrapper; - RefPtr<MediaByteBuffer> mExtraData; - RefPtr<MediaByteBuffer> mAnnexB; - GMPVideoDecoderCallback* mCallback; - std::map<uint64_t, uint64_t> mFrameDurations; - bool mSentInput; - GMPVideoCodecType mCodecType; - // Frames waiting on allocation - std::deque<WidevineVideoFrame> mFrameAllocationQueue; - // Number of calls of ReturnOutput currently in progress. - int32_t mReturnOutputCallDepth; - // If we're waiting to drain. Used to prevent drain completing while - // ReturnOutput calls are still on the stack. - bool mDrainPending; - // If a reset is being performed. Used to track if ReturnOutput should - // dump current frame. - bool mResetInProgress; -}; - -} // namespace mozilla - -#endif // WidevineVideoDecoder_h_ diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp deleted file mode 100644 index 4221bf15b..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- 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 "WidevineVideoFrame.h" - -#include "WidevineUtils.h" - -using namespace cdm; - -namespace mozilla { - -WidevineVideoFrame::WidevineVideoFrame() - : mFormat(kUnknownVideoFormat) - , mSize(0,0) - , mBuffer(nullptr) - , mTimestamp(0) -{ - Log("WidevineVideoFrame::WidevineVideoFrame() this=%p", this); - memset(mPlaneOffsets, 0, sizeof(mPlaneOffsets)); - memset(mPlaneStrides, 0, sizeof(mPlaneStrides)); -} - -WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&& aOther) - : mFormat(aOther.mFormat) - , mSize(aOther.mSize) - , mBuffer(aOther.mBuffer) - , mTimestamp(aOther.mTimestamp) -{ - Log("WidevineVideoFrame::WidevineVideoFrame(WidevineVideoFrame&&) this=%p, other=%p", - this, &aOther); - memcpy(mPlaneOffsets, aOther.mPlaneOffsets, sizeof(mPlaneOffsets)); - memcpy(mPlaneStrides, aOther.mPlaneStrides, sizeof(mPlaneStrides)); - aOther.mBuffer = nullptr; -} - -WidevineVideoFrame::~WidevineVideoFrame() -{ - if (mBuffer) { - mBuffer->Destroy(); - mBuffer = nullptr; - } -} - -void -WidevineVideoFrame::SetFormat(cdm::VideoFormat aFormat) -{ - Log("WidevineVideoFrame::SetFormat(%d) this=%p", aFormat, this); - mFormat = aFormat; -} - -cdm::VideoFormat -WidevineVideoFrame::Format() const -{ - return mFormat; -} - -void -WidevineVideoFrame::SetSize(cdm::Size aSize) -{ - Log("WidevineVideoFrame::SetSize(%d,%d) this=%p", aSize.width, aSize.height, this); - mSize.width = aSize.width; - mSize.height = aSize.height; -} - -cdm::Size -WidevineVideoFrame::Size() const -{ - return mSize; -} - -void -WidevineVideoFrame::SetFrameBuffer(cdm::Buffer* aFrameBuffer) -{ - Log("WidevineVideoFrame::SetFrameBuffer(%p) this=%p", aFrameBuffer, this); - MOZ_ASSERT(!mBuffer); - mBuffer = aFrameBuffer; -} - -cdm::Buffer* -WidevineVideoFrame::FrameBuffer() -{ - return mBuffer; -} - -void -WidevineVideoFrame::SetPlaneOffset(cdm::VideoFrame::VideoPlane aPlane, uint32_t aOffset) -{ - Log("WidevineVideoFrame::SetPlaneOffset(%d, %d) this=%p", aPlane, aOffset, this); - mPlaneOffsets[aPlane] = aOffset; -} - -uint32_t -WidevineVideoFrame::PlaneOffset(cdm::VideoFrame::VideoPlane aPlane) -{ - return mPlaneOffsets[aPlane]; -} - -void -WidevineVideoFrame::SetStride(cdm::VideoFrame::VideoPlane aPlane, uint32_t aStride) -{ - Log("WidevineVideoFrame::SetStride(%d, %d) this=%p", aPlane, aStride, this); - mPlaneStrides[aPlane] = aStride; -} - -uint32_t -WidevineVideoFrame::Stride(cdm::VideoFrame::VideoPlane aPlane) -{ - return mPlaneStrides[aPlane]; -} - -void -WidevineVideoFrame::SetTimestamp(int64_t timestamp) -{ - Log("WidevineVideoFrame::SetTimestamp(%lld) this=%p", timestamp, this); - mTimestamp = timestamp; -} - -int64_t -WidevineVideoFrame::Timestamp() const -{ - return mTimestamp; -} - -} // namespace mozilla diff --git a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h b/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h deleted file mode 100644 index 96d4f20f8..000000000 --- a/dom/media/gmp/widevine-adapter/WidevineVideoFrame.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- 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/. */ - -#ifndef WidevineVideoFrame_h_ -#define WidevineVideoFrame_h_ - -#include "stddef.h" -#include "content_decryption_module.h" -#include <vector> - -namespace mozilla { - -class WidevineVideoFrame : public cdm::VideoFrame { -public: - WidevineVideoFrame(); - WidevineVideoFrame(WidevineVideoFrame&& other); - ~WidevineVideoFrame(); - - void SetFormat(cdm::VideoFormat aFormat) override; - cdm::VideoFormat Format() const override; - - void SetSize(cdm::Size aSize) override; - cdm::Size Size() const override; - - void SetFrameBuffer(cdm::Buffer* aFrameBuffer) override; - cdm::Buffer* FrameBuffer() override; - - void SetPlaneOffset(cdm::VideoFrame::VideoPlane aPlane, uint32_t aOffset) override; - uint32_t PlaneOffset(cdm::VideoFrame::VideoPlane aPlane) override; - - void SetStride(cdm::VideoFrame::VideoPlane aPlane, uint32_t aStride) override; - uint32_t Stride(cdm::VideoFrame::VideoPlane aPlane) override; - - void SetTimestamp(int64_t aTimestamp) override; - int64_t Timestamp() const override; - -protected: - cdm::VideoFormat mFormat; - cdm::Size mSize; - cdm::Buffer* mBuffer; - uint32_t mPlaneOffsets[kMaxPlanes]; - uint32_t mPlaneStrides[kMaxPlanes]; - int64_t mTimestamp; -}; - -} // namespace mozilla - -#endif diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module.h b/dom/media/gmp/widevine-adapter/content_decryption_module.h deleted file mode 100644 index 0539135fb..000000000 --- a/dom/media/gmp/widevine-adapter/content_decryption_module.h +++ /dev/null @@ -1,1278 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CDM_CONTENT_DECRYPTION_MODULE_H_ -#define CDM_CONTENT_DECRYPTION_MODULE_H_ - -#include "content_decryption_module_export.h" - -#if defined(_MSC_VER) -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef int int32_t; -typedef __int64 int64_t; -#else -#include <stdint.h> -#endif - -// Define CDM_CLASS_API to export class types. We have to add visibility -// attributes to make sure virtual tables in CDM consumer and CDM implementation -// are the same. Generally, it was always a good idea, as there're no guarantees -// about that for the internal symbols, but it has only become a practical issue -// after introduction of LTO devirtualization. See more details on -// https://crbug.com/609564#c35 -#if defined(_WIN32) -#if defined(__clang__) -#define CDM_CLASS_API [[clang::lto_visibility_public]] -#else -#define CDM_CLASS_API -#endif -#else // defined(_WIN32) -#define CDM_CLASS_API __attribute__((visibility("default"))) -#endif // defined(_WIN32) - -// The version number must be rolled when the exported functions are updated! -// If the CDM and the adapter use different versions of these functions, the -// adapter will fail to load or crash! -#define CDM_MODULE_VERSION 4 - -// Build the versioned entrypoint name. -// The extra macros are necessary to expand version to an actual value. -#define INITIALIZE_CDM_MODULE \ - BUILD_ENTRYPOINT(InitializeCdmModule, CDM_MODULE_VERSION) -#define BUILD_ENTRYPOINT(name, version) \ - BUILD_ENTRYPOINT_NO_EXPANSION(name, version) -#define BUILD_ENTRYPOINT_NO_EXPANSION(name, version) name##_##version - -extern "C" { -CDM_API void INITIALIZE_CDM_MODULE(); - -CDM_API void DeinitializeCdmModule(); - -// Returns a pointer to the requested CDM Host interface upon success. -// Returns NULL if the requested CDM Host interface is not supported. -// The caller should cast the returned pointer to the type matching -// |host_interface_version|. -typedef void* (*GetCdmHostFunc)(int host_interface_version, void* user_data); - -// Returns a pointer to the requested CDM upon success. -// Returns NULL if an error occurs or the requested |cdm_interface_version| or -// |key_system| is not supported or another error occurs. -// The caller should cast the returned pointer to the type matching -// |cdm_interface_version|. -// Caller retains ownership of arguments and must call Destroy() on the returned -// object. -CDM_API void* CreateCdmInstance( - int cdm_interface_version, - const char* key_system, uint32_t key_system_size, - GetCdmHostFunc get_cdm_host_func, void* user_data); - -CDM_API const char* GetCdmVersion(); -} - -namespace cdm { - -class CDM_CLASS_API AudioFrames; -class CDM_CLASS_API DecryptedBlock; -class CDM_CLASS_API VideoFrame; - -class CDM_CLASS_API Host_8; -class CDM_CLASS_API Host_9; - -enum Status { - kSuccess = 0, - kNeedMoreData, // Decoder needs more data to produce a decoded frame/sample. - kNoKey, // The required decryption key is not available. - kInitializationError, // Initialization error. - kDecryptError, // Decryption failed. - kDecodeError, // Error decoding audio or video. - kDeferredInitialization // Decoder is not ready for initialization. -}; - -// This must at least contain the exceptions defined in the spec: -// https://w3c.github.io/encrypted-media/#exceptions -// The following starts with the list of DOM4 exceptions from: -// http://www.w3.org/TR/dom/#domexception -// Some DOM4 exceptions are not included as they are not expected to be used. -// Should only be used on Host_8 and before. -enum Error { - kNotSupportedError = 9, - kInvalidStateError = 11, - kInvalidAccessError = 15, - kQuotaExceededError = 22, - - // Additional exceptions that do not have assigned codes. - // There are other non-EME-specific values, not included in this list. - kUnknownError = 30, - - // Additional values from previous EME versions. They currently have no - // matching DOMException. - kClientError = 100, - kOutputError = 101 -}; - -// Exceptions used by the CDM to reject promises. -// https://w3c.github.io/encrypted-media/#exceptions -enum Exception { - kExceptionTypeError, - kExceptionNotSupportedError, - kExceptionInvalidStateError, - kExceptionQuotaExceededError -}; - -// Time is defined as the number of seconds since the Epoch -// (00:00:00 UTC, January 1, 1970), not including any added leap second. -// Also see Time definition in spec: https://w3c.github.io/encrypted-media/#time -// Note that Time is defined in millisecond accuracy in the spec but in second -// accuracy here. -typedef double Time; - -// An input buffer can be split into several continuous subsamples. -// A SubsampleEntry specifies the number of clear and cipher bytes in each -// subsample. For example, the following buffer has three subsamples: -// -// |<----- subsample1 ----->|<----- subsample2 ----->|<----- subsample3 ----->| -// | clear1 | cipher1 | clear2 | cipher2 | clear3 | cipher3 | -// -// For decryption, all of the cipher bytes in a buffer should be concatenated -// (in the subsample order) into a single logical stream. The clear bytes should -// not be considered as part of decryption. -// -// Stream to decrypt: | cipher1 | cipher2 | cipher3 | -// Decrypted stream: | decrypted1| decrypted2 | decrypted3 | -// -// After decryption, the decrypted bytes should be copied over the position -// of the corresponding cipher bytes in the original buffer to form the output -// buffer. Following the above example, the decrypted buffer should be: -// -// |<----- subsample1 ----->|<----- subsample2 ----->|<----- subsample3 ----->| -// | clear1 | decrypted1| clear2 | decrypted2 | clear3 | decrypted3 | -// -struct SubsampleEntry { - SubsampleEntry(uint32_t clear_bytes, uint32_t cipher_bytes) - : clear_bytes(clear_bytes), cipher_bytes(cipher_bytes) {} - - uint32_t clear_bytes; - uint32_t cipher_bytes; -}; - -// Represents an input buffer to be decrypted (and possibly decoded). It does -// not own any pointers in this struct. If |iv_size| = 0, the data is -// unencrypted. -struct InputBuffer { - InputBuffer() - : data(nullptr), - data_size(0), - key_id(nullptr), - key_id_size(0), - iv(nullptr), - iv_size(0), - subsamples(nullptr), - num_subsamples(0), - timestamp(0) {} - - const uint8_t* data; // Pointer to the beginning of the input data. - uint32_t data_size; // Size (in bytes) of |data|. - - const uint8_t* key_id; // Key ID to identify the decryption key. - uint32_t key_id_size; // Size (in bytes) of |key_id|. - - const uint8_t* iv; // Initialization vector. - uint32_t iv_size; // Size (in bytes) of |iv|. - - const struct SubsampleEntry* subsamples; - uint32_t num_subsamples; // Number of subsamples in |subsamples|. - - int64_t timestamp; // Presentation timestamp in microseconds. -}; - -struct AudioDecoderConfig { - enum AudioCodec { - kUnknownAudioCodec = 0, - kCodecVorbis, - kCodecAac - }; - - AudioDecoderConfig() - : codec(kUnknownAudioCodec), - channel_count(0), - bits_per_channel(0), - samples_per_second(0), - extra_data(nullptr), - extra_data_size(0) {} - - AudioCodec codec; - int32_t channel_count; - int32_t bits_per_channel; - int32_t samples_per_second; - - // Optional byte data required to initialize audio decoders, such as the - // vorbis setup header. - uint8_t* extra_data; - uint32_t extra_data_size; -}; - -// Supported sample formats for AudioFrames. -enum AudioFormat { - kUnknownAudioFormat = 0, // Unknown format value. Used for error reporting. - kAudioFormatU8, // Interleaved unsigned 8-bit w/ bias of 128. - kAudioFormatS16, // Interleaved signed 16-bit. - kAudioFormatS32, // Interleaved signed 32-bit. - kAudioFormatF32, // Interleaved float 32-bit. - kAudioFormatPlanarS16, // Signed 16-bit planar. - kAudioFormatPlanarF32, // Float 32-bit planar. -}; - -// Surface formats based on FOURCC labels, see: http://www.fourcc.org/yuv.php -// Values are chosen to be consistent with Chromium's VideoPixelFormat values. -enum VideoFormat { - kUnknownVideoFormat = 0, // Unknown format value. Used for error reporting. - kYv12 = 1, // 12bpp YVU planar 1x1 Y, 2x2 VU samples. - kI420 = 2, // 12bpp YUV planar 1x1 Y, 2x2 UV samples. - - // In the following formats, each sample uses 16-bit in storage, while the - // sample value is stored in the least significant N bits where N is - // specified by the number after "P". For example, for YUV420P9, each Y, U, - // and V sample is stored in the least significant 9 bits in a 2-byte block. - kYUV420P9 = 16, - kYUV420P10 = 17, - kYUV422P9 = 18, - kYUV422P10 = 19, - kYUV444P9 = 20, - kYUV444P10 = 21, - kYUV420P12 = 22, - kYUV422P12 = 23, - kYUV444P12 = 24, -}; - -struct Size { - Size() : width(0), height(0) {} - Size(int32_t width, int32_t height) : width(width), height(height) {} - - int32_t width; - int32_t height; -}; - -struct VideoDecoderConfig { - enum VideoCodec { - kUnknownVideoCodec = 0, - kCodecVp8, - kCodecH264, - kCodecVp9 - }; - - enum VideoCodecProfile { - kUnknownVideoCodecProfile = 0, - kProfileNotNeeded, - kH264ProfileBaseline, - kH264ProfileMain, - kH264ProfileExtended, - kH264ProfileHigh, - kH264ProfileHigh10, - kH264ProfileHigh422, - kH264ProfileHigh444Predictive, - // VP9 Profiles are only passed in starting from CDM_9. - kVP9Profile0, - kVP9Profile1, - kVP9Profile2, - kVP9Profile3 - }; - - VideoDecoderConfig() - : codec(kUnknownVideoCodec), - profile(kUnknownVideoCodecProfile), - format(kUnknownVideoFormat), - extra_data(nullptr), - extra_data_size(0) {} - - VideoCodec codec; - VideoCodecProfile profile; - VideoFormat format; - - // Width and height of video frame immediately post-decode. Not all pixels - // in this region are valid. - Size coded_size; - - // Optional byte data required to initialize video decoders, such as H.264 - // AAVC data. - uint8_t* extra_data; - uint32_t extra_data_size; -}; - -enum StreamType { - kStreamTypeAudio = 0, - kStreamTypeVideo = 1 -}; - -// Structure provided to ContentDecryptionModule::OnPlatformChallengeResponse() -// after a platform challenge was initiated via Host::SendPlatformChallenge(). -// All values will be NULL / zero in the event of a challenge failure. -struct PlatformChallengeResponse { - // |challenge| provided during Host::SendPlatformChallenge() combined with - // nonce data and signed with the platform's private key. - const uint8_t* signed_data; - uint32_t signed_data_length; - - // RSASSA-PKCS1-v1_5-SHA256 signature of the |signed_data| block. - const uint8_t* signed_data_signature; - uint32_t signed_data_signature_length; - - // X.509 device specific certificate for the |service_id| requested. - const uint8_t* platform_key_certificate; - uint32_t platform_key_certificate_length; -}; - -// Used when passing arrays of binary data. Does not own the referenced data. -struct BinaryData { - BinaryData() : data(nullptr), length(0) {} - const uint8_t* data; - uint32_t length; -}; - -// The current status of the associated key. The valid types are defined in the -// spec: https://w3c.github.io/encrypted-media/#idl-def-MediaKeyStatus -enum KeyStatus { - kUsable = 0, - kInternalError = 1, - kExpired = 2, - kOutputRestricted = 3, - kOutputDownscaled = 4, - kStatusPending = 5, - kReleased = 6 -}; - -// Used when passing arrays of key information. Does not own the referenced -// data. |system_code| is an additional error code for unusable keys and -// should be 0 when |status| == kUsable. -struct KeyInformation { - KeyInformation() - : key_id(nullptr), - key_id_size(0), - status(kInternalError), - system_code(0) {} - const uint8_t* key_id; - uint32_t key_id_size; - KeyStatus status; - uint32_t system_code; -}; - -// Supported output protection methods for use with EnableOutputProtection() and -// returned by OnQueryOutputProtectionStatus(). -enum OutputProtectionMethods { - kProtectionNone = 0, - kProtectionHDCP = 1 << 0 -}; - -// Connected output link types returned by OnQueryOutputProtectionStatus(). -enum OutputLinkTypes { - kLinkTypeNone = 0, - kLinkTypeUnknown = 1 << 0, - kLinkTypeInternal = 1 << 1, - kLinkTypeVGA = 1 << 2, - kLinkTypeHDMI = 1 << 3, - kLinkTypeDVI = 1 << 4, - kLinkTypeDisplayPort = 1 << 5, - kLinkTypeNetwork = 1 << 6 -}; - -// Result of the QueryOutputProtectionStatus() call. -enum QueryResult { - kQuerySucceeded = 0, - kQueryFailed -}; - -// The Initialization Data Type. The valid types are defined in the spec: -// http://w3c.github.io/encrypted-media/initdata-format-registry.html#registry -enum InitDataType { - kCenc = 0, - kKeyIds = 1, - kWebM = 2 -}; - -// The type of session to create. The valid types are defined in the spec: -// https://w3c.github.io/encrypted-media/#idl-def-SessionType -enum SessionType { - kTemporary = 0, - kPersistentLicense = 1, - kPersistentKeyRelease = 2 -}; - -// The type of the message event. The valid types are defined in the spec: -// https://w3c.github.io/encrypted-media/#idl-def-MediaKeyMessageType -enum MessageType { - kLicenseRequest = 0, - kLicenseRenewal = 1, - kLicenseRelease = 2 -}; - -enum HdcpVersion { - kHdcpVersionNone, - kHdcpVersion1_0, - kHdcpVersion1_1, - kHdcpVersion1_2, - kHdcpVersion1_3, - kHdcpVersion1_4, - kHdcpVersion2_0, - kHdcpVersion2_1, - kHdcpVersion2_2 -}; - -struct Policy { - Policy() : min_hdcp_version(kHdcpVersionNone) {} - - HdcpVersion min_hdcp_version; -}; - -// FileIO interface provides a way for the CDM to store data in a file in -// persistent storage. This interface aims only at providing basic read/write -// capabilities and should not be used as a full fledged file IO API. -// Each CDM and origin (e.g. HTTPS, "foo.example.com", 443) combination has -// its own persistent storage. All instances of a given CDM associated with a -// given origin share the same persistent storage. -// Note to implementors of this interface: -// Per-origin storage and the ability for users to clear it are important. -// See http://www.w3.org/TR/encrypted-media/#privacy-storedinfo. -class CDM_CLASS_API FileIO { - public: - // Opens the file with |file_name| for read and write. - // FileIOClient::OnOpenComplete() will be called after the opening - // operation finishes. - // - When the file is opened by a CDM instance, it will be classified as "in - // use". In this case other CDM instances in the same domain may receive - // kInUse status when trying to open it. - // - |file_name| must only contain letters (A-Za-z), digits(0-9), or "._-". - // It must not start with an underscore ('_'), and must be at least 1 - // character and no more than 256 characters long. - virtual void Open(const char* file_name, uint32_t file_name_size) = 0; - - // Reads the contents of the file. FileIOClient::OnReadComplete() will be - // called with the read status. Read() should not be called if a previous - // Read() or Write() call is still pending; otherwise OnReadComplete() will - // be called with kInUse. - virtual void Read() = 0; - - // Writes |data_size| bytes of |data| into the file. - // FileIOClient::OnWriteComplete() will be called with the write status. - // All existing contents in the file will be overwritten. Calling Write() with - // NULL |data| will clear all contents in the file. Write() should not be - // called if a previous Write() or Read() call is still pending; otherwise - // OnWriteComplete() will be called with kInUse. - virtual void Write(const uint8_t* data, uint32_t data_size) = 0; - - // Closes the file if opened, destroys this FileIO object and releases any - // resources allocated. The CDM must call this method when it finished using - // this object. A FileIO object must not be used after Close() is called. - virtual void Close() = 0; - - protected: - FileIO() {} - virtual ~FileIO() {} -}; - -// Responses to FileIO calls. All responses will be called asynchronously. -// When kError is returned, the FileIO object could be in an error state. All -// following calls (other than Close()) could return kError. The CDM should -// still call Close() to destroy the FileIO object. -class CDM_CLASS_API FileIOClient { - public: - enum Status { - kSuccess = 0, - kInUse, - kError - }; - - // Response to a FileIO::Open() call with the open |status|. - virtual void OnOpenComplete(Status status) = 0; - - // Response to a FileIO::Read() call to provide |data_size| bytes of |data| - // read from the file. - // - kSuccess indicates that all contents of the file has been successfully - // read. In this case, 0 |data_size| means that the file is empty. - // - kInUse indicates that there are other read/write operations pending. - // - kError indicates read failure, e.g. the storage is not open or cannot be - // fully read. - virtual void OnReadComplete(Status status, - const uint8_t* data, uint32_t data_size) = 0; - - // Response to a FileIO::Write() call. - // - kSuccess indicates that all the data has been written into the file - // successfully. - // - kInUse indicates that there are other read/write operations pending. - // - kError indicates write failure, e.g. the storage is not open or cannot be - // fully written. Upon write failure, the contents of the file should be - // regarded as corrupt and should not used. - virtual void OnWriteComplete(Status status) = 0; - - protected: - FileIOClient() {} - virtual ~FileIOClient() {} -}; - -// ContentDecryptionModule interface that all CDMs need to implement. -// The interface is versioned for backward compatibility. -// Note: ContentDecryptionModule implementations must use the allocator -// provided in CreateCdmInstance() to allocate any Buffer that needs to -// be passed back to the caller. Implementations must call Buffer::Destroy() -// when a Buffer is created that will never be returned to the caller. -class CDM_CLASS_API ContentDecryptionModule_8 { - public: - static const int kVersion = 8; - typedef Host_8 Host; - - // Initializes the CDM instance, providing information about permitted - // functionalities. - // If |allow_distinctive_identifier| is false, messages from the CDM, - // such as message events, must not contain a Distinctive Identifier, - // even in an encrypted form. - // If |allow_persistent_state| is false, the CDM must not attempt to - // persist state. Calls to CreateFileIO() will fail. - virtual void Initialize(bool allow_distinctive_identifier, - bool allow_persistent_state) = 0; - - // SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(), - // UpdateSession(), CloseSession(), and RemoveSession() all accept a - // |promise_id|, which must be passed to the completion Host method - // (e.g. Host::OnResolveNewSessionPromise()). - - // Provides a server certificate to be used to encrypt messages to the - // license server. The CDM must respond by calling either - // Host::OnResolvePromise() or Host::OnRejectPromise(). - virtual void SetServerCertificate(uint32_t promise_id, - const uint8_t* server_certificate_data, - uint32_t server_certificate_data_size) = 0; - - // Creates a session given |session_type|, |init_data_type|, and |init_data|. - // The CDM must respond by calling either Host::OnResolveNewSessionPromise() - // or Host::OnRejectPromise(). - virtual void CreateSessionAndGenerateRequest(uint32_t promise_id, - SessionType session_type, - InitDataType init_data_type, - const uint8_t* init_data, - uint32_t init_data_size) = 0; - - // Loads the session of type |session_type| specified by |session_id|. - // The CDM must respond by calling either Host::OnResolveNewSessionPromise() - // or Host::OnRejectPromise(). If the session is not found, call - // Host::OnResolveNewSessionPromise() with session_id = NULL. - virtual void LoadSession(uint32_t promise_id, - SessionType session_type, - const char* session_id, - uint32_t session_id_size) = 0; - - // Updates the session with |response|. The CDM must respond by calling - // either Host::OnResolvePromise() or Host::OnRejectPromise(). - virtual void UpdateSession(uint32_t promise_id, - const char* session_id, - uint32_t session_id_size, - const uint8_t* response, - uint32_t response_size) = 0; - - // Requests that the CDM close the session. The CDM must respond by calling - // either Host::OnResolvePromise() or Host::OnRejectPromise() when the request - // has been processed. This may be before the session is closed. Once the - // session is closed, Host::OnSessionClosed() must also be called. - virtual void CloseSession(uint32_t promise_id, - const char* session_id, - uint32_t session_id_size) = 0; - - // Removes any stored session data associated with this session. Will only be - // called for persistent sessions. The CDM must respond by calling either - // Host::OnResolvePromise() or Host::OnRejectPromise() when the request has - // been processed. - virtual void RemoveSession(uint32_t promise_id, - const char* session_id, - uint32_t session_id_size) = 0; - - // Performs scheduled operation with |context| when the timer fires. - virtual void TimerExpired(void* context) = 0; - - // Decrypts the |encrypted_buffer|. - // - // Returns kSuccess if decryption succeeded, in which case the callee - // should have filled the |decrypted_buffer| and passed the ownership of - // |data| in |decrypted_buffer| to the caller. - // Returns kNoKey if the CDM did not have the necessary decryption key - // to decrypt. - // Returns kDecryptError if any other error happened. - // If the return value is not kSuccess, |decrypted_buffer| should be ignored - // by the caller. - virtual Status Decrypt(const InputBuffer& encrypted_buffer, - DecryptedBlock* decrypted_buffer) = 0; - - // Initializes the CDM audio decoder with |audio_decoder_config|. This - // function must be called before DecryptAndDecodeSamples() is called. - // - // Returns kSuccess if the |audio_decoder_config| is supported and the CDM - // audio decoder is successfully initialized. - // Returns kSessionError if |audio_decoder_config| is not supported. The CDM - // may still be able to do Decrypt(). - // Returns kDeferredInitialization if the CDM is not ready to initialize the - // decoder at this time. Must call Host::OnDeferredInitializationDone() once - // initialization is complete. - virtual Status InitializeAudioDecoder( - const AudioDecoderConfig& audio_decoder_config) = 0; - - // Initializes the CDM video decoder with |video_decoder_config|. This - // function must be called before DecryptAndDecodeFrame() is called. - // - // Returns kSuccess if the |video_decoder_config| is supported and the CDM - // video decoder is successfully initialized. - // Returns kSessionError if |video_decoder_config| is not supported. The CDM - // may still be able to do Decrypt(). - // Returns kDeferredInitialization if the CDM is not ready to initialize the - // decoder at this time. Must call Host::OnDeferredInitializationDone() once - // initialization is complete. - virtual Status InitializeVideoDecoder( - const VideoDecoderConfig& video_decoder_config) = 0; - - // De-initializes the CDM decoder and sets it to an uninitialized state. The - // caller can initialize the decoder again after this call to re-initialize - // it. This can be used to reconfigure the decoder if the configuration - // changes. - virtual void DeinitializeDecoder(StreamType decoder_type) = 0; - - // Resets the CDM decoder to an initialized clean state. All internal buffers - // MUST be flushed. - virtual void ResetDecoder(StreamType decoder_type) = 0; - - // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into a - // |video_frame|. Upon end-of-stream, the caller should call this function - // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty - // |video_frame| (|format| == kEmptyVideoFrame) is produced. - // - // Returns kSuccess if decryption and decoding both succeeded, in which case - // the callee will have filled the |video_frame| and passed the ownership of - // |frame_buffer| in |video_frame| to the caller. - // Returns kNoKey if the CDM did not have the necessary decryption key - // to decrypt. - // Returns kNeedMoreData if more data was needed by the decoder to generate - // a decoded frame (e.g. during initialization and end-of-stream). - // Returns kDecryptError if any decryption error happened. - // Returns kDecodeError if any decoding error happened. - // If the return value is not kSuccess, |video_frame| should be ignored by - // the caller. - virtual Status DecryptAndDecodeFrame(const InputBuffer& encrypted_buffer, - VideoFrame* video_frame) = 0; - - // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into - // |audio_frames|. Upon end-of-stream, the caller should call this function - // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty - // |audio_frames| is produced. - // - // Returns kSuccess if decryption and decoding both succeeded, in which case - // the callee will have filled |audio_frames| and passed the ownership of - // |data| in |audio_frames| to the caller. - // Returns kNoKey if the CDM did not have the necessary decryption key - // to decrypt. - // Returns kNeedMoreData if more data was needed by the decoder to generate - // audio samples (e.g. during initialization and end-of-stream). - // Returns kDecryptError if any decryption error happened. - // Returns kDecodeError if any decoding error happened. - // If the return value is not kSuccess, |audio_frames| should be ignored by - // the caller. - virtual Status DecryptAndDecodeSamples(const InputBuffer& encrypted_buffer, - AudioFrames* audio_frames) = 0; - - // Called by the host after a platform challenge was initiated via - // Host::SendPlatformChallenge(). - virtual void OnPlatformChallengeResponse( - const PlatformChallengeResponse& response) = 0; - - // Called by the host after a call to Host::QueryOutputProtectionStatus(). The - // |link_mask| is a bit mask of OutputLinkTypes and |output_protection_mask| - // is a bit mask of OutputProtectionMethods. If |result| is kQueryFailed, - // then |link_mask| and |output_protection_mask| are undefined and should - // be ignored. - virtual void OnQueryOutputProtectionStatus( - QueryResult result, - uint32_t link_mask, - uint32_t output_protection_mask) = 0; - - // Destroys the object in the same context as it was created. - virtual void Destroy() = 0; - - protected: - ContentDecryptionModule_8() {} - virtual ~ContentDecryptionModule_8() {} -}; - -// ContentDecryptionModule interface that all CDMs need to implement. -// The interface is versioned for backward compatibility. -// Note: ContentDecryptionModule implementations must use the allocator -// provided in CreateCdmInstance() to allocate any Buffer that needs to -// be passed back to the caller. Implementations must call Buffer::Destroy() -// when a Buffer is created that will never be returned to the caller. -class CDM_CLASS_API ContentDecryptionModule_9 { - public: - static const int kVersion = 9; - typedef Host_9 Host; - - // Initializes the CDM instance, providing information about permitted - // functionalities. - // If |allow_distinctive_identifier| is false, messages from the CDM, - // such as message events, must not contain a Distinctive Identifier, - // even in an encrypted form. - // If |allow_persistent_state| is false, the CDM must not attempt to - // persist state. Calls to CreateFileIO() will fail. - virtual void Initialize(bool allow_distinctive_identifier, - bool allow_persistent_state) = 0; - - // Gets the key status if the CDM has a hypothetical key with the |policy|. - // The CDM must respond by calling either Host::OnResolveKeyStatusPromise() - // with the result key status or Host::OnRejectPromise() if an unexpected - // error happened or this method is not supported. - virtual void GetStatusForPolicy(uint32_t promise_id, - const Policy& policy) = 0; - - // SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(), - // UpdateSession(), CloseSession(), and RemoveSession() all accept a - // |promise_id|, which must be passed to the completion Host method - // (e.g. Host::OnResolveNewSessionPromise()). - - // Provides a server certificate to be used to encrypt messages to the - // license server. The CDM must respond by calling either - // Host::OnResolvePromise() or Host::OnRejectPromise(). - virtual void SetServerCertificate(uint32_t promise_id, - const uint8_t* server_certificate_data, - uint32_t server_certificate_data_size) = 0; - - // Creates a session given |session_type|, |init_data_type|, and |init_data|. - // The CDM must respond by calling either Host::OnResolveNewSessionPromise() - // or Host::OnRejectPromise(). - virtual void CreateSessionAndGenerateRequest(uint32_t promise_id, - SessionType session_type, - InitDataType init_data_type, - const uint8_t* init_data, - uint32_t init_data_size) = 0; - - // Loads the session of type |session_type| specified by |session_id|. - // The CDM must respond by calling either Host::OnResolveNewSessionPromise() - // or Host::OnRejectPromise(). If the session is not found, call - // Host::OnResolveNewSessionPromise() with session_id = NULL. - virtual void LoadSession(uint32_t promise_id, - SessionType session_type, - const char* session_id, - uint32_t session_id_size) = 0; - - // Updates the session with |response|. The CDM must respond by calling - // either Host::OnResolvePromise() or Host::OnRejectPromise(). - virtual void UpdateSession(uint32_t promise_id, - const char* session_id, - uint32_t session_id_size, - const uint8_t* response, - uint32_t response_size) = 0; - - // Requests that the CDM close the session. The CDM must respond by calling - // either Host::OnResolvePromise() or Host::OnRejectPromise() when the request - // has been processed. This may be before the session is closed. Once the - // session is closed, Host::OnSessionClosed() must also be called. - virtual void CloseSession(uint32_t promise_id, - const char* session_id, - uint32_t session_id_size) = 0; - - // Removes any stored session data associated with this session. Will only be - // called for persistent sessions. The CDM must respond by calling either - // Host::OnResolvePromise() or Host::OnRejectPromise() when the request has - // been processed. - virtual void RemoveSession(uint32_t promise_id, - const char* session_id, - uint32_t session_id_size) = 0; - - // Performs scheduled operation with |context| when the timer fires. - virtual void TimerExpired(void* context) = 0; - - // Decrypts the |encrypted_buffer|. - // - // Returns kSuccess if decryption succeeded, in which case the callee - // should have filled the |decrypted_buffer| and passed the ownership of - // |data| in |decrypted_buffer| to the caller. - // Returns kNoKey if the CDM did not have the necessary decryption key - // to decrypt. - // Returns kDecryptError if any other error happened. - // If the return value is not kSuccess, |decrypted_buffer| should be ignored - // by the caller. - virtual Status Decrypt(const InputBuffer& encrypted_buffer, - DecryptedBlock* decrypted_buffer) = 0; - - // Initializes the CDM audio decoder with |audio_decoder_config|. This - // function must be called before DecryptAndDecodeSamples() is called. - // - // Returns kSuccess if the |audio_decoder_config| is supported and the CDM - // audio decoder is successfully initialized. - // Returns kInitializationError if |audio_decoder_config| is not supported. - // The CDM may still be able to do Decrypt(). - // Returns kDeferredInitialization if the CDM is not ready to initialize the - // decoder at this time. Must call Host::OnDeferredInitializationDone() once - // initialization is complete. - virtual Status InitializeAudioDecoder( - const AudioDecoderConfig& audio_decoder_config) = 0; - - // Initializes the CDM video decoder with |video_decoder_config|. This - // function must be called before DecryptAndDecodeFrame() is called. - // - // Returns kSuccess if the |video_decoder_config| is supported and the CDM - // video decoder is successfully initialized. - // Returns kInitializationError if |video_decoder_config| is not supported. - // The CDM may still be able to do Decrypt(). - // Returns kDeferredInitialization if the CDM is not ready to initialize the - // decoder at this time. Must call Host::OnDeferredInitializationDone() once - // initialization is complete. - virtual Status InitializeVideoDecoder( - const VideoDecoderConfig& video_decoder_config) = 0; - - // De-initializes the CDM decoder and sets it to an uninitialized state. The - // caller can initialize the decoder again after this call to re-initialize - // it. This can be used to reconfigure the decoder if the configuration - // changes. - virtual void DeinitializeDecoder(StreamType decoder_type) = 0; - - // Resets the CDM decoder to an initialized clean state. All internal buffers - // MUST be flushed. - virtual void ResetDecoder(StreamType decoder_type) = 0; - - // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into a - // |video_frame|. Upon end-of-stream, the caller should call this function - // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty - // |video_frame| (|format| == kEmptyVideoFrame) is produced. - // - // Returns kSuccess if decryption and decoding both succeeded, in which case - // the callee will have filled the |video_frame| and passed the ownership of - // |frame_buffer| in |video_frame| to the caller. - // Returns kNoKey if the CDM did not have the necessary decryption key - // to decrypt. - // Returns kNeedMoreData if more data was needed by the decoder to generate - // a decoded frame (e.g. during initialization and end-of-stream). - // Returns kDecryptError if any decryption error happened. - // Returns kDecodeError if any decoding error happened. - // If the return value is not kSuccess, |video_frame| should be ignored by - // the caller. - virtual Status DecryptAndDecodeFrame(const InputBuffer& encrypted_buffer, - VideoFrame* video_frame) = 0; - - // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into - // |audio_frames|. Upon end-of-stream, the caller should call this function - // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty - // |audio_frames| is produced. - // - // Returns kSuccess if decryption and decoding both succeeded, in which case - // the callee will have filled |audio_frames| and passed the ownership of - // |data| in |audio_frames| to the caller. - // Returns kNoKey if the CDM did not have the necessary decryption key - // to decrypt. - // Returns kNeedMoreData if more data was needed by the decoder to generate - // audio samples (e.g. during initialization and end-of-stream). - // Returns kDecryptError if any decryption error happened. - // Returns kDecodeError if any decoding error happened. - // If the return value is not kSuccess, |audio_frames| should be ignored by - // the caller. - virtual Status DecryptAndDecodeSamples(const InputBuffer& encrypted_buffer, - AudioFrames* audio_frames) = 0; - - // Called by the host after a platform challenge was initiated via - // Host::SendPlatformChallenge(). - virtual void OnPlatformChallengeResponse( - const PlatformChallengeResponse& response) = 0; - - // Called by the host after a call to Host::QueryOutputProtectionStatus(). The - // |link_mask| is a bit mask of OutputLinkTypes and |output_protection_mask| - // is a bit mask of OutputProtectionMethods. If |result| is kQueryFailed, - // then |link_mask| and |output_protection_mask| are undefined and should - // be ignored. - virtual void OnQueryOutputProtectionStatus( - QueryResult result, - uint32_t link_mask, - uint32_t output_protection_mask) = 0; - - // Called by the host after a call to Host::RequestStorageId(). If the - // version of the storage ID requested is available, |storage_id| and - // |storage_id_size| are set appropriately. |version| will be the same as - // what was requested, unless 0 (latest) was requested, in which case - // |version| will be the actual version number for the |storage_id| returned. - // If the requested version is not available, null/zero will be provided as - // |storage_id| and |storage_id_size|, respectively, and |version| should be - // ignored. - virtual void OnStorageId(uint32_t version, - const uint8_t* storage_id, - uint32_t storage_id_size) = 0; - - // Destroys the object in the same context as it was created. - virtual void Destroy() = 0; - - protected: - ContentDecryptionModule_9() {} - virtual ~ContentDecryptionModule_9() {} -}; - -typedef ContentDecryptionModule_9 ContentDecryptionModule; - -// Represents a buffer created by Allocator implementations. -class CDM_CLASS_API Buffer { - public: - // Destroys the buffer in the same context as it was created. - virtual void Destroy() = 0; - - virtual uint32_t Capacity() const = 0; - virtual uint8_t* Data() = 0; - virtual void SetSize(uint32_t size) = 0; - virtual uint32_t Size() const = 0; - - protected: - Buffer() {} - virtual ~Buffer() {} - - private: - Buffer(const Buffer&); - void operator=(const Buffer&); -}; - -class CDM_CLASS_API Host_8 { - public: - static const int kVersion = 8; - - // Returns a Buffer* containing non-zero members upon success, or NULL on - // failure. The caller owns the Buffer* after this call. The buffer is not - // guaranteed to be zero initialized. The capacity of the allocated Buffer - // is guaranteed to be not less than |capacity|. - virtual Buffer* Allocate(uint32_t capacity) = 0; - - // Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms| - // from now with |context|. - virtual void SetTimer(int64_t delay_ms, void* context) = 0; - - // Returns the current wall time. - virtual Time GetCurrentWallTime() = 0; - - // Called by the CDM when a session is created or loaded and the value for the - // MediaKeySession's sessionId attribute is available (|session_id|). - // This must be called before OnSessionMessage() or - // OnSessionKeysChange() is called for the same session. |session_id_size| - // should not include null termination. - // When called in response to LoadSession(), the |session_id| must be the - // same as the |session_id| passed in LoadSession(), or NULL if the - // session could not be loaded. - virtual void OnResolveNewSessionPromise(uint32_t promise_id, - const char* session_id, - uint32_t session_id_size) = 0; - - // Called by the CDM when a session is updated or released. - virtual void OnResolvePromise(uint32_t promise_id) = 0; - - // Called by the CDM when an error occurs as a result of one of the - // ContentDecryptionModule calls that accept a |promise_id|. - // |error| must be specified, |error_message| and |system_code| - // are optional. |error_message_size| should not include null termination. - virtual void OnRejectPromise(uint32_t promise_id, - Error error, - uint32_t system_code, - const char* error_message, - uint32_t error_message_size) = 0; - - // Called by the CDM when it has a message for session |session_id|. - // Size parameters should not include null termination. - // |legacy_destination_url| is only for supporting the prefixed EME API and - // is ignored by unprefixed EME. It should only be non-null if |message_type| - // is kLicenseRenewal. - virtual void OnSessionMessage(const char* session_id, - uint32_t session_id_size, - MessageType message_type, - const char* message, - uint32_t message_size, - const char* legacy_destination_url, - uint32_t legacy_destination_url_length) = 0; - - // Called by the CDM when there has been a change in keys or their status for - // session |session_id|. |has_additional_usable_key| should be set if a - // key is newly usable (e.g. new key available, previously expired key has - // been renewed, etc.) and the browser should attempt to resume playback. - // |key_ids| is the list of key ids for this session along with their - // current status. |key_ids_count| is the number of entries in |key_ids|. - // Size parameter for |session_id| should not include null termination. - virtual void OnSessionKeysChange(const char* session_id, - uint32_t session_id_size, - bool has_additional_usable_key, - const KeyInformation* keys_info, - uint32_t keys_info_count) = 0; - - // Called by the CDM when there has been a change in the expiration time for - // session |session_id|. This can happen as the result of an Update() call - // or some other event. If this happens as a result of a call to Update(), - // it must be called before resolving the Update() promise. |new_expiry_time| - // represents the time after which the key(s) in the session will no longer - // be usable for decryption. It can be 0 if no such time exists or if the - // license explicitly never expires. Size parameter should not include null - // termination. - virtual void OnExpirationChange(const char* session_id, - uint32_t session_id_size, - Time new_expiry_time) = 0; - - // Called by the CDM when session |session_id| is closed. Size - // parameter should not include null termination. - virtual void OnSessionClosed(const char* session_id, - uint32_t session_id_size) = 0; - - // Called by the CDM when an error occurs in session |session_id| - // unrelated to one of the ContentDecryptionModule calls that accept a - // |promise_id|. |error| must be specified, |error_message| and - // |system_code| are optional. Length parameters should not include null - // termination. - // Note: - // - This method is only for supporting prefixed EME API. - // - This method will be ignored by unprefixed EME. All errors reported - // in this method should probably also be reported by one of other methods. - virtual void OnLegacySessionError( - const char* session_id, uint32_t session_id_length, - Error error, - uint32_t system_code, - const char* error_message, uint32_t error_message_length) = 0; - - // The following are optional methods that may not be implemented on all - // platforms. - - // Sends a platform challenge for the given |service_id|. |challenge| is at - // most 256 bits of data to be signed. Once the challenge has been completed, - // the host will call ContentDecryptionModule::OnPlatformChallengeResponse() - // with the signed challenge response and platform certificate. Size - // parameters should not include null termination. - virtual void SendPlatformChallenge(const char* service_id, - uint32_t service_id_size, - const char* challenge, - uint32_t challenge_size) = 0; - - // Attempts to enable output protection (e.g. HDCP) on the display link. The - // |desired_protection_mask| is a bit mask of OutputProtectionMethods. No - // status callback is issued, the CDM must call QueryOutputProtectionStatus() - // periodically to ensure the desired protections are applied. - virtual void EnableOutputProtection(uint32_t desired_protection_mask) = 0; - - // Requests the current output protection status. Once the host has the status - // it will call ContentDecryptionModule::OnQueryOutputProtectionStatus(). - virtual void QueryOutputProtectionStatus() = 0; - - // Must be called by the CDM if it returned kDeferredInitialization during - // InitializeAudioDecoder() or InitializeVideoDecoder(). - virtual void OnDeferredInitializationDone(StreamType stream_type, - Status decoder_status) = 0; - - // Creates a FileIO object from the host to do file IO operation. Returns NULL - // if a FileIO object cannot be obtained. Once a valid FileIO object is - // returned, |client| must be valid until FileIO::Close() is called. The - // CDM can call this method multiple times to operate on different files. - virtual FileIO* CreateFileIO(FileIOClient* client) = 0; - - protected: - Host_8() {} - virtual ~Host_8() {} -}; - -class CDM_CLASS_API Host_9 { - public: - static const int kVersion = 9; - - // Returns a Buffer* containing non-zero members upon success, or NULL on - // failure. The caller owns the Buffer* after this call. The buffer is not - // guaranteed to be zero initialized. The capacity of the allocated Buffer - // is guaranteed to be not less than |capacity|. - virtual Buffer* Allocate(uint32_t capacity) = 0; - - // Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms| - // from now with |context|. - virtual void SetTimer(int64_t delay_ms, void* context) = 0; - - // Returns the current wall time. - virtual Time GetCurrentWallTime() = 0; - - // Called by the CDM when a key status is available in response to - // GetStatusForPolicy(). - virtual void OnResolveKeyStatusPromise(uint32_t promise_id, - KeyStatus key_status) = 0; - - // Called by the CDM when a session is created or loaded and the value for the - // MediaKeySession's sessionId attribute is available (|session_id|). - // This must be called before OnSessionMessage() or - // OnSessionKeysChange() is called for the same session. |session_id_size| - // should not include null termination. - // When called in response to LoadSession(), the |session_id| must be the - // same as the |session_id| passed in LoadSession(), or NULL if the - // session could not be loaded. - virtual void OnResolveNewSessionPromise(uint32_t promise_id, - const char* session_id, - uint32_t session_id_size) = 0; - - // Called by the CDM when a session is updated or released. - virtual void OnResolvePromise(uint32_t promise_id) = 0; - - // Called by the CDM when an error occurs as a result of one of the - // ContentDecryptionModule calls that accept a |promise_id|. - // |exception| must be specified. |error_message| and |system_code| - // are optional. |error_message_size| should not include null termination. - virtual void OnRejectPromise(uint32_t promise_id, - Exception exception, - uint32_t system_code, - const char* error_message, - uint32_t error_message_size) = 0; - - // Called by the CDM when it has a message for session |session_id|. - // Size parameters should not include null termination. - virtual void OnSessionMessage(const char* session_id, - uint32_t session_id_size, - MessageType message_type, - const char* message, - uint32_t message_size) = 0; - - // Called by the CDM when there has been a change in keys or their status for - // session |session_id|. |has_additional_usable_key| should be set if a - // key is newly usable (e.g. new key available, previously expired key has - // been renewed, etc.) and the browser should attempt to resume playback. - // |key_ids| is the list of key ids for this session along with their - // current status. |key_ids_count| is the number of entries in |key_ids|. - // Size parameter for |session_id| should not include null termination. - virtual void OnSessionKeysChange(const char* session_id, - uint32_t session_id_size, - bool has_additional_usable_key, - const KeyInformation* keys_info, - uint32_t keys_info_count) = 0; - - // Called by the CDM when there has been a change in the expiration time for - // session |session_id|. This can happen as the result of an Update() call - // or some other event. If this happens as a result of a call to Update(), - // it must be called before resolving the Update() promise. |new_expiry_time| - // represents the time after which the key(s) in the session will no longer - // be usable for decryption. It can be 0 if no such time exists or if the - // license explicitly never expires. Size parameter should not include null - // termination. - virtual void OnExpirationChange(const char* session_id, - uint32_t session_id_size, - Time new_expiry_time) = 0; - - // Called by the CDM when session |session_id| is closed. Size - // parameter should not include null termination. - virtual void OnSessionClosed(const char* session_id, - uint32_t session_id_size) = 0; - - // The following are optional methods that may not be implemented on all - // platforms. - - // Sends a platform challenge for the given |service_id|. |challenge| is at - // most 256 bits of data to be signed. Once the challenge has been completed, - // the host will call ContentDecryptionModule::OnPlatformChallengeResponse() - // with the signed challenge response and platform certificate. Size - // parameters should not include null termination. - virtual void SendPlatformChallenge(const char* service_id, - uint32_t service_id_size, - const char* challenge, - uint32_t challenge_size) = 0; - - // Attempts to enable output protection (e.g. HDCP) on the display link. The - // |desired_protection_mask| is a bit mask of OutputProtectionMethods. No - // status callback is issued, the CDM must call QueryOutputProtectionStatus() - // periodically to ensure the desired protections are applied. - virtual void EnableOutputProtection(uint32_t desired_protection_mask) = 0; - - // Requests the current output protection status. Once the host has the status - // it will call ContentDecryptionModule::OnQueryOutputProtectionStatus(). - virtual void QueryOutputProtectionStatus() = 0; - - // Must be called by the CDM if it returned kDeferredInitialization during - // InitializeAudioDecoder() or InitializeVideoDecoder(). - virtual void OnDeferredInitializationDone(StreamType stream_type, - Status decoder_status) = 0; - - // Creates a FileIO object from the host to do file IO operation. Returns NULL - // if a FileIO object cannot be obtained. Once a valid FileIO object is - // returned, |client| must be valid until FileIO::Close() is called. The - // CDM can call this method multiple times to operate on different files. - virtual FileIO* CreateFileIO(FileIOClient* client) = 0; - - // Requests a specific version of the storage ID. A storage ID is a stable, - // device specific ID used by the CDM to securely store persistent data. The - // ID will be returned by the host via ContentDecryptionModule::OnStorageId(). - // If |version| is 0, the latest version will be returned. All |version|s - // that are greater than or equal to 0x80000000 are reserved for the CDM and - // should not be supported or returned by the host. The CDM must not expose - // the ID outside the client device, even in encrypted form. - virtual void RequestStorageId(uint32_t version) = 0; - - protected: - Host_9() {} - virtual ~Host_9() {} -}; - -// Represents a decrypted block that has not been decoded. -class CDM_CLASS_API DecryptedBlock { - public: - virtual void SetDecryptedBuffer(Buffer* buffer) = 0; - virtual Buffer* DecryptedBuffer() = 0; - - // TODO(tomfinegan): Figure out if timestamp is really needed. If it is not, - // we can just pass Buffer pointers around. - virtual void SetTimestamp(int64_t timestamp) = 0; - virtual int64_t Timestamp() const = 0; - - protected: - DecryptedBlock() {} - virtual ~DecryptedBlock() {} -}; - -class CDM_CLASS_API VideoFrame { - public: - enum VideoPlane { - kYPlane = 0, - kUPlane = 1, - kVPlane = 2, - kMaxPlanes = 3, - }; - - virtual void SetFormat(VideoFormat format) = 0; - virtual VideoFormat Format() const = 0; - - virtual void SetSize(cdm::Size size) = 0; - virtual cdm::Size Size() const = 0; - - virtual void SetFrameBuffer(Buffer* frame_buffer) = 0; - virtual Buffer* FrameBuffer() = 0; - - virtual void SetPlaneOffset(VideoPlane plane, uint32_t offset) = 0; - virtual uint32_t PlaneOffset(VideoPlane plane) = 0; - - virtual void SetStride(VideoPlane plane, uint32_t stride) = 0; - virtual uint32_t Stride(VideoPlane plane) = 0; - - virtual void SetTimestamp(int64_t timestamp) = 0; - virtual int64_t Timestamp() const = 0; - - protected: - VideoFrame() {} - virtual ~VideoFrame() {} -}; - -// Represents decrypted and decoded audio frames. AudioFrames can contain -// multiple audio output buffers, which are serialized into this format: -// -// |<------------------- serialized audio buffer ------------------->| -// | int64_t timestamp | int64_t length | length bytes of audio data | -// -// For example, with three audio output buffers, the AudioFrames will look -// like this: -// -// |<----------------- AudioFrames ------------------>| -// | audio buffer 0 | audio buffer 1 | audio buffer 2 | -class CDM_CLASS_API AudioFrames { - public: - virtual void SetFrameBuffer(Buffer* buffer) = 0; - virtual Buffer* FrameBuffer() = 0; - - // The CDM must call this method, providing a valid format, when providing - // frame buffers. Planar data should be stored end to end; e.g., - // |ch1 sample1||ch1 sample2|....|ch1 sample_last||ch2 sample1|... - virtual void SetFormat(AudioFormat format) = 0; - virtual AudioFormat Format() const = 0; - - protected: - AudioFrames() {} - virtual ~AudioFrames() {} -}; - -} // namespace cdm - -#endif // CDM_CONTENT_DECRYPTION_MODULE_H_ diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module_export.h b/dom/media/gmp/widevine-adapter/content_decryption_module_export.h deleted file mode 100644 index 51d485892..000000000 --- a/dom/media/gmp/widevine-adapter/content_decryption_module_export.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_ -#define CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_ - -// Define CDM_API so that functionality implemented by the CDM module -// can be exported to consumers. -#if defined(_WIN32) - -#if defined(CDM_IMPLEMENTATION) -#define CDM_API __declspec(dllexport) -#else -#define CDM_API __declspec(dllimport) -#endif // defined(CDM_IMPLEMENTATION) - -#else // defined(_WIN32) -#define CDM_API __attribute__((visibility("default"))) -#endif // defined(_WIN32) - -#endif // CDM_CONTENT_DECRYPTION_MODULE_EXPORT_H_ diff --git a/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h b/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h deleted file mode 100644 index 5df8344e6..000000000 --- a/dom/media/gmp/widevine-adapter/content_decryption_module_ext.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CDM_CONTENT_DECRYPTION_MODULE_EXT_H_ -#define CDM_CONTENT_DECRYPTION_MODULE_EXT_H_ - -#if defined(_WIN32) -#include <windows.h> -#endif - -#include "content_decryption_module_export.h" - -#if defined(_MSC_VER) -typedef unsigned int uint32_t; -#else -#include <stdint.h> -#endif - -namespace cdm { - -#if defined(_WIN32) -typedef wchar_t FilePathCharType; -typedef HANDLE PlatformFile; -const PlatformFile kInvalidPlatformFile = INVALID_HANDLE_VALUE; -#else -typedef char FilePathCharType; -typedef int PlatformFile; -const PlatformFile kInvalidPlatformFile = -1; -#endif // defined(_WIN32) - -struct HostFile { - HostFile(const FilePathCharType* file_path, - PlatformFile file, - PlatformFile sig_file) - : file_path(file_path), file(file), sig_file(sig_file) {} - - // File that is part of the host of the CDM. - const FilePathCharType* file_path = nullptr; - PlatformFile file = kInvalidPlatformFile; - - // Signature file for |file|. - PlatformFile sig_file = kInvalidPlatformFile; -}; - -} // namespace cdm - -extern "C" { - -// Functions in this file are dynamically retrieved by their versioned function -// names. Increment the version number for any backward incompatible API -// changes. - -// Verifies CDM host. All files in |host_files| are opened in read-only mode. -// -// Returns false and closes all files if there is an immediate failure. -// Otherwise returns true as soon as possible and processes the files -// asynchronously. All files MUST be closed by the CDM after this one-time -// processing is finished. -CDM_API bool VerifyCdmHost_0(const cdm::HostFile* host_files, - uint32_t num_files); -} - -#endif // CDM_CONTENT_DECRYPTION_MODULE_EXT_H_ diff --git a/dom/media/gmp/widevine-adapter/moz.build b/dom/media/gmp/widevine-adapter/moz.build deleted file mode 100644 index 4a3a079ce..000000000 --- a/dom/media/gmp/widevine-adapter/moz.build +++ /dev/null @@ -1,24 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# 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/. - -SOURCES += [ - 'WidevineAdapter.cpp', - 'WidevineDecryptor.cpp', - 'WidevineFileIO.cpp', - 'WidevineUtils.cpp', - 'WidevineVideoDecoder.cpp', - 'WidevineVideoFrame.cpp', -] - -FINAL_LIBRARY = 'xul' - -LOCAL_INCLUDES += [ - '/dom/media/gmp', -] - -if CONFIG['CLANG_CXX']: - CXXFLAGS += ['-Wno-error=shadow'] - -include('/ipc/chromium/chromium-config.mozbuild') |