[vlmc-devel] commit: Workflow: Fixing potential deadlock. ( Hugo Beauzée-Luyssen )
git at videolan.org
git at videolan.org
Fri May 14 18:51:23 CEST 2010
vlmc | branch: master | Hugo Beauzée-Luyssen <beauze.h at gmail.com> | Wed May 12 18:33:46 2010 +0200| [5d8a8deaace41527684f3ec8df75b30fffd399ae] | committer: Hugo Beauzée-Luyssen
Workflow: Fixing potential deadlock.
Splitting the stopping process in three parts : first stopping the
ClipWorkflow media player, stopping the renderer, and put the workflow
in a stopped state.
This seems to improve the perfs with a MOV sample, though i don't really
see why it would...
> http://git.videolan.org/gitweb.cgi/vlmc.git/?a=commit;h=5d8a8deaace41527684f3ec8df75b30fffd399ae
---
src/Renderer/WorkflowRenderer.cpp | 1 +
src/Workflow/ClipWorkflow.cpp | 18 ++++++++++++++----
src/Workflow/ClipWorkflow.h | 7 +++++++
src/Workflow/MainWorkflow.cpp | 7 +++++++
src/Workflow/MainWorkflow.h | 8 ++++++++
src/Workflow/TrackHandler.cpp | 12 ++++++++++++
src/Workflow/TrackHandler.h | 2 ++
src/Workflow/TrackWorkflow.cpp | 24 ++++++++++++++++++++++++
src/Workflow/TrackWorkflow.h | 2 ++
src/Workflow/VideoClipWorkflow.cpp | 3 +++
10 files changed, 80 insertions(+), 4 deletions(-)
diff --git a/src/Renderer/WorkflowRenderer.cpp b/src/Renderer/WorkflowRenderer.cpp
index 97f5d08..5e8a4ab 100644
--- a/src/Renderer/WorkflowRenderer.cpp
+++ b/src/Renderer/WorkflowRenderer.cpp
@@ -299,6 +299,7 @@ WorkflowRenderer::killRenderer()
m_isRendering = false;
m_paused = false;
m_stopping = true;
+ m_mainWorkflow->stopFrameComputing();
m_mediaPlayer->stop();
m_mainWorkflow->stop();
delete[] m_silencedAudioBuffer;
diff --git a/src/Workflow/ClipWorkflow.cpp b/src/Workflow/ClipWorkflow.cpp
index 190a9cb..1f7eed9 100644
--- a/src/Workflow/ClipWorkflow.cpp
+++ b/src/Workflow/ClipWorkflow.cpp
@@ -114,18 +114,28 @@ void ClipWorkflow::clipEndReached()
setState( EndReached );
}
-void ClipWorkflow::stop()
+void
+ClipWorkflow::stop()
+{
+ flushComputedBuffers();
+ releasePrealocated();
+}
+
+void
+ClipWorkflow::stopRenderer()
{
if ( m_mediaPlayer )
{
+ {
+ QMutexLocker lock( m_renderLock );
+ m_renderWaitCond->wakeAll();
+ }
m_mediaPlayer->stop();
disconnect( m_mediaPlayer, SIGNAL( endReached() ), this, SLOT( clipEndReached() ) );
MemoryPool<LibVLCpp::MediaPlayer>::getInstance()->release( m_mediaPlayer );
m_mediaPlayer = NULL;
- setState( Stopped );
delete m_vlcMedia;
- flushComputedBuffers();
- releasePrealocated();
+ setState( Stopped );
}
}
diff --git a/src/Workflow/ClipWorkflow.h b/src/Workflow/ClipWorkflow.h
index a181550..f7f43d4 100644
--- a/src/Workflow/ClipWorkflow.h
+++ b/src/Workflow/ClipWorkflow.h
@@ -193,6 +193,13 @@ class ClipWorkflow : public QObject
*/
bool isResyncRequired();
+ /**
+ * \brief Stop the renderer part of the ClipWorkflow
+ *
+ * IE. just stop the VLC thread, and do not flush anything.
+ */
+ void stopRenderer();
+
private:
void setState( State state );
void adjustBegin();
diff --git a/src/Workflow/MainWorkflow.cpp b/src/Workflow/MainWorkflow.cpp
index 9e0f3cf..34a0dc3 100644
--- a/src/Workflow/MainWorkflow.cpp
+++ b/src/Workflow/MainWorkflow.cpp
@@ -196,6 +196,13 @@ MainWorkflow::stop()
}
void
+MainWorkflow::stopFrameComputing()
+{
+ for ( qint32 type = 0; type < NbTrackType; ++type )
+ m_tracks[type]->stopFrameComputing();
+}
+
+void
MainWorkflow::moveClip( const QUuid &clipUuid, unsigned int oldTrack,
unsigned int newTrack, qint64 startingFrame,
MainWorkflow::TrackType trackType,
diff --git a/src/Workflow/MainWorkflow.h b/src/Workflow/MainWorkflow.h
index 2aff016..2d4f096 100644
--- a/src/Workflow/MainWorkflow.h
+++ b/src/Workflow/MainWorkflow.h
@@ -339,6 +339,14 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
*/
bool contains( const QUuid& uuid ) const;
+ /**
+ * \brief Stop the frame computing process.
+ *
+ * This will stop all the currently running ClipWorkflow.
+ * This is meant to be called just before the stop() method.
+ */
+ void stopFrameComputing();
+
private:
MainWorkflow( int trackCount = 64 );
~MainWorkflow();
diff --git a/src/Workflow/TrackHandler.cpp b/src/Workflow/TrackHandler.cpp
index 0f2cdec..b1b9b72 100644
--- a/src/Workflow/TrackHandler.cpp
+++ b/src/Workflow/TrackHandler.cpp
@@ -325,3 +325,15 @@ TrackHandler::contains( const QUuid &uuid ) const
return true;
return false;
}
+
+void
+TrackHandler::stopFrameComputing()
+{
+ for ( unsigned int i = 0; i < m_trackCount; ++i )
+ {
+ //First stop the frame computing
+ m_tracks[i]->stopFrameComputing();
+ //then deactivate the track to avoid the generation to be resumed.
+ m_tracks[i].deactivate();
+ }
+}
diff --git a/src/Workflow/TrackHandler.h b/src/Workflow/TrackHandler.h
index 39b95d3..e059683 100644
--- a/src/Workflow/TrackHandler.h
+++ b/src/Workflow/TrackHandler.h
@@ -101,6 +101,8 @@ class TrackHandler : public QObject
bool contains( const QUuid& uuid ) const;
+ void stopFrameComputing();
+
private:
void computeLength();
void activateTrack( unsigned int tracKId );
diff --git a/src/Workflow/TrackWorkflow.cpp b/src/Workflow/TrackWorkflow.cpp
index 0370aae..4f55e88 100644
--- a/src/Workflow/TrackWorkflow.cpp
+++ b/src/Workflow/TrackWorkflow.cpp
@@ -526,3 +526,27 @@ TrackWorkflow::contains( const QUuid &uuid ) const
}
return false;
}
+
+void
+TrackWorkflow::stopFrameComputing()
+{
+ QMap<qint64, ClipWorkflow*>::const_iterator it = m_clips.begin();
+ QMap<qint64, ClipWorkflow*>::const_iterator end = m_clips.end();
+
+ while ( it != end )
+ {
+ ClipWorkflow* cw = it.value();
+
+ cw->getStateLock()->lockForRead();
+
+ if ( cw->getState() == ClipWorkflow::Stopped ||
+ cw->getState() == ClipWorkflow::Muted )
+ {
+ cw->getStateLock()->unlock();
+ return ;
+ }
+ cw->getStateLock()->unlock();
+ cw->stopRenderer();
+ ++it;
+ }
+}
diff --git a/src/Workflow/TrackWorkflow.h b/src/Workflow/TrackWorkflow.h
index b503cb7..3f3dab6 100644
--- a/src/Workflow/TrackWorkflow.h
+++ b/src/Workflow/TrackWorkflow.h
@@ -87,6 +87,8 @@ class TrackWorkflow : public QObject
bool contains( const QUuid& uuid ) const;
+ void stopFrameComputing();
+
private:
void computeLength();
void* renderClip( ClipWorkflow* cw, qint64 currentFrame,
diff --git a/src/Workflow/VideoClipWorkflow.cpp b/src/Workflow/VideoClipWorkflow.cpp
index 1d53317..0aba2d3 100644
--- a/src/Workflow/VideoClipWorkflow.cpp
+++ b/src/Workflow/VideoClipWorkflow.cpp
@@ -116,6 +116,9 @@ VideoClipWorkflow::getOutput( ClipWorkflow::GetMode mode )
return NULL;
if ( getNbComputedBuffers() == 0 )
m_renderWaitCond->wait( m_renderLock );
+ //Recheck again, as the WaitCondition may have been awaken when stopping.
+ if ( getNbComputedBuffers() == 0 )
+ return NULL;
::StackedBuffer<LightVideoFrame*>* buff;
if ( mode == ClipWorkflow::Pop )
buff = new StackedBuffer( m_computedBuffers.dequeue(), this, true );
More information about the Vlmc-devel
mailing list