Commit f0c8aec2 authored by Christophe Courtaut's avatar Christophe Courtaut

More Thread Safe way to compute metadata

parent 5b1ec1ac
......@@ -232,7 +232,6 @@ void Media::emitSnapshotComputed()
if ( m_metadataState == ParsedWithoutSnapshot )
m_metadataState = ParsedWithSnapshot;
emit snapshotComputed( this );
disconnect( this, SIGNAL( snapshotComputed( Media* ) ), MetaDataManager::getInstance(), SLOT( checkMediasToCompute() ) );
}
Media::InputType Media::getInputType() const
......
......@@ -23,7 +23,10 @@
#include "MetaDataManager.h"
#include "MetaDataWorker.h"
#include "vlmc.h"
#include <QMap>
#include <QDebug>
MetaDataManager::MetaDataManager() : m_mediaPlayersMaxCount( DEFAULT_MAX_MEDIA_PLAYER ), m_mediaPlayersToRemove( 0 )
{
......@@ -31,6 +34,14 @@ MetaDataManager::MetaDataManager() : m_mediaPlayersMaxCount( DEFAULT_MAX_MEDIA_P
addMediaPlayer();
}
MetaDataManager::~MetaDataManager()
{
while ( m_mediaPlayers.count(Running) )
SleepMS(1);
while ( LibVLCpp::MediaPlayer* mediaPlayer = m_mediaPlayers.take( Idle ) )
delete mediaPlayer;
}
void MetaDataManager::addMediaPlayer()
{
if ( m_mediaPlayers.count() <= m_mediaPlayersMaxCount )
......@@ -80,47 +91,70 @@ int MetaDataManager::mediaPlayersMaxCount() const
void MetaDataManager::computeMediaMetadata( Media *media )
{
m_mediasToComputeMetaData.enqueue( media );
{
QMutexLocker lock(&m_mediasToComputeMetaDataMutex);
m_mediasToComputeMetaData.enqueue( media );
}
checkMediasToCompute();
}
void MetaDataManager::checkMediasToCompute()
{
qDebug() << "checking media to compute" << m_mediasToComputeMetaData << m_mediasToComputeSnapshot;
m_mediasToComputeMetaDataMutex.lock();
m_mediasToComputeSnapshotMutex.lock();
m_mediaPlayersMutex.lock();
QMap<MediaPlayerState, LibVLCpp::MediaPlayer*>::iterator it;
if ( m_mediasToComputeMetaData.count() > 0 &&
( it = m_mediaPlayers.find( Idle ) ) != m_mediaPlayers.end() )
{
Media* media;
media = m_mediasToComputeMetaData.dequeue();
m_mediasToComputeSnapshot.enqueue( media );
m_mediasToComputeMetaDataMutex.unlock();
m_mediasToComputeSnapshotMutex.unlock();
LibVLCpp::MediaPlayer* mediaPlayer = it.value();
m_mediaPlayers.erase( it );
m_mediaPlayers.insert( Running, mediaPlayer );
media = m_mediasToComputeMetaData.dequeue();
m_mediaPlayersMutex.unlock();
MetaDataWorker* worker = new MetaDataWorker( mediaPlayer, media, MetaDataWorker::MetaData );
connect( worker, SIGNAL( mediaPlayerIdle( LibVLCpp::MediaPlayer* ) ), this, SLOT( mediaPlayerIdle( LibVLCpp::MediaPlayer* ) ) );
connect( worker, SIGNAL( mediaPlayerIdle( LibVLCpp::MediaPlayer* ) ), this, SLOT( mediaPlayerIdle( LibVLCpp::MediaPlayer* ) ), Qt::DirectConnection );
//connect( media, SIGNAL( metaDataComputed( Media* ) ), this, SLOT( checkMediasToCompute() ) );
worker->compute();
m_mediasToComputeSnapshot.enqueue( media );
}
else if ( m_mediasToComputeSnapshot.count() > 0 &&
( it = m_mediaPlayers.find( Idle ) ) != m_mediaPlayers.end() )
{
m_mediasToComputeMetaDataMutex.unlock();
Media* media;
media = m_mediasToComputeSnapshot.dequeue();
m_mediasToComputeSnapshotMutex.unlock();
LibVLCpp::MediaPlayer* mediaPlayer = it.value();
m_mediaPlayers.erase( it );
m_mediaPlayers.insert( Running, mediaPlayer );
media = m_mediasToComputeSnapshot.dequeue();
m_mediaPlayersMutex.unlock();
MetaDataWorker* worker = new MetaDataWorker( mediaPlayer, media, MetaDataWorker::Snapshot );
disconnect( media, SIGNAL( metaDataComputed( Media* ) ), this, SLOT( checkMediasToCompute() ) );
connect( worker, SIGNAL( mediaPlayerIdle( LibVLCpp::MediaPlayer* ) ), this, SLOT( mediaPlayerIdle( LibVLCpp::MediaPlayer* ) ) );
//disconnect( media, SIGNAL( metaDataComputed( Media* ) ), this, SLOT( checkMediasToCompute() ) );
connect( worker, SIGNAL( mediaPlayerIdle( LibVLCpp::MediaPlayer* ) ), this, SLOT( mediaPlayerIdle( LibVLCpp::MediaPlayer* ) ), Qt::DirectConnection );
//connect( media, SIGNAL( snapshotComputed( Media* ) ), this, SLOT( checkMediasToCompute() ) );
worker->compute();
}
else
{
m_mediasToComputeSnapshotMutex.unlock();
m_mediasToComputeMetaDataMutex.unlock();
m_mediaPlayersMutex.unlock();
}
return;
}
void MetaDataManager::mediaPlayerIdle( LibVLCpp::MediaPlayer* mediaPlayer )
{
m_mediaPlayers.remove( Running, mediaPlayer );
m_mediaPlayers.insert( Idle, mediaPlayer );
qDebug() << "new media player idle";
{
QMutexLocker lock(&m_mediaPlayersMutex);
m_mediaPlayers.remove( Running, mediaPlayer );
m_mediaPlayers.insert( Idle, mediaPlayer );
}
checkMediasToCompute();
}
......@@ -24,6 +24,8 @@
#define METADATAMANAGER_H
#include <QObject>
#include <QMutex>
#include <QMutexLocker>
#include <QQueue>
#include <QMultiMap>
#include <QThreadPool>
......@@ -31,7 +33,7 @@
#include "Media.h"
#include "Singleton.hpp"
#define DEFAULT_MAX_MEDIA_PLAYER 1
#define DEFAULT_MAX_MEDIA_PLAYER 2
class MetaDataManager : public QObject, public Singleton<MetaDataManager>
{
......@@ -44,6 +46,7 @@ class MetaDataManager : public QObject, public Singleton<MetaDataManager>
};
public:
~MetaDataManager();
void computeMediaMetadata( Media* media );
void setMediaPlayersNumberMaxCount( int number );
void addMediaPlayer();
......@@ -60,6 +63,9 @@ class MetaDataManager : public QObject, public Singleton<MetaDataManager>
QQueue<Media*> m_mediasToComputeMetaData;
QQueue<Media*> m_mediasToComputeSnapshot;
QMultiMap<MediaPlayerState, LibVLCpp::MediaPlayer*> m_mediaPlayers;
QMutex m_mediasToComputeMetaDataMutex;
QMutex m_mediasToComputeSnapshotMutex;
QMutex m_mediaPlayersMutex;
int m_mediaPlayersMaxCount;
int m_mediaPlayersToRemove;
friend class Singleton<MetaDataManager>;
......
......@@ -37,8 +37,8 @@ MetaDataWorker::MetaDataWorker( LibVLCpp::MediaPlayer* mediaPlayer, Media* media
MetaDataWorker::~MetaDataWorker()
{
if ( m_mediaPlayer->isPlaying() )
m_mediaPlayer->stop();
//if ( m_mediaPlayer->isPlaying() )
// m_mediaPlayer->stop();
}
void MetaDataWorker::compute()
......@@ -100,9 +100,13 @@ void MetaDataWorker::getMetaData()
m_media->setFps( FPS );
}
m_media->setNbFrames( (m_media->getLengthMS() / 1000) * m_media->getFps() );
// connect( m_mediaPlayer, SIGNAL( stopped () ), this, SLOT( mediaPlayerStopped() ), Qt::QueuedConnection );
m_mediaPlayer->stop();
emit mediaPlayerIdle( m_mediaPlayer );
m_media->emitMetaDataComputed( true );
if ( m_type == Snapshot )
m_media->emitSnapshotComputed();
else
m_media->emitMetaDataComputed( true );
delete this;
return;
}
......@@ -121,6 +125,7 @@ void MetaDataWorker::getMetaData()
void MetaDataWorker::renderSnapshot()
{
qDebug() << "rendering snapshot";
if ( m_media->getFileType() == Media::Video )
disconnect( m_mediaPlayer, SIGNAL( positionChanged() ), this, SLOT( renderSnapshot() ) );
else
......@@ -153,10 +158,25 @@ void MetaDataWorker::setSnapshot()
//CHECKME:
//This is synchrone, but it may become asynchrone in the future...
// connect( m_mediaPlayer, SIGNAL( stopped () ), this, SLOT( mediaPlayerStopped() ), Qt::QueuedConnection );
m_mediaPlayer->stop();
emit mediaPlayerIdle( m_mediaPlayer );
m_media->emitSnapshotComputed();
if ( m_type == Snapshot )
m_media->emitSnapshotComputed();
else
m_media->emitMetaDataComputed( true );
delete this;
//startAudioDataParsing();
}
void MetaDataWorker::mediaPlayerStopped()
{
disconnect( m_mediaPlayer, SIGNAL( stopped() ), this, SLOT( mediaPlayerStopped() ) );
emit mediaPlayerIdle( m_mediaPlayer );
if ( m_type == Snapshot )
m_media->emitSnapshotComputed();
else
m_media->emitMetaDataComputed( true );
delete this;
}
......
......@@ -87,6 +87,7 @@ class MetaDataWorker : public QObject
void stopAudioDataParsing();
void entrypointPlaying();
void entrypointLengthChanged();
void mediaPlayerStopped();
};
#endif // METADATAWORKER_H
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