Commit 8a94f651 authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen

Fixed other bugs, but big refactoring incomming...

parent 4e6cbbc1
......@@ -32,26 +32,37 @@ ClipWorkflow::ClipWorkflow( Clip::Clip* clip, QMutex* condMutex, QWaitCondition*
m_waitCond( waitCond ),
m_mediaPlayer(NULL),
m_isReady( false ),
m_endReached( false )
m_endReached( false ),
m_stopScheduled( false )
{
m_mutex = new QReadWriteLock();
m_renderCompleteMutex = new QReadWriteLock();
m_buffer = new unsigned char[VIDEOHEIGHT * VIDEOWIDTH * 4];
m_initMutex = new QReadWriteLock();
m_endReachedLock = new QReadWriteLock();
m_stopScheduledMutex = new QReadWriteLock();
}
ClipWorkflow::~ClipWorkflow()
{
delete[] m_buffer;
delete m_mutex;
delete m_renderCompleteMutex;
delete m_initMutex;
delete m_endReachedLock;
delete m_stopScheduledMutex;
}
bool ClipWorkflow::renderComplete() const
{
QReadLocker lock( m_mutex );
return m_renderComplete;
QReadLocker lock( m_renderCompleteMutex );
QReadLocker lock2( m_endReachedLock );
return ( m_renderComplete || ( m_endReached == true) );
}
void ClipWorkflow::scheduleStop()
{
QWriteLocker lock( m_stopScheduledMutex );
m_stopScheduled = true;
}
unsigned char* ClipWorkflow::getOutput()
......@@ -67,7 +78,7 @@ 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 brain !! ahem...
qDebug() << "Locking in ClipWorkflow::lock";
// qDebug() << "Locking in ClipWorkflow::lock";
*pp_ret = clipWorkflow->m_buffer;
}
......@@ -75,34 +86,30 @@ void ClipWorkflow::unlock( ClipWorkflow* clipWorkflow )
{
if ( clipWorkflow->m_isReady == true )
{
QMutexLocker lock5( clipWorkflow->m_condMutex );
{
QReadLocker lock( clipWorkflow->m_endReachedLock );
QWriteLocker lock( clipWorkflow->m_endReachedLock );
if ( clipWorkflow->m_endReached == true )
{
qDebug() << "UnLocking in ClipWorkflow::unlock";
qDebug() << "UnLocking in ClipWorkflow::unlock (endReached == true)";
return ;
}
}
{
QWriteLocker lock2( clipWorkflow->m_mutex );
QReadLocker lock2( clipWorkflow->m_stopScheduledMutex );
if ( clipWorkflow->m_stopScheduled == true )
{
qDebug() << "UnLocking in ClipWorkflow::unlock (stopScheduled == true)";
return ;
}
QWriteLocker lock3( clipWorkflow->m_renderCompleteMutex );
clipWorkflow->m_renderComplete = true;
if ( clipWorkflow->m_mediaPlayer->getPosition() > clipWorkflow->m_clip->getEnd() )
clipWorkflow->m_endReached = true;
}
if ( clipWorkflow->m_mediaPlayer->getPosition() > clipWorkflow->m_clip->getEnd() )
{
QWriteLocker lock2( clipWorkflow->m_endReachedLock );
clipWorkflow->m_endReached = true;
}
QMutexLocker lock( clipWorkflow->m_condMutex );
clipWorkflow->m_waitCond->wait( clipWorkflow->m_condMutex );
}
qDebug() << "UnLocking in ClipWorkflow::unlock";
}
void ClipWorkflow::setRenderComplete()
{
// qDebug() << "UnLocking in ClipWorkflow::unlock";
}
void ClipWorkflow::setVmem()
......@@ -128,6 +135,7 @@ void ClipWorkflow::setVmem()
void ClipWorkflow::initialize( LibVLCpp::MediaPlayer* mediaPlayer )
{
reinitFlags();
setVmem();
m_mediaPlayer = mediaPlayer;
m_mediaPlayer->setMedia( m_clip->getParent()->getVLCMedia() );
......@@ -207,20 +215,11 @@ const Clip* ClipWorkflow::getClip() const
void ClipWorkflow::stop()
{
Q_ASSERT( m_mediaPlayer != NULL );
{
QWriteLocker lock2( m_mutex );
m_renderComplete = false;
}
{
QWriteLocker lock2( m_endReachedLock );
m_endReached = true;
}
{
QWriteLocker lock( m_initMutex);
m_isReady = false;
}
qDebug() << "Calling mediaPlayer::stop()";
m_mediaPlayer->stop();
qDebug() << "Succesfully called mediaPlayer::stop()";
Q_ASSERT( m_mediaPlayer != NULL );
reinitFlags();
m_mediaPlayer = NULL;
qDebug() << "Stoped ClipWorkflow";
}
......@@ -234,3 +233,23 @@ bool ClipWorkflow::isStopped() const
{
return ( m_mediaPlayer == NULL );
}
void ClipWorkflow::reinitFlags()
{
{
QWriteLocker lock2( m_renderCompleteMutex );
m_renderComplete = false;
}
{
QWriteLocker lock2( m_endReachedLock );
m_endReached = false;
}
{
QWriteLocker lock( m_initMutex);
m_isReady = false;
}
{
QWriteLocker lock( m_stopScheduledMutex );
m_stopScheduled = false;
}
}
......@@ -45,6 +45,11 @@ class ClipWorkflow : public QObject
ClipWorkflow( Clip* clip, QMutex* condMutex, QWaitCondition* waitCond );
virtual ~ClipWorkflow();
/**
* Will return true if the render is completed or the end of the clip has been
* reached.
* If the workflow is still rendering, this will return false.
*/
bool renderComplete() const;
unsigned char* getOutput();
void initialize( LibVLCpp::MediaPlayer* mediaPlayer );
......@@ -67,24 +72,31 @@ class ClipWorkflow : public QObject
*/
bool isStopped() const;
void scheduleStop();
private:
static void lock( ClipWorkflow* clipWorkflow, void** pp_ret );
static void unlock( ClipWorkflow* clipWorkflow );
void setVmem();
void setRenderComplete();
void reinitFlags();
private:
Clip* m_clip;
QReadWriteLock* m_mutex;
QReadWriteLock* m_renderCompleteMutex;
bool m_renderComplete;
unsigned char* m_buffer;
QMutex* m_condMutex;
QWaitCondition* m_waitCond;
LibVLCpp::MediaPlayer* m_mediaPlayer;
QReadWriteLock* m_initMutex;
bool m_isReady;
bool m_endReached;
QReadWriteLock* m_endReachedLock;
bool m_endReached;
QReadWriteLock* m_stopScheduledMutex;
bool m_stopScheduled;
public slots:
void pauseAfterPlaybackStarted();
......
......@@ -137,13 +137,13 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
QReadLocker lock( m_currentLock );
// qDebug() << "Frame nb" << currentFrame;
qDebug() << "Frame nb" << currentFrame;
clipsRemaining = checkNextClip( currentFrame );
if ( m_current == m_clips.end() )
{
if ( clipsRemaining == false )
{
// qDebug() << "End Reached";
qDebug() << "End Reached";
emit endReached();
}
// qDebug() << "Stil no clip at this time, going to the next frame";
......@@ -154,6 +154,8 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
{
m_waitCondition->wakeAll();
// We wait until the end of the render. If the clip reach end, this
// will also return true.
while ( m_current.value()->renderComplete() == false )
usleep( 20 );
if ( m_current.value()->isEndReached() == false )
......@@ -172,9 +174,26 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
void TrackWorkflow::stopCurrentClipWorkflow()
{
qDebug() << "About to stopCurrentClipWorkflow()";
//Awaking renderer thread to avoid dead lock
m_current.value()->scheduleStop();
m_waitCondition->wakeAll();
if ( m_current.value()->isStopped() == false )
m_current.value()->stop();
qDebug() << "Stopped stopCurrentClipWorkflow();";
}
void TrackWorkflow::initializeClipWorkflow( ClipWorkflow* cw )
{
//>Launching the initialization
qDebug()<< "Initializing clip workflow (initializeClipWorkflow())";
cw->initialize( m_mediaPlayer );
//And then wait for it to be ready
while ( cw->isReady() == false )
usleep( 20 );
//Once it is, we actually start the render
cw->startRender();
qDebug() << "End of clip workflow reinitialization";
}
void TrackWorkflow::setPosition( float pos )
......@@ -202,7 +221,7 @@ void TrackWorkflow::setPosition( float pos )
if ( it.key() <= frame &&
( it.key() + it.value()->getClip()->getLength() ) > frame )
{
qDebug() << "Found new current clip workflow";
// qDebug() << "Found new current clip workflow";
break;
}
else if ( next == m_clips.end() && it.key() > frame )
......@@ -214,13 +233,13 @@ void TrackWorkflow::setPosition( float pos )
next = it;
if ( next != m_clips.begin() )
{
qDebug() << "Next clip isn't the first one";
// qDebug() << "Next clip isn't the first one";
next = next - 1; //Since the iterator must point to the previous video
}
else
{
next = end;
qDebug() << "Next clip is the first of the track";
// qDebug() << "Next clip is the first of the track";
}
// in order to checkNextClip() to work.
it = end;
......@@ -229,36 +248,45 @@ void TrackWorkflow::setPosition( float pos )
++it;
}
if ( it == m_clips.end() )
//No clip was found :
if ( it == end )
{
//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 )
{
stopCurrentClipWorkflow();
}
m_current = next;
}
// If the clip found is the current, we just change the position of the
// media player
else if ( it == m_current )
{
//The clip may have been stoped (if we reached end but came back at it)
if ( it.value()->isStopped() )
{
initializeClipWorkflow( it.value() );
}
qDebug() << "Changing the position of the current clip";
//We're changing the position of the current clip
it.value()->setPosition( (float)( frame - it.key() ) / (float)(it.value()->getClip()->getLength()) );
//Awaking renderers to avoid them to be stuck inside of the lock...
// qDebug() << "Waking all renderer threads";
m_waitCondition->wakeAll();
}
// Else, we found a clip that is not the current one.
else
{
qDebug() << "Switching to other Clip";
{
// qDebug() << "Switching to other Clip";
//First, we stop the current workflow.
if ( m_current != end )
{
stopCurrentClipWorkflow();
// m_waitCondition->wakeAll();
}
it.value()->initialize( m_mediaPlayer );
while ( it.value()->isReady() == false )
usleep( 20 );
it.value()->startRender();
//We initialize the new workflow
initializeClipWorkflow( it.value() );
//And this is now our current clip
m_current = it;
// qDebug() << "Switched current clip workflow";
}
......
......@@ -69,6 +69,7 @@ class TrackWorkflow : public QObject
bool checkNextClip( qint64 currentFrame );
void computeLength();
void stopCurrentClipWorkflow();
void initializeClipWorkflow( ClipWorkflow* cw );
private:
QMap<qint64, ClipWorkflow*> m_clips;
......
......@@ -76,6 +76,7 @@ void RenderPreviewWidget::unlock( void* )
void RenderPreviewWidget::stopPreview()
{
//This might be called multiple times, but this is due to Qt message loop
m_mediaPlayer->stop();
m_isRendering = false;
qDebug() << "Stopped";
......
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