From 2cf157ac7fe03f05f60fef1ec0fef8ee0c60cfe0 Mon Sep 17 00:00:00 2001 From: Hugo Beauzee-Luyssen Date: Mon, 1 Jun 2009 17:38:48 +0200 Subject: [PATCH] Refactored TrackWorkflow --- src/Workflow/ClipWorkflow.cpp | 97 +++++++--- src/Workflow/ClipWorkflow.h | 45 ++++- src/Workflow/MainWorkflow.cpp | 2 - src/Workflow/TrackWorkflow.cpp | 314 ++++++++++++--------------------- src/Workflow/TrackWorkflow.h | 51 +----- 5 files changed, 224 insertions(+), 285 deletions(-) diff --git a/src/Workflow/ClipWorkflow.cpp b/src/Workflow/ClipWorkflow.cpp index 971456d1a..dbfaaf085 100644 --- a/src/Workflow/ClipWorkflow.cpp +++ b/src/Workflow/ClipWorkflow.cpp @@ -24,41 +24,51 @@ #include "ClipWorkflow.h" -ClipWorkflow::ClipWorkflow( Clip::Clip* clip, QMutex* renderMutex, - QMutex* condMutex, QWaitCondition* waitCond ) : +int g_debugId = 0; + +ClipWorkflow::ClipWorkflow( Clip::Clip* clip ) : m_clip( clip ), m_buffer( NULL ), - m_renderMutex( renderMutex ), - m_condMutex( condMutex ), - m_waitCond( waitCond ), + m_usingBackBuffer( false ), m_mediaPlayer(NULL), - m_state( ClipWorkflow::Stopped ) + m_state( ClipWorkflow::Stopped ), + m_requiredState( ClipWorkflow::None ) { m_buffer = new unsigned char[VIDEOHEIGHT * VIDEOWIDTH * 4]; + m_backBuffer = new unsigned char[VIDEOHEIGHT * VIDEOWIDTH * 4]; m_stateLock = new QReadWriteLock; m_requiredStateLock = new QMutex; + m_condMutex = new QMutex; + m_waitCond = new QWaitCondition; + m_backBufferLock = new QReadWriteLock; + + this->debugId = g_debugId++; } ClipWorkflow::~ClipWorkflow() { delete[] m_buffer; + delete[] m_backBuffer; delete m_stateLock; delete m_requiredStateLock; + delete m_backBufferLock; } unsigned char* ClipWorkflow::getOutput() { - QMutexLocker lock( m_renderMutex ); - return m_buffer; + QReadLocker lock( m_backBufferLock ); + if ( m_usingBackBuffer == true ) + return m_buffer; + return m_backBuffer; } void ClipWorkflow::checkStateChange() { QMutexLocker lock( m_requiredStateLock ); - QWriteLocker lock2 ( m_stateLock ); + QWriteLocker lock2( m_stateLock ); if ( m_requiredState != ClipWorkflow::None ) { - qDebug() << "Changing state"; + qDebug() << "Setting required state : " << m_requiredState; m_state = m_requiredState; m_requiredState = ClipWorkflow::None; } @@ -66,29 +76,42 @@ void ClipWorkflow::checkStateChange() void ClipWorkflow::lock( ClipWorkflow* clipWorkflow, void** pp_ret ) { - //In any case, we give vlc a buffer to render in... - //If we don't, segmentation fault will catch us and eat our brains !! ahem... // qDebug() << "Locking in ClipWorkflow::lock"; - clipWorkflow->m_renderMutex->lock(); -// qDebug() << clipWorkflow->getState(); - *pp_ret = clipWorkflow->m_buffer; + QReadLocker lock( clipWorkflow->m_backBufferLock ); + + if ( clipWorkflow->m_usingBackBuffer ) + *pp_ret = clipWorkflow->m_backBuffer; + else + *pp_ret = clipWorkflow->m_buffer; } -void ClipWorkflow::unlock( ClipWorkflow* clipWorkflow ) +void ClipWorkflow::unlock( ClipWorkflow* cw ) { - clipWorkflow->m_renderMutex->unlock(); + cw->m_stateLock->lockForWrite(); - clipWorkflow->checkStateChange(); - clipWorkflow->m_stateLock->lockForRead(); - if ( clipWorkflow->m_state == Rendering ) + if ( cw->m_state == Rendering ) { - QMutexLocker lock( clipWorkflow->m_condMutex ); - clipWorkflow->m_stateLock->unlock(); - clipWorkflow->m_waitCond->wait( clipWorkflow->m_condMutex ); + cw->m_state = Sleeping; + cw->m_stateLock->unlock(); + + QMutexLocker lock( cw->m_condMutex ); + cw->m_waitCond->wait( cw->m_condMutex ); + + { + QWriteLocker lock2( cw->m_backBufferLock ); + cw->m_usingBackBuffer = !cw->m_usingBackBuffer; + } + + cw->m_stateLock->lockForWrite(); + cw->m_state = Rendering; } else - qDebug() << clipWorkflow->m_state; - clipWorkflow->m_stateLock->unlock(); + { + qDebug() << "UnLocking. State = " << cw->m_state << "Debug Id = " << cw->debugId; + } + cw->m_stateLock->unlock(); + cw->checkStateChange(); + // qDebug() << "UnLocking in ClipWorkflow::unlock"; } @@ -96,6 +119,7 @@ void ClipWorkflow::setVmem() { char buffer[32]; + qDebug() << "Setting vmem from clip " << this->debugId; //TODO: it would be good if we somehow backup the old media parameters to restore it later. m_clip->getParent()->getVLCMedia()->addOption( ":vout=vmem" ); m_clip->getParent()->getVLCMedia()->setDataCtx( this ); @@ -146,6 +170,7 @@ void ClipWorkflow::pausedMediaPlayer() { disconnect( m_mediaPlayer, SIGNAL( paused() ), this, SLOT( pausedMediaPlayer() ) ); setState( Ready ); + qDebug() << "Set Ready state"; } bool ClipWorkflow::isReady() const @@ -168,7 +193,6 @@ bool ClipWorkflow::isStopped() const ClipWorkflow::State ClipWorkflow::getState() const { - QReadLocker lock( m_stateLock ); return m_state; } @@ -199,6 +223,8 @@ void ClipWorkflow::stop() qDebug() << "Stopped media player"; m_mediaPlayer = NULL; setState( Stopped ); + QMutexLocker lock( m_requiredStateLock ); + m_requiredState = ClipWorkflow::None; qDebug() << "Changed state"; } @@ -215,6 +241,7 @@ bool ClipWorkflow::isRendering() const void ClipWorkflow::setState( State state ) { + qDebug() << "Setting state : " << state; QWriteLocker lock( m_stateLock ); m_state = state; } @@ -225,3 +252,21 @@ void ClipWorkflow::queryStateChange( State newState ) QMutexLocker lock( m_requiredStateLock ); m_requiredState = newState; } + +void ClipWorkflow::wake() +{ + m_waitCond->wakeAll(); +} + +QReadWriteLock* ClipWorkflow::getStateLock() +{ + return m_stateLock; +} + +void ClipWorkflow::reinitialize() +{ + QWriteLocker lock( m_stateLock ); + m_state = Stopped; + queryStateChange( None ); +} + diff --git a/src/Workflow/ClipWorkflow.h b/src/Workflow/ClipWorkflow.h index a9d070135..8b618f299 100644 --- a/src/Workflow/ClipWorkflow.h +++ b/src/Workflow/ClipWorkflow.h @@ -49,11 +49,13 @@ class ClipWorkflow : public QObject Initializing, Ready, Rendering, + Sleeping, + Stopping, EndReached, - StopRequired, }; + int debugId; - ClipWorkflow( Clip* clip, QMutex* renderMutex, QMutex* condMutex, QWaitCondition* waitCond ); + ClipWorkflow( Clip* clip ); virtual ~ClipWorkflow(); /** @@ -89,6 +91,9 @@ class ClipWorkflow : public QObject /** * Returns the current workflow state. + * Be carrefull, as this function is NOT thread safe, and return the + * state without locking the state. + * It's your job to do it, by calling the getStateLock() method. */ State getState() const; @@ -120,23 +125,53 @@ class ClipWorkflow : public QObject */ void queryStateChange( State newState ); + /** + * This method will wake the renderer thread for one iteration. + */ + void wake(); + + /** + * This returns the QReadWriteLock that protects the ClipWorkflow's state. + * It should be use to lock the value when checking states from outside this + * class. + */ + QReadWriteLock* getStateLock(); + + /** + * Put back the ClipWorkflow in its initial state. + */ + void reinitialize(); + private: static void lock( ClipWorkflow* clipWorkflow, void** pp_ret ); static void unlock( ClipWorkflow* clipWorkflow ); void setVmem(); void setState( State state ); + /** + * Don't ever call this method from anywhere else than the unlock() method + */ void checkStateChange(); private: Clip* m_clip; unsigned char* m_buffer; + unsigned char* m_backBuffer; + /** + * This allow the render procedure to know in which buffer it should render. + * If true, then the render occurs in the back buffer, which means the + * returned buffer much be the "front" buffer. + * In other term : + * - When m_usingBackBuffer == false, lock() will return m_buffer, and getOutput() m_backBuffer + * - When m_usingBackBuffer == true, lock() will return m_backBuffer, and getOutput() m_buffer + */ + bool m_usingBackBuffer; + QReadWriteLock* m_backBufferLock; + + LibVLCpp::MediaPlayer* m_mediaPlayer; - QMutex* m_renderMutex; QMutex* m_condMutex; QWaitCondition* m_waitCond; - LibVLCpp::MediaPlayer* m_mediaPlayer; - State m_state; QReadWriteLock* m_stateLock; State m_requiredState; diff --git a/src/Workflow/MainWorkflow.cpp b/src/Workflow/MainWorkflow.cpp index dacc33198..ebffb86a9 100644 --- a/src/Workflow/MainWorkflow.cpp +++ b/src/Workflow/MainWorkflow.cpp @@ -50,7 +50,6 @@ void MainWorkflow::startRender() m_currentFrame = 0; emit frameChanged( 0 ); m_length = m_tracks[0]->getLength(); - m_tracks[0]->startRender(); } unsigned char* MainWorkflow::getOutput() @@ -67,7 +66,6 @@ void MainWorkflow::setPosition( float pos ) if ( m_renderStarted == false ) return ; qint64 frame = (float)m_length * pos; - m_tracks[0]->requirePositionChanged( pos ); m_currentFrame = frame; emit frameChanged( frame ); //Do not emit a signal for the RenderWidget, since it's the one that triggered that call... diff --git a/src/Workflow/TrackWorkflow.cpp b/src/Workflow/TrackWorkflow.cpp index 550e290af..da47f809f 100644 --- a/src/Workflow/TrackWorkflow.cpp +++ b/src/Workflow/TrackWorkflow.cpp @@ -26,13 +26,9 @@ unsigned char* TrackWorkflow::blackOutput = NULL; -TrackWorkflow::TrackWorkflow() : m_requiredPosition( -1.0f ) +TrackWorkflow::TrackWorkflow() { - m_condMutex = new QMutex; - m_waitCondition = new QWaitCondition; m_mediaPlayer = new LibVLCpp::MediaPlayer(); - m_renderMutex = new QMutex; - m_requiredPositionLock = new QMutex; if ( TrackWorkflow::blackOutput == NULL ) { //TODO: this ain't free ! @@ -43,38 +39,17 @@ TrackWorkflow::TrackWorkflow() : m_requiredPosition( -1.0f ) TrackWorkflow::~TrackWorkflow() { - delete m_condMutex; - delete m_waitCondition; delete m_mediaPlayer; - delete m_renderMutex; } void TrackWorkflow::addClip( Clip* clip, qint64 start ) { qDebug() << "Inserting clip at frame nb" << start; - ClipWorkflow* cw = new ClipWorkflow( clip, m_renderMutex, m_condMutex, m_waitCondition ); + ClipWorkflow* cw = new ClipWorkflow( clip ); m_clips.insert( start, cw ); computeLength(); } -void TrackWorkflow::startRender() -{ - m_current = m_clips.end(); - - if ( m_clips.size() <= 0) - return ; - //If the first frame is to be render soon, we should play it now. - if ( m_clips.begin().key() < TrackWorkflow::nbFrameBeforePreload ) - { - m_clips.begin().value()->initialize( m_mediaPlayer ); - if ( m_current.key() == 0 ) - { - m_current = m_clips.begin(); - m_current.value()->startRender(); - } - } -} - void TrackWorkflow::computeLength() { if ( m_clips.count() == 0 ) @@ -88,227 +63,158 @@ qint64 TrackWorkflow::getLength() const return m_length; } -bool TrackWorkflow::checkNextClip( qint64 currentFrame ) +unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, bool needRepositioning, float pos ) { - QMap::iterator next; - const QMap::const_iterator end = m_clips.end(); + unsigned char* ret = TrackWorkflow::blackOutput; - //Picking next clip : - if ( m_current == end ) - { - //Checking if there is a clip in the first place... - if ( m_clips.count() == 0 ) - return false; - next = m_clips.begin(); - } - else - { - next = m_clips.begin() + 1; - if ( next == end ) - return false; - } + cw->getStateLock()->lockForRead(); - //If it's about to be used, initialize it - if ( next.key() == currentFrame + TrackWorkflow::nbFrameBeforePreload ) - { - //Don't do anything if the current media player is still in use - //But for it to be in use, we should have a current media : - if ( m_current != end && m_current.value()->isRendering() == false ) - qDebug() << "Preloading media"; - next.value()->initialize( m_mediaPlayer ); - } - //This ClipWorkflow must start at this frame : - else if ( next.key() == currentFrame ) + if ( cw->getState() == ClipWorkflow::Rendering ) { - qDebug() << "Starting rendering"; - m_current = next; - m_current.value()->startRender(); + //The rendering state meens... whell it means that the frame is + //beeing rendered, so we wait. + cw->getStateLock()->unlock(); + while ( cw->isRendering() == true ) + { +// qDebug() << "Waiting for complete render. State == " << cw->getState(); + usleep( 100 ); + } + cw->getStateLock()->lockForRead(); + //This way we can trigger the appropriate if just below. } - return true; -} -unsigned char* TrackWorkflow::getOutput( qint64 currentFrame ) -{ - unsigned char* ret = TrackWorkflow::blackOutput; - bool clipsRemaining; - - QMutexLocker lock( m_requiredPositionLock ); - if ( m_requiredPosition >= 0.0f ) + //If frame has been rendered : + if ( cw->getState() == ClipWorkflow::Sleeping ) { - setPosition( m_requiredPosition ); - m_requiredPosition = -1.0f; + cw->getStateLock()->unlock(); + ret = cw->getOutput(); + if ( needRepositioning == true ) + { + cw->setPosition( pos ); + } + cw->wake(); } - checkStop(); -// qDebug() << "Frame nb" << currentFrame; - clipsRemaining = checkNextClip( currentFrame ); - //This is true only before the first render. - if ( m_current == m_clips.end() ) + else if ( cw->getState() == ClipWorkflow::Stopped ) { -// qDebug() << "m_current == m_clips.end()"; - //If the track was empty, then its end is reached - if ( clipsRemaining == false ) - emit endReached(); - //Else, we return a black screen. - return TrackWorkflow::blackOutput; + cw->getStateLock()->unlock(); + cw->initialize( m_mediaPlayer ); + cw->startRender(); + qDebug() << "Render started for clip" << cw->debugId; } - //We proceed to the render only if the ClipWorkflow is in rendering mode. - if ( m_current.value()->isRendering() == true ) + else if ( cw->getState() == ClipWorkflow::Ready || + cw->getState() == ClipWorkflow::Initializing ) { - m_waitCondition->wakeAll(); -// qDebug() << "Is rendering == true"; - ret = m_current.value()->getOutput(); - return ret; + //If the state is Initializing, then the workflow will wait. + //Otherwise, it will start directly. + cw->getStateLock()->unlock(); + cw->startRender(); + qDebug() << "Started render for clip" << cw->debugId; } - else if ( m_current.value()->getState() == ClipWorkflow::EndReached || - m_current.value()->getState() == ClipWorkflow::StopRequired ) + else { - //First, we stop the current ClipWorkflow so that it won't - //enter the lock/unlock cycle anymore. - qDebug() << "Stopping"; - m_current.value()->stop(); - //Then, if there's no remaining clip, end of track is reached. - if ( clipsRemaining == false ) - emit endReached(); + qDebug() << "Unexpected ClipWorkflow::State when rendering:" << cw->getState(); + cw->getStateLock()->unlock(); } -// else -// qDebug() << "Uncoherent state : " << m_current.value()->getState(); return ret; } -void TrackWorkflow::initializeClipWorkflow( ClipWorkflow* cw ) +void TrackWorkflow::preloadClip( ClipWorkflow* cw ) { - //>Launching the initialization - cw->initialize( m_mediaPlayer ); - cw->startRender(); -} + cw->getStateLock()->lockForRead(); -void TrackWorkflow::stopClipWorkflow( ClipWorkflow* cw ) -{ - if ( cw->getState() != ClipWorkflow::Stopped && cw->getState() != ClipWorkflow::StopRequired ) + if ( cw->getState() == ClipWorkflow::Stopped ) { - cw->queryStateChange( ClipWorkflow::StopRequired ); - //Since state change won't be immediate, we add the clip workflow to a lookup list - m_toStop.enqueue( cw ); + cw->getStateLock()->unlock(); + cw->initialize( m_mediaPlayer ); + return ; } + cw->getStateLock()->unlock(); } -void TrackWorkflow::setPosition( float pos ) +void TrackWorkflow::stopClipWorkflow( ClipWorkflow* cw ) { - qDebug() << "Setting pos"; - qint64 frame = (float)m_length * pos; - QMap::iterator it = m_clips.begin(); - const QMap::iterator end = m_clips.end(); - QMap::iterator next = end; + cw->getStateLock()->lockForRead(); - if ( frame > m_length ) + if ( cw->getState() == ClipWorkflow::Stopped ) { - if ( m_current != end ) - { - stopClipWorkflow( m_current.value() ); - m_current = end; - qDebug() << "After end of current track"; - return ; - } + cw->getStateLock()->unlock(); + return ; } - - //Locate the new clip workflow - while ( it != end ) + if ( cw->getState() == ClipWorkflow::Sleeping || + cw->getState() == ClipWorkflow::Ready || + cw->getState() == ClipWorkflow::EndReached ) { - if ( it.key() <= frame && - ( it.key() + it.value()->getClip()->getLength() ) > frame ) - { - break; - } - else if ( next == m_clips.end() && it.key() > frame ) - { - // If this clip doesn't match, but starts AFTER the frame we aim, - // we can assume that it's the next clip. - // We can break, and put it to end() in order to simulate the - // normal end of the loop. - next = it; - if ( next != m_clips.begin() ) - { - next = next - 1; //Since the iterator must point to the previous video - } - else - { - next = end; - } - // in order to checkNextClip() to work. - it = end; - break ; - } - ++it; + qDebug() << "Stopping from sleeping / ready / endreached state for clip " << cw->debugId; + cw->getStateLock()->unlock(); + cw->queryStateChange( ClipWorkflow::Stopping ); + cw->wake(); + cw->stop(); } - - //No clip was found, just adjusing the current clip. (Render will be black though) - if ( it == end ) + else if ( cw->getState() == ClipWorkflow::Rendering ) { - qDebug() << "In black zone"; - //We should use the next clip, however, we use the clip just before - //the next. - //We also stop the current clip if it was started. - if ( m_current != end ) - { - stopClipWorkflow( m_current.value() ); - } - //TODO: it seems that m_current may be equal to next... check if that could be a problem... - m_current = next; + qDebug() << "Stopping from rendering state for clip" << cw->debugId; + cw->getStateLock()->unlock(); + while ( cw->isRendering() == true ) + usleep( 100 ); + qDebug() << "Rendering completed" << cw->debugId; + cw->queryStateChange( ClipWorkflow::Stopping ); + cw->wake(); + cw->stop(); + qDebug() << "Mediaplayer Stop asked for clip" << cw->debugId; } - // If the clip found is the current, we just change the position of the - // media player - else if ( it == m_current ) + else if ( cw->getState() == ClipWorkflow::Initializing ) { - qDebug() << "Using current clip with new position"; - qDebug() << it.value()->getState(); - //The clip may have been stoped (if we reached end but came back at it) - if ( it.value()->isStopped() ) - { - initializeClipWorkflow( it.value() ); - } - it.value()->setPosition( (float)( frame - it.key() ) / (float)(it.value()->getClip()->getLength()) ); - //Awaking renderers to avoid them to be stuck inside of the lock... - m_waitCondition->wakeAll(); + qDebug() << "Stopping from initializing state for clip" << cw->debugId; + cw->getStateLock()->unlock(); + while ( cw->isReady() == false ) + usleep( 20 ); + cw->stop(); } - // Else, we found a clip that is not the current one. else { - qDebug() << "Using other clip"; - //First, we stop the current workflow. - if ( m_current != end ) - { - stopClipWorkflow( m_current.value() ); - } - //We initialize the new workflow - initializeClipWorkflow( it.value() ); - //And this is now our current clip - m_current = it; - - //TODO: we doesn't take the new position in count :/ + qDebug() << "Unexpected ClipWorkflow::State when stopping :" << cw->getState(); + cw->getStateLock()->unlock(); } } -void TrackWorkflow::requirePositionChanged( float pos ) +unsigned char* TrackWorkflow::getOutput( qint64 currentFrame ) { - QMutexLocker lock( m_requiredPositionLock ); - m_requiredPosition = pos; -} + unsigned char* ret = TrackWorkflow::blackOutput; + QMap::iterator it = m_clips.begin(); + QMap::iterator end = m_clips.end(); + static qint64 lastFrame = 0; + bool needRepositioning; -void TrackWorkflow::checkStop() -{ - while ( m_toStop.isEmpty() == false ) + needRepositioning = ( abs( currentFrame - lastFrame ) > 3 ) ? true : false; + while ( it != end ) { - ClipWorkflow* cw = m_toStop.head(); - if ( cw->getState() == ClipWorkflow::StopRequired ) + qint64 start = it.key(); + ClipWorkflow* cw = it.value(); + + //Is the clip supposed to render now ? + if ( start <= currentFrame && currentFrame <= start + cw->getClip()->getLength() ) { - qDebug() << "Stopping from queue"; - cw->stop(); - m_toStop.dequeue(); + if ( needRepositioning == true ) + { + qDebug() << "Repositionning"; + ret = renderClip( cw, true, + ( (float)( currentFrame - start ) / (float)(cw->getClip()->getLength()) ) ); + } + else + ret = renderClip( cw, false, 0 ); + lastFrame = currentFrame; } - else + //Is it about to be rendered ? + else if ( start > currentFrame && + start - currentFrame < TrackWorkflow::nbFrameBeforePreload ) { - qDebug() << cw->getState(); - return ; + preloadClip( cw ); } + //Is it supposed to be stopped ? + else + stopClipWorkflow( cw ); + + ++it; } + return ret; } diff --git a/src/Workflow/TrackWorkflow.h b/src/Workflow/TrackWorkflow.h index 6c1e02eba..95034bd0f 100644 --- a/src/Workflow/TrackWorkflow.h +++ b/src/Workflow/TrackWorkflow.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include "ClipWorkflow.h" @@ -46,58 +46,21 @@ class TrackWorkflow : public QObject TrackWorkflow(); ~TrackWorkflow(); - void startRender(); unsigned char* getOutput( qint64 currentFrame ); qint64 getLength() const; - /** - \brief Set the track workflow position - \param pos: The new pos in VLC position - */ - void setPosition( float pos ); - void requirePositionChanged( float pos ); - //FIXME: this won't be reliable as soon as we change the fps from the configuration static const unsigned int nbFrameBeforePreload = 60; static unsigned char* blackOutput; private: - /** - * \brief Check if there's a ClipWorkflow that's comming soon. If so, it preload it to avoid - freeze when switching video. - This does NOT search for the next current clip ! - * \return true if at least one video remains, false otherwise (IE end of this track) - */ - bool checkNextClip( qint64 currentFrame ); void computeLength(); - void initializeClipWorkflow( ClipWorkflow* cw ); + unsigned char* renderClip( ClipWorkflow* cw, bool needRepositioning, float pos ); + void preloadClip( ClipWorkflow* cw ); void stopClipWorkflow( ClipWorkflow* cw ); - void checkStop(); private: QMap m_clips; - /** - * \brief An iterator that "point" the current ClipWorkflow used. - * - * This holds the current ClipWorkflow, and the current starting frame - * of this ClipWorkflow. - * If the track is empty at a T time, this iterator still points to the last - * ClipWorkflow used. However, if the next video occurs to be the first one - * in the Track, this iterators is equal to m_clips.end(); - */ - QMap::iterator m_current; - - /** - * This mutex is used for ClipWorkflow synchronisation. - * Using it otherwise might be a (really) bad idea. - */ - QMutex* m_condMutex; - QWaitCondition* m_waitCondition; - - /** - * This mutex is used to wait for the ClipWorkflow render to end - */ - QMutex* m_renderMutex; /** * This is the MediaPlayer that the clipworkflow @@ -110,14 +73,6 @@ class TrackWorkflow : public QObject */ qint64 m_length; - /** - * This is used to dispatch a setPosition event to the renderer thread - */ - float m_requiredPosition; - QMutex* m_requiredPositionLock; - - QQueue m_toStop; - public: void addClip( Clip*, qint64 start ); -- GitLab