Merge pull request #2023 from ethanhugg/refcount
Change GMP code to RefCount instead of deleting on enc/decode complete.
This commit is contained in:
commit
703cce0214
141
module/RefCounted.h
Normal file
141
module/RefCounted.h
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2015, 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 __RefCount_h__
|
||||
#define __RefCount_h__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
extern GMPPlatformAPI* g_platform_api;
|
||||
|
||||
inline GMPMutex* GMPCreateMutex() {
|
||||
GMPMutex* mutex;
|
||||
if (!g_platform_api) {
|
||||
return nullptr;
|
||||
}
|
||||
GMPErr err = g_platform_api->createmutex(&mutex);
|
||||
assert(mutex);
|
||||
return GMP_FAILED(err) ? nullptr : mutex;
|
||||
}
|
||||
|
||||
class AutoLock {
|
||||
public:
|
||||
explicit AutoLock(GMPMutex* aMutex)
|
||||
: mMutex(aMutex)
|
||||
{
|
||||
assert(aMutex);
|
||||
if (mMutex) {
|
||||
mMutex->Acquire();
|
||||
}
|
||||
}
|
||||
~AutoLock() {
|
||||
if (mMutex) {
|
||||
mMutex->Release();
|
||||
}
|
||||
}
|
||||
private:
|
||||
GMPMutex* mMutex;
|
||||
};
|
||||
|
||||
class AtomicRefCount {
|
||||
public:
|
||||
explicit AtomicRefCount(uint32_t aValue)
|
||||
: mCount(aValue)
|
||||
, mMutex(GMPCreateMutex())
|
||||
{
|
||||
assert(mMutex);
|
||||
}
|
||||
~AtomicRefCount()
|
||||
{
|
||||
if (mMutex) {
|
||||
mMutex->Destroy();
|
||||
}
|
||||
}
|
||||
uint32_t operator--() {
|
||||
AutoLock lock(mMutex);
|
||||
return --mCount;
|
||||
}
|
||||
uint32_t operator++() {
|
||||
AutoLock lock(mMutex);
|
||||
return ++mCount;
|
||||
}
|
||||
operator uint32_t() {
|
||||
AutoLock lock(mMutex);
|
||||
return mCount;
|
||||
}
|
||||
private:
|
||||
uint32_t mCount;
|
||||
GMPMutex* mMutex;
|
||||
};
|
||||
|
||||
// Note: Thread safe.
|
||||
class RefCounted {
|
||||
public:
|
||||
void AddRef() {
|
||||
++mRefCount;
|
||||
}
|
||||
|
||||
uint32_t Release() {
|
||||
uint32_t newCount = --mRefCount;
|
||||
if (!newCount) {
|
||||
delete this;
|
||||
}
|
||||
return newCount;
|
||||
}
|
||||
|
||||
protected:
|
||||
RefCounted()
|
||||
: mRefCount(0)
|
||||
{
|
||||
}
|
||||
virtual ~RefCounted()
|
||||
{
|
||||
assert(!mRefCount);
|
||||
}
|
||||
AtomicRefCount mRefCount;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class RefPtr {
|
||||
public:
|
||||
explicit RefPtr(T* aPtr) : mPtr(nullptr) {
|
||||
Assign(aPtr);
|
||||
}
|
||||
~RefPtr() {
|
||||
Assign(nullptr);
|
||||
}
|
||||
T* operator->() const { return mPtr; }
|
||||
|
||||
RefPtr& operator=(T* aVal) {
|
||||
Assign(aVal);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void Assign(T* aPtr) {
|
||||
if (mPtr) {
|
||||
mPtr->Release();
|
||||
}
|
||||
mPtr = aPtr;
|
||||
if (mPtr) {
|
||||
aPtr->AddRef();
|
||||
}
|
||||
}
|
||||
T* mPtr;
|
||||
};
|
||||
|
||||
#endif // __RefCount_h__
|
@ -53,8 +53,6 @@
|
||||
#include "codec_app_def.h"
|
||||
#include "codec_api.h"
|
||||
|
||||
#include "task_utils.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define PUBLIC_FUNC __declspec(dllexport)
|
||||
#else
|
||||
@ -91,6 +89,8 @@
|
||||
# define nullptr __null
|
||||
#endif
|
||||
|
||||
#include "task_utils.h"
|
||||
|
||||
static int g_log_level = 0;
|
||||
|
||||
#define GMPLOG(l, x) do { \
|
||||
@ -116,7 +116,7 @@ const char* kLogStrings[] = {
|
||||
};
|
||||
|
||||
|
||||
static GMPPlatformAPI* g_platform_api = nullptr;
|
||||
GMPPlatformAPI* g_platform_api = nullptr;
|
||||
|
||||
class OpenH264VideoEncoder;
|
||||
|
||||
@ -179,7 +179,7 @@ class FrameStats {
|
||||
const std::string type_;
|
||||
};
|
||||
|
||||
class OpenH264VideoEncoder : public GMPVideoEncoder {
|
||||
class OpenH264VideoEncoder : public GMPVideoEncoder, public RefCounted {
|
||||
public:
|
||||
OpenH264VideoEncoder (GMPVideoHost* hostAPI) :
|
||||
host_ (hostAPI),
|
||||
@ -187,11 +187,9 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
|
||||
encoder_ (nullptr),
|
||||
max_payload_size_ (0),
|
||||
callback_ (nullptr),
|
||||
stats_ ("Encoder") {}
|
||||
|
||||
virtual ~OpenH264VideoEncoder() {
|
||||
worker_thread_->Join();
|
||||
}
|
||||
stats_ ("Encoder") {
|
||||
AddRef();
|
||||
}
|
||||
|
||||
virtual void InitEncode (const GMPVideoCodec& codecSettings,
|
||||
const uint8_t* aCodecSpecific,
|
||||
@ -285,7 +283,7 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
|
||||
|
||||
assert (aFrameTypesLength != 0);
|
||||
|
||||
worker_thread_->Post (WrapTask (
|
||||
worker_thread_->Post (WrapTaskRefCounted (
|
||||
this, &OpenH264VideoEncoder::Encode_w,
|
||||
inputImage,
|
||||
(aFrameTypes)[0]));
|
||||
@ -363,10 +361,14 @@ class OpenH264VideoEncoder : public GMPVideoEncoder {
|
||||
}
|
||||
|
||||
virtual void EncodingComplete() {
|
||||
delete this;
|
||||
Release();
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~OpenH264VideoEncoder() {
|
||||
worker_thread_->Join();
|
||||
}
|
||||
|
||||
void Error (GMPErr error) {
|
||||
if (callback_) {
|
||||
callback_->Error (error);
|
||||
@ -560,17 +562,16 @@ void copyWithStartCode(std::vector<uint8_t>& out, const uint8_t* in, size_t size
|
||||
out.insert(out.end(), in, in + size);
|
||||
}
|
||||
|
||||
class OpenH264VideoDecoder : public GMPVideoDecoder {
|
||||
class OpenH264VideoDecoder : public GMPVideoDecoder, public RefCounted {
|
||||
public:
|
||||
OpenH264VideoDecoder (GMPVideoHost* hostAPI) :
|
||||
host_ (hostAPI),
|
||||
worker_thread_ (nullptr),
|
||||
callback_ (nullptr),
|
||||
decoder_ (nullptr),
|
||||
stats_ ("Decoder") {}
|
||||
|
||||
virtual ~OpenH264VideoDecoder() {
|
||||
}
|
||||
stats_ ("Decoder") {
|
||||
AddRef();
|
||||
}
|
||||
|
||||
virtual void InitDecode (const GMPVideoCodec& codecSettings,
|
||||
const uint8_t* aCodecSpecific,
|
||||
@ -691,7 +692,7 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
|
||||
break;
|
||||
}
|
||||
DECODING_STATE dState = dsErrorFree;
|
||||
worker_thread_->Post (WrapTask (
|
||||
worker_thread_->Post (WrapTaskRefCounted (
|
||||
this, &OpenH264VideoDecoder::Decode_w,
|
||||
inputFrame,
|
||||
missingFrames,
|
||||
@ -715,10 +716,13 @@ class OpenH264VideoDecoder : public GMPVideoDecoder {
|
||||
}
|
||||
|
||||
virtual void DecodingComplete() {
|
||||
delete this;
|
||||
Release();
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~OpenH264VideoDecoder() {
|
||||
}
|
||||
|
||||
void Error (GMPErr error) {
|
||||
if (callback_) {
|
||||
callback_->Error (error);
|
||||
|
@ -7,6 +7,29 @@ boilerplate = "/* This Source Code Form is subject to the terms of the Mozilla P
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this\n\
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n"
|
||||
|
||||
includes = "#include \"RefCounted.h\"\n"
|
||||
|
||||
refcountclass = "class RefCountTaskWrapper : public gmp_args_base {\n\
|
||||
public:\n\
|
||||
RefCountTaskWrapper(GMPTask* aTask, RefCounted* aRefCounted)\n\
|
||||
: mTask(aTask)\n\
|
||||
, mRefCounted(aRefCounted)\n\
|
||||
{}\n\
|
||||
virtual void Run() {\n\
|
||||
mTask->Run();\n\
|
||||
}\n\
|
||||
virtual void Destroy() {\n\
|
||||
mTask->Destroy();\n\
|
||||
gmp_args_base::Destroy();\n\
|
||||
}\n\
|
||||
private:\n\
|
||||
~RefCountTaskWrapper() {}\n\
|
||||
\n\
|
||||
GMPTask* mTask;\n\
|
||||
RefPtr<RefCounted> mRefCounted;\n\
|
||||
};\n"
|
||||
|
||||
|
||||
def gen_args_type(args, member):
|
||||
if member:
|
||||
ret = ["C o"]
|
||||
@ -35,16 +58,16 @@ def gen_args_(args):
|
||||
|
||||
def gen_init(args, r = False, member = False):
|
||||
if member:
|
||||
ret = ["o_(o)"]
|
||||
ret = ["o_ (o)"]
|
||||
else:
|
||||
ret = []
|
||||
ret.append("m_(m)")
|
||||
ret.append("m_ (m)")
|
||||
|
||||
if r:
|
||||
ret.append("r_(r)")
|
||||
ret.append("r_ (r)")
|
||||
|
||||
for arg in range(0, args):
|
||||
ret.append("a%d_(a%d)"%(arg, arg))
|
||||
ret.append("a%d_ (a%d)"%(arg, arg))
|
||||
return ", ".join(ret)
|
||||
|
||||
def gen_typenames(args, member):
|
||||
@ -84,12 +107,12 @@ def generate_class_template(args, ret = False, member = True):
|
||||
print " public:"
|
||||
|
||||
if not ret:
|
||||
print " gmp_args_%s_%d("%(nm, args) + gen_args_type(args, member) + ") :"
|
||||
print " gmp_args_%s_%d ("%(nm, args) + gen_args_type(args, member) + ") :"
|
||||
print " " + gen_init(args, False, member) + " {}"
|
||||
else:
|
||||
print " gmp_args_%s_%d_ret("%(nm, args) + gen_args_type(args, member) + ", R *r) :"
|
||||
print " gmp_args_%s_%d_ret ("%(nm, args) + gen_args_type(args, member) + ", R* r) :"
|
||||
print " " + gen_init(args, True, member) + " {}"
|
||||
print " virtual bool returns_value() const { return true; }"
|
||||
print " virtual bool returns_value() const {\n return true;\n }"
|
||||
print
|
||||
print " void Run() {"
|
||||
if ret:
|
||||
@ -97,9 +120,9 @@ def generate_class_template(args, ret = False, member = True):
|
||||
else:
|
||||
print " ",
|
||||
if member:
|
||||
print "((*o_).*m_)(" + gen_args_(args) + ");"
|
||||
print "((*o_).*m_) (" + gen_args_(args) + ");"
|
||||
else:
|
||||
print "m_(" + gen_args_(args) + ");"
|
||||
print "m_ (" + gen_args_(args) + ");"
|
||||
print " }"
|
||||
print
|
||||
print " private:"
|
||||
@ -125,11 +148,19 @@ def generate_function_template(args, member):
|
||||
|
||||
print "// %d arguments --"%args
|
||||
print "template<" + gen_typenames(args, member) + ">"
|
||||
print "gmp_args_%s_%d<"%(nm, args) + gen_types(args, member) + ">* WrapTask%s("%NM + gen_args_type(args, member) + ") {"
|
||||
print "gmp_args_%s_%d<"%(nm, args) + gen_types(args, member) + ">* WrapTask%s ("%NM + gen_args_type(args, member) + ") {"
|
||||
print " return new gmp_args_%s_%d<"%(nm, args) + gen_types(args, member) + ">"
|
||||
print " (" + gen_args(args, member) + ");"
|
||||
print "}"
|
||||
print
|
||||
if member:
|
||||
print "template<" + gen_typenames(args, member) + ">"
|
||||
print "GMPTask*"
|
||||
print "WrapTaskRefCounted%s ("%NM + gen_args_type(args, member) + ") {"
|
||||
print " GMPTask *t = WrapTask%s ("%NM + gen_args(args, member) + ");"
|
||||
print " return new RefCountTaskWrapper(t, o);"
|
||||
print "}"
|
||||
print
|
||||
|
||||
def generate_function_template_ret(args, member):
|
||||
if member:
|
||||
@ -140,15 +171,20 @@ def generate_function_template_ret(args, member):
|
||||
NM = "NM";
|
||||
print "// %d arguments --"%args
|
||||
print "template<" + gen_typenames(args, member) + ", typename R>"
|
||||
print "gmp_args_%s_%d_ret<"%(nm, args) + gen_types(args, member) + ", R>* WrapTask%sRet("%NM + gen_args_type(args, member) + ", R* r) {"
|
||||
print "gmp_args_%s_%d_ret<"%(nm, args) + gen_types(args, member) + ", R>* WrapTask%sRet ("%NM + gen_args_type(args, member) + ", R* r) {"
|
||||
print " return new gmp_args_%s_%d_ret<"%(nm, args) + gen_types(args, member) + ", R>"
|
||||
print " (" + gen_args(args, member) + ", r);"
|
||||
print "}"
|
||||
print
|
||||
|
||||
|
||||
|
||||
print boilerplate
|
||||
print
|
||||
print includes
|
||||
print
|
||||
print refcountclass
|
||||
print
|
||||
|
||||
for num_args in range (0, MAX_ARGS):
|
||||
generate_class_template(num_args, False, False)
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user