From 431ed392e2687ca3fc84b9de286c5fc0f312b7f1 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Mon, 11 Apr 2011 02:53:29 +0200 Subject: [PATCH] Rewrote initialization code: Instead of extracting all binaries at startup and later selecting the suitable binary for the detected CPU, we will now extract only the binaries that are suitable for the detected CPU. This way we need to extract fewer files at startup. Also CPU selection can be skipped later, as there will be only one registered binary for each tool (the one suitable for the CPU). --- res/Tools.qrc | 10 +- ...{mediainfo_i386.exe => mediainfo.i386.exe} | Bin .../{mediainfo_x64.exe => mediainfo.x64.exe} | Bin .../{oggenc2_i386.exe => oggenc2.i386.exe} | Bin .../{oggenc2_sse2.exe => oggenc2.sse2.exe} | Bin .../{oggenc2_x64.exe => oggenc2.x64.exe} | Bin src/Config.h | 2 +- src/Encoder_Vorbis.cpp | 10 +- src/Encoder_Vorbis.h | 4 +- src/Main.cpp | 2 +- src/Thread_FileAnalyzer.cpp | 16 +-- src/Thread_FileAnalyzer.h | 5 +- src/Thread_Initialization.cpp | 116 +++++++++++------- src/Thread_Initialization.h | 4 +- 14 files changed, 97 insertions(+), 72 deletions(-) rename res/tools/{mediainfo_i386.exe => mediainfo.i386.exe} (100%) rename res/tools/{mediainfo_x64.exe => mediainfo.x64.exe} (100%) rename res/tools/{oggenc2_i386.exe => oggenc2.i386.exe} (100%) rename res/tools/{oggenc2_sse2.exe => oggenc2.sse2.exe} (100%) rename res/tools/{oggenc2_x64.exe => oggenc2.x64.exe} (100%) diff --git a/res/Tools.qrc b/res/Tools.qrc index 32db05d3..f05c440a 100644 --- a/res/Tools.qrc +++ b/res/Tools.qrc @@ -9,14 +9,14 @@ tools/gpgv.gpg tools/lame.exe tools/mac.exe - tools/mediainfo_i386.exe - tools/mediainfo_x64.exe + tools/mediainfo.i386.exe + tools/mediainfo.x64.exe tools/mpcdec.exe tools/mpg123.exe tools/oggdec.exe - tools/oggenc2_i386.exe - tools/oggenc2_sse2.exe - tools/oggenc2_x64.exe + tools/oggenc2.i386.exe + tools/oggenc2.sse2.exe + tools/oggenc2.x64.exe tools/shorten.exe tools/sox.exe tools/speexdec.exe diff --git a/res/tools/mediainfo_i386.exe b/res/tools/mediainfo.i386.exe similarity index 100% rename from res/tools/mediainfo_i386.exe rename to res/tools/mediainfo.i386.exe diff --git a/res/tools/mediainfo_x64.exe b/res/tools/mediainfo.x64.exe similarity index 100% rename from res/tools/mediainfo_x64.exe rename to res/tools/mediainfo.x64.exe diff --git a/res/tools/oggenc2_i386.exe b/res/tools/oggenc2.i386.exe similarity index 100% rename from res/tools/oggenc2_i386.exe rename to res/tools/oggenc2.i386.exe diff --git a/res/tools/oggenc2_sse2.exe b/res/tools/oggenc2.sse2.exe similarity index 100% rename from res/tools/oggenc2_sse2.exe rename to res/tools/oggenc2.sse2.exe diff --git a/res/tools/oggenc2_x64.exe b/res/tools/oggenc2.x64.exe similarity index 100% rename from res/tools/oggenc2_x64.exe rename to res/tools/oggenc2.x64.exe diff --git a/src/Config.h b/src/Config.h index 93a69bba..961ee28f 100644 --- a/src/Config.h +++ b/src/Config.h @@ -25,7 +25,7 @@ #define VER_LAMEXP_MAJOR 4 #define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_LO 2 -#define VER_LAMEXP_BUILD 430 +#define VER_LAMEXP_BUILD 432 #define VER_LAMEXP_SUFFIX Alpha-1 /* diff --git a/src/Encoder_Vorbis.cpp b/src/Encoder_Vorbis.cpp index 998b18ba..1b4c69b9 100644 --- a/src/Encoder_Vorbis.cpp +++ b/src/Encoder_Vorbis.cpp @@ -32,11 +32,9 @@ VorbisEncoder::VorbisEncoder(void) : - m_binary_i386(lamexp_lookup_tool("oggenc2_i386.exe")), - m_binary_sse2(lamexp_lookup_tool("oggenc2_sse2.exe")), - m_binary_x64(lamexp_lookup_tool("oggenc2_x64.exe")) + m_binary(lamexp_lookup_tool("oggenc2.exe")) { - if(m_binary_i386.isEmpty() || m_binary_sse2.isEmpty() || m_binary_x64.isEmpty()) + if(m_binary.isEmpty()) { throw "Error initializing Vorbis encoder. Tool 'oggenc2.exe' is not registred!"; } @@ -55,8 +53,6 @@ bool VorbisEncoder::encode(const QString &sourceFile, const AudioFileModel &meta QProcess process; QStringList args; const QString baseName = QFileInfo(outputFile).fileName(); - lamexp_cpu_t cpuFeatures = lamexp_detect_cpu_features(); - const QString &binary = (cpuFeatures.x64 ? m_binary_x64 : ((cpuFeatures.intel && cpuFeatures.sse && cpuFeatures.sse2) ? m_binary_sse2 : m_binary_i386)); switch(m_configRCMode) { @@ -97,7 +93,7 @@ bool VorbisEncoder::encode(const QString &sourceFile, const AudioFileModel &meta args << "-o" << QDir::toNativeSeparators(outputFile); args << QDir::toNativeSeparators(sourceFile); - if(!startProcess(process, binary, args)) + if(!startProcess(process, m_binary, args)) { return false; } diff --git a/src/Encoder_Vorbis.h b/src/Encoder_Vorbis.h index 04d2fb64..9a024af9 100644 --- a/src/Encoder_Vorbis.h +++ b/src/Encoder_Vorbis.h @@ -40,9 +40,7 @@ public: virtual void setSamplingRate(int value); private: - const QString m_binary_i386; - const QString m_binary_sse2; - const QString m_binary_x64; + const QString m_binary; int m_configBitrateMaximum; int m_configBitrateMinimum; int m_configSamplingRate; diff --git a/src/Main.cpp b/src/Main.cpp index 936bdbb3..1f237cd7 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -122,7 +122,7 @@ int lamexp_main(int argc, char* argv[]) SettingsModel *settingsModel = new SettingsModel(); //Show splash screen - InitializationThread *poInitializationThread = new InitializationThread(); + InitializationThread *poInitializationThread = new InitializationThread(&cpuFeatures); SplashScreen::showSplash(poInitializationThread); LAMEXP_DELETE(poInitializationThread); diff --git a/src/Thread_FileAnalyzer.cpp b/src/Thread_FileAnalyzer.cpp index 3d8a087b..dcb41153 100644 --- a/src/Thread_FileAnalyzer.cpp +++ b/src/Thread_FileAnalyzer.cpp @@ -42,12 +42,11 @@ FileAnalyzer::FileAnalyzer(const QStringList &inputFiles) : m_inputFiles(inputFiles), - m_mediaInfoBin_x86(lamexp_lookup_tool("mediainfo_i386.exe")), - m_mediaInfoBin_x64(lamexp_lookup_tool("mediainfo_x64.exe")) + m_mediaInfoBin(lamexp_lookup_tool("mediainfo.exe")) { m_bSuccess = false; - if(m_mediaInfoBin_x86.isEmpty() || m_mediaInfoBin_x64.isEmpty()) + if(m_mediaInfoBin.isEmpty()) { qFatal("Invalid path to MediaInfo binary. Tool not initialized properly."); } @@ -102,9 +101,6 @@ void FileAnalyzer::run() const AudioFileModel FileAnalyzer::analyzeFile(const QString &filePath) { - lamexp_cpu_t cpuInfo = lamexp_detect_cpu_features(); - const QString mediaInfoBin = cpuInfo.x64 ? m_mediaInfoBin_x64 : m_mediaInfoBin_x86; - AudioFileModel audioFile(filePath); m_currentSection = sectionOther; m_currentCover = coverNone; @@ -129,7 +125,7 @@ const AudioFileModel FileAnalyzer::analyzeFile(const QString &filePath) QProcess process; process.setProcessChannelMode(QProcess::MergedChannels); process.setReadChannel(QProcess::StandardOutput); - process.start(mediaInfoBin, QStringList() << QDir::toNativeSeparators(filePath)); + process.start(m_mediaInfoBin, QStringList() << QDir::toNativeSeparators(filePath)); if(!process.waitForStarted()) { @@ -201,7 +197,7 @@ const AudioFileModel FileAnalyzer::analyzeFile(const QString &filePath) if(m_currentCover != coverNone) { - retrieveCover(audioFile, filePath, mediaInfoBin); + retrieveCover(audioFile, filePath); } return audioFile; @@ -404,7 +400,7 @@ bool FileAnalyzer::checkFile_CDDA(QFile &file) return ((i >= 0) && (j >= 0) && (k >= 0) && (k > j) && (j > i)); } -void FileAnalyzer::retrieveCover(AudioFileModel &audioFile, const QString &filePath, const QString &mediaInfoBin) +void FileAnalyzer::retrieveCover(AudioFileModel &audioFile, const QString &filePath) { qDebug64("Retrieving cover from: %1", filePath); QString extension; @@ -425,7 +421,7 @@ void FileAnalyzer::retrieveCover(AudioFileModel &audioFile, const QString &fileP QProcess process; process.setProcessChannelMode(QProcess::MergedChannels); process.setReadChannel(QProcess::StandardOutput); - process.start(mediaInfoBin, QStringList() << "-f" << QDir::toNativeSeparators(filePath)); + process.start(m_mediaInfoBin, QStringList() << "-f" << QDir::toNativeSeparators(filePath)); if(!process.waitForStarted()) { diff --git a/src/Thread_FileAnalyzer.h b/src/Thread_FileAnalyzer.h index c625d2de..b5d61d65 100644 --- a/src/Thread_FileAnalyzer.h +++ b/src/Thread_FileAnalyzer.h @@ -73,11 +73,10 @@ private: unsigned int parseYear(const QString &str); unsigned int parseDuration(const QString &str); bool checkFile_CDDA(QFile &file); - void retrieveCover(AudioFileModel &audioFile, const QString &filePath, const QString &mediaInfoBin); + void retrieveCover(AudioFileModel &audioFile, const QString &filePath); QStringList m_inputFiles; - const QString m_mediaInfoBin_x86; - const QString m_mediaInfoBin_x64; + const QString m_mediaInfoBin; section_t m_currentSection; cover_t m_currentCover; unsigned int m_filesAccepted; diff --git a/src/Thread_Initialization.cpp b/src/Thread_Initialization.cpp index 760037e6..cc34d3e2 100644 --- a/src/Thread_Initialization.cpp +++ b/src/Thread_Initialization.cpp @@ -21,7 +21,6 @@ #include "Thread_Initialization.h" -#include "Global.h" #include "LockedFile.h" #include @@ -39,48 +38,62 @@ // TOOLS //////////////////////////////////////////////////////////// +#define CPU_TYPE_X86 0x000001 //x86-32 +#define CPU_TYPE_SSE 0x000002 //x86-32 + SSE2 (Intel only!) +#define CPU_TYPE_X64 0x000004 //x86-64 + +#define CPU_TYPE_GEN (CPU_TYPE_X86|CPU_TYPE_SSE) //Generic: use for all x86-32 CPU's +#define CPU_TYPE_ALL (CPU_TYPE_X86|CPU_TYPE_SSE|CPU_TYPE_X64) //All: use for all CPU's (x86-32 and x86-64) + static const struct { char *pcHash; + unsigned int uiCpuType; char *pcName; unsigned int uiVersion; } g_lamexp_tools[] = { - {"3b41f85dde8d4a5a0f4cd5f461099d0db24610ba", "alac.exe", UINT_MAX}, - {"fb74ac8b73ad8cba2c3b4e6e61f23401d630dc22", "elevator.exe", UINT_MAX}, - {"3c647950bccfcc75d0746c0772e7115684be4dc5", "faad.exe", 27}, - {"d33cd86f04bd4067e244d2804466583c7b90a4e2", "flac.exe", 121}, - {"9328a50e89b54ec065637496d9681a7e3eebf915", "gpgv.exe", 1411}, - {"d837bf6ee4dab557d8b02d46c75a24e58980fffa", "gpgv.gpg", UINT_MAX}, - {"b8800842893e2900eea7cda5c2556661333bc5db", "lame.exe", 39916}, - {"a4e929cfaa42fa2e61a3d0c6434c77a06d45aef3", "mac.exe", 406}, - {"9ee3074dc3232c61c0ffd6ae6755f65974695c51", "mediainfo_i386.exe", 743}, - {"3691da33a4efd7625d1bd01cbf5ce6ffd8a12d19", "mediainfo_x64.exe", 743}, - {"aa89763a5ba4d1a5986549b9ee53e005c51940c1", "mpcdec.exe", 435}, - {"38f81efca6c1eeab0b9dc39d06c2ac750267217f", "mpg123.exe", 1132}, - {"8dd7138714c3bcb39f5a3213413addba13d06f1e", "oggdec.exe", UINT_MAX}, - {"14a99d3b1f0b166dbd68db45196da871e58e14ec", "oggenc2_i386.exe", 287602}, - {"36f8d93ef3df6a420a73a9b5cf02dafdaf4321f0", "oggenc2_sse2.exe", 287602}, - {"87ad1af73e9b9db3da3db645e5c2253cb0c2a2ea", "oggenc2_x64.exe", 287602}, - {"0d9035bb62bdf46a2785261f8be5a4a0972abd15", "shorten.exe", 361}, - {"50ead3b852cbfc067a402e6c2d0d0d8879663dec", "sox.exe", 1432}, - {"8671e16497a2d217d3707d4aa418678d02b16bcc", "speexdec.exe", 12}, - {"093bfdec22872ca99e40183937c88785468be989", "tta.exe", 21}, - {"8c842eef65248b46fa6cb9a9e5714f575672d999", "valdec.exe", 31}, - {"62e2805d1b2eb2a4d86a5ca6e6ea58010d05d2a7", "wget.exe", 1114}, - {"a7e8aad52213e339ad985829722f35eab62be182", "wupdate.exe", UINT_MAX}, - {"b7d14b3540d24df13119a55d97623a61412de6e3", "wvunpack.exe", 4601}, - {NULL, NULL, NULL} + {"3b41f85dde8d4a5a0f4cd5f461099d0db24610ba", CPU_TYPE_ALL, "alac.exe", UINT_MAX}, + {"fb74ac8b73ad8cba2c3b4e6e61f23401d630dc22", CPU_TYPE_ALL, "elevator.exe", UINT_MAX}, + {"3c647950bccfcc75d0746c0772e7115684be4dc5", CPU_TYPE_ALL, "faad.exe", 27}, + {"d33cd86f04bd4067e244d2804466583c7b90a4e2", CPU_TYPE_ALL, "flac.exe", 121}, + {"9328a50e89b54ec065637496d9681a7e3eebf915", CPU_TYPE_ALL, "gpgv.exe", 1411}, + {"d837bf6ee4dab557d8b02d46c75a24e58980fffa", CPU_TYPE_ALL, "gpgv.gpg", UINT_MAX}, + {"b8800842893e2900eea7cda5c2556661333bc5db", CPU_TYPE_ALL, "lame.exe", 39916}, + {"a4e929cfaa42fa2e61a3d0c6434c77a06d45aef3", CPU_TYPE_ALL, "mac.exe", 406}, + {"9ee3074dc3232c61c0ffd6ae6755f65974695c51", CPU_TYPE_GEN, "mediainfo.i386.exe", 743}, + {"3691da33a4efd7625d1bd01cbf5ce6ffd8a12d19", CPU_TYPE_X64, "mediainfo.x64.exe", 743}, + {"aa89763a5ba4d1a5986549b9ee53e005c51940c1", CPU_TYPE_ALL, "mpcdec.exe", 435}, + {"38f81efca6c1eeab0b9dc39d06c2ac750267217f", CPU_TYPE_ALL, "mpg123.exe", 1132}, + {"8dd7138714c3bcb39f5a3213413addba13d06f1e", CPU_TYPE_ALL, "oggdec.exe", UINT_MAX}, + {"14a99d3b1f0b166dbd68db45196da871e58e14ec", CPU_TYPE_X86, "oggenc2.i386.exe", 287602}, + {"36f8d93ef3df6a420a73a9b5cf02dafdaf4321f0", CPU_TYPE_SSE, "oggenc2.sse2.exe", 287602}, + {"87ad1af73e9b9db3da3db645e5c2253cb0c2a2ea", CPU_TYPE_X64, "oggenc2.x64.exe", 287602}, + {"0d9035bb62bdf46a2785261f8be5a4a0972abd15", CPU_TYPE_ALL, "shorten.exe", 361}, + {"50ead3b852cbfc067a402e6c2d0d0d8879663dec", CPU_TYPE_ALL, "sox.exe", 1432}, + {"8671e16497a2d217d3707d4aa418678d02b16bcc", CPU_TYPE_ALL, "speexdec.exe", 12}, + {"093bfdec22872ca99e40183937c88785468be989", CPU_TYPE_ALL, "tta.exe", 21}, + {"8c842eef65248b46fa6cb9a9e5714f575672d999", CPU_TYPE_ALL, "valdec.exe", 31}, + {"62e2805d1b2eb2a4d86a5ca6e6ea58010d05d2a7", CPU_TYPE_ALL, "wget.exe", 1114}, + {"a7e8aad52213e339ad985829722f35eab62be182", CPU_TYPE_ALL, "wupdate.exe", UINT_MAX}, + {"b7d14b3540d24df13119a55d97623a61412de6e3", CPU_TYPE_ALL, "wvunpack.exe", 4601}, + {NULL, NULL, NULL, NULL} }; //////////////////////////////////////////////////////////// // Constructor //////////////////////////////////////////////////////////// -InitializationThread::InitializationThread(void) +InitializationThread::InitializationThread(const lamexp_cpu_t *cpuFeatures) { m_bSuccess = false; + memset(&m_cpuFeatures, 0, sizeof(lamexp_cpu_t)); + + if(cpuFeatures) + { + memcpy(&m_cpuFeatures, cpuFeatures, sizeof(lamexp_cpu_t)); + } } //////////////////////////////////////////////////////////// @@ -92,10 +105,15 @@ void InitializationThread::run() m_bSuccess = false; delay(); - QMap checksum; - QMap version; + //CPU type selection + unsigned int cpuSupport = m_cpuFeatures.x64 ? CPU_TYPE_X64 : ((m_cpuFeatures.intel && m_cpuFeatures.sse && m_cpuFeatures.sse2) ? CPU_TYPE_SSE : CPU_TYPE_X86); + + //Allocate maps + QMap mapChecksum; + QMap mapVersion; + QMap mapCpuType; - //Init checksums + //Init properties for(int i = 0; i < INT_MAX; i++) { if(!g_lamexp_tools[i].pcName && !g_lamexp_tools[i].pcHash && !g_lamexp_tools[i].uiVersion) @@ -105,8 +123,9 @@ void InitializationThread::run() else if(g_lamexp_tools[i].pcName && g_lamexp_tools[i].pcHash && g_lamexp_tools[i].uiVersion) { const QString currentTool = QString::fromLatin1(g_lamexp_tools[i].pcName); - checksum.insert(currentTool, QString::fromLatin1(g_lamexp_tools[i].pcHash)); - version.insert(currentTool, g_lamexp_tools[i].uiVersion); + mapChecksum.insert(currentTool, QString::fromLatin1(g_lamexp_tools[i].pcHash)); + mapCpuType.insert(currentTool, g_lamexp_tools[i].uiCpuType); + mapVersion.insert(currentTool, g_lamexp_tools[i].uiVersion); } else { @@ -121,20 +140,29 @@ void InitializationThread::run() timer.start(); //Extract all files - for(int i = 0; i < toolsList.count(); i++) + while(!toolsList.isEmpty()) { try { - QString toolName = toolsList.at(i).fileName().toLower(); - qDebug("Extracting file: %s", toolName.toLatin1().constData()); - QByteArray toolHash = checksum.take(toolName).toLatin1(); - unsigned int toolVersion = version.take(toolName); + QFileInfo currentTool = toolsList.takeFirst(); + QString toolName = currentTool.fileName().toLower(); + QString toolShortName = QString("%1.%2").arg(currentTool.baseName().toLower(), currentTool.suffix().toLower()); + + QByteArray toolHash = mapChecksum.take(toolName).toLatin1(); + unsigned int toolCpuType = mapCpuType.take(toolName); + unsigned int toolVersion = mapVersion.take(toolName); + if(toolHash.size() != 40) { throw "The required checksum is missing, take care!"; } - LockedFile *lockedFile = new LockedFile(QString(":/tools/%1").arg(toolName), QString(lamexp_temp_folder2()).append(QString("/tool_%1").arg(toolName)), toolHash); - lamexp_register_tool(toolName, lockedFile, toolVersion); + + if(toolCpuType & cpuSupport) + { + qDebug("Extracting file: %s -> %s", toolName.toLatin1().constData(), toolShortName.toLatin1().constData()); + LockedFile *lockedFile = new LockedFile(QString(":/tools/%1").arg(toolName), QString("%1/tool_%2").arg(lamexp_temp_folder2(), toolShortName), toolHash); + lamexp_register_tool(toolShortName, lockedFile, toolVersion); + } } catch(char *errorMsg) { @@ -143,12 +171,18 @@ void InitializationThread::run() } } - if(!checksum.isEmpty()) + //Make sure all files were extracted + if(!mapChecksum.isEmpty()) { - qFatal("At least one required tool could not be found:\n%s", toolsDir.filePath(checksum.keys().first()).toLatin1().constData()); + qFatal("At least one required tool could not be found:\n%s", toolsDir.filePath(mapChecksum.keys().first()).toLatin1().constData()); return; } + //Clean-up + mapChecksum.clear(); + mapVersion.clear(); + mapCpuType.clear(); + qDebug("All extracted.\n"); //Check delay diff --git a/src/Thread_Initialization.h b/src/Thread_Initialization.h index b109774e..d0242e0e 100644 --- a/src/Thread_Initialization.h +++ b/src/Thread_Initialization.h @@ -21,6 +21,7 @@ #pragma once +#include "Global.h" #include //////////////////////////////////////////////////////////// @@ -32,7 +33,7 @@ class InitializationThread: public QThread Q_OBJECT public: - InitializationThread(void); + InitializationThread(const lamexp_cpu_t *cpuFeatures); void run(); bool getSuccess(void) { return !isRunning() && m_bSuccess; } @@ -42,5 +43,6 @@ private: void initNeroAac(void); void initWmaDec(void); + lamexp_cpu_t m_cpuFeatures; bool m_bSuccess; };