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

Next frame is almost working (again...)

It just lacks RenderPreviewWidget to query only one frame at a time.
parent aea23cd3
......@@ -87,7 +87,7 @@ void ClipWorkflow::lock( ClipWorkflow* cw, void** pp_ret )
// else
// {
*pp_ret = cw->m_buffer;
// qDebug() << "Clip workflow locking";
qDebug() << "Clip workflow locking <<<<<<<<<<<<<<<<<<<<<<<<<<";
// }
}
......@@ -95,6 +95,15 @@ void ClipWorkflow::unlock( ClipWorkflow* cw )
{
cw->m_stateLock->lockForWrite();
// if ( cw->m_oneFrameOnly )
// {
// qDebug() << "One frame only mode is ON :)";
// //Forcing pause after rendering a frame
// cw->m_oneFrameOnly = 0;
// cw->m_state = Paused;
// }
// else
// qDebug() << "One frame only mode is OFF :(";
if ( cw->m_state == Rendering )
{
cw->m_state = Sleeping;
......@@ -111,8 +120,17 @@ void ClipWorkflow::unlock( ClipWorkflow* cw )
// QWriteLocker lock2( cw->m_backBufferLock );
// cw->m_usingBackBuffer = !cw->m_usingBackBuffer;
// }
cw->m_stateLock->unlock();
}
else if ( cw->m_state == Paused )
{
qDebug() << "Forcing pause by pausing thread";
cw->m_stateLock->unlock();
QMutexLocker lock( cw->m_condMutex );
cw->m_waitCond->wait( cw->m_condMutex );
}
cw->m_stateLock->unlock();
else
cw->m_stateLock->unlock();
cw->checkStateChange();
}
......@@ -272,17 +290,25 @@ void ClipWorkflow::reinitialize()
void ClipWorkflow::pause()
{
m_mediaPlayer->pause();
setState( Paused );
m_mediaPlayer->pause();
QMutexLocker lock( m_requiredStateLock );
m_requiredState = ClipWorkflow::None;
}
void ClipWorkflow::unpause()
void ClipWorkflow::unpause( bool wakeRenderThread /*= true*/ )
{
//Since VLC will detect that the media player is paused and unpause it, we can do this safely
m_mediaPlayer->pause();
setState( ClipWorkflow::Rendering );
QMutexLocker lock( m_requiredStateLock );
m_requiredState = ClipWorkflow::None;
m_mediaPlayer->pause();
// QMutexLocker lock( m_requiredStateLock );
// m_requiredState = ClipWorkflow::None;
if ( wakeRenderThread == true )
wake();
}
//void ClipWorkflow::activateOneFrameOnly()
//{
// qDebug() << "Activating one frame only";
// m_oneFrameOnly = 1;
//}
......@@ -145,7 +145,9 @@ class ClipWorkflow : public QObject
*/
void reinitialize();
void unpause();
void unpause( bool wakeRenderThread = true );
// void activateOneFrameOnly();
private:
static void lock( ClipWorkflow* clipWorkflow, void** pp_ret );
......@@ -188,6 +190,8 @@ class ClipWorkflow : public QObject
State m_requiredState;
QMutex* m_requiredStateLock;
QAtomicInt m_oneFrameOnly;
private slots:
void pauseAfterPlaybackStarted();
......
......@@ -218,3 +218,13 @@ void MainWorkflow::clipMoved( QUuid clipUuid, int oldTrack, int newTra
m_tracks[newTrack].activate();
}
}
void MainWorkflow::activateOneFrameOnly()
{
for (unsigned int i = 0; i < m_trackCount; ++i)
{
//FIXME: After debugging period, this should'nt be necessary --
if ( m_tracks[i].activated() == true )
m_tracks[i]->activateOneFrameOnly();
}
}
......@@ -73,6 +73,8 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
static unsigned char* blackOutput;
void nextFrame();
void previousFrame();
void activateOneFrameOnly();
static MainWorkflow* getInstance();
......
......@@ -80,16 +80,29 @@ qint64 TrackWorkflow::getLength() const
}
unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentFrame,
qint64 start , bool needRepositioning )
qint64 start , bool needRepositioning,
bool pauseAfterRender )
{
unsigned char* ret = NULL;
cw->getStateLock()->lockForRead();
qDebug() << "Rendering clip";
if ( cw->getState() == ClipWorkflow::Paused && pauseAfterRender == false )
{
cw->getStateLock()->unlock();
qDebug() << "Unpausing clip workflow";
//If we must pause after render, we must NOT wake the renderer thread, or it could render more than one frame
// (since this is for the next/previous frame)
//However, if this is just for a classic unpause, with just don't give a shit :)
cw->unpause( false );
cw->getStateLock()->lockForRead();
}
if ( cw->getState() == ClipWorkflow::Rendering )
{
//The rendering state meens... whell it means that the frame is
//beeing rendered, so we wait.
qDebug() << "State == rendering";
cw->getStateLock()->unlock();
while ( cw->isRendering() == true )
{
......@@ -102,7 +115,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF
}
//If frame has been rendered :
if ( cw->getState() == ClipWorkflow::Sleeping )
if ( cw->getState() == ClipWorkflow::Sleeping || pauseAfterRender == true )
{
cw->getStateLock()->unlock();
if ( needRepositioning == true )
......@@ -111,6 +124,12 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF
cw->setPosition( pos );
}
ret = cw->getOutput();
if ( pauseAfterRender == true )
{
cw->unpause( false );
qDebug() << "Querying state back to pause after render";
cw->queryStateChange( ClipWorkflow::Paused );
}
cw->wake();
//FIXME: sometimes, the renderer isn't awake soon enough, and we can
//pass though this function many times before the frame is actually rendered.
......@@ -194,9 +213,16 @@ void TrackWorkflow::stopClipWorkflow( ClipWorkflow* cw )
SleepMS( 1 );
cw->stop();
}
else if ( cw->getState() == ClipWorkflow::Paused )
{
cw->getStateLock()->unlock();
cw->queryStateChange( ClipWorkflow::Stopping );
cw->unpause();
cw->stop();
}
else
{
// qDebug() << "Unexpected ClipWorkflow::State when stopping :" << cw->getState();
qDebug() << "Unexpected ClipWorkflow::State when stopping :" << cw->getState();
cw->getStateLock()->unlock();
}
}
......@@ -232,7 +258,16 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
QMap<qint64, ClipWorkflow*>::iterator end = m_clips.end();
static qint64 lastFrame = 0;
bool needRepositioning;
bool oneFrameOnlyFlag = false;
qDebug() << "Checking flag...";
if ( m_oneFrameOnly == 1 )
{
qDebug() << "...Flag is activated";
oneFrameOnlyFlag = true;
}
else
qDebug() << "...Flag is OFF";
if ( checkEnd( currentFrame ) == true )
{
emit trackEndReached( m_trackId );
......@@ -256,7 +291,14 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
//Is the clip supposed to render now ?
if ( start <= currentFrame && currentFrame <= start + cw->getClip()->getLength() )
{
ret = renderClip( cw, currentFrame, start, needRepositioning );
// if ( oneFrameOnlyFlag == true )
// cw->activateOneFrameOnly();
ret = renderClip( cw, currentFrame, start, needRepositioning, oneFrameOnlyFlag );
if ( oneFrameOnlyFlag == true )
{
cw->pause();
qDebug() << "Pausing back clip workflow";
}
lastFrame = currentFrame;
}
//Is it about to be rendered ?
......@@ -273,6 +315,11 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
++it;
}
if ( oneFrameOnlyFlag == true )
{
qDebug() << "Switching off m_oneFrameOnly";
m_oneFrameOnly = 0;
}
return ret;
}
......@@ -304,7 +351,7 @@ void TrackWorkflow::pauseClipWorkflow( ClipWorkflow* cw )
}
else
{
// qDebug() << "Unexpected ClipWorkflow::State when pausing:" << cw->getState();
qDebug() << "Unexpected ClipWorkflow::State when pausing:" << cw->getState();
cw->getStateLock()->unlock();
}
bool pausing = false;
......@@ -325,18 +372,23 @@ void TrackWorkflow::pause()
QMap<qint64, ClipWorkflow*>::iterator it = m_clips.begin();
QMap<qint64, ClipWorkflow*>::iterator end = m_clips.end();
//FIXME: it's probably bad to iterate over every clip workflows.
while ( it != end )
{
qDebug() << "Iterating...";
ClipWorkflow* cw = it.value();
//TODO: try to do this with the State
if ( m_paused == false )
cw->getStateLock()->lockForRead();
if ( cw->getState() != ClipWorkflow::Paused )
{
qDebug() << "Pausing clip workflow";
cw->getStateLock()->unlock();
pauseClipWorkflow( cw );
}
else
{
cw->getStateLock()->lockForRead();
//This should never be used.
Q_ASSERT( false );
if ( cw->getState() == ClipWorkflow::Paused )
{
cw->getStateLock()->unlock();
......@@ -398,3 +450,10 @@ Clip* TrackWorkflow::removeClip( const QUuid& id )
}
return NULL;
}
void TrackWorkflow::activateOneFrameOnly()
{
qDebug() << "Activating flag";
m_oneFrameOnly = 1;
qDebug() << "Flag activated";
}
......@@ -57,6 +57,7 @@ class TrackWorkflow : public QObject
Clip* removeClip( const QUuid& id );
void addClip( Clip*, qint64 start );
void addClip( ClipWorkflow*, qint64 start );
void activateOneFrameOnly();
//FIXME: this won't be reliable as soon as we change the fps from the configuration
static const unsigned int nbFrameBeforePreload = 60;
......@@ -64,7 +65,8 @@ class TrackWorkflow : public QObject
private:
void computeLength();
unsigned char* renderClip( ClipWorkflow* cw, qint64 currentFrame,
qint64 start, bool needRepositioning );
qint64 start, bool needRepositioning,
bool pauseAfterRender );
void preloadClip( ClipWorkflow* cw );
void stopClipWorkflow( ClipWorkflow* cw );
void pauseClipWorkflow( ClipWorkflow* cw );
......@@ -90,6 +92,8 @@ class TrackWorkflow : public QObject
QReadWriteLock* m_clipsLock;
bool m_paused;
QAtomicInt m_oneFrameOnly;
signals:
void trackEndReached( unsigned int );
};
......
......@@ -29,10 +29,8 @@
RenderPreviewWidget::RenderPreviewWidget( MainWorkflow* mainWorkflow, QWidget* renderWidget ) :
GenericPreviewWidget( renderWidget ),
m_mainWorkflow( mainWorkflow ),
m_framePlayed( false )
m_mainWorkflow( mainWorkflow )
{
m_framePlayedLock = new QReadWriteLock;
m_media = new LibVLCpp::Media( "fake://" );
// --invmem-width <integer> Width
// --invmem-height <integer> Height
......@@ -82,6 +80,7 @@ RenderPreviewWidget::~RenderPreviewWidget()
void* RenderPreviewWidget::lock( void* datas )
{
qDebug() << "\nQuerying new picture";
RenderPreviewWidget* self = reinterpret_cast<RenderPreviewWidget*>( datas );
void* ret = self->m_mainWorkflow->getOutput();
return ret;
......@@ -90,9 +89,7 @@ void* RenderPreviewWidget::lock( void* datas )
void RenderPreviewWidget::unlock( void* datas )
{
RenderPreviewWidget* self = reinterpret_cast<RenderPreviewWidget*>( datas );
QWriteLocker lock( self->m_framePlayedLock );
self->m_framePlayed = true;
self->m_framePlayed = 1;
}
void RenderPreviewWidget::stopPreview()
......@@ -123,19 +120,15 @@ void RenderPreviewWidget::setPosition( float newPos )
void RenderPreviewWidget::nextFrame()
{
{
QWriteLocker lock( m_framePlayedLock );
m_framePlayed = false;
}
qDebug() << "Next frame :";
m_mainWorkflow->nextFrame();
m_mediaPlayer->play();
bool framePlayed = false;
while ( framePlayed == false )
{
SleepMS( 50 );
QReadLocker lock( m_framePlayedLock );
framePlayed = m_framePlayed;
}
qDebug() << "Activatign one frame only";
m_mainWorkflow->activateOneFrameOnly();
//Both media players should be stopped now... restauring playback
m_framePlayed = 0;
m_mediaPlayer->pause();
while ( m_framePlayed == 0 )
SleepMS( 1 );
m_mediaPlayer->pause();
}
......@@ -153,9 +146,10 @@ void RenderPreviewWidget::togglePlayPause( bool forcePause )
{
if ( m_paused == true && forcePause == false )
{
qDebug() << "Unpausing";
m_mediaPlayer->play();
//This will automaticly unpause... no worries
m_mainWorkflow->pause();
// m_mainWorkflow->pause();
m_paused = false;
}
else
......@@ -164,6 +158,7 @@ void RenderPreviewWidget::togglePlayPause( bool forcePause )
//So be careful about pausing two times :
if ( m_paused == false )
{
qDebug() << "Pausing";
m_mediaPlayer->pause();
m_mainWorkflow->pause();
m_paused = true;
......
......@@ -60,8 +60,7 @@ class RenderPreviewWidget : public GenericPreviewWidget
private:
MainWorkflow* m_mainWorkflow;
LibVLCpp::Media* m_media;
QReadWriteLock* m_framePlayedLock;
bool m_framePlayed;
QAtomicInt m_framePlayed;
public slots:
void __positionChanged();
......
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