Commit 6a9bc6c9 authored by luyikei's avatar luyikei

Media, Clip, Renderer: Use Producer and Consumer to handle

parent a8a2ab30
......@@ -92,7 +92,6 @@ SET(VLMC_SRCS
Main/main.cpp
Media/Clip.cpp
Media/Media.cpp
Metadata/MetaDataManager.cpp
Project/Project.cpp
Project/Workspace.cpp
Project/WorkspaceWorker.cpp
......@@ -220,7 +219,6 @@ ELSE(NOT WITH_GUI)
Gui/wizard/firstlaunch/FirstLaunchPage.cpp
Gui/wizard/firstlaunch/WorkspaceLocation.cpp
Gui/wizard/firstlaunch/Done.cpp
Media/Transcoder.cpp #Won't be needed without the import, so let's put it in GUI list
)
SET(VLMC_UIS
......
......@@ -29,10 +29,9 @@
#include "Project/Project.h"
#include "Media/Clip.h"
#include "Renderer/ClipRenderer.h"
#include "Backend/VLC/VLCSource.h"
#include "Backend/IProducer.h"
#include "Library/Library.h"
#include "Media/Media.h"
#include "Metadata/MetaDataManager.h"
#include "Settings/Settings.h"
#include "TagWidget.h"
#include "Media/Transcoder.h"
......@@ -107,9 +106,6 @@ ImportController::ImportController(QWidget *parent) :
this, SLOT( clipSelection( Clip* ) ) );
connect( m_mediaListView, SIGNAL( clipRemoved( const QUuid& ) ),
m_clipRenderer, SLOT( clipUnloaded( const QUuid& ) ) );
connect( MetaDataManager::instance(), SIGNAL( failedToCompute( Media* ) ),
this, SLOT( failedToLoad( Media* ) ) );
}
ImportController::~ImportController()
......@@ -236,7 +232,7 @@ ImportController::accept()
collapseAllButCurrentPath();
foreach ( Clip* clip, m_temporaryMedias->clips().values() )
{
if ( clip->media()->source()->length() == 0 )
if ( clip->media()->producer()->length() == 0 )
invalidMedias = true;
Core::instance()->library()->addClip( clip );
}
......@@ -258,11 +254,11 @@ ImportController::handleInvalidMedias()
{
foreach ( Clip* clip, m_temporaryMedias->clips().values() )
{
if ( clip->media()->source()->length() == 0 )
{
if ( clip->media()->producer()->length() == 0 )
{/* TODO
Transcoder *transcoder = new Transcoder( clip->media() );
connect( transcoder, SIGNAL( done() ), transcoder, SLOT( deleteLater() ) );
transcoder->transcodeToPs();
transcoder->transcodeToPs();*/
}
}
}
......
......@@ -31,7 +31,6 @@
#include "Backend/VLC/VLCSource.h"
#include "Library/Library.h"
#include "Media/Media.h"
#include "Metadata/MetaDataManager.h"
#include "Workflow/MainWorkflow.h"
#include "Project/Workspace.h"
......@@ -65,12 +64,6 @@ MediaCellView::MediaCellView( Clip* clip, QWidget *parent ) :
m_ui->clipCountLabel->hide();
m_ui->arrow->hide();
}
if ( clip->media()->source()->isParsed() == false )
{
m_ui->thumbnail->setEnabled( false );
connect( MetaDataManager::instance(), SIGNAL( startingComputing( const Media* )),
this, SLOT( metadataComputingStarted( const Media* ) ), Qt::DirectConnection );
}
connect( clip->media(), SIGNAL( metaDataComputed() ),
this, SLOT( metadataUpdated() ) );
// Snapshot generation will generate a QPixmap, which has to be done on GUI thread
......@@ -94,15 +87,12 @@ MediaCellView::metadataComputingStarted( const Media *media )
return ;
//Disable the delete button to avoid deleting the media while metadata are computed.
m_ui->delLabel->setEnabled( false );
//We don't need this event anymore now.
disconnect( MetaDataManager::instance(), SIGNAL( startingComputing( const Media* )),
this, SLOT( metadataComputingStarted( const Media* ) ) );
}
void
MediaCellView::metadataUpdated()
{
setLength( m_clip->media()->source()->length() );
setLength( m_clip->media()->producer()->length() );
m_ui->thumbnail->setEnabled( true );
//If the media is a Video or an Image, we must wait for the snapshot to be computer
//before allowing deletion.
......
......@@ -47,20 +47,20 @@ ClipMetadataDisplayer::metadataUpdated()
QTime duration;
duration = duration.addSecs( m_watchedClip->lengthSecond() );
const auto* source = m_watchedMedia->source();
const auto* producer = m_watchedMedia->producer();
updateInterface();
//Duration
m_ui->durationValueLabel->setText( duration.toString( "hh:mm:ss" ) );
//Filename || title
m_ui->nameValueLabel->setText( m_watchedMedia->fileInfo()->fileName() );
//Resolution
m_ui->resolutionValueLabel->setText( QString::number( source->width() )
+ " x " + QString::number( source->height() ) );
m_ui->resolutionValueLabel->setText( QString::number( producer->width() )
+ " x " + QString::number( producer->height() ) );
//FPS
m_ui->fpsValueLabel->setText( QString::number( source->fps() ) );
m_ui->fpsValueLabel->setText( QString::number( producer->fps() ) );
//nb tracks :
m_ui->nbVideoTracksValueLabel->setText( QString::number( source->nbVideoTracks() ) );
m_ui->nbAudioTracksValueLabel->setText( QString::number( source->nbAudioTracks() ) );
m_ui->nbVideoTracksValueLabel->setText( QString::number( producer->nbVideoTracks() ) );
m_ui->nbAudioTracksValueLabel->setText( QString::number( producer->nbAudioTracks() ) );
//Path:
m_ui->pathValueLabel->setText( m_watchedMedia->fileInfo()->absoluteFilePath() );
}
......@@ -100,19 +100,13 @@ ClipMetadataDisplayer::setWatchedClip( const Clip *clip )
m_watchedClip = clip;
m_watchedMedia = clip->media();
connect( m_watchedClip, SIGNAL( unloaded( Clip* ) ), this, SLOT( clipDestroyed( Clip* ) ) );
if ( m_watchedMedia->source()->isParsed() == true )
metadataUpdated();
else
{
connect( m_watchedMedia, SIGNAL( metaDataComputed() ),
this, SLOT( metadataUpdated() ) );
}
metadataUpdated();
}
void
ClipMetadataDisplayer::updateInterface()
{
bool visible = m_watchedMedia->source()->hasVideo();
bool visible = m_watchedMedia->producer()->hasVideo();
m_ui->fpsLabel->setVisible( visible );
m_ui->fpsValueLabel->setVisible( visible );
m_ui->resolutionLabel->setVisible( visible );
......
......@@ -25,6 +25,7 @@
#include <QPolygon>
#include <QBrush>
#include "PreviewRuler.h"
#include "Tools/RendererEventWatcher.h"
PreviewRuler::PreviewRuler( QWidget* parent ) :
QWidget( parent ),
......@@ -44,8 +45,8 @@ PreviewRuler::setRenderer( AbstractRenderer* renderer )
m_renderer->disconnect( this );
m_renderer = renderer;
connect( m_renderer, SIGNAL( frameChanged( qint64, Vlmc::FrameChangedReason ) ),
this, SLOT( updateTimecode( qint64 ) ) );
connect( m_renderer->eventWatcher(), &RendererEventWatcher::positionChanged,
this, &PreviewRuler::updateTimecode );
connect( m_renderer->eventWatcher(), SIGNAL( stopped() ),
this, SLOT( clear() ) );
}
......
......@@ -25,6 +25,7 @@
#include "Media/Clip.h"
#include "Renderer/ClipRenderer.h"
#include "Backend/MLT/MLTConsumer.h"
#include "PreviewWidget.h"
#include "PreviewRuler.h"
#include "RenderWidget.h"
......@@ -64,13 +65,16 @@ PreviewWidget::~PreviewWidget()
}
void
PreviewWidget::setRenderer(AbstractRenderer *renderer)
PreviewWidget::setRenderer( AbstractRenderer* renderer )
{
delete m_renderer;
m_renderer = renderer;
// Give the renderer to the ruler
m_ui->rulerWidget->setRenderer( m_renderer );
auto consumer = new Backend::MLT::MLTSdlConsumer;
consumer->setWindowId( m_ui->renderWidget->id() );
m_renderer->setConsumer( std::unique_ptr<Backend::IConsumer>( consumer ) );
#if defined ( Q_OS_MAC )
/* Releases the NSView in the RenderWidget*/
......
......@@ -37,7 +37,7 @@
GraphicsAudioItem::GraphicsAudioItem( Clip* clip ) :
AbstractGraphicsMediaItem( clip )
{
QTime length = QTime().addMSecs( clip->media()->source()->length() );
QTime length = QTime().addMSecs( clip->media()->producer()->length() );
QString tooltip( tr( "<p style='white-space:pre'><b>Name:</b> %1"
"<br><b>Length:</b> %2" )
.arg( clip->media()->fileName() )
......
......@@ -36,7 +36,7 @@
GraphicsMovieItem::GraphicsMovieItem( Clip* clip ) :
AbstractGraphicsMediaItem( clip )
{
QTime length = QTime().addMSecs( clip->media()->source()->length() );
QTime length = QTime().addMSecs( clip->media()->producer()->length() );
QString tooltip( tr( "<p style='white-space:pre'><b>Name:</b> %1"
"<br><b>Length:</b> %2" )
.arg( clip->media()->fileName() )
......
......@@ -376,8 +376,8 @@ TracksView::clipDragEnterEvent( QDragEnterEvent *event )
Clip *clip = Core::instance()->library()->clip( fullId );
if ( clip == nullptr )
return;
bool hasVideo = clip->media()->source()->hasVideo();
bool hasAudio = clip->media()->source()->hasAudio();
bool hasVideo = clip->media()->producer()->hasVideo();
bool hasAudio = clip->media()->producer()->hasAudio();
if ( hasAudio == false && hasVideo == false )
return ;
......
......@@ -30,7 +30,6 @@
#include "Library.h"
#include "Media/Clip.h"
#include "Media/Media.h"
#include "Metadata/MetaDataManager.h"
#include "Project/Project.h"
#include "Settings/Settings.h"
#include "Tools/VlmcDebug.h"
......
......@@ -27,7 +27,6 @@
#include "MediaContainer.h"
#include "Media/Clip.h"
#include "Media/Media.h"
#include "Metadata/MetaDataManager.h"
#include "Settings/Settings.h"
#include "Tools/VlmcDebug.h"
#include "Project/Workspace.h"
......
......@@ -4,6 +4,7 @@
* Copyright (C) 2008-2016 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
* Yikei Lu <luyikei.qmltu@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -26,54 +27,49 @@
#include "Clip.h"
#include "Main/Core.h"
#include "Backend/VLC/VLCSource.h"
#include "Backend/MLT/MLTProducer.h"
#include "Library/Library.h"
#include "Media/Media.h"
#include "Project/Workspace.h"
#include "EffectsEngine/EffectHelper.h"
#include <QVariant>
const int Clip::DefaultFPS = 30;
Clip::Clip( Media *media, qint64 begin /*= 0*/, qint64 end /*= -1*/, const QString& uuid /*= QString()*/ ) :
Clip::Clip( Media *media, qint64 begin /*= 0*/, qint64 end /*= Backend::IProducer::EndOfMedia */, const QString& uuid /*= QString()*/ ) :
Workflow::Helper( begin, end, uuid ),
m_media( media ),
m_producer( m_media->producer()->cut( begin, end ) ),
m_parent( media->baseClip() ),
m_clipWorkflow( nullptr )
{
int64_t nbSourceFrames = media->source()->nbFrames();
if ( end == -1 )
m_end = nbSourceFrames;
m_beginPosition = (float)begin / (float)nbSourceFrames;
m_endPosition = (float)end / (float)nbSourceFrames;
m_childs = new MediaContainer( this );
m_rootClip = media->baseClip();
computeLength();
connect( media, &Media::metaDataComputed,
this, &Clip::mediaMetadataUpdated );
}
Clip::Clip( Clip *parent, qint64 begin /*= -1*/, qint64 end /*= -1*/,
Clip::Clip( Clip *parent, qint64 begin /*= -1*/, qint64 end /*= -2*/,
const QString &uuid /*= QString()*/ ) :
Workflow::Helper( begin, end, uuid ),
m_media( parent->media() ),
m_rootClip( parent->rootClip() ),
m_parent( parent )
{
int64_t nbSourceFrames = parent->media()->source()->nbFrames();
if ( begin < 0 )
m_begin = parent->m_begin;
if ( end < 0 )
m_end = parent->m_end;
m_beginPosition = (float)begin / (float)nbSourceFrames;
m_endPosition = (float)end / (float)nbSourceFrames;
m_childs = new MediaContainer( this );
computeLength();
if ( begin == -1 )
begin = parent->begin();
else
begin = parent->begin() + begin;
if ( end == Backend::IProducer::EndOfParent )
end = parent->end();
else
end = parent->begin() + end;
m_producer = parent->producer()->cut( begin, end );
}
Clip::~Clip()
{
emit unloaded( this );
delete m_childs;
delete m_producer;
if ( isRootClip() == true )
delete m_media;
}
......@@ -93,15 +89,7 @@ Clip::media() const
qint64
Clip::lengthSecond() const
{
return m_lengthSeconds;
}
void
Clip::computeLength()
{
int64_t sourceLengthSeconds = m_media->source()->length() / 1000;
m_nbFrames = m_end - m_begin;
m_lengthSeconds = qRound64( ( m_endPosition - m_beginPosition ) * sourceLengthSeconds );
return qRound64( m_producer->playableLength() / m_producer->fps() );
}
const QStringList&
......@@ -157,6 +145,42 @@ Clip::setUuid( const QUuid &uuid )
m_uuid = uuid;
}
qint64
Clip::begin() const
{
return m_producer->begin();
}
qint64
Clip::end() const
{
return m_producer->end();
}
void
Clip::setBegin( qint64 begin )
{
m_producer->setBegin( begin );
}
void
Clip::setEnd( qint64 end )
{
m_producer->setEnd( end );
}
qint64
Clip::length() const
{
return m_producer->playableLength();
}
void
Clip::setBoundaries( qint64 begin, qint64 end )
{
m_producer->setBoundaries( begin, end );
}
Clip*
Clip::rootClip()
{
......@@ -234,8 +258,8 @@ Clip::toVariant() const
else
{
h.insert( "parent", m_parent->uuid().toString() );
h.insert( "begin", m_begin );
h.insert( "end", m_end );
h.insert( "begin", begin() );
h.insert( "end", end() );
}
return QVariant( h );
......@@ -269,28 +293,14 @@ Clip::setFormats( Formats formats )
m_formats = formats;
}
ClipWorkflow*
Clip::clipWorkflow() const
Backend::IProducer*
Clip::producer()
{
return m_clipWorkflow;
}
void
Clip::setClipWorkflow( ClipWorkflow *cw )
{
m_clipWorkflow = cw;
return m_producer;
}
void
Clip::mediaMetadataUpdated()
{
Q_ASSERT ( isRootClip() == true );
if ( m_end == 0 )
{
m_begin = 0;
m_end = m_media->source()->nbFrames();
m_beginPosition = 0.0f;
m_endPosition = 1.0f;
computeLength();
}
}
......@@ -4,6 +4,7 @@
* Copyright (C) 2008-2016 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
* Yikei Lu <luyikei.qmltu@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -32,6 +33,7 @@
#include <QStringList>
#include <QUuid>
#include <QXmlStreamWriter>
#include "Backend/IProducer.h"
class MediaContainer;
class Media;
......@@ -60,7 +62,7 @@ class Clip : public Workflow::Helper
* the end of the parent will be used.
* \param uuid A unique identifier. If not given, one will be generated.
*/
Clip( Media *parent, qint64 begin = 0, qint64 end = -1, const QString &uuid = QString() );
Clip( Media *parent, qint64 begin = 0, qint64 end = Backend::IProducer::EndOfMedia, const QString &uuid = QString() );
/**
* \brief Clones a Clip, potentially with a new begin and end.
*
......@@ -70,7 +72,7 @@ class Clip : public Workflow::Helper
* \param end The end, in frames, from the parent's beginning. If not given,
* the end of the parent will be used.
*/
Clip( Clip *creator, qint64 begin = -1, qint64 end = -1, const QString& uuid = QString() );
Clip( Clip *creator, qint64 begin = -1, qint64 end = Backend::IProducer::EndOfParent, const QString& uuid = QString() );
virtual ~Clip();
/**
......@@ -98,6 +100,13 @@ class Clip : public Workflow::Helper
const QUuid &uuid() const;
void setUuid( const QUuid &uuid );
virtual qint64 begin() const override;
virtual qint64 end() const override;
virtual void setBegin( qint64 begin ) override;
virtual void setEnd( qint64 end ) override;
virtual qint64 length() const override;
virtual void setBoundaries( qint64 begin, qint64 end ) override;
const QStringList &metaTags() const;
void setMetaTags( const QStringList &tags );
bool matchMetaTag( const QString &tag ) const;
......@@ -105,8 +114,6 @@ class Clip : public Workflow::Helper
const QString &notes() const;
void setNotes( const QString &notes );
void computeLength();
bool isRootClip() const;
Clip* rootClip();
......@@ -128,30 +135,11 @@ class Clip : public Workflow::Helper
Formats formats() const;
void setFormats( Formats formats );
ClipWorkflow* clipWorkflow() const;
void setClipWorkflow( ClipWorkflow* cw );
Backend::IProducer* producer();
private:
Media *m_media;
/**
* \brief This represents the beginning of the Clip in form of [0; 1] float
*/
float m_beginPosition;
/**
* \brief This represents the end of the Clip in form of [0;1] float
*/
float m_endPosition;
/**
* \brief The length in frames
*
*/
qint64 m_nbFrames;
/**
* \brief The length in seconds (Be carreful, VLC uses MILLIseconds)
*/
qint64 m_lengthSeconds;
Media* m_media;
Backend::IProducer* m_producer;
QStringList m_metaTags;
QString m_notes;
......
......@@ -4,6 +4,7 @@
* Copyright (C) 2008-2016 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
* Yikei Lu <luyikei.qmltu@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -33,9 +34,9 @@
#include "Clip.h"
#include "Main/Core.h"
#include "Library/Library.h"
#include "Metadata/MetaDataManager.h"
#include "Tools/VlmcDebug.h"
#include "Project/Workspace.h"
#include "Backend/MLT/MLTProducer.h"
#include "Backend/VLC/VLCSource.h"
#include "Backend/VLC/VLCBackend.h"
......@@ -60,7 +61,7 @@ QPixmap* Media::defaultSnapshot = nullptr;
#endif
Media::Media(const QString &path )
: m_source( nullptr )
: m_producer( nullptr )
, m_fileInfo( nullptr )
, m_baseClip( nullptr )
#ifdef WITH_GUI
......@@ -72,7 +73,7 @@ Media::Media(const QString &path )
Media::~Media()
{
delete m_source;
delete m_producer;
delete m_fileInfo;
}
......@@ -105,18 +106,6 @@ Media::fileName() const
return m_fileName;
}
Backend::VLC::VLCSource*
Media::source()
{
return m_source;
}
const Backend::VLC::VLCSource*
Media::source() const
{
return m_source;
}
void
Media::setBaseClip( Clip *clip )
{
......@@ -124,42 +113,24 @@ Media::setBaseClip( Clip *clip )
m_baseClip = clip;
}
void
Media::onMetaDataComputed()
{
emit metaDataComputed();
if ( m_source->hasVideo() == true )
{
const QString filter = "*." + m_fileInfo->suffix().toLower();
if ( Media::ImageExtensions.contains( filter ) )
m_fileType = Image;
else
m_fileType = Video;
#ifdef WITH_GUI
if ( m_source->snapshot() != nullptr )
{
Q_ASSERT( m_snapshotImage == nullptr );
m_snapshotImage = new QImage( m_source->snapshot(), 320, 180, QImage::Format_RGB32 );
emit snapshotAvailable();
}
#endif
}
else if ( m_source->hasAudio() )
m_fileType = Audio;
else
{
// We expect this case to be handled by the metadata manager. It should
// trigger an error for this kind of file since we can't use them.
vlmcFatal("Got metadata for a file which has no video nor audio.");
}
}
QVariant
Media::toVariant() const
{
return QVariant( m_fileInfo->absoluteFilePath() );
}
Backend::IProducer*
Media::producer()
{
return m_producer;
}
const Backend::IProducer*
Media::producer() const
{
return m_producer;
}
void
Media::setFilePath( const QString &filePath )
{
......@@ -169,29 +140,15 @@ Media::setFilePath( const QString &filePath )
m_fileName = m_fileInfo->fileName();
m_mrl = "file:///" + QUrl::toPercentEncoding( filePath, "/" );
auto backend = Backend::getVLCBackend();
delete m_source;
m_source = backend->createSource( qPrintable( filePath ) );
MetaDataManager::instance()->computeMediaMetadata( this );
delete m_producer;
m_producer = new Backend::MLT::MLTProducer( qPrintable( filePath ) );
}
#ifdef WITH_GUI
QPixmap&
Media::snapshot()
{
if ( m_snapshot.isNull() == false )
return m_snapshot;
if ( m_snapshotImage != nullptr )
{
m_snapshot = QPixmap::fromImage( *m_snapshotImage );
delete m_snapshotImage;
if ( m_snapshot.isNull() == false )
return m_snapshot;
}
if ( Media::defaultSnapshot == nullptr )
Media::defaultSnapshot = new QPixmap( ":/images/vlmc" );
Media::defaultSnapshot = new QPixmap( ":/images/vlmc" );
return *Media::defaultSnapshot;
}
#endif
......@@ -4,6 +4,7 @@
* Copyright (C) 2008-2016 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
* Yikei Lu <luyikei.qmltu@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -42,6 +43,7 @@
namespace Backend
{
class IProducer;
namespace VLC
{
class VLCSource;
......@@ -78,8 +80,6 @@ public:
const QFileInfo *fileInfo() const;
const QString &mrl() const;
const QString &fileName() const;
Backend::VLC::VLCSource *source();
const Backend::VLC::VLCSource *source() const;
/**
* \brief Set this media's path.
*
......@@ -102,12 +102,15 @@ public:
QVariant toVariant() const;
Backend::IProducer* producer();
const Backend::IProducer* producer() const;
#ifdef WITH_GUI
// This has to be called from the GUI thread.
QPixmap& snapshot();
#endif
protected:
Backend::VLC::VLCSource* m_source;
Backend::IProducer* m_producer;
QString m_mrl;
QFileInfo* m_fileInfo;
FileType m_fileType;
......
......@@ -3,7 +3,8 @@
*****************************************************************************
* Copyright (C) 2008-2016 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
* Authors: Yikei Lu <luyikei.qmltu@gmail.com>
* Hugo Beauzée-Luyssen <hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -20,45 +21,170 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include "AbstractRenderer.h"
#include "Backend/MLT/MLTBackend.h"
#include "Tools/RendererEventWatcher.h"
#include "Backend/MLT/MLTConsumer.h"
#include <QtGlobal>
AbstractRenderer::AbstractRenderer()
: m_sourceRenderer( nullptr )
, m_paused( false )
, m_isRendering( false )
: m_producer( nullptr )
{
m_eventWatcher = new RendererEventWatcher;
connect( m_eventWatcher, &RendererEventWatcher::stopped, this, &AbstractRenderer::stop );
connect( m_eventWatcher, &RendererEventWatcher::positionChanged, this, [this]( qint64 pos ){ emit frameChanged( pos, Vlmc::Renderer ); } );
connect( m_eventWatcher, &RendererEventWatcher::lengthChanged, this, &AbstractRenderer::lengthChanged );
connect( m_eventWatcher, &RendererEventWatcher::endReached, this, &AbstractRenderer::stop );
}
AbstractRenderer::~AbstractRenderer()
{
delete m_sourceRenderer;
stop();
delete m_eventWatcher;
}
#ifdef WITH_GUI
RendererEventWatcher*
AbstractRenderer::eventWatcher()
{
return m_eventWatcher;