[vlmc-devel] commit: EffectsEngine: Refactoring. ( Hugo Beauzée-Luyssen )

git at videolan.org git at videolan.org
Wed Jul 28 00:22:07 CEST 2010


vlmc | branch: master | Hugo Beauzée-Luyssen <beauze.h at gmail.com> | Mon Jul 26 23:31:58 2010 +0200| [baf29920a0d80adc6807db899db69dd89c7f7b27] | committer: Hugo Beauzée-Luyssen 

EffectsEngine: Refactoring.

Making the WorkflowRenderer effect processing thread safe

> http://git.videolan.org/gitweb.cgi/vlmc.git/?a=commit;h=baf29920a0d80adc6807db899db69dd89c7f7b27
---

 src/EffectsEngine/EffectsEngine.cpp |   50 +++++++++++++++++++++++++++++++
 src/EffectsEngine/EffectsEngine.h   |    5 +++
 src/Renderer/WorkflowRenderer.cpp   |   56 ++++------------------------------
 src/Renderer/WorkflowRenderer.h     |    5 +--
 4 files changed, 64 insertions(+), 52 deletions(-)

diff --git a/src/EffectsEngine/EffectsEngine.cpp b/src/EffectsEngine/EffectsEngine.cpp
index ad176de..b3e26b6 100644
--- a/src/EffectsEngine/EffectsEngine.cpp
+++ b/src/EffectsEngine/EffectsEngine.cpp
@@ -23,6 +23,7 @@
 #include "EffectsEngine.h"
 
 #include "Effect.h"
+#include "Types.h"
 
 #include <QDir>
 #include <QtDebug>
@@ -83,3 +84,52 @@ EffectsEngine::browseDirectory( const QString &path )
         loadEffect( path + '/' + file );
     }
 }
+
+void
+EffectsEngine::applyEffects( const EffectList &effects, MainWorkflow::OutputBuffers *ret,
+                             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 = ret->video->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[ret->video->size()];
+            Effect  *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;
+            ret->video->setBuffer( buff2 );
+        }
+        else
+        {
+            delete[] buff2;
+            ret->video->setBuffer( buff1 );
+        }
+    }
+}
diff --git a/src/EffectsEngine/EffectsEngine.h b/src/EffectsEngine/EffectsEngine.h
index aaf6719..3304715 100644
--- a/src/EffectsEngine/EffectsEngine.h
+++ b/src/EffectsEngine/EffectsEngine.h
@@ -26,6 +26,7 @@
 #include "Singleton.hpp"
 
 #include "Effect.h"
+#include "MainWorkflow.h"
 
 #include <QObject>
 #include <QHash>
@@ -42,11 +43,15 @@ class   EffectsEngine : public QObject, public Singleton<EffectsEngine>
             qint64  start;
             qint64  end;
         };
+        typedef QList<EffectHelper*>    EffectList;
 
         void        initAll( quint32 width, quint32 height );
         Effect*     effect( const QString& name );
         bool        loadEffect( const QString& fileName );
         void        browseDirectory( const QString& path );
+
+        static void applyEffects( const EffectList& effects,
+                                  MainWorkflow::OutputBuffers* ret, qint64 currentFrame );
     private:
         EffectsEngine();
         ~EffectsEngine();
diff --git a/src/Renderer/WorkflowRenderer.cpp b/src/Renderer/WorkflowRenderer.cpp
index 7b4dde3..f63a3d8 100644
--- a/src/Renderer/WorkflowRenderer.cpp
+++ b/src/Renderer/WorkflowRenderer.cpp
@@ -48,6 +48,7 @@ WorkflowRenderer::WorkflowRenderer() :
             m_esHandler( NULL ),
             m_oldLength( 0 )
 {
+    m_effectsLock = new QReadWriteLock;
 }
 
 void    WorkflowRenderer::initializeRenderer()
@@ -82,6 +83,7 @@ WorkflowRenderer::~WorkflowRenderer()
         delete m_media;
     if ( m_silencedAudioBuffer )
         delete m_silencedAudioBuffer;
+    delete m_effectsLock;
 }
 
 void
@@ -167,7 +169,10 @@ WorkflowRenderer::lockVideo( EsHandler *handler, qint64 *pts, size_t *bufferSize
         //this is a bit hackish though... (especially regarding the "no frame computed" detection)
         ptsDiff = 1000000 / handler->fps;
     }
-    applyEffects( ret );
+    {
+        QReadLocker lock( m_effectsLock );
+        EffectsEngine::applyEffects( m_effects, ret, m_mainWorkflow->getCurrentFrame() );
+    }
     m_pts = *pts = ptsDiff + m_pts;
     *buffer = ret->video->buffer();
     *bufferSize = ret->video->size();
@@ -216,54 +221,6 @@ void    WorkflowRenderer::unlock( void*, const char*, size_t, void* )
 {
 }
 
-void
-WorkflowRenderer::applyEffects( MainWorkflow::OutputBuffers* ret )
-{
-    if ( m_effects.size() == 0 )
-        return ;
-    QList<EffectsEngine::EffectHelper*>::const_iterator     it = m_effects.constBegin();
-    QList<EffectsEngine::EffectHelper*>::const_iterator     ite = m_effects.constEnd();
-
-    quint8      *buff1 = NULL;
-    quint8      *buff2 = NULL;
-    quint8      *input = ret->video->buffer();
-    bool        firstBuff = true;
-
-    while ( it != ite )
-    {
-        if ( (*it)->start < m_mainWorkflow->getCurrentFrame() &&
-             ( (*it)->end < 0 || (*it)->end > m_mainWorkflow->getCurrentFrame() ) )
-        {
-            quint8      **buff;
-            if ( firstBuff == true )
-                buff = &buff1;
-            else
-                buff = &buff2;
-            if ( *buff == NULL )
-                *buff = new quint8[ret->video->size()];
-            Effect  *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;
-            ret->video->setBuffer( buff2 );
-        }
-        else
-        {
-            delete[] buff2;
-            ret->video->setBuffer( buff1 );
-        }
-    }
-}
-
 void        WorkflowRenderer::startPreview()
 {
     if ( m_mainWorkflow->getLengthFrame() <= 0 )
@@ -431,6 +388,7 @@ WorkflowRenderer::appendEffect( Effect *effect, qint64 start, qint64 end )
 {
     effect->setUsed( true );
     effect->init( m_width, m_height );
+    QWriteLocker    lock( m_effectsLock );
     m_effects.push_back( new EffectsEngine::EffectHelper( effect, start, end ) );
 }
 
diff --git a/src/Renderer/WorkflowRenderer.h b/src/Renderer/WorkflowRenderer.h
index 50bdf93..f1f30c0 100644
--- a/src/Renderer/WorkflowRenderer.h
+++ b/src/Renderer/WorkflowRenderer.h
@@ -149,8 +149,6 @@ class   WorkflowRenderer : public GenericRenderer
          */
         virtual void        startPreview();
 
-        void                applyEffects( MainWorkflow::OutputBuffers *ret );
-
     protected:
         /**
          *  \brief          Will return a pointer to the function/static method to use
@@ -283,7 +281,8 @@ class   WorkflowRenderer : public GenericRenderer
          */
         qint64              m_oldLength;
 
-        QList<EffectsEngine::EffectHelper*>     m_effects;
+        QReadWriteLock      *m_effectsLock;
+        EffectsEngine::EffectList     m_effects;
 
         static const quint8     VideoCookie = '0';
         static const quint8     AudioCookie = '1';



More information about the Vlmc-devel mailing list