Commit 116529cc authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen

Added a synchrone mode for rendering

parent b909f520
......@@ -116,9 +116,10 @@ void ClipWorkflow::unlock( ClipWorkflow* cw )
cw->m_stateLock->unlock();
//Signal that render has been completed.
cw->m_renderWaitCond->wake();
qDebug() << "Render completed";
cw->emit renderComplete( cw );
// qDebug() << "Entering condwait";
qDebug() << "Entering condwait";
cw->m_waitCond->wait( cw->m_condMutex );
// qDebug() << "Leaved condwait";
cw->m_stateLock->lockForWrite();
......
......@@ -46,15 +46,23 @@ MainWorkflow::MainWorkflow( int trackCount ) :
m_tracks[i].setPtr( new TrackWorkflow( i ) );
connect( m_tracks[i], SIGNAL( trackEndReached( unsigned int ) ), this, SLOT( trackEndReached(unsigned int) ) );
connect( m_tracks[i], SIGNAL( trackPaused() ), this, SLOT( trackPaused() ) );
connect( m_tracks[i], SIGNAL( renderCompleted( unsigned int ) ), this, SLOT( tracksRenderCompleted( unsigned int ) ), Qt::DirectConnection );
}
m_renderStartedLock = new QReadWriteLock;
m_renderMutex = new QMutex;
m_highestTrackNumberMutex = new QMutex;
m_synchroneRenderWaitCondition = new QWaitCondition;
m_synchroneRenderWaitConditionMutex = new QMutex;
}
MainWorkflow::~MainWorkflow()
{
stop();
delete m_synchroneRenderWaitConditionMutex;
delete m_synchroneRenderWaitCondition;
delete m_highestTrackNumberMutex;
delete m_renderMutex;
delete m_renderStartedLock;
for (unsigned int i = 0; i < m_trackCount; ++i)
delete m_tracks[i];
......@@ -102,6 +110,12 @@ unsigned char* MainWorkflow::getOutput()
QReadLocker lock( m_renderStartedLock );
QMutexLocker lock2( m_renderMutex );
{
QMutexLocker lockHighestTrackNumber( m_highestTrackNumberMutex );
m_highestTrackNumber = 0;
}
m_nbTracksToRender = 0;
m_synchroneRenderingBuffer = NULL;
if ( m_renderStarted == true )
{
unsigned char* ret;
......@@ -110,12 +124,15 @@ unsigned char* MainWorkflow::getOutput()
{
if ( m_tracks[i].activated() == false )
continue ;
if ( ( ret = m_tracks[i]->getOutput( m_currentFrame ) ) != NULL )
{
m_nbTracksToRender.fetchAndAddAcquire( 1 );
break ;
}
}
if ( ret == NULL )
ret = MainWorkflow::blackOutput;
nextFrame();
return ret;
}
......@@ -261,3 +278,44 @@ void MainWorkflow::trackPaused()
emit mainWorkflowPaused();
}
}
void MainWorkflow::tracksRenderCompleted( unsigned int trackId )
{
m_nbTracksToRender.fetchAndAddAcquire( -1 );
{
QMutexLocker lock( m_highestTrackNumberMutex );
if ( m_highestTrackNumber <= trackId )
{
m_highestTrackNumber = trackId;
m_synchroneRenderingBuffer = m_tracks[trackId]->getSynchroneOutput();
}
}
//We check for minus or equal, since we can have 0 frame to compute,
//therefore, m_nbTracksToRender will be equal to -1
if ( m_nbTracksToRender <= 0 )
{
qDebug() << "MainWorkflow render completed";
//Just a synchronisation barriere
{
QMutexLocker lock( m_synchroneRenderWaitConditionMutex );
}
m_synchroneRenderWaitCondition->wakeAll();
}
else
qDebug() << m_nbTracksToRender << "tracks left to render";
}
unsigned char* MainWorkflow::getSynchroneOutput()
{
m_synchroneRenderWaitConditionMutex->lock();
getOutput();
qDebug() << "Waiting for synchrone output";
m_synchroneRenderWaitCondition->wait( m_synchroneRenderWaitConditionMutex );
qDebug() << "Got it";
m_synchroneRenderWaitConditionMutex->unlock();
qDebug() << (void*)m_synchroneRenderingBuffer;
if ( m_synchroneRenderingBuffer == NULL )
return MainWorkflow::blackOutput;
return m_synchroneRenderingBuffer;
}
......@@ -43,6 +43,7 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
void addClip( Clip* clip, unsigned int trackId, qint64 start );
void startRender();
unsigned char* getOutput();
unsigned char* getSynchroneOutput();
/**
* \brief Set the workflow position
......@@ -99,6 +100,12 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
QMutex* m_renderMutex;
QAtomicInt m_nbTracksToPause;
QAtomicInt m_nbTracksToRender;
QMutex* m_highestTrackNumberMutex;
unsigned int m_highestTrackNumber;
unsigned char* m_synchroneRenderingBuffer;
QWaitCondition* m_synchroneRenderWaitCondition;
QMutex* m_synchroneRenderWaitConditionMutex;
public slots:
void clipMoved( QUuid, int, int, qint64 );
......@@ -106,6 +113,7 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
private slots:
void trackEndReached( unsigned int trackId );
void trackPaused();
void tracksRenderCompleted( unsigned int trackId );
signals:
/**
......
......@@ -29,7 +29,8 @@ TrackWorkflow::TrackWorkflow( unsigned int trackId ) :
m_trackId( trackId ),
m_length( 0 ),
m_forceRepositionning( false ),
m_paused( false )
m_paused( false ),
m_synchroneRenderBuffer( NULL )
{
m_forceRepositionningMutex = new QMutex;
m_clipsLock = new QReadWriteLock;
......@@ -101,6 +102,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF
}
if ( cw->getState() == ClipWorkflow::Rendering )
{
qDebug() << "Rendering a 'Rendering' ClipWorkflow";
//The rendering state meens... whell it means that the frame is
//beeing rendered, so we wait.
cw->getStateLock()->unlock();
......@@ -114,7 +116,9 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF
//If frame has been rendered :
if ( cw->getState() == ClipWorkflow::Sleeping || pauseAfterRender == true )
{
qDebug() << "renderign a sleeping clip worjkflow";
cw->getStateLock()->unlock();
if ( needRepositioning == true )
{
float pos = ( (float)( currentFrame - start ) / (float)(cw->getClip()->getLength()) );
......@@ -127,6 +131,9 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF
// qDebug() << "Querying state back to pause after render";
cw->queryStateChange( ClipWorkflow::Paused );
}
{
QMutexLocker lock( cw->getSleepMutex() );
}
cw->wake();
}
else if ( cw->getState() == ClipWorkflow::Stopped )
......@@ -260,6 +267,7 @@ void TrackWorkflow::stop()
unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
{
qDebug() << "Getting track output";
QReadLocker lock( m_clipsLock );
unsigned char* ret = NULL;
......@@ -468,15 +476,16 @@ void TrackWorkflow::clipWorkflowPaused()
void TrackWorkflow::clipWorkflowRenderCompleted( ClipWorkflow* cw )
{
m_lastFrame = cw->getOutput();
m_synchroneRenderBuffer = cw->getOutput();
m_nbClipToRender.fetchAndAddAcquire( -1 );
if ( m_nbClipToRender == 0 )
{
qDebug() << "TrackWorkflow render is completed";
emit renderCompleted();
}
else
{
qDebug() << "Clip workflow render complete." << m_nbClipToRender << "clips remaining.";
qDebug() << "TrackWorkflow render is completed. Buffer =" << (void*)m_synchroneRenderBuffer;
emit renderCompleted( m_trackId );
}
}
unsigned char* TrackWorkflow::getSynchroneOutput()
{
return m_synchroneRenderBuffer;
}
......@@ -58,6 +58,10 @@ class TrackWorkflow : public QObject
void addClip( Clip*, qint64 start );
void addClip( ClipWorkflow*, qint64 start );
void activateOneFrameOnly();
/**
* Returns the output that has been computed in synchrone mode.
*/
unsigned char* getSynchroneOutput();
//FIXME: this won't be reliable as soon as we change the fps from the configuration
static const unsigned int nbFrameBeforePreload = 60;
......@@ -97,7 +101,7 @@ class TrackWorkflow : public QObject
QAtomicInt m_nbClipToPause;
QAtomicInt m_nbClipToRender;
unsigned char* m_lastFrame;
unsigned char* m_synchroneRenderBuffer;
private slots:
void clipWorkflowPaused();
......@@ -106,7 +110,7 @@ class TrackWorkflow : public QObject
signals:
void trackEndReached( unsigned int );
void trackPaused();
void renderCompleted();
void renderCompleted( unsigned int );
};
#endif // TRACKWORKFLOW_H
......@@ -95,7 +95,7 @@ void* WorkflowRenderer::lock( void* datas )
}
if ( self->m_oneFrameOnly < 2 )
{
void* ret = self->m_mainWorkflow->getOutput();
void* ret = self->m_mainWorkflow->getSynchroneOutput();
self->m_lastFrame = static_cast<unsigned char*>( ret );
qDebug() << "Returning new frame";
return ret;
......
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