[vlmc-devel] [PATCH 06/10] Use ClipSmemRenderer
Yikai Lu
luyikei.qmltu at gmail.com
Wed May 4 16:18:37 CEST 2016
---
src/CMakeLists.txt | 4 +-
src/Renderer/ClipSmemRenderer.cpp | 4 +-
src/Workflow/ClipWorkflow.cpp | 100 ++++++++++++++++++++------------------
src/Workflow/ClipWorkflow.h | 47 ++++--------------
src/Workflow/TrackWorkflow.cpp | 47 ++++++------------
src/Workflow/TrackWorkflow.h | 2 +-
6 files changed, 83 insertions(+), 121 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 75d6679..9b1a88d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -66,6 +66,7 @@ SET(VLMC_SRCS
Project/WorkspaceWorker.cpp
Project/RecentProjects.cpp
Renderer/AbstractRenderer.cpp
+ Renderer/ClipSmemRenderer.cpp
Renderer/WorkflowRenderer.cpp
Services/AbstractSharingService.h
Services/UploaderIODevice.cpp
@@ -78,15 +79,12 @@ SET(VLMC_SRCS
Tools/Toggleable.hpp
Tools/VlmcDebug.h
Tools/VlmcLogger.cpp
- Workflow/AudioClipWorkflow.cpp
Workflow/ClipWorkflow.cpp
Workflow/ClipHelper.cpp
Workflow/Helper.cpp
- Workflow/ImageClipWorkflow.cpp
Workflow/MainWorkflow.cpp
Workflow/TrackWorkflow.cpp
Workflow/Types.cpp
- Workflow/VideoClipWorkflow.cpp
)
IF (WIN32)
diff --git a/src/Renderer/ClipSmemRenderer.cpp b/src/Renderer/ClipSmemRenderer.cpp
index 5565d5b..b44c7cf 100644
--- a/src/Renderer/ClipSmemRenderer.cpp
+++ b/src/Renderer/ClipSmemRenderer.cpp
@@ -264,7 +264,7 @@ ClipSmemRenderer::audioUnlock( void *data, uint8_t *pcm_buffer, unsigned int cha
ClipSmemRenderer* renderer = reinterpret_cast<ClipSmemRenderer*>( data );
Workflow::Frame *frame = renderer->m_computedBuffers[Workflow::AudioTrack].last();
- frame->pts = pts;
+ frame->setPts( pts );
renderer->m_renderWaitCond[Workflow::AudioTrack]->wakeAll();
if ( maxNumBuffers( Workflow::AudioTrack ) <= renderer->m_computedBuffers[Workflow::AudioTrack].count() )
emit renderer->bufferReachedMax();
@@ -308,7 +308,7 @@ ClipSmemRenderer::videoUnlock( void *data, uint8_t *buffer, int width, int heigh
ClipSmemRenderer* renderer = reinterpret_cast<ClipSmemRenderer*>( data );
Workflow::Frame *frame = renderer->m_computedBuffers[Workflow::VideoTrack].last();
- frame->pts = pts;
+ frame->setPts( pts );
renderer->m_renderWaitCond[Workflow::VideoTrack]->wakeAll();
if ( maxNumBuffers( Workflow::VideoTrack ) <= renderer->m_computedBuffers[Workflow::VideoTrack].count() )
emit renderer->bufferReachedMax();
diff --git a/src/Workflow/ClipWorkflow.cpp b/src/Workflow/ClipWorkflow.cpp
index f7fa55c..c272c48 100644
--- a/src/Workflow/ClipWorkflow.cpp
+++ b/src/Workflow/ClipWorkflow.cpp
@@ -31,6 +31,7 @@
#include "ClipWorkflow.h"
#include "Backend/ISource.h"
#include "Backend/ISourceRenderer.h"
+#include "Renderer/ClipSmemRenderer.h"
#include "Media/Media.h"
#include "Tools/RendererEventWatcher.h"
#include "Workflow/Types.h"
@@ -61,30 +62,53 @@ ClipWorkflow::~ClipWorkflow()
delete m_stateLock;
}
+Workflow::Frame*
+ClipWorkflow::getOutput( Workflow::TrackType trackType, ClipSmemRenderer::GetMode mode, qint64 currentFrame )
+{
+ if ( m_clipHelper->clip()->media()->fileType() == Media::Image )
+ mode = ClipSmemRenderer::Get;
+
+ auto ret = m_renderer->getOutput( trackType, mode, currentFrame );
+ if ( ret )
+ {
+ computePtsDiff( ret->pts(), trackType );
+ ret->ptsDiff = m_currentPts[trackType] - m_previousPts[trackType];
+ }
+ if ( trackType == Workflow::VideoTrack )
+ {
+ auto newFrame = applyFilters( ret, currentFrame );
+ if ( newFrame != nullptr )
+ ret->setBuffer( newFrame );
+ }
+
+ return ret;
+}
+
void
-ClipWorkflow::initialize()
+ClipWorkflow::initialize( quint32 width, quint32 height )
{
QWriteLocker lock( m_stateLock );
m_state = ClipWorkflow::Initializing;
delete m_renderer;
- m_renderer = m_clipHelper->clip()->media()->source()->createRenderer( m_eventWatcher );
-
- preallocate();
- initializeInternals();
+ m_renderer = new ClipSmemRenderer( m_clipHelper, width, height );
+ if ( m_clipHelper->formats() & ClipHelper::Video )
+ initFilters();
- m_currentPts = -1;
- m_previousPts = -1;
+ for ( int i = 0; i < Workflow::NbTrackType; ++i )
+ {
+ m_currentPts[i] = -1;
+ m_previousPts[i] = -1;
+ }
m_pauseDuration = -1;
//Use QueuedConnection to avoid getting called from intf-event callback, as
//we will trigger intf-event callback as well when setting time for this clip,
//thus resulting in a deadlock.
- connect( m_eventWatcher, SIGNAL( playing() ), this, SLOT( loadingComplete() ), Qt::QueuedConnection );
- connect( m_eventWatcher, SIGNAL( endReached() ), this, SLOT( clipEndReached() ), Qt::DirectConnection );
- connect( m_eventWatcher, SIGNAL( errorEncountered() ), this, SLOT( errorEncountered() ) );
- connect( m_eventWatcher, &RendererEventWatcher::stopped, this, &ClipWorkflow::mediaPlayerStopped );
- connect( this, &ClipWorkflow::bufferReachedMax, this, &ClipWorkflow::pause, Qt::QueuedConnection );
+ connect( m_renderer->eventWatcher(), SIGNAL( playing() ), this, SLOT( loadingComplete() ), Qt::QueuedConnection );
+ connect( m_renderer->eventWatcher(), SIGNAL( endReached() ), this, SLOT( clipEndReached() ), Qt::DirectConnection );
+ connect( m_renderer->eventWatcher(), SIGNAL( errorEncountered() ), this, SLOT( errorEncountered() ) );
+ connect( m_renderer->eventWatcher(), &RendererEventWatcher::stopped, this, &ClipWorkflow::mediaPlayerStopped );
m_renderer->start();
}
@@ -92,9 +116,9 @@ void
ClipWorkflow::loadingComplete()
{
adjustBegin();
- disconnect( m_eventWatcher, SIGNAL( playing() ), this, SLOT( loadingComplete() ) );
- connect( m_eventWatcher, SIGNAL( playing() ), this, SLOT( mediaPlayerUnpaused() ), Qt::DirectConnection );
- connect( m_eventWatcher, SIGNAL( paused() ), this, SLOT( mediaPlayerPaused() ), Qt::DirectConnection );
+ disconnect( m_renderer->eventWatcher(), SIGNAL( playing() ), this, SLOT( loadingComplete() ) );
+ connect( m_renderer->eventWatcher(), SIGNAL( playing() ), this, SLOT( mediaPlayerUnpaused() ), Qt::DirectConnection );
+ connect( m_renderer->eventWatcher(), SIGNAL( paused() ), this, SLOT( mediaPlayerPaused() ), Qt::DirectConnection );
QWriteLocker lock( m_stateLock );
m_isRendering = true;
m_state = Rendering;
@@ -132,15 +156,6 @@ ClipWorkflow::stop()
}
void
-ClipWorkflow::pause()
-{
- if ( m_renderer != nullptr ) {
- m_renderer->setPause( true );
- vlmcWarning() << "ClipWorkflow:" << m_clipHelper->uuid() << " was paused unexpectedly";
- }
-}
-
-void
ClipWorkflow::setTime( qint64 time )
{
vlmcDebug() << "Setting ClipWorkflow" << m_clipHelper->uuid() << "time:" << time;
@@ -165,34 +180,24 @@ ClipWorkflow::waitForCompleteInit()
}
void
-ClipWorkflow::postGetOutput()
-{
- //If we're running out of computed buffers, refill our stack.
- if ( getNbComputedBuffers() < getMaxComputedBuffers() / 3 )
- m_renderer->setPause( false );
- //Don't test using availableBuffer, as it may evolve if a buffer is required while
- //no one is available : we would spawn a new buffer, thus modifying the number of available buffers
- else if ( getNbComputedBuffers() >= getMaxComputedBuffers() )
- {
- // It's OK to check from here: if getOutput is not called, it means the clipworkflow is
- // stopped or preloading, in which case, we don't care about the buffer queue growing uncontrolled
- m_renderer->setPause( true );
- }
-}
-
-void
-ClipWorkflow::computePtsDiff( qint64 pts )
+ClipWorkflow::computePtsDiff( qint64 pts, Workflow::TrackType trackType )
{
if ( m_pauseDuration != -1 )
{
//No need to check for m_currentPtr before, as we can't start in paused mode.
//so m_currentPts will not be -1
- m_previousPts = m_currentPts + m_pauseDuration;
+ m_previousPts[trackType] = m_currentPts[trackType] + m_pauseDuration;
m_pauseDuration = -1;
}
else
- m_previousPts = m_currentPts;
- m_currentPts = qMax( pts, m_previousPts );
+ m_previousPts[trackType] = m_currentPts[trackType];
+ m_currentPts[trackType] = qMax( pts, m_previousPts[trackType] );
+}
+
+void
+ClipWorkflow::flushComputedBuffers()
+{
+ m_renderer->flushComputedBuffers();
}
void
@@ -226,8 +231,11 @@ void
ClipWorkflow::resyncClipWorkflow()
{
flushComputedBuffers();
- m_previousPts = -1;
- m_currentPts = -1;
+ for ( int i = 0; i < Workflow::NbTrackType; ++i )
+ {
+ m_currentPts[i] = -1;
+ m_previousPts[i] = -1;
+ }
}
void
diff --git a/src/Workflow/ClipWorkflow.h b/src/Workflow/ClipWorkflow.h
index 5419a23..0b812e7 100644
--- a/src/Workflow/ClipWorkflow.h
+++ b/src/Workflow/ClipWorkflow.h
@@ -28,6 +28,7 @@
#include "EffectsEngine/EffectUser.h"
#include "ClipHelper.h"
#include "Workflow/Types.h"
+#include "Renderer/ClipSmemRenderer.h"
#include <QObject>
#include <QUuid>
@@ -78,17 +79,6 @@ class ClipWorkflow : public EffectUser
Error //5
};
- /**
- * \brief Used to know which way you want to get a computed output.
- * Pop: the buffer is popped and returned
- * Get: the buffer is just returned (for paused mode for instance)
- */
- enum GetMode
- {
- Pop,
- Get,
- };
-
ClipWorkflow( ClipHelper* clip );
virtual ~ClipWorkflow();
@@ -97,18 +87,14 @@ class ClipWorkflow : public EffectUser
* therefore, you can call this method blindly, without taking care
* of the rendering process advancement.
*/
- virtual Workflow::OutputBuffer *getOutput( ClipWorkflow::GetMode mode, qint64 currentFrame ) = 0;
- virtual Workflow::TrackType type() const = 0;
- void postGetOutput();
+ Workflow::Frame* getOutput( Workflow::TrackType trackType, ClipSmemRenderer::GetMode mode, qint64 currentFrame );
/**
* @brief Initialize base variables for the SourceRenderer.
*
* This may also perform some addditional initializations, and
* therefore should be called before createSoutChain()
*/
- virtual void initializeInternals() = 0;
- virtual void preallocate() = 0;
- void initialize();
+ void initialize( quint32 width, quint32 height );
/**
* \return true if the ClipWorkflow is able to, and should render
@@ -143,11 +129,6 @@ class ClipWorkflow : public EffectUser
void stop();
/**
- * \brief Pause this workflow.
- */
- void pause();
-
- /**
* \brief Set the rendering position
* \param time The position in millisecond
* \param frame The new current frame.
@@ -181,25 +162,15 @@ class ClipWorkflow : public EffectUser
void adjustBegin();
protected:
- void computePtsDiff( qint64 pts );
- /**
- * \warning Must be called from a thread safe context.
- * This thread safe context has to be set
- * from the underlying ClipWorkflow implementation.
- */
- virtual quint32 getNbComputedBuffers() const = 0;
- virtual quint32 getMaxComputedBuffers() const = 0;
+ void computePtsDiff( qint64 pts , Workflow::TrackType trackType );
+
/**
* \brief Will empty the computed buffers stack.
* This has to be implemented in the underlying
* clipworkflow implementation.
*/
- virtual void flushComputedBuffers() = 0;
+ void flushComputedBuffers();
- /**
- * \brief Release the preallocated buffers
- */
- virtual void releasePrealocated() = 0;
private:
/**
@@ -217,14 +188,14 @@ class ClipWorkflow : public EffectUser
bool m_resyncRequired;
protected:
- Backend::ISourceRenderer* m_renderer;
+ ClipSmemRenderer* m_renderer;
RendererEventWatcher* m_eventWatcher;
ClipHelper* m_clipHelper;
QMutex* m_renderLock;
QReadWriteLock* m_stateLock;
State m_state;
- qint64 m_previousPts;
- qint64 m_currentPts;
+ qint64 m_previousPts[Workflow::NbTrackType];
+ qint64 m_currentPts[Workflow::NbTrackType];
/**
* \brief This is used for basic synchronisation when
* the clipworkflow hasn't generate a frame yet,
diff --git a/src/Workflow/TrackWorkflow.cpp b/src/Workflow/TrackWorkflow.cpp
index f40ed4c..9d34269 100644
--- a/src/Workflow/TrackWorkflow.cpp
+++ b/src/Workflow/TrackWorkflow.cpp
@@ -26,17 +26,15 @@
#include "Project/Project.h"
#include "Media/Clip.h"
#include "ClipHelper.h"
-#include "AudioClipWorkflow.h"
+#include "ClipWorkflow.h"
#include "EffectsEngine/EffectInstance.h"
#include "EffectsEngine/EffectHelper.h"
-#include "ImageClipWorkflow.h"
#include "Backend/ISource.h"
#include "Main/Core.h"
#include "Library/Library.h"
#include "MainWorkflow.h"
#include "Media/Media.h"
#include "Types.h"
-#include "VideoClipWorkflow.h"
#include "vlmc.h"
#include "Tools/VlmcDebug.h"
@@ -80,22 +78,7 @@ TrackWorkflow::~TrackWorkflow()
void
TrackWorkflow::addClip( ClipHelper* ch, qint64 start )
{
- ClipWorkflow* cw;
- if ( ch->clip()->media()->fileType() == Media::FileType::Video )
- // FIXME: This whole if statement will be gone as soon as I implement a united ClipWorkflow,
- // which can generate both audio and video buffers.
- if ( ch->formats() & ClipHelper::Video )
- cw = new VideoClipWorkflow( ch );
- else if ( ch->formats() & ClipHelper::Audio )
- cw = new AudioClipWorkflow( ch );
- else
- vlmcFatal( "Nothing to render from this clip!" );
- else if ( ch->clip()->media()->fileType() == Media::FileType::Audio )
- cw = new AudioClipWorkflow( ch );
- else if ( ch->clip()->media()->fileType() == Media::FileType::Image )
- cw = new ImageClipWorkflow( ch );
- else
- vlmcFatal( "Unknown file type!" );
+ ClipWorkflow* cw = new ClipWorkflow( ch );
ch->setClipWorkflow( cw );
addClip( cw, start );
}
@@ -180,15 +163,15 @@ TrackWorkflow::getClipHelper( const QUuid& uuid )
}
Workflow::OutputBuffer*
-TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentFrame,
+TrackWorkflow::renderClip( Workflow::TrackType trackType, ClipWorkflow* cw, qint64 currentFrame,
qint64 start , bool needRepositioning,
bool renderOneFrame, bool paused )
{
if ( cw->isMuted() == true )
return nullptr;
- ClipWorkflow::GetMode mode = ( paused == false || renderOneFrame == true ?
- ClipWorkflow::Pop : ClipWorkflow::Get );
+ ClipSmemRenderer::GetMode mode = ( paused == false || renderOneFrame == true ?
+ ClipSmemRenderer::Pop : ClipSmemRenderer::Get );
ClipWorkflow::State state = cw->getState();
if ( state == ClipWorkflow::Rendering ||
@@ -196,12 +179,12 @@ TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentFrame,
{
if ( cw->isResyncRequired() == true || needRepositioning == true )
adjustClipTime( currentFrame, start, cw );
- return cw->getOutput( mode, currentFrame - start );
+ return cw->getOutput( trackType, mode, currentFrame - start );
}
else if ( state == ClipWorkflow::Stopped || state == ClipWorkflow::Initializing )
{
if ( state == ClipWorkflow::Stopped )
- cw->initialize();
+ cw->initialize( m_width, m_height );
//If the init failed, don't even try to call getOutput.
if ( cw->waitForCompleteInit() == false )
return nullptr;
@@ -211,7 +194,7 @@ TrackWorkflow::renderClip( ClipWorkflow* cw, qint64 currentFrame,
//Clip was not started at its real begining: adjust the position
adjustClipTime( currentFrame, start, cw );
}
- return cw->getOutput( mode, currentFrame - start );
+ return cw->getOutput( trackType, mode, currentFrame - start );
}
else if ( state == ClipWorkflow::EndReached ||
state == ClipWorkflow::Error )
@@ -230,7 +213,7 @@ void
TrackWorkflow::preloadClip( ClipWorkflow* cw )
{
if ( cw->getState() == ClipWorkflow::Stopped )
- cw->initialize();
+ cw->initialize( m_width, m_height );
}
void
@@ -310,17 +293,19 @@ TrackWorkflow::getOutput( Workflow::TrackType trackType, qint64 currentFrame, qi
qint64 start = it.key();
ClipWorkflow* cw = it.value();
- if ( trackType != cw->type() )
+ if ( ( trackType == Workflow::VideoTrack && cw->getClipHelper()->formats().testFlag( ClipHelper::Video ) == false ) ||
+ ( trackType == Workflow::AudioTrack && cw->getClipHelper()->formats().testFlag( ClipHelper::Audio ) == false ) ||
+ cw->getClipHelper()->formats().testFlag( ClipHelper::None )
+ )
{
++it;
continue ;
}
-
//Is the clip supposed to render now?
if ( start <= currentFrame && currentFrame <= start + cw->getClipHelper()->length() )
{
- ret = renderClip( cw, currentFrame, start, needRepositioning,
- renderOneFrame, paused );
+ ret = renderClip( trackType, cw, currentFrame, start, needRepositioning,
+ renderOneFrame, paused );
if ( trackType == Workflow::VideoTrack )
{
frames[frameId] = static_cast<Workflow::Frame*>( ret );
@@ -613,7 +598,7 @@ TrackWorkflow::initRender( quint32 width, quint32 height )
{
QReadLocker lock( m_clipsLock );
- m_mixerBuffer->resize( width, height );
+ m_mixerBuffer->resize( width * height * Workflow::Depth );
m_width = width;
m_height = height;
m_isRendering = true;
diff --git a/src/Workflow/TrackWorkflow.h b/src/Workflow/TrackWorkflow.h
index d9369d2..dff05b0 100644
--- a/src/Workflow/TrackWorkflow.h
+++ b/src/Workflow/TrackWorkflow.h
@@ -102,7 +102,7 @@ class TrackWorkflow : public EffectUser
private:
void computeLength();
- Workflow::OutputBuffer *renderClip( ClipWorkflow* cw, qint64 currentFrame,
+ Workflow::OutputBuffer *renderClip( Workflow::TrackType trackType, ClipWorkflow* cw, qint64 currentFrame,
qint64 start, bool needRepositioning,
bool renderOneFrame, bool paused );
void preloadClip( ClipWorkflow* cw );
--
1.9.1
More information about the Vlmc-devel
mailing list