Permalink
Browse files

Make libmythfreesurround thread-safe and allowing more than one insta…

…nce of it...

Was way too complicated for its own good. so what if we need to reallocate memory during creation.. Happens only very occasionally.
  • Loading branch information...
jyavenard committed Jul 12, 2013
1 parent ad5cad6 commit 9b79f1036db95fb2486f42df435292d0160251bf
Showing with 6 additions and 86 deletions.
  1. +6 −86 mythtv/libs/libmythfreesurround/freesurround.cpp
@@ -47,63 +47,6 @@ static const float m7db = 0.44721359549996; // 7dB = SQRT(5)
unsigned int block_size = default_block_size;
// stupidity countermeasure...
template<class T> T pop_back(std::list<T> &l)
{
T result(l.back());
l.pop_back();
return result;
}
// a pool, where the DSP can throw its objects at after it got deleted and
// get them back when it is recreated...
class object_pool
{
public:
typedef void* (*callback)();
typedef void* (*dcallback)(void*);
// initialize
object_pool(callback cbf, dcallback dbf):construct(cbf), destruct(dbf) { }
~object_pool()
{
for (std::map<void*,void*>::iterator i=pool.begin(),e=pool.end();
i != e; i++)
destruct(i->second);
for (std::list<void*>::iterator i=freelist.begin(),e=freelist.end();
i != e; i++)
destruct(*i);
}
// (re)acquire an object
void *acquire(void *who)
{
std::map<void*,void*>::iterator i(pool.find(who));
if (i != pool.end())
return i->second;
else
if (!freelist.empty())
return pool.insert(std::make_pair(who,pop_back(freelist)))
.first->second;
else
return pool.insert(std::make_pair(who,construct()))
.first->second;
}
// release an object into the wild
void release(void *who)
{
std::map<void*,void*>::iterator i(pool.find(who));
if (i != pool.end()) {
freelist.push_back(i->second);
pool.erase(i);
}
}
public:
callback construct; // object constructor callback
dcallback destruct; // object destructor callback
std::list<void*> freelist; // list of available objects
std::map<void*,void*> pool; // pool of used objects, by class
};
// buffers which we usually need (and want to share between plugin lifespans)
struct buffers
{
buffers(unsigned int s):
@@ -124,23 +67,6 @@ struct buffers
rls, rrs; // for demultiplexing
};
// construction methods
void *new_decoder() { return new fsurround_decoder(block_size); }
void *new_buffers() { return new buffers(block_size/2); }
void *delete_decoder(void *_p)
{
fsurround_decoder *p = static_cast<fsurround_decoder*>(_p);
delete p;
}
void *delete_buffers(void *_p)
{
buffers *p = static_cast<buffers*>(_p);
delete p;
}
object_pool dp(&new_decoder, &delete_decoder);
object_pool bp(&new_buffers, &delete_buffers);
//#define SPEAKERTEST
#ifdef SPEAKERTEST
int channel_select = -1;
@@ -186,7 +112,7 @@ FreeSurround::FreeSurround(uint srate, bool moviemode, SurroundMode smode) :
break;
}
bufs = (buffers*)bp.acquire((void*)1);
bufs = new buffers(block_size/2);
open();
#ifdef SPEAKERTEST
channel_select++;
@@ -226,11 +152,8 @@ FreeSurround::~FreeSurround()
{
LOG(VB_AUDIO, LOG_DEBUG, QString("FreeSurround::~FreeSurround"));
close();
if (bufs)
{
bp.release((void*)1);
bufs = NULL;
}
delete bufs;
bufs = NULL;
LOG(VB_AUDIO, LOG_DEBUG, QString("FreeSurround::~FreeSurround done"));
}
@@ -519,7 +442,7 @@ void FreeSurround::open()
{
if (!decoder)
{
decoder = (fsurround_decoder*)dp.acquire((void*)1);
decoder = new fsurround_decoder(block_size);
decoder->flush();
if (bufs)
bufs->clear();
@@ -530,11 +453,8 @@ void FreeSurround::open()
void FreeSurround::close()
{
if (decoder)
{
dp.release((void*)1);
decoder = 0;
}
delete decoder;
decoder = NULL;
}
uint FreeSurround::numUnprocessedFrames()

0 comments on commit 9b79f10

Please sign in to comment.