Commit 3865376a authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen

More refactoring on the new clip workflows.

StackedBuffer are used now, on the clipworkflow's side.
parent ee8974cc
......@@ -32,7 +32,16 @@ template <typename T>
class Pool
{
public:
T get()
Pool()
{
m_mutex = new QMutex;
}
~Pool()
{
Q_ASSERT( m_pool.empty() == true );
delete m_mutex;
}
T pop()
{
QMutexLocker lock( m_mutex );
if ( m_pool.size() == 0 )
......@@ -43,22 +52,32 @@ public:
T ret = m_pool.dequeue();
return ret;
}
T head()
{
QMutexLocker lock( m_mutex );
return m_pool.head();
}
int count() const
{
return m_pool.count();
}
void release( T toRelease )
{
QMutexLocker lock( m_mutex );
m_pool.enqueue( toRelease );
}
private:
Pool()
bool isEmpty() const
{
m_mutex = new QMutex;
return m_pool.empty();
}
~Pool()
void push_back( const T& val )
{
Q_ASSERT( m_pool.empty() == true );
delete m_mutex;
m_pool.push_back( val );
}
QQueue<uint8_t*> m_pool;
private:
QQueue<T> m_pool;
QMutex* m_mutex;
};
......
......@@ -23,19 +23,23 @@
#include <QtDebug>
#include "AudioClipWorkflow.h"
#include "StackedBuffer.hpp"
AudioClipWorkflow::AudioClipWorkflow( Clip* clip ) :
ClipWorkflow( clip )
{
m_buffer = new AudioSample;
m_buffer->buff = NULL;
m_availableBuffersLock = new QReadWriteLock;
m_computedBuffersLock = new QReadWriteLock;
}
AudioClipWorkflow::~AudioClipWorkflow()
{
if ( m_buffer->buff != NULL )
delete[] m_buffer->buff;
delete m_buffer;
while ( m_availableBuffers.isEmpty() == false )
delete m_availableBuffers.pop();
while ( m_computedBuffers.isEmpty() == false )
delete m_computedBuffers.pop();
delete m_availableBuffersLock;
delete m_computedBuffersLock;
}
void* AudioClipWorkflow::getLockCallback()
......@@ -48,7 +52,7 @@ void* AudioClipWorkflow::getUnlockCallback()
return reinterpret_cast<void*>(&AudioClipWorkflow::unlock);
}
void* AudioClipWorkflow::getOutput()
void* AudioClipWorkflow::getOutput( ClipWorkflow::GetMode mode )
{
QMutexLocker lock( m_renderLock );
......@@ -57,7 +61,10 @@ void* AudioClipWorkflow::getOutput()
qDebug() << "Audio end reached";
return NULL;
}
return m_buffer;
if ( mode == ClipWorkflow::Get )
qCritical() << "A sound buffer should never be asked with 'Get' mode";
StackedBuffer<AudioSample*>* buff = new StackedBuffer<AudioSample*>( m_computedBuffers.pop(), &m_availableBuffers, true );
return buff;
}
void AudioClipWorkflow::initVlcOutput()
......@@ -75,13 +82,21 @@ void AudioClipWorkflow::initVlcOutput()
void AudioClipWorkflow::lock( AudioClipWorkflow* cw, uint8_t** pcm_buffer , unsigned int size )
{
if ( cw->m_buffer->buff == NULL )
//If there's no buffer at all, it must be the first render
if ( cw->m_availableBuffers.count() == 0 && cw->m_computedBuffers.count() == 0 )
{
cw->m_buffer->buff = new unsigned char[size];
cw->m_buffer->size = size;
for ( unsigned int i = 0; i < AudioClipWorkflow::nbBuffers; ++i )
{
AudioSample* as = new AudioSample;
as->buff = new uchar[size];
as->size = size;
cw->m_availableBuffers.push_back( as );
}
}
cw->m_renderLock->lock();
*pcm_buffer = cw->m_buffer->buff;
AudioSample* as = cw->m_availableBuffers.pop();
cw->m_computedBuffers.push_back( as );
*pcm_buffer = as->buff;
}
void AudioClipWorkflow::unlock( AudioClipWorkflow* cw, uint8_t* pcm_buffer,
......@@ -96,15 +111,15 @@ void AudioClipWorkflow::unlock( AudioClipWorkflow* cw, uint8_t* pcm_buffe
Q_UNUSED( bits_per_sample );
Q_UNUSED( size );
cw->m_renderLock->unlock();
cw->computePtsDiff( pts );
if ( cw->m_buffer->buff != NULL )
AudioSample* as = cw->m_computedBuffers.head();
if ( as->buff != NULL )
{
cw->m_buffer->nbSample = nb_samples;
cw->m_buffer->nbChannels = channels;
cw->m_buffer->ptsDiff = cw->m_currentPts - cw->m_previousPts;
as->nbSample = nb_samples;
as->nbChannels = channels;
as->ptsDiff = cw->m_currentPts - cw->m_previousPts;
}
cw->m_renderLock->unlock();
cw->commonUnlock();
}
......@@ -24,6 +24,7 @@
#define AUDIOCLIPWORKFLOW_H
#include "ClipWorkflow.h"
#include "Pool.hpp"
class AudioClipWorkflow : public ClipWorkflow
{
......@@ -40,17 +41,22 @@ class AudioClipWorkflow : public ClipWorkflow
~AudioClipWorkflow();
void* getLockCallback();
void* getUnlockCallback();
virtual void* getOutput();
virtual void* getOutput( ClipWorkflow::GetMode mode );
private:
//FIXME: this should be temporary
AudioSample* m_buffer;
QReadWriteLock* m_computedBuffersLock;
Pool<AudioSample*> m_computedBuffers;
QReadWriteLock* m_availableBuffersLock;
Pool<AudioSample*> m_availableBuffers;
void initVlcOutput();
static void lock( AudioClipWorkflow* clipWorkflow, uint8_t** pcm_buffer , unsigned int size );
static void unlock( AudioClipWorkflow* clipWorkflow, uint8_t* pcm_buffer,
unsigned int channels, unsigned int rate,
unsigned int nb_samples, unsigned int bits_per_sample,
unsigned int size, qint64 pts );
//FIXME: this is totally random powered ! Please adjust with a value that does make sense...
static const uint32_t nbBuffers = 128;
};
#endif // AUDIOCLIPWORKFLOW_H
......@@ -71,7 +71,7 @@ class ClipWorkflow : public QObject
* therefore, you can call this method blindly, without taking care
* of the rendering process advancement.
*/
virtual void* getOutput() = 0;
virtual void* getOutput( ClipWorkflow::GetMode mode ) = 0;
virtual void initVlcOutput() = 0;
void initialize( bool preloading = false );
......
......@@ -25,11 +25,6 @@
#include "Pool.hpp"
/**
* This class is to be used closely with the templated Pool.
* When release, the buffer will automatically pushed itself back into the appropriate pool.
*/
template <typename T>
class StackedBuffer
{
......@@ -37,18 +32,16 @@ class StackedBuffer
StackedBuffer( T buff, Pool<T>* pool, bool mustBeReleased = true ) :
m_buff( buff ),
m_pool( pool ),
m_released( false ),
m_mustRelease( mustBeReleased )
{
}
/// \warning Calling this method will definitely invalidate the pointer;
void release()
{
Q_ASSERT( m_released == false );
Q_ASSERT( m_mustRelease == true );
m_released = true;
m_pool->release( m_buff );
if ( m_mustRelease == true )
m_pool->release( m_buff );
delete this;
}
const T& get() const
{
......@@ -70,7 +63,6 @@ class StackedBuffer
private:
T m_buff;
Pool<T>* m_pool;
bool m_released;
bool m_mustRelease;
};
......
......@@ -476,7 +476,7 @@ void TrackWorkflow::clipWorkflowRenderCompleted( ClipWorkflow* cw )
// qDebug() << "Clip [" << QObject::sender() << "] render is completed on track" << m_trackId;
if ( cw != NULL )
{
m_synchroneRenderBuffer = cw->getOutput();
m_synchroneRenderBuffer = cw->getOutput( ClipWorkflow::Pop );
}
else
{
......
......@@ -22,17 +22,29 @@
#include "VideoClipWorkflow.h"
#include "MainWorkflow.h"
#include "StackedBuffer.hpp"
VideoClipWorkflow::VideoClipWorkflow( Clip* clip ) : ClipWorkflow( clip )
{
m_buffer = new LightVideoFrame( MainWorkflow::getInstance()->getWidth()
for ( unsigned int i = 0; i < VideoClipWorkflow::nbBuffers; ++i )
{
//Actually we don't release, we extend pool, but the release method do exactly what we want.
m_availableBuffers.push_back( new LightVideoFrame( MainWorkflow::getInstance()->getWidth()
* MainWorkflow::getInstance()->getHeight()
* Pixel::NbComposantes );
* Pixel::NbComposantes ) );
}
// m_availableBuffersLock = new QReadWriteLock;
// m_computedBuffersLock = new QReadWriteLock;
}
VideoClipWorkflow::~VideoClipWorkflow()
{
delete m_buffer;
while ( m_availableBuffers.isEmpty() == false )
delete m_availableBuffers.pop();
while ( m_computedBuffers.isEmpty() == false )
delete m_computedBuffers.pop();
// delete m_availableBuffersLock;
// delete m_computedBuffersLock;
}
void VideoClipWorkflow::initVlcOutput()
......@@ -72,20 +84,27 @@ void* VideoClipWorkflow::getUnlockCallback()
return reinterpret_cast<void*>( &VideoClipWorkflow::unlock );
}
void* VideoClipWorkflow::getOutput()
void* VideoClipWorkflow::getOutput( ClipWorkflow::GetMode mode )
{
QMutexLocker lock( m_renderLock );
if ( isEndReached() == true )
return NULL;
return m_buffer;
StackedBuffer<LightVideoFrame*>* buff;
if ( mode == ClipWorkflow::Pop )
buff = new StackedBuffer<LightVideoFrame*>( m_computedBuffers.pop(), &m_availableBuffers, true );
else if ( mode == ClipWorkflow::Get )
buff = new StackedBuffer<LightVideoFrame*>( m_computedBuffers.head(), NULL, false );
return buff;
}
void VideoClipWorkflow::lock( VideoClipWorkflow* cw, void** pp_ret, int size )
{
Q_UNUSED( size );
cw->m_renderLock->lock();
*pp_ret = (*(cw->m_buffer))->frame.octets;
LightVideoFrame* lvf = cw->m_availableBuffers.pop();
cw->m_computedBuffers.push_back( lvf );
*pp_ret = (*(lvf))->frame.octets;
}
void VideoClipWorkflow::unlock( VideoClipWorkflow* cw, void* buffer, int width, int height, int bpp, int size, qint64 pts )
......@@ -96,10 +115,10 @@ void VideoClipWorkflow::unlock( VideoClipWorkflow* cw, void* buffer, int widt
Q_UNUSED( bpp );
Q_UNUSED( size );
cw->m_renderLock->unlock();
cw->computePtsDiff( pts );
(*(cw->m_buffer))->ptsDiff = cw->m_currentPts - cw->m_previousPts;
LightVideoFrame* lvf = cw->m_computedBuffers.head();
(*(lvf))->ptsDiff = cw->m_currentPts - cw->m_previousPts;
cw->m_renderLock->unlock();
cw->commonUnlock();
}
......@@ -35,7 +35,7 @@ class VideoClipWorkflow : public ClipWorkflow
~VideoClipWorkflow();
void* getLockCallback();
void* getUnlockCallback();
virtual void* getOutput();
virtual void* getOutput( ClipWorkflow::GetMode mode );
static const uint32_t nbBuffers = 3 * 30; //3 seconds with an average fps of 30
......@@ -43,7 +43,11 @@ class VideoClipWorkflow : public ClipWorkflow
virtual void initVlcOutput();
private:
LightVideoFrame* m_buffer;
// Pool<LightVideoFrame*> m_pool;
// QReadWriteLock* m_computedBuffersLock;
Pool<LightVideoFrame*> m_computedBuffers;
// QReadWriteLock* m_availableBuffersLock;
Pool<LightVideoFrame*> m_availableBuffers;
static void lock( VideoClipWorkflow* clipWorkflow, void** pp_ret, int size );
static void unlock( VideoClipWorkflow* clipWorkflow, void* buffer, int width, int height, int bpp, int size, qint64 pts );
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment