Commit 7626faf7 authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Merge branch 'effect-engine'

parents 4e3f7652 a6ae6246
......@@ -6,8 +6,9 @@
SET(VLMC_SRCS
Commands/Commands.cpp
Settings/SettingsManager.cpp
Settings/SettingValue.cpp
EffectsEngine/EffectsEngine.cpp
EffectsEngine/Effect.cpp
EffectsEngine/EffectInstance.cpp
Library/Library.cpp
Library/MediaContainer.cpp
LibVLCpp/VLCInstance.cpp
......@@ -25,6 +26,8 @@ SET(VLMC_SRCS
Renderer/GenericRenderer.cpp
Renderer/WorkflowFileRenderer.cpp
Renderer/WorkflowRenderer.cpp
Settings/SettingsManager.cpp
Settings/SettingValue.cpp
Tools/ErrorHandler.cpp
Tools/Pool.hpp
Tools/QSingleton.hpp
......@@ -51,8 +54,9 @@ ELSE (WIN32)
ENDIF(WIN32)
SET (VLMC_HDRS
Settings/SettingsManager.h
Settings/SettingValue.h
EffectsEngine/EffectsEngine.h
EffectsEngine/Effect.h
EffectsEngine/EffectInstance.h
Library/Library.h
Library/MediaContainer.h
LibVLCpp/VLCInstance.h
......@@ -68,6 +72,8 @@ SET (VLMC_HDRS
Renderer/GenericRenderer.h
Renderer/WorkflowFileRenderer.h
Renderer/WorkflowRenderer.h
Settings/SettingsManager.h
Settings/SettingValue.h
Tools/ErrorHandler.h
Tools/VlmcDebug.h
Workflow/AudioClipWorkflow.h
......@@ -96,8 +102,10 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_BINARY_DIR}/src
.
Commands
EffectsEngine
Settings
Gui
Gui/effectsengine
Gui/import
Gui/library
Gui/media
......@@ -114,6 +122,7 @@ INCLUDE_DIRECTORIES(
Renderer
Tools
Workflow
${CMAKE_SOURCE_DIR}/extras
)
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/cmake/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
......@@ -135,8 +144,6 @@ IF (NOT WITH_GUI)
ELSE(NOT WITH_GUI)
LIST( APPEND VLMC_SRCS
Commands/KeyboardShortcutHelper.cpp
Main/guimain.cpp
Media/Transcoder.cpp #Won't be needed without the import, so let's put it in GUI list
Gui/About.cpp
Gui/AudioSpectrumDrawer.cpp
Gui/ClickableLabel.cpp
......@@ -144,25 +151,27 @@ ELSE(NOT WITH_GUI)
Gui/DockWidgetManager.cpp
Gui/IntroDialog.cpp
Gui/LanguageHelper.cpp
Gui/preview/LCDTimecode.cpp
Gui/MainWindow.cpp
Gui/import/TagWidget.cpp
Gui/UndoStack.cpp
Gui/WorkflowFileRendererDialog.cpp
Gui/effectsengine/EffectsList.cpp
Gui/effectsengine/EffectsListView.cpp
Gui/export/RendererSettings.cpp
Gui/export/ShareOnYoutube.cpp
Gui/import/ImportController.cpp
Gui/import/TagWidget.cpp
Gui/library/ListViewController.cpp
Gui/library/MediaCellView.cpp
Gui/library/MediaLibrary.cpp
Gui/library/MediaListView.cpp
Gui/library/StackViewController.cpp
Gui/library/StackViewNavController.cpp
Gui/media/GuiMedia.cpp
Gui/media/ClipMetadataDisplayer.cpp
Gui/project/GuiProjectManager.cpp
Gui/media/GuiMedia.cpp
Gui/preview/LCDTimecode.cpp
Gui/preview/PreviewRuler.cpp
Gui/preview/PreviewWidget.cpp
Gui/project/GuiProjectManager.cpp
Gui/settings/BoolWidget.cpp
Gui/settings/DoubleWidget.cpp
Gui/settings/IntWidget.cpp
......@@ -194,20 +203,26 @@ ELSE(NOT WITH_GUI)
Gui/wizard/ProjectWizard.cpp
Gui/wizard/VideoPage.cpp
Gui/wizard/WelcomePage.cpp
Main/guimain.cpp
Media/Transcoder.cpp #Won't be needed without the import, so let's put it in GUI list
)
LIST( APPEND VLMC_HDRS
Commands/KeyboardShortcutHelper.h
Media/Transcoder.h #Won't be needed without the import, so let's put it in GUI list
Gui/About.h
Gui/ClickableLabel.h
Gui/ClipProperty.h
Gui/DockWidgetManager.h
Gui/IntroDialog.h
Gui/LanguageHelper.h
Gui/MainWindow.h
Gui/UndoStack.h
Gui/WorkflowFileRendererDialog.h
Gui/effectsengine/EffectsList.h
Gui/effectsengine/EffectsListView.h
Gui/export/RendererSettings.h
Gui/export/ShareOnYoutube.h
Gui/import/ImportController.h
Gui/IntroDialog.h
Gui/LanguageHelper.h
Gui/import/TagWidget.h
Gui/library/ListViewController.h
Gui/library/MediaCellView.h
......@@ -216,26 +231,25 @@ ELSE(NOT WITH_GUI)
Gui/library/StackViewController.h
Gui/library/StackViewNavController.h
Gui/library/ViewController.h
Gui/MainWindow.h
Gui/media/ClipMetadataDisplayer.h
Gui/media/GuiMedia.h
Gui/preview/LCDTimecode.h
Gui/preview/PreviewRuler.h
Gui/preview/PreviewWidget.h
Gui/project/GuiProjectManager.h
Gui/settings/KeyboardShortcut.h
Gui/settings/KeyboardShortcutInput.h
Gui/settings/BoolWidget.h
Gui/settings/DoubleWidget.h
Gui/settings/IntWidget.h
Gui/settings/ISettingsCategoryWidget.h
Gui/settings/IntWidget.h
Gui/settings/KeyboardShortcut.h
Gui/settings/KeyboardShortcutInput.h
Gui/settings/LanguageWidget.h
Gui/settings/Panel.h
Gui/settings/PathWidget.h
Gui/settings/PreferenceWidget.h
Gui/settings/StringWidget.h
Gui/settings/Panel.h
Gui/settings/PreferenceWidget.h
Gui/settings/Settings.h
Gui/settings/StringWidget.h
Gui/timeline/AbstractGraphicsMediaItem.h
Gui/timeline/GraphicsAudioItem.h
Gui/timeline/GraphicsCursorItem.h
......@@ -246,7 +260,6 @@ ELSE(NOT WITH_GUI)
Gui/timeline/TracksRuler.h
Gui/timeline/TracksScene.h
Gui/timeline/TracksView.h
Gui/UndoStack.h
Gui/widgets/ElidableLabel.h
Gui/widgets/FramelessButton.h
Gui/widgets/NotificationZone.h
......@@ -257,24 +270,25 @@ ELSE(NOT WITH_GUI)
Gui/wizard/ProjectWizard.h
Gui/wizard/VideoPage.h
Gui/wizard/WelcomePage.h
Gui/WorkflowFileRendererDialog.h
Media/Transcoder.h #Won't be needed without the import, so let's put it in GUI list
)
SET(VLMC_UIS
Gui/effectsengine/ui/EffectsList.ui
Gui/export/RendererSettings.ui
Gui/export/ShareOnYoutube.ui
Gui/import/ui/ImportController.ui
Gui/import/ui/TagWidget.ui
Gui/library/StackViewNavController.ui
Gui/library/ui/MediaCellView.ui
Gui/library/ui/MediaLibrary.ui
Gui/library/ui/StackViewNavController.ui
Gui/media/ui/ClipMetadataDisplayer.ui
Gui/preview/ui/PreviewWidget.ui
Gui/ui/About.ui
Gui/ui/ClipProperty.ui
Gui/ui/IntroDialog.ui
Gui/ui/MainWindow.ui
Gui/media/ui/ClipMetadataDisplayer.ui
Gui/preview/ui/PreviewWidget.ui
Gui/import/ui/TagWidget.ui
Gui/ui/Timeline.ui
Gui/ui/WorkflowFileRendererDialog.ui
Gui/widgets/TrackControls.ui
......
/*****************************************************************************
* Effect.cpp: Handle a frei0r effect.
*****************************************************************************
* Copyright (C) 2008-2010 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* 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.
*****************************************************************************/
#include "Effect.h"
#include "EffectInstance.h"
#include "frei0r/frei0r.h"
#include <QtDebug>
Effect::Effect( const QString &fileName ) :
QLibrary( fileName ),
m_type( Unknown )
{
}
Effect::~Effect()
{
m_f0r_deinit();
}
#define LOAD_FREI0R_SYMBOL( dest, symbolName ) \
if ( ( dest = reinterpret_cast<typeof( dest )>( resolve( symbolName ) ) ) == NULL ) \
{ \
qCritical() << "Failed to load symbol:" << symbolName; \
return false; \
}
bool
Effect::load()
{
if ( isLoaded() == true )
return true;
LOAD_FREI0R_SYMBOL( m_f0r_init, "f0r_init" );
LOAD_FREI0R_SYMBOL( m_f0r_deinit, "f0r_deinit" )
LOAD_FREI0R_SYMBOL( m_f0r_info, "f0r_get_plugin_info" )
LOAD_FREI0R_SYMBOL( m_f0r_construct, "f0r_construct" )
LOAD_FREI0R_SYMBOL( m_f0r_destruct, "f0r_destruct" )
LOAD_FREI0R_SYMBOL( m_f0r_update, "f0r_update" )
//Initializing structures
f0r_plugin_info_t infos;
m_f0r_init();
m_f0r_info( &infos );
m_name = infos.name;
m_desc = infos.explanation;
m_type = static_cast<Type>( infos.plugin_type );
return true;
}
#undef LOAD_FREI0R_SYMBOL
const QString&
Effect::name()
{
if ( isLoaded() == false )
load();
return m_name;
}
const QString&
Effect::description()
{
if ( isLoaded() == false )
load();
return m_desc;
}
Effect::Type
Effect::type()
{
if ( isLoaded() == false )
load();
return m_type;
}
EffectInstance*
Effect::createInstance()
{
m_instCount.fetchAndAddAcquire( 1 );
return new EffectInstance( this );
}
void
Effect::destroyInstance( EffectInstance *instance )
{
delete instance;
//fetchAndAddAcquire returns the old value.
if ( m_instCount.fetchAndAddAcquire( -1 ) == 1 )
unload();
}
/*****************************************************************************
* Effect.h: Handle a frei0r effect.
*****************************************************************************
* Copyright (C) 2008-2010 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* 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 EFFECT_H
#define EFFECT_H
#include <QLibrary>
#include "frei0r/frei0r.h"
class EffectInstance;
class Effect : public QLibrary
{
public:
enum Type
{
Unknown = -1,
Filter = F0R_PLUGIN_TYPE_FILTER,
Source = F0R_PLUGIN_TYPE_SOURCE,
Mixer2 = F0R_PLUGIN_TYPE_MIXER2,
Mixer3 = F0R_PLUGIN_TYPE_MIXER3
};
typedef int (*f0r_init_t)();
typedef void (*f0r_deinit_t)();
typedef void (*f0r_get_info_t)(f0r_plugin_info_t*);
typedef f0r_instance_t (*f0r_construct_t)( unsigned int, unsigned int );
typedef void (*f0r_destruct_t)( f0r_instance_t );
typedef void (*f0r_update_t)( f0r_instance_t, double, const unsigned int*, unsigned int * );
Effect( const QString& fileName );
virtual ~Effect();
bool load();
const QString& name();
const QString& description();
Type type();
EffectInstance *createInstance();
private:
void destroyInstance( EffectInstance* instance );
private:
QString m_name;
QString m_desc;
Type m_type;
QAtomicInt m_instCount;
//Symbols:
f0r_init_t m_f0r_init;
f0r_deinit_t m_f0r_deinit;
f0r_get_info_t m_f0r_info;
f0r_construct_t m_f0r_construct;
f0r_destruct_t m_f0r_destruct;
f0r_update_t m_f0r_update;
friend class EffectInstance;
};
#endif // EFFECT_H
/*****************************************************************************
* EffectInstance.cpp: Handle an effect instance.
*****************************************************************************
* Copyright (C) 2008-2010 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* 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.
*****************************************************************************/
#include "EffectInstance.h"
#include "Effect.h"
EffectInstance::EffectInstance( Effect *effect ) :
m_effect( effect ),
m_width( 0 ),
m_height( 0 ),
m_instance( NULL )
{
}
EffectInstance::~EffectInstance()
{
m_effect->m_f0r_destruct( m_instance );
}
void
EffectInstance::init( quint32 width, quint32 height )
{
if ( width != m_width || height != m_height )
{
m_effect->load();
m_instance = m_effect->m_f0r_construct( width, height );
m_width = width;
m_height = height;
}
}
void
EffectInstance::process( double time, const quint32 *input, quint32 *output ) const
{
m_effect->m_f0r_update( m_instance, time, input, output );
}
Effect*
EffectInstance::effect()
{
return m_effect;
}
/*****************************************************************************
* EffectInstance.h: Handle an effect instance.
*****************************************************************************
* Copyright (C) 2008-2010 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* 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 EFFECTINSTANCE_H
#define EFFECTINSTANCE_H
class Effect;
#include <QtGlobal>
#include "frei0r/frei0r.h"
class EffectInstance
{
public:
void init( quint32 width, quint32 height );
void process( double time, const quint32* input, quint32* output ) const;
Effect* effect();
private:
EffectInstance( Effect *effect );
~EffectInstance();
Effect *m_effect;
quint32 m_width;
quint32 m_height;
f0r_instance_t m_instance;
friend class Effect;
};
#endif // EFFECTINSTANCE_H
/*****************************************************************************
* EffectsEngine.cpp: Manage the effects plugins.
*****************************************************************************
* Copyright (C) 2008-2010 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* 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.
*****************************************************************************/
#include "EffectsEngine.h"
#include "Effect.h"
#include "EffectInstance.h"
#include "Types.h"
#include <QDesktopServices>
#include <QDir>
#include <QSettings>
#include <QtDebug>
EffectsEngine::EffectsEngine()
{
m_cache = new QSettings( QDesktopServices::storageLocation(
QDesktopServices::CacheLocation ) + "/effects",
QSettings::IniFormat, this );
}
EffectsEngine::~EffectsEngine()
{
}
EffectsEngine::EffectHelper::EffectHelper( EffectInstance *_effect, qint64 _start, qint64 _end,
const QString& _uuid ) :
effect( _effect ),
start( _start ),
end( _end )
{
if ( _uuid.isNull() == true )
uuid = QUuid::createUuid();
else
uuid = _uuid;
}
Effect*
EffectsEngine::effect( const QString& name )
{
QHash<QString, Effect*>::iterator it = m_effects.find( name );
if ( it != m_effects.end() )
return it.value();
return NULL;
}
bool
EffectsEngine::loadEffect( const QString &fileName )
{
Effect* e = new Effect( fileName );
QString name;
Effect::Type type;
if ( m_cache->contains( fileName + "/name" ) == true &&
m_cache->contains( fileName + "/type" ) == true )
{
name = m_cache->value( fileName + "/name" ).toString();
int typeInt = m_cache->value( fileName + "/type" ).toInt();
if ( typeInt < Effect::Unknown || typeInt > Effect::Mixer3 )
qWarning() << "Invalid plugin type.";
else
{
type = static_cast<Effect::Type>( typeInt );
m_effects[name] = e;
emit effectAdded( e, name, type );
return true;
}
}
if ( e->load() == false )
{
delete e;
return false;
}
m_effects[e->name()] = e;
m_cache->setValue( fileName + "/name", e->name() );
m_cache->setValue( fileName + "/type", e->type() );
name = e->name();
type = e->type();
emit effectAdded( e, name, type );
return true;
}
void
EffectsEngine::browseDirectory( const QString &path )
{
QDir dir( path );
const QStringList& files = dir.entryList( QDir::Files | QDir::NoDotAndDotDot |
QDir::Readable | QDir::Executable );
foreach ( const QString& file, files )
{
loadEffect( path + '/' + file );
}
}
void
EffectsEngine::applyEffects( const EffectList &effects, Workflow::Frame* frame,
qint64 currentFrame )
{
if ( effects.size() == 0 )
return ;
EffectList::const_iterator it = effects.constBegin();
EffectList::const_iterator ite = effects.constEnd();
quint8 *buff1 = NULL;
quint8 *buff2 = NULL;
quint8 *input = frame->buffer();
bool firstBuff = true;
while ( it != ite )
{
if ( (*it)->start < currentFrame &&
( (*it)->end < 0 || (*it)->end > currentFrame ) )
{
quint8 **buff;
if ( firstBuff == true )
buff = &buff1;
else
buff = &buff2;
if ( *buff == NULL )
*buff = new quint8[frame->size()];
EffectInstance *effect = (*it)->effect;
effect->process( 0.0, (quint32*)input, (quint32*)*buff );
input = *buff;
firstBuff = !firstBuff;
}
++it;
}
if ( buff1 != NULL || buff2 != NULL )
{
//The old input frame will automatically be deleted when setting the new buffer
if ( firstBuff == true )
{
delete[] buff1;
frame->setBuffer( buff2 );
}
else
{
delete[] buff2;
frame->setBuffer( buff1 );
}
}
}
/*****************************************************************************
* EffectsEngine.h: Manage the effects plugins.
*****************************************************************************
* Copyright (C) 2008-2010 VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <beauze.h@gmail.com>
*
* 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 EFFECTSENGINE_H
#define EFFECTSENGINE_H
#include "Singleton.hpp"
#include "Effect.h"
#include "MainWorkflow.h"
#include <QObject>
#include <QHash>
class QSettings;
class EffectsEngine : public QObject, public Singleton<EffectsEngine>
{
Q_OBJECT
public:
struct EffectHelper
{
EffectHelper( EffectInstance* effect, qint64 start = 0, qint64 end = -1,
const QString& uuid = QString() );
EffectInstance* effect;
qint64 start;
qint64 end;
QUuid uuid;
};
typedef QList<EffectHelper*> EffectList;
Effect* effect( const QString& name );
bool loadEffect( const QString& fileName );
void browseDirectory( const QString& path );
static void applyEffects( const EffectList& effects,
Workflow::Frame *frame, qint64 currentFrame );
private:
EffectsEngine();
~EffectsEngine();
QHash<QString, Effect*> m_effects;
QSettings *m_cache;
signals:
void effectAdded( Effect*, const QString& name, Effect::Type );
friend class Singleton<EffectsEngine>;
};
#endif // EFFECTSENGINE_H
......@@ -38,6 +38,7 @@
#include "About.h"
#include "VlmcDebug.h"
#include "EffectsEngine/EffectsEngine.h"
#include "MainWorkflow.h"
#include "export/RendererSettings.h"
#include "export/ShareOnYoutube.h"
......@@ -47,6 +48,7 @@
/* Widgets */
#include "DockWidgetManager.h"
#include "EffectsList.h"
#include "ImportController.h"
#include "MediaLibrary.h"
#include "NotificationZone.h"
...</