Commit 7943189e authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen

Corrected random crash when moving a media between tracks

Added a basic media player pool
parent bba5a790
...@@ -32,10 +32,11 @@ Instance::Instance() ...@@ -32,10 +32,11 @@ Instance::Instance()
{ {
char const *argv[] = char const *argv[] =
{ {
//"-vvvvv", // "-vvvvv",
"--no-skip-frames", "--no-skip-frames",
//"--no-audio", //"--no-audio",
//"--plugin-path", VLC_TREE "/modules", //"--plugin-path", VLC_TREE "/modules",
"--disable-screensaver",
"--ignore-config", //Don't use VLC's config files "--ignore-config", //Don't use VLC's config files
}; };
int argc = sizeof( argv ) / sizeof( *argv ); int argc = sizeof( argv ) / sizeof( *argv );
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "vlmc.h" #include "vlmc.h"
#include "ClipWorkflow.h" #include "ClipWorkflow.h"
#include "Pool.hpp"
int g_debugId = 0; int g_debugId = 0;
...@@ -114,34 +115,34 @@ void ClipWorkflow::setVmem() ...@@ -114,34 +115,34 @@ void ClipWorkflow::setVmem()
{ {
char buffer[32]; char buffer[32];
m_clip->getParent()->addVolatileParam( ":no-audio", ":audio" ); m_vlcMedia->addOption( ":no-audio" );
m_clip->getParent()->addVolatileParam( ":vout=vmem", ":vout=''" ); m_vlcMedia->addOption( ":vout=vmem" );
m_clip->getParent()->getVLCMedia()->setDataCtx( this ); m_vlcMedia->setDataCtx( this );
m_clip->getParent()->getVLCMedia()->setLockCallback( reinterpret_cast<LibVLCpp::Media::lockCallback>( &ClipWorkflow::lock ) ); m_vlcMedia->setLockCallback( reinterpret_cast<LibVLCpp::Media::lockCallback>( &ClipWorkflow::lock ) );
m_clip->getParent()->getVLCMedia()->setUnlockCallback( reinterpret_cast<LibVLCpp::Media::unlockCallback>( &ClipWorkflow::unlock ) ); m_vlcMedia->setUnlockCallback( reinterpret_cast<LibVLCpp::Media::unlockCallback>( &ClipWorkflow::unlock ) );
m_clip->getParent()->addConstantParam( ":vmem-chroma=RV24" ); m_vlcMedia->addOption( ":vmem-chroma=RV24" );
sprintf( buffer, ":vmem-width=%i", VIDEOWIDTH ); sprintf( buffer, ":vmem-width=%i", VIDEOWIDTH );
m_clip->getParent()->addConstantParam( buffer ); m_vlcMedia->addOption( buffer );
sprintf( buffer, ":vmem-height=%i", VIDEOHEIGHT ); sprintf( buffer, ":vmem-height=%i", VIDEOHEIGHT );
m_clip->getParent()->addConstantParam( buffer ); m_vlcMedia->addOption( buffer );
sprintf( buffer, "vmem-pitch=%i", VIDEOWIDTH * 3 ); sprintf( buffer, "vmem-pitch=%i", VIDEOWIDTH * 3 );
m_clip->getParent()->addConstantParam( buffer ); m_vlcMedia->addOption( buffer );
} }
void ClipWorkflow::initialize( LibVLCpp::MediaPlayer* mediaPlayer ) void ClipWorkflow::initialize()
{ {
setState( Initializing ); setState( Initializing );
m_vlcMedia = new LibVLCpp::Media( m_clip->getParent()->getFileInfo()->absoluteFilePath() );
setVmem(); setVmem();
m_mediaPlayer = mediaPlayer; m_mediaPlayer = Pool<LibVLCpp::MediaPlayer>::getInstance()->get();
m_mediaPlayer->setMedia( m_clip->getParent()->getVLCMedia() ); m_mediaPlayer->setMedia( m_vlcMedia );
connect( m_mediaPlayer, SIGNAL( playing() ), this, SLOT( setPositionAfterPlayback() ), Qt::DirectConnection ); connect( m_mediaPlayer, SIGNAL( playing() ), this, SLOT( setPositionAfterPlayback() ), Qt::DirectConnection );
connect( m_mediaPlayer, SIGNAL( endReached() ), this, SLOT( clipEndReached() ), Qt::DirectConnection ); connect( m_mediaPlayer, SIGNAL( endReached() ), this, SLOT( clipEndReached() ), Qt::DirectConnection );
m_mediaPlayer->play(); m_mediaPlayer->play();
//m_clip->getParent()->flushVolatileParameters();
} }
void ClipWorkflow::setPositionAfterPlayback() void ClipWorkflow::setPositionAfterPlayback()
...@@ -218,6 +219,7 @@ void ClipWorkflow::stop() ...@@ -218,6 +219,7 @@ void ClipWorkflow::stop()
setState( Stopped ); setState( Stopped );
QMutexLocker lock( m_requiredStateLock ); QMutexLocker lock( m_requiredStateLock );
m_requiredState = ClipWorkflow::None; m_requiredState = ClipWorkflow::None;
delete m_vlcMedia;
} }
else else
qDebug() << "ClipWorkflow has already been stopped"; qDebug() << "ClipWorkflow has already been stopped";
......
...@@ -64,7 +64,7 @@ class ClipWorkflow : public QObject ...@@ -64,7 +64,7 @@ class ClipWorkflow : public QObject
* of the rendering process advancement. * of the rendering process advancement.
*/ */
unsigned char* getOutput(); unsigned char* getOutput();
void initialize( LibVLCpp::MediaPlayer* mediaPlayer ); void initialize();
/** /**
* Return true ONLY if the state is equal to Ready. * Return true ONLY if the state is equal to Ready.
* If the state is Rendering, EndReached or anything else, this will * If the state is Rendering, EndReached or anything else, this will
...@@ -154,6 +154,12 @@ class ClipWorkflow : public QObject ...@@ -154,6 +154,12 @@ class ClipWorkflow : public QObject
private: private:
Clip* m_clip; Clip* m_clip;
/**
* \brief The VLC media used to render
*/
LibVLCpp::Media* m_vlcMedia;
unsigned char* m_buffer; unsigned char* m_buffer;
//unsigned char* m_backBuffer; //unsigned char* m_backBuffer;
/** /**
......
...@@ -30,7 +30,6 @@ TrackWorkflow::TrackWorkflow( unsigned int trackId ) : ...@@ -30,7 +30,6 @@ TrackWorkflow::TrackWorkflow( unsigned int trackId ) :
m_length( 0 ), m_length( 0 ),
m_forceRepositionning( false ) m_forceRepositionning( false )
{ {
m_mediaPlayer = new LibVLCpp::MediaPlayer();
m_forceRepositionningMutex = new QMutex; m_forceRepositionningMutex = new QMutex;
m_clipsLock = new QReadWriteLock; m_clipsLock = new QReadWriteLock;
} }
...@@ -48,7 +47,6 @@ TrackWorkflow::~TrackWorkflow() ...@@ -48,7 +47,6 @@ TrackWorkflow::~TrackWorkflow()
} }
delete m_clipsLock; delete m_clipsLock;
delete m_forceRepositionningMutex; delete m_forceRepositionningMutex;
delete m_mediaPlayer;
} }
void TrackWorkflow::addClip( Clip* clip, qint64 start ) void TrackWorkflow::addClip( Clip* clip, qint64 start )
...@@ -59,6 +57,13 @@ void TrackWorkflow::addClip( Clip* clip, qint64 start ) ...@@ -59,6 +57,13 @@ void TrackWorkflow::addClip( Clip* clip, qint64 start )
computeLength(); computeLength();
} }
void TrackWorkflow::addClip( ClipWorkflow* cw, qint64 start )
{
QWriteLocker lock( m_clipsLock );
m_clips.insert( start, cw );
computeLength();
}
//Must be called from a thread safe method (m_clipsLock locked) //Must be called from a thread safe method (m_clipsLock locked)
void TrackWorkflow::computeLength() void TrackWorkflow::computeLength()
{ {
...@@ -112,7 +117,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF ...@@ -112,7 +117,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF
else if ( cw->getState() == ClipWorkflow::Stopped ) else if ( cw->getState() == ClipWorkflow::Stopped )
{ {
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
cw->initialize( m_mediaPlayer ); cw->initialize( );
cw->startRender(); cw->startRender();
if ( start != currentFrame ) //Clip was not started as its real begining if ( start != currentFrame ) //Clip was not started as its real begining
{ {
...@@ -148,7 +153,7 @@ void TrackWorkflow::preloadClip( ClipWorkflow* cw ) ...@@ -148,7 +153,7 @@ void TrackWorkflow::preloadClip( ClipWorkflow* cw )
if ( cw->getState() == ClipWorkflow::Stopped ) if ( cw->getState() == ClipWorkflow::Stopped )
{ {
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
cw->initialize( m_mediaPlayer ); cw->initialize();
return ; return ;
} }
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
...@@ -190,7 +195,7 @@ void TrackWorkflow::stopClipWorkflow( ClipWorkflow* cw ) ...@@ -190,7 +195,7 @@ void TrackWorkflow::stopClipWorkflow( ClipWorkflow* cw )
} }
else else
{ {
qDebug() << "Unexpected ClipWorkflow::State when stopping :" << cw->getState(); // qDebug() << "Unexpected ClipWorkflow::State when stopping :" << cw->getState();
cw->getStateLock()->unlock(); cw->getStateLock()->unlock();
} }
} }
...@@ -308,8 +313,8 @@ Clip* TrackWorkflow::removeClip( const QUuid& id ) ...@@ -308,8 +313,8 @@ Clip* TrackWorkflow::removeClip( const QUuid& id )
ClipWorkflow* cw = it.value(); ClipWorkflow* cw = it.value();
Clip* clip = cw->getClip(); Clip* clip = cw->getClip();
m_clips.erase( it ); m_clips.erase( it );
stopClipWorkflow( cw ); // stopClipWorkflow( cw );
delete cw; // delete cw;
return clip; return clip;
} }
++it; ++it;
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include <QReadWriteLock> #include <QReadWriteLock>
#include "ClipWorkflow.h" #include "ClipWorkflow.h"
#include "VLCMediaPlayer.h"
//TODO: REMOVE THIS //TODO: REMOVE THIS
#ifndef FPS #ifndef FPS
...@@ -56,6 +55,7 @@ class TrackWorkflow : public QObject ...@@ -56,6 +55,7 @@ class TrackWorkflow : public QObject
void moveClip( const QUuid& id, qint64 startingFrame ); void moveClip( const QUuid& id, qint64 startingFrame );
Clip* removeClip( const QUuid& id ); Clip* removeClip( const QUuid& id );
void addClip( Clip*, qint64 start ); void addClip( Clip*, qint64 start );
void addClip( ClipWorkflow*, qint64 start );
//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;
...@@ -73,12 +73,6 @@ class TrackWorkflow : public QObject ...@@ -73,12 +73,6 @@ class TrackWorkflow : public QObject
QMap<qint64, ClipWorkflow*> m_clips; QMap<qint64, ClipWorkflow*> m_clips;
/**
* This is the MediaPlayer that the clipworkflow
* will be using to process its render.
* It is never used internally.
*/
LibVLCpp::MediaPlayer* m_mediaPlayer;
/** /**
* \brief The track length in frames. * \brief The track length in frames.
*/ */
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "AbstractGraphicsMediaItem.h" #include "AbstractGraphicsMediaItem.h"
AbstractGraphicsMediaItem::AbstractGraphicsMediaItem() : AbstractGraphicsMediaItem::AbstractGraphicsMediaItem() :
m_tracksView( NULL ), oldTrackNumber( -1 ) oldTrackNumber( -1 ), m_tracksView( NULL )
{ {
setCursor( Qt::OpenHandCursor ); setCursor( Qt::OpenHandCursor );
} }
......
...@@ -86,7 +86,6 @@ void RenderPreviewWidget::unlock( void* datas ) ...@@ -86,7 +86,6 @@ void RenderPreviewWidget::unlock( void* datas )
{ {
RenderPreviewWidget* self = reinterpret_cast<RenderPreviewWidget*>( datas ); RenderPreviewWidget* self = reinterpret_cast<RenderPreviewWidget*>( datas );
// qDebug() << "RenderPreviewWidget::unlock() : Frame rendered";
QWriteLocker lock( self->m_framePlayedLock ); QWriteLocker lock( self->m_framePlayedLock );
self->m_framePlayed = true; self->m_framePlayed = true;
} }
......
/*****************************************************************************
* Pool.hpp: Generic object pool
*****************************************************************************
* Copyright (C) 2008-2009 the VLMC team
*
* Authors: Hugo Beauzee-Luyssen <hugo@vlmc.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef POOL_HPP
#define POOL_HPP
#include <QMutex>
#include <QQueue>
#include "Singleton.hpp"
template <typename T>
class Pool : public Singleton< Pool<T> >
{
public:
T* get()
{
if ( m_pool.size() == 0 )
return new T;
return m_pool.dequeue();
}
void release( T* toRelease )
{
m_pool.enqueue( toRelease );
}
private:
Pool()
{
m_mutex = new QMutex;
}
~Pool()
{
while ( m_pool.size() != 0 )
{
T* ptr = m_pool.dequeue();
delete ptr;
}
}
QQueue<T*> m_pool;
QMutex* m_mutex;
friend class Singleton< Pool<T> >;
};
#endif // POOL_HPP
...@@ -87,7 +87,8 @@ HEADERS += src/gui/MainWindow.h \ ...@@ -87,7 +87,8 @@ HEADERS += src/gui/MainWindow.h \
src/API/ModuleManager.h \ src/API/ModuleManager.h \
src/API/vlmc_module_internal.h \ src/API/vlmc_module_internal.h \
src/WorkflowFileRenderer.h \ src/WorkflowFileRenderer.h \
src/vlmc.h src/vlmc.h \
src/tools/Pool.hpp
FORMS += src/gui/ui/MainWindow.ui \ FORMS += src/gui/ui/MainWindow.ui \
src/gui/ui/PreviewWidget.ui \ src/gui/ui/PreviewWidget.ui \
src/gui/ui/Preferences.ui \ src/gui/ui/Preferences.ui \
......
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