Bug 1057908 - GeckoMediaPluginService needs to be proxied from Content processes to parent process. Part 3 - split the GMP IPDL actors in 2 parts (and use opens to open the second in non-e10s). r=billm.

This commit is contained in:
Peter Van der Beken 2015-02-10 11:48:42 +01:00
parent ace406a462
commit 3af38cd4ea
35 changed files with 1052 additions and 565 deletions

View File

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPAudioDecoderChild.h"
#include "GMPChild.h"
#include "GMPContentChild.h"
#include "GMPAudioHost.h"
#include "mozilla/unused.h"
#include <stdio.h>
@ -12,7 +12,7 @@
namespace mozilla {
namespace gmp {
GMPAudioDecoderChild::GMPAudioDecoderChild(GMPChild* aPlugin)
GMPAudioDecoderChild::GMPAudioDecoderChild(GMPContentChild* aPlugin)
: mPlugin(aPlugin)
, mAudioDecoder(nullptr)
{

View File

@ -13,13 +13,13 @@
namespace mozilla {
namespace gmp {
class GMPChild;
class GMPContentChild;
class GMPAudioDecoderChild : public PGMPAudioDecoderChild,
public GMPAudioDecoderCallback
{
public:
explicit GMPAudioDecoderChild(GMPChild* aPlugin);
explicit GMPAudioDecoderChild(GMPContentChild* aPlugin);
virtual ~GMPAudioDecoderChild();
void Init(GMPAudioDecoder* aDecoder);
@ -40,7 +40,7 @@ private:
virtual bool RecvDrain() override;
virtual bool RecvDecodingComplete() override;
GMPChild* mPlugin;
GMPContentChild* mPlugin;
GMPAudioDecoder* mAudioDecoder;
GMPAudioHostImpl mAudioHost;
};

View File

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPAudioDecoderParent.h"
#include "GMPParent.h"
#include "GMPContentParent.h"
#include <stdio.h>
#include "mozilla/unused.h"
#include "GMPMessageUtils.h"
@ -29,7 +29,7 @@ extern PRLogModuleInfo* GetGMPLog();
namespace gmp {
GMPAudioDecoderParent::GMPAudioDecoderParent(GMPParent* aPlugin)
GMPAudioDecoderParent::GMPAudioDecoderParent(GMPContentParent* aPlugin)
: mIsOpen(false)
, mShuttingDown(false)
, mPlugin(aPlugin)
@ -263,6 +263,13 @@ GMPAudioDecoderParent::RecvError(const GMPErr& aError)
return true;
}
bool
GMPAudioDecoderParent::RecvShutdown()
{
Shutdown();
return true;
}
bool
GMPAudioDecoderParent::Recv__delete__()
{

View File

@ -16,7 +16,7 @@
namespace mozilla {
namespace gmp {
class GMPParent;
class GMPContentParent;
class GMPAudioDecoderParent final : public GMPAudioDecoderProxy
, public PGMPAudioDecoderParent
@ -24,7 +24,7 @@ class GMPAudioDecoderParent final : public GMPAudioDecoderProxy
public:
NS_INLINE_DECL_REFCOUNTING(GMPAudioDecoderParent)
explicit GMPAudioDecoderParent(GMPParent *aPlugin);
explicit GMPAudioDecoderParent(GMPContentParent *aPlugin);
nsresult Shutdown();
@ -50,11 +50,12 @@ private:
virtual bool RecvDrainComplete() override;
virtual bool RecvResetComplete() override;
virtual bool RecvError(const GMPErr& aError) override;
virtual bool RecvShutdown() override;
virtual bool Recv__delete__() override;
bool mIsOpen;
bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
nsRefPtr<GMPContentParent> mPlugin;
GMPAudioDecoderCallbackProxy* mCallback;
};

View File

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPChild.h"
#include "GMPContentChild.h"
#include "GMPProcessChild.h"
#include "GMPLoader.h"
#include "GMPVideoDecoderChild.h"
@ -256,12 +257,6 @@ GMPChild::StartMacSandbox()
}
#endif // XP_MACOSX && MOZ_GMP_SANDBOX
void
GMPChild::CheckThread()
{
MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current());
}
bool
GMPChild::Init(const std::string& aPluginPath,
const std::string& aVoucherPath,
@ -467,6 +462,11 @@ GMPChild::ActorDestroy(ActorDestroyReason aWhy)
{
LOGD("%s reason=%d", __FUNCTION__, aWhy);
for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
MOZ_ASSERT_IF(aWhy == NormalShutdown, !mGMPContentChildren[i - 1]->IsUsed());
mGMPContentChildren[i - 1]->Close();
}
if (mGMPLoader) {
mGMPLoader->Shutdown();
}
@ -501,19 +501,6 @@ GMPChild::ProcessingError(Result aCode, const char* aReason)
}
}
PGMPAudioDecoderChild*
GMPChild::AllocPGMPAudioDecoderChild()
{
return new GMPAudioDecoderChild(this);
}
bool
GMPChild::DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor)
{
delete aActor;
return true;
}
mozilla::dom::PCrashReporterChild*
GMPChild::AllocPCrashReporterChild(const NativeThreadId& aThread)
{
@ -527,120 +514,6 @@ GMPChild::DeallocPCrashReporterChild(PCrashReporterChild* aCrashReporter)
return true;
}
PGMPVideoDecoderChild*
GMPChild::AllocPGMPVideoDecoderChild()
{
return new GMPVideoDecoderChild(this);
}
bool
GMPChild::DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor)
{
delete aActor;
return true;
}
PGMPDecryptorChild*
GMPChild::AllocPGMPDecryptorChild()
{
GMPDecryptorChild* actor = new GMPDecryptorChild(this, mPluginVoucher, mSandboxVoucher);
actor->AddRef();
return actor;
}
bool
GMPChild::DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor)
{
static_cast<GMPDecryptorChild*>(aActor)->Release();
return true;
}
bool
GMPChild::RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor)
{
auto vdc = static_cast<GMPAudioDecoderChild*>(aActor);
void* vd = nullptr;
GMPErr err = GetAPI(GMP_API_AUDIO_DECODER, &vdc->Host(), &vd);
if (err != GMPNoErr || !vd) {
return false;
}
vdc->Init(static_cast<GMPAudioDecoder*>(vd));
return true;
}
PGMPVideoEncoderChild*
GMPChild::AllocPGMPVideoEncoderChild()
{
return new GMPVideoEncoderChild(this);
}
bool
GMPChild::DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor)
{
delete aActor;
return true;
}
bool
GMPChild::RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor)
{
auto vdc = static_cast<GMPVideoDecoderChild*>(aActor);
void* vd = nullptr;
GMPErr err = GetAPI(GMP_API_VIDEO_DECODER, &vdc->Host(), &vd);
if (err != GMPNoErr || !vd) {
NS_WARNING("GMPGetAPI call failed trying to construct decoder.");
return false;
}
vdc->Init(static_cast<GMPVideoDecoder*>(vd));
return true;
}
bool
GMPChild::RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor)
{
auto vec = static_cast<GMPVideoEncoderChild*>(aActor);
void* ve = nullptr;
GMPErr err = GetAPI(GMP_API_VIDEO_ENCODER, &vec->Host(), &ve);
if (err != GMPNoErr || !ve) {
NS_WARNING("GMPGetAPI call failed trying to construct encoder.");
return false;
}
vec->Init(static_cast<GMPVideoEncoder*>(ve));
return true;
}
bool
GMPChild::RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor)
{
GMPDecryptorChild* child = static_cast<GMPDecryptorChild*>(aActor);
GMPDecryptorHost* host = static_cast<GMPDecryptorHost*>(child);
void* session = nullptr;
GMPErr err = GetAPI(GMP_API_DECRYPTOR, host, &session);
if (err != GMPNoErr && !session) {
// XXX to remove in bug 1147692
err = GetAPI(GMP_API_DECRYPTOR_COMPAT, host, &session);
}
if (err != GMPNoErr || !session) {
return false;
}
child->Init(static_cast<GMPDecryptor*>(session));
return true;
}
PGMPTimerChild*
GMPChild::AllocPGMPTimerChild()
{
@ -715,6 +588,15 @@ GMPChild::RecvBeginAsyncShutdown()
return true;
}
bool
GMPChild::RecvCloseActive()
{
for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
mGMPContentChildren[i - 1]->CloseActive();
}
return true;
}
void
GMPChild::ShutdownComplete()
{
@ -802,6 +684,32 @@ GMPChild::PreLoadSandboxVoucher()
}
}
PGMPContentChild*
GMPChild::AllocPGMPContentChild(Transport* aTransport,
ProcessId aOtherPid)
{
GMPContentChild* child =
mGMPContentChildren.AppendElement(new GMPContentChild(this))->get();
child->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide);
return child;
}
void
GMPChild::GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild)
{
for (uint32_t i = mGMPContentChildren.Length(); i > 0; i--) {
UniquePtr<GMPContentChild>& toDestroy = mGMPContentChildren[i - 1];
if (toDestroy.get() == aGMPContentChild) {
SendPGMPContentChildDestroyed();
MessageLoop::current()->PostTask(FROM_HERE,
new DeleteTask<GMPContentChild>(toDestroy.release()));
mGMPContentChildren.RemoveElementAt(i - 1);
break;
}
}
}
} // namespace gmp
} // namespace mozilla

View File

@ -7,7 +7,6 @@
#define GMPChild_h_
#include "mozilla/gmp/PGMPChild.h"
#include "GMPSharedMemManager.h"
#include "GMPTimerChild.h"
#include "GMPStorageChild.h"
#include "GMPLoader.h"
@ -18,8 +17,9 @@
namespace mozilla {
namespace gmp {
class GMPContentChild;
class GMPChild : public PGMPChild
, public GMPSharedMem
, public GMPAsyncShutdownHost
{
public:
@ -40,9 +40,6 @@ public:
GMPTimerChild* GetGMPTimers();
GMPStorageChild* GetGMPStorage();
// GMPSharedMem
virtual void CheckThread() override;
// GMPAsyncShutdownHost
void ShutdownComplete() override;
@ -51,6 +48,7 @@ public:
#endif
private:
friend class GMPContentChild;
bool PreLoadPluginVoucher(const std::string& aPluginPath);
void PreLoadSandboxVoucher();
@ -63,36 +61,27 @@ private:
virtual PCrashReporterChild* AllocPCrashReporterChild(const NativeThreadId& aThread) override;
virtual bool DeallocPCrashReporterChild(PCrashReporterChild*) override;
virtual PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild() override;
virtual bool DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor) override;
virtual bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor) override;
virtual PGMPVideoEncoderChild* AllocPGMPVideoEncoderChild() override;
virtual bool DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor) override;
virtual bool RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor) override;
virtual PGMPDecryptorChild* AllocPGMPDecryptorChild() override;
virtual bool DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor) override;
virtual bool RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor) override;
virtual PGMPAudioDecoderChild* AllocPGMPAudioDecoderChild() override;
virtual bool DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor) override;
virtual bool RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor) override;
virtual PGMPTimerChild* AllocPGMPTimerChild() override;
virtual bool DeallocPGMPTimerChild(PGMPTimerChild* aActor) override;
virtual PGMPStorageChild* AllocPGMPStorageChild() override;
virtual bool DeallocPGMPStorageChild(PGMPStorageChild* aActor) override;
virtual PGMPContentChild* AllocPGMPContentChild(Transport* aTransport,
ProcessId aOtherPid) override;
void GMPContentChildActorDestroy(GMPContentChild* aGMPContentChild);
virtual bool RecvCrashPluginNow() override;
virtual bool RecvBeginAsyncShutdown() override;
virtual bool RecvCloseActive() override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual void ProcessingError(Result aCode, const char* aReason) override;
GMPErr GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI);
nsTArray<UniquePtr<GMPContentChild>> mGMPContentChildren;
GMPAsyncShutdown* mAsyncShutdown;
nsRefPtr<GMPTimerChild> mTimerChild;
nsRefPtr<GMPStorageChild> mStorage;

View File

@ -0,0 +1,215 @@
/* -*- 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 "GMPContentChild.h"
namespace mozilla {
namespace gmp {
GMPContentChild::GMPContentChild(GMPChild* aChild)
: mGMPChild(aChild)
{
MOZ_COUNT_CTOR(GMPContentChild);
}
GMPContentChild::~GMPContentChild()
{
MOZ_COUNT_DTOR(GMPContentChild);
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new DeleteTask<Transport>(GetTransport()));
}
MessageLoop*
GMPContentChild::GMPMessageLoop()
{
return mGMPChild->GMPMessageLoop();
}
void
GMPContentChild::CheckThread()
{
MOZ_ASSERT(mGMPChild->mGMPMessageLoop == MessageLoop::current());
}
void
GMPContentChild::ActorDestroy(ActorDestroyReason aWhy)
{
mGMPChild->GMPContentChildActorDestroy(this);
}
void
GMPContentChild::ProcessingError(Result aCode, const char* aReason)
{
mGMPChild->ProcessingError(aCode, aReason);
}
PGMPAudioDecoderChild*
GMPContentChild::AllocPGMPAudioDecoderChild()
{
return new GMPAudioDecoderChild(this);
}
bool
GMPContentChild::DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor)
{
delete aActor;
return true;
}
PGMPDecryptorChild*
GMPContentChild::AllocPGMPDecryptorChild()
{
GMPDecryptorChild* actor = new GMPDecryptorChild(this,
mGMPChild->mPluginVoucher,
mGMPChild->mSandboxVoucher);
actor->AddRef();
return actor;
}
bool
GMPContentChild::DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor)
{
static_cast<GMPDecryptorChild*>(aActor)->Release();
return true;
}
PGMPVideoDecoderChild*
GMPContentChild::AllocPGMPVideoDecoderChild()
{
return new GMPVideoDecoderChild(this);
}
bool
GMPContentChild::DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor)
{
delete aActor;
return true;
}
PGMPVideoEncoderChild*
GMPContentChild::AllocPGMPVideoEncoderChild()
{
return new GMPVideoEncoderChild(this);
}
bool
GMPContentChild::DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor)
{
delete aActor;
return true;
}
bool
GMPContentChild::RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor)
{
GMPDecryptorChild* child = static_cast<GMPDecryptorChild*>(aActor);
GMPDecryptorHost* host = static_cast<GMPDecryptorHost*>(child);
void* session = nullptr;
GMPErr err = mGMPChild->GetAPI(GMP_API_DECRYPTOR, host, &session);
if (err != GMPNoErr && !session) {
// XXX to remove in bug 1147692
err = mGMPChild->GetAPI(GMP_API_DECRYPTOR_COMPAT, host, &session);
}
if (err != GMPNoErr || !session) {
return false;
}
child->Init(static_cast<GMPDecryptor*>(session));
return true;
}
bool
GMPContentChild::RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor)
{
auto vdc = static_cast<GMPAudioDecoderChild*>(aActor);
void* vd = nullptr;
GMPErr err = mGMPChild->GetAPI(GMP_API_AUDIO_DECODER, &vdc->Host(), &vd);
if (err != GMPNoErr || !vd) {
return false;
}
vdc->Init(static_cast<GMPAudioDecoder*>(vd));
return true;
}
bool
GMPContentChild::RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor)
{
auto vdc = static_cast<GMPVideoDecoderChild*>(aActor);
void* vd = nullptr;
GMPErr err = mGMPChild->GetAPI(GMP_API_VIDEO_DECODER, &vdc->Host(), &vd);
if (err != GMPNoErr || !vd) {
NS_WARNING("GMPGetAPI call failed trying to construct decoder.");
return false;
}
vdc->Init(static_cast<GMPVideoDecoder*>(vd));
return true;
}
bool
GMPContentChild::RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor)
{
auto vec = static_cast<GMPVideoEncoderChild*>(aActor);
void* ve = nullptr;
GMPErr err = mGMPChild->GetAPI(GMP_API_VIDEO_ENCODER, &vec->Host(), &ve);
if (err != GMPNoErr || !ve) {
NS_WARNING("GMPGetAPI call failed trying to construct encoder.");
return false;
}
vec->Init(static_cast<GMPVideoEncoder*>(ve));
return true;
}
void
GMPContentChild::CloseActive()
{
// Invalidate and remove any remaining API objects.
const nsTArray<PGMPAudioDecoderChild*>& audioDecoders =
ManagedPGMPAudioDecoderChild();
for (uint32_t i = audioDecoders.Length(); i > 0; i--) {
audioDecoders[i - 1]->SendShutdown();
}
const nsTArray<PGMPDecryptorChild*>& decryptors =
ManagedPGMPDecryptorChild();
for (uint32_t i = decryptors.Length(); i > 0; i--) {
decryptors[i - 1]->SendShutdown();
}
const nsTArray<PGMPVideoDecoderChild*>& videoDecoders =
ManagedPGMPVideoDecoderChild();
for (uint32_t i = videoDecoders.Length(); i > 0; i--) {
videoDecoders[i - 1]->SendShutdown();
}
const nsTArray<PGMPVideoEncoderChild*>& videoEncoders =
ManagedPGMPVideoEncoderChild();
for (uint32_t i = videoEncoders.Length(); i > 0; i--) {
videoEncoders[i - 1]->SendShutdown();
}
}
bool
GMPContentChild::IsUsed()
{
return !ManagedPGMPAudioDecoderChild().IsEmpty() ||
!ManagedPGMPDecryptorChild().IsEmpty() ||
!ManagedPGMPVideoDecoderChild().IsEmpty() ||
!ManagedPGMPVideoEncoderChild().IsEmpty();
}
} // namespace gmp
} // namespace mozilla

View File

@ -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 GMPContentChild_h_
#define GMPContentChild_h_
#include "mozilla/gmp/PGMPContentChild.h"
#include "GMPSharedMemManager.h"
namespace mozilla {
namespace gmp {
class GMPChild;
class GMPContentChild : public PGMPContentChild
, public GMPSharedMem
{
public:
explicit GMPContentChild(GMPChild* aChild);
virtual ~GMPContentChild();
MessageLoop* GMPMessageLoop();
virtual bool RecvPGMPAudioDecoderConstructor(PGMPAudioDecoderChild* aActor) override;
virtual bool RecvPGMPDecryptorConstructor(PGMPDecryptorChild* aActor) override;
virtual bool RecvPGMPVideoDecoderConstructor(PGMPVideoDecoderChild* aActor) override;
virtual bool RecvPGMPVideoEncoderConstructor(PGMPVideoEncoderChild* aActor) override;
virtual PGMPAudioDecoderChild* AllocPGMPAudioDecoderChild() override;
virtual bool DeallocPGMPAudioDecoderChild(PGMPAudioDecoderChild* aActor) override;
virtual PGMPDecryptorChild* AllocPGMPDecryptorChild() override;
virtual bool DeallocPGMPDecryptorChild(PGMPDecryptorChild* aActor) override;
virtual PGMPVideoDecoderChild* AllocPGMPVideoDecoderChild() override;
virtual bool DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor) override;
virtual PGMPVideoEncoderChild* AllocPGMPVideoEncoderChild() override;
virtual bool DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual void ProcessingError(Result aCode, const char* aReason) override;
// GMPSharedMem
virtual void CheckThread() override;
void CloseActive();
bool IsUsed();
GMPChild* mGMPChild;
};
} // namespace gmp
} // namespace mozilla
#endif // GMPContentChild_h_

View File

@ -0,0 +1,293 @@
/* -*- 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 "GMPContentParent.h"
#include "GMPAudioDecoderParent.h"
#include "GMPDecryptorParent.h"
#include "GMPParent.h"
#include "GMPVideoDecoderParent.h"
#include "GMPVideoEncoderParent.h"
#include "mozIGeckoMediaPluginService.h"
#include "prlog.h"
namespace mozilla {
#ifdef LOG
#undef LOG
#endif
#ifdef PR_LOGGING
extern PRLogModuleInfo* GetGMPLog();
#define LOGD(msg) PR_LOG(GetGMPLog(), PR_LOG_DEBUG, msg)
#define LOG(level, msg) PR_LOG(GetGMPLog(), (level), msg)
#else
#define LOGD(msg)
#define LOG(level, msg)
#endif
#ifdef __CLASS__
#undef __CLASS__
#endif
#define __CLASS__ "GMPContentParent"
namespace gmp {
GMPContentParent::GMPContentParent(GMPParent* aParent)
: mParent(aParent)
{
if (mParent) {
SetDisplayName(mParent->GetDisplayName());
SetPluginId(mParent->GetPluginId());
}
}
GMPContentParent::~GMPContentParent()
{
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new DeleteTask<Transport>(GetTransport()));
}
class ReleaseGMPContentParent : public nsRunnable
{
public:
explicit ReleaseGMPContentParent(GMPContentParent* aToRelease)
: mToRelease(aToRelease)
{
}
NS_IMETHOD Run()
{
return NS_OK;
}
private:
nsRefPtr<GMPContentParent> mToRelease;
};
void
GMPContentParent::ActorDestroy(ActorDestroyReason aWhy)
{
MOZ_ASSERT(mAudioDecoders.IsEmpty() &&
mDecryptors.IsEmpty() &&
mVideoDecoders.IsEmpty() &&
mVideoEncoders.IsEmpty());
NS_DispatchToCurrentThread(new ReleaseGMPContentParent(this));
}
void
GMPContentParent::CheckThread()
{
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
}
void
GMPContentParent::AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
MOZ_ALWAYS_TRUE(mAudioDecoders.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();
}
void
GMPContentParent::VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
// If the constructor fails, we'll get called before it's added
unused << NS_WARN_IF(!mVideoEncoders.RemoveElement(aEncoder));
CloseIfUnused();
}
void
GMPContentParent::DecryptorDestroyed(GMPDecryptorParent* aSession)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
MOZ_ALWAYS_TRUE(mDecryptors.RemoveElement(aSession));
CloseIfUnused();
}
void
GMPContentParent::CloseIfUnused()
{
if (mAudioDecoders.IsEmpty() &&
mDecryptors.IsEmpty() &&
mVideoDecoders.IsEmpty() &&
mVideoEncoders.IsEmpty()) {
nsRefPtr<GMPContentParent> toClose(mParent->ForgetGMPContentParent());
NS_DispatchToCurrentThread(NS_NewRunnableMethod(toClose,
&GMPContentParent::Close));
}
}
nsresult
GMPContentParent::GetGMPDecryptor(GMPDecryptorParent** aGMPDP)
{
PGMPDecryptorParent* pdp = SendPGMPDecryptorConstructor();
if (!pdp) {
return NS_ERROR_FAILURE;
}
GMPDecryptorParent* dp = static_cast<GMPDecryptorParent*>(pdp);
// This addref corresponds to the Proxy pointer the consumer is returned.
// It's dropped by calling Close() on the interface.
NS_ADDREF(dp);
mDecryptors.AppendElement(dp);
*aGMPDP = dp;
return NS_OK;
}
nsIThread*
GMPContentParent::GMPThread()
{
if (!mGMPThread) {
nsCOMPtr<mozIGeckoMediaPluginService> mps = do_GetService("@mozilla.org/gecko-media-plugin-service;1");
MOZ_ASSERT(mps);
if (!mps) {
return nullptr;
}
// Not really safe if we just grab to the mGMPThread, as we don't know
// what thread we're running on and other threads may be trying to
// access this without locks! However, debug only, and primary failure
// mode outside of compiler-helped TSAN is a leak. But better would be
// to use swap() under a lock.
mps->GetThread(getter_AddRefs(mGMPThread));
MOZ_ASSERT(mGMPThread);
}
return mGMPThread;
}
nsresult
GMPContentParent::GetGMPAudioDecoder(GMPAudioDecoderParent** aGMPAD)
{
PGMPAudioDecoderParent* pvap = SendPGMPAudioDecoderConstructor();
if (!pvap) {
return NS_ERROR_FAILURE;
}
GMPAudioDecoderParent* vap = static_cast<GMPAudioDecoderParent*>(pvap);
// This addref corresponds to the Proxy pointer the consumer is returned.
// It's dropped by calling Close() on the interface.
NS_ADDREF(vap);
*aGMPAD = vap;
mAudioDecoders.AppendElement(vap);
return NS_OK;
}
nsresult
GMPContentParent::GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD)
{
// returned with one anonymous AddRef that locks it until Destroy
PGMPVideoDecoderParent* pvdp = SendPGMPVideoDecoderConstructor();
if (!pvdp) {
return NS_ERROR_FAILURE;
}
GMPVideoDecoderParent *vdp = static_cast<GMPVideoDecoderParent*>(pvdp);
// This addref corresponds to the Proxy pointer the consumer is returned.
// It's dropped by calling Close() on the interface.
NS_ADDREF(vdp);
*aGMPVD = vdp;
mVideoDecoders.AppendElement(vdp);
return NS_OK;
}
nsresult
GMPContentParent::GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE)
{
// returned with one anonymous AddRef that locks it until Destroy
PGMPVideoEncoderParent* pvep = SendPGMPVideoEncoderConstructor();
if (!pvep) {
return NS_ERROR_FAILURE;
}
GMPVideoEncoderParent *vep = static_cast<GMPVideoEncoderParent*>(pvep);
// This addref corresponds to the Proxy pointer the consumer is returned.
// It's dropped by calling Close() on the interface.
NS_ADDREF(vep);
*aGMPVE = vep;
mVideoEncoders.AppendElement(vep);
return NS_OK;
}
PGMPVideoDecoderParent*
GMPContentParent::AllocPGMPVideoDecoderParent()
{
GMPVideoDecoderParent* vdp = new GMPVideoDecoderParent(this);
NS_ADDREF(vdp);
return vdp;
}
bool
GMPContentParent::DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor)
{
GMPVideoDecoderParent* vdp = static_cast<GMPVideoDecoderParent*>(aActor);
NS_RELEASE(vdp);
return true;
}
PGMPVideoEncoderParent*
GMPContentParent::AllocPGMPVideoEncoderParent()
{
GMPVideoEncoderParent* vep = new GMPVideoEncoderParent(this);
NS_ADDREF(vep);
return vep;
}
bool
GMPContentParent::DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor)
{
GMPVideoEncoderParent* vep = static_cast<GMPVideoEncoderParent*>(aActor);
NS_RELEASE(vep);
return true;
}
PGMPDecryptorParent*
GMPContentParent::AllocPGMPDecryptorParent()
{
GMPDecryptorParent* ksp = new GMPDecryptorParent(this);
NS_ADDREF(ksp);
return ksp;
}
bool
GMPContentParent::DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor)
{
GMPDecryptorParent* ksp = static_cast<GMPDecryptorParent*>(aActor);
NS_RELEASE(ksp);
return true;
}
PGMPAudioDecoderParent*
GMPContentParent::AllocPGMPAudioDecoderParent()
{
GMPAudioDecoderParent* vdp = new GMPAudioDecoderParent(this);
NS_ADDREF(vdp);
return vdp;
}
bool
GMPContentParent::DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor)
{
GMPAudioDecoderParent* vdp = static_cast<GMPAudioDecoderParent*>(aActor);
NS_RELEASE(vdp);
return true;
}
} // namespace gmp
} // namespace mozilla

View File

@ -0,0 +1,105 @@
/* -*- 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 GMPContentParent_h_
#define GMPContentParent_h_
#include "mozilla/gmp/PGMPContentParent.h"
#include "nsISupportsImpl.h"
class nsITimer;
namespace mozilla {
namespace gmp {
class GeckoMediaPluginService;
class GMPAudioDecoderParent;
class GMPCapability;
class GMPDecryptorParent;
class GMPParent;
class GMPVideoDecoderParent;
class GMPVideoEncoderParent;
class GMPContentParent final : public PGMPContentParent,
public GMPSharedMem
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPContentParent)
explicit GMPContentParent(GMPParent* aParent);
nsresult GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD);
void VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder);
nsresult GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE);
void VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder);
nsresult GetGMPDecryptor(GMPDecryptorParent** aGMPKS);
void DecryptorDestroyed(GMPDecryptorParent* aSession);
nsresult GetGMPAudioDecoder(GMPAudioDecoderParent** aGMPAD);
void AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder);
nsIThread* GMPThread();
// GMPSharedMem
virtual void CheckThread() override;
void SetDisplayName(const nsCString& aDisplayName)
{
mDisplayName = aDisplayName;
}
const nsCString& GetDisplayName()
{
return mDisplayName;
}
void SetPluginId(const nsCString& aPluginId)
{
mPluginId = aPluginId;
}
const nsCString& GetPluginId()
{
return mPluginId;
}
private:
~GMPContentParent();
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual PGMPVideoDecoderParent* AllocPGMPVideoDecoderParent() override;
virtual bool DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor) override;
virtual PGMPVideoEncoderParent* AllocPGMPVideoEncoderParent() override;
virtual bool DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor) override;
virtual PGMPDecryptorParent* AllocPGMPDecryptorParent() override;
virtual bool DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor) override;
virtual PGMPAudioDecoderParent* AllocPGMPAudioDecoderParent() override;
virtual bool DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor) override;
void CloseIfUnused();
// Needed because NS_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<nsRefPtr<GMPVideoDecoderParent>> mVideoDecoders;
nsTArray<nsRefPtr<GMPVideoEncoderParent>> mVideoEncoders;
nsTArray<nsRefPtr<GMPDecryptorParent>> mDecryptors;
nsTArray<nsRefPtr<GMPAudioDecoderParent>> mAudioDecoders;
nsCOMPtr<nsIThread> mGMPThread;
nsRefPtr<GMPParent> mParent;
nsCString mDisplayName;
nsCString mPluginId;
};
} // namespace gmp
} // namespace mozilla
#endif // GMPParent_h_

View File

@ -18,7 +18,7 @@
namespace mozilla {
namespace gmp {
GMPDecryptorChild::GMPDecryptorChild(GMPChild* aPlugin,
GMPDecryptorChild::GMPDecryptorChild(GMPContentChild* aPlugin,
const nsTArray<uint8_t>& aPluginVoucher,
const nsTArray<uint8_t>& aSandboxVoucher)
: mSession(nullptr)

View File

@ -15,7 +15,7 @@
namespace mozilla {
namespace gmp {
class GMPChild;
class GMPContentChild;
class GMPDecryptorChild : public GMPDecryptorCallback
, public GMPDecryptorHost
@ -24,7 +24,7 @@ class GMPDecryptorChild : public GMPDecryptorCallback
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPDecryptorChild);
explicit GMPDecryptorChild(GMPChild* aPlugin,
explicit GMPDecryptorChild(GMPContentChild* aPlugin,
const nsTArray<uint8_t>& aPluginVoucher,
const nsTArray<uint8_t>& aSandboxVoucher);
@ -123,7 +123,7 @@ private:
// GMP's GMPDecryptor implementation.
// Only call into this on the (GMP process) main thread.
GMPDecryptor* mSession;
GMPChild* mPlugin;
GMPContentChild* mPlugin;
// Reference to the vouchers owned by the GMPChild.
const nsTArray<uint8_t>& mPluginVoucher;

View File

@ -4,14 +4,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPDecryptorParent.h"
#include "GMPParent.h"
#include "GMPContentParent.h"
#include "mp4_demuxer/DecoderData.h"
#include "mozilla/unused.h"
namespace mozilla {
namespace gmp {
GMPDecryptorParent::GMPDecryptorParent(GMPParent* aPlugin)
GMPDecryptorParent::GMPDecryptorParent(GMPContentParent* aPlugin)
: mIsOpen(false)
, mShuttingDown(false)
, mPlugin(aPlugin)
@ -307,6 +307,13 @@ GMPDecryptorParent::RecvDecrypted(const uint32_t& aId,
return true;
}
bool
GMPDecryptorParent::RecvShutdown()
{
Shutdown();
return true;
}
// Note: may be called via Terminated()
void
GMPDecryptorParent::Close()

View File

@ -17,7 +17,7 @@ class CryptoSample;
namespace mozilla {
namespace gmp {
class GMPParent;
class GMPContentParent;
class GMPDecryptorParent final : public GMPDecryptorProxy
, public PGMPDecryptorParent
@ -25,7 +25,7 @@ class GMPDecryptorParent final : public GMPDecryptorProxy
public:
NS_INLINE_DECL_REFCOUNTING(GMPDecryptorParent)
explicit GMPDecryptorParent(GMPParent *aPlugin);
explicit GMPDecryptorParent(GMPContentParent *aPlugin);
// GMPDecryptorProxy
@ -104,12 +104,14 @@ private:
virtual bool RecvSetCaps(const uint64_t& aCaps) override;
virtual bool RecvShutdown() override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool Recv__delete__() override;
bool mIsOpen;
bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
nsRefPtr<GMPContentParent> mPlugin;
nsCString mPluginId;
GMPDecryptorProxyCallback* mCallback;
#ifdef DEBUG

View File

@ -14,6 +14,7 @@
#include "nsThreadUtils.h"
#include "nsIRunnable.h"
#include "mozIGeckoMediaPluginService.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/unused.h"
#include "nsIObserverService.h"
#include "GMPTimerParent.h"
@ -53,6 +54,7 @@ GMPParent::GMPParent()
, mProcess(nullptr)
, mDeleteProcessOnlyOnUnload(false)
, mAbnormalShutdownInProgress(false)
, mGMPContentChildCount(0)
, mAsyncShutdownRequired(false)
, mAsyncShutdownInProgress(false)
#ifdef PR_LOGGING
@ -72,12 +74,6 @@ GMPParent::~GMPParent()
LOGD("GMPParent dtor");
}
void
GMPParent::CheckThread()
{
MOZ_ASSERT(mGMPThread == NS_GetCurrentThread());
}
nsresult
GMPParent::CloneFrom(const GMPParent* aOther)
{
@ -226,6 +222,16 @@ GMPParent::EnsureAsyncShutdownTimeoutSet()
nsITimer::TYPE_ONE_SHOT);
}
bool
GMPParent::RecvPGMPContentChildDestroyed()
{
--mGMPContentChildCount;
if (!IsUsed()) {
CloseIfUnused();
}
return true;
}
void
GMPParent::CloseIfUnused()
{
@ -235,11 +241,7 @@ GMPParent::CloseIfUnused()
if ((mDeleteProcessOnlyOnUnload ||
mState == GMPStateLoaded ||
mState == GMPStateUnloading) &&
mVideoDecoders.IsEmpty() &&
mVideoEncoders.IsEmpty() &&
mDecryptors.IsEmpty() &&
mAudioDecoders.IsEmpty()) {
!IsUsed()) {
// Ensure all timers are killed.
for (uint32_t i = mTimers.Length(); i > 0; i--) {
mTimers[i - 1]->Shutdown();
@ -286,57 +288,21 @@ GMPParent::AbortAsyncShutdown()
CloseIfUnused();
}
void
GMPParent::AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
MOZ_ALWAYS_TRUE(mAudioDecoders.RemoveElement(aDecoder));
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
// until after this has completed.
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
NS_DispatchToCurrentThread(event);
}
void
GMPParent::CloseActive(bool aDieWhenUnloaded)
{
LOGD("%s: state %d", __FUNCTION__, mState);
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
if (aDieWhenUnloaded) {
mDeleteProcessOnlyOnUnload = true; // don't allow this to go back...
}
if (mState == GMPStateLoaded) {
mState = GMPStateUnloading;
}
// Invalidate and remove any remaining API objects.
for (uint32_t i = mVideoDecoders.Length(); i > 0; i--) {
mVideoDecoders[i - 1]->Shutdown();
if (mState != GMPStateNotLoaded && IsUsed()) {
unused << SendCloseActive();
}
for (uint32_t i = mVideoEncoders.Length(); i > 0; i--) {
mVideoEncoders[i - 1]->Shutdown();
}
for (uint32_t i = mDecryptors.Length(); i > 0; i--) {
mDecryptors[i - 1]->Shutdown();
}
for (uint32_t i = mAudioDecoders.Length(); i > 0; i--) {
mAudioDecoders[i - 1]->Shutdown();
}
// Note: we don't shutdown timers here, we do that in CloseIfUnused(),
// as there are multiple entry points to CloseIfUnused().
// Note: We don't shutdown storage API objects here, as they need to
// work during async shutdown of GMPs.
// Note: the shutdown of the codecs is async! don't kill
// the plugin-container until they're all safely shut down via
// CloseIfUnused();
CloseIfUnused();
}
void
@ -350,7 +316,8 @@ GMPParent::Shutdown()
if (mAbnormalShutdownInProgress) {
return;
}
MOZ_ASSERT(mVideoDecoders.IsEmpty() && mVideoEncoders.IsEmpty());
MOZ_ASSERT(!IsUsed());
if (mState == GMPStateNotLoaded || mState == GMPStateClosing) {
return;
}
@ -406,78 +373,6 @@ GMPParent::DeleteProcess()
}
void
GMPParent::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));
if (mVideoDecoders.IsEmpty() &&
mVideoEncoders.IsEmpty()) {
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
// until after this has completed.
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
NS_DispatchToCurrentThread(event);
}
}
void
GMPParent::VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
// If the constructor fails, we'll get called before it's added
unused << NS_WARN_IF(!mVideoEncoders.RemoveElement(aEncoder));
if (mVideoDecoders.IsEmpty() &&
mVideoEncoders.IsEmpty()) {
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
// until after this has completed.
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
NS_DispatchToCurrentThread(event);
}
}
void
GMPParent::DecryptorDestroyed(GMPDecryptorParent* aSession)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
MOZ_ALWAYS_TRUE(mDecryptors.RemoveElement(aSession));
// Recv__delete__ is on the stack, don't potentially destroy the top-level actor
// until after this has completed.
if (mDecryptors.IsEmpty()) {
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &GMPParent::CloseIfUnused);
NS_DispatchToCurrentThread(event);
}
}
nsresult
GMPParent::GetGMPDecryptor(GMPDecryptorParent** aGMPDP)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
if (!EnsureProcessLoaded()) {
return NS_ERROR_FAILURE;
}
PGMPDecryptorParent* pdp = SendPGMPDecryptorConstructor();
if (!pdp) {
return NS_ERROR_FAILURE;
}
GMPDecryptorParent* dp = static_cast<GMPDecryptorParent*>(pdp);
// This addref corresponds to the Proxy pointer the consumer is returned.
// It's dropped by calling Close() on the interface.
NS_ADDREF(dp);
mDecryptors.AppendElement(dp);
*aGMPDP = dp;
return NS_OK;
}
GMPState
GMPParent::State() const
{
@ -539,77 +434,6 @@ GMPParent::EnsureProcessLoaded()
return NS_SUCCEEDED(rv);
}
nsresult
GMPParent::GetGMPAudioDecoder(GMPAudioDecoderParent** aGMPAD)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
if (!EnsureProcessLoaded()) {
return NS_ERROR_FAILURE;
}
PGMPAudioDecoderParent* pvap = SendPGMPAudioDecoderConstructor();
if (!pvap) {
return NS_ERROR_FAILURE;
}
GMPAudioDecoderParent* vap = static_cast<GMPAudioDecoderParent*>(pvap);
// This addref corresponds to the Proxy pointer the consumer is returned.
// It's dropped by calling Close() on the interface.
NS_ADDREF(vap);
*aGMPAD = vap;
mAudioDecoders.AppendElement(vap);
return NS_OK;
}
nsresult
GMPParent::GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
if (!EnsureProcessLoaded()) {
return NS_ERROR_FAILURE;
}
// returned with one anonymous AddRef that locks it until Destroy
PGMPVideoDecoderParent* pvdp = SendPGMPVideoDecoderConstructor();
if (!pvdp) {
return NS_ERROR_FAILURE;
}
GMPVideoDecoderParent *vdp = static_cast<GMPVideoDecoderParent*>(pvdp);
// This addref corresponds to the Proxy pointer the consumer is returned.
// It's dropped by calling Close() on the interface.
NS_ADDREF(vdp);
*aGMPVD = vdp;
mVideoDecoders.AppendElement(vdp);
return NS_OK;
}
nsresult
GMPParent::GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
if (!EnsureProcessLoaded()) {
return NS_ERROR_FAILURE;
}
// returned with one anonymous AddRef that locks it until Destroy
PGMPVideoEncoderParent* pvep = SendPGMPVideoEncoderConstructor();
if (!pvep) {
return NS_ERROR_FAILURE;
}
GMPVideoEncoderParent *vep = static_cast<GMPVideoEncoderParent*>(pvep);
// This addref corresponds to the Proxy pointer the consumer is returned.
// It's dropped by calling Close() on the interface.
NS_ADDREF(vep);
*aGMPVE = vep;
mVideoEncoders.AppendElement(vep);
return NS_OK;
}
#ifdef MOZ_CRASHREPORTER
void
GMPParent::WriteExtraDataForMinidump(CrashReporter::AnnotationTable& notes)
@ -724,70 +548,6 @@ GMPParent::DeallocPCrashReporterParent(PCrashReporterParent* aCrashReporter)
return true;
}
PGMPVideoDecoderParent*
GMPParent::AllocPGMPVideoDecoderParent()
{
GMPVideoDecoderParent* vdp = new GMPVideoDecoderParent(this);
NS_ADDREF(vdp);
return vdp;
}
bool
GMPParent::DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor)
{
GMPVideoDecoderParent* vdp = static_cast<GMPVideoDecoderParent*>(aActor);
NS_RELEASE(vdp);
return true;
}
PGMPVideoEncoderParent*
GMPParent::AllocPGMPVideoEncoderParent()
{
GMPVideoEncoderParent* vep = new GMPVideoEncoderParent(this);
NS_ADDREF(vep);
return vep;
}
bool
GMPParent::DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor)
{
GMPVideoEncoderParent* vep = static_cast<GMPVideoEncoderParent*>(aActor);
NS_RELEASE(vep);
return true;
}
PGMPDecryptorParent*
GMPParent::AllocPGMPDecryptorParent()
{
GMPDecryptorParent* ksp = new GMPDecryptorParent(this);
NS_ADDREF(ksp);
return ksp;
}
bool
GMPParent::DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor)
{
GMPDecryptorParent* ksp = static_cast<GMPDecryptorParent*>(aActor);
NS_RELEASE(ksp);
return true;
}
PGMPAudioDecoderParent*
GMPParent::AllocPGMPAudioDecoderParent()
{
GMPAudioDecoderParent* vdp = new GMPAudioDecoderParent(this);
NS_ADDREF(vdp);
return vdp;
}
bool
GMPParent::DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor)
{
GMPAudioDecoderParent* vdp = static_cast<GMPAudioDecoderParent*>(aActor);
NS_RELEASE(vdp);
return true;
}
PGMPStorageParent*
GMPParent::AllocPGMPStorageParent()
{
@ -1024,7 +784,7 @@ GMPParent::GetVersion() const
return mVersion;
}
const nsACString&
const nsCString&
GMPParent::GetPluginId() const
{
return mPluginId;
@ -1053,6 +813,87 @@ GMPParent::RecvAsyncShutdownComplete()
return true;
}
class RunCreateContentParentCallbacks : public nsRunnable
{
public:
explicit RunCreateContentParentCallbacks(GMPContentParent* aGMPContentParent)
: mGMPContentParent(aGMPContentParent)
{
}
void TakeCallbacks(nsTArray<UniquePtr<GetGMPContentParentCallback>>& aCallbacks)
{
mCallbacks.SwapElements(aCallbacks);
}
NS_IMETHOD
Run()
{
for (uint32_t i = 0, length = mCallbacks.Length(); i < length; ++i) {
mCallbacks[i]->Done(mGMPContentParent);
}
return NS_OK;
}
private:
nsRefPtr<GMPContentParent> mGMPContentParent;
nsTArray<UniquePtr<GetGMPContentParentCallback>> mCallbacks;
};
PGMPContentParent*
GMPParent::AllocPGMPContentParent(Transport* aTransport, ProcessId aOtherPid)
{
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
MOZ_ASSERT(!mGMPContentParent);
mGMPContentParent = new GMPContentParent(this);
mGMPContentParent->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(),
ipc::ParentSide);
nsRefPtr<RunCreateContentParentCallbacks> runCallbacks =
new RunCreateContentParentCallbacks(mGMPContentParent);
runCallbacks->TakeCallbacks(mCallbacks);
NS_DispatchToCurrentThread(runCallbacks);
MOZ_ASSERT(mCallbacks.IsEmpty());
return mGMPContentParent;
}
bool
GMPParent::GetGMPContentParent(UniquePtr<GetGMPContentParentCallback>&& aCallback)
{
LOGD("%s %p", __FUNCTION__, this);
MOZ_ASSERT(GMPThread() == NS_GetCurrentThread());
if (mGMPContentParent) {
aCallback->Done(mGMPContentParent);
} else {
mCallbacks.AppendElement(Move(aCallback));
// If we don't have a GMPContentParent and we try to get one for the first
// time (mCallbacks.Length() == 1) then call PGMPContent::Open. If more
// calls to GetGMPContentParent happen before mGMPContentParent has been
// set then we should just store them, so that they get called when we set
// mGMPContentParent as a result of the PGMPContent::Open call.
if (mCallbacks.Length() == 1) {
if (!EnsureProcessLoaded() || !PGMPContent::Open(this)) {
return false;
}
// We want to increment this as soon as possible, to avoid that we'd try
// to shut down the GMP process while we're still trying to get a
// PGMPContentParent actor.
++mGMPContentChildCount;
}
}
return true;
}
already_AddRefed<GMPContentParent>
GMPParent::ForgetGMPContentParent()
{
MOZ_ASSERT(mCallbacks.IsEmpty());
return Move(mGMPContentParent.forget());
}
} // namespace gmp
} // namespace mozilla

View File

@ -54,8 +54,23 @@ enum GMPState {
GMPStateClosing
};
class GMPParent final : public PGMPParent,
public GMPSharedMem
class GMPContentParent;
class GetGMPContentParentCallback
{
public:
GetGMPContentParentCallback()
{
MOZ_COUNT_CTOR(GetGMPContentParentCallback);
};
virtual ~GetGMPContentParentCallback()
{
MOZ_COUNT_DTOR(GetGMPContentParentCallback);
};
virtual void Done(GMPContentParent* aGMPContentParent) = 0;
};
class GMPParent final : public PGMPParent
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(GMPParent)
@ -84,18 +99,6 @@ public:
bool SupportsAPI(const nsCString& aAPI, const nsCString& aTag);
nsresult GetGMPVideoDecoder(GMPVideoDecoderParent** aGMPVD);
void VideoDecoderDestroyed(GMPVideoDecoderParent* aDecoder);
nsresult GetGMPVideoEncoder(GMPVideoEncoderParent** aGMPVE);
void VideoEncoderDestroyed(GMPVideoEncoderParent* aEncoder);
nsresult GetGMPDecryptor(GMPDecryptorParent** aGMPKS);
void DecryptorDestroyed(GMPDecryptorParent* aSession);
nsresult GetGMPAudioDecoder(GMPAudioDecoderParent** aGMPAD);
void AudioDecoderDestroyed(GMPAudioDecoderParent* aDecoder);
GMPState State() const;
nsIThread* GMPThread();
@ -117,7 +120,7 @@ public:
const nsCString& GetDisplayName() const;
const nsCString& GetVersion() const;
const nsACString& GetPluginId() const;
const nsCString& GetPluginId() const;
// Returns true if a plugin can be or is being used across multiple NodeIds.
bool CanBeSharedCrossNodeIds() const;
@ -131,11 +134,11 @@ public:
return nsCOMPtr<nsIFile>(mDirectory).forget();
}
// GMPSharedMem
virtual void CheckThread() override;
void AbortAsyncShutdown();
bool GetGMPContentParent(UniquePtr<GetGMPContentParentCallback>&& aCallback);
already_AddRefed<GMPContentParent> ForgetGMPContentParent();
private:
~GMPParent();
nsRefPtr<GeckoMediaPluginServiceParent> mService;
@ -150,22 +153,13 @@ private:
virtual PCrashReporterParent* AllocPCrashReporterParent(const NativeThreadId& aThread) override;
virtual bool DeallocPCrashReporterParent(PCrashReporterParent* aCrashReporter) override;
virtual PGMPVideoDecoderParent* AllocPGMPVideoDecoderParent() override;
virtual bool DeallocPGMPVideoDecoderParent(PGMPVideoDecoderParent* aActor) override;
virtual PGMPVideoEncoderParent* AllocPGMPVideoEncoderParent() override;
virtual bool DeallocPGMPVideoEncoderParent(PGMPVideoEncoderParent* aActor) override;
virtual PGMPDecryptorParent* AllocPGMPDecryptorParent() override;
virtual bool DeallocPGMPDecryptorParent(PGMPDecryptorParent* aActor) override;
virtual PGMPAudioDecoderParent* AllocPGMPAudioDecoderParent() override;
virtual bool DeallocPGMPAudioDecoderParent(PGMPAudioDecoderParent* aActor) override;
virtual bool RecvPGMPStorageConstructor(PGMPStorageParent* actor) override;
virtual PGMPStorageParent* AllocPGMPStorageParent() override;
virtual bool DeallocPGMPStorageParent(PGMPStorageParent* aActor) override;
virtual PGMPContentParent* AllocPGMPContentParent(Transport* aTransport,
ProcessId aOtherPid) override;
virtual bool RecvPGMPTimerConstructor(PGMPTimerParent* actor) override;
virtual PGMPTimerParent* AllocPGMPTimerParent() override;
virtual bool DeallocPGMPTimerParent(PGMPTimerParent* aActor) override;
@ -173,6 +167,13 @@ private:
virtual bool RecvAsyncShutdownComplete() override;
virtual bool RecvAsyncShutdownRequired() override;
virtual bool RecvPGMPContentChildDestroyed() override;
bool IsUsed()
{
return mGMPContentChildCount > 0;
}
nsresult EnsureAsyncShutdownTimeoutSet();
GMPState mState;
@ -187,10 +188,6 @@ private:
bool mDeleteProcessOnlyOnUnload;
bool mAbnormalShutdownInProgress;
nsTArray<nsRefPtr<GMPVideoDecoderParent>> mVideoDecoders;
nsTArray<nsRefPtr<GMPVideoEncoderParent>> mVideoEncoders;
nsTArray<nsRefPtr<GMPDecryptorParent>> mDecryptors;
nsTArray<nsRefPtr<GMPAudioDecoderParent>> mAudioDecoders;
nsTArray<nsRefPtr<GMPTimerParent>> mTimers;
nsTArray<nsRefPtr<GMPStorageParent>> mStorage;
nsCOMPtr<nsIThread> mGMPThread;
@ -198,6 +195,11 @@ private:
// NodeId the plugin is assigned to, or empty if the the plugin is not
// assigned to a NodeId.
nsAutoCString mNodeId;
// This is used for GMP content in the parent, there may be more of these in
// the content processes.
nsRefPtr<GMPContentParent> mGMPContentParent;
nsTArray<UniquePtr<GetGMPContentParentCallback>> mCallbacks;
uint32_t mGMPContentChildCount;
bool mAsyncShutdownRequired;
bool mAsyncShutdownInProgress;

View File

@ -281,18 +281,20 @@ GeckoMediaPluginService::GetThread(nsIThread** aThread)
return NS_OK;
}
class GetGMPParentForAudioDecoderDone
class GetGMPContentParentForAudioDecoderDone : public GetGMPContentParentCallback
{
public:
explicit GetGMPParentForAudioDecoderDone(UniquePtr<GetGMPAudioDecoderCallback>&& aCallback)
explicit GetGMPContentParentForAudioDecoderDone(UniquePtr<GetGMPAudioDecoderCallback>&& aCallback)
: mCallback(Move(aCallback))
{
}
void Done(GMPParent* aGMPParent)
virtual void Done(GMPContentParent* aGMPParent) override
{
GMPAudioDecoderParent* gmpADP = nullptr;
aGMPParent->GetGMPAudioDecoder(&gmpADP);
if (aGMPParent) {
aGMPParent->GetGMPAudioDecoder(&gmpADP);
}
mCallback->Done(gmpADP);
}
@ -313,32 +315,29 @@ GeckoMediaPluginService::GetGMPAudioDecoder(nsTArray<nsCString>* aTags,
return NS_ERROR_FAILURE;
}
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(aNodeId,
NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
*aTags);
if (!gmp) {
UniquePtr<GetGMPContentParentCallback> callback(
new GetGMPContentParentForAudioDecoderDone(Move(aCallback)));
if (!GetContentParentFrom(aNodeId, NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
*aTags, Move(callback))) {
return NS_ERROR_FAILURE;
}
GetGMPParentForAudioDecoderDone(Move(aCallback)).Done(gmp);
return NS_OK;
}
class GetGMPParentForVideoDecoderDone
class GetGMPContentParentForVideoDecoderDone : public GetGMPContentParentCallback
{
public:
explicit GetGMPParentForVideoDecoderDone(UniquePtr<GetGMPVideoDecoderCallback>&& aCallback)
explicit GetGMPContentParentForVideoDecoderDone(UniquePtr<GetGMPVideoDecoderCallback>&& aCallback)
: mCallback(Move(aCallback))
{
}
void Done(GMPParent* aGMPParent)
virtual void Done(GMPContentParent* aGMPParent) override
{
GMPVideoDecoderParent* gmpVDP = nullptr;
GMPVideoHostImpl* videoHost = nullptr;
nsresult rv = aGMPParent->GetGMPVideoDecoder(&gmpVDP);
if (NS_SUCCEEDED(rv)) {
if (aGMPParent && NS_SUCCEEDED(aGMPParent->GetGMPVideoDecoder(&gmpVDP))) {
videoHost = &gmpVDP->Host();
}
mCallback->Done(gmpVDP, videoHost);
@ -361,37 +360,29 @@ GeckoMediaPluginService::GetGMPVideoDecoder(nsTArray<nsCString>* aTags,
return NS_ERROR_FAILURE;
}
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(aNodeId,
NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
*aTags);
#ifdef PR_LOGGING
nsCString api = (*aTags)[0];
LOGD(("%s: %p returning %p for api %s", __FUNCTION__, (void *)this, (void *)gmp, api.get()));
#endif
if (!gmp) {
UniquePtr<GetGMPContentParentCallback> callback(
new GetGMPContentParentForVideoDecoderDone(Move(aCallback)));
if (!GetContentParentFrom(aNodeId, NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
*aTags, Move(callback))) {
return NS_ERROR_FAILURE;
}
GetGMPParentForVideoDecoderDone(Move(aCallback)).Done(gmp);
return NS_OK;
}
class GetGMPParentForVideoEncoderDone
class GetGMPContentParentForVideoEncoderDone : public GetGMPContentParentCallback
{
public:
explicit GetGMPParentForVideoEncoderDone(UniquePtr<GetGMPVideoEncoderCallback>&& aCallback)
explicit GetGMPContentParentForVideoEncoderDone(UniquePtr<GetGMPVideoEncoderCallback>&& aCallback)
: mCallback(Move(aCallback))
{
}
void Done(GMPParent* aGMPParent)
virtual void Done(GMPContentParent* aGMPParent) override
{
GMPVideoEncoderParent* gmpVEP = nullptr;
GMPVideoHostImpl* videoHost = nullptr;
nsresult rv = aGMPParent->GetGMPVideoEncoder(&gmpVEP);
if (NS_SUCCEEDED(rv)) {
if (aGMPParent && NS_SUCCEEDED(aGMPParent->GetGMPVideoEncoder(&gmpVEP))) {
videoHost = &gmpVEP->Host();
}
mCallback->Done(gmpVEP, videoHost);
@ -414,34 +405,30 @@ GeckoMediaPluginService::GetGMPVideoEncoder(nsTArray<nsCString>* aTags,
return NS_ERROR_FAILURE;
}
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(aNodeId,
NS_LITERAL_CSTRING(GMP_API_VIDEO_ENCODER),
*aTags);
#ifdef PR_LOGGING
nsCString api = (*aTags)[0];
LOGD(("%s: %p returning %p for api %s", __FUNCTION__, (void *)this, (void *)gmp, api.get()));
#endif
if (!gmp) {
UniquePtr<GetGMPContentParentCallback> callback(
new GetGMPContentParentForVideoEncoderDone(Move(aCallback)));
if (!GetContentParentFrom(aNodeId, NS_LITERAL_CSTRING(GMP_API_VIDEO_ENCODER),
*aTags, Move(callback))) {
return NS_ERROR_FAILURE;
}
GetGMPParentForVideoEncoderDone(Move(aCallback)).Done(gmp);
return NS_OK;
}
class GetGMPParentForDecryptorDone
class GetGMPContentParentForDecryptorDone : public GetGMPContentParentCallback
{
public:
explicit GetGMPParentForDecryptorDone(UniquePtr<GetGMPDecryptorCallback>&& aCallback)
explicit GetGMPContentParentForDecryptorDone(UniquePtr<GetGMPDecryptorCallback>&& aCallback)
: mCallback(Move(aCallback))
{
}
void Done(GMPParent* aGMPParent)
virtual void Done(GMPContentParent* aGMPParent) override
{
GMPDecryptorParent* ksp = nullptr;
aGMPParent->GetGMPDecryptor(&ksp);
if (aGMPParent) {
aGMPParent->GetGMPDecryptor(&ksp);
}
mCallback->Done(ksp);
}
@ -470,15 +457,13 @@ GeckoMediaPluginService::GetGMPDecryptor(nsTArray<nsCString>* aTags,
return NS_ERROR_FAILURE;
}
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(aNodeId,
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
*aTags);
if (!gmp) {
UniquePtr<GetGMPContentParentCallback> callback(
new GetGMPContentParentForDecryptorDone(Move(aCallback)));
if (!GetContentParentFrom(aNodeId, NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
*aTags, Move(callback))) {
return NS_ERROR_FAILURE;
}
GetGMPParentForDecryptorDone(Move(aCallback)).Done(gmp);
return NS_OK;
}

View File

@ -24,7 +24,7 @@ extern PRLogModuleInfo* GetGMPLog();
namespace gmp {
class GMPParent;
class GetGMPContentParentCallback;
#define GMP_DEFAULT_ASYNC_SHUTDONW_TIMEOUT 3000
@ -94,9 +94,10 @@ protected:
virtual ~GeckoMediaPluginService();
virtual void InitializePlugins() = 0;
virtual GMPParent* SelectPluginForAPI(const nsACString& aNodeId,
const nsCString& aAPI,
const nsTArray<nsCString>& aTags) = 0;
virtual bool GetContentParentFrom(const nsACString& aNodeId,
const nsCString& aAPI,
const nsTArray<nsCString>& aTags,
UniquePtr<GetGMPContentParentCallback>&& aCallback) = 0;
nsresult GMPDispatch(nsIRunnable* event, uint32_t flags = NS_DISPATCH_NORMAL);
void ShutdownGMPThread();

View File

@ -297,6 +297,26 @@ GeckoMediaPluginServiceParent::Observe(nsISupports* aSubject,
return NS_OK;
}
bool
GeckoMediaPluginServiceParent::GetContentParentFrom(const nsACString& aNodeId,
const nsCString& aAPI,
const nsTArray<nsCString>& aTags,
UniquePtr<GetGMPContentParentCallback>&& aCallback)
{
nsRefPtr<GMPParent> gmp = SelectPluginForAPI(aNodeId, aAPI, aTags);
#ifdef PR_LOGGING
nsCString api = aTags[0];
LOGD(("%s: %p returning %p for api %s", __FUNCTION__, (void *)this, (void *)gmp, api.get()));
#endif
if (!gmp) {
return false;
}
return gmp->GetGMPContentParent(Move(aCallback));
}
void
GeckoMediaPluginServiceParent::InitializePlugins()
{

View File

@ -91,6 +91,11 @@ protected:
friend class GMPParent;
void ReAddOnGMPThread(nsRefPtr<GMPParent>& aOld);
virtual void InitializePlugins() override;
virtual bool GetContentParentFrom(const nsACString& aNodeId,
const nsCString& aAPI,
const nsTArray<nsCString>& aTags,
UniquePtr<GetGMPContentParentCallback>&& aCallback)
override;
private:
GMPParent* ClonePlugin(const GMPParent* aOriginal);
nsresult EnsurePluginsOnDiskScanned();

View File

@ -5,7 +5,7 @@
#include "GMPVideoDecoderChild.h"
#include "GMPVideoi420FrameImpl.h"
#include "GMPChild.h"
#include "GMPContentChild.h"
#include <stdio.h>
#include "mozilla/unused.h"
#include "GMPVideoEncodedFrameImpl.h"
@ -13,7 +13,7 @@
namespace mozilla {
namespace gmp {
GMPVideoDecoderChild::GMPVideoDecoderChild(GMPChild* aPlugin)
GMPVideoDecoderChild::GMPVideoDecoderChild(GMPContentChild* aPlugin)
: GMPSharedMemManager(aPlugin),
mPlugin(aPlugin),
mVideoDecoder(nullptr),

View File

@ -16,14 +16,14 @@
namespace mozilla {
namespace gmp {
class GMPChild;
class GMPContentChild;
class GMPVideoDecoderChild : public PGMPVideoDecoderChild,
public GMPVideoDecoderCallback,
public GMPSharedMemManager
{
public:
explicit GMPVideoDecoderChild(GMPChild* aPlugin);
explicit GMPVideoDecoderChild(GMPContentChild* aPlugin);
virtual ~GMPVideoDecoderChild();
void Init(GMPVideoDecoder* aDecoder);
@ -74,7 +74,7 @@ private:
virtual bool RecvDrain() override;
virtual bool RecvDecodingComplete() override;
GMPChild* mPlugin;
GMPContentChild* mPlugin;
GMPVideoDecoder* mVideoDecoder;
GMPVideoHostImpl mVideoHost;
};

View File

@ -11,7 +11,7 @@
#include "GMPUtils.h"
#include "GMPVideoEncodedFrameImpl.h"
#include "GMPVideoi420FrameImpl.h"
#include "GMPParent.h"
#include "GMPContentParent.h"
#include "GMPMessageUtils.h"
#include "mozilla/gmp/GMPTypes.h"
@ -43,7 +43,7 @@ namespace gmp {
// on Shutdown -> Dead
// Dead: mIsOpen == false
GMPVideoDecoderParent::GMPVideoDecoderParent(GMPParent* aPlugin)
GMPVideoDecoderParent::GMPVideoDecoderParent(GMPContentParent* aPlugin)
: GMPSharedMemManager(aPlugin)
, mIsOpen(false)
, mShuttingDown(false)
@ -335,6 +335,13 @@ GMPVideoDecoderParent::RecvError(const GMPErr& aError)
return true;
}
bool
GMPVideoDecoderParent::RecvShutdown()
{
Shutdown();
return true;
}
bool
GMPVideoDecoderParent::RecvParentShmemForPool(Shmem&& aEncodedBuffer)
{

View File

@ -18,7 +18,7 @@
namespace mozilla {
namespace gmp {
class GMPParent;
class GMPContentParent;
class GMPVideoDecoderParent final : public PGMPVideoDecoderParent
, public GMPVideoDecoderProxy
@ -27,7 +27,7 @@ class GMPVideoDecoderParent final : public PGMPVideoDecoderParent
public:
NS_INLINE_DECL_REFCOUNTING(GMPVideoDecoderParent)
explicit GMPVideoDecoderParent(GMPParent *aPlugin);
explicit GMPVideoDecoderParent(GMPContentParent *aPlugin);
GMPVideoHostImpl& Host();
nsresult Shutdown();
@ -73,6 +73,7 @@ private:
virtual bool RecvDrainComplete() override;
virtual bool RecvResetComplete() override;
virtual bool RecvError(const GMPErr& aError) override;
virtual bool RecvShutdown() override;
virtual bool RecvParentShmemForPool(Shmem&& aEncodedBuffer) override;
virtual bool AnswerNeedShmem(const uint32_t& aFrameBufferSize,
Shmem* aMem) override;
@ -80,7 +81,7 @@ private:
bool mIsOpen;
bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
nsRefPtr<GMPContentParent> mPlugin;
GMPVideoDecoderCallbackProxy* mCallback;
GMPVideoHostImpl mVideoHost;
};

View File

@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPVideoEncoderChild.h"
#include "GMPChild.h"
#include "GMPContentChild.h"
#include <stdio.h>
#include "mozilla/unused.h"
#include "GMPVideoEncodedFrameImpl.h"
@ -13,7 +13,7 @@
namespace mozilla {
namespace gmp {
GMPVideoEncoderChild::GMPVideoEncoderChild(GMPChild* aPlugin)
GMPVideoEncoderChild::GMPVideoEncoderChild(GMPContentChild* aPlugin)
: GMPSharedMemManager(aPlugin),
mPlugin(aPlugin),
mVideoEncoder(nullptr),

View File

@ -15,14 +15,14 @@
namespace mozilla {
namespace gmp {
class GMPChild;
class GMPContentChild;
class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
public GMPVideoEncoderCallback,
public GMPSharedMemManager
{
public:
explicit GMPVideoEncoderChild(GMPChild* aPlugin);
explicit GMPVideoEncoderChild(GMPContentChild* aPlugin);
virtual ~GMPVideoEncoderChild();
void Init(GMPVideoEncoder* aEncoder);
@ -73,7 +73,7 @@ private:
virtual bool RecvSetPeriodicKeyFrames(const bool& aEnable) override;
virtual bool RecvEncodingComplete() override;
GMPChild* mPlugin;
GMPContentChild* mPlugin;
GMPVideoEncoder* mVideoEncoder;
GMPVideoHostImpl mVideoHost;
};

View File

@ -10,7 +10,7 @@
#include "mozilla/unused.h"
#include "GMPMessageUtils.h"
#include "nsAutoRef.h"
#include "GMPParent.h"
#include "GMPContentParent.h"
#include "mozilla/gmp/GMPTypes.h"
#include "nsThread.h"
#include "nsThreadUtils.h"
@ -50,7 +50,7 @@ namespace gmp {
// on Shutdown -> Dead
// Dead: mIsOpen == false
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPParent *aPlugin)
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPContentParent *aPlugin)
: GMPSharedMemManager(aPlugin),
mIsOpen(false),
mShuttingDown(false),
@ -320,6 +320,13 @@ GMPVideoEncoderParent::RecvError(const GMPErr& aError)
return true;
}
bool
GMPVideoEncoderParent::RecvShutdown()
{
Shutdown();
return true;
}
bool
GMPVideoEncoderParent::RecvParentShmemForPool(Shmem&& aFrameBuffer)
{

View File

@ -18,7 +18,7 @@
namespace mozilla {
namespace gmp {
class GMPParent;
class GMPContentParent;
class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
public PGMPVideoEncoderParent,
@ -27,7 +27,7 @@ class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
public:
NS_INLINE_DECL_REFCOUNTING(GMPVideoEncoderParent)
explicit GMPVideoEncoderParent(GMPParent *aPlugin);
explicit GMPVideoEncoderParent(GMPContentParent *aPlugin);
GMPVideoHostImpl& Host();
void Shutdown();
@ -69,6 +69,7 @@ private:
virtual bool RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
InfallibleTArray<uint8_t>&& aCodecSpecificInfo) override;
virtual bool RecvError(const GMPErr& aError) override;
virtual bool RecvShutdown() override;
virtual bool RecvParentShmemForPool(Shmem&& aFrameBuffer) override;
virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
Shmem* aMem) override;
@ -76,7 +77,7 @@ private:
bool mIsOpen;
bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
nsRefPtr<GMPContentParent> mPlugin;
GMPVideoEncoderCallbackProxy* mCallback;
GMPVideoHostImpl mVideoHost;
nsCOMPtr<nsIThread> mEncodedThread;

View File

@ -3,11 +3,8 @@
* 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 PCrashReporter;
include protocol PGMPDecryptor;
include protocol PGMPAudioDecoder;
include protocol PGMPContent;
include protocol PGMPTimer;
include protocol PGMPStorage;
@ -18,10 +15,8 @@ namespace gmp {
intr protocol PGMP
{
manages PGMPAudioDecoder;
manages PGMPDecryptor;
manages PGMPVideoDecoder;
manages PGMPVideoEncoder;
parent opens PGMPContent;
manages PCrashReporter;
manages PGMPTimer;
manages PGMPStorage;
@ -31,19 +26,17 @@ parent:
async PGMPTimer();
async PGMPStorage();
async PGMPContentChildDestroyed();
async AsyncShutdownComplete();
async AsyncShutdownRequired();
child:
async PGMPAudioDecoder();
async PGMPDecryptor();
async PGMPVideoDecoder();
async PGMPVideoEncoder();
async SetNodeId(nsCString nodeId);
async StartPlugin();
async BeginAsyncShutdown();
async CrashPluginNow();
async StartPlugin();
async SetNodeId(nsCString nodeId);
async CloseActive();
};
} // namespace gmp

View File

@ -3,7 +3,7 @@
* 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 PGMP;
include protocol PGMPContent;
include GMPTypes;
using GMPCodecSpecificInfo from "gmp-audio-codec.h";
@ -16,7 +16,7 @@ namespace gmp {
async protocol PGMPAudioDecoder
{
manager PGMP;
manager PGMPContent;
child:
InitDecode(GMPAudioCodecData aCodecSettings);
Decode(GMPAudioEncodedSampleData aInput);
@ -30,6 +30,7 @@ parent:
DrainComplete();
ResetComplete();
Error(GMPErr aErr);
async Shutdown();
};
} // namespace gmp

View File

@ -0,0 +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 PGMPAudioDecoder;
namespace mozilla {
namespace gmp {
intr protocol PGMPContent
{
manages PGMPAudioDecoder;
manages PGMPDecryptor;
manages PGMPVideoDecoder;
manages PGMPVideoEncoder;
child:
async PGMPAudioDecoder();
async PGMPDecryptor();
async PGMPVideoDecoder();
async PGMPVideoEncoder();
};
} // namespace gmp
} // namespace mozilla

View File

@ -3,7 +3,7 @@
* 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 PGMP;
include protocol PGMPContent;
include GMPTypes;
using GMPSessionMessageType from "gmp-decryption.h";
@ -17,7 +17,7 @@ namespace gmp {
async protocol PGMPDecryptor
{
manager PGMP;
manager PGMPContent;
child:
Init();
@ -84,6 +84,8 @@ parent:
SetCaps(uint64_t aCaps);
Decrypted(uint32_t aId, GMPErr aResult, uint8_t[] aBuffer);
async Shutdown();
};
} // namespace gmp

View File

@ -3,7 +3,7 @@
* 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 PGMP;
include protocol PGMPContent;
include GMPTypes;
using GMPVideoCodec from "gmp-video-codec.h";
@ -16,7 +16,7 @@ namespace gmp {
intr protocol PGMPVideoDecoder
{
manager PGMP;
manager PGMPContent;
child:
async InitDecode(GMPVideoCodec aCodecSettings,
uint8_t[] aCodecSpecific,
@ -39,6 +39,7 @@ parent:
async DrainComplete();
async ResetComplete();
async Error(GMPErr aErr);
async Shutdown();
async ParentShmemForPool(Shmem aEncodedBuffer);
// MUST be intr - if sync and we create a new Shmem, when the returned
// Shmem is received in the Child it will fail to Deserialize

View File

@ -3,7 +3,7 @@
* 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 PGMP;
include protocol PGMPContent;
include GMPTypes;
using GMPVideoCodec from "gmp-video-codec.h";
@ -17,7 +17,7 @@ namespace gmp {
intr protocol PGMPVideoEncoder
{
manager PGMP;
manager PGMPContent;
child:
async InitEncode(GMPVideoCodec aCodecSettings,
uint8_t[] aCodecSpecific,
@ -37,6 +37,7 @@ parent:
async Encoded(GMPVideoEncodedFrameData aEncodedFrame,
uint8_t[] aCodecSpecificInfo);
async Error(GMPErr aErr);
async Shutdown();
async ParentShmemForPool(Shmem aFrameBuffer);
// MUST be intr - if sync and we create a new Shmem, when the returned
// Shmem is received in the Child it will fail to Deserialize

View File

@ -36,6 +36,8 @@ EXPORTS += [
'GMPAudioHost.h',
'GMPCallbackBase.h',
'GMPChild.h',
'GMPContentChild.h',
'GMPContentParent.h',
'GMPDecryptorChild.h',
'GMPDecryptorParent.h',
'GMPDecryptorProxy.h',
@ -78,6 +80,8 @@ UNIFIED_SOURCES += [
'GMPAudioDecoderParent.cpp',
'GMPAudioHost.cpp',
'GMPChild.cpp',
'GMPContentChild.cpp',
'GMPContentParent.cpp',
'GMPDecryptorChild.cpp',
'GMPDecryptorParent.cpp',
'GMPEncryptedBufferDataImpl.cpp',
@ -111,6 +115,7 @@ IPDL_SOURCES += [
'GMPTypes.ipdlh',
'PGMP.ipdl',
'PGMPAudioDecoder.ipdl',
'PGMPContent.ipdl',
'PGMPDecryptor.ipdl',
'PGMPStorage.ipdl',
'PGMPTimer.ipdl',