[vlmc-devel] commit: Workflow: Stop the renderer when something goes wrong. ( Hugo Beauzée-Luyssen )

git at videolan.org git at videolan.org
Mon May 31 23:07:23 CEST 2010


vlmc | branch: master | Hugo Beauzée-Luyssen <beauze.h at gmail.com> | Mon May 31 22:51:12 2010 +0200| [c79b5bd79408ae3b12a77d781fb7aa2029591b11] | committer: Hugo Beauzée-Luyssen 

Workflow: Stop the renderer when something goes wrong.

Removing useless methods.
This commit should solve some potential deadlocks

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

 src/Workflow/AudioClipWorkflow.cpp |    2 +-
 src/Workflow/ClipWorkflow.cpp      |   74 ++++++++++++++++++++++++------------
 src/Workflow/ClipWorkflow.h        |   30 ++++++--------
 src/Workflow/TrackWorkflow.cpp     |   13 ++++--
 src/Workflow/VideoClipWorkflow.cpp |    2 +-
 5 files changed, 74 insertions(+), 47 deletions(-)

diff --git a/src/Workflow/AudioClipWorkflow.cpp b/src/Workflow/AudioClipWorkflow.cpp
index 5482f20..2984f0f 100644
--- a/src/Workflow/AudioClipWorkflow.cpp
+++ b/src/Workflow/AudioClipWorkflow.cpp
@@ -84,7 +84,7 @@ AudioClipWorkflow::getOutput( ClipWorkflow::GetMode mode )
 
     if ( getNbComputedBuffers() == 0 )
         return NULL;
-    if ( isEndReached() == true )
+    if ( shouldRender() == false )
         return NULL;
     if ( mode == ClipWorkflow::Get )
         qCritical() << "A sound buffer should never be asked with 'Get' mode";
diff --git a/src/Workflow/ClipWorkflow.cpp b/src/Workflow/ClipWorkflow.cpp
index 58e574e..3a040e6 100644
--- a/src/Workflow/ClipWorkflow.cpp
+++ b/src/Workflow/ClipWorkflow.cpp
@@ -68,10 +68,12 @@ void    ClipWorkflow::initialize()
 
     connect( m_mediaPlayer, SIGNAL( playing() ), this, SLOT( loadingComplete() ), Qt::DirectConnection );
     connect( m_mediaPlayer, SIGNAL( endReached() ), this, SLOT( clipEndReached() ), Qt::DirectConnection );
+    connect( m_mediaPlayer, SIGNAL( errorEncountered() ), this, SLOT( errorEncountered() ) );
     m_mediaPlayer->play();
 }
 
-void    ClipWorkflow::loadingComplete()
+void
+ClipWorkflow::loadingComplete()
 {
     adjustBegin();
     disconnect( m_mediaPlayer, SIGNAL( playing() ), this, SLOT( loadingComplete() ) );
@@ -82,7 +84,8 @@ void    ClipWorkflow::loadingComplete()
     m_initWaitCond->wake();
 }
 
-void    ClipWorkflow::adjustBegin()
+void
+ClipWorkflow::adjustBegin()
 {
     if ( m_clipHelper->clip()->getMedia()->fileType() == Media::Video ||
          m_clipHelper->clip()->getMedia()->fileType() == Media::Audio )
@@ -92,24 +95,14 @@ void    ClipWorkflow::adjustBegin()
     }
 }
 
-bool    ClipWorkflow::isEndReached() const
-{
-    QReadLocker lock( m_stateLock );
-    return m_state == ClipWorkflow::EndReached;
-}
-
-bool    ClipWorkflow::isStopped() const
-{
-    QReadLocker lock( m_stateLock );
-    return m_state == ClipWorkflow::Stopped;
-}
-
-ClipWorkflow::State     ClipWorkflow::getState() const
+ClipWorkflow::State
+ClipWorkflow::getState() const
 {
     return m_state;
 }
 
-void    ClipWorkflow::clipEndReached()
+void
+ClipWorkflow::clipEndReached()
 {
     setState( EndReached );
 }
@@ -126,6 +119,11 @@ ClipWorkflow::stopRenderer()
 {
     if ( m_mediaPlayer )
     {
+        setState( Stopping );
+        {
+            QMutexLocker    lock( m_initWaitCond->getMutex() );
+            m_initWaitCond->wake();
+        }
         {
             QMutexLocker    lock( m_renderLock );
             m_renderWaitCond->wakeAll();
@@ -152,12 +150,6 @@ ClipWorkflow::setTime( qint64 time )
     }
 }
 
-bool            ClipWorkflow::isRendering() const
-{
-    QReadLocker lock( m_stateLock );
-    return m_state == ClipWorkflow::Rendering;
-}
-
 void            ClipWorkflow::setState( State state )
 {
     QWriteLocker    lock( m_stateLock );
@@ -169,13 +161,30 @@ QReadWriteLock* ClipWorkflow::getStateLock()
     return m_stateLock;
 }
 
-void        ClipWorkflow::waitForCompleteInit()
+bool
+ClipWorkflow::waitForCompleteInit()
 {
-    if ( isRendering() == false )
+    m_stateLock->lockForRead();
+    if ( m_state != ClipWorkflow::Rendering && m_state != ClipWorkflow::Error )
     {
+        if ( m_state == ClipWorkflow::Error )
+        {
+            m_stateLock->unlock();
+            return false;
+        }
+        m_stateLock->unlock();
         QMutexLocker    lock( m_initWaitCond->getMutex() );
         m_initWaitCond->waitLocked();
+
+        m_stateLock->lockForRead();
+        if ( m_state == ClipWorkflow::Error )
+        {
+            m_stateLock->unlock();
+            return false;
+        }
     }
+    m_stateLock->unlock();
+    return true;
 }
 
 LibVLCpp::MediaPlayer*       ClipWorkflow::getMediaPlayer()
@@ -279,3 +288,20 @@ ClipWorkflow::isResyncRequired()
     }
     return false;
 }
+
+void
+ClipWorkflow::errorEncountered()
+{
+    stopRenderer();
+    setState( Error );
+    emit error();
+}
+
+bool
+ClipWorkflow::shouldRender() const
+{
+    QReadLocker lock( m_stateLock );
+    return ( m_state != ClipWorkflow::Error &&
+             m_state != ClipWorkflow::Stopped &&
+             m_state != ClipWorkflow::Stopping );
+}
diff --git a/src/Workflow/ClipWorkflow.h b/src/Workflow/ClipWorkflow.h
index f7f43d4..1b96fa6 100644
--- a/src/Workflow/ClipWorkflow.h
+++ b/src/Workflow/ClipWorkflow.h
@@ -76,7 +76,9 @@ class   ClipWorkflow : public QObject
             ///         because of a sufficient number of computed buffers
             Paused,             //7
             /// \brief  This state means a clip is mutted and must not be restarted
-            Muted,
+            Muted,              //8
+            /// \brief  An error was encountered, this ClipWorkflow must not be used anymore.
+            Error,              //9
         };
 
         /**
@@ -104,22 +106,12 @@ class   ClipWorkflow : public QObject
         void                    initialize();
 
         /**
-         *  Return true ONLY if the state is equal to EndReached.
-         *  In any other cases, this will return false.
-         */
-        bool                    isEndReached() const;
-
-        /**
-         *  Return true ONLY if the state is equal to Stopped.
-         *  In any other cases, this will return false.
-         */
-        bool                    isStopped() const;
-
-        /**
-         *  Return true ONLY if the state is equal to Rendering.
-         *  In any other cases, this will return false.
+         *  \return             true if the ClipWorkflow is able to, and should render
+         *                      a frame.
+         *
+         *  This is true when the state is not stopped, stopping, nor rendering.
          */
-        bool                    isRendering() const;
+        bool                    shouldRender() const;
 
         /**
          *  Returns the current workflow state.
@@ -169,7 +161,7 @@ class   ClipWorkflow : public QObject
          */
         QReadWriteLock*         getStateLock();
 
-        void                    waitForCompleteInit();
+        bool                    waitForCompleteInit();
 
         virtual void*           getLockCallback() const = 0;
         virtual void*           getUnlockCallback() const = 0;
@@ -264,6 +256,10 @@ class   ClipWorkflow : public QObject
         void                    mediaPlayerPaused();
         void                    mediaPlayerUnpaused();
         void                    resyncClipWorkflow();
+        void                    errorEncountered();
+
+    signals:
+        void                    error();
 };
 
 #endif // CLIPWORKFLOW_H
diff --git a/src/Workflow/TrackWorkflow.cpp b/src/Workflow/TrackWorkflow.cpp
index 4f55e88..cb49f5f 100644
--- a/src/Workflow/TrackWorkflow.cpp
+++ b/src/Workflow/TrackWorkflow.cpp
@@ -159,7 +159,9 @@ TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentFrame,
     {
         cw->getStateLock()->unlock();
         cw->initialize();
-        cw->waitForCompleteInit();
+        //If the init failed, don't even try to call getOutput.
+        if ( cw->waitForCompleteInit() == false )
+            return NULL;
         //We check for a difference greater than one to avoid false positive when starting.
         if ( (  qAbs(start - currentFrame) > 1 ) || cw->getClipHelper()->begin() != 0 )
         {
@@ -169,7 +171,8 @@ TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentFrame,
         return cw->getOutput( mode );
     }
     else if ( cw->getState() == ClipWorkflow::EndReached ||
-              cw->getState() == ClipWorkflow::Muted )
+              cw->getState() == ClipWorkflow::Muted ||
+              cw->getState() == ClipWorkflow::Error )
     {
         cw->getStateLock()->unlock();
         //The stopClipWorkflow() method will take care of that.
@@ -201,7 +204,8 @@ void                TrackWorkflow::stopClipWorkflow( ClipWorkflow* cw )
     cw->getStateLock()->lockForRead();
 
     if ( cw->getState() == ClipWorkflow::Stopped ||
-         cw->getState() == ClipWorkflow::Muted )
+         cw->getState() == ClipWorkflow::Muted ||
+         cw->getState() == ClipWorkflow::Error )
     {
         cw->getStateLock()->unlock();
         return ;
@@ -540,7 +544,8 @@ TrackWorkflow::stopFrameComputing()
         cw->getStateLock()->lockForRead();
 
         if ( cw->getState() == ClipWorkflow::Stopped ||
-             cw->getState() == ClipWorkflow::Muted )
+             cw->getState() == ClipWorkflow::Muted ||
+             cw->getState() == ClipWorkflow::Error )
         {
             cw->getStateLock()->unlock();
             return ;
diff --git a/src/Workflow/VideoClipWorkflow.cpp b/src/Workflow/VideoClipWorkflow.cpp
index 0aba2d3..e8d08d8 100644
--- a/src/Workflow/VideoClipWorkflow.cpp
+++ b/src/Workflow/VideoClipWorkflow.cpp
@@ -112,7 +112,7 @@ VideoClipWorkflow::getOutput( ClipWorkflow::GetMode mode )
 {
     QMutexLocker    lock( m_renderLock );
 
-    if ( isEndReached() == true )
+    if ( shouldRender() == false )
         return NULL;
     if ( getNbComputedBuffers() == 0 )
         m_renderWaitCond->wait( m_renderLock );



More information about the Vlmc-devel mailing list