From 62a598c259e500d2cdc861cc3f6dd3b089524279 Mon Sep 17 00:00:00 2001 From: Hugo Beauzee-Luyssen Date: Mon, 3 Aug 2009 18:09:19 +0200 Subject: [PATCH] Pausing and unpausing doesn't dead lock anymore. --- src/Workflow/ClipWorkflow.cpp | 2 +- src/Workflow/TrackWorkflow.cpp | 15 +++++++++++++-- src/gui/MainWindow.cpp | 20 ++++++++++---------- src/renderer/WorkflowRenderer.cpp | 13 ++++++++++++- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/Workflow/ClipWorkflow.cpp b/src/Workflow/ClipWorkflow.cpp index 1fa9fb2cf..1f81ca969 100644 --- a/src/Workflow/ClipWorkflow.cpp +++ b/src/Workflow/ClipWorkflow.cpp @@ -349,7 +349,7 @@ void ClipWorkflow::pause() void ClipWorkflow::unpause( bool wakeRenderThread /*= true*/ ) { //Since VLC will detect that the media player is paused and unpause it, we can do this safely - setState( ClipWorkflow::Rendering ); + queryStateChange( ClipWorkflow::Rendering ); m_mediaPlayer->pause(); // QMutexLocker lock( m_requiredStateLock ); // m_requiredState = ClipWorkflow::None; diff --git a/src/Workflow/TrackWorkflow.cpp b/src/Workflow/TrackWorkflow.cpp index 620fc5796..ea33cd9be 100644 --- a/src/Workflow/TrackWorkflow.cpp +++ b/src/Workflow/TrackWorkflow.cpp @@ -91,8 +91,9 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF cw->getStateLock()->lockForRead(); qDebug() << "Rendering clip"; - if ( cw->getState() == ClipWorkflow::Paused && pauseAfterRender == false ) + if ( cw->getState() == ClipWorkflow::ThreadPaused && pauseAfterRender == false ) { + qDebug() << "Paused clip, but no need to repause it after"; cw->getStateLock()->unlock(); //If we must pause after render, we must NOT wake the renderer thread, or it could render more than one frame // (since this is for the next/previous frame) @@ -116,7 +117,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF //If frame has been rendered : if ( cw->getState() == ClipWorkflow::Sleeping || pauseAfterRender == true ) { -// qDebug() << "rendering a sleeping clip workflow"; + qDebug() << "rendering a sleeping clip workflow"; if ( pauseAfterRender == true ) qDebug() << "Rendering only one frame"; cw->getStateLock()->unlock(); @@ -126,6 +127,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF float pos = ( (float)( currentFrame - start ) / (float)(cw->getClip()->getLength()) ); cw->setPosition( pos ); } + qDebug() << "getting clip output"; ret = cw->getOutput(); if ( pauseAfterRender == false ) { @@ -150,6 +152,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF } else if ( cw->getState() == ClipWorkflow::Stopped ) { + qDebug() << "Rendering a stopped clip workflow"; cw->getStateLock()->unlock(); cw->initialize( ); cw->startRender(); @@ -164,6 +167,7 @@ unsigned char* TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentF { //If the state is Initializing, then the workflow will wait. //Otherwise, it will start directly. + qDebug() << "Rendering a ready clip workflow"; cw->getStateLock()->unlock(); cw->startRender(); if ( needRepositioning == true ) @@ -495,10 +499,17 @@ void TrackWorkflow::clipWorkflowPaused() void TrackWorkflow::clipWorkflowRenderCompleted( ClipWorkflow* cw ) { + qDebug() << "clip workflow render complete. Checking for track completed"; if ( cw != NULL ) + { + qDebug() << " There is a complete buffer to return/////////////////////"; m_synchroneRenderBuffer = cw->getOutput(); + } else + { + qDebug() << "cw is null, no tracks to render/////////////////////////"; m_synchroneRenderBuffer = NULL; + } m_nbClipToRender.fetchAndAddAcquire( -1 ); //When there is nothing to render, m_nbClipToRender will be equal to one here, so we check for minus //or equal to 0 diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index b9ea2f718..4644e66ee 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -119,10 +119,10 @@ void MainWindow::setupLibrary() libraryWidget, SLOT( mediaRemoved( const QUuid& ) ) ); - connect( libraryWidget->getVideoListWidget(), SIGNAL( selectedMediaChanged(const Media*) ), - m_clipPreview->getGenericRenderer(), SLOT( setMedia(const Media*) ) ); - connect( Library::getInstance(), SIGNAL( mediaRemoved( const QUuid& ) ), - m_clipPreview->getGenericRenderer(), SLOT( mediaUnloaded( QUuid ) ) ); +// connect( libraryWidget->getVideoListWidget(), SIGNAL( selectedMediaChanged(const Media*) ), +// m_clipPreview->getGenericRenderer(), SLOT( setMedia(const Media*) ) ); +// connect( Library::getInstance(), SIGNAL( mediaRemoved( const QUuid& ) ), +// m_clipPreview->getGenericRenderer(), SLOT( mediaUnloaded( QUuid ) ) ); } void MainWindow::createStatusBar() @@ -153,12 +153,12 @@ void MainWindow::initializeDockWidgets( void ) QDockWidget::AllDockWidgetFeatures, Qt::TopDockWidgetArea); - m_clipPreview = new PreviewWidget( new ClipRenderer, this ); - dockManager->addDockedWidget( m_clipPreview, - tr( "Clip Preview" ), - Qt::AllDockWidgetAreas, - QDockWidget::AllDockWidgetFeatures, - Qt::TopDockWidgetArea ); +// m_clipPreview = new PreviewWidget( new ClipRenderer, this ); +// dockManager->addDockedWidget( m_clipPreview, +// tr( "Clip Preview" ), +// Qt::AllDockWidgetAreas, +// QDockWidget::AllDockWidgetFeatures, +// Qt::TopDockWidgetArea ); m_projectPreview = new PreviewWidget( new WorkflowRenderer( m_timeline->getMainWorkflow() ), this ); dockManager->addDockedWidget( m_projectPreview, diff --git a/src/renderer/WorkflowRenderer.cpp b/src/renderer/WorkflowRenderer.cpp index 6abac19b8..defa331af 100644 --- a/src/renderer/WorkflowRenderer.cpp +++ b/src/renderer/WorkflowRenderer.cpp @@ -84,11 +84,15 @@ WorkflowRenderer::~WorkflowRenderer() void* WorkflowRenderer::lock( void* datas ) { + qDebug() << "Locking workflow renderer"; WorkflowRenderer* self = reinterpret_cast( datas ); //If renderer is stopping, don't ask for another frame: if ( self->m_isRendering == false ) return self->m_lastFrame; + //If a pause was asked, don't try to start a new render... it could (and would) dead lock... + if ( self->m_pauseAsked == true ) + return self->m_lastFrame; //If we're not playing, then where in a paused media player. if ( self->m_pausedMediaPlayer == true ) { @@ -102,7 +106,7 @@ void* WorkflowRenderer::lock( void* datas ) // ret = self->m_mainWorkflow->getOutput(); // else // { -// qDebug() << "Asking synchrone frame"; + qDebug() << "Asking synchrone frame"; ret = self->m_mainWorkflow->getSynchroneOutput(); // } self->m_lastFrame = static_cast( ret ); @@ -119,6 +123,8 @@ void* WorkflowRenderer::lock( void* datas ) void WorkflowRenderer::unlock( void* datas ) { WorkflowRenderer* self = reinterpret_cast( datas ); + + qDebug() << "Workflowrenderer::unlock. m_oneFrameOnly ==" << self->m_oneFrameOnly; if ( self->m_oneFrameOnly == 1 ) { qDebug() << "Pausing back"; @@ -146,6 +152,7 @@ void WorkflowRenderer::checkActions() if ( m_pauseAsked == true ) continue ; m_pauseAsked = true; + qDebug() << "Pausing workflow renderer"; m_mediaPlayer->pause(); //This will also pause the MainWorkflow via a signal/slot break ; @@ -154,6 +161,7 @@ void WorkflowRenderer::checkActions() break ; } } + qDebug() << "End of method ----------------------------------------"; } void WorkflowRenderer::stopPreview() @@ -194,6 +202,7 @@ void WorkflowRenderer::frameByFrameAfterPaused() qDebug() << "Unpausing everything"; togglePlayPause( false ); + qDebug() << "Everything should be unpaused"; } void WorkflowRenderer::frameByFramePausingProxy() @@ -254,6 +263,7 @@ void WorkflowRenderer::togglePlayPause( bool forcePause ) if ( m_paused == true && forcePause == false ) { //This will automaticly unpause the ClipWorkflow... no worries + qDebug() << "Unpausing workflow renderer"; m_mediaPlayer->play(); } else @@ -301,6 +311,7 @@ void WorkflowRenderer::__positionChanged( float pos ) void WorkflowRenderer::__videoPaused() { + qDebug() << "Slot for media player paused"; if ( m_oneFrameOnly != 0 ) { m_oneFrameOnly = 0; -- GitLab