[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