Commit 4293db3d authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen
Browse files

ClipWorkflow: Reworked thread safety.

This removes 3 useless mutex, and avoid a race condition.
parent 94e7d1ed
...@@ -81,7 +81,6 @@ void* ...@@ -81,7 +81,6 @@ void*
AudioClipWorkflow::getOutput( ClipWorkflow::GetMode mode ) AudioClipWorkflow::getOutput( ClipWorkflow::GetMode mode )
{ {
QMutexLocker lock( m_renderLock ); QMutexLocker lock( m_renderLock );
QMutexLocker lock2( m_computedBuffersMutex );
if ( preGetOutput() == false ) if ( preGetOutput() == false )
return NULL; return NULL;
...@@ -138,9 +137,7 @@ AudioClipWorkflow::createBuffer( size_t size ) ...@@ -138,9 +137,7 @@ AudioClipWorkflow::createBuffer( size_t size )
void void
AudioClipWorkflow::lock( AudioClipWorkflow *cw, quint8 **pcm_buffer , quint32 size ) AudioClipWorkflow::lock( AudioClipWorkflow *cw, quint8 **pcm_buffer , quint32 size )
{ {
QMutexLocker lock( cw->m_availableBuffersMutex );
cw->m_renderLock->lock(); cw->m_renderLock->lock();
cw->m_computedBuffersMutex->lock();
AudioSample *as = NULL; AudioSample *as = NULL;
if ( cw->m_availableBuffers.isEmpty() == true ) if ( cw->m_availableBuffers.isEmpty() == true )
...@@ -192,7 +189,6 @@ AudioClipWorkflow::unlock( AudioClipWorkflow *cw, quint8 *pcm_buffer, ...@@ -192,7 +189,6 @@ AudioClipWorkflow::unlock( AudioClipWorkflow *cw, quint8 *pcm_buffer,
} }
cw->commonUnlock(); cw->commonUnlock();
cw->m_renderLock->unlock(); cw->m_renderLock->unlock();
cw->m_computedBuffersMutex->unlock();
} }
void void
...@@ -229,15 +225,14 @@ AudioClipWorkflow::getMaxComputedBuffers() const ...@@ -229,15 +225,14 @@ AudioClipWorkflow::getMaxComputedBuffers() const
void void
AudioClipWorkflow::releaseBuffer( AudioSample *sample ) AudioClipWorkflow::releaseBuffer( AudioSample *sample )
{ {
QMutexLocker lock( m_availableBuffersMutex ); QMutexLocker lock( m_renderLock );
m_availableBuffers.enqueue( sample ); m_availableBuffers.enqueue( sample );
} }
void void
AudioClipWorkflow::flushComputedBuffers() AudioClipWorkflow::flushComputedBuffers()
{ {
QMutexLocker lock( m_availableBuffersMutex ); QMutexLocker lock( m_renderLock );
QMutexLocker lock2( m_computedBuffersMutex );
while ( m_computedBuffers.isEmpty() == false ) while ( m_computedBuffers.isEmpty() == false )
{ {
......
...@@ -43,16 +43,12 @@ ClipWorkflow::ClipWorkflow( Clip::Clip* clip ) : ...@@ -43,16 +43,12 @@ ClipWorkflow::ClipWorkflow( Clip::Clip* clip ) :
m_initWaitCond = new WaitCondition; m_initWaitCond = new WaitCondition;
m_pausingStateWaitCond = new WaitCondition; m_pausingStateWaitCond = new WaitCondition;
m_renderLock = new QMutex; m_renderLock = new QMutex;
m_availableBuffersMutex = new QMutex; m_renderWaitCond = new QWaitCondition;
m_computedBuffersMutex = new QMutex;
m_renderWaitCond = new WaitCondition;
} }
ClipWorkflow::~ClipWorkflow() ClipWorkflow::~ClipWorkflow()
{ {
delete m_renderWaitCond; delete m_renderWaitCond;
delete m_computedBuffersMutex;
delete m_availableBuffersMutex;
delete m_renderLock; delete m_renderLock;
delete m_pausingStateWaitCond; delete m_pausingStateWaitCond;
delete m_initWaitCond; delete m_initWaitCond;
......
...@@ -27,8 +27,9 @@ ...@@ -27,8 +27,9 @@
#include <QObject> #include <QObject>
class QReadWriteLock;
class QMutex; class QMutex;
class QReadWriteLock;
class QWaitCondition;
class Clip; class Clip;
class WaitCondition; class WaitCondition;
...@@ -241,12 +242,10 @@ class ClipWorkflow : public QObject ...@@ -241,12 +242,10 @@ class ClipWorkflow : public QObject
* the clipworkflow hasn't generate a frame yet, * the clipworkflow hasn't generate a frame yet,
* while the renderer asks for one. * while the renderer asks for one.
*/ */
QMutex* m_computedBuffersMutex; QWaitCondition *m_renderWaitCond;
QMutex* m_availableBuffersMutex;
qint64 m_beginPausePts; qint64 m_beginPausePts;
qint64 m_pauseDuration; qint64 m_pauseDuration;
bool m_fullSpeedRender; bool m_fullSpeedRender;
WaitCondition *m_renderWaitCond;
private slots: private slots:
void loadingComplete(); void loadingComplete();
......
...@@ -111,25 +111,11 @@ void* ...@@ -111,25 +111,11 @@ void*
VideoClipWorkflow::getOutput( ClipWorkflow::GetMode mode ) VideoClipWorkflow::getOutput( ClipWorkflow::GetMode mode )
{ {
QMutexLocker lock( m_renderLock ); QMutexLocker lock( m_renderLock );
QMutexLocker lock2( m_computedBuffersMutex );
if ( isEndReached() == true ) if ( isEndReached() == true )
return NULL; return NULL;
if ( preGetOutput() == false ) if ( preGetOutput() == false )
{ m_renderWaitCond->wait( m_renderLock );
QMutexLocker waitLock( m_renderWaitCond->getMutex() );
m_computedBuffersMutex->unlock();
m_renderLock->unlock();
m_renderWaitCond->waitLocked();
m_renderLock->lock();
m_computedBuffersMutex->lock();
}
//FIXME
//TODO: This is a nasty work arround. The race condition needs to be fixed !
if ( m_computedBuffers.isEmpty() == true )
return NULL;
::StackedBuffer<LightVideoFrame*>* buff; ::StackedBuffer<LightVideoFrame*>* buff;
if ( mode == ClipWorkflow::Pop ) if ( mode == ClipWorkflow::Pop )
buff = new StackedBuffer( m_computedBuffers.dequeue(), this, true ); buff = new StackedBuffer( m_computedBuffers.dequeue(), this, true );
...@@ -143,11 +129,9 @@ void ...@@ -143,11 +129,9 @@ void
VideoClipWorkflow::lock( VideoClipWorkflow *cw, void **pp_ret, int size ) VideoClipWorkflow::lock( VideoClipWorkflow *cw, void **pp_ret, int size )
{ {
Q_UNUSED( size ); Q_UNUSED( size );
QMutexLocker lock( cw->m_availableBuffersMutex );
LightVideoFrame* lvf = NULL; LightVideoFrame* lvf = NULL;
cw->m_renderLock->lock(); cw->m_renderLock->lock();
cw->m_computedBuffersMutex->lock();
if ( cw->m_availableBuffers.isEmpty() == true ) if ( cw->m_availableBuffers.isEmpty() == true )
{ {
lvf = new LightVideoFrame( cw->m_width, cw->m_height ); lvf = new LightVideoFrame( cw->m_width, cw->m_height );
...@@ -172,10 +156,8 @@ VideoClipWorkflow::unlock( VideoClipWorkflow *cw, void *buffer, int width, ...@@ -172,10 +156,8 @@ VideoClipWorkflow::unlock( VideoClipWorkflow *cw, void *buffer, int width,
LightVideoFrame *lvf = cw->m_computedBuffers.last(); LightVideoFrame *lvf = cw->m_computedBuffers.last();
(*(lvf))->ptsDiff = cw->m_currentPts - cw->m_previousPts; (*(lvf))->ptsDiff = cw->m_currentPts - cw->m_previousPts;
cw->commonUnlock(); cw->commonUnlock();
cw->m_renderWaitCond->wakeAll();
cw->m_renderLock->unlock(); cw->m_renderLock->unlock();
cw->m_computedBuffersMutex->unlock();
QMutexLocker lock( cw->m_renderWaitCond->getMutex() );
cw->m_renderWaitCond->wake();
} }
uint32_t uint32_t
...@@ -193,15 +175,15 @@ VideoClipWorkflow::getMaxComputedBuffers() const ...@@ -193,15 +175,15 @@ VideoClipWorkflow::getMaxComputedBuffers() const
void void
VideoClipWorkflow::releaseBuffer( LightVideoFrame *lvf ) VideoClipWorkflow::releaseBuffer( LightVideoFrame *lvf )
{ {
QMutexLocker lock( m_availableBuffersMutex ); QMutexLocker lock( m_renderLock );
m_availableBuffers.enqueue( lvf ); m_availableBuffers.enqueue( lvf );
} }
void void
VideoClipWorkflow::flushComputedBuffers() VideoClipWorkflow::flushComputedBuffers()
{ {
QMutexLocker lock( m_computedBuffersMutex ); QMutexLocker lock( m_renderLock );
QMutexLocker lock2( m_availableBuffersMutex );
while ( m_computedBuffers.isEmpty() == false ) while ( m_computedBuffers.isEmpty() == false )
m_availableBuffers.enqueue( m_computedBuffers.dequeue() ); m_availableBuffers.enqueue( m_computedBuffers.dequeue() );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment