Bug 1315850 - Add PChromiumCDM.ipdl for Widevine CDM. r=gerald
The implementations of this protocol will be stubbed out in later patches.
MozReview-Commit-ID: 622CB1BOoR9
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/ChromiumCDMChild.cpp
@@ -0,0 +1,102 @@
+/* -*- 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 "ChromiumCDMChild.h"
+#include "GMPContentChild.h"
+
+namespace mozilla {
+namespace gmp {
+
+ChromiumCDMChild::ChromiumCDMChild(GMPContentChild* aPlugin)
+ : mPlugin(aPlugin)
+{
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvInit(const bool& aAllowDistinctiveIdentifier,
+ const bool& aAllowPersistentState)
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvSetServerCertificate(const uint32_t& aPromiseId,
+ nsTArray<uint8_t>&& aServerCert)
+
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvCreateSessionAndGenerateRequest(
+ const uint32_t& aPromiseId,
+ const uint32_t& aSessionType,
+ const uint32_t& aInitDataType,
+ nsTArray<uint8_t>&& aInitData)
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvUpdateSession(const uint32_t& aPromiseId,
+ const nsCString& aSessionId,
+ nsTArray<uint8_t>&& aResponse)
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvCloseSession(const uint32_t& aPromiseId,
+ const nsCString& aSessionId)
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvRemoveSession(const uint32_t& aPromiseId,
+ const nsCString& aSessionId)
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvDecrypt(const CDMInputBuffer& aBuffer)
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvInitializeVideoDecoder(
+ const CDMVideoDecoderConfig& aConfig)
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvDeinitializeVideoDecoder()
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvResetVideoDecoder()
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvDecryptAndDecodeFrame(const CDMInputBuffer& aBuffer)
+{
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+ChromiumCDMChild::RecvDestroy()
+{
+ return IPC_OK();
+}
+
+} // namespace gmp
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/ChromiumCDMChild.h
@@ -0,0 +1,58 @@
+/* -*- 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 ChromiumCDMChild_h_
+#define ChromiumCDMChild_h_
+
+#include "mozilla/gmp/PChromiumCDMChild.h"
+
+namespace mozilla {
+namespace gmp {
+
+class GMPContentChild;
+
+class ChromiumCDMChild : public PChromiumCDMChild
+{
+public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMChild);
+
+ explicit ChromiumCDMChild(GMPContentChild* aPlugin);
+
+protected:
+ ~ChromiumCDMChild() {}
+
+ ipc::IPCResult RecvInit(const bool& aAllowDistinctiveIdentifier,
+ const bool& aAllowPersistentState) override;
+ ipc::IPCResult RecvSetServerCertificate(
+ const uint32_t& aPromiseId,
+ nsTArray<uint8_t>&& aServerCert) override;
+ ipc::IPCResult RecvCreateSessionAndGenerateRequest(
+ const uint32_t& aPromiseId,
+ const uint32_t& aSessionType,
+ const uint32_t& aInitDataType,
+ nsTArray<uint8_t>&& aInitData) override;
+ ipc::IPCResult RecvUpdateSession(const uint32_t& aPromiseId,
+ const nsCString& aSessionId,
+ nsTArray<uint8_t>&& aResponse) override;
+ ipc::IPCResult RecvCloseSession(const uint32_t& aPromiseId,
+ const nsCString& aSessionId) override;
+ ipc::IPCResult RecvRemoveSession(const uint32_t& aPromiseId,
+ const nsCString& aSessionId) override;
+ ipc::IPCResult RecvDecrypt(const CDMInputBuffer& aBuffer) override;
+ ipc::IPCResult RecvInitializeVideoDecoder(
+ const CDMVideoDecoderConfig& aConfig) override;
+ ipc::IPCResult RecvDeinitializeVideoDecoder() override;
+ ipc::IPCResult RecvResetVideoDecoder() override;
+ ipc::IPCResult RecvDecryptAndDecodeFrame(
+ const CDMInputBuffer& aBuffer) override;
+ ipc::IPCResult RecvDestroy() override;
+
+ GMPContentChild* mPlugin;
+};
+
+} // namespace gmp
+} // namespace mozilla
+
+#endif // ChromiumCDMChild_h_
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/ChromiumCDMParent.cpp
@@ -0,0 +1,116 @@
+/* -*- 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 "ChromiumCDMParent.h"
+#include "mozilla/gmp/GMPTypes.h"
+#include "GMPContentChild.h"
+
+namespace mozilla {
+namespace gmp {
+
+ChromiumCDMParent::ChromiumCDMParent(GMPContentParent* aContentParent)
+ : mContentParent(aContentParent)
+{
+}
+
+ipc::IPCResult
+ChromiumCDMParent::Recv__delete__()
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvOnResolveNewSessionPromise(const uint32_t& aPromiseId,
+ const nsCString& aSessionId)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvOnResolvePromise(const uint32_t& aPromiseId)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvOnRejectPromise(const uint32_t& aPromiseId,
+ const uint32_t& aError,
+ const uint32_t& aSystemCode,
+ const nsCString& aErrorMessage)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvOnSessionMessage(const nsCString& aSessionId,
+ const uint32_t& aMessageType,
+ nsTArray<uint8_t>&& aMessage)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvOnSessionKeysChange(
+ const nsCString& aSessionId,
+ nsTArray<CDMKeyInformation>&& aKeysInfo)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvOnExpirationChange(const nsCString& aSessionId,
+ const double& aSecondsSinceEpoch)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvOnSessionClosed(const nsCString& aSessionId)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvOnLegacySessionError(const nsCString& aSessionId,
+ const uint32_t& aError,
+ const uint32_t& aSystemCode,
+ const nsCString& aMessage)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvDecrypted(const uint32_t& aStatus,
+ nsTArray<uint8_t>&& aData)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvDecoded(const CDMVideoFrame& aFrame)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvDecodeFailed(const uint32_t& aStatus)
+{
+ return IPC_OK();
+}
+
+ipc::IPCResult
+ChromiumCDMParent::RecvShutdown()
+{
+ // TODO: SendDestroy(), call Terminated.
+ return IPC_OK();
+}
+
+void
+ChromiumCDMParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+}
+
+} // namespace gmp
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/ChromiumCDMParent.h
@@ -0,0 +1,71 @@
+/* -*- 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 ChromiumCDMParent_h_
+#define ChromiumCDMParent_h_
+
+#include "GMPCrashHelper.h"
+#include "GMPCrashHelperHolder.h"
+#include "GMPMessageUtils.h"
+#include "mozilla/gmp/PChromiumCDMParent.h"
+#include "mozilla/RefPtr.h"
+
+namespace mozilla {
+namespace gmp {
+
+class GMPContentParent;
+
+class ChromiumCDMParent final
+ : public PChromiumCDMParent
+ , public GMPCrashHelperHolder
+{
+public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ChromiumCDMParent)
+
+ explicit ChromiumCDMParent(GMPContentParent* aContentParent);
+
+ // TODO: Add functions for clients to send data to CDM, and
+ // a Close() function.
+
+protected:
+ ~ChromiumCDMParent() {}
+
+ ipc::IPCResult Recv__delete__() override;
+ ipc::IPCResult RecvOnResolveNewSessionPromise(
+ const uint32_t& aPromiseId,
+ const nsCString& aSessionId) override;
+ ipc::IPCResult RecvOnResolvePromise(const uint32_t& aPromiseId) override;
+ ipc::IPCResult RecvOnRejectPromise(const uint32_t& aPromiseId,
+ const uint32_t& aError,
+ const uint32_t& aSystemCode,
+ const nsCString& aErrorMessage) override;
+ ipc::IPCResult RecvOnSessionMessage(const nsCString& aSessionId,
+ const uint32_t& aMessageType,
+ nsTArray<uint8_t>&& aMessage) override;
+ ipc::IPCResult RecvOnSessionKeysChange(
+ const nsCString& aSessionId,
+ nsTArray<CDMKeyInformation>&& aKeysInfo) override;
+ ipc::IPCResult RecvOnExpirationChange(
+ const nsCString& aSessionId,
+ const double& aSecondsSinceEpoch) override;
+ ipc::IPCResult RecvOnSessionClosed(const nsCString& aSessionId) override;
+ ipc::IPCResult RecvOnLegacySessionError(const nsCString& aSessionId,
+ const uint32_t& aError,
+ const uint32_t& aSystemCode,
+ const nsCString& aMessage) override;
+ ipc::IPCResult RecvDecrypted(const uint32_t& aStatus,
+ nsTArray<uint8_t>&& aData) override;
+ ipc::IPCResult RecvDecoded(const CDMVideoFrame& aFrame) override;
+ ipc::IPCResult RecvDecodeFailed(const uint32_t& aStatus) override;
+ ipc::IPCResult RecvShutdown() override;
+ void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ GMPContentParent* mContentParent;
+};
+
+} // namespace gmp
+} // namespace mozilla
+
+#endif // ChromiumCDMParent_h_
--- a/dom/media/gmp/GMPContentChild.cpp
+++ b/dom/media/gmp/GMPContentChild.cpp
@@ -3,16 +3,17 @@
* 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 "GMPContentChild.h"
#include "GMPChild.h"
#include "GMPDecryptorChild.h"
#include "GMPVideoDecoderChild.h"
#include "GMPVideoEncoderChild.h"
+#include "ChromiumCDMChild.h"
#include "base/task.h"
namespace mozilla {
namespace gmp {
GMPContentChild::GMPContentChild(GMPChild* aChild)
: mGMPChild(aChild)
{
@@ -88,16 +89,31 @@ GMPContentChild::AllocPGMPVideoEncoderCh
bool
GMPContentChild::DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor)
{
static_cast<GMPVideoEncoderChild*>(aActor)->Release();
return true;
}
+PChromiumCDMChild*
+GMPContentChild::AllocPChromiumCDMChild()
+{
+ ChromiumCDMChild* actor = new ChromiumCDMChild(this);
+ actor->AddRef();
+ return actor;
+}
+
+bool
+GMPContentChild::DeallocPChromiumCDMChild(PChromiumCDMChild* aActor)
+{
+ static_cast<ChromiumCDMChild*>(aActor)->Release();
+ return true;
+}
+
mozilla::ipc::IPCResult
GMPContentChild::RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor)
{
GMPDecryptorChild* child = static_cast<GMPDecryptorChild*>(aActor);
void* ptr = nullptr;
GMPErr err = mGMPChild->GetAPI(GMP_API_DECRYPTOR, nullptr, &ptr, child->DecryptorId());
if (err != GMPNoErr || !ptr) {
@@ -139,16 +155,23 @@ GMPContentChild::RecvPGMPVideoEncoderCon
return IPC_FAIL_NO_REASON(this);
}
vec->Init(static_cast<GMPVideoEncoder*>(ve));
return IPC_OK();
}
+mozilla::ipc::IPCResult
+GMPContentChild::RecvPChromiumCDMConstructor(PChromiumCDMChild* aActor)
+{
+ // TODO: Implement.
+ return IPC_OK();
+}
+
void
GMPContentChild::CloseActive()
{
// Invalidate and remove any remaining API objects.
const ManagedContainer<PGMPDecryptorChild>& decryptors =
ManagedPGMPDecryptorChild();
for (auto iter = decryptors.ConstIter(); !iter.Done(); iter.Next()) {
iter.Get()->GetKey()->SendShutdown();
@@ -160,20 +183,26 @@ GMPContentChild::CloseActive()
iter.Get()->GetKey()->SendShutdown();
}
const ManagedContainer<PGMPVideoEncoderChild>& videoEncoders =
ManagedPGMPVideoEncoderChild();
for (auto iter = videoEncoders.ConstIter(); !iter.Done(); iter.Next()) {
iter.Get()->GetKey()->SendShutdown();
}
+
+ const ManagedContainer<PChromiumCDMChild>& cdms = ManagedPChromiumCDMChild();
+ for (auto iter = cdms.ConstIter(); !iter.Done(); iter.Next()) {
+ iter.Get()->GetKey()->SendShutdown();
+ }
}
bool
GMPContentChild::IsUsed()
{
return !ManagedPGMPDecryptorChild().IsEmpty() ||
!ManagedPGMPVideoDecoderChild().IsEmpty() ||
- !ManagedPGMPVideoEncoderChild().IsEmpty();
+ !ManagedPGMPVideoEncoderChild().IsEmpty() ||
+ !ManagedPChromiumCDMChild().IsEmpty();
}
} // namespace gmp
} // namespace mozilla
--- a/dom/media/gmp/GMPContentChild.h
+++ b/dom/media/gmp/GMPContentChild.h
@@ -21,26 +21,31 @@ public:
explicit GMPContentChild(GMPChild* aChild);
virtual ~GMPContentChild();
MessageLoop* GMPMessageLoop();
mozilla::ipc::IPCResult RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor) override;
mozilla::ipc::IPCResult RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor, const uint32_t& aDecryptorId) override;
mozilla::ipc::IPCResult RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor) override;
+ mozilla::ipc::IPCResult RecvPChromiumCDMConstructor(
+ PChromiumCDMChild* aActor) override;
PGMPDecryptorChild* AllocPGMPDecryptorChild() override;
bool DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor) override;
PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild(const uint32_t& aDecryptorId) override;
bool DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor) override;
PGMPVideoEncoderChild* AllocPGMPVideoEncoderChild() override;
bool DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor) override;
+ PChromiumCDMChild* AllocPChromiumCDMChild() override;
+ bool DeallocPChromiumCDMChild(PChromiumCDMChild* aActor) override;
+
void ActorDestroy(ActorDestroyReason aWhy) override;
void ProcessingError(Result aCode, const char* aReason) override;
// GMPSharedMem
void CheckThread() override;
void CloseActive();
bool IsUsed();
--- a/dom/media/gmp/GMPContentParent.cpp
+++ b/dom/media/gmp/GMPContentParent.cpp
@@ -4,16 +4,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPContentParent.h"
#include "GMPDecryptorParent.h"
#include "GMPParent.h"
#include "GMPServiceChild.h"
#include "GMPVideoDecoderParent.h"
#include "GMPVideoEncoderParent.h"
+#include "ChromiumCDMParent.h"
#include "mozIGeckoMediaPluginService.h"
#include "mozilla/Logging.h"
#include "mozilla/Unused.h"
#include "base/task.h"
namespace mozilla {
#ifdef LOG
@@ -60,29 +61,37 @@ public:
private:
RefPtr<GMPContentParent> mToRelease;
};
void
GMPContentParent::ActorDestroy(ActorDestroyReason aWhy)
{
- MOZ_ASSERT(mDecryptors.IsEmpty() &&
- mVideoDecoders.IsEmpty() &&
- mVideoEncoders.IsEmpty());
+ MOZ_ASSERT(mDecryptors.IsEmpty() && mVideoDecoders.IsEmpty() &&
+ mVideoEncoders.IsEmpty() && mChromiumCDMs.IsEmpty());
NS_DispatchToCurrentThread(new ReleaseGMPContentParent(this));
}
void
GMPContentParent::CheckThread()
{
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
}
void
+GMPContentParent::ChromiumCDMDestroyed(ChromiumCDMParent* aDecoder)
+{
+ MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
+
+ MOZ_ALWAYS_TRUE(mChromiumCDMs.RemoveElement(aDecoder));
+ CloseIfUnused();
+}
+
+void
GMPContentParent::VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
// If the constructor fails, we'll get called before it's added
Unused << NS_WARN_IF(!mVideoDecoders.RemoveElement(aDecoder));
CloseIfUnused();
}
@@ -119,19 +128,18 @@ GMPContentParent::RemoveCloseBlocker()
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
--mCloseBlockerCount;
CloseIfUnused();
}
void
GMPContentParent::CloseIfUnused()
{
- if (mDecryptors.IsEmpty() &&
- mVideoDecoders.IsEmpty() &&
- mVideoEncoders.IsEmpty() &&
+ if (mDecryptors.IsEmpty() && mVideoDecoders.IsEmpty() &&
+ mVideoEncoders.IsEmpty() && mChromiumCDMs.IsEmpty() &&
mCloseBlockerCount == 0) {
RefPtr<GMPContentParent> toClose;
if (mParent) {
toClose = mParent->ForgetGMPContentParent();
} else {
toClose = this;
RefPtr<GeckoMediaPluginServiceChild> gmp(
GeckoMediaPluginServiceChild::GetSingleton());
@@ -175,16 +183,31 @@ GMPContentParent::GMPThread()
// to use swap() under a lock.
mps->GetThread(getter_AddRefs(mGMPThread));
MOZ_ASSERT(mGMPThread);
}
return mGMPThread;
}
+already_AddRefed<ChromiumCDMParent>
+GMPContentParent::GetChromiumCDM()
+{
+ PChromiumCDMParent* actor = SendPChromiumCDMConstructor();
+ if (!actor) {
+ return nullptr;
+ }
+ RefPtr<ChromiumCDMParent> parent = static_cast<ChromiumCDMParent*>(actor);
+
+ // TODO: Remove parent from mChromiumCDMs in ChromiumCDMParent::Destroy().
+ mChromiumCDMs.AppendElement(parent);
+
+ return parent.forget();
+}
+
nsresult
GMPContentParent::GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD,
uint32_t aDecryptorId)
{
// returned with one anonymous AddRef that locks it until Destroy
PGMPVideoDecoderParent* pvdp = SendPGMPVideoDecoderConstructor(aDecryptorId);
if (!pvdp) {
return NS_ERROR_FAILURE;
@@ -212,25 +235,41 @@ GMPContentParent::GetGMPVideoEncoder(GMP
// It's dropped by calling Close() on the interface.
NS_ADDREF(vep);
*aGMPVE = vep;
mVideoEncoders.AppendElement(vep);
return NS_OK;
}
+PChromiumCDMParent*
+GMPContentParent::AllocPChromiumCDMParent()
+{
+ ChromiumCDMParent* parent = new ChromiumCDMParent(this);
+ NS_ADDREF(parent);
+ return parent;
+}
+
PGMPVideoDecoderParent*
GMPContentParent::AllocPGMPVideoDecoderParent(const uint32_t& aDecryptorId)
{
GMPVideoDecoderParent* vdp = new GMPVideoDecoderParent(this);
NS_ADDREF(vdp);
return vdp;
}
bool
+GMPContentParent::DeallocPChromiumCDMParent(PChromiumCDMParent* aActor)
+{
+ ChromiumCDMParent* parent = static_cast<ChromiumCDMParent*>(aActor);
+ NS_RELEASE(parent);
+ return true;
+}
+
+bool
GMPContentParent::DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor)
{
GMPVideoDecoderParent* vdp = static_cast<GMPVideoDecoderParent*>(aActor);
NS_RELEASE(vdp);
return true;
}
PGMPVideoEncoderParent*
--- a/dom/media/gmp/GMPContentParent.h
+++ b/dom/media/gmp/GMPContentParent.h
@@ -12,16 +12,17 @@
namespace mozilla {
namespace gmp {
class GMPDecryptorParent;
class GMPParent;
class GMPVideoDecoderParent;
class GMPVideoEncoderParent;
+class ChromiumCDMParent;
class GMPContentParent final : public PGMPContentParent,
public GMPSharedMem
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPContentParent)
explicit GMPContentParent(GMPParent* aParent = nullptr);
@@ -31,16 +32,19 @@ public:
void VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder);
nsresult GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE);
void VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder);
nsresult GetGMPDecryptor(GMPDecryptorParent** aGMPKS);
void DecryptorDestroyed(GMPDecryptorParent* aSession);
+ already_AddRefed<ChromiumCDMParent> GetChromiumCDM();
+ void ChromiumCDMDestroyed(ChromiumCDMParent* aCDM);
+
nsIThread* GMPThread();
// GMPSharedMem
void CheckThread() override;
void SetDisplayName(const nsCString& aDisplayName)
{
mDisplayName = aDisplayName;
@@ -87,27 +91,31 @@ private:
bool DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor) override;
PGMPVideoEncoderParent* AllocPGMPVideoEncoderParent() override;
bool DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor) override;
PGMPDecryptorParent* AllocPGMPDecryptorParent() override;
bool DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor) override;
+ PChromiumCDMParent* AllocPChromiumCDMParent() override;
+ bool DeallocPChromiumCDMParent(PChromiumCDMParent* aActor) override;
+
void CloseIfUnused();
// Needed because NewRunnableMethod tried to use the class that the method
// lives on to store the receiver, but PGMPContentParent isn't refcounted.
void Close()
{
PGMPContentParent::Close();
}
nsTArray<RefPtr<GMPVideoDecoderParent>> mVideoDecoders;
nsTArray<RefPtr<GMPVideoEncoderParent>> mVideoEncoders;
nsTArray<RefPtr<GMPDecryptorParent>> mDecryptors;
+ nsTArray<RefPtr<ChromiumCDMParent>> mChromiumCDMs;
nsCOMPtr<nsIThread> mGMPThread;
RefPtr<GMPParent> mParent;
nsCString mDisplayName;
uint32_t mPluginId;
uint32_t mCloseBlockerCount = 0;
};
} // namespace gmp
--- a/dom/media/gmp/GMPTypes.ipdlh
+++ b/dom/media/gmp/GMPTypes.ipdlh
@@ -49,10 +49,53 @@ struct GMPVideoi420FrameData
uint64_t mDuration; // microseconds
};
struct GMPKeyInformation {
uint8_t[] keyId;
GMPMediaKeyStatus status;
};
+struct CDMInputBuffer {
+ uint8_t[] mData;
+ uint8_t[] mKeyId;
+ uint8_t[] mIV;
+ int64_t mTimestamp;
+ int64_t mDuration;
+ uint16_t[] mClearBytes;
+ uint32_t[] mCipherBytes;
+ bool mIsEncrypted;
+};
+
+struct CDMVideoDecoderConfig {
+ uint32_t mCodec;
+ uint32_t mProfile;
+ uint32_t mFormat;
+ int32_t mImageWidth;
+ int32_t mImageHeight;
+ uint8_t[] mExtraData;
+};
+
+struct CDMKeyInformation {
+ uint8_t[] mKeyId;
+ uint32_t mStatus;
+ uint32_t mSystemCode;
+};
+
+struct CDMVideoPlane {
+ uint32_t mPlaneOffset;
+ uint32_t mStride;
+};
+
+struct CDMVideoFrame {
+ uint32_t mFormat;
+ int32_t mImageWidth;
+ int32_t mImageHeight;
+ uint8_t[] mData;
+ CDMVideoPlane mYPlane;
+ CDMVideoPlane mUPlane;
+ CDMVideoPlane mVPlane;
+ int64_t mTimestamp;
+ int64_t mDuration;
+};
+
}
}
--- a/dom/media/gmp/GMPVideoEncoderParent.cpp
+++ b/dom/media/gmp/GMPVideoEncoderParent.cpp
@@ -12,16 +12,17 @@
#include "nsAutoRef.h"
#include "GMPContentParent.h"
#include "mozilla/gmp/GMPTypes.h"
#include "nsThread.h"
#include "nsThreadUtils.h"
#include "runnable_utils.h"
#include "GMPUtils.h"
#include "mozilla/SystemGroup.h"
+#include "GMPCrashHelper.h"
namespace mozilla {
#ifdef LOG
#undef LOG
#endif
extern LogModule* GetGMPLog();
new file mode 100644
--- /dev/null
+++ b/dom/media/gmp/PChromiumCDM.ipdl
@@ -0,0 +1,92 @@
+/* -*- 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 protocol PGMPContent;
+include GMPTypes;
+
+namespace mozilla {
+namespace gmp {
+
+async protocol PChromiumCDM
+{
+ manager PGMPContent;
+child:
+
+ // cdm::ContentDecryptionModule8
+ async Init(bool aAllowDistinctiveIdentifier,
+ bool aAllowPersistentState);
+
+ async SetServerCertificate(uint32_t aPromiseId,
+ uint8_t[] aServerCert);
+
+ async CreateSessionAndGenerateRequest(uint32_t aPromiseId,
+ uint32_t aSessionType,
+ uint32_t aInitDataType,
+ uint8_t[] aInitData);
+
+ async UpdateSession(uint32_t aPromiseId,
+ nsCString aSessionId,
+ uint8_t[] aResponse);
+
+ async CloseSession(uint32_t aPromiseId,
+ nsCString aSessionId);
+
+ async RemoveSession(uint32_t aPromiseId,
+ nsCString aSessionId);
+
+ async Decrypt(CDMInputBuffer aBuffer);
+
+ async InitializeVideoDecoder(CDMVideoDecoderConfig aConfig);
+
+ async DeinitializeVideoDecoder();
+
+ async ResetVideoDecoder();
+
+ async DecryptAndDecodeFrame(CDMInputBuffer aBuffer);
+
+ async Destroy();
+
+parent:
+ async __delete__();
+
+ // cdm::Host8
+ async OnResolveNewSessionPromise(uint32_t aPromiseId, nsCString aSessionId);
+
+ async OnResolvePromise(uint32_t aPromiseId);
+
+ async OnRejectPromise(uint32_t aPromiseId,
+ uint32_t aError,
+ uint32_t aSystemCode,
+ nsCString aErrorMessage);
+
+ async OnSessionMessage(nsCString aSessionId,
+ uint32_t aMessageType,
+ uint8_t[] aMessage);
+
+ async OnSessionKeysChange(nsCString aSessionId,
+ CDMKeyInformation[] aKeysInfo);
+
+ async OnExpirationChange(nsCString aSessionId,
+ double aSecondsSinceEpoch);
+
+ async OnSessionClosed(nsCString aSessionId);
+
+ async OnLegacySessionError(nsCString aSessionId,
+ uint32_t aError,
+ uint32_t aSystemCode,
+ nsCString aMessage);
+
+ // Return values of cdm::ContentDecryptionModule8::Decrypt
+ async Decrypted(uint32_t aStatus, uint8_t[] aData);
+
+ // Return values of cdm::ContentDecryptionModule8::DecryptAndDecodeFrame
+ async Decoded(CDMVideoFrame aFrame);
+ async DecodeFailed(uint32_t aStatus);
+
+ async Shutdown();
+};
+
+} // namespace gmp
+} // namespace mozilla
--- a/dom/media/gmp/PGMPContent.ipdl
+++ b/dom/media/gmp/PGMPContent.ipdl
@@ -1,26 +1,29 @@
/* -*- 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 protocol PGMPVideoDecoder;
include protocol PGMPVideoEncoder;
include protocol PGMPDecryptor;
+include protocol PChromiumCDM;
namespace mozilla {
namespace gmp {
intr protocol PGMPContent
{
manages PGMPDecryptor;
manages PGMPVideoDecoder;
manages PGMPVideoEncoder;
+ manages PChromiumCDM;
child:
async PGMPDecryptor();
async PGMPVideoDecoder(uint32_t aDecryptorId);
async PGMPVideoEncoder();
+ async PChromiumCDM();
};
} // namespace gmp
} // namespace mozilla
--- a/dom/media/gmp/moz.build
+++ b/dom/media/gmp/moz.build
@@ -63,16 +63,18 @@ EXPORTS += [
'GMPVideoEncoderProxy.h',
'GMPVideoHost.h',
'GMPVideoi420FrameImpl.h',
'GMPVideoPlaneImpl.h',
'widevine-adapter/content_decryption_module.h',
]
UNIFIED_SOURCES += [
+ 'ChromiumCDMChild.cpp',
+ 'ChromiumCDMParent.cpp',
'DecryptJob.cpp',
'GMPCDMCallbackProxy.cpp',
'GMPCDMProxy.cpp',
'GMPChild.cpp',
'GMPContentChild.cpp',
'GMPContentParent.cpp',
'GMPCrashHelper.cpp',
'GMPCrashHelperHolder.cpp',
@@ -106,16 +108,17 @@ UNIFIED_SOURCES += [
]
DIRS += [
'widevine-adapter',
]
IPDL_SOURCES += [
'GMPTypes.ipdlh',
+ 'PChromiumCDM.ipdl',
'PGMP.ipdl',
'PGMPContent.ipdl',
'PGMPDecryptor.ipdl',
'PGMPService.ipdl',
'PGMPStorage.ipdl',
'PGMPTimer.ipdl',
'PGMPVideoDecoder.ipdl',
'PGMPVideoEncoder.ipdl',