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

Added stop button, MainWorkflow deletion, removed crash on exiting.

parent 22a85527
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
<file alias="back" >images/back.png</file> <file alias="back" >images/back.png</file>
<file alias="forward" >images/forward.png</file> <file alias="forward" >images/forward.png</file>
<file alias="up" >images/up.png</file> <file alias="up" >images/up.png</file>
<file>images/next_frame.png</file>
<file>images/previous_frame.png</file>
<file>images/stop.png</file>
</qresource> </qresource>
<qresource prefix="/text" > <qresource prefix="/text" >
<file>AUTHORS</file> <file>AUTHORS</file>
......
...@@ -56,14 +56,9 @@ ClipWorkflow::~ClipWorkflow() ...@@ -56,14 +56,9 @@ ClipWorkflow::~ClipWorkflow()
unsigned char* ClipWorkflow::getOutput() unsigned char* ClipWorkflow::getOutput()
{ {
// qDebug() << "Getting output";
QReadLocker lock( m_backBufferLock ); QReadLocker lock( m_backBufferLock );
if ( m_usingBackBuffer == true ) if ( m_usingBackBuffer == true )
{
// qDebug() << "Returning frontbuffer";
return m_buffer; return m_buffer;
}
// qDebug() << "Returning backbuffer";
return m_backBuffer; return m_backBuffer;
} }
...@@ -80,24 +75,20 @@ void ClipWorkflow::checkStateChange() ...@@ -80,24 +75,20 @@ void ClipWorkflow::checkStateChange()
void ClipWorkflow::lock( ClipWorkflow* cw, void** pp_ret ) void ClipWorkflow::lock( ClipWorkflow* cw, void** pp_ret )
{ {
// qDebug() << "Locking in ClipWorkflow::lock";
QReadLocker lock( cw->m_backBufferLock ); QReadLocker lock( cw->m_backBufferLock );
if ( cw->m_usingBackBuffer ) if ( cw->m_usingBackBuffer )
{ {
// qDebug() << "Using backbuffer";
*pp_ret = cw->m_backBuffer; *pp_ret = cw->m_backBuffer;
} }
else else
{ {
// qDebug() << "Using frontbuffer";
*pp_ret = cw->m_buffer; *pp_ret = cw->m_buffer;
} }
} }
void ClipWorkflow::unlock( ClipWorkflow* cw ) void ClipWorkflow::unlock( ClipWorkflow* cw )
{ {
// qDebug() << "UnLocking in ClipWorkflow::unlock";
cw->m_stateLock->lockForWrite(); cw->m_stateLock->lockForWrite();
if ( cw->m_state == Rendering ) if ( cw->m_state == Rendering )
...@@ -105,12 +96,10 @@ void ClipWorkflow::unlock( ClipWorkflow* cw ) ...@@ -105,12 +96,10 @@ void ClipWorkflow::unlock( ClipWorkflow* cw )
cw->m_state = Sleeping; cw->m_state = Sleeping;
cw->m_stateLock->unlock(); cw->m_stateLock->unlock();
// qDebug() << "Sleeping....";
QMutexLocker lock( cw->m_condMutex ); QMutexLocker lock( cw->m_condMutex );
cw->m_waitCond->wait( cw->m_condMutex ); cw->m_waitCond->wait( cw->m_condMutex );
cw->m_stateLock->lockForWrite(); cw->m_stateLock->lockForWrite();
cw->m_state = Rendering; cw->m_state = Rendering;
// qDebug() << "Waiking";
{ {
QWriteLocker lock2( cw->m_backBufferLock ); QWriteLocker lock2( cw->m_backBufferLock );
cw->m_usingBackBuffer = !cw->m_usingBackBuffer; cw->m_usingBackBuffer = !cw->m_usingBackBuffer;
......
...@@ -27,13 +27,13 @@ ...@@ -27,13 +27,13 @@
unsigned char* MainWorkflow::blackOutput = NULL; unsigned char* MainWorkflow::blackOutput = NULL;
MainWorkflow::MainWorkflow( int trackCount ) : MainWorkflow::MainWorkflow( QObject* parent, int trackCount ) :
QObject( parent ),
m_trackCount( trackCount ), m_trackCount( trackCount ),
m_renderStarted( false ) m_renderStarted( false )
{ {
if ( MainWorkflow::blackOutput == NULL ) if ( MainWorkflow::blackOutput == NULL )
{ {
//TODO: this ain't free !
MainWorkflow::blackOutput = new unsigned char[VIDEOHEIGHT * VIDEOWIDTH * 3]; MainWorkflow::blackOutput = new unsigned char[VIDEOHEIGHT * VIDEOWIDTH * 3];
memset( MainWorkflow::blackOutput, 0, VIDEOHEIGHT * VIDEOWIDTH * 3 ); memset( MainWorkflow::blackOutput, 0, VIDEOHEIGHT * VIDEOWIDTH * 3 );
} }
...@@ -44,6 +44,18 @@ MainWorkflow::MainWorkflow( int trackCount ) : ...@@ -44,6 +44,18 @@ MainWorkflow::MainWorkflow( int trackCount ) :
m_tracks[i].setPtr( new TrackWorkflow( i ) ); m_tracks[i].setPtr( new TrackWorkflow( i ) );
connect( m_tracks[i], SIGNAL( trackEndReached( unsigned int ) ), this, SLOT( trackEndReached(unsigned int) ) ); connect( m_tracks[i], SIGNAL( trackEndReached( unsigned int ) ), this, SLOT( trackEndReached(unsigned int) ) );
} }
m_renderStartedLock = new QReadWriteLock;
}
MainWorkflow::~MainWorkflow()
{
qDebug() << "MainWorkflow::~MainWorkflow()";
delete m_renderStartedLock;
for (unsigned int i = 0; i < m_trackCount; ++i)
delete m_tracks[i];
delete[] m_tracks;
//FIXME: if we have two main workflows (which is very unlikely) this will crash...
delete[] blackOutput;
} }
void MainWorkflow::addClip( Clip* clip, unsigned int trackId, qint64 start ) void MainWorkflow::addClip( Clip* clip, unsigned int trackId, qint64 start )
...@@ -78,24 +90,31 @@ void MainWorkflow::startRender() ...@@ -78,24 +90,31 @@ void MainWorkflow::startRender()
unsigned char* MainWorkflow::getOutput() unsigned char* MainWorkflow::getOutput()
{ {
unsigned char* ret; QReadLocker lock( m_renderStartedLock );
for ( unsigned int i = 0; i < m_trackCount; ++i ) if ( m_renderStarted == true )
{ {
if ( m_tracks[i].activated() == false ) unsigned char* ret;
continue ;
if ( ( ret = m_tracks[i]->getOutput( m_currentFrame ) ) != NULL ) for ( unsigned int i = 0; i < m_trackCount; ++i )
{ {
break ; if ( m_tracks[i].activated() == false )
continue ;
if ( ( ret = m_tracks[i]->getOutput( m_currentFrame ) ) != NULL )
{
break ;
}
} }
} if ( ret == NULL )
if ( ret == NULL ) ret = MainWorkflow::blackOutput;
ret = MainWorkflow::blackOutput;
++m_currentFrame; ++m_currentFrame;
emit frameChanged( m_currentFrame ); emit frameChanged( m_currentFrame );
emit positionChanged( (float)m_currentFrame / (float)m_length ); emit positionChanged( (float)m_currentFrame / (float)m_length );
return ret; return ret;
}
else
return MainWorkflow::blackOutput;
} }
void MainWorkflow::setPosition( float pos ) void MainWorkflow::setPosition( float pos )
...@@ -137,3 +156,19 @@ unsigned int MainWorkflow::getTrackCount() const ...@@ -137,3 +156,19 @@ unsigned int MainWorkflow::getTrackCount() const
{ {
return m_trackCount; return m_trackCount;
} }
void MainWorkflow::stop()
{
QWriteLocker lock( m_renderStartedLock );
m_renderStarted = false;
for (unsigned int i = 0; i < m_trackCount; ++i)
{
//FIXME: After debugging period, this should'nt be necessary --
m_tracks[i].activate();
//--------
m_tracks[i]->stop();
}
m_currentFrame = 0;
emit frameChanged( 0 );
}
...@@ -28,13 +28,15 @@ ...@@ -28,13 +28,15 @@
#include "tools/Toggleable.hpp" #include "tools/Toggleable.hpp"
#include "TrackWorkflow.h" #include "TrackWorkflow.h"
#include <QReadWriteLock>
class MainWorkflow : public QObject class MainWorkflow : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
MainWorkflow( int trackCount ); MainWorkflow( QObject* parent, int trackCount );
~MainWorkflow();
void addClip( Clip* clip, unsigned int trackId, qint64 start ); void addClip( Clip* clip, unsigned int trackId, qint64 start );
void startRender(); void startRender();
...@@ -57,6 +59,11 @@ class MainWorkflow : public QObject ...@@ -57,6 +59,11 @@ class MainWorkflow : public QObject
*/ */
unsigned int getTrackCount() const; unsigned int getTrackCount() const;
/**
* Stop the workflow (including sub track workflows and clip workflows)
*/
void stop();
static unsigned char* blackOutput; static unsigned char* blackOutput;
private: private:
...@@ -68,6 +75,7 @@ class MainWorkflow : public QObject ...@@ -68,6 +75,7 @@ class MainWorkflow : public QObject
* This boolean describe is a render has been started * This boolean describe is a render has been started
*/ */
bool m_renderStarted; bool m_renderStarted;
QReadWriteLock* m_renderStartedLock;
private slots: private slots:
void trackEndReached( unsigned int trackId ); void trackEndReached( unsigned int trackId );
......
...@@ -88,9 +88,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF ...@@ -88,9 +88,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF
cw->setPosition( pos ); cw->setPosition( pos );
} }
ret = cw->getOutput(); ret = cw->getOutput();
// qDebug() << "Waking renderer";
cw->wake(); cw->wake();
// qDebug() << "Awaken renderer";
//FIXME: sometimes, the renderer isn't awake soon enough, and we can //FIXME: sometimes, the renderer isn't awake soon enough, and we can
//pass though this function many times before the frame is actually rendered. //pass though this function many times before the frame is actually rendered.
} }
...@@ -190,6 +188,18 @@ bool TrackWorkflow::checkEnd( qint64 currentFrame ) const ...@@ -190,6 +188,18 @@ bool TrackWorkflow::checkEnd( qint64 currentFrame ) const
return ( it.value()->getClip()->getLength() + it.key() < currentFrame ); return ( it.value()->getClip()->getLength() + it.key() < currentFrame );
} }
void TrackWorkflow::stop()
{
QMap<qint64, ClipWorkflow*>::iterator it = m_clips.begin();
QMap<qint64, ClipWorkflow*>::iterator end = m_clips.end();
while ( it != end )
{
stopClipWorkflow( it.value() );
++it;
}
}
unsigned char* TrackWorkflow::getOutput( qint64 currentFrame ) unsigned char* TrackWorkflow::getOutput( qint64 currentFrame )
{ {
unsigned char* ret = NULL; unsigned char* ret = NULL;
......
...@@ -48,6 +48,7 @@ class TrackWorkflow : public QObject ...@@ -48,6 +48,7 @@ class TrackWorkflow : public QObject
unsigned char* getOutput( qint64 currentFrame ); unsigned char* getOutput( qint64 currentFrame );
qint64 getLength() const; qint64 getLength() const;
void stop();
//FIXME: this won't be reliable as soon as we change the fps from the configuration //FIXME: this won't be reliable as soon as we change the fps from the configuration
static const unsigned int nbFrameBeforePreload = 60; static const unsigned int nbFrameBeforePreload = 60;
......
...@@ -60,6 +60,15 @@ void ClipPreviewWidget::setPosition( float newPos ) ...@@ -60,6 +60,15 @@ void ClipPreviewWidget::setPosition( float newPos )
m_mediaPlayer->setPosition( newPos ); m_mediaPlayer->setPosition( newPos );
} }
void ClipPreviewWidget::stop()
{
if ( m_clipLoaded == true && m_videoStopped == false )
{
m_videoStopped = true;
m_mediaPlayer->stop();
}
}
void ClipPreviewWidget::togglePlayPause( bool forcePause ) void ClipPreviewWidget::togglePlayPause( bool forcePause )
{ {
if ( m_clipLoaded == false) if ( m_clipLoaded == false)
......
...@@ -43,6 +43,7 @@ public: ...@@ -43,6 +43,7 @@ public:
virtual void startPreview( Media* media ); virtual void startPreview( Media* media );
virtual void setPosition( float newPos ); virtual void setPosition( float newPos );
virtual void togglePlayPause( bool forcePause ); virtual void togglePlayPause( bool forcePause );
virtual void stop();
private: private:
bool m_clipLoaded; bool m_clipLoaded;
......
...@@ -47,6 +47,8 @@ public: ...@@ -47,6 +47,8 @@ public:
virtual void startPreview( Media* media ) = 0; virtual void startPreview( Media* media ) = 0;
virtual void setPosition( float newPos ) = 0; virtual void setPosition( float newPos ) = 0;
virtual void togglePlayPause( bool forcePause = false ) = 0;
virtual void stop() = 0;
protected: protected:
LibVLCpp::MediaPlayer* m_mediaPlayer; LibVLCpp::MediaPlayer* m_mediaPlayer;
...@@ -57,9 +59,6 @@ public slots: ...@@ -57,9 +59,6 @@ public slots:
virtual void __videoPlaying() = 0; virtual void __videoPlaying() = 0;
virtual void __endReached() = 0; virtual void __endReached() = 0;
//For meta invoking
virtual void togglePlayPause( bool forcePause = false ) = 0;
signals: signals:
void stopped(); void stopped();
void paused(); void paused();
......
#include <QtDebug>
#include "GraphicsCursorItem.h" #include "GraphicsCursorItem.h"
GraphicsCursorItem::GraphicsCursorItem( int height, const QPen& pen ) GraphicsCursorItem::GraphicsCursorItem( int height, const QPen& pen )
......
...@@ -137,7 +137,8 @@ void PreviewWidget::dropEvent( QDropEvent* event ) ...@@ -137,7 +137,8 @@ void PreviewWidget::dropEvent( QDropEvent* event )
void PreviewWidget::positionChanged( float newPos ) void PreviewWidget::positionChanged( float newPos )
{ {
m_ui->seekSlider->setValue( (int)( newPos * 1000.0 ) ); if ( m_previewStopped == false )
m_ui->seekSlider->setValue( (int)( newPos * 1000.0 ) );
} }
...@@ -174,7 +175,16 @@ void PreviewWidget::seekSliderReleased() ...@@ -174,7 +175,16 @@ void PreviewWidget::seekSliderReleased()
this, SLOT( positionChanged( float ) ) ); this, SLOT( positionChanged( float ) ) );
} }
void PreviewWidget::on_pushButtonPlay_clicked() void PreviewWidget::on_pushButtonStop_clicked()
{
if ( m_previewStopped == false )
{
m_previewStopped = true;
m_currentPreviewRenderer->stop();
}
}
void PreviewWidget::on_pushButtonPlay_clicked()
{ {
if ( m_previewStopped == true ) if ( m_previewStopped == true )
m_previewStopped = false; m_previewStopped = false;
......
...@@ -66,6 +66,7 @@ protected: ...@@ -66,6 +66,7 @@ protected:
virtual void dropEvent( QDropEvent* event ); virtual void dropEvent( QDropEvent* event );
private slots: private slots:
void on_pushButtonPlay_clicked(); void on_pushButtonPlay_clicked();
void on_pushButtonStop_clicked();
void positionChanged( float ); void positionChanged( float );
void seekSliderPressed(); void seekSliderPressed();
void seekSliderMoved( int value ); void seekSliderMoved( int value );
......
...@@ -51,8 +51,9 @@ RenderPreviewWidget::RenderPreviewWidget( MainWorkflow* mainWorkflow, QWidget* r ...@@ -51,8 +51,9 @@ RenderPreviewWidget::RenderPreviewWidget( MainWorkflow* mainWorkflow, QWidget* r
m_media->addOption( buffer ); m_media->addOption( buffer );
m_mediaPlayer->setMedia( m_media ); m_mediaPlayer->setMedia( m_media );
connect( m_mediaPlayer, SIGNAL( playing() ), this, SLOT( __videoPlaying() ) ); connect( m_mediaPlayer, SIGNAL( playing() ), this, SLOT( __videoPlaying() ) );
connect( m_mediaPlayer, SIGNAL( paused() ), this, SLOT( __videoPaused() ) ); connect( m_mediaPlayer, SIGNAL( paused() ), this, SLOT( __videoPaused() ) );
connect( m_mediaPlayer, SIGNAL( stopped() ), this, SLOT( __videoStopped() ) );
connect( m_mainWorkflow, SIGNAL( mainWorkflowEndReached() ), this, SLOT( __endReached() ) ); connect( m_mainWorkflow, SIGNAL( mainWorkflowEndReached() ), this, SLOT( __endReached() ) );
connect( m_mainWorkflow, SIGNAL( positionChanged( float ) ), this, SLOT( __positionChanged( float ) ) ); connect( m_mainWorkflow, SIGNAL( positionChanged( float ) ), this, SLOT( __positionChanged( float ) ) );
} }
...@@ -65,7 +66,6 @@ RenderPreviewWidget::~RenderPreviewWidget() ...@@ -65,7 +66,6 @@ RenderPreviewWidget::~RenderPreviewWidget()
void* RenderPreviewWidget::lock( void* datas ) void* RenderPreviewWidget::lock( void* datas )
{ {
// qDebug() << "Locking invmem";
RenderPreviewWidget* self = reinterpret_cast<RenderPreviewWidget*>( datas); RenderPreviewWidget* self = reinterpret_cast<RenderPreviewWidget*>( datas);
void* ret = self->m_mainWorkflow->getOutput(); void* ret = self->m_mainWorkflow->getOutput();
return ret; return ret;
...@@ -73,7 +73,6 @@ void* RenderPreviewWidget::lock( void* datas ) ...@@ -73,7 +73,6 @@ void* RenderPreviewWidget::lock( void* datas )
void RenderPreviewWidget::unlock( void* ) void RenderPreviewWidget::unlock( void* )
{ {
// qDebug() << "Unlocking invmem";
} }
void RenderPreviewWidget::stopPreview() void RenderPreviewWidget::stopPreview()
...@@ -114,13 +113,19 @@ void RenderPreviewWidget::togglePlayPause( bool forcePause ) ...@@ -114,13 +113,19 @@ void RenderPreviewWidget::togglePlayPause( bool forcePause )
} }
} }
void RenderPreviewWidget::stop()
{
m_isRendering = false;
m_mainWorkflow->stop();
m_mediaPlayer->stop();
}
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
/////SLOTS : /////SLOTS :
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
void RenderPreviewWidget::__endReached() void RenderPreviewWidget::__endReached()
{ {
// qDebug() << "Stopping preview";
stopPreview(); stopPreview();
emit endReached(); emit endReached();
} }
...@@ -144,3 +149,8 @@ void RenderPreviewWidget::__videoPlaying() ...@@ -144,3 +149,8 @@ void RenderPreviewWidget::__videoPlaying()
{ {
emit playing(); emit playing();
} }
void RenderPreviewWidget::__videoStopped()
{
emit endReached();
}
...@@ -50,6 +50,7 @@ class RenderPreviewWidget : public GenericPreviewWidget ...@@ -50,6 +50,7 @@ class RenderPreviewWidget : public GenericPreviewWidget
*/ */
virtual void setPosition( float newPos ); virtual void setPosition( float newPos );
virtual void togglePlayPause( bool forcePause ); virtual void togglePlayPause( bool forcePause );
virtual void stop();
static void* lock( void* datas ); static void* lock( void* datas );
static void unlock( void* datas ); static void unlock( void* datas );
...@@ -60,11 +61,12 @@ class RenderPreviewWidget : public GenericPreviewWidget ...@@ -60,11 +61,12 @@ class RenderPreviewWidget : public GenericPreviewWidget
bool m_isRendering; bool m_isRendering;
public slots: public slots:
void __positionChanged(); void __positionChanged();
void __positionChanged( float pos ); void __positionChanged( float pos );
void __videoPaused(); void __videoPaused();
void __videoPlaying(); void __videoStopped();
void __endReached(); void __videoPlaying();
void __endReached();
}; };
#endif // RENDERPREVIEWWIDGET_H #endif // RENDERPREVIEWWIDGET_H
...@@ -32,7 +32,7 @@ Timeline::Timeline( QWidget *parent ) : ...@@ -32,7 +32,7 @@ Timeline::Timeline( QWidget *parent ) :
{ {
m_ui.setupUi( this ); m_ui.setupUi( this );
m_mainWorkflow = new MainWorkflow( 5 ); m_mainWorkflow = new MainWorkflow( this, 5 );
m_tracksScene = new TracksScene( this ); m_tracksScene = new TracksScene( this );
m_tracksView = new TracksView( m_tracksScene, m_mainWorkflow, m_ui.tracksFrame ); m_tracksView = new TracksView( m_tracksScene, m_mainWorkflow, m_ui.tracksFrame );
......
...@@ -115,6 +115,29 @@ ...@@ -115,6 +115,29 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="pushButtonStop">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../ressources.qrc">
<normaloff>:/images/images/stop.png</normaloff>:/images/images/stop.png</iconset>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
......
...@@ -46,10 +46,8 @@ class Toggleable ...@@ -46,10 +46,8 @@ class Toggleable
} }
T operator->() T operator->()
{ {
if ( m_activated == true ) Q_ASSERT_X( m_activated == true, "Toggleable<T>::operator->", "Pointer is deactivated" );
return m_ptr; return m_ptr;
qDebug() << "using operator -> on a disabled value !";
return NULL;
} }
bool activated() const bool activated() const
{ {
......
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