зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1020090: Proxy all GMP Shmem create/delete to parent and reduce allocation traffic. r=nical
This commit is contained in:
Родитель
0ca44dcac3
Коммит
31b1106753
|
@ -0,0 +1,85 @@
|
|||
/* -*- 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 "GMPSharedMemManager.h"
|
||||
#include "GMPMessageUtils.h"
|
||||
#include "mozilla/ipc/SharedMemory.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
// Really one set of pools on each side of the plugin API.
|
||||
|
||||
// YUV buffers go from Encoder parent to child; pool there, and then return
|
||||
// with Decoded() frames to the Decoder parent and goes into the parent pool.
|
||||
// Compressed (encoded) data goes from the Decoder parent to the child;
|
||||
// pool there, and then return with Encoded() frames and goes into the parent
|
||||
// pool.
|
||||
static nsTArray<ipc::Shmem> sGmpFreelist[GMPSharedMemManager::kGMPNumTypes];
|
||||
static uint32_t sGmpAllocated[GMPSharedMemManager::kGMPNumTypes]; // 0's
|
||||
|
||||
bool
|
||||
GMPSharedMemManager::MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem)
|
||||
{
|
||||
CheckThread();
|
||||
|
||||
// first look to see if we have a free buffer large enough
|
||||
for (uint32_t i = 0; i < sGmpFreelist[aClass].Length(); i++) {
|
||||
MOZ_ASSERT(sGmpFreelist[aClass][i].IsWritable());
|
||||
if (aSize <= sGmpFreelist[aClass][i].Size<uint8_t>()) {
|
||||
*aMem = sGmpFreelist[aClass][i];
|
||||
sGmpFreelist[aClass].RemoveElementAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find a buffer free with enough space; allocate one
|
||||
size_t pagesize = ipc::SharedMemory::SystemPageSize();
|
||||
aSize = (aSize + (pagesize-1)) & ~(pagesize-1); // round up to page size
|
||||
bool retval = Alloc(aSize, aType, aMem);
|
||||
if (retval) {
|
||||
sGmpAllocated[aClass]++;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPSharedMemManager::MgrDeallocShmem(GMPMemoryClasses aClass, ipc::Shmem& aMem)
|
||||
{
|
||||
CheckThread();
|
||||
|
||||
size_t size = aMem.Size<uint8_t>();
|
||||
size_t total = 0;
|
||||
// XXX This works; there are better pool algorithms. We need to avoid
|
||||
// "falling off a cliff" with too low a number
|
||||
if (sGmpFreelist[aClass].Length() > 10) {
|
||||
Dealloc(sGmpFreelist[aClass][0]);
|
||||
sGmpFreelist[aClass].RemoveElementAt(0);
|
||||
// The allocation numbers will be fubar on the Child!
|
||||
sGmpAllocated[aClass]--;
|
||||
}
|
||||
for (uint32_t i = 0; i < sGmpFreelist[aClass].Length(); i++) {
|
||||
MOZ_ASSERT(sGmpFreelist[aClass][i].IsWritable());
|
||||
total += sGmpFreelist[aClass][i].Size<uint8_t>();
|
||||
if (size < sGmpFreelist[aClass][i].Size<uint8_t>()) {
|
||||
sGmpFreelist[aClass].InsertElementAt(i, aMem);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
sGmpFreelist[aClass].AppendElement(aMem);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
GMPSharedMemManager::NumInUse(GMPMemoryClasses aClass)
|
||||
{
|
||||
return sGmpAllocated[aClass] - sGmpFreelist[aClass].Length();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
#define GMPSharedMemManager_h_
|
||||
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
@ -14,10 +15,40 @@ namespace gmp {
|
|||
class GMPSharedMemManager
|
||||
{
|
||||
public:
|
||||
virtual bool MgrAllocShmem(size_t aSize,
|
||||
typedef enum {
|
||||
kGMPFrameData = 0,
|
||||
kGMPEncodedData,
|
||||
kGMPNumTypes
|
||||
} GMPMemoryClasses;
|
||||
|
||||
// This is a heuristic - max of 10 free in the Child pool, plus those
|
||||
// in-use for the encoder and decoder at the given moment and not yet
|
||||
// returned to the parent pool (which is not included). If more than
|
||||
// this are needed, we presume the client has either crashed or hung
|
||||
// (perhaps temporarily).
|
||||
static const uint32_t kGMPBufLimit = 20;
|
||||
|
||||
GMPSharedMemManager() {}
|
||||
|
||||
virtual ~GMPSharedMemManager() {
|
||||
// XXX free everything in the freelist
|
||||
}
|
||||
|
||||
virtual bool MgrAllocShmem(GMPMemoryClasses aClass, size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem) = 0;
|
||||
virtual bool MgrDeallocShmem(ipc::Shmem& aMem) = 0;
|
||||
ipc::Shmem* aMem);
|
||||
virtual bool MgrDeallocShmem(GMPMemoryClasses aClass, ipc::Shmem& aMem);
|
||||
|
||||
// So we can know if data is "piling up" for the plugin - I.e. it's hung or crashed
|
||||
virtual uint32_t NumInUse(GMPMemoryClasses aClass);
|
||||
|
||||
// Parent and child impls will differ here
|
||||
virtual void CheckThread() = 0;
|
||||
|
||||
// These have to be implemented using the AllocShmem/etc provided by the IPDL-generated interfaces,
|
||||
// so have the Parent/Child implement them.
|
||||
virtual bool Alloc(size_t aSize, ipc::Shmem::SharedMemory::SharedMemoryType aType, ipc::Shmem* aMem) = 0;
|
||||
virtual void Dealloc(ipc::Shmem& aMem) = 0;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -80,22 +80,10 @@ GMPVideoDecoderChild::InputDataExhausted()
|
|||
SendInputDataExhausted();
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderChild::MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem)
|
||||
void
|
||||
GMPVideoDecoderChild::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
return AllocShmem(aSize, aType, aMem);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderChild::MgrDeallocShmem(Shmem& aMem)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
return DeallocShmem(aMem);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -127,6 +115,18 @@ GMPVideoDecoderChild::RecvDecode(const GMPVideoEncodedFrameData& aInputFrame,
|
|||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mVideoDecoder->Decode(f, aMissingFrames, aCodecSpecificInfo, aRenderTimeMs);
|
||||
|
||||
// Return SHM to sender to recycle
|
||||
//SendDecodeReturn(aInputFrame, aCodecSpecificInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderChild::RecvChildShmemForPool(Shmem& aFrameBuffer)
|
||||
{
|
||||
if (aFrameBuffer.IsWritable()) {
|
||||
mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData,
|
||||
aFrameBuffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,27 @@ public:
|
|||
virtual void InputDataExhausted() MOZ_OVERRIDE;
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual bool MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem) MOZ_OVERRIDE;
|
||||
virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
|
||||
virtual void CheckThread();
|
||||
virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#ifndef SHMEM_ALLOC_IN_CHILD
|
||||
SendParentShmemForPool(aMem);
|
||||
#else
|
||||
DeallocShmem(aMem);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
// PGMPVideoDecoderChild
|
||||
|
@ -48,6 +65,7 @@ private:
|
|||
const bool& missingFrames,
|
||||
const GMPCodecSpecificInfo& codecSpecificInfo,
|
||||
const int64_t& renderTimeMs) MOZ_OVERRIDE;
|
||||
virtual bool RecvChildShmemForPool(Shmem& aFrameBuffer) MOZ_OVERRIDE;
|
||||
virtual bool RecvReset() MOZ_OVERRIDE;
|
||||
virtual bool RecvDrain() MOZ_OVERRIDE;
|
||||
virtual bool RecvDecodingComplete() MOZ_OVERRIDE;
|
||||
|
|
|
@ -42,24 +42,6 @@ GMPVideoDecoderParent::Host()
|
|||
return mVideoHost;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
return AllocShmem(aSize, aType, aMem);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::MgrDeallocShmem(Shmem& aMem)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
return DeallocShmem(aMem);
|
||||
}
|
||||
|
||||
GMPVideoErr
|
||||
GMPVideoDecoderParent::InitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
GMPDecoderCallback* aCallback,
|
||||
|
@ -105,6 +87,14 @@ GMPVideoDecoderParent::Decode(GMPVideoEncodedFrame* aInputFrame,
|
|||
GMPVideoEncodedFrameData frameData;
|
||||
inputFrameImpl->RelinquishFrameData(frameData);
|
||||
|
||||
// Very rough kill-switch if the plugin stops processing. If it's merely
|
||||
// hung and continues, we'll come back to life eventually.
|
||||
// 3* is because we're using 3 buffers per frame for i420 data for now.
|
||||
if (NumInUse(kGMPFrameData) > 3*GMPSharedMemManager::kGMPBufLimit ||
|
||||
NumInUse(kGMPEncodedData) > GMPSharedMemManager::kGMPBufLimit) {
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
if (!SendDecode(frameData,
|
||||
aMissingFrames,
|
||||
aCodecSpecificInfo,
|
||||
|
@ -186,6 +176,12 @@ GMPVideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
|
|||
mVideoHost.ActorDestroyed();
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoDecoderParent::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::RecvDecoded(const GMPVideoi420FrameData& aDecodedFrame)
|
||||
{
|
||||
|
@ -240,6 +236,33 @@ GMPVideoDecoderParent::RecvInputDataExhausted()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::RecvParentShmemForPool(Shmem& aEncodedBuffer)
|
||||
{
|
||||
if (aEncodedBuffer.IsWritable()) {
|
||||
mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData,
|
||||
aEncodedBuffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::AnswerNeedShmem(const uint32_t& aFrameBufferSize,
|
||||
Shmem* aMem)
|
||||
{
|
||||
ipc::Shmem mem;
|
||||
|
||||
if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPFrameData,
|
||||
aFrameBufferSize,
|
||||
ipc::SharedMemory::TYPE_BASIC, &mem))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*aMem = mem;
|
||||
mem = ipc::Shmem();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::Recv__delete__()
|
||||
{
|
||||
|
|
|
@ -29,12 +29,6 @@ public:
|
|||
|
||||
GMPVideoHostImpl& Host();
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual bool MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem) MOZ_OVERRIDE;
|
||||
virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
|
||||
|
||||
// GMPVideoDecoder
|
||||
virtual GMPVideoErr InitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
GMPDecoderCallback* aCallback,
|
||||
|
@ -47,6 +41,21 @@ public:
|
|||
virtual GMPVideoErr Drain() MOZ_OVERRIDE;
|
||||
virtual void DecodingComplete() MOZ_OVERRIDE;
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual void CheckThread();
|
||||
virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
|
||||
{
|
||||
#ifdef GMP_SAFE_SHMEM
|
||||
return AllocShmem(aSize, aType, aMem);
|
||||
#else
|
||||
return AllocUnsafeShmem(aSize, aType, aMem);
|
||||
#endif
|
||||
}
|
||||
virtual void Dealloc(Shmem& aMem)
|
||||
{
|
||||
DeallocShmem(aMem);
|
||||
}
|
||||
|
||||
private:
|
||||
~GMPVideoDecoderParent();
|
||||
|
||||
|
@ -56,6 +65,9 @@ private:
|
|||
virtual bool RecvReceivedDecodedReferenceFrame(const uint64_t& aPictureId) MOZ_OVERRIDE;
|
||||
virtual bool RecvReceivedDecodedFrame(const uint64_t& aPictureId) MOZ_OVERRIDE;
|
||||
virtual bool RecvInputDataExhausted() MOZ_OVERRIDE;
|
||||
virtual bool RecvParentShmemForPool(Shmem& aEncodedBuffer) MOZ_OVERRIDE;
|
||||
virtual bool AnswerNeedShmem(const uint32_t& aFrameBufferSize,
|
||||
Shmem* aMem) MOZ_OVERRIDE;
|
||||
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
||||
|
||||
bool mCanSendMessages;
|
||||
|
|
|
@ -99,7 +99,7 @@ void
|
|||
GMPVideoEncodedFrameImpl::DestroyBuffer()
|
||||
{
|
||||
if (mHost && mBuffer.IsWritable()) {
|
||||
mHost->SharedMemMgr()->MgrDeallocShmem(mBuffer);
|
||||
mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData, mBuffer);
|
||||
}
|
||||
mBuffer = ipc::Shmem();
|
||||
}
|
||||
|
@ -107,15 +107,16 @@ GMPVideoEncodedFrameImpl::DestroyBuffer()
|
|||
GMPVideoErr
|
||||
GMPVideoEncodedFrameImpl::CreateEmptyFrame(uint32_t aSize)
|
||||
{
|
||||
if (aSize == 0) {
|
||||
DestroyBuffer();
|
||||
|
||||
if (aSize != 0) {
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(aSize, ipc::SharedMemory::TYPE_BASIC, &mBuffer) ||
|
||||
} else if (aSize > AllocatedSize()) {
|
||||
DestroyBuffer();
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData, aSize,
|
||||
ipc::SharedMemory::TYPE_BASIC, &mBuffer) ||
|
||||
!Buffer()) {
|
||||
return GMPVideoAllocErr;
|
||||
}
|
||||
}
|
||||
|
||||
mSize = aSize;
|
||||
|
||||
return GMPVideoNoErr;
|
||||
|
@ -138,7 +139,7 @@ GMPVideoEncodedFrameImpl::CopyFrame(const GMPVideoEncodedFrame& aFrame)
|
|||
mTimeStamp = f.mTimeStamp;
|
||||
mCaptureTime_ms = f.mCaptureTime_ms;
|
||||
mFrameType = f.mFrameType;
|
||||
mSize = f.mSize;
|
||||
mSize = f.mSize; // already set...
|
||||
mCompleteFrame = f.mCompleteFrame;
|
||||
// Don't copy host, that should have been set properly on object creation via host.
|
||||
|
||||
|
@ -217,7 +218,8 @@ GMPVideoEncodedFrameImpl::SetAllocatedSize(uint32_t aNewSize)
|
|||
}
|
||||
|
||||
ipc::Shmem new_mem;
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(aNewSize, ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData, aNewSize,
|
||||
ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
|
||||
!new_mem.get<uint8_t>()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "GMPVideoEncodedFrameImpl.h"
|
||||
#include "GMPVideoi420FrameImpl.h"
|
||||
|
||||
using mozilla::ipc::ProcessChild;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
|
@ -54,22 +56,10 @@ GMPVideoEncoderChild::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
|||
aEncodedFrame->Destroy();
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderChild::MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem)
|
||||
void
|
||||
GMPVideoEncoderChild::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
return AllocShmem(aSize, aType, aMem);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderChild::MgrDeallocShmem(Shmem& aMem)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
return DeallocShmem(aMem);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -102,13 +92,22 @@ GMPVideoEncoderChild::RecvEncode(const GMPVideoi420FrameData& aInputFrame,
|
|||
for (uint32_t i = 0; i < aFrameTypes.Length(); i++) {
|
||||
frameTypes[i] = static_cast<GMPVideoFrameType>(aFrameTypes[i]);
|
||||
}
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mVideoEncoder->Encode(f, aCodecSpecificInfo, frameTypes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderChild::RecvChildShmemForPool(Shmem& aEncodedBuffer)
|
||||
{
|
||||
if (aEncodedBuffer.IsWritable()) {
|
||||
mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData,
|
||||
aEncodedBuffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderChild::RecvSetChannelParameters(const uint32_t& aPacketLoss,
|
||||
const uint32_t& aRTT)
|
||||
|
|
|
@ -33,10 +33,27 @@ public:
|
|||
const GMPCodecSpecificInfo& aCodecSpecificInfo) MOZ_OVERRIDE;
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual bool MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem) MOZ_OVERRIDE;
|
||||
virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
|
||||
virtual void CheckThread();
|
||||
virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#ifndef SHMEM_ALLOC_IN_CHILD
|
||||
SendParentShmemForPool(aMem);
|
||||
#else
|
||||
DeallocShmem(aMem);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
// PGMPVideoEncoderChild
|
||||
|
@ -46,6 +63,7 @@ private:
|
|||
virtual bool RecvEncode(const GMPVideoi420FrameData& aInputFrame,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
const InfallibleTArray<int>& aFrameTypes) MOZ_OVERRIDE;
|
||||
virtual bool RecvChildShmemForPool(Shmem& aEncodedBuffer) MOZ_OVERRIDE;
|
||||
virtual bool RecvSetChannelParameters(const uint32_t& aPacketLoss,
|
||||
const uint32_t& aRTT) MOZ_OVERRIDE;
|
||||
virtual bool RecvSetRates(const uint32_t& aNewBitRate,
|
||||
|
|
|
@ -43,24 +43,6 @@ GMPVideoEncoderParent::Host()
|
|||
return mVideoHost;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderParent::MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
return AllocShmem(aSize, aType, aMem);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderParent::MgrDeallocShmem(Shmem& aMem)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
return DeallocShmem(aMem);
|
||||
}
|
||||
|
||||
GMPVideoErr
|
||||
GMPVideoEncoderParent::InitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
GMPEncoderCallback* aCallback,
|
||||
|
@ -106,6 +88,14 @@ GMPVideoEncoderParent::Encode(GMPVideoi420Frame* aInputFrame,
|
|||
GMPVideoi420FrameData frameData;
|
||||
inputFrameImpl->InitFrameData(frameData);
|
||||
|
||||
// Very rough kill-switch if the plugin stops processing. If it's merely
|
||||
// hung and continues, we'll come back to life eventually.
|
||||
// 3* is because we're using 3 buffers per frame for i420 data for now.
|
||||
if (NumInUse(kGMPFrameData) > 3*GMPSharedMemManager::kGMPBufLimit ||
|
||||
NumInUse(kGMPEncodedData) > GMPSharedMemManager::kGMPBufLimit) {
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
InfallibleTArray<int> frameTypes;
|
||||
frameTypes.SetCapacity(aFrameTypes.size());
|
||||
for (std::vector<int>::size_type i = 0; i != aFrameTypes.size(); i++) {
|
||||
|
@ -210,6 +200,12 @@ GMPVideoEncoderParent::ActorDestroy(ActorDestroyReason aWhy)
|
|||
mVideoHost.ActorDestroyed();
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoEncoderParent::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderParent::RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo)
|
||||
|
@ -223,6 +219,35 @@ GMPVideoEncoderParent::RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame
|
|||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->Encoded(f, aCodecSpecificInfo);
|
||||
|
||||
// Return SHM to sender to recycle
|
||||
//SendEncodedReturn(aEncodedFrame, aCodecSpecificInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderParent::RecvParentShmemForPool(Shmem& aFrameBuffer)
|
||||
{
|
||||
if (aFrameBuffer.IsWritable()) {
|
||||
mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData,
|
||||
aFrameBuffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderParent::AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
|
||||
Shmem* aMem)
|
||||
{
|
||||
ipc::Shmem mem;
|
||||
|
||||
if (!mVideoHost.SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData,
|
||||
aEncodedBufferSize,
|
||||
ipc::SharedMemory::TYPE_BASIC, &mem))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*aMem = mem;
|
||||
mem = ipc::Shmem();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,12 +29,6 @@ public:
|
|||
|
||||
GMPVideoHostImpl& Host();
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual bool MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem) MOZ_OVERRIDE;
|
||||
virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
|
||||
|
||||
// GMPVideoEncoder
|
||||
virtual GMPVideoErr InitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
GMPEncoderCallback* aCallback,
|
||||
|
@ -48,6 +42,21 @@ public:
|
|||
virtual GMPVideoErr SetPeriodicKeyFrames(bool aEnable) MOZ_OVERRIDE;
|
||||
virtual void EncodingComplete() MOZ_OVERRIDE;
|
||||
|
||||
// GMPSharedMemManager
|
||||
virtual void CheckThread();
|
||||
virtual bool Alloc(size_t aSize, Shmem::SharedMemory::SharedMemoryType aType, Shmem* aMem)
|
||||
{
|
||||
#ifdef GMP_SAFE_SHMEM
|
||||
return AllocShmem(aSize, aType, aMem);
|
||||
#else
|
||||
return AllocUnsafeShmem(aSize, aType, aMem);
|
||||
#endif
|
||||
}
|
||||
virtual void Dealloc(Shmem& aMem)
|
||||
{
|
||||
DeallocShmem(aMem);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~GMPVideoEncoderParent();
|
||||
|
||||
|
@ -55,6 +64,9 @@ private:
|
|||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
virtual bool RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo) MOZ_OVERRIDE;
|
||||
virtual bool RecvParentShmemForPool(Shmem& aFrameBuffer) MOZ_OVERRIDE;
|
||||
virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
|
||||
Shmem* aMem) MOZ_OVERRIDE;
|
||||
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
||||
|
||||
bool mCanSendMessages;
|
||||
|
|
|
@ -84,7 +84,8 @@ GMPPlaneImpl::MaybeResize(int32_t aNewSize) {
|
|||
}
|
||||
|
||||
ipc::Shmem new_mem;
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(aNewSize, ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPFrameData, aNewSize,
|
||||
ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
|
||||
!new_mem.get<uint8_t>()) {
|
||||
return GMPVideoAllocErr;
|
||||
}
|
||||
|
@ -104,7 +105,7 @@ void
|
|||
GMPPlaneImpl::DestroyBuffer()
|
||||
{
|
||||
if (mHost && mBuffer.IsWritable()) {
|
||||
mHost->SharedMemMgr()->MgrDeallocShmem(mBuffer);
|
||||
mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData, mBuffer);
|
||||
}
|
||||
mBuffer = ipc::Shmem();
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@ include protocol PGMPVideoEncoder;
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
async protocol PGMP
|
||||
intr protocol PGMP
|
||||
{
|
||||
manages PGMPVideoDecoder;
|
||||
manages PGMPVideoEncoder;
|
||||
child:
|
||||
PGMPVideoDecoder();
|
||||
PGMPVideoEncoder();
|
||||
async PGMPVideoDecoder();
|
||||
async PGMPVideoEncoder();
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -14,25 +14,31 @@ include "GMPMessageUtils.h";
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
async protocol PGMPVideoDecoder
|
||||
intr protocol PGMPVideoDecoder
|
||||
{
|
||||
manager PGMP;
|
||||
child:
|
||||
InitDecode(GMPVideoCodec aCodecSettings,
|
||||
async InitDecode(GMPVideoCodec aCodecSettings,
|
||||
int32_t aCoreCount);
|
||||
Decode(GMPVideoEncodedFrameData aInputFrame,
|
||||
async Decode(GMPVideoEncodedFrameData aInputFrame,
|
||||
bool aMissingFrames,
|
||||
GMPCodecSpecificInfo aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs);
|
||||
Reset();
|
||||
Drain();
|
||||
DecodingComplete();
|
||||
async Reset();
|
||||
async Drain();
|
||||
async DecodingComplete();
|
||||
async ChildShmemForPool(Shmem aFrameBuffer);
|
||||
|
||||
parent:
|
||||
__delete__();
|
||||
Decoded(GMPVideoi420FrameData aDecodedFrame);
|
||||
ReceivedDecodedReferenceFrame(uint64_t aPictureId);
|
||||
ReceivedDecodedFrame(uint64_t aPictureId);
|
||||
InputDataExhausted();
|
||||
async __delete__();
|
||||
async Decoded(GMPVideoi420FrameData aDecodedFrame);
|
||||
async ReceivedDecodedReferenceFrame(uint64_t aPictureId);
|
||||
async ReceivedDecodedFrame(uint64_t aPictureId);
|
||||
async InputDataExhausted();
|
||||
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
|
||||
intr NeedShmem(uint32_t aFrameBufferSize) returns (Shmem aMem);
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -14,25 +14,30 @@ include "GMPMessageUtils.h";
|
|||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
async protocol PGMPVideoEncoder
|
||||
intr protocol PGMPVideoEncoder
|
||||
{
|
||||
manager PGMP;
|
||||
child:
|
||||
InitEncode(GMPVideoCodec aCodecSettings,
|
||||
async InitEncode(GMPVideoCodec aCodecSettings,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize);
|
||||
Encode(GMPVideoi420FrameData aInputFrame,
|
||||
async Encode(GMPVideoi420FrameData aInputFrame,
|
||||
GMPCodecSpecificInfo aCodecSpecificInfo,
|
||||
int[] aFrameTypes);
|
||||
SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT);
|
||||
SetRates(uint32_t aNewBitRate, uint32_t aFrameRate);
|
||||
SetPeriodicKeyFrames(bool aEnable);
|
||||
EncodingComplete();
|
||||
async SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT);
|
||||
async SetRates(uint32_t aNewBitRate, uint32_t aFrameRate);
|
||||
async SetPeriodicKeyFrames(bool aEnable);
|
||||
async EncodingComplete();
|
||||
async ChildShmemForPool(Shmem aEncodedBuffer);
|
||||
|
||||
parent:
|
||||
__delete__();
|
||||
Encoded(GMPVideoEncodedFrameData aEncodedFrame,
|
||||
async __delete__();
|
||||
async Encoded(GMPVideoEncodedFrameData aEncodedFrame,
|
||||
GMPCodecSpecificInfo aCodecSpecificInfo);
|
||||
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
|
||||
intr NeedShmem(uint32_t aEncodedBufferSize) returns (Shmem aMem);
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
|
|
@ -48,6 +48,7 @@ UNIFIED_SOURCES += [
|
|||
'GMPProcessChild.cpp',
|
||||
'GMPProcessParent.cpp',
|
||||
'GMPService.cpp',
|
||||
'GMPSharedMemManager.cpp',
|
||||
'GMPVideoDecoderChild.cpp',
|
||||
'GMPVideoDecoderParent.cpp',
|
||||
'GMPVideoEncodedFrameImpl.cpp',
|
||||
|
@ -70,6 +71,9 @@ LIBRARY_NAME = 'mozgmp'
|
|||
if CONFIG['GKMEDIAS_SHARED_LIBRARY']:
|
||||
NO_VISIBILITY_FLAGS = True
|
||||
|
||||
# comment this out to use Unsafe Shmem for more performance
|
||||
DEFINES['GMP_SAFE_SHMEM'] = True
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
|
Загрузка…
Ссылка в новой задаче