Skip to content

Commit

Permalink
Make libmythfreesurround thread-safe and allowing more than one insta…
Browse files Browse the repository at this point in the history
…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 9b79f10
Showing 1 changed file with 6 additions and 86 deletions.
92 changes: 6 additions & 86 deletions mythtv/libs/libmythfreesurround/freesurround.cpp
Expand Up @@ -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):
Expand All @@ -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;
Expand Down Expand Up @@ -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++;
Expand Down Expand Up @@ -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"));
}

Expand Down Expand Up @@ -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();
Expand All @@ -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()
Expand Down

0 comments on commit 9b79f10

Please sign in to comment.