mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out 5 changesets (bug 1020760, bug 1035653, bug 1020090) for leaks on a CLOSED TREE.
Backed out changeset f0b20e3db93c (bug 1020760) Backed out changeset 412b654e5cd2 (bug 1035653) Backed out changeset 01ba0892af29 (bug 1020760) Backed out changeset c7de1f4b078f (bug 1020760) Backed out changeset 96aa9d33a1f5 (bug 1020090)
This commit is contained in:
parent
671530fba0
commit
1dea3b300a
@ -7,24 +7,9 @@
|
||||
#define GMPMessageUtils_h_
|
||||
|
||||
#include "gmp-video-codec.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPErr>
|
||||
: public ContiguousEnumSerializer<GMPErr,
|
||||
GMPNoErr,
|
||||
GMPLastErr>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPVideoFrameType>
|
||||
: public ContiguousEnumSerializer<GMPVideoFrameType,
|
||||
kGMPKeyFrame,
|
||||
kGMPSkipFrame>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPVideoCodecComplexity>
|
||||
: public ContiguousEnumSerializer<GMPVideoCodecComplexity,
|
||||
@ -54,11 +39,57 @@ struct ParamTraits<GMPVideoCodecMode>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPBufferType>
|
||||
: public ContiguousEnumSerializer<GMPBufferType,
|
||||
GMP_BufferSingle,
|
||||
GMP_BufferInvalid>
|
||||
{};
|
||||
struct ParamTraits<GMPVideoCodecVP8>
|
||||
{
|
||||
typedef GMPVideoCodecVP8 paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mPictureLossIndicationOn);
|
||||
WriteParam(aMsg, aParam.mFeedbackModeOn);
|
||||
WriteParam(aMsg, aParam.mComplexity);
|
||||
WriteParam(aMsg, aParam.mResilience);
|
||||
WriteParam(aMsg, aParam.mNumberOfTemporalLayers);
|
||||
WriteParam(aMsg, aParam.mDenoisingOn);
|
||||
WriteParam(aMsg, aParam.mErrorConcealmentOn);
|
||||
WriteParam(aMsg, aParam.mAutomaticResizeOn);
|
||||
WriteParam(aMsg, aParam.mFrameDroppingOn);
|
||||
WriteParam(aMsg, aParam.mKeyFrameInterval);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
if (ReadParam(aMsg, aIter, &(aResult->mPictureLossIndicationOn)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mFeedbackModeOn)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mComplexity)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mResilience)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mNumberOfTemporalLayers)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mDenoisingOn)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mErrorConcealmentOn)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mAutomaticResizeOn)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mFrameDroppingOn)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mKeyFrameInterval))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
aLog->append(StringPrintf(L"[%d, %d, %d, %d, %u, %d, %d, %d, %d, %d]",
|
||||
aParam.mPictureLossIndicationOn,
|
||||
aParam.mFeedbackModeOn,
|
||||
aParam.mComplexity,
|
||||
aParam.mResilience,
|
||||
aParam.mNumberOfTemporalLayers,
|
||||
aParam.mDenoisingOn,
|
||||
aParam.mErrorConcealmentOn,
|
||||
aParam.mAutomaticResizeOn,
|
||||
aParam.mFrameDroppingOn,
|
||||
aParam.mKeyFrameInterval));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPSimulcastStream>
|
||||
@ -105,7 +136,6 @@ struct ParamTraits<GMPVideoCodec>
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mGMPApiVersion);
|
||||
WriteParam(aMsg, aParam.mCodecType);
|
||||
WriteParam(aMsg, nsAutoCString(aParam.mPLName));
|
||||
WriteParam(aMsg, aParam.mPLType);
|
||||
@ -115,8 +145,11 @@ struct ParamTraits<GMPVideoCodec>
|
||||
WriteParam(aMsg, aParam.mMaxBitrate);
|
||||
WriteParam(aMsg, aParam.mMinBitrate);
|
||||
WriteParam(aMsg, aParam.mMaxFramerate);
|
||||
WriteParam(aMsg, aParam.mFrameDroppingOn);
|
||||
WriteParam(aMsg, aParam.mKeyFrameInterval);
|
||||
if (aParam.mCodecType == kGMPVideoCodecVP8) {
|
||||
WriteParam(aMsg, aParam.mCodecSpecific.mVP8);
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Serializing unknown codec type!");
|
||||
}
|
||||
WriteParam(aMsg, aParam.mQPMax);
|
||||
WriteParam(aMsg, aParam.mNumberOfSimulcastStreams);
|
||||
for (uint32_t i = 0; i < aParam.mNumberOfSimulcastStreams; i++) {
|
||||
@ -127,11 +160,6 @@ struct ParamTraits<GMPVideoCodec>
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
// NOTE: make sure this matches any versions supported
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->mGMPApiVersion)) ||
|
||||
aResult->mGMPApiVersion != kGMPVersion33) {
|
||||
return false;
|
||||
}
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->mCodecType))) {
|
||||
return false;
|
||||
}
|
||||
@ -150,9 +178,16 @@ struct ParamTraits<GMPVideoCodec>
|
||||
!ReadParam(aMsg, aIter, &(aResult->mStartBitrate)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mMaxBitrate)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mMinBitrate)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mMaxFramerate)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mFrameDroppingOn)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mKeyFrameInterval))) {
|
||||
!ReadParam(aMsg, aIter, &(aResult->mMaxFramerate))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aResult->mCodecType == kGMPVideoCodecVP8) {
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->mCodecSpecific.mVP8))) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(false, "De-serializing unknown codec type!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -191,6 +226,104 @@ struct ParamTraits<GMPVideoCodec>
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPCodecSpecificInfoVP8>
|
||||
{
|
||||
typedef GMPCodecSpecificInfoVP8 paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mHasReceivedSLI);
|
||||
WriteParam(aMsg, aParam.mPictureIdSLI);
|
||||
WriteParam(aMsg, aParam.mHasReceivedRPSI);
|
||||
WriteParam(aMsg, aParam.mPictureIdRPSI);
|
||||
WriteParam(aMsg, aParam.mPictureId);
|
||||
WriteParam(aMsg, aParam.mNonReference);
|
||||
WriteParam(aMsg, aParam.mSimulcastIdx);
|
||||
WriteParam(aMsg, aParam.mTemporalIdx);
|
||||
WriteParam(aMsg, aParam.mLayerSync);
|
||||
WriteParam(aMsg, aParam.mTL0PicIdx);
|
||||
WriteParam(aMsg, aParam.mKeyIdx);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
if (ReadParam(aMsg, aIter, &(aResult->mHasReceivedSLI)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mPictureIdSLI)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mHasReceivedRPSI)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mPictureIdRPSI)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mPictureId)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mNonReference)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mSimulcastIdx)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mTemporalIdx)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mLayerSync)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mTL0PicIdx)) &&
|
||||
ReadParam(aMsg, aIter, &(aResult->mKeyIdx))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
aLog->append(StringPrintf(L"[%d, %u, %d, %u, %d, %d, %u, %u, %d, %d, %d]",
|
||||
aParam.mHasReceivedSLI,
|
||||
aParam.mPictureIdSLI,
|
||||
aParam.mHasReceivedRPSI,
|
||||
aParam.mPictureIdRPSI,
|
||||
aParam.mPictureId,
|
||||
aParam.mNonReference,
|
||||
aParam.mSimulcastIdx,
|
||||
aParam.mTemporalIdx,
|
||||
aParam.mLayerSync,
|
||||
aParam.mTL0PicIdx,
|
||||
aParam.mKeyIdx));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<GMPCodecSpecificInfo>
|
||||
{
|
||||
typedef GMPCodecSpecificInfo paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mCodecType);
|
||||
if (aParam.mCodecType == kGMPVideoCodecVP8) {
|
||||
WriteParam(aMsg, aParam.mCodecSpecific.mVP8);
|
||||
} else {
|
||||
MOZ_ASSERT(false, "Serializing unknown codec type!");
|
||||
}
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->mCodecType))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aResult->mCodecType == kGMPVideoCodecVP8) {
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->mCodecSpecific.mVP8))) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(false, "De-serializing unknown codec type!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
const char* codecName = nullptr;
|
||||
if (aParam.mCodecType == kGMPVideoCodecVP8) {
|
||||
codecName = "VP8";
|
||||
}
|
||||
aLog->append(StringPrintf(L"[%s]", codecName));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // GMPMessageUtils_h_
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIFile.h"
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
|
||||
class nsILineInputStream;
|
||||
class nsIThread;
|
||||
@ -39,7 +38,7 @@ enum GMPState {
|
||||
class GMPParent MOZ_FINAL : public PGMPParent
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(GMPParent)
|
||||
NS_INLINE_DECL_REFCOUNTING(GMPParent)
|
||||
|
||||
GMPParent();
|
||||
|
||||
|
@ -27,7 +27,6 @@ public:
|
||||
void Run()
|
||||
{
|
||||
mTask->Run();
|
||||
mTask->Destroy();
|
||||
mTask = nullptr;
|
||||
}
|
||||
|
||||
@ -36,7 +35,7 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
GMPTask* mTask;
|
||||
nsAutoPtr<GMPTask> mTask;
|
||||
};
|
||||
|
||||
class SyncRunnable MOZ_FINAL
|
||||
@ -72,7 +71,6 @@ public:
|
||||
void Run()
|
||||
{
|
||||
mTask->Run();
|
||||
mTask->Destroy();
|
||||
mTask = nullptr;
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
mDone = true;
|
||||
@ -85,7 +83,7 @@ private:
|
||||
}
|
||||
|
||||
bool mDone;
|
||||
GMPTask* mTask;
|
||||
nsAutoPtr<GMPTask> mTask;
|
||||
MessageLoop* mMessageLoop;
|
||||
Monitor mMonitor;
|
||||
};
|
||||
@ -110,6 +108,7 @@ RunOnMainThread(GMPTask* aTask)
|
||||
}
|
||||
|
||||
nsRefPtr<Runnable> r = new Runnable(aTask);
|
||||
|
||||
sMainLoop->PostTask(FROM_HERE, NewRunnableMethod(r.get(), &Runnable::Run));
|
||||
|
||||
return GMPNoErr;
|
||||
@ -153,9 +152,6 @@ InitPlatformAPI(GMPPlatformAPI& aPlatformAPI)
|
||||
aPlatformAPI.runonmainthread = &RunOnMainThread;
|
||||
aPlatformAPI.syncrunonmainthread = &SyncRunOnMainThread;
|
||||
aPlatformAPI.createmutex = &CreateMutex;
|
||||
aPlatformAPI.createrecord = nullptr;
|
||||
aPlatformAPI.settimer = nullptr;
|
||||
aPlatformAPI.getcurrenttime = nullptr;
|
||||
}
|
||||
|
||||
GMPThreadImpl::GMPThreadImpl()
|
||||
|
@ -13,8 +13,6 @@
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPChild;
|
||||
|
||||
void InitPlatformAPI(GMPPlatformAPI& aPlatformAPI);
|
||||
|
||||
class GMPThreadImpl : public GMPThread
|
||||
|
@ -183,7 +183,7 @@ NS_IMETHODIMP
|
||||
GeckoMediaPluginService::GetGMPVideoDecoder(nsTArray<nsCString>* aTags,
|
||||
const nsAString& aOrigin,
|
||||
GMPVideoHost** aOutVideoHost,
|
||||
GMPVideoDecoderProxy** aGMPVD)
|
||||
GMPVideoDecoder** aGMPVD)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
NS_ENSURE_ARG(aTags && aTags->Length() > 0);
|
||||
@ -217,7 +217,7 @@ NS_IMETHODIMP
|
||||
GeckoMediaPluginService::GetGMPVideoEncoder(nsTArray<nsCString>* aTags,
|
||||
const nsAString& aOrigin,
|
||||
GMPVideoHost** aOutVideoHost,
|
||||
GMPVideoEncoderProxy** aGMPVE)
|
||||
GMPVideoEncoder** aGMPVE)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
|
||||
NS_ENSURE_ARG(aTags && aTags->Length() > 0);
|
||||
@ -364,19 +364,6 @@ GeckoMediaPluginService::SelectPluginForAPI(const nsAString& aOrigin,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class CreateGMPParentTask : public nsRunnable {
|
||||
public:
|
||||
NS_IMETHOD Run() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mParent = new GMPParent();
|
||||
return NS_OK;
|
||||
}
|
||||
already_AddRefed<GMPParent> GetParent() {
|
||||
return mParent.forget();
|
||||
}
|
||||
private:
|
||||
nsRefPtr<GMPParent> mParent;
|
||||
};
|
||||
|
||||
void
|
||||
GeckoMediaPluginService::AddOnGMPThread(const nsAString& aDirectory)
|
||||
@ -389,16 +376,9 @@ GeckoMediaPluginService::AddOnGMPThread(const nsAString& aDirectory)
|
||||
return;
|
||||
}
|
||||
|
||||
// The GMPParent inherits from IToplevelProtocol, which must be created
|
||||
// on the main thread to be threadsafe. See Bug 1035653.
|
||||
nsRefPtr<CreateGMPParentTask> task(new CreateGMPParentTask());
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
MOZ_ASSERT(mainThread);
|
||||
mozilla::SyncRunnable::DispatchToThread(mainThread, task);
|
||||
nsRefPtr<GMPParent> gmp = task->GetParent();
|
||||
nsRefPtr<GMPParent> gmp = new GMPParent();
|
||||
rv = gmp->Init(directory);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Can't Create GMPParent");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
#ifndef GMPService_h_
|
||||
#define GMPService_h_
|
||||
|
||||
#include "nsString.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsTArray.h"
|
||||
|
@ -1,85 +0,0 @@
|
||||
/* -*- 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,7 +7,6 @@
|
||||
#define GMPSharedMemManager_h_
|
||||
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
@ -15,40 +14,10 @@ namespace gmp {
|
||||
class GMPSharedMemManager
|
||||
{
|
||||
public:
|
||||
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,
|
||||
virtual bool MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
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;
|
||||
ipc::Shmem* aMem) = 0;
|
||||
virtual bool MgrDeallocShmem(ipc::Shmem& aMem) = 0;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
@ -8,10 +8,10 @@ namespace gmp {
|
||||
|
||||
struct GMPVideoEncodedFrameData
|
||||
{
|
||||
int64_t mCaptureTime_ms;
|
||||
uint32_t mEncodedWidth;
|
||||
uint32_t mEncodedHeight;
|
||||
uint64_t mTimestamp; // microseconds
|
||||
uint64_t mDuration; // microseconds
|
||||
uint32_t mTimeStamp;
|
||||
uint32_t mFrameType;
|
||||
uint32_t mSize;
|
||||
Shmem mBuffer;
|
||||
@ -32,8 +32,8 @@ struct GMPVideoi420FrameData
|
||||
GMPPlaneData mVPlane;
|
||||
int32_t mWidth;
|
||||
int32_t mHeight;
|
||||
uint64_t mTimestamp; // microseconds
|
||||
uint64_t mDuration; // microseconds
|
||||
uint32_t mTimestamp;
|
||||
int64_t mRenderTime_ms;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -80,31 +80,26 @@ GMPVideoDecoderChild::InputDataExhausted()
|
||||
SendInputDataExhausted();
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoDecoderChild::DrainComplete()
|
||||
bool
|
||||
GMPVideoDecoderChild::MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
SendDrainComplete();
|
||||
return AllocShmem(aSize, aType, aMem);
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoDecoderChild::ResetComplete()
|
||||
bool
|
||||
GMPVideoDecoderChild::MgrDeallocShmem(Shmem& aMem)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
SendResetComplete();
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoDecoderChild::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
return DeallocShmem(aMem);
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderChild::RecvInitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
const int32_t& aCoreCount)
|
||||
{
|
||||
if (!mVideoDecoder) {
|
||||
@ -112,19 +107,15 @@ GMPVideoDecoderChild::RecvInitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
}
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mVideoDecoder->InitDecode(aCodecSettings,
|
||||
aCodecSpecific.Elements(),
|
||||
aCodecSpecific.Length(),
|
||||
this,
|
||||
aCoreCount);
|
||||
mVideoDecoder->InitDecode(aCodecSettings, this, aCoreCount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderChild::RecvDecode(const GMPVideoEncodedFrameData& aInputFrame,
|
||||
const bool& aMissingFrames,
|
||||
const GMPBufferType& aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
const int64_t& aRenderTimeMs)
|
||||
{
|
||||
if (!mVideoDecoder) {
|
||||
@ -134,26 +125,11 @@ GMPVideoDecoderChild::RecvDecode(const GMPVideoEncodedFrameData& aInputFrame,
|
||||
auto f = new GMPVideoEncodedFrameImpl(aInputFrame, &mVideoHost);
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mVideoDecoder->Decode(f,
|
||||
aMissingFrames,
|
||||
aBufferType,
|
||||
aCodecSpecificInfo.Elements(),
|
||||
aCodecSpecificInfo.Length(),
|
||||
aRenderTimeMs);
|
||||
mVideoDecoder->Decode(f, aMissingFrames, aCodecSpecificInfo, aRenderTimeMs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderChild::RecvChildShmemForPool(Shmem& aFrameBuffer)
|
||||
{
|
||||
if (aFrameBuffer.IsWritable()) {
|
||||
mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData,
|
||||
aFrameBuffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderChild::RecvReset()
|
||||
{
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "gmp-video-decode.h"
|
||||
#include "GMPSharedMemManager.h"
|
||||
#include "GMPVideoHost.h"
|
||||
#include "mozilla/gmp/GMPTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
@ -19,7 +18,7 @@ namespace gmp {
|
||||
class GMPChild;
|
||||
|
||||
class GMPVideoDecoderChild : public PGMPVideoDecoderChild,
|
||||
public GMPVideoDecoderCallback,
|
||||
public GMPDecoderCallback,
|
||||
public GMPSharedMemManager
|
||||
{
|
||||
public:
|
||||
@ -29,48 +28,26 @@ public:
|
||||
void Init(GMPVideoDecoder* aDecoder);
|
||||
GMPVideoHostImpl& Host();
|
||||
|
||||
// GMPVideoDecoderCallback
|
||||
// GMPDecoderCallback
|
||||
virtual void Decoded(GMPVideoi420Frame* decodedFrame) MOZ_OVERRIDE;
|
||||
virtual void ReceivedDecodedReferenceFrame(const uint64_t pictureId) MOZ_OVERRIDE;
|
||||
virtual void ReceivedDecodedFrame(const uint64_t pictureId) MOZ_OVERRIDE;
|
||||
virtual void InputDataExhausted() MOZ_OVERRIDE;
|
||||
virtual void DrainComplete() MOZ_OVERRIDE;
|
||||
virtual void ResetComplete() MOZ_OVERRIDE;
|
||||
|
||||
// GMPSharedMemManager
|
||||
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
|
||||
}
|
||||
virtual bool MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem) MOZ_OVERRIDE;
|
||||
virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// PGMPVideoDecoderChild
|
||||
virtual bool RecvInitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
const int32_t& aCoreCount) MOZ_OVERRIDE;
|
||||
virtual bool RecvDecode(const GMPVideoEncodedFrameData& aInputFrame,
|
||||
const bool& aMissingFrames,
|
||||
const GMPBufferType& aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const int64_t& aRenderTimeMs) MOZ_OVERRIDE;
|
||||
virtual bool RecvChildShmemForPool(Shmem& aFrameBuffer) MOZ_OVERRIDE;
|
||||
virtual bool RecvInitDecode(const GMPVideoCodec& codecSettings,
|
||||
const int32_t& coreCount) MOZ_OVERRIDE;
|
||||
virtual bool RecvDecode(const GMPVideoEncodedFrameData& inputFrame,
|
||||
const bool& missingFrames,
|
||||
const GMPCodecSpecificInfo& codecSpecificInfo,
|
||||
const int64_t& renderTimeMs) MOZ_OVERRIDE;
|
||||
virtual bool RecvReset() MOZ_OVERRIDE;
|
||||
virtual bool RecvDrain() MOZ_OVERRIDE;
|
||||
virtual bool RecvDecodingComplete() MOZ_OVERRIDE;
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "GMPMessageUtils.h"
|
||||
#include "nsAutoRef.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/gmp/GMPTypes.h"
|
||||
|
||||
template <>
|
||||
class nsAutoRefTraits<GMPVideoEncodedFrame> : public nsPointerRefTraits<GMPVideoEncodedFrame>
|
||||
@ -43,44 +42,60 @@ GMPVideoDecoderParent::Host()
|
||||
return mVideoHost;
|
||||
}
|
||||
|
||||
nsresult
|
||||
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,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
GMPVideoDecoderCallback* aCallback,
|
||||
GMPDecoderCallback* aCallback,
|
||||
int32_t aCoreCount)
|
||||
{
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video decoder!");
|
||||
return NS_ERROR_FAILURE;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!aCallback) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
mCallback = aCallback;
|
||||
|
||||
if (!SendInitDecode(aCodecSettings, aCodecSpecific, aCoreCount)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!SendInitDecode(aCodecSettings, aCoreCount)) {
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return NS_OK;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPVideoErr
|
||||
GMPVideoDecoderParent::Decode(GMPVideoEncodedFrame* aInputFrame,
|
||||
bool aMissingFrames,
|
||||
GMPBufferType aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs)
|
||||
{
|
||||
nsAutoRef<GMPVideoEncodedFrame> autoDestroy(aInputFrame);
|
||||
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video decoder!");
|
||||
return NS_ERROR_FAILURE;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
@ -90,69 +105,60 @@ 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 NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!SendDecode(frameData,
|
||||
aMissingFrames,
|
||||
aBufferType,
|
||||
aCodecSpecificInfo,
|
||||
aRenderTimeMs)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return NS_OK;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPVideoErr
|
||||
GMPVideoDecoderParent::Reset()
|
||||
{
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video decoder!");
|
||||
return NS_ERROR_FAILURE;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!SendReset()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return NS_OK;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GMPVideoErr
|
||||
GMPVideoDecoderParent::Drain()
|
||||
{
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video decoder!");
|
||||
return NS_ERROR_FAILURE;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!SendDrain()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return NS_OK;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
// Note: Consider keeping ActorDestroy sync'd up when making changes here.
|
||||
nsresult
|
||||
void
|
||||
GMPVideoDecoderParent::DecodingComplete()
|
||||
{
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video decoder!");
|
||||
return NS_ERROR_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
@ -164,8 +170,6 @@ GMPVideoDecoderParent::DecodingComplete()
|
||||
mVideoHost.DoneWithAPI();
|
||||
|
||||
unused << SendDecodingComplete();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Note: Keep this sync'd up with DecodingComplete
|
||||
@ -182,12 +186,6 @@ GMPVideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
mVideoHost.ActorDestroyed();
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoDecoderParent::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::RecvDecoded(const GMPVideoi420FrameData& aDecodedFrame)
|
||||
{
|
||||
@ -242,59 +240,6 @@ GMPVideoDecoderParent::RecvInputDataExhausted()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::RecvDrainComplete()
|
||||
{
|
||||
if (!mCallback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->DrainComplete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoDecoderParent::RecvResetComplete()
|
||||
{
|
||||
if (!mCallback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->ResetComplete();
|
||||
|
||||
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__()
|
||||
{
|
||||
|
@ -12,16 +12,15 @@
|
||||
#include "GMPMessageUtils.h"
|
||||
#include "GMPSharedMemManager.h"
|
||||
#include "GMPVideoHost.h"
|
||||
#include "GMPVideoDecoderProxy.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
|
||||
class GMPVideoDecoderParent MOZ_FINAL : public PGMPVideoDecoderParent
|
||||
class GMPVideoDecoderParent MOZ_FINAL : public GMPVideoDecoder
|
||||
, public PGMPVideoDecoderParent
|
||||
, public GMPSharedMemManager
|
||||
, public GMPVideoDecoderProxy
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(GMPVideoDecoderParent)
|
||||
@ -30,34 +29,23 @@ public:
|
||||
|
||||
GMPVideoHostImpl& Host();
|
||||
|
||||
// GMPVideoDecoder
|
||||
virtual nsresult InitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
GMPVideoDecoderCallback* aCallback,
|
||||
int32_t aCoreCount) MOZ_OVERRIDE;
|
||||
virtual nsresult Decode(GMPVideoEncodedFrame* aInputFrame,
|
||||
bool aMissingFrames,
|
||||
GMPBufferType aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs = -1) MOZ_OVERRIDE;
|
||||
virtual nsresult Reset() MOZ_OVERRIDE;
|
||||
virtual nsresult Drain() MOZ_OVERRIDE;
|
||||
virtual nsresult 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);
|
||||
}
|
||||
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,
|
||||
int32_t aCoreCount) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr Decode(GMPVideoEncodedFrame* aInputFrame,
|
||||
bool aMissingFrames,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs = -1) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr Reset() MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr Drain() MOZ_OVERRIDE;
|
||||
virtual void DecodingComplete() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
~GMPVideoDecoderParent();
|
||||
@ -68,16 +56,11 @@ 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 RecvDrainComplete() MOZ_OVERRIDE;
|
||||
virtual bool RecvResetComplete() 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;
|
||||
GMPParent* mPlugin;
|
||||
GMPVideoDecoderCallback* mCallback;
|
||||
GMPDecoderCallback* mCallback;
|
||||
GMPVideoHostImpl mVideoHost;
|
||||
};
|
||||
|
||||
|
@ -1,34 +0,0 @@
|
||||
/* -*- 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 GMPVideoDecoderProxy_h_
|
||||
#define GMPVideoDecoderProxy_h_
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "gmp-video-decode.h"
|
||||
#include "gmp-video-frame-i420.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
|
||||
// A proxy to GMPVideoDecoder in the child process.
|
||||
// GMPVideoDecoderParent exposes this to users the GMP.
|
||||
// This enables Gecko to pass nsTArrays to the child GMP and avoid
|
||||
// an extra copy when doing so.
|
||||
class GMPVideoDecoderProxy {
|
||||
public:
|
||||
virtual nsresult InitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
GMPVideoDecoderCallback* aCallback,
|
||||
int32_t aCoreCount) = 0;
|
||||
virtual nsresult Decode(GMPVideoEncodedFrame* aInputFrame,
|
||||
bool aMissingFrames,
|
||||
GMPBufferType aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs = -1) = 0;
|
||||
virtual nsresult Reset() = 0;
|
||||
virtual nsresult Drain() = 0;
|
||||
virtual nsresult DecodingComplete() = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -14,8 +14,8 @@ namespace gmp {
|
||||
GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(GMPVideoHostImpl* aHost)
|
||||
: mEncodedWidth(0),
|
||||
mEncodedHeight(0),
|
||||
mTimeStamp(0ll),
|
||||
mDuration(0ll),
|
||||
mTimeStamp(0),
|
||||
mCaptureTime_ms(0),
|
||||
mFrameType(kGMPDeltaFrame),
|
||||
mSize(0),
|
||||
mCompleteFrame(false),
|
||||
@ -29,8 +29,8 @@ GMPVideoEncodedFrameImpl::GMPVideoEncodedFrameImpl(const GMPVideoEncodedFrameDat
|
||||
GMPVideoHostImpl* aHost)
|
||||
: mEncodedWidth(aFrameData.mEncodedWidth()),
|
||||
mEncodedHeight(aFrameData.mEncodedHeight()),
|
||||
mTimeStamp(aFrameData.mTimestamp()),
|
||||
mDuration(aFrameData.mDuration()),
|
||||
mTimeStamp(aFrameData.mTimeStamp()),
|
||||
mCaptureTime_ms(aFrameData.mCaptureTime_ms()),
|
||||
mFrameType(static_cast<GMPVideoFrameType>(aFrameData.mFrameType())),
|
||||
mSize(aFrameData.mSize()),
|
||||
mCompleteFrame(aFrameData.mCompleteFrame()),
|
||||
@ -49,12 +49,6 @@ GMPVideoEncodedFrameImpl::~GMPVideoEncodedFrameImpl()
|
||||
}
|
||||
}
|
||||
|
||||
const GMPEncryptedBufferData*
|
||||
GMPVideoEncodedFrameImpl::GetDecryptionData() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GMPVideoFrameFormat
|
||||
GMPVideoEncodedFrameImpl::GetFrameFormat()
|
||||
{
|
||||
@ -86,8 +80,8 @@ GMPVideoEncodedFrameImpl::RelinquishFrameData(GMPVideoEncodedFrameData& aFrameDa
|
||||
{
|
||||
aFrameData.mEncodedWidth() = mEncodedWidth;
|
||||
aFrameData.mEncodedHeight() = mEncodedHeight;
|
||||
aFrameData.mTimestamp() = mTimeStamp;
|
||||
aFrameData.mDuration() = mDuration;
|
||||
aFrameData.mTimeStamp() = mTimeStamp;
|
||||
aFrameData.mCaptureTime_ms() = mCaptureTime_ms;
|
||||
aFrameData.mFrameType() = mFrameType;
|
||||
aFrameData.mSize() = mSize;
|
||||
aFrameData.mCompleteFrame() = mCompleteFrame;
|
||||
@ -105,37 +99,36 @@ void
|
||||
GMPVideoEncodedFrameImpl::DestroyBuffer()
|
||||
{
|
||||
if (mHost && mBuffer.IsWritable()) {
|
||||
mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData, mBuffer);
|
||||
mHost->SharedMemMgr()->MgrDeallocShmem(mBuffer);
|
||||
}
|
||||
mBuffer = ipc::Shmem();
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoEncodedFrameImpl::CreateEmptyFrame(uint32_t aSize)
|
||||
{
|
||||
if (aSize == 0) {
|
||||
DestroyBuffer();
|
||||
} else if (aSize > AllocatedSize()) {
|
||||
DestroyBuffer();
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData, aSize,
|
||||
ipc::SharedMemory::TYPE_BASIC, &mBuffer) ||
|
||||
DestroyBuffer();
|
||||
|
||||
if (aSize != 0) {
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(aSize, ipc::SharedMemory::TYPE_BASIC, &mBuffer) ||
|
||||
!Buffer()) {
|
||||
return GMPAllocErr;
|
||||
return GMPVideoAllocErr;
|
||||
}
|
||||
}
|
||||
|
||||
mSize = aSize;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoEncodedFrameImpl::CopyFrame(const GMPVideoEncodedFrame& aFrame)
|
||||
{
|
||||
auto& f = static_cast<const GMPVideoEncodedFrameImpl&>(aFrame);
|
||||
|
||||
if (f.mSize != 0) {
|
||||
GMPErr err = CreateEmptyFrame(f.mSize);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = CreateEmptyFrame(f.mSize);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
memcpy(Buffer(), f.Buffer(), f.mSize);
|
||||
@ -143,13 +136,13 @@ GMPVideoEncodedFrameImpl::CopyFrame(const GMPVideoEncodedFrame& aFrame)
|
||||
mEncodedWidth = f.mEncodedWidth;
|
||||
mEncodedHeight = f.mEncodedHeight;
|
||||
mTimeStamp = f.mTimeStamp;
|
||||
mDuration = f.mDuration;
|
||||
mCaptureTime_ms = f.mCaptureTime_ms;
|
||||
mFrameType = f.mFrameType;
|
||||
mSize = f.mSize; // already set...
|
||||
mSize = f.mSize;
|
||||
mCompleteFrame = f.mCompleteFrame;
|
||||
// Don't copy host, that should have been set properly on object creation via host.
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -177,27 +170,27 @@ GMPVideoEncodedFrameImpl::EncodedHeight()
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoEncodedFrameImpl::SetTimeStamp(uint64_t aTimeStamp)
|
||||
GMPVideoEncodedFrameImpl::SetTimeStamp(uint32_t aTimeStamp)
|
||||
{
|
||||
mTimeStamp = aTimeStamp;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
uint32_t
|
||||
GMPVideoEncodedFrameImpl::TimeStamp()
|
||||
{
|
||||
return mTimeStamp;
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoEncodedFrameImpl::SetDuration(uint64_t aDuration)
|
||||
GMPVideoEncodedFrameImpl::SetCaptureTime(int64_t aCaptureTime)
|
||||
{
|
||||
mDuration = aDuration;
|
||||
mCaptureTime_ms = aCaptureTime;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
GMPVideoEncodedFrameImpl::Duration() const
|
||||
int64_t
|
||||
GMPVideoEncodedFrameImpl::CaptureTime()
|
||||
{
|
||||
return mDuration;
|
||||
return mCaptureTime_ms;
|
||||
}
|
||||
|
||||
void
|
||||
@ -224,8 +217,7 @@ GMPVideoEncodedFrameImpl::SetAllocatedSize(uint32_t aNewSize)
|
||||
}
|
||||
|
||||
ipc::Shmem new_mem;
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPEncodedData, aNewSize,
|
||||
ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(aNewSize, ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
|
||||
!new_mem.get<uint8_t>()) {
|
||||
return;
|
||||
}
|
||||
|
@ -31,10 +31,9 @@
|
||||
#ifndef GMPVideoEncodedFrameImpl_h_
|
||||
#define GMPVideoEncodedFrameImpl_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-video-errors.h"
|
||||
#include "gmp-video-frame.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
#include "gmp-decryption.h"
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -64,21 +63,16 @@ public:
|
||||
virtual void Destroy() MOZ_OVERRIDE;
|
||||
|
||||
// GMPVideoEncodedFrame
|
||||
virtual GMPErr CreateEmptyFrame(uint32_t aSize) MOZ_OVERRIDE;
|
||||
virtual GMPErr CopyFrame(const GMPVideoEncodedFrame& aFrame) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr CreateEmptyFrame(uint32_t aSize) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr CopyFrame(const GMPVideoEncodedFrame& aFrame) MOZ_OVERRIDE;
|
||||
virtual void SetEncodedWidth(uint32_t aEncodedWidth) MOZ_OVERRIDE;
|
||||
virtual uint32_t EncodedWidth() MOZ_OVERRIDE;
|
||||
virtual void SetEncodedHeight(uint32_t aEncodedHeight) MOZ_OVERRIDE;
|
||||
virtual uint32_t EncodedHeight() MOZ_OVERRIDE;
|
||||
// Microseconds
|
||||
virtual void SetTimeStamp(uint64_t aTimeStamp) MOZ_OVERRIDE;
|
||||
virtual uint64_t TimeStamp() MOZ_OVERRIDE;
|
||||
// Set frame duration (microseconds)
|
||||
// NOTE: next-frame's Timestamp() != this-frame's TimeStamp()+Duration()
|
||||
// depending on rounding to avoid having to track roundoff errors
|
||||
// and dropped/missing frames(!) (which may leave a large gap)
|
||||
virtual void SetDuration(uint64_t aDuration) MOZ_OVERRIDE;
|
||||
virtual uint64_t Duration() const MOZ_OVERRIDE;
|
||||
virtual void SetTimeStamp(uint32_t aTimeStamp) MOZ_OVERRIDE;
|
||||
virtual uint32_t TimeStamp() MOZ_OVERRIDE;
|
||||
virtual void SetCaptureTime(int64_t aCaptureTime) MOZ_OVERRIDE;
|
||||
virtual int64_t CaptureTime() MOZ_OVERRIDE;
|
||||
virtual void SetFrameType(GMPVideoFrameType aFrameType) MOZ_OVERRIDE;
|
||||
virtual GMPVideoFrameType FrameType() MOZ_OVERRIDE;
|
||||
virtual void SetAllocatedSize(uint32_t aNewSize) MOZ_OVERRIDE;
|
||||
@ -89,15 +83,14 @@ public:
|
||||
virtual bool CompleteFrame() MOZ_OVERRIDE;
|
||||
virtual const uint8_t* Buffer() const MOZ_OVERRIDE;
|
||||
virtual uint8_t* Buffer() MOZ_OVERRIDE;
|
||||
virtual const GMPEncryptedBufferData* GetDecryptionData() const MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
void DestroyBuffer();
|
||||
|
||||
uint32_t mEncodedWidth;
|
||||
uint32_t mEncodedHeight;
|
||||
uint64_t mTimeStamp;
|
||||
uint64_t mDuration;
|
||||
uint32_t mTimeStamp;
|
||||
int64_t mCaptureTime_ms;
|
||||
GMPVideoFrameType mFrameType;
|
||||
uint32_t mSize;
|
||||
bool mCompleteFrame;
|
||||
|
@ -40,9 +40,7 @@ GMPVideoEncoderChild::Host()
|
||||
|
||||
void
|
||||
GMPVideoEncoderChild::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
GMPBufferType aBufferType,
|
||||
const uint8_t* aCodecSpecificInfo,
|
||||
uint32_t aCodecSpecificInfoLength)
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo)
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPMessageLoop() == MessageLoop::current());
|
||||
|
||||
@ -51,22 +49,31 @@ GMPVideoEncoderChild::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
GMPVideoEncodedFrameData frameData;
|
||||
ef->RelinquishFrameData(frameData);
|
||||
|
||||
nsTArray<uint8_t> codecSpecific;
|
||||
codecSpecific.AppendElements(aCodecSpecificInfo, aCodecSpecificInfoLength);
|
||||
SendEncoded(frameData, aBufferType, codecSpecific);
|
||||
SendEncoded(frameData, aCodecSpecificInfo);
|
||||
|
||||
aEncodedFrame->Destroy();
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoEncoderChild::CheckThread()
|
||||
bool
|
||||
GMPVideoEncoderChild::MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem)
|
||||
{
|
||||
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
|
||||
GMPVideoEncoderChild::RecvInitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
const int32_t& aNumberOfCores,
|
||||
const uint32_t& aMaxPayloadSize)
|
||||
{
|
||||
@ -75,20 +82,15 @@ GMPVideoEncoderChild::RecvInitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
}
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mVideoEncoder->InitEncode(aCodecSettings,
|
||||
aCodecSpecific.Elements(),
|
||||
aCodecSpecific.Length(),
|
||||
this,
|
||||
aNumberOfCores,
|
||||
aMaxPayloadSize);
|
||||
mVideoEncoder->InitEncode(aCodecSettings, this, aNumberOfCores, aMaxPayloadSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderChild::RecvEncode(const GMPVideoi420FrameData& aInputFrame,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const nsTArray<GMPVideoFrameType>& aFrameTypes)
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
const InfallibleTArray<int>& aFrameTypes)
|
||||
{
|
||||
if (!mVideoEncoder) {
|
||||
return false;
|
||||
@ -96,23 +98,14 @@ GMPVideoEncoderChild::RecvEncode(const GMPVideoi420FrameData& aInputFrame,
|
||||
|
||||
auto f = new GMPVideoi420FrameImpl(aInputFrame, &mVideoHost);
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mVideoEncoder->Encode(f,
|
||||
aCodecSpecificInfo.Elements(),
|
||||
aCodecSpecificInfo.Length(),
|
||||
aFrameTypes.Elements(),
|
||||
aFrameTypes.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderChild::RecvChildShmemForPool(Shmem& aEncodedBuffer)
|
||||
{
|
||||
if (aEncodedBuffer.IsWritable()) {
|
||||
mVideoHost.SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPEncodedData,
|
||||
aEncodedBuffer);
|
||||
std::vector<GMPVideoFrameType> frameTypes(aFrameTypes.Length());
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace gmp {
|
||||
class GMPChild;
|
||||
|
||||
class GMPVideoEncoderChild : public PGMPVideoEncoderChild,
|
||||
public GMPVideoEncoderCallback,
|
||||
public GMPEncoderCallback,
|
||||
public GMPSharedMemManager
|
||||
{
|
||||
public:
|
||||
@ -28,45 +28,24 @@ public:
|
||||
void Init(GMPVideoEncoder* aEncoder);
|
||||
GMPVideoHostImpl& Host();
|
||||
|
||||
// GMPVideoEncoderCallback
|
||||
// GMPEncoderCallback
|
||||
virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
GMPBufferType aBufferType,
|
||||
const uint8_t* aCodecSpecificInfo,
|
||||
uint32_t aCodecSpecificInfoLength) MOZ_OVERRIDE;
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo) MOZ_OVERRIDE;
|
||||
|
||||
// GMPSharedMemManager
|
||||
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
|
||||
}
|
||||
virtual bool MgrAllocShmem(size_t aSize,
|
||||
ipc::Shmem::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aMem) MOZ_OVERRIDE;
|
||||
virtual bool MgrDeallocShmem(Shmem& aMem) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// PGMPVideoEncoderChild
|
||||
virtual bool RecvInitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
const int32_t& aNumberOfCores,
|
||||
const uint32_t& aMaxPayloadSize) MOZ_OVERRIDE;
|
||||
virtual bool RecvEncode(const GMPVideoi420FrameData& aInputFrame,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const nsTArray<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
|
||||
virtual bool RecvChildShmemForPool(Shmem& aEncodedBuffer) MOZ_OVERRIDE;
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
const InfallibleTArray<int>& aFrameTypes) MOZ_OVERRIDE;
|
||||
virtual bool RecvSetChannelParameters(const uint32_t& aPacketLoss,
|
||||
const uint32_t& aRTT) MOZ_OVERRIDE;
|
||||
virtual bool RecvSetRates(const uint32_t& aNewBitRate,
|
||||
|
@ -43,43 +43,60 @@ GMPVideoEncoderParent::Host()
|
||||
return mVideoHost;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
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,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
GMPVideoEncoderCallbackProxy* aCallback,
|
||||
GMPEncoderCallback* aCallback,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize)
|
||||
{
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video encoder!");
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!aCallback) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
mCallback = aCallback;
|
||||
|
||||
if (!SendInitEncode(aCodecSettings, aCodecSpecific, aNumberOfCores, aMaxPayloadSize)) {
|
||||
return GMPGenericErr;
|
||||
if (!SendInitEncode(aCodecSettings, aNumberOfCores, aMaxPayloadSize)) {
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoEncoderParent::Encode(GMPVideoi420Frame* aInputFrame,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const nsTArray<GMPVideoFrameType>& aFrameTypes)
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
const std::vector<GMPVideoFrameType>& aFrameTypes)
|
||||
{
|
||||
nsAutoRef<GMPVideoi420Frame> frameRef(aInputFrame);
|
||||
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video encoder!");
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
@ -89,76 +106,74 @@ 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 GMPGenericErr;
|
||||
InfallibleTArray<int> frameTypes;
|
||||
frameTypes.SetCapacity(aFrameTypes.size());
|
||||
for (std::vector<int>::size_type i = 0; i != aFrameTypes.size(); i++) {
|
||||
frameTypes.AppendElement(static_cast<int>(aFrameTypes[i]));
|
||||
}
|
||||
|
||||
if (!SendEncode(frameData,
|
||||
aCodecSpecificInfo,
|
||||
aFrameTypes)) {
|
||||
return GMPGenericErr;
|
||||
frameTypes)) {
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoEncoderParent::SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT)
|
||||
{
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video encoder!");
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!SendSetChannelParameters(aPacketLoss, aRTT)) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoEncoderParent::SetRates(uint32_t aNewBitRate, uint32_t aFrameRate)
|
||||
{
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video encoder!");
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!SendSetRates(aNewBitRate, aFrameRate)) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoEncoderParent::SetPeriodicKeyFrames(bool aEnable)
|
||||
{
|
||||
if (!mCanSendMessages) {
|
||||
NS_WARNING("Trying to use an invalid GMP video encoder!");
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
|
||||
if (!SendSetPeriodicKeyFrames(aEnable)) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
// Async IPC, we don't have access to a return value.
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
// Note: Consider keeping ActorDestroy sync'd up when making changes here.
|
||||
@ -195,16 +210,9 @@ GMPVideoEncoderParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
mVideoHost.ActorDestroyed();
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoEncoderParent::CheckThread()
|
||||
{
|
||||
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
|
||||
}
|
||||
|
||||
bool
|
||||
GMPVideoEncoderParent::RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
|
||||
const GMPBufferType& aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo)
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo)
|
||||
{
|
||||
if (!mCallback) {
|
||||
return false;
|
||||
@ -213,37 +221,8 @@ GMPVideoEncoderParent::RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame
|
||||
auto f = new GMPVideoEncodedFrameImpl(aEncodedFrame, &mVideoHost);
|
||||
|
||||
// Ignore any return code. It is OK for this to fail without killing the process.
|
||||
mCallback->Encoded(f, aBufferType, aCodecSpecificInfo);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -12,14 +12,13 @@
|
||||
#include "GMPMessageUtils.h"
|
||||
#include "GMPSharedMemManager.h"
|
||||
#include "GMPVideoHost.h"
|
||||
#include "GMPVideoEncoderProxy.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
class GMPParent;
|
||||
|
||||
class GMPVideoEncoderParent : public GMPVideoEncoderProxy,
|
||||
class GMPVideoEncoderParent : public GMPVideoEncoder,
|
||||
public PGMPVideoEncoderParent,
|
||||
public GMPSharedMemManager
|
||||
{
|
||||
@ -30,34 +29,24 @@ public:
|
||||
|
||||
GMPVideoHostImpl& Host();
|
||||
|
||||
// GMPVideoEncoderProxy
|
||||
virtual GMPErr InitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
GMPVideoEncoderCallbackProxy* aCallback,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize) MOZ_OVERRIDE;
|
||||
virtual GMPErr Encode(GMPVideoi420Frame* aInputFrame,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const nsTArray<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
|
||||
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) MOZ_OVERRIDE;
|
||||
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) MOZ_OVERRIDE;
|
||||
virtual GMPErr 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);
|
||||
}
|
||||
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,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr Encode(GMPVideoi420Frame* aInputFrame,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
const std::vector<GMPVideoFrameType>& aFrameTypes) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr SetPeriodicKeyFrames(bool aEnable) MOZ_OVERRIDE;
|
||||
virtual void EncodingComplete() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
virtual ~GMPVideoEncoderParent();
|
||||
@ -65,16 +54,12 @@ private:
|
||||
// PGMPVideoEncoderParent
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
virtual bool RecvEncoded(const GMPVideoEncodedFrameData& aEncodedFrame,
|
||||
const GMPBufferType& aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo) MOZ_OVERRIDE;
|
||||
virtual bool RecvParentShmemForPool(Shmem& aFrameBuffer) MOZ_OVERRIDE;
|
||||
virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
|
||||
Shmem* aMem) MOZ_OVERRIDE;
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo) MOZ_OVERRIDE;
|
||||
virtual bool Recv__delete__() MOZ_OVERRIDE;
|
||||
|
||||
bool mCanSendMessages;
|
||||
GMPParent* mPlugin;
|
||||
GMPVideoEncoderCallbackProxy* mCallback;
|
||||
GMPEncoderCallback* mCallback;
|
||||
GMPVideoHostImpl mVideoHost;
|
||||
};
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
/* -*- 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 GMPVideoEncoderProxy_h_
|
||||
#define GMPVideoEncoderProxy_h_
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "gmp-video-encode.h"
|
||||
#include "gmp-video-frame-i420.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
|
||||
class GMPVideoEncoderCallbackProxy {
|
||||
public:
|
||||
virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
GMPBufferType aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo) = 0;
|
||||
};
|
||||
|
||||
// A proxy to GMPVideoEncoder in the child process.
|
||||
// GMPVideoEncoderParent exposes this to users the GMP.
|
||||
// This enables Gecko to pass nsTArrays to the child GMP and avoid
|
||||
// an extra copy when doing so.
|
||||
class GMPVideoEncoderProxy {
|
||||
public:
|
||||
virtual GMPErr InitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
const nsTArray<uint8_t>& aCodecSpecific,
|
||||
GMPVideoEncoderCallbackProxy* aCallback,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize) = 0;
|
||||
virtual GMPErr Encode(GMPVideoi420Frame* aInputFrame,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo,
|
||||
const nsTArray<GMPVideoFrameType>& aFrameTypes) = 0;
|
||||
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
|
||||
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
|
||||
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) = 0;
|
||||
virtual void EncodingComplete() = 0;
|
||||
};
|
||||
|
||||
#endif // GMPVideoEncoderProxy_h_
|
@ -20,41 +20,41 @@ GMPVideoHostImpl::~GMPVideoHostImpl()
|
||||
{
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoHostImpl::CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame)
|
||||
{
|
||||
if (!mSharedMemMgr) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
if (!aFrame) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
*aFrame = nullptr;
|
||||
|
||||
switch (aFormat) {
|
||||
case kGMPI420VideoFrame:
|
||||
*aFrame = new GMPVideoi420FrameImpl(this);
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
case kGMPEncodedVideoFrame:
|
||||
*aFrame = new GMPVideoEncodedFrameImpl(this);
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
default:
|
||||
NS_NOTREACHED("Unknown frame format!");
|
||||
}
|
||||
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoHostImpl::CreatePlane(GMPPlane** aPlane)
|
||||
{
|
||||
if (!mSharedMemMgr) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
if (!aPlane) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
*aPlane = nullptr;
|
||||
|
||||
@ -62,7 +62,7 @@ GMPVideoHostImpl::CreatePlane(GMPPlane** aPlane)
|
||||
|
||||
*aPlane = p;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPSharedMemManager*
|
||||
|
@ -35,8 +35,8 @@ public:
|
||||
void EncodedFrameDestroyed(GMPVideoEncodedFrameImpl* aFrame);
|
||||
|
||||
// GMPVideoHost
|
||||
virtual GMPErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) MOZ_OVERRIDE;
|
||||
virtual GMPErr CreatePlane(GMPPlane** aPlane) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr CreatePlane(GMPPlane** aPlane) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// All shared memory allocations have to be made by an IPDL actor.
|
||||
|
@ -73,21 +73,20 @@ GMPPlaneImpl::InitPlaneData(GMPPlaneData& aPlaneData)
|
||||
return true;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPPlaneImpl::MaybeResize(int32_t aNewSize) {
|
||||
if (aNewSize <= AllocatedSize()) {
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
if (!mHost) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
ipc::Shmem new_mem;
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(GMPSharedMemManager::kGMPFrameData, aNewSize,
|
||||
ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
|
||||
if (!mHost->SharedMemMgr()->MgrAllocShmem(aNewSize, ipc::SharedMemory::TYPE_BASIC, &new_mem) ||
|
||||
!new_mem.get<uint8_t>()) {
|
||||
return GMPAllocErr;
|
||||
return GMPVideoAllocErr;
|
||||
}
|
||||
|
||||
if (mBuffer.IsReadable()) {
|
||||
@ -98,43 +97,43 @@ GMPPlaneImpl::MaybeResize(int32_t aNewSize) {
|
||||
|
||||
mBuffer = new_mem;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
void
|
||||
GMPPlaneImpl::DestroyBuffer()
|
||||
{
|
||||
if (mHost && mBuffer.IsWritable()) {
|
||||
mHost->SharedMemMgr()->MgrDeallocShmem(GMPSharedMemManager::kGMPFrameData, mBuffer);
|
||||
mHost->SharedMemMgr()->MgrDeallocShmem(mBuffer);
|
||||
}
|
||||
mBuffer = ipc::Shmem();
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPPlaneImpl::CreateEmptyPlane(int32_t aAllocatedSize, int32_t aStride, int32_t aPlaneSize)
|
||||
{
|
||||
if (aAllocatedSize < 1 || aStride < 1 || aPlaneSize < 1) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
GMPErr err = MaybeResize(aAllocatedSize);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = MaybeResize(aAllocatedSize);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
mSize = aPlaneSize;
|
||||
mStride = aStride;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPPlaneImpl::Copy(const GMPPlane& aPlane)
|
||||
{
|
||||
auto& planeimpl = static_cast<const GMPPlaneImpl&>(aPlane);
|
||||
|
||||
GMPErr err = MaybeResize(planeimpl.mSize);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = MaybeResize(planeimpl.mSize);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -145,14 +144,14 @@ GMPPlaneImpl::Copy(const GMPPlane& aPlane)
|
||||
mSize = planeimpl.mSize;
|
||||
mStride = planeimpl.mStride;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPPlaneImpl::Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer)
|
||||
{
|
||||
GMPErr err = MaybeResize(aSize);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = MaybeResize(aSize);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -163,7 +162,7 @@ GMPPlaneImpl::Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer)
|
||||
mSize = aSize;
|
||||
mStride = aStride;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -34,13 +34,13 @@ public:
|
||||
bool InitPlaneData(GMPPlaneData& aPlaneData);
|
||||
|
||||
// GMPPlane
|
||||
virtual GMPErr CreateEmptyPlane(int32_t aAllocatedSize,
|
||||
int32_t aStride,
|
||||
int32_t aPlaneSize) MOZ_OVERRIDE;
|
||||
virtual GMPErr Copy(const GMPPlane& aPlane) MOZ_OVERRIDE;
|
||||
virtual GMPErr Copy(int32_t aSize,
|
||||
int32_t aStride,
|
||||
const uint8_t* aBuffer) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr CreateEmptyPlane(int32_t aAllocatedSize,
|
||||
int32_t aStride,
|
||||
int32_t aPlaneSize) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr Copy(const GMPPlane& aPlane) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr Copy(int32_t aSize,
|
||||
int32_t aStride,
|
||||
const uint8_t* aBuffer) MOZ_OVERRIDE;
|
||||
virtual void Swap(GMPPlane& aPlane) MOZ_OVERRIDE;
|
||||
virtual int32_t AllocatedSize() const MOZ_OVERRIDE;
|
||||
virtual void ResetSize() MOZ_OVERRIDE;
|
||||
@ -51,7 +51,7 @@ public:
|
||||
virtual void Destroy() MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
GMPErr MaybeResize(int32_t aNewSize);
|
||||
GMPVideoErr MaybeResize(int32_t aNewSize);
|
||||
void DestroyBuffer();
|
||||
|
||||
ipc::Shmem mBuffer;
|
||||
|
@ -15,8 +15,8 @@ GMPVideoi420FrameImpl::GMPVideoi420FrameImpl(GMPVideoHostImpl* aHost)
|
||||
mVPlane(aHost),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mTimestamp(0ll),
|
||||
mDuration(0ll)
|
||||
mTimestamp(0),
|
||||
mRenderTime_ms(0)
|
||||
{
|
||||
MOZ_ASSERT(aHost);
|
||||
}
|
||||
@ -29,7 +29,7 @@ GMPVideoi420FrameImpl::GMPVideoi420FrameImpl(const GMPVideoi420FrameData& aFrame
|
||||
mWidth(aFrameData.mWidth()),
|
||||
mHeight(aFrameData.mHeight()),
|
||||
mTimestamp(aFrameData.mTimestamp()),
|
||||
mDuration(aFrameData.mDuration())
|
||||
mRenderTime_ms(aFrameData.mRenderTime_ms())
|
||||
{
|
||||
MOZ_ASSERT(aHost);
|
||||
}
|
||||
@ -47,7 +47,7 @@ GMPVideoi420FrameImpl::InitFrameData(GMPVideoi420FrameData& aFrameData)
|
||||
aFrameData.mWidth() = mWidth;
|
||||
aFrameData.mHeight() = mHeight;
|
||||
aFrameData.mTimestamp() = mTimestamp;
|
||||
aFrameData.mDuration() = mDuration;
|
||||
aFrameData.mRenderTime_ms() = mRenderTime_ms;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -106,12 +106,12 @@ GMPVideoi420FrameImpl::GetPlane(GMPPlaneType aType) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoi420FrameImpl::CreateEmptyFrame(int32_t aWidth, int32_t aHeight,
|
||||
int32_t aStride_y, int32_t aStride_u, int32_t aStride_v)
|
||||
{
|
||||
if (!CheckDimensions(aWidth, aHeight, aStride_y, aStride_u, aStride_v)) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
int32_t size_y = aStride_y * aHeight;
|
||||
@ -119,28 +119,28 @@ GMPVideoi420FrameImpl::CreateEmptyFrame(int32_t aWidth, int32_t aHeight,
|
||||
int32_t size_u = aStride_u * half_height;
|
||||
int32_t size_v = aStride_v * half_height;
|
||||
|
||||
GMPErr err = mYPlane.CreateEmptyPlane(size_y, aStride_y, size_y);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = mYPlane.CreateEmptyPlane(size_y, aStride_y, size_y);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
err = mUPlane.CreateEmptyPlane(size_u, aStride_u, size_u);
|
||||
if (err != GMPNoErr) {
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
err = mVPlane.CreateEmptyPlane(size_v, aStride_v, size_v);
|
||||
if (err != GMPNoErr) {
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
mWidth = aWidth;
|
||||
mHeight = aHeight;
|
||||
mTimestamp = 0ll;
|
||||
mDuration = 0ll;
|
||||
mTimestamp = 0;
|
||||
mRenderTime_ms = 0;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoi420FrameImpl::CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
|
||||
int32_t aSize_u, const uint8_t* aBuffer_u,
|
||||
int32_t aSize_v, const uint8_t* aBuffer_v,
|
||||
@ -152,58 +152,58 @@ GMPVideoi420FrameImpl::CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
|
||||
MOZ_ASSERT(aBuffer_v);
|
||||
|
||||
if (aSize_y < 1 || aSize_u < 1 || aSize_v < 1) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
if (!CheckDimensions(aWidth, aHeight, aStride_y, aStride_u, aStride_v)) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
|
||||
GMPErr err = mYPlane.Copy(aSize_y, aStride_y, aBuffer_y);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = mYPlane.Copy(aSize_y, aStride_y, aBuffer_y);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
err = mUPlane.Copy(aSize_u, aStride_u, aBuffer_u);
|
||||
if (err != GMPNoErr) {
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
err = mVPlane.Copy(aSize_v, aStride_v, aBuffer_v);
|
||||
if (err != GMPNoErr) {
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
mWidth = aWidth;
|
||||
mHeight = aHeight;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoi420FrameImpl::CopyFrame(const GMPVideoi420Frame& aFrame)
|
||||
{
|
||||
auto& f = static_cast<const GMPVideoi420FrameImpl&>(aFrame);
|
||||
|
||||
GMPErr err = mYPlane.Copy(f.mYPlane);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = mYPlane.Copy(f.mYPlane);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = mUPlane.Copy(f.mUPlane);
|
||||
if (err != GMPNoErr) {
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = mVPlane.Copy(f.mVPlane);
|
||||
if (err != GMPNoErr) {
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
mWidth = f.mWidth;
|
||||
mHeight = f.mHeight;
|
||||
mTimestamp = f.mTimestamp;
|
||||
mDuration = f.mDuration;
|
||||
mRenderTime_ms = f.mRenderTime_ms;
|
||||
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -216,7 +216,7 @@ GMPVideoi420FrameImpl::SwapFrame(GMPVideoi420Frame* aFrame)
|
||||
std::swap(mWidth, f->mWidth);
|
||||
std::swap(mHeight, f->mHeight);
|
||||
std::swap(mTimestamp, f->mTimestamp);
|
||||
std::swap(mDuration, f->mDuration);
|
||||
std::swap(mRenderTime_ms, f->mRenderTime_ms);
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
@ -259,28 +259,28 @@ GMPVideoi420FrameImpl::Stride(GMPPlaneType aType) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoi420FrameImpl::SetWidth(int32_t aWidth)
|
||||
{
|
||||
if (!CheckDimensions(aWidth, mHeight,
|
||||
mYPlane.Stride(), mUPlane.Stride(),
|
||||
mVPlane.Stride())) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
mWidth = aWidth;
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
GMPErr
|
||||
GMPVideoErr
|
||||
GMPVideoi420FrameImpl::SetHeight(int32_t aHeight)
|
||||
{
|
||||
if (!CheckDimensions(mWidth, aHeight,
|
||||
mYPlane.Stride(), mUPlane.Stride(),
|
||||
mVPlane.Stride())) {
|
||||
return GMPGenericErr;
|
||||
return GMPVideoGenericErr;
|
||||
}
|
||||
mHeight = aHeight;
|
||||
return GMPNoErr;
|
||||
return GMPVideoNoErr;
|
||||
}
|
||||
|
||||
int32_t
|
||||
@ -296,27 +296,27 @@ GMPVideoi420FrameImpl::Height() const
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoi420FrameImpl::SetTimestamp(uint64_t aTimestamp)
|
||||
GMPVideoi420FrameImpl::SetTimestamp(uint32_t aTimestamp)
|
||||
{
|
||||
mTimestamp = aTimestamp;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
uint32_t
|
||||
GMPVideoi420FrameImpl::Timestamp() const
|
||||
{
|
||||
return mTimestamp;
|
||||
}
|
||||
|
||||
void
|
||||
GMPVideoi420FrameImpl::SetDuration(uint64_t aDuration)
|
||||
GMPVideoi420FrameImpl::SetRenderTime_ms(int64_t aRenderTime_ms)
|
||||
{
|
||||
mDuration = aDuration;
|
||||
mRenderTime_ms = aRenderTime_ms;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
GMPVideoi420FrameImpl::Duration() const
|
||||
int64_t
|
||||
GMPVideoi420FrameImpl::RenderTime_ms() const
|
||||
{
|
||||
return mDuration;
|
||||
return mRenderTime_ms;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -32,33 +32,33 @@ public:
|
||||
virtual void Destroy() MOZ_OVERRIDE;
|
||||
|
||||
// GMPVideoi420Frame
|
||||
virtual GMPErr CreateEmptyFrame(int32_t aWidth,
|
||||
virtual GMPVideoErr CreateEmptyFrame(int32_t aWidth,
|
||||
int32_t aHeight,
|
||||
int32_t aStride_y,
|
||||
int32_t aStride_u,
|
||||
int32_t aStride_v) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
|
||||
int32_t aSize_u, const uint8_t* aBuffer_u,
|
||||
int32_t aSize_v, const uint8_t* aBuffer_v,
|
||||
int32_t aWidth,
|
||||
int32_t aHeight,
|
||||
int32_t aStride_y,
|
||||
int32_t aStride_u,
|
||||
int32_t aStride_v) MOZ_OVERRIDE;
|
||||
virtual GMPErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
|
||||
int32_t aSize_u, const uint8_t* aBuffer_u,
|
||||
int32_t aSize_v, const uint8_t* aBuffer_v,
|
||||
int32_t aWidth,
|
||||
int32_t aHeight,
|
||||
int32_t aStride_y,
|
||||
int32_t aStride_u,
|
||||
int32_t aStride_v) MOZ_OVERRIDE;
|
||||
virtual GMPErr CopyFrame(const GMPVideoi420Frame& aFrame) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr CopyFrame(const GMPVideoi420Frame& aFrame) MOZ_OVERRIDE;
|
||||
virtual void SwapFrame(GMPVideoi420Frame* aFrame) MOZ_OVERRIDE;
|
||||
virtual uint8_t* Buffer(GMPPlaneType aType) MOZ_OVERRIDE;
|
||||
virtual const uint8_t* Buffer(GMPPlaneType aType) const MOZ_OVERRIDE;
|
||||
virtual int32_t AllocatedSize(GMPPlaneType aType) const MOZ_OVERRIDE;
|
||||
virtual int32_t Stride(GMPPlaneType aType) const MOZ_OVERRIDE;
|
||||
virtual GMPErr SetWidth(int32_t aWidth) MOZ_OVERRIDE;
|
||||
virtual GMPErr SetHeight(int32_t aHeight) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr SetWidth(int32_t aWidth) MOZ_OVERRIDE;
|
||||
virtual GMPVideoErr SetHeight(int32_t aHeight) MOZ_OVERRIDE;
|
||||
virtual int32_t Width() const MOZ_OVERRIDE;
|
||||
virtual int32_t Height() const MOZ_OVERRIDE;
|
||||
virtual void SetTimestamp(uint64_t aTimestamp) MOZ_OVERRIDE;
|
||||
virtual uint64_t Timestamp() const MOZ_OVERRIDE;
|
||||
virtual void SetDuration(uint64_t aDuration) MOZ_OVERRIDE;
|
||||
virtual uint64_t Duration() const MOZ_OVERRIDE;
|
||||
virtual void SetTimestamp(uint32_t aTimestamp) MOZ_OVERRIDE;
|
||||
virtual uint32_t Timestamp() const MOZ_OVERRIDE;
|
||||
virtual void SetRenderTime_ms(int64_t aRenderTime_ms) MOZ_OVERRIDE;
|
||||
virtual int64_t RenderTime_ms() const MOZ_OVERRIDE;
|
||||
virtual bool IsZeroSize() const MOZ_OVERRIDE;
|
||||
virtual void ResetSize() MOZ_OVERRIDE;
|
||||
|
||||
@ -71,8 +71,8 @@ private:
|
||||
GMPPlaneImpl mVPlane;
|
||||
int32_t mWidth;
|
||||
int32_t mHeight;
|
||||
uint64_t mTimestamp;
|
||||
uint64_t mDuration;
|
||||
uint32_t mTimestamp;
|
||||
int64_t mRenderTime_ms;
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
@ -9,13 +9,13 @@ include protocol PGMPVideoEncoder;
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
intr protocol PGMP
|
||||
async protocol PGMP
|
||||
{
|
||||
manages PGMPVideoDecoder;
|
||||
manages PGMPVideoEncoder;
|
||||
child:
|
||||
async PGMPVideoDecoder();
|
||||
async PGMPVideoEncoder();
|
||||
PGMPVideoDecoder();
|
||||
PGMPVideoEncoder();
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
@ -7,42 +7,32 @@ include protocol PGMP;
|
||||
include GMPTypes;
|
||||
|
||||
using GMPVideoCodec from "gmp-video-codec.h";
|
||||
using GMPBufferType from "gmp-video-codec.h";
|
||||
using GMPCodecSpecificInfo from "gmp-video-codec.h";
|
||||
|
||||
include "GMPMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
intr protocol PGMPVideoDecoder
|
||||
async protocol PGMPVideoDecoder
|
||||
{
|
||||
manager PGMP;
|
||||
child:
|
||||
async InitDecode(GMPVideoCodec aCodecSettings,
|
||||
uint8_t[] aCodecSpecific,
|
||||
int32_t aCoreCount);
|
||||
async Decode(GMPVideoEncodedFrameData aInputFrame,
|
||||
bool aMissingFrames,
|
||||
GMPBufferType aBufferType,
|
||||
uint8_t[] aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs);
|
||||
async Reset();
|
||||
async Drain();
|
||||
async DecodingComplete();
|
||||
async ChildShmemForPool(Shmem aFrameBuffer);
|
||||
|
||||
InitDecode(GMPVideoCodec aCodecSettings,
|
||||
int32_t aCoreCount);
|
||||
Decode(GMPVideoEncodedFrameData aInputFrame,
|
||||
bool aMissingFrames,
|
||||
GMPCodecSpecificInfo aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs);
|
||||
Reset();
|
||||
Drain();
|
||||
DecodingComplete();
|
||||
parent:
|
||||
async __delete__();
|
||||
async Decoded(GMPVideoi420FrameData aDecodedFrame);
|
||||
async ReceivedDecodedReferenceFrame(uint64_t aPictureId);
|
||||
async ReceivedDecodedFrame(uint64_t aPictureId);
|
||||
async InputDataExhausted();
|
||||
async DrainComplete();
|
||||
async ResetComplete();
|
||||
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);
|
||||
__delete__();
|
||||
Decoded(GMPVideoi420FrameData aDecodedFrame);
|
||||
ReceivedDecodedReferenceFrame(uint64_t aPictureId);
|
||||
ReceivedDecodedFrame(uint64_t aPictureId);
|
||||
InputDataExhausted();
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
@ -7,40 +7,32 @@ include protocol PGMP;
|
||||
include GMPTypes;
|
||||
|
||||
using GMPVideoCodec from "gmp-video-codec.h";
|
||||
using GMPVideoFrameType from "gmp-video-frame-encoded.h";
|
||||
using GMPBufferType from "gmp-video-codec.h";
|
||||
using GMPCodecSpecificInfo from "gmp-video-codec.h";
|
||||
|
||||
include "GMPMessageUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace gmp {
|
||||
|
||||
intr protocol PGMPVideoEncoder
|
||||
async protocol PGMPVideoEncoder
|
||||
{
|
||||
manager PGMP;
|
||||
child:
|
||||
async InitEncode(GMPVideoCodec aCodecSettings,
|
||||
uint8_t[] aCodecSpecific,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize);
|
||||
async Encode(GMPVideoi420FrameData aInputFrame,
|
||||
uint8_t[] aCodecSpecificInfo,
|
||||
GMPVideoFrameType[] aFrameTypes);
|
||||
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);
|
||||
InitEncode(GMPVideoCodec aCodecSettings,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize);
|
||||
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();
|
||||
|
||||
parent:
|
||||
async __delete__();
|
||||
async Encoded(GMPVideoEncodedFrameData aEncodedFrame,
|
||||
GMPBufferType aBufferType,
|
||||
uint8_t[] 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);
|
||||
__delete__();
|
||||
Encoded(GMPVideoEncodedFrameData aEncodedFrame,
|
||||
GMPCodecSpecificInfo aCodecSpecificInfo);
|
||||
};
|
||||
|
||||
} // namespace gmp
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013, Mozilla Foundation and contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GMP_ASYNC_SHUTDOWN_H_
|
||||
#define GMP_ASYNC_SHUTDOWN_H_
|
||||
|
||||
// API exposed by the plugin library to manage asynchronous shutdown.
|
||||
// Some plugins require special cleanup which may need to make calls
|
||||
// to host services and wait for async responses.
|
||||
//
|
||||
// To enable a plugins to block shutdown until its async shutdown is
|
||||
// complete, implement the GMPAsyncShutdown interface and return it when
|
||||
// your plugin's GMPGetAPI function is called with "async-shutdown".
|
||||
// When your GMPAsyncShutdown's BeginShutdown() implementation is called
|
||||
// by the GMP host, you should initate your async shutdown process.
|
||||
// Once you have completed shutdown, call the ShutdownComplete() function
|
||||
// of the GMPAsyncShutdownHost that is passed as the host argument to the
|
||||
// GMPGetAPI() call.
|
||||
//
|
||||
// Note: Your GMP's GMPShutdown function will still be called after your
|
||||
// call to ShutdownComplete().
|
||||
//
|
||||
// API name: "async-shutdown"
|
||||
// Host API: GMPAsyncShutdownHost
|
||||
class GMPAsyncShutdown {
|
||||
public:
|
||||
virtual ~GMPAsyncShutdown() {}
|
||||
|
||||
virtual void BeginShutdown() = 0;
|
||||
};
|
||||
|
||||
class GMPAsyncShutdownHost {
|
||||
public:
|
||||
virtual ~GMPAsyncShutdownHost() {}
|
||||
|
||||
virtual void ShutdownComplete() = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_ASYNC_SHUTDOWN_H_
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013, Mozilla Foundation and contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GMP_AUDIO_CODEC_h_
|
||||
#define GMP_AUDIO_CODEC_h_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum GMPAudioCodecType
|
||||
{
|
||||
kGMPAudioCodecAAC,
|
||||
kGMPAudioCodecVorbis,
|
||||
kGMPAudioCodecInvalid // Should always be last.
|
||||
};
|
||||
|
||||
struct GMPAudioCodec
|
||||
{
|
||||
GMPAudioCodecType mCodecType;
|
||||
uint32_t mChannelCount;
|
||||
uint32_t mBitsPerChannel;
|
||||
uint32_t mSamplesPerSecond;
|
||||
|
||||
// Codec extra data, such as vorbis setup header, or
|
||||
// AAC AudioSpecificConfig.
|
||||
// These are null/0 if not externally negotiated
|
||||
const uint8_t* mExtraData;
|
||||
size_t mExtraDataLen;
|
||||
};
|
||||
|
||||
#endif // GMP_AUDIO_CODEC_h_
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013, Mozilla Foundation and contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GMP_AUDIO_DECODE_h_
|
||||
#define GMP_AUDIO_DECODE_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-audio-samples.h"
|
||||
#include "gmp-audio-codec.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
|
||||
class GMPAudioDecoderCallback
|
||||
{
|
||||
public:
|
||||
virtual ~GMPAudioDecoderCallback() {}
|
||||
|
||||
virtual void Decoded(GMPAudioSamples* aDecodedSamples) = 0;
|
||||
|
||||
virtual void InputDataExhausted() = 0;
|
||||
|
||||
virtual void DrainComplete() = 0;
|
||||
|
||||
virtual void ResetComplete() = 0;
|
||||
};
|
||||
|
||||
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
|
||||
class GMPAudioDecoder
|
||||
{
|
||||
public:
|
||||
virtual ~GMPAudioDecoder() {}
|
||||
|
||||
// aCallback: Subclass should retain reference to it until DecodingComplete
|
||||
// is called. Do not attempt to delete it, host retains ownership.
|
||||
// TODO: Pass AudioHost so decoder can create GMPAudioEncodedFrame objects?
|
||||
virtual GMPErr InitDecode(const GMPAudioCodec& aCodecSettings,
|
||||
GMPAudioDecoderCallback* aCallback) = 0;
|
||||
|
||||
// Decode encoded audio frames (as a part of an audio stream). The decoded
|
||||
// frames must be returned to the user through the decode complete callback.
|
||||
virtual GMPErr Decode(GMPAudioSamples* aEncodedSamples) = 0;
|
||||
|
||||
// Reset decoder state and prepare for a new call to Decode(...).
|
||||
// Flushes the decoder pipeline.
|
||||
// The decoder should enqueue a task to run ResetComplete() on the main
|
||||
// thread once the reset has finished.
|
||||
virtual GMPErr Reset() = 0;
|
||||
|
||||
// Output decoded frames for any data in the pipeline, regardless of ordering.
|
||||
// All remaining decoded frames should be immediately returned via callback.
|
||||
// The decoder should enqueue a task to run DrainComplete() on the main
|
||||
// thread once the reset has finished.
|
||||
virtual GMPErr Drain() = 0;
|
||||
|
||||
// May free decoder memory.
|
||||
virtual void DecodingComplete() = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_VIDEO_DECODE_h_
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013, Mozilla Foundation and contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GMP_AUDIO_HOST_h_
|
||||
#define GMP_AUDIO_HOST_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-audio-samples.h"
|
||||
|
||||
class GMPAudioHost
|
||||
{
|
||||
public:
|
||||
// Construct various Audio API objects. Host does not retain reference,
|
||||
// caller is owner and responsible for deleting.
|
||||
virtual GMPErr CreateSamples(GMPAudioFormat aFormat,
|
||||
GMPAudioSamples** aSamples) = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_AUDIO_HOST_h_
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013, Mozilla Foundation and contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GMP_AUDIO_FRAME_h_
|
||||
#define GMP_AUDIO_FRAME_h_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-decryption.h"
|
||||
|
||||
enum GMPAudioFormat
|
||||
{
|
||||
kGMPAudioEncodedSamples, // Raw compressed data, i.e. an AAC/Vorbis packet.
|
||||
kGMPAudioIS16Samples, // Interleaved int16_t PCM samples.
|
||||
kGMPAudioSamplesFormatInvalid // Should always be last.
|
||||
};
|
||||
|
||||
class GMPAudioSamples {
|
||||
public:
|
||||
// The format of the buffer.
|
||||
virtual GMPAudioFormat GetFormat() = 0;
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
// MAIN THREAD ONLY
|
||||
// Buffer size must be exactly what's required to contain all samples in
|
||||
// the buffer; every byte is assumed to be part of a sample.
|
||||
virtual GMPErr SetBufferSize(uint32_t aSize) = 0;
|
||||
|
||||
// Size of the buffer in bytes.
|
||||
virtual uint32_t Size() = 0;
|
||||
|
||||
// Timestamps are in microseconds, and are the playback start time of the
|
||||
// first sample in the buffer.
|
||||
virtual void SetTimeStamp(uint64_t aTimeStamp) = 0;
|
||||
virtual uint64_t TimeStamp() = 0;
|
||||
virtual const uint8_t* Buffer() const = 0;
|
||||
virtual uint8_t* Buffer() = 0;
|
||||
|
||||
// Get data describing how this frame is encrypted, or nullptr if the
|
||||
// buffer is not encrypted.
|
||||
virtual const GMPEncryptedBufferData* GetDecryptionData() const = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_AUDIO_FRAME_h_
|
@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013, Mozilla Foundation and contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GMP_DECRYPTION_h_
|
||||
#define GMP_DECRYPTION_h_
|
||||
|
||||
#include "gmp-platform.h"
|
||||
|
||||
class GMPEncryptedBufferData {
|
||||
public:
|
||||
// Key ID to identify the decryption key.
|
||||
virtual const uint8_t* KeyId() const = 0;
|
||||
|
||||
// Size (in bytes) of |KeyId()|.
|
||||
virtual uint32_t KeyIdSize() const = 0;
|
||||
|
||||
// Initialization vector.
|
||||
virtual const uint8_t* IV() const = 0;
|
||||
|
||||
// Size (in bytes) of |IV|.
|
||||
virtual uint32_t IVSize() const = 0;
|
||||
|
||||
// Number of enties returned by ClearBytes and CipherBytes().
|
||||
virtual uint32_t NumSubsamples() const = 0;
|
||||
|
||||
virtual const uint32_t* ClearBytes() const = 0;
|
||||
|
||||
virtual const uint32_t* CipherBytes() const = 0;
|
||||
};
|
||||
|
||||
// These match to the DOMException codes as per:
|
||||
// http://www.w3.org/TR/dom/#domexception
|
||||
enum GMPDOMException {
|
||||
kGMPNoModificationAllowedError = 7,
|
||||
kGMPNotFoundError = 8,
|
||||
kGMPNotSupportedError = 9,
|
||||
kGMPInvalidStateError = 11,
|
||||
kGMPSyntaxError = 12,
|
||||
kGMPInvalidModificationError = 13,
|
||||
kGMPInvalidAccessError = 15,
|
||||
kGMPSecurityError = 18,
|
||||
kGMPAbortError = 20,
|
||||
kGMPQuotaExceededError = 22,
|
||||
kGMPTimeoutError = 23
|
||||
};
|
||||
|
||||
// Time in milliseconds, as offset from epoch, 1 Jan 1970.
|
||||
typedef int64_t GMPTimestamp;
|
||||
|
||||
class GMPDecryptorCallback {
|
||||
public:
|
||||
// Resolves a promise for a session created or loaded.
|
||||
// Passes the session id to be exposed to JavaScript.
|
||||
// Must be called before OnSessionMessage().
|
||||
// aSessionId must be null terminated.
|
||||
virtual void OnResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
|
||||
// Called to resolve a specified promise with "undefined".
|
||||
virtual void OnResolvePromise(uint32_t aPromiseId) = 0;
|
||||
|
||||
// Called to reject a promise with a DOMException.
|
||||
// aMessage is logged to the WebConsole.
|
||||
// aMessage is optional, but if present must be null terminated.
|
||||
virtual void OnRejectPromise(uint32_t aPromiseId,
|
||||
GMPDOMException aException,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength) = 0;
|
||||
|
||||
// Called by the CDM when it has a message for session |session_id|.
|
||||
// Length parameters should not include null termination.
|
||||
// aSessionId must be null terminated.
|
||||
virtual void OnSessionMessage(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aMessage,
|
||||
uint32_t aMessageLength,
|
||||
const char* aDestinationURL,
|
||||
uint32_t aDestinationURLLength) = 0;
|
||||
|
||||
// aSessionId must be null terminated.
|
||||
virtual void OnExpirationChange(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPTimestamp aExpiryTime) = 0;
|
||||
|
||||
// Called by the GMP when a session is closed. All file IO
|
||||
// that a session requires should be complete before calling this.
|
||||
// aSessionId must be null terminated.
|
||||
virtual void OnSessionClosed(const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
|
||||
// Called by the GMP when an error occurs in a session.
|
||||
// aSessionId must be null terminated.
|
||||
// aMessage is logged to the WebConsole.
|
||||
// aMessage is optional, but if present must be null terminated.
|
||||
virtual void OnSessionError(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPDOMException aException,
|
||||
uint32_t aSystemCode,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength) = 0;
|
||||
|
||||
virtual void OnKeyIdUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength) = 0;
|
||||
|
||||
// Marks a key as no longer usable.
|
||||
// Note: Keys are assumed to be not usable when a session is closed or removed.
|
||||
virtual void OnKeyIdNotUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength) = 0;
|
||||
|
||||
};
|
||||
|
||||
// Host interface, passed to GetAPIFunc(), with "decrypt".
|
||||
class GMPDecryptorHost {
|
||||
public:
|
||||
|
||||
// Returns an origin specific string uniquely identifying the device.
|
||||
// The node id contains a random component, and is consistent between
|
||||
// plugin instantiations, unless the user clears it.
|
||||
// Different origins have different node ids.
|
||||
// The node id pointer returned here remains valid for the until shutdown
|
||||
// begins.
|
||||
// *aOutNodeId is null terminated.
|
||||
virtual void GetNodeId(const char** aOutNodeId,
|
||||
uint32_t* aOutNodeIdLength) = 0;
|
||||
|
||||
virtual void GetSandboxVoucher(const uint8_t** aVoucher,
|
||||
uint8_t* aVoucherLength) = 0;
|
||||
|
||||
virtual void GetPluginVoucher(const uint8_t** aVoucher,
|
||||
uint8_t* aVoucherLength) = 0;
|
||||
};
|
||||
|
||||
enum GMPSessionType {
|
||||
kGMPTemporySession = 0,
|
||||
kGMPPersistentSession = 1
|
||||
};
|
||||
|
||||
// API exposed by plugin library to manage decryption sessions.
|
||||
// When the Host requests this by calling GMPGetAPIFunc().
|
||||
//
|
||||
// API name: "eme-decrypt".
|
||||
// Host API: GMPDecryptorHost
|
||||
class GMPDecryptor {
|
||||
public:
|
||||
|
||||
// Sets the callback to use with the decryptor to return results
|
||||
// to Gecko.
|
||||
virtual void Init(GMPDecryptorCallback* aCallback) = 0;
|
||||
|
||||
// Requests the creation of a session given |aType| and |aInitData|.
|
||||
// Decryptor should callback GMPDecryptorCallback::OnSessionCreated()
|
||||
// with the web session ID on success, or OnSessionError() on failure,
|
||||
// and then call OnSessionReady() once all keys for that session are
|
||||
// available.
|
||||
virtual void CreateSession(uint32_t aPromiseId,
|
||||
const char* aInitDataType,
|
||||
uint32_t aInitDataTypeSize,
|
||||
const uint8_t* aInitData,
|
||||
uint32_t aInitDataSize,
|
||||
GMPSessionType aSessionType) = 0;
|
||||
|
||||
// Loads a previously loaded persistent session.
|
||||
virtual void LoadSession(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
|
||||
// Updates the session with |aResponse|.
|
||||
virtual void UpdateSession(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aResponse,
|
||||
uint32_t aResponseSize) = 0;
|
||||
|
||||
// Releases the resources (keys) for the specified session.
|
||||
virtual void CloseSession(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
|
||||
// Removes the resources (keys) for the specified session.
|
||||
virtual void RemoveSession(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
|
||||
// Resolve/reject promise on completion.
|
||||
virtual void SetServerCertificate(uint32_t aPromiseId,
|
||||
const uint8_t* aServerCert,
|
||||
uint32_t aServerCertSize) = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_DECRYPTION_h_
|
@ -35,16 +35,7 @@
|
||||
|
||||
typedef enum {
|
||||
GMPNoErr = 0,
|
||||
GMPGenericErr = 1,
|
||||
GMPClosedErr = 2,
|
||||
GMPAllocErr = 3,
|
||||
GMPNotImplementedErr = 4,
|
||||
GMPNotClosedErr = 5,
|
||||
GMPQuotaExceededErr = 6,
|
||||
GMPLastErr // Placeholder, must be last. This enum's values must remain consecutive!
|
||||
GMPGenericErr = 1
|
||||
} GMPErr;
|
||||
|
||||
#define GMP_SUCCEEDED(x) ((x) == GMPNoErr)
|
||||
#define GMP_FAILED(x) ((x) != GMPNoErr)
|
||||
|
||||
#endif // GMP_ERRORS_h_
|
||||
|
@ -34,14 +34,12 @@
|
||||
#define GMP_PLATFORM_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-storage.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Platform helper API. */
|
||||
|
||||
class GMPTask {
|
||||
public:
|
||||
virtual void Destroy() = 0;
|
||||
virtual ~GMPTask() {}
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
@ -60,20 +58,10 @@ public:
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
// Time is defined as the number of milliseconds since the
|
||||
// Epoch (00:00:00 UTC, January 1, 1970).
|
||||
typedef int64_t GMPTimestamp;
|
||||
|
||||
typedef GMPErr (*GMPCreateThreadPtr)(GMPThread** aThread);
|
||||
typedef GMPErr (*GMPRunOnMainThreadPtr)(GMPTask* aTask);
|
||||
typedef GMPErr (*GMPSyncRunOnMainThreadPtr)(GMPTask* aTask);
|
||||
typedef GMPErr (*GMPCreateMutexPtr)(GMPMutex** aMutex);
|
||||
typedef GMPErr (*GMPCreateRecordPtr)(const char* aRecordName,
|
||||
uint32_t aRecordNameSize,
|
||||
GMPRecord** aOutRecord,
|
||||
GMPRecordClient* aClient);
|
||||
typedef GMPErr (*GMPSetTimerOnMainThreadPtr)(GMPTask* aTask, int64_t aTimeoutMS);
|
||||
typedef GMPErr (*GMPGetCurrentTimePtr)(GMPTimestamp* aOutTime);
|
||||
|
||||
struct GMPPlatformAPI {
|
||||
// Increment the version when things change. Can only add to the struct,
|
||||
@ -86,9 +74,6 @@ struct GMPPlatformAPI {
|
||||
GMPRunOnMainThreadPtr runonmainthread;
|
||||
GMPSyncRunOnMainThreadPtr syncrunonmainthread;
|
||||
GMPCreateMutexPtr createmutex;
|
||||
GMPCreateRecordPtr createrecord;
|
||||
GMPSetTimerOnMainThreadPtr settimer;
|
||||
GMPGetCurrentTimePtr getcurrenttime;
|
||||
};
|
||||
|
||||
#endif // GMP_PLATFORM_h_
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013, Mozilla Foundation and contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef GMP_STORAGE_h_
|
||||
#define GMP_STORAGE_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// Provides basic per-origin storage for CDMs. GMPRecord instances can be
|
||||
// retrieved by calling GMPPlatformAPI->openstorage. Multiple GMPRecord
|
||||
// can be open at once. This interface is asynchronous, with results
|
||||
// being returned via callbacks to the GMPRecordClient pointer provided
|
||||
// to the GMPPlatformAPI->openstorage call, on the main thread.
|
||||
class GMPRecord {
|
||||
public:
|
||||
|
||||
// Opens the record. Calls OnOpenComplete() once the record is open.
|
||||
// Note: OnReadComplete() is only called if this returns GMPNoErr.
|
||||
virtual GMPErr Open() = 0;
|
||||
|
||||
// Reads the entire contents of the file, and calls
|
||||
// GMPRecordClient::OnReadComplete() once the operation is complete.
|
||||
// Note: OnReadComplete() is only called if this returns GMPNoErr.
|
||||
virtual GMPErr Read() = 0;
|
||||
|
||||
// Writes aDataSize bytes of aData into the file, overwritting the contents
|
||||
// of the file. Overwriting with 0 bytes "deletes" the file.
|
||||
// Write 0 bytes to "delete" a file.
|
||||
// Note: OnWriteComplete is only called if this returns GMPNoErr.
|
||||
virtual GMPErr Write(const uint8_t* aData, uint32_t aDataSize) = 0;
|
||||
|
||||
// Closes a file. File must not be used after this is called. Cancels all
|
||||
// callbacks.
|
||||
virtual GMPErr Close() = 0;
|
||||
|
||||
virtual ~GMPRecord() {}
|
||||
};
|
||||
|
||||
// Callback object that receives the results of GMPRecord calls. Callbacks
|
||||
// run asynchronously to the GMPRecord call, on the main thread.
|
||||
class GMPRecordClient {
|
||||
public:
|
||||
|
||||
// Response to a GMPRecord::Open() call with the open |status|.
|
||||
// aStatus values:
|
||||
// - GMPNoErr - File opened successfully. File may be empty.
|
||||
// - GMPFileInUse - There file is in use by another client.
|
||||
// - GMPGenericErr - Unspecified error.
|
||||
// Do not use the GMPRecord if aStatus is not GMPNoErr.
|
||||
virtual void OnOpenComplete(GMPErr aStatus) = 0;
|
||||
|
||||
// Response to a GMPRecord::Read() call, where aData is the file contents,
|
||||
// of length aDataSize.
|
||||
// aData is only valid for the duration of the call to OnReadComplete.
|
||||
// Copy it if you want to hang onto it!
|
||||
// aStatus values:
|
||||
// - GMPNoErr - File contents read successfully, aDataSize 0 means file
|
||||
// is empty.
|
||||
// - GMPFileInUse - There are other operations or clients in use on this file.
|
||||
// - GMPGenericErr - Unspecified error.
|
||||
// Do not continue to use the GMPRecord if aStatus is not GMPNoErr.
|
||||
virtual void OnReadComplete(GMPErr aStatus,
|
||||
const uint8_t* aData,
|
||||
uint32_t aDataSize) = 0;
|
||||
|
||||
// Response to a GMPRecord::Write() call.
|
||||
// - GMPNoErr - File contents written successfully.
|
||||
// - GMPFileInUse - There are other operations or clients in use on this file.
|
||||
// - GMPGenericErr - Unspecified error. File should be regarded as corrupt.
|
||||
// Do not continue to use the GMPRecord if aStatus is not GMPNoErr.
|
||||
virtual void OnWriteComplete(GMPErr aStatus) = 0;
|
||||
|
||||
virtual ~GMPRecordClient() {}
|
||||
};
|
||||
|
||||
#endif // GMP_STORAGE_h_
|
@ -72,50 +72,39 @@ struct GMPVideoCodecVP8
|
||||
bool mDenoisingOn;
|
||||
bool mErrorConcealmentOn;
|
||||
bool mAutomaticResizeOn;
|
||||
bool mFrameDroppingOn;
|
||||
int32_t mKeyFrameInterval;
|
||||
};
|
||||
|
||||
// H264 specific
|
||||
|
||||
// Needs to match a binary spec for this structure.
|
||||
// Note: the mSPS at the end of this structure is variable length.
|
||||
struct GMPVideoCodecH264AVCC
|
||||
{
|
||||
uint8_t mVersion; // == 0x01
|
||||
uint8_t mProfile; // these 3 are profile_level_id
|
||||
uint8_t mConstraints;
|
||||
uint8_t mLevel;
|
||||
uint8_t mLengthSizeMinusOne; // lower 2 bits (== GMPBufferType-1). Top 6 reserved (1's)
|
||||
|
||||
// SPS/PPS will not generally be present for interactive use unless SDP
|
||||
// parameter-sets are used.
|
||||
uint8_t mNumSPS; // lower 5 bits; top 5 reserved (1's)
|
||||
|
||||
/*** uint8_t mSPS[]; (Not defined due to compiler warnings and warnings-as-errors ...) **/
|
||||
// Following mNumSPS is a variable number of bytes, which is the SPS and PPS.
|
||||
// Each SPS == 16 bit size, ("N"), then "N" bytes,
|
||||
// then uint8_t mNumPPS, then each PPS == 16 bit size ("N"), then "N" bytes.
|
||||
};
|
||||
|
||||
// Codec specific data for H.264 decoding/encoding.
|
||||
// Cast the "aCodecSpecific" parameter of GMPVideoDecoder::InitDecode() and
|
||||
// GMPVideoEncoder::InitEncode() to this structure.
|
||||
struct GMPVideoCodecH264
|
||||
{
|
||||
uint8_t mProfile;
|
||||
uint8_t mConstraints;
|
||||
uint8_t mLevel;
|
||||
uint8_t mPacketizationMode; // 0 or 1
|
||||
struct GMPVideoCodecH264AVCC mAVCC; // holds a variable-sized struct GMPVideoCodecH264AVCC mAVCC;
|
||||
bool mFrameDroppingOn;
|
||||
int32_t mKeyFrameInterval;
|
||||
// These are null/0 if not externally negotiated
|
||||
const uint8_t* mSPSData;
|
||||
size_t mSPSLen;
|
||||
const uint8_t* mPPSData;
|
||||
size_t mPPSLen;
|
||||
};
|
||||
|
||||
enum GMPVideoCodecType
|
||||
{
|
||||
kGMPVideoCodecVP8,
|
||||
|
||||
// Encoded frames are in AVCC format; NAL length field of 4 bytes, followed
|
||||
// by frame data. May be multiple NALUs per sample. Codec specific extra data
|
||||
// is the AVCC extra data (in AVCC format).
|
||||
kGMPVideoCodecH264,
|
||||
kGMPVideoCodecInvalid // Should always be last.
|
||||
};
|
||||
|
||||
union GMPVideoCodecUnion
|
||||
{
|
||||
GMPVideoCodecVP8 mVP8;
|
||||
GMPVideoCodecH264 mH264;
|
||||
};
|
||||
|
||||
// Simulcast is when the same stream is encoded multiple times with different
|
||||
// settings such as resolution.
|
||||
struct GMPSimulcastStream
|
||||
@ -132,19 +121,11 @@ struct GMPSimulcastStream
|
||||
enum GMPVideoCodecMode {
|
||||
kGMPRealtimeVideo,
|
||||
kGMPScreensharing,
|
||||
kGMPStreamingVideo,
|
||||
kGMPCodecModeInvalid // Should always be last.
|
||||
};
|
||||
|
||||
enum GMPApiVersion {
|
||||
kGMPVersion32 = 1, // leveraging that V32 had mCodecType first, and only supported H264
|
||||
kGMPVersion33 = 33,
|
||||
};
|
||||
|
||||
struct GMPVideoCodec
|
||||
{
|
||||
uint32_t mGMPApiVersion;
|
||||
|
||||
GMPVideoCodecType mCodecType;
|
||||
char mPLName[kGMPPayloadNameSize]; // Must be NULL-terminated!
|
||||
uint32_t mPLType;
|
||||
@ -157,8 +138,7 @@ struct GMPVideoCodec
|
||||
uint32_t mMinBitrate; // kilobits/sec.
|
||||
uint32_t mMaxFramerate;
|
||||
|
||||
bool mFrameDroppingOn;
|
||||
int32_t mKeyFrameInterval;
|
||||
GMPVideoCodecUnion mCodecSpecific;
|
||||
|
||||
uint32_t mQPMax;
|
||||
uint32_t mNumberOfSimulcastStreams;
|
||||
@ -177,7 +157,6 @@ enum GMPBufferType {
|
||||
GMP_BufferLength16,
|
||||
GMP_BufferLength24,
|
||||
GMP_BufferLength32,
|
||||
GMP_BufferInvalid,
|
||||
};
|
||||
|
||||
struct GMPCodecSpecificInfoGeneric {
|
||||
@ -209,7 +188,6 @@ union GMPCodecSpecificInfoUnion
|
||||
{
|
||||
GMPCodecSpecificInfoGeneric mGeneric;
|
||||
GMPCodecSpecificInfoVP8 mVP8;
|
||||
GMPCodecSpecificInfoH264 mH264;
|
||||
};
|
||||
|
||||
// Note: if any pointers are added to this struct or its sub-structs, it
|
||||
|
@ -34,17 +34,17 @@
|
||||
#ifndef GMP_VIDEO_DECODE_h_
|
||||
#define GMP_VIDEO_DECODE_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-video-errors.h"
|
||||
#include "gmp-video-frame-i420.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
#include "gmp-video-codec.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
|
||||
class GMPVideoDecoderCallback
|
||||
class GMPDecoderCallback
|
||||
{
|
||||
public:
|
||||
virtual ~GMPVideoDecoderCallback() {}
|
||||
virtual ~GMPDecoderCallback() {}
|
||||
|
||||
virtual void Decoded(GMPVideoi420Frame* aDecodedFrame) = 0;
|
||||
|
||||
@ -53,10 +53,6 @@ public:
|
||||
virtual void ReceivedDecodedFrame(const uint64_t aPictureId) = 0;
|
||||
|
||||
virtual void InputDataExhausted() = 0;
|
||||
|
||||
virtual void DrainComplete() = 0;
|
||||
|
||||
virtual void ResetComplete() = 0;
|
||||
};
|
||||
|
||||
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
|
||||
@ -65,50 +61,37 @@ class GMPVideoDecoder
|
||||
public:
|
||||
virtual ~GMPVideoDecoder() {}
|
||||
|
||||
// - aCodecSettings: Details of decoder to create.
|
||||
// - aCodecSpecific: codec specific data, cast to a GMPVideoCodecXXX struct
|
||||
// to get codec specific config data.
|
||||
// - aCodecSpecificLength: number of bytes in aCodecSpecific.
|
||||
// - aCallback: Subclass should retain reference to it until DecodingComplete
|
||||
// is called. Do not attempt to delete it, host retains ownership.
|
||||
// aCoreCount: number of CPU cores.
|
||||
virtual GMPErr InitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
const uint8_t* aCodecSpecific,
|
||||
uint32_t aCodecSpecificLength,
|
||||
GMPVideoDecoderCallback* aCallback,
|
||||
int32_t aCoreCount) = 0;
|
||||
// aCallback: Subclass should retain reference to it until DecodingComplete
|
||||
// is called. Do not attempt to delete it, host retains ownership.
|
||||
virtual GMPVideoErr InitDecode(const GMPVideoCodec& aCodecSettings,
|
||||
GMPDecoderCallback* aCallback,
|
||||
int32_t aCoreCount) = 0;
|
||||
|
||||
// Decode encoded frame (as a part of a video stream). The decoded frame
|
||||
// will be returned to the user through the decode complete callback.
|
||||
//
|
||||
// - aInputFrame: Frame to decode. Call Destroy() on frame when it's decoded.
|
||||
// - aMissingFrames: True if one or more frames have been lost since the
|
||||
// previous decode call.
|
||||
// - aBufferType : type of frame to encode
|
||||
// - aCodecSpecificInfo : codec specific data, pointer to a
|
||||
// GMPCodecSpecificInfo structure appropriate for
|
||||
// this codec type.
|
||||
// - aCodecSpecificInfoLength : number of bytes in aCodecSpecificInfo
|
||||
// - renderTimeMs : System time to render in milliseconds. Only used by
|
||||
// decoders with internal rendering.
|
||||
virtual GMPErr Decode(GMPVideoEncodedFrame* aInputFrame,
|
||||
bool aMissingFrames,
|
||||
GMPBufferType aBufferType,
|
||||
const uint8_t* aCodecSpecificInfo,
|
||||
uint32_t aCodecSpecificInfoLength,
|
||||
int64_t aRenderTimeMs = -1) = 0;
|
||||
// inputFrame: Frame to decode.
|
||||
//
|
||||
// missingFrames: True if one or more frames have been lost since the previous decode call.
|
||||
//
|
||||
// fragmentation: Specifies where the encoded frame can be split into separate fragments.
|
||||
// The meaning of fragment is codec specific, but often means that each
|
||||
// fragment is decodable by itself.
|
||||
//
|
||||
// codecSpecificInfo: Codec-specific data
|
||||
//
|
||||
// renderTimeMs : System time to render in milliseconds. Only used by decoders with internal
|
||||
// rendering.
|
||||
virtual GMPVideoErr Decode(GMPVideoEncodedFrame* aInputFrame,
|
||||
bool aMissingFrames,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
int64_t aRenderTimeMs = -1) = 0;
|
||||
|
||||
// Reset decoder state and prepare for a new call to Decode(...).
|
||||
// Flushes the decoder pipeline.
|
||||
// The decoder should enqueue a task to run ResetComplete() on the main
|
||||
// thread once the reset has finished.
|
||||
virtual GMPErr Reset() = 0;
|
||||
// Reset decoder state and prepare for a new call to Decode(...). Flushes the decoder pipeline.
|
||||
virtual GMPVideoErr Reset() = 0;
|
||||
|
||||
// Output decoded frames for any data in the pipeline, regardless of ordering.
|
||||
// All remaining decoded frames should be immediately returned via callback.
|
||||
// The decoder should enqueue a task to run DrainComplete() on the main
|
||||
// thread once the reset has finished.
|
||||
virtual GMPErr Drain() = 0;
|
||||
virtual GMPVideoErr Drain() = 0;
|
||||
|
||||
// May free decoder memory.
|
||||
virtual void DecodingComplete() = 0;
|
||||
|
@ -37,21 +37,19 @@
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-video-errors.h"
|
||||
#include "gmp-video-frame-i420.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
#include "gmp-video-codec.h"
|
||||
|
||||
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
|
||||
class GMPVideoEncoderCallback
|
||||
class GMPEncoderCallback
|
||||
{
|
||||
public:
|
||||
virtual ~GMPVideoEncoderCallback() {}
|
||||
virtual ~GMPEncoderCallback() {}
|
||||
|
||||
virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
GMPBufferType aBufferType,
|
||||
const uint8_t* aCodecSpecificInfo,
|
||||
uint32_t aCodecSpecificInfoLength) = 0;
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo) = 0;
|
||||
};
|
||||
|
||||
// ALL METHODS MUST BE CALLED ON THE MAIN THREAD
|
||||
@ -64,38 +62,26 @@ public:
|
||||
//
|
||||
// Input:
|
||||
// - codecSettings : Codec settings
|
||||
// - aCodecSpecific : codec specific data, pointer to a
|
||||
// GMPCodecSpecific structure appropriate for
|
||||
// this codec type.
|
||||
// - aCodecSpecificLength : number of bytes in aCodecSpecific
|
||||
// - aCallback: Subclass should retain reference to it until EncodingComplete
|
||||
// is called. Do not attempt to delete it, host retains ownership.
|
||||
// - aNnumberOfCores : Number of cores available for the encoder
|
||||
// - aMaxPayloadSize : The maximum size each payload is allowed
|
||||
// - numberOfCores : Number of cores available for the encoder
|
||||
// - maxPayloadSize : The maximum size each payload is allowed
|
||||
// to have. Usually MTU - overhead.
|
||||
virtual GMPErr InitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
const uint8_t* aCodecSpecific,
|
||||
uint32_t aCodecSpecificLength,
|
||||
GMPVideoEncoderCallback* aCallback,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize) = 0;
|
||||
virtual GMPVideoErr InitEncode(const GMPVideoCodec& aCodecSettings,
|
||||
GMPEncoderCallback* aCallback,
|
||||
int32_t aNumberOfCores,
|
||||
uint32_t aMaxPayloadSize) = 0;
|
||||
|
||||
// Encode an I420 frame (as a part of a video stream). The encoded frame
|
||||
// will be returned to the user through the encode complete callback.
|
||||
//
|
||||
// Input:
|
||||
// - aInputFrame : Frame to be encoded
|
||||
// - aCodecSpecificInfo : codec specific data, pointer to a
|
||||
// GMPCodecSpecificInfo structure appropriate for
|
||||
// this codec type.
|
||||
// - aCodecSpecificInfoLength : number of bytes in aCodecSpecific
|
||||
// - aFrameTypes : The frame type to encode
|
||||
// - aFrameTypesLength : The number of elements in aFrameTypes array.
|
||||
virtual GMPErr Encode(GMPVideoi420Frame* aInputFrame,
|
||||
const uint8_t* aCodecSpecificInfo,
|
||||
uint32_t aCodecSpecificInfoLength,
|
||||
const GMPVideoFrameType* aFrameTypes,
|
||||
uint32_t aFrameTypesLength) = 0;
|
||||
// - inputFrame : Frame to be encoded
|
||||
// - codecSpecificInfo : Pointer to codec specific data
|
||||
// - frame_types : The frame type to encode
|
||||
virtual GMPVideoErr Encode(GMPVideoi420Frame* aInputFrame,
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo,
|
||||
const std::vector<GMPVideoFrameType>& aFrameTypes) = 0;
|
||||
|
||||
// Inform the encoder about the packet loss and round trip time on the
|
||||
// network used to decide the best pattern and signaling.
|
||||
@ -103,19 +89,19 @@ public:
|
||||
// - packetLoss : Fraction lost (loss rate in percent =
|
||||
// 100 * packetLoss / 255)
|
||||
// - rtt : Round-trip time in milliseconds
|
||||
virtual GMPErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
|
||||
virtual GMPVideoErr SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0;
|
||||
|
||||
// Inform the encoder about the new target bit rate.
|
||||
//
|
||||
// - newBitRate : New target bit rate
|
||||
// - frameRate : The target frame rate
|
||||
virtual GMPErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
|
||||
virtual GMPVideoErr SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0;
|
||||
|
||||
// Use this function to enable or disable periodic key frames. Can be useful for codecs
|
||||
// which have other ways of stopping error propagation.
|
||||
//
|
||||
// - enable : Enable or disable periodic key frames
|
||||
virtual GMPErr SetPeriodicKeyFrames(bool aEnable) = 0;
|
||||
virtual GMPVideoErr SetPeriodicKeyFrames(bool aEnable) = 0;
|
||||
|
||||
// May free Encoder memory.
|
||||
virtual void EncodingComplete() = 0;
|
||||
|
43
content/media/gmp/gmp-api/gmp-video-errors.h
Normal file
43
content/media/gmp/gmp-api/gmp-video-errors.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* Copyright (c) 2011, The WebRTC project authors. All rights reserved.
|
||||
* Copyright (c) 2014, Mozilla
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
** Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
** Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
** Neither the name of Google nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef GMP_VIDEO_ERRORS_h_
|
||||
#define GMP_VIDEO_ERRORS_h_
|
||||
|
||||
enum GMPVideoErr {
|
||||
GMPVideoNoErr = 0,
|
||||
GMPVideoGenericErr = 1,
|
||||
GMPVideoAllocErr = 2
|
||||
};
|
||||
|
||||
#endif // GMP_VIDEO_ERRORS_h_
|
@ -35,8 +35,6 @@
|
||||
#define GMP_VIDEO_FRAME_ENCODED_h_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "gmp-decryption.h"
|
||||
#include "gmp-video-frame.h"
|
||||
|
||||
enum GMPVideoFrameType
|
||||
{
|
||||
@ -60,22 +58,17 @@ class GMPVideoEncodedFrame : public GMPVideoFrame
|
||||
{
|
||||
public:
|
||||
// MAIN THREAD ONLY
|
||||
virtual GMPErr CreateEmptyFrame(uint32_t aSize) = 0;
|
||||
virtual GMPVideoErr CreateEmptyFrame(uint32_t aSize) = 0;
|
||||
// MAIN THREAD ONLY
|
||||
virtual GMPErr CopyFrame(const GMPVideoEncodedFrame& aVideoFrame) = 0;
|
||||
virtual GMPVideoErr CopyFrame(const GMPVideoEncodedFrame& aVideoFrame) = 0;
|
||||
virtual void SetEncodedWidth(uint32_t aEncodedWidth) = 0;
|
||||
virtual uint32_t EncodedWidth() = 0;
|
||||
virtual void SetEncodedHeight(uint32_t aEncodedHeight) = 0;
|
||||
virtual uint32_t EncodedHeight() = 0;
|
||||
// Microseconds
|
||||
virtual void SetTimeStamp(uint64_t aTimeStamp) = 0;
|
||||
virtual uint64_t TimeStamp() = 0;
|
||||
// Set frame duration (microseconds)
|
||||
// NOTE: next-frame's Timestamp() != this-frame's TimeStamp()+Duration()
|
||||
// depending on rounding to avoid having to track roundoff errors
|
||||
// and dropped/missing frames(!) (which may leave a large gap)
|
||||
virtual void SetDuration(uint64_t aDuration) = 0;
|
||||
virtual uint64_t Duration() const = 0;
|
||||
virtual void SetTimeStamp(uint32_t aTimeStamp) = 0;
|
||||
virtual uint32_t TimeStamp() = 0;
|
||||
virtual void SetCaptureTime(int64_t aCaptureTime) = 0;
|
||||
virtual int64_t CaptureTime() = 0;
|
||||
virtual void SetFrameType(GMPVideoFrameType aFrameType) = 0;
|
||||
virtual GMPVideoFrameType FrameType() = 0;
|
||||
virtual void SetAllocatedSize(uint32_t aNewSize) = 0;
|
||||
@ -86,9 +79,6 @@ public:
|
||||
virtual bool CompleteFrame() = 0;
|
||||
virtual const uint8_t* Buffer() const = 0;
|
||||
virtual uint8_t* Buffer() = 0;
|
||||
// Get data describing how this frame is encrypted, or nullptr if the
|
||||
// frame is not encrypted.
|
||||
virtual const GMPEncryptedBufferData* GetDecryptionData() const = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_VIDEO_FRAME_ENCODED_h_
|
||||
|
@ -34,7 +34,7 @@
|
||||
#ifndef GMP_VIDEO_FRAME_I420_h_
|
||||
#define GMP_VIDEO_FRAME_I420_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-video-errors.h"
|
||||
#include "gmp-video-frame.h"
|
||||
#include "gmp-video-plane.h"
|
||||
|
||||
@ -63,22 +63,22 @@ public:
|
||||
// on set dimensions - height and plane stride.
|
||||
// If required size is bigger than the allocated one, new buffers of adequate
|
||||
// size will be allocated.
|
||||
virtual GMPErr CreateEmptyFrame(int32_t aWidth, int32_t aHeight,
|
||||
int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0;
|
||||
virtual GMPVideoErr CreateEmptyFrame(int32_t aWidth, int32_t aHeight,
|
||||
int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0;
|
||||
|
||||
// MAIN THREAD ONLY
|
||||
// CreateFrame: Sets the frame's members and buffers. If required size is
|
||||
// bigger than allocated one, new buffers of adequate size will be allocated.
|
||||
virtual GMPErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
|
||||
int32_t aSize_u, const uint8_t* aBuffer_u,
|
||||
int32_t aSize_v, const uint8_t* aBuffer_v,
|
||||
int32_t aWidth, int32_t aHeight,
|
||||
int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0;
|
||||
virtual GMPVideoErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y,
|
||||
int32_t aSize_u, const uint8_t* aBuffer_u,
|
||||
int32_t aSize_v, const uint8_t* aBuffer_v,
|
||||
int32_t aWidth, int32_t aHeight,
|
||||
int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0;
|
||||
|
||||
// MAIN THREAD ONLY
|
||||
// Copy frame: If required size is bigger than allocated one, new buffers of
|
||||
// adequate size will be allocated.
|
||||
virtual GMPErr CopyFrame(const GMPVideoi420Frame& aVideoFrame) = 0;
|
||||
virtual GMPVideoErr CopyFrame(const GMPVideoi420Frame& aVideoFrame) = 0;
|
||||
|
||||
// Swap Frame.
|
||||
virtual void SwapFrame(GMPVideoi420Frame* aVideoFrame) = 0;
|
||||
@ -96,10 +96,10 @@ public:
|
||||
virtual int32_t Stride(GMPPlaneType aType) const = 0;
|
||||
|
||||
// Set frame width.
|
||||
virtual GMPErr SetWidth(int32_t aWidth) = 0;
|
||||
virtual GMPVideoErr SetWidth(int32_t aWidth) = 0;
|
||||
|
||||
// Set frame height.
|
||||
virtual GMPErr SetHeight(int32_t aHeight) = 0;
|
||||
virtual GMPVideoErr SetHeight(int32_t aHeight) = 0;
|
||||
|
||||
// Get frame width.
|
||||
virtual int32_t Width() const = 0;
|
||||
@ -107,20 +107,17 @@ public:
|
||||
// Get frame height.
|
||||
virtual int32_t Height() const = 0;
|
||||
|
||||
// Set frame timestamp (microseconds)
|
||||
virtual void SetTimestamp(uint64_t aTimestamp) = 0;
|
||||
// Set frame timestamp (90kHz).
|
||||
virtual void SetTimestamp(uint32_t aTimestamp) = 0;
|
||||
|
||||
// Get frame timestamp (microseconds)
|
||||
virtual uint64_t Timestamp() const = 0;
|
||||
// Get frame timestamp (90kHz).
|
||||
virtual uint32_t Timestamp() const = 0;
|
||||
|
||||
// Set frame duration (microseconds)
|
||||
// NOTE: next-frame's Timestamp() != this-frame's TimeStamp()+Duration()
|
||||
// depending on rounding to avoid having to track roundoff errors
|
||||
// and dropped/missing frames(!) (which may leave a large gap)
|
||||
virtual void SetDuration(uint64_t aDuration) = 0;
|
||||
// Set render time in miliseconds.
|
||||
virtual void SetRenderTime_ms(int64_t aRenderTime_ms) = 0;
|
||||
|
||||
// Get frame duration (microseconds)
|
||||
virtual uint64_t Duration() const = 0;
|
||||
// Get render time in miliseconds.
|
||||
virtual int64_t RenderTime_ms() const = 0;
|
||||
|
||||
// Return true if underlying plane buffers are of zero size, false if not.
|
||||
virtual bool IsZeroSize() const = 0;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#ifndef GMP_VIDEO_FRAME_h_
|
||||
#define GMP_VIDEO_FRAME_h_
|
||||
|
||||
#include "gmp-video-errors.h"
|
||||
#include "gmp-video-plane.h"
|
||||
|
||||
enum GMPVideoFrameFormat {
|
||||
|
@ -34,7 +34,7 @@
|
||||
#ifndef GMP_VIDEO_HOST_h_
|
||||
#define GMP_VIDEO_HOST_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-video-errors.h"
|
||||
#include "gmp-video-frame-i420.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
#include "gmp-video-codec.h"
|
||||
@ -44,8 +44,8 @@ class GMPVideoHost
|
||||
public:
|
||||
// Construct various video API objects. Host does not retain reference,
|
||||
// caller is owner and responsible for deleting.
|
||||
virtual GMPErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) = 0;
|
||||
virtual GMPErr CreatePlane(GMPPlane** aPlane) = 0;
|
||||
virtual GMPVideoErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) = 0;
|
||||
virtual GMPVideoErr CreatePlane(GMPPlane** aPlane) = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_VIDEO_HOST_h_
|
||||
|
@ -34,7 +34,7 @@
|
||||
#ifndef GMP_VIDEO_PLANE_h_
|
||||
#define GMP_VIDEO_PLANE_h_
|
||||
|
||||
#include "gmp-errors.h"
|
||||
#include "gmp-video-errors.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// The implementation backing this interface uses shared memory for the
|
||||
@ -52,18 +52,18 @@ public:
|
||||
// CreateEmptyPlane - set allocated size, actual plane size and stride:
|
||||
// If current size is smaller than current size, then a buffer of sufficient
|
||||
// size will be allocated.
|
||||
virtual GMPErr CreateEmptyPlane(int32_t aAllocatedSize,
|
||||
int32_t aStride,
|
||||
int32_t aPlaneSize) = 0;
|
||||
virtual GMPVideoErr CreateEmptyPlane(int32_t aAllocatedSize,
|
||||
int32_t aStride,
|
||||
int32_t aPlaneSize) = 0;
|
||||
|
||||
// MAIN THREAD ONLY
|
||||
// Copy the entire plane data.
|
||||
virtual GMPErr Copy(const GMPPlane& aPlane) = 0;
|
||||
virtual GMPVideoErr Copy(const GMPPlane& aPlane) = 0;
|
||||
|
||||
// MAIN THREAD ONLY
|
||||
// Copy buffer: If current size is smaller
|
||||
// than current size, then a buffer of sufficient size will be allocated.
|
||||
virtual GMPErr Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer) = 0;
|
||||
virtual GMPVideoErr Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer) = 0;
|
||||
|
||||
// Swap plane data.
|
||||
virtual void Swap(GMPPlane& aPlane) = 0;
|
||||
|
@ -11,19 +11,13 @@ XPIDL_SOURCES += [
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'gmp-api/gmp-async-shutdown.h',
|
||||
'gmp-api/gmp-audio-codec.h',
|
||||
'gmp-api/gmp-audio-decode.h',
|
||||
'gmp-api/gmp-audio-host.h',
|
||||
'gmp-api/gmp-audio-samples.h',
|
||||
'gmp-api/gmp-decryption.h',
|
||||
'gmp-api/gmp-entrypoints.h',
|
||||
'gmp-api/gmp-errors.h',
|
||||
'gmp-api/gmp-platform.h',
|
||||
'gmp-api/gmp-storage.h',
|
||||
'gmp-api/gmp-video-codec.h',
|
||||
'gmp-api/gmp-video-decode.h',
|
||||
'gmp-api/gmp-video-encode.h',
|
||||
'gmp-api/gmp-video-errors.h',
|
||||
'gmp-api/gmp-video-frame-encoded.h',
|
||||
'gmp-api/gmp-video-frame-i420.h',
|
||||
'gmp-api/gmp-video-frame.h',
|
||||
@ -39,11 +33,9 @@ EXPORTS += [
|
||||
'GMPSharedMemManager.h',
|
||||
'GMPVideoDecoderChild.h',
|
||||
'GMPVideoDecoderParent.h',
|
||||
'GMPVideoDecoderProxy.h',
|
||||
'GMPVideoEncodedFrameImpl.h',
|
||||
'GMPVideoEncoderChild.h',
|
||||
'GMPVideoEncoderParent.h',
|
||||
'GMPVideoEncoderProxy.h',
|
||||
'GMPVideoHost.h',
|
||||
'GMPVideoi420FrameImpl.h',
|
||||
'GMPVideoPlaneImpl.h',
|
||||
@ -56,7 +48,6 @@ UNIFIED_SOURCES += [
|
||||
'GMPProcessChild.cpp',
|
||||
'GMPProcessParent.cpp',
|
||||
'GMPService.cpp',
|
||||
'GMPSharedMemManager.cpp',
|
||||
'GMPVideoDecoderChild.cpp',
|
||||
'GMPVideoDecoderParent.cpp',
|
||||
'GMPVideoEncodedFrameImpl.cpp',
|
||||
@ -79,9 +70,6 @@ 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')
|
||||
|
@ -10,18 +10,18 @@
|
||||
%{C++
|
||||
#include "nsTArray.h"
|
||||
#include "nsStringGlue.h"
|
||||
class GMPVideoDecoderProxy;
|
||||
class GMPVideoEncoderProxy;
|
||||
class GMPVideoDecoder;
|
||||
class GMPVideoEncoder;
|
||||
class GMPVideoHost;
|
||||
%}
|
||||
|
||||
[ptr] native GMPVideoDecoderProxy(GMPVideoDecoderProxy);
|
||||
[ptr] native GMPVideoEncoderProxy(GMPVideoEncoderProxy);
|
||||
[ptr] native GMPVideoDecoder(GMPVideoDecoder);
|
||||
[ptr] native GMPVideoEncoder(GMPVideoEncoder);
|
||||
[ptr] native GMPVideoHost(GMPVideoHost);
|
||||
[ptr] native MessageLoop(MessageLoop);
|
||||
[ptr] native TagArray(nsTArray<nsCString>);
|
||||
|
||||
[scriptable, uuid(7cef50ca-7a0f-41f2-9560-47abf709f0d7)]
|
||||
[scriptable, uuid(63fc797f-9d01-43f4-8b93-5b1fe713c2f8)]
|
||||
interface mozIGeckoMediaPluginService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -36,9 +36,9 @@ interface mozIGeckoMediaPluginService : nsISupports
|
||||
* Callable only on GMP thread.
|
||||
*/
|
||||
[noscript]
|
||||
GMPVideoDecoderProxy getGMPVideoDecoder(in TagArray tags,
|
||||
[optional] in AString origin,
|
||||
out GMPVideoHost outVideoHost);
|
||||
GMPVideoDecoder getGMPVideoDecoder(in TagArray tags,
|
||||
[optional] in AString origin,
|
||||
out GMPVideoHost outVideoHost);
|
||||
|
||||
/**
|
||||
* Get a video encoder that supports the specified tags.
|
||||
@ -47,9 +47,9 @@ interface mozIGeckoMediaPluginService : nsISupports
|
||||
* Callable only on GMP thread.
|
||||
*/
|
||||
[noscript]
|
||||
GMPVideoEncoderProxy getGMPVideoEncoder(in TagArray tags,
|
||||
[optional] in AString origin,
|
||||
out GMPVideoHost outVideoHost);
|
||||
GMPVideoEncoder getGMPVideoEncoder(in TagArray tags,
|
||||
[optional] in AString origin,
|
||||
out GMPVideoHost outVideoHost);
|
||||
|
||||
/**
|
||||
* Add a directory to scan for gecko media plugins.
|
||||
|
@ -14,8 +14,6 @@
|
||||
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "GMPVideoDecoderProxy.h"
|
||||
#include "GMPVideoEncoderProxy.h"
|
||||
|
||||
#include "gmp-video-host.h"
|
||||
#include "gmp-video-frame-i420.h"
|
||||
@ -25,26 +23,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
#ifdef LOG
|
||||
#undef LOG
|
||||
#endif
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo*
|
||||
GetGMPLog()
|
||||
{
|
||||
static PRLogModuleInfo *sLog;
|
||||
if (!sLog)
|
||||
sLog = PR_NewLogModule("GMP");
|
||||
return sLog;
|
||||
}
|
||||
#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(leve, msg)
|
||||
#endif
|
||||
|
||||
// Encoder.
|
||||
WebrtcGmpVideoEncoder::WebrtcGmpVideoEncoder()
|
||||
: mGMPThread(nullptr)
|
||||
@ -143,7 +121,7 @@ WebrtcGmpVideoEncoder::InitEncode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
uint32_t aMaxPayloadSize)
|
||||
{
|
||||
GMPVideoHost* host = nullptr;
|
||||
GMPVideoEncoderProxy* gmp = nullptr;
|
||||
GMPVideoEncoder* gmp = nullptr;
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("vp8"));
|
||||
@ -166,7 +144,6 @@ WebrtcGmpVideoEncoder::InitEncode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
GMPVideoCodec codec;
|
||||
memset(&codec, 0, sizeof(codec));
|
||||
|
||||
codec.mGMPApiVersion = 33;
|
||||
codec.mWidth = aCodecSettings->width;
|
||||
codec.mHeight = aCodecSettings->height;
|
||||
codec.mStartBitrate = aCodecSettings->startBitrate;
|
||||
@ -174,12 +151,8 @@ WebrtcGmpVideoEncoder::InitEncode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
codec.mMaxBitrate = aCodecSettings->maxBitrate;
|
||||
codec.mMaxFramerate = aCodecSettings->maxFramerate;
|
||||
|
||||
// Pass dummy codecSpecific data for now...
|
||||
nsTArray<uint8_t> codecSpecific;
|
||||
|
||||
// H.264 mode 1 only supported so far
|
||||
GMPErr err = mGMP->InitEncode(codec, codecSpecific, this, 1, 256000 /*aMaxPayloadSize*/);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = mGMP->InitEncode(codec, this, 1, aMaxPayloadSize);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
@ -215,8 +188,8 @@ WebrtcGmpVideoEncoder::Encode_g(const webrtc::I420VideoFrame* aInputImage,
|
||||
MOZ_ASSERT(mGMP);
|
||||
|
||||
GMPVideoFrame* ftmp = nullptr;
|
||||
GMPErr err = mHost->CreateFrame(kGMPI420VideoFrame, &ftmp);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = mHost->CreateFrame(kGMPI420VideoFrame, &ftmp);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
GMPVideoi420Frame* frame = static_cast<GMPVideoi420Frame*>(ftmp);
|
||||
@ -232,20 +205,17 @@ WebrtcGmpVideoEncoder::Encode_g(const webrtc::I420VideoFrame* aInputImage,
|
||||
aInputImage->stride(webrtc::kYPlane),
|
||||
aInputImage->stride(webrtc::kUPlane),
|
||||
aInputImage->stride(webrtc::kVPlane));
|
||||
if (err != GMPNoErr) {
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
frame->SetTimestamp((aInputImage->timestamp() * 1000ll)/90); // note: rounds down!
|
||||
//frame->SetDuration(1000000ll/30); // XXX base duration on measured current FPS - or don't bother
|
||||
frame->SetTimestamp(aInputImage->timestamp());
|
||||
frame->SetRenderTime_ms(aInputImage->render_time_ms());
|
||||
|
||||
// Bug XXXXXX: Set codecSpecific info
|
||||
GMPCodecSpecificInfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.mCodecType = kGMPVideoCodecH264;
|
||||
nsTArray<uint8_t> codecSpecificInfo;
|
||||
codecSpecificInfo.AppendElements((uint8_t*)&info, sizeof(GMPCodecSpecificInfo));
|
||||
|
||||
nsTArray<GMPVideoFrameType> gmp_frame_types;
|
||||
std::vector<GMPVideoFrameType> gmp_frame_types;
|
||||
for (auto it = aFrameTypes->begin(); it != aFrameTypes->end(); ++it) {
|
||||
GMPVideoFrameType ft;
|
||||
|
||||
@ -254,12 +224,11 @@ WebrtcGmpVideoEncoder::Encode_g(const webrtc::I420VideoFrame* aInputImage,
|
||||
return ret;
|
||||
}
|
||||
|
||||
gmp_frame_types.AppendElement(ft);
|
||||
gmp_frame_types.push_back(ft);
|
||||
}
|
||||
|
||||
LOGD(("GMP Encode: %llu", (aInputImage->timestamp() * 1000ll)/90));
|
||||
err = mGMP->Encode(frame, codecSpecificInfo, gmp_frame_types);
|
||||
if (err != GMPNoErr) {
|
||||
err = mGMP->Encode(frame, info, gmp_frame_types);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -306,27 +275,104 @@ int32_t
|
||||
WebrtcGmpVideoEncoder::SetRates_g(uint32_t aNewBitRate, uint32_t aFrameRate)
|
||||
{
|
||||
MOZ_ASSERT(mGMP);
|
||||
GMPErr err = mGMP->SetRates(aNewBitRate, aFrameRate);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = mGMP->SetRates(aNewBitRate, aFrameRate);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
// GMPVideoEncoderCallback virtual functions.
|
||||
#define GMP_ENCODE_HAS_START_CODES 1
|
||||
#ifdef GMP_ENCODE_HAS_START_CODES
|
||||
// Temporary until inside-sandbox-code switches from start codes to the API here
|
||||
static int GetNextNALUnit(const uint8_t **aData,
|
||||
const uint8_t *aEnd, // at first byte past end
|
||||
size_t *aNalSize)
|
||||
{
|
||||
const uint8_t *data = *aData;
|
||||
uint8_t zeros = 0;
|
||||
|
||||
MOZ_ASSERT(data);
|
||||
// Don't assume we start with a start code (paranoia)
|
||||
while (data < aEnd) {
|
||||
if (*data == 0) {
|
||||
zeros++;
|
||||
if (zeros > 3) {
|
||||
// internal format error; keep going anyways
|
||||
zeros = 3;
|
||||
}
|
||||
} else {
|
||||
if (*data == 0x01) {
|
||||
if (zeros >= 2) {
|
||||
// Found start code 0x000001 or 0x00000001
|
||||
MOZ_ASSERT(zeros == 3); // current temp code only handles 4-byte codes
|
||||
// now find the length of the NAL
|
||||
*aData = ++data; // start of actual data
|
||||
|
||||
while (data < aEnd) {
|
||||
if (*data == 0) {
|
||||
zeros++;
|
||||
if (zeros > 3) {
|
||||
// internal format error; keep going anyways
|
||||
zeros = 3;
|
||||
}
|
||||
} else {
|
||||
if (*data == 0x01) {
|
||||
if (zeros >= 2) {
|
||||
// Found start code 0x000001 or 0x00000001
|
||||
*aNalSize = (data - *aData) - zeros;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
zeros = 0;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
// NAL ends at the end of the buffer
|
||||
*aNalSize = (data - *aData);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
zeros = 0;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
return -1; // no nals
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// GMPEncoderCallback virtual functions.
|
||||
void
|
||||
WebrtcGmpVideoEncoder::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
GMPBufferType aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo)
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo)
|
||||
{
|
||||
if (mCallback) { // paranoia
|
||||
webrtc::VideoFrameType ft;
|
||||
GmpFrameTypeToWebrtcFrameType(aEncodedFrame->FrameType(), &ft);
|
||||
uint32_t timestamp = (aEncodedFrame->TimeStamp() * 90ll + 999)/1000;
|
||||
GMPBufferType type = aCodecSpecificInfo.mBufferType;
|
||||
|
||||
LOGD(("GMP Encoded: %llu, type %d, len %d", aEncodedFrame->TimeStamp(), aBufferType,
|
||||
aEncodedFrame->Size()));
|
||||
#ifdef GMP_ENCODE_HAS_START_CODES
|
||||
{
|
||||
// This code will be removed when the code inside the plugin is updated
|
||||
// Break input encoded data into NALUs and convert to length+data format
|
||||
const uint8_t* data = aEncodedFrame->Buffer();
|
||||
const uint8_t* end = data + aEncodedFrame->Size(); // at first byte past end
|
||||
size_t nalSize = 0;
|
||||
while (GetNextNALUnit(&data, end, &nalSize) == 0) {
|
||||
// Assumes 4-byte start codes (0x00000001)
|
||||
MOZ_ASSERT(data >= aEncodedFrame->Buffer() + 4);
|
||||
uint8_t *start_code = const_cast<uint8_t*>(data-sizeof(uint32_t));
|
||||
if (*start_code == 0x00 && *(start_code+1) == 0x00 &&
|
||||
*(start_code+2) == 0x00 && *(start_code+3) == 0x01) {
|
||||
*(reinterpret_cast<uint32_t*>(start_code)) = nalSize;
|
||||
}
|
||||
data += nalSize;
|
||||
}
|
||||
type = GMP_BufferLength32;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Right now makes one Encoded() callback per unit
|
||||
// XXX convert to FragmentationHeader format (array of offsets and sizes plus a buffer) in
|
||||
@ -335,7 +381,7 @@ WebrtcGmpVideoEncoder::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
uint8_t *end = aEncodedFrame->Buffer() + aEncodedFrame->Size();
|
||||
uint32_t size;
|
||||
while (buffer < end) {
|
||||
switch (aBufferType) {
|
||||
switch (type) {
|
||||
case GMP_BufferSingle:
|
||||
size = aEncodedFrame->Size();
|
||||
break;
|
||||
@ -362,13 +408,13 @@ WebrtcGmpVideoEncoder::Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
break;
|
||||
default:
|
||||
// really that it's not in the enum; gives more readable error
|
||||
MOZ_ASSERT(aBufferType != GMP_BufferSingle);
|
||||
MOZ_ASSERT(aCodecSpecificInfo.mBufferType != GMP_BufferSingle);
|
||||
aEncodedFrame->Destroy();
|
||||
return;
|
||||
}
|
||||
webrtc::EncodedImage unit(buffer, size, size);
|
||||
unit._frameType = ft;
|
||||
unit._timeStamp = timestamp;
|
||||
unit._timeStamp = aEncodedFrame->TimeStamp();
|
||||
unit._completeFrame = true;
|
||||
|
||||
mCallback->Encoded(unit, nullptr, nullptr);
|
||||
@ -415,7 +461,7 @@ WebrtcGmpVideoDecoder::InitDecode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
int32_t aNumberOfCores)
|
||||
{
|
||||
GMPVideoHost* host = nullptr;
|
||||
GMPVideoDecoderProxy* gmp = nullptr;
|
||||
GMPVideoDecoder* gmp = nullptr;
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("vp8"));
|
||||
@ -435,14 +481,9 @@ WebrtcGmpVideoDecoder::InitDecode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
// Bug XXXXXX: transfer settings from codecSettings to codec.
|
||||
GMPVideoCodec codec;
|
||||
memset(&codec, 0, sizeof(codec));
|
||||
codec.mGMPApiVersion = 33;
|
||||
|
||||
// XXX this is currently a hack
|
||||
//GMPVideoCodecUnion codecSpecific;
|
||||
//memset(&codecSpecific, 0, sizeof(codecSpecific));
|
||||
nsTArray<uint8_t> codecSpecific;
|
||||
nsresult rv = mGMP->InitDecode(codec, codecSpecific, this, 1);
|
||||
if (NS_FAILED(rv)) {
|
||||
GMPVideoErr err = mGMP->InitDecode(codec, this, 1);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
@ -482,27 +523,22 @@ WebrtcGmpVideoDecoder::Decode_g(const webrtc::EncodedImage& aInputImage,
|
||||
MOZ_ASSERT(mGMP);
|
||||
|
||||
GMPVideoFrame* ftmp = nullptr;
|
||||
GMPErr err = mHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp);
|
||||
if (err != GMPNoErr) {
|
||||
GMPVideoErr err = mHost->CreateFrame(kGMPEncodedVideoFrame, &ftmp);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
GMPVideoEncodedFrame* frame = static_cast<GMPVideoEncodedFrame*>(ftmp);
|
||||
err = frame->CreateEmptyFrame(aInputImage._length);
|
||||
if (err != GMPNoErr) {
|
||||
if (err != GMPVideoNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
// XXX At this point, we only will get mode1 data (a single length and a buffer)
|
||||
// Session_info.cc/etc code needs to change to support mode 0.
|
||||
*(reinterpret_cast<uint32_t*>(frame->Buffer())) = frame->Size();
|
||||
|
||||
// XXX It'd be wonderful not to have to memcpy the encoded data!
|
||||
memcpy(frame->Buffer()+4, aInputImage._buffer+4, frame->Size()-4);
|
||||
memcpy(frame->Buffer(), aInputImage._buffer, frame->Size());
|
||||
|
||||
frame->SetEncodedWidth(aInputImage._encodedWidth);
|
||||
frame->SetEncodedHeight(aInputImage._encodedHeight);
|
||||
frame->SetTimeStamp((aInputImage._timeStamp * 1000ll)/90); // rounds down
|
||||
frame->SetTimeStamp(aInputImage._timeStamp);
|
||||
frame->SetCompleteFrame(aInputImage._completeFrame);
|
||||
|
||||
GMPVideoFrameType ft;
|
||||
@ -514,18 +550,9 @@ WebrtcGmpVideoDecoder::Decode_g(const webrtc::EncodedImage& aInputImage,
|
||||
// Bug XXXXXX: Set codecSpecific info
|
||||
GMPCodecSpecificInfo info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.mCodecType = kGMPVideoCodecH264;
|
||||
info.mCodecSpecific.mH264.mSimulcastIdx = 0;
|
||||
nsTArray<uint8_t> codecSpecificInfo;
|
||||
codecSpecificInfo.AppendElements((uint8_t*)&info, sizeof(GMPCodecSpecificInfo));
|
||||
|
||||
LOGD(("GMP Decode: %llu, len %d", frame->TimeStamp(), aInputImage._length));
|
||||
nsresult rv = mGMP->Decode(frame,
|
||||
aMissingFrames,
|
||||
GMP_BufferLength32,
|
||||
codecSpecificInfo,
|
||||
aRenderTimeMs);
|
||||
if (NS_FAILED(rv)) {
|
||||
err = mGMP->Decode(frame, aMissingFrames, info, aRenderTimeMs);
|
||||
if (err != GMPVideoNoErr) {
|
||||
return WEBRTC_VIDEO_CODEC_ERROR;
|
||||
}
|
||||
|
||||
@ -572,10 +599,9 @@ WebrtcGmpVideoDecoder::Decoded(GMPVideoi420Frame* aDecodedFrame)
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
image.set_timestamp((aDecodedFrame->Timestamp() * 90ll + 999)/1000); // round up
|
||||
image.set_timestamp(aDecodedFrame->Timestamp());
|
||||
image.set_render_time_ms(0);
|
||||
|
||||
LOGD(("GMP Decoded: %llu", aDecodedFrame->Timestamp()));
|
||||
mCallback->Decoded(image);
|
||||
}
|
||||
aDecodedFrame->Destroy();
|
||||
|
@ -30,15 +30,17 @@
|
||||
#include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h"
|
||||
|
||||
#include "gmp-video-host.h"
|
||||
#include "GMPVideoDecoderProxy.h"
|
||||
#include "GMPVideoEncoderProxy.h"
|
||||
#include "gmp-video-encode.h"
|
||||
#include "gmp-video-decode.h"
|
||||
#include "gmp-video-frame-i420.h"
|
||||
#include "gmp-video-frame-encoded.h"
|
||||
|
||||
#include "WebrtcGmpVideoCodec.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebrtcGmpVideoEncoder : public WebrtcVideoEncoder,
|
||||
public GMPVideoEncoderCallbackProxy
|
||||
public GMPEncoderCallback
|
||||
{
|
||||
public:
|
||||
WebrtcGmpVideoEncoder();
|
||||
@ -64,10 +66,9 @@ public:
|
||||
virtual int32_t SetRates(uint32_t aNewBitRate,
|
||||
uint32_t aFrameRate) MOZ_OVERRIDE;
|
||||
|
||||
// GMPVideoEncoderCallback virtual functions.
|
||||
// GMPEncoderCallback virtual functions.
|
||||
virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame,
|
||||
GMPBufferType aBufferType,
|
||||
const nsTArray<uint8_t>& aCodecSpecificInfo) MOZ_OVERRIDE;
|
||||
const GMPCodecSpecificInfo& aCodecSpecificInfo) MOZ_OVERRIDE;
|
||||
|
||||
|
||||
private:
|
||||
@ -84,14 +85,14 @@ private:
|
||||
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
||||
nsIThread* mGMPThread;
|
||||
GMPVideoEncoderProxy* mGMP;
|
||||
GMPVideoEncoder* mGMP;
|
||||
GMPVideoHost* mHost;
|
||||
webrtc::EncodedImageCallback* mCallback;
|
||||
};
|
||||
|
||||
|
||||
class WebrtcGmpVideoDecoder : public WebrtcVideoDecoder,
|
||||
public GMPVideoDecoderCallback
|
||||
public GMPDecoderCallback
|
||||
{
|
||||
public:
|
||||
WebrtcGmpVideoDecoder();
|
||||
@ -125,14 +126,6 @@ public:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
virtual void DrainComplete() MOZ_OVERRIDE {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
virtual void ResetComplete() MOZ_OVERRIDE {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
private:
|
||||
virtual int32_t InitDecode_g(const webrtc::VideoCodec* aCodecSettings,
|
||||
int32_t aNumberOfCores);
|
||||
@ -145,7 +138,7 @@ private:
|
||||
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mMPS;
|
||||
nsIThread* mGMPThread;
|
||||
GMPVideoDecoderProxy* mGMP;
|
||||
GMPVideoDecoder* mGMP;
|
||||
GMPVideoHost* mHost;
|
||||
webrtc::DecodedImageCallback* mCallback;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user