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

Again some refactoring

parent e5f4dd37
......@@ -122,7 +122,7 @@ int WorkflowRenderer::lockVideo( WorkflowRenderer* self, int64_t *pts, size_
if ( self->m_stopping == false && self->m_paused == false )
{
MainWorkflow::OutputBuffers* ret = self->m_mainWorkflow->getSynchroneOutput( MainWorkflow::VideoTrack );
MainWorkflow::OutputBuffers* ret = self->m_mainWorkflow->getOutput( MainWorkflow::VideoTrack );
memcpy( self->m_renderVideoFrame, (*(ret->video))->frame.octets, (*(ret->video))->nboctets );
self->m_videoBuffSize = (*(ret->video))->nboctets;
ptsDiff = (*(ret->video))->ptsDiff;
......@@ -143,7 +143,7 @@ int WorkflowRenderer::lockAudio( WorkflowRenderer* self, int64_t *pts, size
return 1;
if ( self->m_stopping == false )
{
MainWorkflow::OutputBuffers* ret = self->m_mainWorkflow->getSynchroneOutput( MainWorkflow::AudioTrack );
MainWorkflow::OutputBuffers* ret = self->m_mainWorkflow->getOutput( MainWorkflow::AudioTrack );
self->m_renderAudioSample = ret->audio;
}
uint32_t nbSample;
......@@ -276,7 +276,6 @@ void WorkflowRenderer::stop()
m_isRendering = false;
m_paused = false;
m_stopping = true;
m_mainWorkflow->cancelSynchronisation();
m_mediaPlayer->stop();
m_mainWorkflow->stop();
}
......
......@@ -38,9 +38,6 @@ MainWorkflow::MainWorkflow( int trackCount ) :
m_currentFrameLock = new QReadWriteLock;
m_renderStartedLock = new QReadWriteLock;
m_renderMutex = new QMutex;
m_synchroneRenderWaitCondition = new QWaitCondition;
m_synchroneRenderWaitConditionMutex = new QMutex;
m_pauseWaitCond = new WaitCondition;
const SettingValue* width = SettingsManager::getInstance()->getValue( "project", "VideoProjectWidth" );
connect( width, SIGNAL( changed( QVariant ) ), this, SLOT( widthChanged( QVariant ) ) );
......@@ -65,7 +62,6 @@ MainWorkflow::MainWorkflow( int trackCount ) :
m_currentFrame[i] = 0;
}
m_outputBuffers = new OutputBuffers;
m_nbTrackHandlerToRenderMutex = new QMutex;
blackOutput = new LightVideoFrame( m_width * m_height * Pixel::NbComposantes );
memset( (*blackOutput)->frame.octets, 0, (*blackOutput)->nboctets );
......@@ -76,11 +72,7 @@ MainWorkflow::~MainWorkflow()
//FIXME: this is probably useless, since already done by the renderer
stop();
delete m_nbTrackHandlerToRenderMutex;
delete m_pauseWaitCond;
delete m_effectEngine;
delete m_synchroneRenderWaitConditionMutex;
delete m_synchroneRenderWaitCondition;
delete m_renderMutex;
delete m_renderStartedLock;
delete m_currentFrameLock;
......@@ -125,7 +117,7 @@ void MainWorkflow::startRender()
computeLength();
}
void MainWorkflow::getOutput( TrackType trackType )
MainWorkflow::OutputBuffers* MainWorkflow::getOutput( TrackType trackType )
{
QReadLocker lock( m_renderStartedLock );
QMutexLocker lock2( m_renderMutex );
......@@ -133,33 +125,33 @@ void MainWorkflow::getOutput( TrackType trackType )
if ( m_renderStarted == true )
{
QReadLocker lock3( m_currentFrameLock );
QMutexLocker lock4( m_nbTrackHandlerToRenderMutex );
//This has probably no reason for existing... and therefore shouldn't
if ( trackType == BothTrackType )
m_tracks[trackType]->getOutput( m_currentFrame[trackType] );
if ( trackType == MainWorkflow::VideoTrack )
{
m_nbTrackHandlerToRender = MainWorkflow::NbTrackType;
for ( unsigned int i = 0; i < MainWorkflow::NbTrackType; ++i )
m_tracks[i]->getOutput( m_currentFrame[i] );
m_effectEngine->render();
if ( m_effectEngine->getOutputFrame( 0 )->nboctets == 0 )
m_outputBuffers->video = MainWorkflow::blackOutput;
else
m_outputBuffers->video = &( m_effectEngine->getOutputFrame( 0 ) );
}
else
{
m_nbTrackHandlerToRender = 1;
m_tracks[trackType]->getOutput( m_currentFrame[trackType] );
m_outputBuffers->audio = m_tracks[MainWorkflow::AudioTrack]->getTmpAudioBuffer();
}
}
return m_outputBuffers;
}
void MainWorkflow::pause()
{
//Just wait for the current render to finish
m_renderMutex->lock();
QMutexLocker lock( m_pauseWaitCond->getMutex() );
m_renderMutex->unlock();
//TODO:
//FIXME: check if this is not alreay handled by the stacked actions system.
QMutexLocker lock( m_renderMutex );
for ( unsigned int i = 0; i < MainWorkflow::NbTrackType; ++i )
m_tracks[i]->pause();
m_pauseWaitCond->waitLocked();
}
void MainWorkflow::unpause()
......@@ -239,37 +231,6 @@ Clip* MainWorkflow::removeClip( const QUuid& uuid, unsigned int trackId, M
return clip;
}
MainWorkflow::OutputBuffers* MainWorkflow::getSynchroneOutput( MainWorkflow::TrackType trackType )
{
m_synchroneRenderWaitConditionMutex->lock();
getOutput( trackType );
// qDebug() << "Waiting for sync output";
m_synchroneRenderWaitCondition->wait( m_synchroneRenderWaitConditionMutex );
// qDebug() << "Got it";
if ( trackType == BothTrackType || trackType == VideoTrack )
{
m_effectEngine->render();
if ( m_effectEngine->getOutputFrame( 0 )->nboctets == 0 )
m_outputBuffers->video = MainWorkflow::blackOutput;
else
m_outputBuffers->video = &( m_effectEngine->getOutputFrame( 0 ) );
}
if ( trackType == BothTrackType || trackType == AudioTrack )
{
m_outputBuffers->audio = m_tracks[MainWorkflow::AudioTrack]->getTmpAudioBuffer();
}
m_synchroneRenderWaitConditionMutex->unlock();
return m_outputBuffers;
}
void MainWorkflow::cancelSynchronisation()
{
{
QMutexLocker lock( m_synchroneRenderWaitConditionMutex );
}
m_synchroneRenderWaitCondition->wakeAll();
}
void MainWorkflow::muteTrack( unsigned int trackId, MainWorkflow::TrackType trackType )
{
m_tracks[trackType]->muteTrack( trackId );
......@@ -414,19 +375,6 @@ void MainWorkflow::clear()
emit cleared();
}
void MainWorkflow::tracksPaused()
{
for ( unsigned int i = 0; i < MainWorkflow::NbTrackType; ++i )
if ( m_tracks[i]->isPaused() == false )
return ;
m_paused = true;
{
QMutexLocker lock( m_pauseWaitCond->getMutex() );
m_pauseWaitCond->wake();
}
emit mainWorkflowPaused();
}
void MainWorkflow::tracksEndReached()
{
for ( unsigned int i = 0; i < MainWorkflow::NbTrackType; ++i )
......@@ -435,30 +383,6 @@ void MainWorkflow::tracksEndReached()
emit mainWorkflowEndReached();
}
void MainWorkflow::tracksUnpaused()
{
for ( unsigned int i = 0; i < MainWorkflow::NbTrackType; ++i )
if ( m_tracks[i]->isPaused() == true )
return ;
m_paused = false;
emit mainWorkflowUnpaused();
}
void MainWorkflow::tracksRenderCompleted()
{
{
QMutexLocker lock( m_nbTrackHandlerToRenderMutex );
--m_nbTrackHandlerToRender;
if ( m_nbTrackHandlerToRender > 0 )
return ;
}
{
QMutexLocker lock( m_synchroneRenderWaitConditionMutex );
}
m_synchroneRenderWaitCondition->wakeAll();
}
int MainWorkflow::getTrackCount( MainWorkflow::TrackType trackType ) const
{
return m_tracks[trackType]->getTrackCount();
......@@ -471,7 +395,6 @@ qint64 MainWorkflow::getCurrentFrame() const
return m_currentFrame[MainWorkflow::VideoTrack];
}
void MainWorkflow::widthChanged( const QVariant& width )
{
m_width = width.toUInt();
......
......@@ -52,7 +52,6 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
};
enum TrackType
{
BothTrackType = -1,
VideoTrack,
AudioTrack,
NbTrackType,
......@@ -68,8 +67,7 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
void addClip( Clip* clip, unsigned int trackId, qint64 start, TrackType type );
void startRender();
void getOutput( TrackType trackType );
OutputBuffers* getSynchroneOutput( TrackType trackType );
OutputBuffers* getOutput( TrackType trackType );
EffectsEngine* getEffectsEngine();
/**
......@@ -120,12 +118,6 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
MainWorkflow::TrackType trackType, bool undoRedoCommand = false );
qint64 getClipPosition( const QUuid& uuid, unsigned int trackId, MainWorkflow::TrackType trackType ) const;
/**
* \brief This method will wake every wait condition, so that threads won't
* be waiting anymore, thus avoiding dead locks.
*/
void cancelSynchronisation();
void muteTrack( unsigned int trackId, MainWorkflow::TrackType );
void unmuteTrack( unsigned int trackId, MainWorkflow::TrackType );
......@@ -161,11 +153,6 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
QReadWriteLock* m_renderStartedLock;
QMutex* m_renderMutex;
QWaitCondition* m_synchroneRenderWaitCondition;
QMutex* m_synchroneRenderWaitConditionMutex;
unsigned int m_nbTrackHandlerToRender;
QMutex* m_nbTrackHandlerToRenderMutex;
WaitCondition* m_pauseWaitCond;
bool m_paused;
TrackHandler** m_tracks;
OutputBuffers* m_outputBuffers;
......@@ -179,9 +166,6 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
friend class Singleton<MainWorkflow>;
private slots:
void tracksPaused();
void tracksUnpaused();
void tracksRenderCompleted();
void tracksEndReached();
void widthChanged( const QVariant& );
void heightChanged( const QVariant& );
......@@ -200,8 +184,6 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
MainWorkflow::FrameChangedReason );
void mainWorkflowEndReached();
void mainWorkflowPaused();
void mainWorkflowUnpaused();
void clipAdded( Clip*, unsigned int, qint64, MainWorkflow::TrackType );
void clipRemoved( Clip*, unsigned int, MainWorkflow::TrackType );
void clipMoved( QUuid, unsigned int, qint64, MainWorkflow::TrackType );
......
......@@ -38,11 +38,7 @@ TrackHandler::TrackHandler( unsigned int nbTracks, MainWorkflow::TrackType track
{
m_tracks[i].setPtr( new TrackWorkflow( i, trackType ) );
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( trackUnpaused() ), this, SLOT( trackUnpaused() ) );
connect( m_tracks[i], SIGNAL( renderCompleted( unsigned int ) ), this, SLOT( tracksRenderCompleted( unsigned int ) ), Qt::QueuedConnection );
}
m_nbTracksToRenderMutex = new QMutex;
}
TrackHandler::~TrackHandler()
......@@ -52,7 +48,6 @@ TrackHandler::~TrackHandler()
delete nullOutput;
nullOutput = NULL;
}
delete m_nbTracksToRenderMutex;
for (unsigned int i = 0; i < m_trackCount; ++i)
delete m_tracks[i];
......@@ -102,10 +97,6 @@ qint64 TrackHandler::getLength() const
void TrackHandler::getOutput( qint64 currentFrame )
{
QMutexLocker lockNbTracks( m_nbTracksToRenderMutex );
m_renderCompleted = false;
m_nbTracksToRender = 0;
m_tmpAudioBuffer = NULL;
for ( unsigned int i = 0; i < m_trackCount; ++i )
{
......@@ -114,34 +105,36 @@ void TrackHandler::getOutput( qint64 currentFrame )
if ( m_tracks[i].activated() == false )
m_effectEngine->setInputFrame( *TrackHandler::nullOutput, i );
else
m_effectEngine->setInputFrame( m_tracks[i]->getOutput( currentFrame ), i );
{
StackedBuffer<LightVideoFrame*>* stackedBuffer =
reinterpret_cast<StackedBuffer<LightVideoFrame*>*>( m_tracks[i]->getOutput( currentFrame ) );
m_effectEngine->setInputFrame( *(stackedBuffer->get()), i );
}
}
else
{
StackedBuffer<AudioClipWorkflow::AudioSample*>* stackedBuffer =
reinterpret_cast<StackedBuffer<AudioClipWorkflow::AudioSample*>*> (m_tracks[i]->getOutput( currentFrame ) );
m_tmpAudioBuffer = stackedBuffer->get();
}
}
}
void TrackHandler::pause()
{
m_nbTracksToPause = 0;
for ( unsigned int i = 0; i < m_trackCount; ++i )
{
if ( m_tracks[i].activated() == true )
{
m_nbTracksToPause.fetchAndAddAcquire( 1 );
m_tracks[i]->pause();
}
}
}
void TrackHandler::unpause()
{
m_nbTracksToUnpause = 0;
for ( unsigned int i = 0; i < m_trackCount; ++i )
{
if ( m_tracks[i].activated() == true )
{
m_nbTracksToUnpause.fetchAndAddAcquire( 1 );
m_tracks[i]->unpause();
}
//Don't check for track activation, as it could have change from the time we paused.
m_tracks[i]->unpause();
}
}
......@@ -248,11 +241,6 @@ bool TrackHandler::endIsReached() const
return m_endReached;
}
bool TrackHandler::allTracksRendered() const
{
return m_renderCompleted;
}
void TrackHandler::trackEndReached( unsigned int trackId )
{
m_tracks[trackId].deactivate();
......@@ -266,58 +254,6 @@ void TrackHandler::trackEndReached( unsigned int trackId )
emit tracksEndReached();
}
void TrackHandler::trackPaused()
{
m_nbTracksToPause.fetchAndAddAcquire( -1 );
if ( m_nbTracksToPause <= 0 )
{
m_paused = true;
emit tracksPaused();
}
}
void TrackHandler::trackUnpaused()
{
m_nbTracksToUnpause.fetchAndAddAcquire( -1 );
if ( m_nbTracksToUnpause <= 0 )
{
m_paused = false;
emit tracksUnpaused();
}
}
void TrackHandler::tracksRenderCompleted( unsigned int trackId )
{
QMutexLocker lockNbTracks( m_nbTracksToRenderMutex );
--m_nbTracksToRender;
{
if ( m_trackType == MainWorkflow::VideoTrack )
{
LightVideoFrame* buff = reinterpret_cast<LightVideoFrame*>( m_tracks[trackId]->getSynchroneOutput() );
if ( buff == NULL )
{
m_effectEngine->setInputFrame( *TrackHandler::nullOutput, trackId );
}
else
m_effectEngine->setInputFrame( *buff, trackId );
}
else
{
AudioClipWorkflow::AudioSample* buff = reinterpret_cast<AudioClipWorkflow::AudioSample*>( m_tracks[trackId]->getOutput() );
m_tmpAudioBuffer = buff;
}
}
//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 )
{
//Just a synchronisation barriere
m_renderCompleted = true;
emit allTracksRenderCompleted();
}
}
unsigned int TrackHandler::getTrackCount() const
{
return m_trackCount;
......
......@@ -66,7 +66,6 @@ class TrackHandler : public QObject
bool isPaused() const;
bool endIsReached() const;
bool allTracksRendered() const;
void save( QDomDocument& doc, QDomElement& timelineNode ) const;
......@@ -78,33 +77,19 @@ class TrackHandler : public QObject
static LightVideoFrame* nullOutput;
Toggleable<TrackWorkflow*>* m_tracks;
unsigned int m_trackCount;
QAtomicInt m_nbTracksToPause;
QAtomicInt m_nbTracksToUnpause;
MainWorkflow::TrackType m_trackType;
qint64 m_length;
unsigned int m_highestTrackNumber;
bool m_paused;
bool m_endReached;
/**
* \brief This flag is used to know if all tracks handled
* have been rendered.
* This is for internal synchronisation only.
*/
bool m_renderCompleted;
EffectsEngine* m_effectEngine;
AudioClipWorkflow::AudioSample* m_tmpAudioBuffer;
private slots:
void trackEndReached( unsigned int trackId );
void trackPaused();
void trackUnpaused();
void tracksRenderCompleted( unsigned int trackId );
signals:
void tracksPaused();
void tracksUnpaused();
void allTracksRenderCompleted();
void tracksEndReached();
};
......
......@@ -33,9 +33,10 @@ TrackWorkflow::TrackWorkflow( unsigned int trackId, MainWorkflow::TrackType type
m_length( 0 ),
m_forceRepositionning( false ),
m_paused( false ),
m_synchroneRenderBuffer( NULL ),
m_trackType( type ),
m_lastFrame( 0 )
m_lastFrame( 0 ),
m_videoStackedBuffer( NULL ),
m_audioStackedBuffer( NULL )
{
m_forceRepositionningMutex = new QMutex;
m_clipsLock = new QReadWriteLock;
......@@ -259,6 +260,10 @@ void* TrackWorkflow::getOutput( qint64 currentFrame )
if ( ret != NULL )
qCritical() << "There's more than one clip to render here. Undefined behaviour !";
ret = renderClip( cw, currentFrame, start, needRepositioning );
if ( m_trackType == MainWorkflow::VideoTrack )
m_videoStackedBuffer = reinterpret_cast<StackedBuffer<LightVideoFrame*>*>( ret );
else
m_audioStackedBuffer = reinterpret_cast<StackedBuffer<AudioClipWorkflow::AudioSample*>*>( ret );
}
//Is it about to be rendered ?
else if ( start > currentFrame &&
......
......@@ -34,6 +34,7 @@
#include "ClipWorkflow.h"
#include "LightVideoFrame.h"
#include "MainWorkflow.h"
#include "StackedBuffer.hpp"
//TODO: REMOVE THIS
#ifndef FPS
......@@ -75,7 +76,7 @@ class TrackWorkflow : public QObject
private:
void computeLength();
void renderClip( ClipWorkflow* cw, qint64 currentFrame,
void* renderClip( ClipWorkflow* cw, qint64 currentFrame,
qint64 start, bool needRepositioning );
void preloadClip( ClipWorkflow* cw );
void stopClipWorkflow( ClipWorkflow* cw );
......@@ -105,10 +106,11 @@ class TrackWorkflow : public QObject
bool m_paused;
void* m_output;
MainWorkflow::TrackType m_trackType;
qint64 m_lastFrame;
//Damn i wish this could be a meta-if :D (ho wait... it could be ! once the code will be cleaned)
StackedBuffer<LightVideoFrame*>* m_videoStackedBuffer;
StackedBuffer<AudioClipWorkflow::AudioSample*> * m_audioStackedBuffer;
signals:
void trackEndReached( unsigned int );
......
......@@ -5,7 +5,8 @@ HEADERS += AudioClipWorkflow.h \
TrackWorkflow.h \
VideoClipWorkflow.h \
ImageClipWorkflow.h \
StackedBuffer.hpp
StackedBuffer.hpp \
IStackedBuffer.h
SOURCES += AudioClipWorkflow.cpp \
ClipWorkflow.cpp \
MainWorkflow.cpp \
......
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