diff --git a/src/Thread_FileAnalyzer.cpp b/src/Thread_FileAnalyzer.cpp index 81b6efd6..a10cbc84 100644 --- a/src/Thread_FileAnalyzer.cpp +++ b/src/Thread_FileAnalyzer.cpp @@ -25,6 +25,7 @@ #include "LockedFile.h" #include "Model_AudioFile.h" #include "Thread_FileAnalyzer_Task.h" +#include "PlaylistImporter.h" #include #include @@ -35,6 +36,8 @@ #include #include #include +#include +#include //////////////////////////////////////////////////////////// // Constructor @@ -42,12 +45,22 @@ FileAnalyzer::FileAnalyzer(const QStringList &inputFiles) : - m_abortFlag(false), + m_tasksCounterNext(0), + m_tasksCounterDone(0), m_inputFiles(inputFiles), - m_templateFile(NULL) + m_templateFile(NULL), + m_pool(NULL) { m_bSuccess = false; m_bAborted = false; + + m_filesAccepted = 0; + m_filesRejected = 0; + m_filesDenied = 0; + m_filesDummyCDDA = 0; + m_filesCueSheet = 0; + + m_timer = new QElapsedTimer; } FileAnalyzer::~FileAnalyzer(void) @@ -59,7 +72,13 @@ FileAnalyzer::~FileAnalyzer(void) if(QFile::exists(templatePath)) QFile::remove(templatePath); } - AnalyzeTask::reset(); + if(!m_pool->waitForDone(2500)) + { + qWarning("There are still running tasks in the thread pool!"); + } + + LAMEXP_DELETE(m_pool); + LAMEXP_DELETE(m_timer); } //////////////////////////////////////////////////////////// @@ -109,18 +128,29 @@ const char *FileAnalyzer::g_tags_aud[] = void FileAnalyzer::run() { - m_abortFlag = false; - - m_bAborted = false; m_bSuccess = false; - int nFiles = m_inputFiles.count(); + m_tasksCounterNext = 0; + m_tasksCounterDone = 0; + m_completedCounter = 0; - emit progressMaxChanged(nFiles); + m_completedFiles.clear(); + m_completedTaskIds.clear(); + m_runningTaskIds.clear(); + + m_filesAccepted = 0; + m_filesRejected = 0; + m_filesDenied = 0; + m_filesDummyCDDA = 0; + m_filesCueSheet = 0; + + m_timer->invalidate(); + + //Update progress + emit progressMaxChanged(m_inputFiles.count()); emit progressValChanged(0); - lamexp_natural_string_sort(m_inputFiles, true); //.sort(); - + //Create MediaInfo template file if(!m_templateFile) { if(!createTemplate()) @@ -130,75 +160,106 @@ void FileAnalyzer::run() } } - AnalyzeTask::reset(); - QThreadPool *pool = new QThreadPool(); - QThread::msleep(333); + //Handle playlist files + lamexp_natural_string_sort(m_inputFiles, true); + handlePlaylistFiles(); + lamexp_natural_string_sort(m_inputFiles, true); - pool->setMaxThreadCount(qBound(2, ((QThread::idealThreadCount() * 3) / 2), 12)); + const unsigned int nFiles = m_inputFiles.count(); - while(!(m_inputFiles.isEmpty() || m_bAborted)) - { - while(!(m_inputFiles.isEmpty() || m_bAborted)) - { - if(!AnalyzeTask::waitForFreeSlot(&m_abortFlag)) - { - qWarning("Timeout in AnalyzeTask::waitForFreeSlot() !!!"); - } + //Update progress + emit progressMaxChanged(nFiles); - if(m_abortFlag) - { - MessageBeep(MB_ICONERROR); - m_bAborted = true; - break; - } - - if(!m_bAborted) - { - const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst()); + //Create thread pool + if(!m_pool) m_pool = new QThreadPool(); + m_pool->setMaxThreadCount(qBound(2, ((QThread::idealThreadCount() * 3) / 2), 12)); - AnalyzeTask *task = new AnalyzeTask(currentFile, m_templateFile->filePath(), &m_abortFlag); - connect(task, SIGNAL(fileSelected(QString)), this, SIGNAL(fileSelected(QString)), Qt::DirectConnection); - connect(task, SIGNAL(progressValChanged(unsigned int)), this, SIGNAL(progressValChanged(unsigned int)), Qt::DirectConnection); - connect(task, SIGNAL(progressMaxChanged(unsigned int)), this, SIGNAL(progressMaxChanged(unsigned int)), Qt::DirectConnection); - connect(task, SIGNAL(fileAnalyzed(AudioFileModel)), this, SIGNAL(fileAnalyzed(AudioFileModel)), Qt::DirectConnection); + //Start first N threads + QTimer::singleShot(0, this, SLOT(initializeTasks())); - pool->start(task); + //Start event processing + this->exec(); - if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles)) - { - emit progressMaxChanged(nFiles += count); - } - } - } - - //One of the Analyze tasks may have gathered additional files from a playlist! - if(!m_bAborted) - { - pool->waitForDone(); - if(int count = AnalyzeTask::getAdditionalFiles(m_inputFiles)) - { - emit progressMaxChanged(nFiles += count); - } - } - } - - pool->waitForDone(); - LAMEXP_DELETE(pool); + //Wait for pending tasks to complete + m_pool->waitForDone(); + //Was opertaion aborted? if(m_bAborted) { qWarning("Operation cancelled by user!"); return; } + //Update progress + emit progressValChanged(nFiles); + + //Emit pending files (this should not be required though!) + if(!m_completedFiles.isEmpty()) + { + qWarning("FileAnalyzer: Pending file information found after last thread terminated!"); + QList keys = m_completedFiles.keys(); qSort(keys); + while(!keys.isEmpty()) + { + emit fileAnalyzed(m_completedFiles.take(keys.takeFirst())); + } + } + qDebug("All files added.\n"); m_bSuccess = true; + + QThread::msleep(333); } //////////////////////////////////////////////////////////// // Privtae Functions //////////////////////////////////////////////////////////// +bool FileAnalyzer::analyzeNextFile(void) +{ + if(!(m_inputFiles.isEmpty() || m_bAborted)) + { + const unsigned int taskId = m_tasksCounterNext++; + const QString currentFile = QDir::fromNativeSeparators(m_inputFiles.takeFirst()); + + if((!m_timer->isValid()) || (m_timer->elapsed() >= 250)) + { + emit fileSelected(QFileInfo(currentFile).fileName()); + m_timer->restart(); + } + + AnalyzeTask *task = new AnalyzeTask(taskId, currentFile, m_templateFile->filePath(), &m_bAborted); + connect(task, SIGNAL(fileAnalyzed(const unsigned int, const int, AudioFileModel)), this, SLOT(taskFileAnalyzed(unsigned int, const int, AudioFileModel)), Qt::QueuedConnection); + connect(task, SIGNAL(taskCompleted(const unsigned int)), this, SLOT(taskThreadFinish(const unsigned int)), Qt::QueuedConnection); + m_runningTaskIds.insert(taskId); m_pool->start(task); + + return true; + } + + return false; +} + +void FileAnalyzer::handlePlaylistFiles(void) +{ + QStringList importedFiles; + while(!m_inputFiles.isEmpty()) + { + const QString currentFile = m_inputFiles.takeFirst(); + if(!PlaylistImporter::importPlaylist(importedFiles, currentFile)) + { + importedFiles << currentFile; + } + } + + while(!importedFiles.isEmpty()) + { + const QString currentFile = importedFiles.takeFirst(); + if(!m_inputFiles.contains(currentFile, Qt::CaseInsensitive)) + { + m_inputFiles << currentFile; + } + } +} + bool FileAnalyzer::createTemplate(void) { if(m_templateFile) @@ -251,33 +312,105 @@ bool FileAnalyzer::createTemplate(void) return true; } +//////////////////////////////////////////////////////////// +// Slot Functions +//////////////////////////////////////////////////////////// + +void FileAnalyzer::initializeTasks(void) +{ + for(int i = 0; i < m_pool->maxThreadCount(); i++) + { + if(!analyzeNextFile()) break; + } +} + +void FileAnalyzer::taskFileAnalyzed(const unsigned int taskId, const int fileType, const AudioFileModel &file) +{ + m_completedTaskIds.insert(taskId); + + switch(fileType) + { + case AnalyzeTask::fileTypeNormal: + m_filesAccepted++; + if(m_tasksCounterDone == taskId) + { + emit fileAnalyzed(file); + m_tasksCounterDone++; + } + else + { + m_completedFiles.insert(taskId, file); + } + break; + case AnalyzeTask::fileTypeCDDA: + m_filesDummyCDDA++; + break; + case AnalyzeTask::fileTypeDenied: + m_filesDenied++; + break; + case AnalyzeTask::fileTypeCueSheet: + m_filesCueSheet++; + break; + case AnalyzeTask::fileTypeUnknown: + m_filesRejected++; + break; + default: + throw "Unknown file type identifier!"; + } + + //Emit all pending files + while(m_completedTaskIds.contains(m_tasksCounterDone)) + { + if(m_completedFiles.contains(m_tasksCounterDone)) + { + emit fileAnalyzed(m_completedFiles.take(m_tasksCounterDone)); + } + m_completedTaskIds.remove(m_tasksCounterDone); + m_tasksCounterDone++; + } +} + +void FileAnalyzer::taskThreadFinish(const unsigned int taskId) +{ + m_runningTaskIds.remove(taskId); + emit progressValChanged(++m_completedCounter); + + if(!analyzeNextFile()) + { + if(m_runningTaskIds.empty()) + { + QTimer::singleShot(0, this, SLOT(quit())); //Stop event processing, if all threads have completed! + } + } +} + //////////////////////////////////////////////////////////// // Public Functions //////////////////////////////////////////////////////////// unsigned int FileAnalyzer::filesAccepted(void) { - return AnalyzeTask::filesAccepted(); + return m_filesAccepted; } unsigned int FileAnalyzer::filesRejected(void) { - return AnalyzeTask::filesRejected(); + return m_filesRejected; } unsigned int FileAnalyzer::filesDenied(void) { - return AnalyzeTask::filesDenied(); + return m_filesDenied; } unsigned int FileAnalyzer::filesDummyCDDA(void) { - return AnalyzeTask::filesDummyCDDA(); + return m_filesDummyCDDA; } unsigned int FileAnalyzer::filesCueSheet(void) { - return AnalyzeTask::filesCueSheet(); + return m_filesCueSheet; } //////////////////////////////////////////////////////////// diff --git a/src/Thread_FileAnalyzer.h b/src/Thread_FileAnalyzer.h index d98c2cf6..ea47c4bd 100644 --- a/src/Thread_FileAnalyzer.h +++ b/src/Thread_FileAnalyzer.h @@ -25,12 +25,16 @@ #include #include +#include +#include class AudioFileModel; class QFile; class QDir; class QFileInfo; class LockedFile; +class QThreadPool; +class QElapsedTimer; //////////////////////////////////////////////////////////// // Splash Thread @@ -44,7 +48,7 @@ public: FileAnalyzer(const QStringList &inputFiles); ~FileAnalyzer(void); void run(); - bool getSuccess(void) { return !isRunning() && m_bSuccess; } + bool getSuccess(void) { return (!isRunning()) && (!m_bAborted) && m_bSuccess; } unsigned int filesAccepted(void); unsigned int filesRejected(void); @@ -59,20 +63,41 @@ signals: void progressMaxChanged(unsigned int); public slots: - void abortProcess(void) { m_abortFlag = true; } + void abortProcess(void) { m_bAborted = true; exit(-1); } + +private slots: + void initializeTasks(void); + void taskFileAnalyzed(const unsigned int taskId, const int fileType, const AudioFileModel &file); + void taskThreadFinish(const unsigned int); private: - const AudioFileModel analyzeFile(const QString &filePath, int *type); + bool analyzeNextFile(void); + void handlePlaylistFiles(void); bool createTemplate(void); + QThreadPool *m_pool; + QElapsedTimer *m_timer; + + unsigned int m_tasksCounterNext; + unsigned int m_tasksCounterDone; + unsigned int m_completedCounter; + + unsigned int m_filesAccepted; + unsigned int m_filesRejected; + unsigned int m_filesDenied; + unsigned int m_filesDummyCDDA; + unsigned int m_filesCueSheet; + QStringList m_inputFiles; LockedFile *m_templateFile; - - volatile bool m_abortFlag; + + QSet m_completedTaskIds; + QSet m_runningTaskIds; + QHash m_completedFiles; static const char *g_tags_gen[]; static const char *g_tags_aud[]; - bool m_bAborted; - bool m_bSuccess; + volatile bool m_bAborted; + volatile bool m_bSuccess; }; diff --git a/src/Thread_FileAnalyzer_Task.cpp b/src/Thread_FileAnalyzer_Task.cpp index 223e3ebe..e874e5e4 100644 --- a/src/Thread_FileAnalyzer_Task.cpp +++ b/src/Thread_FileAnalyzer_Task.cpp @@ -24,7 +24,6 @@ #include "Global.h" #include "LockedFile.h" #include "Model_AudioFile.h" -#include "PlaylistImporter.h" #include #include @@ -45,35 +44,13 @@ #define IS_SEC(SEC) (key.startsWith((SEC "_"), Qt::CaseInsensitive)) #define FIRST_TOK(STR) (STR.split(" ", QString::SkipEmptyParts).first()) -/* static vars */ -QMutex AnalyzeTask::s_waitMutex; -QWaitCondition AnalyzeTask::s_waitCond; -QSet AnalyzeTask::s_threadIdx_running; -unsigned int AnalyzeTask::s_threadIdx_next = 0; -QSemaphore AnalyzeTask::s_semaphore(0); - -/* more static vars */ -QReadWriteLock AnalyzeTask::s_lock; -unsigned int AnalyzeTask::s_filesAccepted = 0; -unsigned int AnalyzeTask::s_filesRejected = 0; -unsigned int AnalyzeTask::s_filesDenied = 0; -unsigned int AnalyzeTask::s_filesDummyCDDA = 0; -unsigned int AnalyzeTask::s_filesCueSheet = 0; -QStringList AnalyzeTask::s_additionalFiles; -QSet AnalyzeTask::s_recentlyAdded; - -/*constants*/ -const int WAITCOND_TIMEOUT = 2500; -const int MAX_RETRIES = 60000 / WAITCOND_TIMEOUT; -const int MAX_QUEUE_SLOTS = 32; - //////////////////////////////////////////////////////////// // Constructor //////////////////////////////////////////////////////////// -AnalyzeTask::AnalyzeTask(const QString &inputFile, const QString &templateFile, volatile bool *abortFlag) +AnalyzeTask::AnalyzeTask(const int taskId, const QString &inputFile, const QString &templateFile, volatile bool *abortFlag) : - m_threadIdx(makeThreadIdx()), + m_taskId(taskId), m_inputFile(inputFile), m_templateFile(templateFile), m_mediaInfoBin(lamexp_lookup_tool("mediainfo.exe")), @@ -88,13 +65,7 @@ AnalyzeTask::AnalyzeTask(const QString &inputFile, const QString &templateFile, AnalyzeTask::~AnalyzeTask(void) { - s_semaphore.release(); - - s_waitMutex.lock(); - s_threadIdx_running.remove(m_threadIdx); - s_waitMutex.unlock(); - - s_waitCond.wakeAll(); + emit taskCompleted(m_taskId); } //////////////////////////////////////////////////////////// @@ -111,12 +82,6 @@ void AnalyzeTask::run() { qWarning("WARNING: Caught an in exception AnalyzeTask thread!"); } - - s_waitMutex.lock(); - s_threadIdx_running.remove(m_threadIdx); - s_waitMutex.unlock(); - - s_waitCond.wakeAll(); } void AnalyzeTask::run_ex(void) @@ -125,9 +90,6 @@ void AnalyzeTask::run_ex(void) QString currentFile = QDir::fromNativeSeparators(m_inputFile); qDebug("Analyzing: %s", currentFile.toUtf8().constData()); - emit fileSelected(QFileInfo(currentFile).fileName()); - emit progressValChanged(m_threadIdx + 1); - AudioFileModel file = analyzeFile(currentFile, &fileType); if(*m_abortFlag) @@ -135,79 +97,46 @@ void AnalyzeTask::run_ex(void) qWarning("Operation cancelled by user!"); return; } - if(fileType == fileTypeSkip) - { - qWarning("File was recently added, skipping!"); - return; - } - if(fileType == fileTypeDenied) - { - QWriteLocker lock(&s_lock); - s_filesDenied++; - lock.unlock(); - qWarning("Cannot access file for reading, skipping!"); - return; - } - if(fileType == fileTypeCDDA) - { - QWriteLocker lock(&s_lock); - s_filesDummyCDDA++; - lock.unlock(); - qWarning("Dummy CDDA file detected, skipping!"); - return; - } - //Handle files with *incomplete* meida info - if(file.fileName().isEmpty() || file.formatContainerType().isEmpty() || file.formatAudioType().isEmpty()) + switch(fileType) { - QStringList fileList; - if(PlaylistImporter::importPlaylist(fileList, currentFile)) + case fileTypeDenied: + qWarning("Cannot access file for reading, skipping!"); + break; + case fileTypeCDDA: + qWarning("Dummy CDDA file detected, skipping!"); + break; + default: + if(file.fileName().isEmpty() || file.formatContainerType().isEmpty() || file.formatAudioType().isEmpty()) { - qDebug("Imported playlist file."); - QWriteLocker lock(&s_lock); - s_additionalFiles << fileList; - } - else if(!QFileInfo(currentFile).suffix().compare("cue", Qt::CaseInsensitive)) - { - QWriteLocker lock(&s_lock); - qWarning("Cue Sheet file detected, skipping!"); - s_filesCueSheet++; - } - else if(!QFileInfo(currentFile).suffix().compare("avs", Qt::CaseInsensitive)) - { - qDebug("Found a potential Avisynth script, investigating..."); - if(analyzeAvisynthFile(currentFile, file)) + fileType = fileTypeUnknown; + if(!QFileInfo(currentFile).suffix().compare("cue", Qt::CaseInsensitive)) { - QWriteLocker lock(&s_lock); - s_filesAccepted++; - s_recentlyAdded.insert(file.filePath().toLower()); - lock.unlock(); - waitForPreviousThreads(); - emit fileAnalyzed(file); + qWarning("Cue Sheet file detected, skipping!"); + fileType = fileTypeCueSheet; + } + else if(!QFileInfo(currentFile).suffix().compare("avs", Qt::CaseInsensitive)) + { + qDebug("Found a potential Avisynth script, investigating..."); + if(analyzeAvisynthFile(currentFile, file)) + { + fileType = fileTypeNormal; + } + else + { + qDebug("Rejected Avisynth file: %s", file.filePath().toUtf8().constData()); + } } else { - QWriteLocker lock(&s_lock); - qDebug("Rejected Avisynth file: %s", file.filePath().toUtf8().constData()); - s_filesRejected++; + qDebug("Rejected file of unknown type: %s", file.filePath().toUtf8().constData()); } } - else - { - QWriteLocker lock(&s_lock); - qDebug("Rejected file of unknown type: %s", file.filePath().toUtf8().constData()); - s_filesRejected++; - } - return; + break; } //Emit the file now! - QWriteLocker lock(&s_lock); - s_filesAccepted++; - s_recentlyAdded.insert(file.filePath().toLower()); - lock.unlock(); - waitForPreviousThreads(); - emit fileAnalyzed(file); + emit fileAnalyzed(m_taskId, fileType, file); } //////////////////////////////////////////////////////////// @@ -219,14 +148,6 @@ const AudioFileModel AnalyzeTask::analyzeFile(const QString &filePath, int *type *type = fileTypeNormal; AudioFileModel audioFile(filePath); - QReadLocker readLock(&s_lock); - if(s_recentlyAdded.contains(filePath.toLower())) - { - *type = fileTypeSkip; - return audioFile; - } - readLock.unlock(); - QFile readTest(filePath); if(!readTest.open(QIODevice::ReadOnly)) { @@ -733,139 +654,12 @@ unsigned int AnalyzeTask::parseDuration(const QString &str) return ok ? (value/1000) : 0; } -unsigned __int64 AnalyzeTask::makeThreadIdx(void) -{ - s_waitMutex.lock(); - unsigned int idx = s_threadIdx_next++; - s_threadIdx_running.insert(idx); - s_waitMutex.unlock(); - - return idx; -} - -void AnalyzeTask::waitForPreviousThreads(void) -{ - //This function will block until all threads with a *lower* index have terminated. - //Required to make sure that the files will be added in the "correct" order! - - s_waitMutex.lock(); - int retryCount = 0; - - forever - { - bool bWaitFlag = false; - QSet::const_iterator i; - - for(i = s_threadIdx_running.begin(); i != s_threadIdx_running.end(); ++i) - { - if(*i < m_threadIdx) { bWaitFlag = true; break; } - } - - if((!bWaitFlag) || *m_abortFlag) - { - s_waitMutex.unlock(); - return; - } - - if(!s_waitCond.wait(&s_waitMutex, WAITCOND_TIMEOUT)) - { - if(++retryCount > MAX_RETRIES) - { - qWarning("AnalyzeTask::waitForPreviousThreads encountered timeout !!!"); - s_threadIdx_running.clear(); - } - } - } -} //////////////////////////////////////////////////////////// // Public Functions //////////////////////////////////////////////////////////// -unsigned int AnalyzeTask::filesAccepted(void) -{ - QReadLocker lock(&s_lock); - return s_filesAccepted; -} - -unsigned int AnalyzeTask::filesRejected(void) -{ - QReadLocker lock(&s_lock); - return s_filesRejected; -} - -unsigned int AnalyzeTask::filesDenied(void) -{ - QReadLocker lock(&s_lock); - return s_filesDenied; -} - -unsigned int AnalyzeTask::filesDummyCDDA(void) -{ - QReadLocker lock(&s_lock); - return s_filesDummyCDDA; -} - -unsigned int AnalyzeTask::filesCueSheet(void) -{ - QReadLocker lock(&s_lock); - return s_filesCueSheet; -} - -int AnalyzeTask::getAdditionalFiles(QStringList &fileList) -{ - QReadLocker readLock(&s_lock); - int count = s_additionalFiles.count(); - readLock.unlock(); - - if(count > 0) - { - QWriteLocker lock(&s_lock); - count = s_additionalFiles.count(); - fileList << s_additionalFiles; - s_additionalFiles.clear(); - return count; - } - - return 0; -} - -bool AnalyzeTask::waitForFreeSlot(volatile bool *abortFlag) -{ - bool ret = false; - - for(int i = 0; i < MAX_RETRIES; i++) - { - ret = s_semaphore.tryAcquire(1, WAITCOND_TIMEOUT); - if(ret || (*abortFlag)) break; - } - - return ret; -} - -void AnalyzeTask::reset(void) -{ - QWriteLocker lock(&s_lock); - s_filesAccepted = 0; - s_filesRejected = 0; - s_filesDenied = 0; - s_filesDummyCDDA = 0; - s_filesCueSheet = 0; - s_additionalFiles.clear(); - s_recentlyAdded.clear(); - lock.unlock(); - - s_waitMutex.lock(); - s_threadIdx_next = 0; - s_threadIdx_running.clear(); - s_waitMutex.unlock(); - - int freeSlots = s_semaphore.available(); - if(freeSlots < MAX_QUEUE_SLOTS) - { - s_semaphore.release(MAX_QUEUE_SLOTS - freeSlots); - } -} +/*NONE*/ //////////////////////////////////////////////////////////// // EVENTS diff --git a/src/Thread_FileAnalyzer_Task.h b/src/Thread_FileAnalyzer_Task.h index 1fb9e4ea..bb606fa0 100644 --- a/src/Thread_FileAnalyzer_Task.h +++ b/src/Thread_FileAnalyzer_Task.h @@ -43,25 +43,24 @@ class AnalyzeTask: public QObject, public QRunnable Q_OBJECT public: - AnalyzeTask(const QString &inputFile, const QString &templateFile, volatile bool *abortFlag); + AnalyzeTask(const int taskId, const QString &inputFile, const QString &templateFile, volatile bool *abortFlag); ~AnalyzeTask(void); - static void reset(void); - static int getAdditionalFiles(QStringList &fileList); - static unsigned int filesAccepted(void); - static unsigned int filesRejected(void); - static unsigned int filesDenied(void); - static unsigned int filesDummyCDDA(void); - static unsigned int filesCueSheet(void); + enum fileType_t + { + fileTypeNormal = 0, + fileTypeCDDA = 1, + fileTypeDenied = 2, + fileTypeCueSheet = 3, + fileTypeUnknown = 4 + }; //Wait until there is a free slot in the queue static bool waitForFreeSlot(volatile bool *abortFlag); signals: - void fileSelected(const QString &fileName); - void fileAnalyzed(const AudioFileModel &file); - void progressValChanged(unsigned int); - void progressMaxChanged(unsigned int); + void fileAnalyzed(const unsigned int taskId, const int fileType, const AudioFileModel &file); + void taskCompleted(const unsigned int taskId); protected: void run(void); @@ -75,13 +74,6 @@ private: coverPng, coverGif }; - enum fileType_t - { - fileTypeNormal = 0, - fileTypeCDDA = 1, - fileTypeDenied = 2, - fileTypeSkip = 3 - }; const AudioFileModel analyzeFile(const QString &filePath, int *type); void updateInfo(AudioFileModel &audioFile, bool *skipNext, unsigned int *id_val, cover_t *coverType, QByteArray *coverData, const QString &key, const QString &value); @@ -92,7 +84,7 @@ private: bool analyzeAvisynthFile(const QString &filePath, AudioFileModel &info); void waitForPreviousThreads(void); - const unsigned __int64 m_threadIdx; + const unsigned int m_taskId; const QString m_mediaInfoBin; const QString m_avs2wavBin; @@ -100,22 +92,4 @@ private: const QString m_inputFile; volatile bool *m_abortFlag; - - static QMutex s_waitMutex; - static QWaitCondition s_waitCond; - static QSet s_threadIdx_running; - static unsigned int s_threadIdx_next; - - static QSemaphore s_semaphore; - - static QReadWriteLock s_lock; - static unsigned int s_filesAccepted; - static unsigned int s_filesRejected; - static unsigned int s_filesDenied; - static unsigned int s_filesDummyCDDA; - static unsigned int s_filesCueSheet; - static QSet s_recentlyAdded; - static QStringList s_additionalFiles; - - static unsigned __int64 makeThreadIdx(void); };