mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
ace406a462
commit
3af38cd4ea
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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__()
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
215
dom/media/gmp/GMPContentChild.cpp
Normal file
215
dom/media/gmp/GMPContentChild.cpp
Normal 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
|
58
dom/media/gmp/GMPContentChild.h
Normal file
58
dom/media/gmp/GMPContentChild.h
Normal 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_
|
293
dom/media/gmp/GMPContentParent.cpp
Normal file
293
dom/media/gmp/GMPContentParent.cpp
Normal 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
|
105
dom/media/gmp/GMPContentParent.h
Normal file
105
dom/media/gmp/GMPContentParent.h
Normal 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_
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
29
dom/media/gmp/PGMPContent.ipdl
Normal file
29
dom/media/gmp/PGMPContent.ipdl
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user