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

Improvements in setPosition, however this doesn't work right now...

parent 4993f48c
......@@ -44,11 +44,11 @@ ClipWorkflow::~ClipWorkflow()
delete m_stateLock;
}
//void ClipWorkflow::scheduleStop()
//{
// QWriteLocker lock( m_state );
// m_state = Stopping;
//}
void ClipWorkflow::scheduleStop()
{
QWriteLocker lock( m_stateLock );
m_state = StopScheduled;
}
unsigned char* ClipWorkflow::getOutput()
{
......@@ -183,12 +183,13 @@ const Clip* ClipWorkflow::getClip() const
void ClipWorkflow::stop()
{
QWriteLocker lock( m_stateLock );
qDebug() << "ClipWorkflow::stop()";
m_mediaPlayer->stop();
Q_ASSERT( m_mediaPlayer != NULL );
m_mediaPlayer->stop();
m_mediaPlayer = NULL;
setState( Stopped );
//Don't use setState here since m_stateLock is already locked;
m_state = Stopped;
}
void ClipWorkflow::setPosition( float pos )
......
......@@ -48,7 +48,8 @@ class ClipWorkflow : public QObject
Initializing,
Ready,
Rendering,
EndReached
EndReached,
StopScheduled,
};
ClipWorkflow( Clip* clip, QMutex* renderMutex, QMutex* condMutex, QWaitCondition* waitCond );
......@@ -109,7 +110,7 @@ class ClipWorkflow : public QObject
void stop();
void setPosition( float pos );
// void scheduleStop();
void scheduleStop();
private:
static void lock( ClipWorkflow* clipWorkflow, void** pp_ret );
......
......@@ -67,7 +67,7 @@ void MainWorkflow::setPosition( float pos )
if ( m_renderStarted == false )
return ;
qint64 frame = (float)m_length * pos;
m_tracks[0]->setPosition( 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...
......
......@@ -26,12 +26,13 @@
unsigned char* TrackWorkflow::blackOutput = NULL;
TrackWorkflow::TrackWorkflow()
TrackWorkflow::TrackWorkflow() : m_requiredPosition( -1.0f )
{
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 !
......@@ -74,9 +75,22 @@ void TrackWorkflow::startRender()
}
}
void TrackWorkflow::computeLength()
{
if ( m_clips.count() == 0 )
m_length = 0;
QMap<qint64, ClipWorkflow*>::const_iterator it = m_clips.end() - 1;
m_length = (it.key() + it.value()->getClip()->getLength() );
}
qint64 TrackWorkflow::getLength() const
{
return m_length;
}
bool TrackWorkflow::checkNextClip( qint64 currentFrame )
{
QMap<qint64, ClipWorkflow*>::iterator next;
QMap<qint64, ClipWorkflow*>::iterator next;
const QMap<qint64, ClipWorkflow*>::const_iterator end = m_clips.end();
//Picking next clip :
......@@ -113,24 +127,17 @@ bool TrackWorkflow::checkNextClip( qint64 currentFrame )
return true;
}
void TrackWorkflow::computeLength()
{
if ( m_clips.count() == 0 )
m_length = 0;
QMap<qint64, ClipWorkflow*>::const_iterator it = m_clips.end() - 1;
m_length = (it.key() + it.value()->getClip()->getLength() );
}
qint64 TrackWorkflow::getLength() const
{
return m_length;
}
unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
{
unsigned char* ret = TrackWorkflow::blackOutput;
bool clipsRemaining;
QMutexLocker lock( m_requiredPositionLock );
if ( m_requiredPosition >= 0.0f )
{
setPosition( m_requiredPosition );
m_requiredPosition = -1.0f;
}
// qDebug() << "Frame nb" << currentFrame;
clipsRemaining = checkNextClip( currentFrame );
//This is true only before the first render.
......@@ -150,11 +157,12 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
ret = m_current.value()->getOutput();
return ret;
}
else if ( m_current.value()->getState() == ClipWorkflow::EndReached )
else if ( m_current.value()->getState() == ClipWorkflow::EndReached ||
m_current.value()->getState() == ClipWorkflow::StopScheduled )
{
//First, we stop the current ClipWorkflow so that it won't
//enter the lock/unlock cycle anymore.
stopCurrentClipWorkflow();
m_current.value()->stop();
//Then, if there's no remaining clip, end of track is reached.
if ( clipsRemaining == false )
emit endReached();
......@@ -162,12 +170,6 @@ unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
return ret;
}
void TrackWorkflow::stopCurrentClipWorkflow()
{
Q_ASSERT( m_current.value()->isEndReached() );
m_current.value()->stop();
}
void TrackWorkflow::initializeClipWorkflow( ClipWorkflow* cw )
{
//>Launching the initialization
......@@ -177,101 +179,95 @@ void TrackWorkflow::initializeClipWorkflow( ClipWorkflow* cw )
void TrackWorkflow::setPosition( float pos )
{
qDebug() << "I don't think so...";
return ;
qint64 frame = (float)m_length * pos;
QMap<qint64, ClipWorkflow*>::iterator it = m_clips.begin();
const QMap<qint64, ClipWorkflow*>::iterator end = m_clips.end();
QMap<qint64, ClipWorkflow*>::iterator next = end;
if ( frame > m_length )
{
if ( m_current != end )
{
m_current.value()->scheduleStop();
m_current = end;
return ;
}
}
//Locate the new clip workflow
while ( it != end )
{
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;
}
//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 )
{
m_current.value()->scheduleStop();
}
m_current = next;
}
// If the clip found is the current, we just change the position of the
// media player
else if ( it == m_current )
{
// qint64 frame = (float)m_length * pos;
// QMap<qint64, ClipWorkflow*>::iterator it = m_clips.begin();
// const QMap<qint64, ClipWorkflow*>::iterator end = m_clips.end();
// QMap<qint64, ClipWorkflow*>::iterator next = end;
//
// QWriteLocker lock( m_currentLock );
// if ( frame > m_length )
// {
//// qDebug() << "setting position after the end of this track";
// if ( m_current != end )
// {
// stopCurrentClipWorkflow();
// m_current = end;
// return ;
// }
// }
//
// //Locate the new clip workflow
// while ( it != end )
// {
// if ( it.key() <= frame &&
// ( it.key() + it.value()->getClip()->getLength() ) > frame )
// {
//// qDebug() << "Found new current clip workflow";
// 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() )
// {
//// 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";
// }
// // in order to checkNextClip() to work.
// it = end;
// break ;
// }
// ++it;
// }
//
// //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";
// 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";
// //First, we stop the current workflow.
// if ( m_current != end )
// {
// stopCurrentClipWorkflow();
// }
// //We initialize the new workflow
// initializeClipWorkflow( it.value() );
// //And this is now our current clip
// m_current = it;
//// qDebug() << "Switched current clip workflow";
// }
//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();
}
// Else, we found a clip that is not the current one.
else
{
//First, we stop the current workflow.
if ( m_current != end )
{
m_current.value()->scheduleStop();
}
//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 :/
}
}
void TrackWorkflow::requirePositionChanged( float pos )
{
QMutexLocker lock( m_requiredPositionLock );
m_requiredPosition = pos;
}
......@@ -54,6 +54,7 @@ class TrackWorkflow : public QObject
\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;
......@@ -68,7 +69,6 @@ class TrackWorkflow : public QObject
*/
bool checkNextClip( qint64 currentFrame );
void computeLength();
void stopCurrentClipWorkflow();
void initializeClipWorkflow( ClipWorkflow* cw );
private:
......@@ -84,11 +84,6 @@ class TrackWorkflow : public QObject
*/
QMap<qint64, ClipWorkflow*>::iterator m_current;
// /**
// * This mutex is used to lock the current ClipWorkflow iterator.
// */
// QReadWriteLock* m_currentLock;
/**
* This mutex is used for ClipWorkflow synchronisation.
* Using it otherwise might be a (really) bad idea.
......@@ -112,6 +107,12 @@ 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;
public:
void addClip( Clip*, qint64 start );
......
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