Moved some initialization stuff out of the ProcessThread::run() function into a new initialization function. Also got rid of one Mutex, because file names are now generated in the init function, i.e. by the "main" thread.

This commit is contained in:
LoRd_MuldeR 2013-10-09 16:11:58 +02:00
parent c8242b494c
commit cb3f50e5f3
5 changed files with 97 additions and 60 deletions

View File

@ -34,7 +34,7 @@
#define VER_LAMEXP_MINOR_LO 9 #define VER_LAMEXP_MINOR_LO 9
#define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 2 #define VER_LAMEXP_PATCH 2
#define VER_LAMEXP_BUILD 1370 #define VER_LAMEXP_BUILD 1371
#define VER_LAMEXP_CONFG 1348 #define VER_LAMEXP_CONFG 1348
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -928,10 +928,10 @@ void ProcessingDialog::startNextJob(void)
//Give it a go! //Give it a go!
m_runningThreads++; m_runningThreads++;
m_threadPool->start(thread); if(!thread->start(m_threadPool, QApplication::instance()))
{
//Give thread some advance QTimer::singleShot(0, this, SLOT(doneEncoding()));
lamexp_sleep(1); }
} }
void ProcessingDialog::writePlayList(void) void ProcessingDialog::writePlayList(void)

View File

@ -82,7 +82,6 @@ private:
bool checkFile_CDDA(QFile &file); bool checkFile_CDDA(QFile &file);
void retrieveCover(AudioFileModel &audioFile, cover_t coverType, const QByteArray &coverData); void retrieveCover(AudioFileModel &audioFile, cover_t coverType, const QByteArray &coverData);
bool analyzeAvisynthFile(const QString &filePath, AudioFileModel &info); bool analyzeAvisynthFile(const QString &filePath, AudioFileModel &info);
void waitForPreviousThreads(void);
const unsigned int m_taskId; const unsigned int m_taskId;

View File

@ -39,6 +39,8 @@
#include <QMutex> #include <QMutex>
#include <QMutexLocker> #include <QMutexLocker>
#include <QDate> #include <QDate>
#include <QCoreApplication>
#include <QThreadPool>
#include <limits.h> #include <limits.h>
#include <time.h> #include <time.h>
@ -48,8 +50,6 @@
#define IS_WAVE(X) ((X.formatContainerType().compare("Wave", Qt::CaseInsensitive) == 0) && (X.formatAudioType().compare("PCM", Qt::CaseInsensitive) == 0)) #define IS_WAVE(X) ((X.formatContainerType().compare("Wave", Qt::CaseInsensitive) == 0) && (X.formatAudioType().compare("PCM", Qt::CaseInsensitive) == 0))
#define STRDEF(STR,DEF) ((!STR.isEmpty()) ? STR : DEF) #define STRDEF(STR,DEF) ((!STR.isEmpty()) ? STR : DEF)
QMutex *ProcessThread::m_mutex_genFileName = NULL;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Constructor // Constructor
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -65,14 +65,10 @@ ProcessThread::ProcessThread(const AudioFileModel &audioFile, const QString &out
m_renamePattern("<BaseName>"), m_renamePattern("<BaseName>"),
m_overwriteSkipExistingFile(false), m_overwriteSkipExistingFile(false),
m_overwriteReplacesExisting(false), m_overwriteReplacesExisting(false),
m_initialized(false),
m_aborted(false), m_aborted(false),
m_propDetect(new WaveProperties()) m_propDetect(new WaveProperties())
{ {
if(m_mutex_genFileName)
{
m_mutex_genFileName = new QMutex;
}
connect(m_encoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection); connect(m_encoder, SIGNAL(statusUpdated(int)), this, SLOT(handleUpdate(int)), Qt::DirectConnection);
connect(m_encoder, SIGNAL(messageLogged(QString)), this, SLOT(handleMessage(QString)), Qt::DirectConnection); connect(m_encoder, SIGNAL(messageLogged(QString)), this, SLOT(handleMessage(QString)), Qt::DirectConnection);
@ -100,6 +96,54 @@ ProcessThread::~ProcessThread(void)
emit processFinished(); emit processFinished();
} }
////////////////////////////////////////////////////////////
// Init Function
////////////////////////////////////////////////////////////
bool ProcessThread::start(QThreadPool *pool, QCoreApplication *app)
{
if(!m_initialized)
{
m_initialized = true;
//Initialize job status
qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData());
emit processStateInitialized(m_jobId, QFileInfo(m_audioFile.filePath()).fileName(), tr("Starting..."), ProgressModel::JobRunning);
//Initialize log
handleMessage(QString().sprintf("LameXP v%u.%02u (Build #%u), compiled on %s at %s", lamexp_version_major(), lamexp_version_minor(), lamexp_version_build(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), lamexp_version_time()));
handleMessage("\n-------------------------------\n");
//Process pending GUI events
if(app) app->processEvents(QEventLoop::ExcludeUserInputEvents);
//Generate output file name
m_outFileName.clear();
switch(generateOutFileName(m_outFileName))
{
case 1:
//File name generated successfully :-)
pool->start(this);
return true;
break;
case -1:
//File name already exists -> skipping!
emit processStateChanged(m_jobId, tr("Skipped."), ProgressModel::JobSkipped);
emit processStateFinished(m_jobId, m_outFileName, -1);
return false;
break;
default:
//File name could not be generated
emit processStateChanged(m_jobId, tr("Not found!"), ProgressModel::JobFailed);
emit processStateFinished(m_jobId, m_outFileName, 0);
return false;
break;
}
}
return false;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Thread Entry Point // Thread Entry Point
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -124,31 +168,10 @@ void ProcessThread::processFile()
m_aborted = false; m_aborted = false;
bool bSuccess = true; bool bSuccess = true;
//Initialize job status //Make sure object was initialized correctly
qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData()); if(!m_initialized)
emit processStateInitialized(m_jobId, QFileInfo(m_audioFile.filePath()).fileName(), tr("Starting..."), ProgressModel::JobRunning);
//Initialize log
handleMessage(QString().sprintf("LameXP v%u.%02u (Build #%u), compiled on %s at %s", lamexp_version_major(), lamexp_version_minor(), lamexp_version_build(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), lamexp_version_time()));
handleMessage("\n-------------------------------\n");
//Generate output file name
QString outFileName;
switch(generateOutFileName(outFileName))
{ {
case 1: throw "Object not initialized yet!";
//File name generated successfully :-)
break;
case -1:
//File name already exists -> skipping!
emit processStateChanged(m_jobId, tr("Skipped."), ProgressModel::JobSkipped);
emit processStateFinished(m_jobId, outFileName, -1);
return;
default:
//File name could not be generated
emit processStateChanged(m_jobId, tr("Not found!"), ProgressModel::JobFailed);
emit processStateFinished(m_jobId, outFileName, 0);
return;
} }
QString sourceFile = m_audioFile.filePath(); QString sourceFile = m_audioFile.filePath();
@ -187,10 +210,10 @@ void ProcessThread::processFile()
} }
else else
{ {
if(QFileInfo(outFileName).exists() && (QFileInfo(outFileName).size() < 512)) QFile::remove(outFileName); if(QFileInfo(m_outFileName).exists() && (QFileInfo(m_outFileName).size() < 512)) QFile::remove(m_outFileName);
handleMessage(QString("%1\n%2\n\n%3\t%4\n%5\t%6").arg(tr("The format of this file is NOT supported:"), m_audioFile.filePath(), tr("Container Format:"), m_audioFile.formatContainerInfo(), tr("Audio Format:"), m_audioFile.formatAudioCompressInfo())); handleMessage(QString("%1\n%2\n\n%3\t%4\n%5\t%6").arg(tr("The format of this file is NOT supported:"), m_audioFile.filePath(), tr("Container Format:"), m_audioFile.formatContainerInfo(), tr("Audio Format:"), m_audioFile.formatAudioCompressInfo()));
emit processStateChanged(m_jobId, tr("Unsupported!"), ProgressModel::JobFailed); emit processStateChanged(m_jobId, tr("Unsupported!"), ProgressModel::JobFailed);
emit processStateFinished(m_jobId, outFileName, 0); emit processStateFinished(m_jobId, m_outFileName, 0);
return; return;
} }
} }
@ -254,23 +277,23 @@ void ProcessThread::processFile()
if(bSuccess && !m_aborted) if(bSuccess && !m_aborted)
{ {
m_currentStep = EncodingStep; m_currentStep = EncodingStep;
bSuccess = m_encoder->encode(sourceFile, m_audioFile, outFileName, &m_aborted); bSuccess = m_encoder->encode(sourceFile, m_audioFile, m_outFileName, &m_aborted);
} }
//Clean-up //Clean-up
if((!bSuccess) || m_aborted) if((!bSuccess) || m_aborted)
{ {
QFileInfo fileInfo(outFileName); QFileInfo fileInfo(m_outFileName);
if(fileInfo.exists() && (fileInfo.size() < 512)) if(fileInfo.exists() && (fileInfo.size() < 512))
{ {
QFile::remove(outFileName); QFile::remove(m_outFileName);
} }
} }
//Make sure output file exists //Make sure output file exists
if(bSuccess && (!m_aborted)) if(bSuccess && (!m_aborted))
{ {
QFileInfo fileInfo(outFileName); QFileInfo fileInfo(m_outFileName);
bSuccess = fileInfo.exists() && fileInfo.isFile() && (fileInfo.size() > 0); bSuccess = fileInfo.exists() && fileInfo.isFile() && (fileInfo.size() > 0);
} }
@ -278,7 +301,7 @@ void ProcessThread::processFile()
//Report result //Report result
emit processStateChanged(m_jobId, (m_aborted ? tr("Aborted!") : (bSuccess ? tr("Done.") : tr("Failed!"))), ((bSuccess && !m_aborted) ? ProgressModel::JobComplete : ProgressModel::JobFailed)); emit processStateChanged(m_jobId, (m_aborted ? tr("Aborted!") : (bSuccess ? tr("Done.") : tr("Failed!"))), ((bSuccess && !m_aborted) ? ProgressModel::JobComplete : ProgressModel::JobFailed));
emit processStateFinished(m_jobId, outFileName, (bSuccess ? 1 : 0)); emit processStateFinished(m_jobId, m_outFileName, (bSuccess ? 1 : 0));
qDebug("Process thread is done."); qDebug("Process thread is done.");
} }
@ -321,8 +344,6 @@ int ProcessThread::generateOutFileName(QString &outFileName)
{ {
outFileName.clear(); outFileName.clear();
QMutexLocker lock(m_mutex_genFileName);
//Make sure the source file exists //Make sure the source file exists
QFileInfo sourceFile(m_audioFile.filePath()); QFileInfo sourceFile(m_audioFile.filePath());
if(!sourceFile.exists() || !sourceFile.isFile()) if(!sourceFile.exists() || !sourceFile.isFile())
@ -440,18 +461,30 @@ int ProcessThread::generateOutFileName(QString &outFileName)
QString ProcessThread::generateTempFileName(void) QString ProcessThread::generateTempFileName(void)
{ {
QMutexLocker lock(m_mutex_genFileName); bool bOkay = false;
QString tempFileName = QString("%1/%2.wav").arg(m_tempDirectory, lamexp_rand_str()); QString tempFileName;
while(QFileInfo(tempFileName).exists()) for(int i = 0; i < 4096; i++)
{ {
tempFileName = QString("%1/%2.wav").arg(m_tempDirectory, lamexp_rand_str()); tempFileName = QString("%1/%2.wav").arg(m_tempDirectory, lamexp_rand_str());
if(m_tempFiles.contains(tempFileName, Qt::CaseInsensitive) || QFileInfo(tempFileName).exists())
{
continue;
} }
QFile file(tempFileName); QFile file(tempFileName);
if(file.open(QFile::ReadWrite)) if(file.open(QFile::ReadWrite))
{ {
file.close(); file.close();
bOkay = true;
break;
}
}
if(!bOkay)
{
qWarning("Failed to generate unique temp file name!");
return QString("%1/~whoops.wav").arg(m_tempDirectory);
} }
m_tempFiles << tempFileName; m_tempFiles << tempFileName;

View File

@ -28,9 +28,10 @@
#include "Model_AudioFile.h" #include "Model_AudioFile.h"
#include "Encoder_Abstract.h" #include "Encoder_Abstract.h"
class QMutex;
class AbstractFilter; class AbstractFilter;
class WaveProperties; class WaveProperties;
class QThreadPool;
class QCoreApplication;
class ProcessThread: public QObject, public QRunnable class ProcessThread: public QObject, public QRunnable
{ {
@ -40,7 +41,7 @@ public:
ProcessThread(const AudioFileModel &audioFile, const QString &outputDirectory, const QString &tempDirectory, AbstractEncoder *encoder, const bool prependRelativeSourcePath); ProcessThread(const AudioFileModel &audioFile, const QString &outputDirectory, const QString &tempDirectory, AbstractEncoder *encoder, const bool prependRelativeSourcePath);
~ProcessThread(void); ~ProcessThread(void);
void run(void); bool start(QThreadPool *pool, QCoreApplication *app = NULL);
QUuid getId(void) { return m_jobId; } QUuid getId(void) { return m_jobId; }
void setRenamePattern(const QString &pattern); void setRenamePattern(const QString &pattern);
@ -61,6 +62,9 @@ signals:
void processMessageLogged(const QUuid &jobId, const QString &line); void processMessageLogged(const QUuid &jobId, const QString &line);
void processFinished(void); void processFinished(void);
protected:
virtual void run(void);
private: private:
enum ProcessStep enum ProcessStep
{ {
@ -74,15 +78,17 @@ private:
void processFile(); void processFile();
int generateOutFileName(QString &outFileName); int generateOutFileName(QString &outFileName);
QString generateTempFileName(void); QString generateTempFileName(void);
void insertDownsampleFilter(void);
void insertDownmixFilter(void); void insertDownmixFilter(void);
void insertDownsampleFilter(void);
volatile bool m_aborted;
volatile bool m_initialized;
const QUuid m_jobId; const QUuid m_jobId;
AudioFileModel m_audioFile; AudioFileModel m_audioFile;
AbstractEncoder *m_encoder; AbstractEncoder *m_encoder;
const QString m_outputDirectory; const QString m_outputDirectory;
const QString m_tempDirectory; const QString m_tempDirectory;
volatile bool m_aborted;
ProcessStep m_currentStep; ProcessStep m_currentStep;
QStringList m_tempFiles; QStringList m_tempFiles;
const bool m_prependRelativeSourcePath; const bool m_prependRelativeSourcePath;
@ -91,6 +97,5 @@ private:
bool m_overwriteSkipExistingFile; bool m_overwriteSkipExistingFile;
bool m_overwriteReplacesExisting; bool m_overwriteReplacesExisting;
WaveProperties *m_propDetect; WaveProperties *m_propDetect;
QString m_outFileName;
static QMutex *m_mutex_genFileName;
}; };