Commit a9c842be authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen

Frame by frame mode is working :)

However, due tu the nature of clipworkflow control, a lot of frames are
lost...
parent 9e84b9a8
...@@ -75,7 +75,7 @@ void ClipWorkflow::checkStateChange() ...@@ -75,7 +75,7 @@ void ClipWorkflow::checkStateChange()
QWriteLocker lock2( m_stateLock ); QWriteLocker lock2( m_stateLock );
if ( m_requiredState != ClipWorkflow::None ) if ( m_requiredState != ClipWorkflow::None )
{ {
// qDebug() << "Changed state from" << m_state << "to state" << m_requiredState; qDebug() << "Changed state from" << m_state << "to state" << m_requiredState;
m_state = m_requiredState; m_state = m_requiredState;
m_requiredState = ClipWorkflow::None; m_requiredState = ClipWorkflow::None;
checkSynchronisation( m_state ); checkSynchronisation( m_state );
...@@ -122,9 +122,9 @@ void ClipWorkflow::unlock( ClipWorkflow* cw ) ...@@ -122,9 +122,9 @@ void ClipWorkflow::unlock( ClipWorkflow* cw )
// qDebug() << "Clip render completed"; // qDebug() << "Clip render completed";
cw->emit renderComplete( cw ); cw->emit renderComplete( cw );
// qDebug() << "Entering condwait"; qDebug() << "\t\tEntering condwait";
cw->m_waitCond->wait( cw->m_condMutex ); cw->m_waitCond->wait( cw->m_condMutex );
// qDebug() << "Leaved condwait"; qDebug() << "\t\tLeaved condwait";
cw->m_stateLock->lockForWrite(); cw->m_stateLock->lockForWrite();
cw->m_state = Rendering; cw->m_state = Rendering;
// { // {
...@@ -138,11 +138,11 @@ void ClipWorkflow::unlock( ClipWorkflow* cw ) ...@@ -138,11 +138,11 @@ void ClipWorkflow::unlock( ClipWorkflow* cw )
QMutexLocker lock( cw->m_condMutex ); QMutexLocker lock( cw->m_condMutex );
cw->m_stateLock->unlock(); cw->m_stateLock->unlock();
// qDebug() << "Entering forced pause condwait"; qDebug() << "Entering forced pause condwait";
cw->setState( ClipWorkflow::ThreadPaused ); cw->setState( ClipWorkflow::ThreadPaused );
cw->m_pausedThreadCondWait->wake(); cw->m_pausedThreadCondWait->wake();
cw->m_waitCond->wait( cw->m_condMutex ); cw->m_waitCond->wait( cw->m_condMutex );
// qDebug() << "Leaving forced pause condwait"; qDebug() << "Leaving forced pause condwait";
cw->setState( ClipWorkflow::Paused ); cw->setState( ClipWorkflow::Paused );
} }
else else
...@@ -309,6 +309,7 @@ void ClipWorkflow::setState( State state ) ...@@ -309,6 +309,7 @@ void ClipWorkflow::setState( State state )
{ {
{ {
QWriteLocker lock( m_stateLock ); QWriteLocker lock( m_stateLock );
qDebug() << "Changing from state" << m_state << "to state" << state;
m_state = state; m_state = state;
} }
checkSynchronisation( state ); checkSynchronisation( state );
......
...@@ -153,6 +153,7 @@ void MainWorkflow::pause() ...@@ -153,6 +153,7 @@ void MainWorkflow::pause()
m_tracks[i]->pause(); m_tracks[i]->pause();
} }
} }
qDebug() << "All tracks are paused";
} }
void MainWorkflow::nextFrame() void MainWorkflow::nextFrame()
...@@ -275,10 +276,11 @@ void MainWorkflow::activateOneFrameOnly() ...@@ -275,10 +276,11 @@ void MainWorkflow::activateOneFrameOnly()
void MainWorkflow::trackPaused() void MainWorkflow::trackPaused()
{ {
qDebug() << "Track pausing finished...";
m_nbTracksToPause.fetchAndAddAcquire( -1 ); m_nbTracksToPause.fetchAndAddAcquire( -1 );
if ( m_nbTracksToPause <= 0 ) if ( m_nbTracksToPause <= 0 )
{ {
// qDebug() << "MainWorkflow is paused"; qDebug() << "\t\t...MainWorkflow is paused";
emit mainWorkflowPaused(); emit mainWorkflowPaused();
} }
} }
......
...@@ -314,6 +314,8 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame ) ...@@ -314,6 +314,8 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
needRepositioning = ( abs( currentFrame - lastFrame ) > 1 ) ? true : false; needRepositioning = ( abs( currentFrame - lastFrame ) > 1 ) ? true : false;
} }
m_nbClipToRender = 0; m_nbClipToRender = 0;
//If we ask for an output, then the track should'nt be paused anymore.
m_paused = false;
while ( it != end ) while ( it != end )
{ {
qint64 start = it.key(); qint64 start = it.key();
...@@ -324,10 +326,10 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame ) ...@@ -324,10 +326,10 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
{ {
m_nbClipToRender.fetchAndAddAcquire( 1 ); m_nbClipToRender.fetchAndAddAcquire( 1 );
ret = renderClip( cw, currentFrame, start, needRepositioning, oneFrameOnlyFlag ); ret = renderClip( cw, currentFrame, start, needRepositioning, oneFrameOnlyFlag );
if ( oneFrameOnlyFlag == true ) // if ( oneFrameOnlyFlag == true )
{ // {
cw->pause(); // cw->pause();
} // }
lastFrame = currentFrame; lastFrame = currentFrame;
} }
//Is it about to be rendered ? //Is it about to be rendered ?
...@@ -362,12 +364,16 @@ void TrackWorkflow::pauseClipWorkflow( ClipWorkflow* cw ) ...@@ -362,12 +364,16 @@ void TrackWorkflow::pauseClipWorkflow( ClipWorkflow* cw )
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
return ; return ;
} }
if ( cw->getState() != ClipWorkflow::Paused )
{
if ( cw->getState() == ClipWorkflow::Sleeping || if ( cw->getState() == ClipWorkflow::Sleeping ||
cw->getState() == ClipWorkflow::Ready || cw->getState() == ClipWorkflow::Ready ||
cw->getState() == ClipWorkflow::EndReached ) cw->getState() == ClipWorkflow::EndReached )
{ {
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
//Locking this mutex ensure that the thread is really asleep, and hasn't
//just changed the state, and then get pulled back by the scheduler...
QMutexLocker lock( cw->getSleepMutex() ); QMutexLocker lock( cw->getSleepMutex() );
cw->queryStateChange( ClipWorkflow::Pausing ); cw->queryStateChange( ClipWorkflow::Pausing );
cw->wake(); cw->wake();
...@@ -375,7 +381,9 @@ void TrackWorkflow::pauseClipWorkflow( ClipWorkflow* cw ) ...@@ -375,7 +381,9 @@ void TrackWorkflow::pauseClipWorkflow( ClipWorkflow* cw )
else if ( cw->getState() == ClipWorkflow::Rendering ) else if ( cw->getState() == ClipWorkflow::Rendering )
{ {
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
qDebug() << "Waiting for complete render";
cw->waitForCompleteRender(); cw->waitForCompleteRender();
qDebug() << "Render has been completed... continue pausing";
QMutexLocker lock( cw->getSleepMutex() ); QMutexLocker lock( cw->getSleepMutex() );
cw->queryStateChange( ClipWorkflow::Pausing ); cw->queryStateChange( ClipWorkflow::Pausing );
cw->wake(); cw->wake();
...@@ -388,14 +396,17 @@ void TrackWorkflow::pauseClipWorkflow( ClipWorkflow* cw ) ...@@ -388,14 +396,17 @@ void TrackWorkflow::pauseClipWorkflow( ClipWorkflow* cw )
} }
else else
{ {
// qDebug() << "Unexpected ClipWorkflow::State when pausing:" << cw->getState(); // qDebug() << "Unexpected ClipWorkflow::State when pausing:" << cw->getState();
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
} }
cw->waitForPausingState(); cw->waitForPausingState();
cw->pause(); cw->pause();
// qDebug() << "Wait for pausedthread state"; }
else
cw->getStateLock()->unlock();
qDebug() << "Wait for pausedthread state";
cw->waitForPausedThread(); cw->waitForPausedThread();
// qDebug() << "Ok thread is paused"; qDebug() << "Ok thread is paused";
} }
void TrackWorkflow::pause() void TrackWorkflow::pause()
...@@ -412,27 +423,30 @@ void TrackWorkflow::pause() ...@@ -412,27 +423,30 @@ void TrackWorkflow::pause()
ClipWorkflow* cw = it.value(); ClipWorkflow* cw = it.value();
cw->getStateLock()->lockForRead(); cw->getStateLock()->lockForRead();
qDebug() << "Pausing a clip in state" << cw->getState();
if ( cw->getState() == ClipWorkflow::Stopped ) if ( cw->getState() == ClipWorkflow::Stopped )
{ {
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
continue ; continue ;
} }
if ( cw->getState() != ClipWorkflow::Paused ) else if ( cw->getState() != ClipWorkflow::ThreadPaused )
{ {
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
m_nbClipToPause.fetchAndAddAcquire( 1 ); m_nbClipToPause.fetchAndAddAcquire( 1 );
connect( cw->getMediaPlayer(), SIGNAL( paused() ), this, SLOT( clipWorkflowPaused() ) ); // connect( cw->getMediaPlayer(), SIGNAL( paused() ), this, SLOT( clipWorkflowPaused() ) );
pauseClipWorkflow( cw ); pauseClipWorkflow( cw );
} }
else else
{ {
//This should never be used. //This should never be used.
//TODO: remove this in a few revision (wrote on July 16 2009 ) qDebug() << "Asking to pause in an already paused state";
// qDebug() << "Asking to pause in an already paused state";
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
} }
} }
m_paused = !m_paused; m_paused = !m_paused;
qDebug() << "m_paused ==" << m_paused;
if ( m_paused == true )
emit trackPaused();
} }
void TrackWorkflow::moveClip( const QUuid& id, qint64 startingFrame ) void TrackWorkflow::moveClip( const QUuid& id, qint64 startingFrame )
...@@ -489,14 +503,14 @@ void TrackWorkflow::activateOneFrameOnly() ...@@ -489,14 +503,14 @@ void TrackWorkflow::activateOneFrameOnly()
m_oneFrameOnly = 1; m_oneFrameOnly = 1;
} }
void TrackWorkflow::clipWorkflowPaused() //void TrackWorkflow::clipWorkflowPaused()
{ //{
m_nbClipToPause.fetchAndAddAcquire( -1 ); // m_nbClipToPause.fetchAndAddAcquire( -1 );
if ( m_nbClipToPause == 0 ) // if ( m_nbClipToPause == 0 )
{ // {
emit trackPaused(); // emit trackPaused();
} // }
} //}
void TrackWorkflow::clipWorkflowRenderCompleted( ClipWorkflow* cw ) void TrackWorkflow::clipWorkflowRenderCompleted( ClipWorkflow* cw )
{ {
......
...@@ -52,6 +52,10 @@ class TrackWorkflow : public QObject ...@@ -52,6 +52,10 @@ class TrackWorkflow : public QObject
unsigned char* getOutput( qint64 currentFrame ); unsigned char* getOutput( qint64 currentFrame );
qint64 getLength() const; qint64 getLength() const;
void stop(); void stop();
/**
* Will pause all the track's ClipWorkflow.
* This method *is synchrone*, and will not return until all of the ClipWorkflow's thread are asleep
*/
void pause(); void pause();
void moveClip( const QUuid& id, qint64 startingFrame ); void moveClip( const QUuid& id, qint64 startingFrame );
Clip* removeClip( const QUuid& id ); Clip* removeClip( const QUuid& id );
...@@ -104,7 +108,7 @@ class TrackWorkflow : public QObject ...@@ -104,7 +108,7 @@ class TrackWorkflow : public QObject
unsigned char* m_synchroneRenderBuffer; unsigned char* m_synchroneRenderBuffer;
private slots: private slots:
void clipWorkflowPaused(); // void clipWorkflowPaused();
void clipWorkflowRenderCompleted( ClipWorkflow* ); void clipWorkflowRenderCompleted( ClipWorkflow* );
signals: signals:
......
...@@ -133,9 +133,9 @@ void WorkflowRenderer::unlock( void* datas ) ...@@ -133,9 +133,9 @@ void WorkflowRenderer::unlock( void* datas )
// qDebug() << "Workflowrenderer::unlock. m_oneFrameOnly ==" << self->m_oneFrameOnly; // qDebug() << "Workflowrenderer::unlock. m_oneFrameOnly ==" << self->m_oneFrameOnly;
if ( self->m_oneFrameOnly == 1 ) if ( self->m_oneFrameOnly == 1 )
{ {
// qDebug() << "Pausing back"; qDebug() << "Pausing back";
self->togglePlayPause( true ); self->togglePlayPause( true );
// qDebug() << "Switching m_oneFrameOnly flag to 2"; qDebug() << "Switching m_oneFrameOnly flag to 2";
self->m_oneFrameOnly = 2; self->m_oneFrameOnly = 2;
} }
self->m_framePlayed = true; self->m_framePlayed = true;
...@@ -214,6 +214,8 @@ void WorkflowRenderer::frameByFramePausingProxy() ...@@ -214,6 +214,8 @@ void WorkflowRenderer::frameByFramePausingProxy()
if ( nbPaused == 2 ) if ( nbPaused == 2 )
{ {
nbPaused = 0; nbPaused = 0;
disconnect( m_mediaPlayer, SIGNAL( paused() ), this, SLOT( frameByFramePausingProxy() ) );
disconnect( m_mainWorkflow, SIGNAL( mainWorkflowPaused() ), this, SLOT( frameByFramePausingProxy() ) );
frameByFrameAfterPaused(); frameByFrameAfterPaused();
} }
} }
...@@ -313,6 +315,7 @@ void WorkflowRenderer::__videoPaused() ...@@ -313,6 +315,7 @@ void WorkflowRenderer::__videoPaused()
{ {
m_oneFrameOnly = 0; m_oneFrameOnly = 0;
} }
qDebug() << "Pausing main workflow";
pauseMainWorkflow(); pauseMainWorkflow();
} }
......
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