Commit 74e7599e authored by Hugo Beauzee-Luyssen's avatar Hugo Beauzee-Luyssen

Splitting audio and video when asking for a synchrone output

parent fcaf044e
......@@ -77,6 +77,9 @@ WorkflowRenderer::WorkflowRenderer() :
(qint64)m_audioEsHandler );
m_media->addOption( buffer );
m_media->addOption( ":vvvv" );
m_condMutex = new QMutex;
m_waitCond = new QWaitCondition;
......@@ -105,25 +108,39 @@ WorkflowRenderer::~WorkflowRenderer()
int WorkflowRenderer::lock( void *datas, int64_t *dts, int64_t *pts, unsigned int *flags, size_t *bufferSize, void **buffer )
{
static char computed = 0;
int ret = 1;
EsHandler* handler = reinterpret_cast<EsHandler*>( datas );
*dts = -1;
*flags = 0;
if ( handler->type == Video )
return lockVideo( handler->self, pts, bufferSize, buffer );
{
++computed;
ret = lockVideo( handler->self, pts, bufferSize, buffer );
}
else if ( handler->type == Audio )
return lockAudio( handler->self, pts, bufferSize, buffer );
qWarning() << "Invalid ES type";
return 1;
{
++computed;
ret = lockAudio( handler->self, pts, bufferSize, buffer );
}
else
qWarning() << "Invalid ES type";
if ( computed == 2 )
{
handler->self->m_mainWorkflow->goToNextFrame();
computed = 0;
}
return ret;
}
int WorkflowRenderer::lockVideo( WorkflowRenderer* self, int64_t *pts, size_t *bufferSize, void **buffer )
{
if ( self->m_stopping == false )
{
MainWorkflow::OutputBuffers* ret = self->m_mainWorkflow->getSynchroneOutput();
MainWorkflow::OutputBuffers* ret = self->m_mainWorkflow->getSynchroneOutput( MainWorkflow::VideoTrack );
memcpy( self->m_renderVideoFrame, (*(ret->video))->frame.octets, (*(ret->video))->nboctets );
self->m_videoBuffSize = (*(ret->video))->nboctets;
self->m_renderAudioSample = ret->audio;
}
*pts = ( self->m_pts * 1000000 ) / self->m_outputFps;
++self->m_pts;
......@@ -135,11 +152,18 @@ int WorkflowRenderer::lockVideo( WorkflowRenderer* self, int64_t *pts, size_
int WorkflowRenderer::lockAudio( WorkflowRenderer* self, int64_t *pts, size_t *bufferSize, void **buffer )
{
if ( self->m_paused == true )
return 1;
if ( self->m_stopping == false )
{
MainWorkflow::OutputBuffers* ret = self->m_mainWorkflow->getSynchroneOutput( MainWorkflow::AudioTrack );
self->m_renderAudioSample = ret->audio;
}
*buffer = self->m_renderAudioSample->buff;
*bufferSize = self->m_renderAudioSample->size;
*pts = ( self->m_audioPts * 1000000 ) / 48000;
// qDebug() << ">>>" << *pts;
self->m_audioPts += 2; //chanel number
*pts = (( self->m_audioPts * 1000000 ) / 48000 ) * self->m_renderAudioSample->nbSample;
self->m_audioPts += self->m_renderAudioSample->nbChannels;
qDebug() << "Video buffer size:" << *bufferSize;
return 0;
}
......
......@@ -77,7 +77,6 @@ void AudioClipWorkflow::initVlcOutput()
void AudioClipWorkflow::lock( AudioClipWorkflow* cw, uint8_t** pcm_buffer , unsigned int size )
{
// qDebug() << "<<<<<<<<<<<<<<<<<<<< state:" << cw->m_state;
if ( cw->m_buffer->buff == NULL )
{
cw->m_buffer->buff = new unsigned char[size];
......@@ -94,12 +93,17 @@ void AudioClipWorkflow::unlock( AudioClipWorkflow* cw, uint8_t* pcm_buffe
{
// qDebug() << "pts:" << pts << "nb channels" << channels << "rate:" << rate;
Q_UNUSED( pcm_buffer );
Q_UNUSED( channels );
Q_UNUSED( rate );
Q_UNUSED( nb_samples );
Q_UNUSED( bits_per_sample );
Q_UNUSED( size );
Q_UNUSED( pts );
if ( cw->m_buffer->buff != NULL )
{
cw->m_buffer->nbSample = nb_samples;
cw->m_buffer->nbChannels = channels;
}
cw->m_renderLock->unlock();
cw->m_stateLock->lockForWrite();
......
......@@ -32,6 +32,8 @@ class AudioClipWorkflow : public ClipWorkflow
{
unsigned char* buff;
size_t size;
unsigned int nbSample;
unsigned int nbChannels;
};
AudioClipWorkflow( Clip* clip );
~AudioClipWorkflow();
......
......@@ -59,9 +59,9 @@ MainWorkflow::MainWorkflow( int trackCount ) :
connect( m_tracks[i], SIGNAL( tracksEndReached() ), this, SLOT( tracksEndReached() ) );
}
m_outputBuffers = new OutputBuffers;
blackOutput = new LightVideoFrame( VIDEOHEIGHT * VIDEOWIDTH * Pixel::NbComposantes );
memset( (*blackOutput)->frame.octets, 0, (*blackOutput)->nboctets );
m_nbTrackHandlerToRenderMutex = new QMutex;
}
MainWorkflow::~MainWorkflow()
......@@ -69,6 +69,7 @@ MainWorkflow::~MainWorkflow()
//FIXME: this is probably useless, since already done by the renderer
stop();
delete m_nbTrackHandlerToRenderMutex;
delete m_effectEngine;
delete m_synchroneRenderWaitConditionMutex;
delete m_synchroneRenderWaitCondition;
......@@ -115,21 +116,27 @@ void MainWorkflow::startRender()
computeLength();
}
void MainWorkflow::getOutput()
void MainWorkflow::getOutput( TrackType trackType )
{
QReadLocker lock( m_renderStartedLock );
QMutexLocker lock2( m_renderMutex );
if ( m_renderStarted == true )
{
{
QReadLocker lock3( m_currentFrameLock );
QReadLocker lock3( m_currentFrameLock );
QMutexLocker lock4( m_nbTrackHandlerToRenderMutex );
if ( trackType == BothTrackType )
{
m_nbTrackHandlerToRender = MainWorkflow::NbTrackType;
for ( unsigned int i = 0; i < MainWorkflow::NbTrackType; ++i )
m_tracks[i]->getOutput( m_currentFrame );
}
if ( m_paused == false )
nextFrame();
else
{
m_nbTrackHandlerToRender = 1;
m_tracks[trackType]->getOutput( m_currentFrame );
}
}
}
......@@ -149,6 +156,12 @@ void MainWorkflow::unpause()
m_tracks[i]->unpause();
}
void MainWorkflow::goToNextFrame()
{
if ( m_paused == false )
nextFrame();
}
void MainWorkflow::nextFrame()
{
QWriteLocker lock( m_currentFrameLock );
......@@ -208,10 +221,10 @@ Clip* MainWorkflow::removeClip( const QUuid& uuid, unsigned int trackId, M
return clip;
}
MainWorkflow::OutputBuffers* MainWorkflow::getSynchroneOutput()
MainWorkflow::OutputBuffers* MainWorkflow::getSynchroneOutput( MainWorkflow::TrackType trackType )
{
m_synchroneRenderWaitConditionMutex->lock();
getOutput();
getOutput( trackType );
// qDebug() << "Waiting for sync output";
m_synchroneRenderWaitCondition->wait( m_synchroneRenderWaitConditionMutex );
// qDebug() << "Got it";
......@@ -221,9 +234,14 @@ MainWorkflow::OutputBuffers* MainWorkflow::getSynchroneOutput()
else
m_outputBuffers->video = &( m_effectEngine->getOutputFrame( 0 ) );
if ( trackType == BothTrackType || trackType == VideoTrack )
{
m_effectEngine->render();
m_outputBuffers->video = &( m_effectEngine->getOutputFrame( 0 ) );
}
if ( trackType == BothTrackType || trackType == AudioTrack )
m_outputBuffers->audio = m_tracks[MainWorkflow::AudioTrack]->getTmpAudioBuffer();
m_synchroneRenderWaitConditionMutex->unlock();
m_outputBuffers->video = &( m_effectEngine->getOutputFrame( 0 ) );
m_outputBuffers->audio = m_tracks[MainWorkflow::AudioTrack]->getTmpAudioBuffer();
return m_outputBuffers;
}
......@@ -408,9 +426,13 @@ void MainWorkflow::tracksUnpaused()
void MainWorkflow::tracksRenderCompleted()
{
for ( unsigned int i = 0; i < MainWorkflow::NbTrackType; ++i )
if ( m_tracks[i]->allTracksRendered() == false )
{
QMutexLocker lock( m_nbTrackHandlerToRenderMutex );
--m_nbTrackHandlerToRender;
if ( m_nbTrackHandlerToRender > 0 )
return ;
}
{
QMutexLocker lock( m_synchroneRenderWaitConditionMutex );
}
......
......@@ -51,6 +51,7 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
};
enum TrackType
{
BothTrackType = -1,
VideoTrack,
AudioTrack,
NbTrackType,
......@@ -66,10 +67,17 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
void addClip( Clip* clip, unsigned int trackId, qint64 start, TrackType type );
void startRender();
void getOutput();
OutputBuffers* getSynchroneOutput();
void getOutput( TrackType trackType );
OutputBuffers* getSynchroneOutput( TrackType trackType );
EffectsEngine* getEffectsEngine();
/**
* \brief This method is meant to make the workflow go to the next frame, only in rendering mode.
* The nextFrame() method will always go for the next frame, whereas this one only does when
* rendering isn't paused.
*/
void goToNextFrame();
/**
* \brief Set the workflow position by the desired frame
* \param currentFrame: The desired frame to render from
......@@ -155,6 +163,8 @@ class MainWorkflow : public QObject, public Singleton<MainWorkflow>
QMutex* m_renderMutex;
QWaitCondition* m_synchroneRenderWaitCondition;
QMutex* m_synchroneRenderWaitConditionMutex;
unsigned int m_nbTrackHandlerToRender;
QMutex* m_nbTrackHandlerToRenderMutex;
bool m_paused;
TrackHandler** m_tracks;
OutputBuffers* m_outputBuffers;
......
......@@ -97,6 +97,7 @@ void* VideoClipWorkflow::getOutput()
void VideoClipWorkflow::lock( VideoClipWorkflow* cw, void** pp_ret, int size )
{
qDebug() << "Outputing video buffers. Size:" << size;
Q_UNUSED( size );
cw->m_renderLock->lock();
*pp_ret = (*(cw->m_buffer))->frame.pixels;
......@@ -104,6 +105,7 @@ void VideoClipWorkflow::lock( VideoClipWorkflow* cw, void** pp_ret, int size
void VideoClipWorkflow::unlock( VideoClipWorkflow* cw, void* buffer, int width, int height, int bpp, int size )
{
qDebug() << "size on unlock:" << size;
Q_UNUSED( buffer );
Q_UNUSED( width );
Q_UNUSED( height );
......
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