Bug 1171499 - Defer processing GMP EncodingComplete() calls until intr shmem allocs are finished. r=jesup

This commit is contained in:
Ethan Hugg 2015-06-09 13:38:05 -07:00
parent 30621251ea
commit 16edb95969
3 changed files with 71 additions and 27 deletions

View File

@ -98,13 +98,15 @@ GMPContentChild::DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor)
PGMPVideoEncoderChild*
GMPContentChild::AllocPGMPVideoEncoderChild()
{
return new GMPVideoEncoderChild(this);
GMPVideoEncoderChild* actor = new GMPVideoEncoderChild(this);
actor->AddRef();
return actor;
}
bool
GMPContentChild::DeallocPGMPVideoEncoderChild(PGMPVideoEncoderChild* aActor)
{
delete aActor;
static_cast<GMPVideoEncoderChild*>(aActor)->Release();
return true;
}

View File

@ -9,21 +9,25 @@
#include "mozilla/unused.h"
#include "GMPVideoEncodedFrameImpl.h"
#include "GMPVideoi420FrameImpl.h"
#include "runnable_utils.h"
namespace mozilla {
namespace gmp {
GMPVideoEncoderChild::GMPVideoEncoderChild(GMPContentChild* aPlugin)
: GMPSharedMemManager(aPlugin),
mPlugin(aPlugin),
mVideoEncoder(nullptr),
mVideoHost(this)
: GMPSharedMemManager(aPlugin)
, mPlugin(aPlugin)
, mVideoEncoder(nullptr)
, mVideoHost(this)
, mNeedShmemIntrCount(0)
, mPendingEncodeComplete(false)
{
MOZ_ASSERT(mPlugin);
}
GMPVideoEncoderChild::~GMPVideoEncoderChild()
{
MOZ_ASSERT(!mNeedShmemIntrCount);
}
void
@ -162,6 +166,17 @@ GMPVideoEncoderChild::RecvSetPeriodicKeyFrames(const bool& aEnable)
bool
GMPVideoEncoderChild::RecvEncodingComplete()
{
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
if (mNeedShmemIntrCount) {
// There's a GMP blocked in Alloc() waiting for the CallNeedShem() to
// return a frame they can use. Don't call the GMP's EncodingComplete()
// now and don't delete the GMPVideoEncoderChild, defer processing the
// EncodingComplete() until once the Alloc() finishes.
mPendingEncodeComplete = true;
return true;
}
if (!mVideoEncoder) {
unused << Send__delete__(this);
return false;
@ -179,5 +194,41 @@ GMPVideoEncoderChild::RecvEncodingComplete()
return true;
}
bool
GMPVideoEncoderChild::Alloc(size_t aSize,
Shmem::SharedMemory::SharedMemoryType aType,
Shmem* aMem)
{
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
bool rv;
#ifndef SHMEM_ALLOC_IN_CHILD
++mNeedShmemIntrCount;
rv = CallNeedShmem(aSize, aMem);
--mNeedShmemIntrCount;
if (mPendingEncodeComplete) {
auto t = NewRunnableMethod(this, &GMPVideoEncoderChild::RecvEncodingComplete);
mPlugin->GMPMessageLoop()->PostTask(FROM_HERE, t);
}
#else
#ifdef GMP_SAFE_SHMEM
rv = AllocShmem(aSize, aType, aMem);
#else
rv = AllocUnsafeShmem(aSize, aType, aMem);
#endif
#endif
return rv;
}
void
GMPVideoEncoderChild::Dealloc(Shmem& aMem)
{
#ifndef SHMEM_ALLOC_IN_CHILD
SendParentShmemForPool(aMem);
#else
DeallocShmem(aMem);
#endif
}
} // namespace gmp
} // namespace mozilla

View File

@ -22,8 +22,9 @@ class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
public GMPSharedMemManager
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPVideoEncoderChild);
explicit GMPVideoEncoderChild(GMPContentChild* aPlugin);
virtual ~GMPVideoEncoderChild();
void Init(GMPVideoEncoder* aEncoder);
GMPVideoHostImpl& Host();
@ -35,28 +36,13 @@ public:
virtual void Error(GMPErr aError) override;
// GMPSharedMemManager
virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem) override
{
#ifndef SHMEM_ALLOC_IN_CHILD
return CallNeedShmem(aSize, aMem);
#else
#ifdef GMP_SAFE_SHMEM
return AllocShmem(aSize, aType, aMem);
#else
return AllocUnsafeShmem(aSize, aType, aMem);
#endif
#endif
}
virtual void Dealloc(Shmem& aMem) override
{
#ifndef SHMEM_ALLOC_IN_CHILD
SendParentShmemForPool(aMem);
#else
DeallocShmem(aMem);
#endif
}
virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType,
Shmem* aMem) override;
virtual void Dealloc(Shmem& aMem) override;
private:
virtual ~GMPVideoEncoderChild();
// PGMPVideoEncoderChild
virtual bool RecvInitEncode(const GMPVideoCodec& aCodecSettings,
InfallibleTArray<uint8_t>&& aCodecSpecific,
@ -76,6 +62,11 @@ private:
GMPContentChild* mPlugin;
GMPVideoEncoder* mVideoEncoder;
GMPVideoHostImpl mVideoHost;
// Non-zero when a GMP is blocked spinning the IPC message loop while
// waiting on an NeedShmem to complete.
int mNeedShmemIntrCount;
bool mPendingEncodeComplete;
};
} // namespace gmp