From f38c651a18fd5422ffd08e8ee0ef4a09c1b95bb1 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Sun, 2 Oct 2016 16:18:01 +0200 Subject: [PATCH] Added support for detecting "portable" Avisynth. --- src/encoder_abstract.cpp | 2 +- src/model_sysinfo.h | 1 + src/source_abstract.cpp | 4 ++-- src/source_abstract.h | 3 ++- src/source_avisynth.cpp | 16 ++++++++++++- src/source_avisynth.h | 3 ++- src/source_vapoursynth.cpp | 2 +- src/thread_avisynth.cpp | 48 +++++++++++++++++++++++++++----------- src/thread_avisynth.h | 10 ++++---- src/thread_vapoursynth.cpp | 2 -- src/tool_abstract.cpp | 15 ++++-------- src/tool_abstract.h | 5 ++-- src/version.h | 2 +- 13 files changed, 73 insertions(+), 40 deletions(-) diff --git a/src/encoder_abstract.cpp b/src/encoder_abstract.cpp index 402a933..dbfff0c 100644 --- a/src/encoder_abstract.cpp +++ b/src/encoder_abstract.cpp @@ -80,7 +80,7 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString buildCommandLine(cmdLine_Encode, (pipedSource != NULL), clipInfo, m_indexFile, pass, passLogFile); log("Creating encoder process:"); - if(!startProcess(processEncode, getBinaryPath(), cmdLine_Encode)) + if(!startProcess(processEncode, getBinaryPath(), cmdLine_Encode, true, getExtraPath())) { return false; } diff --git a/src/model_sysinfo.h b/src/model_sysinfo.h index 3023536..e373358 100644 --- a/src/model_sysinfo.h +++ b/src/model_sysinfo.h @@ -107,6 +107,7 @@ public: SYSINFO_MAKE_FLAG(Avisynth) SYSINFO_MAKE_FLAG(VapourSynth) + SYSINFO_MAKE_PATH(AVS) SYSINFO_MAKE_PATH(VPS) SYSINFO_MAKE_PATH(App) diff --git a/src/source_abstract.cpp b/src/source_abstract.cpp index f29ab10..1ab973f 100644 --- a/src/source_abstract.cpp +++ b/src/source_abstract.cpp @@ -67,7 +67,7 @@ bool AbstractSource::checkSourceProperties(ClipInfo &clipInfo) checkSourceProperties_init(patterns, cmdLine); log("Creating process:"); - if(!startProcess(process, getBinaryPath(), cmdLine)) + if(!startProcess(process, getBinaryPath(), cmdLine, true, getExtraPath())) { return false;; } @@ -191,7 +191,7 @@ bool AbstractSource::createProcess(QProcess &processEncode, QProcess&processInpu buildCommandLine(cmdLine_Input); log("Creating input process:"); - if(!startProcess(processInput, getBinaryPath(), cmdLine_Input, false)) + if(!startProcess(processInput, getBinaryPath(), cmdLine_Input, false, getExtraPath())) { return false; } diff --git a/src/source_abstract.h b/src/source_abstract.h index 8b4c39e..4fcd144 100644 --- a/src/source_abstract.h +++ b/src/source_abstract.h @@ -32,7 +32,8 @@ class QProcess; class AbstractSourceInfo { public: - virtual QString getBinaryPath(const SysinfoModel *sysinfo, const bool& x64) const = 0; + virtual QString getBinaryPath(const SysinfoModel *const sysinfo, const bool& x64) const = 0; + virtual QString getExtraPath(const SysinfoModel *const sysinfo, const bool& x64) const { return QString(); } }; class AbstractSource : public AbstractTool diff --git a/src/source_avisynth.cpp b/src/source_avisynth.cpp index eca9005..99aa97b 100644 --- a/src/source_avisynth.cpp +++ b/src/source_avisynth.cpp @@ -25,6 +25,8 @@ #include "global.h" +#include + #include #include @@ -37,10 +39,21 @@ static const unsigned int VER_X264_AVS2YUV_VER = 243; class AvisynthSourceInfo : public AbstractSourceInfo { public: - virtual QString getBinaryPath(const SysinfoModel *sysinfo, const bool& x64) const + virtual QString getBinaryPath(const SysinfoModel *const sysinfo, const bool& x64) const { return QString("%1/toolset/%2/avs2yuv_%2.exe").arg(sysinfo->getAppPath(), (x64 ? "x64": "x86")); } + + virtual QString getExtraPath(const SysinfoModel *const sysinfo, const bool& x64) const + { + const QString avsPath = sysinfo->getAVSPath(); + if (!avsPath.isEmpty()) + { + + return QString("%1/%2").arg(avsPath, x64 ? QLatin1String("x64") : QLatin1String("x86")); + } + return QString(); + } }; static const AvisynthSourceInfo s_avisynthEncoderInfo; @@ -50,6 +63,7 @@ const AbstractSourceInfo &AvisynthSource::getSourceInfo(void) return s_avisynthEncoderInfo; } + // ------------------------------------------------------------ // Constructor & Destructor // ------------------------------------------------------------ diff --git a/src/source_avisynth.h b/src/source_avisynth.h index 29bf8eb..14115d6 100644 --- a/src/source_avisynth.h +++ b/src/source_avisynth.h @@ -49,6 +49,7 @@ protected: virtual void checkSourceProperties_init(QList &patterns, QStringList &cmdLine); virtual void checkSourceProperties_parseLine(const QString &line, QList &patterns, ClipInfo &clipInfo); - virtual QString getBinaryPath() const { return getSourceInfo().getBinaryPath(m_sysinfo, m_sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64) && m_sysinfo->getAvisynth(SysinfoModel::Avisynth_X64) && (m_preferences->getPrefer64BitSource() || (!m_sysinfo->getAvisynth(SysinfoModel::Avisynth_X86)))); } + virtual QString getBinaryPath(void) const { return getSourceInfo().getBinaryPath(m_sysinfo, m_sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64) && m_sysinfo->getAvisynth(SysinfoModel::Avisynth_X64) && (m_preferences->getPrefer64BitSource() || (!m_sysinfo->getAvisynth(SysinfoModel::Avisynth_X86)))); } + virtual QString getExtraPath(void) const { return getSourceInfo().getExtraPath(m_sysinfo, m_sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64) && m_sysinfo->getAvisynth(SysinfoModel::Avisynth_X64) && (m_preferences->getPrefer64BitSource() || (!m_sysinfo->getAvisynth(SysinfoModel::Avisynth_X86)))); } virtual void buildCommandLine(QStringList &cmdLine); }; diff --git a/src/source_vapoursynth.cpp b/src/source_vapoursynth.cpp index bb628be..c95f386 100644 --- a/src/source_vapoursynth.cpp +++ b/src/source_vapoursynth.cpp @@ -39,7 +39,7 @@ static const unsigned int VER_X264_VSPIPE_VER = 24; class VapoursyntSourceInfo : public AbstractSourceInfo { public: - virtual QString getBinaryPath(const SysinfoModel *sysinfo, const bool& x64) const + virtual QString getBinaryPath(const SysinfoModel *const sysinfo, const bool& x64) const { return QString("%1/core%2/vspipe.exe").arg(sysinfo->getVPSPath(), (x64 ? "64" : "32")); } diff --git a/src/thread_avisynth.cpp b/src/thread_avisynth.cpp index b421e44..42f9485 100644 --- a/src/thread_avisynth.cpp +++ b/src/thread_avisynth.cpp @@ -21,6 +21,7 @@ #include "thread_avisynth.h" +//Qt #include #include #include @@ -37,11 +38,15 @@ #include #include +//Const +static const bool ENABLE_PORTABLE_AVS = true; + //Static QMutex AvisynthCheckThread::m_avsLock; QScopedPointer AvisynthCheckThread::m_avsDllPath[2]; //Helper +#define VALID_DIR(STR) ((!(STR).isEmpty()) && QDir((STR)).exists()) #define BOOLIFY(X) ((X) ? '1' : '0') //Utility function @@ -118,6 +123,7 @@ bool AvisynthCheckThread::detect(SysinfoModel *sysinfo) { sysinfo->setAvisynth(SysinfoModel::Avisynth_X86, thread.getSuccess() & AVISYNTH_X86); sysinfo->setAvisynth(SysinfoModel::Avisynth_X64, thread.getSuccess() & AVISYNTH_X64); + sysinfo->setAVSPath(thread.getPath()); qDebug("Avisynth support is officially enabled now! [x86=%c, x64=%c]", BOOLIFY(sysinfo->getAvisynth(SysinfoModel::Avisynth_X86)), BOOLIFY(sysinfo->getAvisynth(SysinfoModel::Avisynth_X64))); } else @@ -148,15 +154,16 @@ void AvisynthCheckThread::run(void) { m_exception = false; m_success &= 0; + m_basePath.clear(); - detectAvisynthVersion1(m_success, m_sysinfo, &m_exception); + detectAvisynthVersion1(m_success, m_basePath, m_sysinfo, &m_exception); } -void AvisynthCheckThread::detectAvisynthVersion1(int &success, const SysinfoModel *const sysinfo, volatile bool *exception) +void AvisynthCheckThread::detectAvisynthVersion1(int &success, QString &basePath, const SysinfoModel *const sysinfo, volatile bool *exception) { __try { - detectAvisynthVersion2(success, sysinfo, exception); + detectAvisynthVersion2(success, basePath, sysinfo, exception); } __except(1) { @@ -165,11 +172,11 @@ void AvisynthCheckThread::detectAvisynthVersion1(int &success, const SysinfoMode } } -void AvisynthCheckThread::detectAvisynthVersion2(int &success, const SysinfoModel *const sysinfo, volatile bool *exception) +void AvisynthCheckThread::detectAvisynthVersion2(int &success, QString &basePath, const SysinfoModel *const sysinfo, volatile bool *exception) { try { - return detectAvisynthVersion3(success, sysinfo); + return detectAvisynthVersion3(success, basePath, sysinfo); } catch(...) { @@ -178,12 +185,12 @@ void AvisynthCheckThread::detectAvisynthVersion2(int &success, const SysinfoMode } } -void AvisynthCheckThread::detectAvisynthVersion3(int &success, const SysinfoModel *const sysinfo) +void AvisynthCheckThread::detectAvisynthVersion3(int &success, QString &basePath, const SysinfoModel *const sysinfo) { success &= 0; QFile *avsPath32; - if(checkAvisynth(sysinfo, avsPath32, false)) + if(checkAvisynth(basePath, sysinfo, avsPath32, false)) { m_avsDllPath[0].reset(avsPath32); success |= AVISYNTH_X86; @@ -197,7 +204,7 @@ void AvisynthCheckThread::detectAvisynthVersion3(int &success, const SysinfoMode if(sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64)) { QFile *avsPath64; - if(checkAvisynth(sysinfo, avsPath64, true)) + if(checkAvisynth(basePath, sysinfo, avsPath64, true)) { m_avsDllPath[1].reset(avsPath64); success |= AVISYNTH_X64; @@ -214,17 +221,33 @@ void AvisynthCheckThread::detectAvisynthVersion3(int &success, const SysinfoMode } } -bool AvisynthCheckThread::checkAvisynth(const SysinfoModel *const sysinfo, QFile *&path, const bool &x64) +bool AvisynthCheckThread::checkAvisynth(QString &basePath, const SysinfoModel *const sysinfo, QFile *&path, const bool &x64) { qDebug("Avisynth %s-Bit support is being tested.", x64 ? "64" : "32"); QProcess process; QStringList output; + QString extraPath; + + //Look for "portable" Avisynth version + if (ENABLE_PORTABLE_AVS) + { + const QString avsPortableDir = QString("%1/extra/Avisynth").arg(QCoreApplication::applicationDirPath()); + if (VALID_DIR(avsPortableDir)) + { + const QString archDir = x64 ? QLatin1String("x64") : QLatin1String("x86"); + QFileInfo avsDllFile(QString("%1/%2/avisynth.dll").arg(avsPortableDir, archDir)), devilDllFile(QString("%1/%2/devil.dll").arg(avsPortableDir, archDir)); + if (avsDllFile.exists() && devilDllFile.exists() && avsDllFile.isFile() && devilDllFile.isFile()) + { + qWarning("Adding portable Avisynth to PATH environment variable: %s", MUTILS_UTF8(avsPortableDir)); + basePath = avsPortableDir; + extraPath = QString("%1/%2").arg(avsPortableDir, archDir); + } + } + } //Setup process object - process.setWorkingDirectory(QDir::tempPath()); - process.setProcessChannelMode(QProcess::MergedChannels); - process.setReadChannel(QProcess::StandardOutput); + MUtils::init_process(process, QDir::tempPath(), true, extraPath); //Try to start VSPIPE.EXE process.start(AVS_CHECK_BINARY(sysinfo, x64), QStringList()); @@ -319,7 +342,6 @@ bool AvisynthCheckThread::checkAvisynth(const SysinfoModel *const sysinfo, QFile { MUTILS_DELETE(path); } - qDebug("Avisynth was detected successfully (current version: %u.%02u).", avisynthVersion[0], avisynthVersion[1]); qDebug("Avisynth DLL path: %s", MUTILS_UTF8(avisynthPath)); return true; diff --git a/src/thread_avisynth.h b/src/thread_avisynth.h index 97c0ef2..16ce1e6 100644 --- a/src/thread_avisynth.h +++ b/src/thread_avisynth.h @@ -41,6 +41,7 @@ protected: int getSuccess(void) { return m_success; } bool getException(void) { return m_exception; } + QString getPath(void) { return m_basePath; } typedef enum _AvisynthFlags { @@ -55,6 +56,7 @@ private slots: private: volatile bool m_exception; int m_success; + QString m_basePath; const SysinfoModel *const m_sysinfo; static QMutex m_avsLock; @@ -64,10 +66,10 @@ private: virtual void run(void); //Functions - static void detectAvisynthVersion1(int &success, const SysinfoModel *const sysinfo, volatile bool *exception); - static void detectAvisynthVersion2(int &success, const SysinfoModel *const sysinfo, volatile bool *exception); - static void detectAvisynthVersion3(int &success, const SysinfoModel *const sysinfo); + static void detectAvisynthVersion1(int &success, QString &basePath, const SysinfoModel *const sysinfo, volatile bool *exception); + static void detectAvisynthVersion2(int &success, QString &basePath, const SysinfoModel *const sysinfo, volatile bool *exception); + static void detectAvisynthVersion3(int &success, QString &basePath, const SysinfoModel *const sysinfo); //Internal functions - static bool checkAvisynth(const SysinfoModel *const sysinfo, QFile *&path, const bool &x64); + static bool checkAvisynth(QString &basePath, const SysinfoModel *const sysinfo, QFile *&path, const bool &x64); }; diff --git a/src/thread_vapoursynth.cpp b/src/thread_vapoursynth.cpp index e52a85b..eeed03d 100644 --- a/src/thread_vapoursynth.cpp +++ b/src/thread_vapoursynth.cpp @@ -262,7 +262,6 @@ void VapourSynthCheckThread::detectVapourSynthPath3(int &success, QString &path) } } - //Make sure VapourSynth directory does exist if(vapoursynthPath.isEmpty()) { @@ -270,7 +269,6 @@ void VapourSynthCheckThread::detectVapourSynthPath3(int &success, QString &path) return; } - //Validate the VapourSynth installation now! qDebug("VapourSynth Dir: %s", vapoursynthPath.toUtf8().constData()); for (size_t i = 0; VPS_CORE_DIR[i]; i++) diff --git a/src/tool_abstract.cpp b/src/tool_abstract.cpp index 2bb5c63..7aba793 100644 --- a/src/tool_abstract.cpp +++ b/src/tool_abstract.cpp @@ -94,7 +94,7 @@ unsigned int AbstractTool::checkVersion(bool &modified) checkVersion_init(patterns, cmdLine); log("Creating process:"); - if(!startProcess(process, getBinaryPath(), cmdLine)) + if(!startProcess(process, getBinaryPath(), cmdLine, true, getExtraPath())) { return false; } @@ -173,19 +173,14 @@ bool AbstractTool::checkVersion_succeeded(const int &exitCode) // Process Creation // ------------------------------------------------------------ -bool AbstractTool::startProcess(QProcess &process, const QString &program, const QStringList &args, bool mergeChannels) +bool AbstractTool::startProcess(QProcess &process, const QString &program, const QStringList &args, bool mergeChannels, const QString &extraPath) { QMutexLocker lock(&s_mutexStartProcess); log(commandline2string(program, args) + "\n"); + log("EXTRAPATH: '" + extraPath + "'\n"); - process.setWorkingDirectory(QDir::tempPath()); - - if(mergeChannels) - { - process.setProcessChannelMode(QProcess::MergedChannels); - process.setReadChannel(QProcess::StandardOutput); - } - else + MUtils::init_process(process, QDir::tempPath(), true, extraPath); + if(!mergeChannels) { process.setProcessChannelMode(QProcess::SeparateChannels); process.setReadChannel(QProcess::StandardError); diff --git a/src/tool_abstract.h b/src/tool_abstract.h index 4d71fb4..ad7f6df 100644 --- a/src/tool_abstract.h +++ b/src/tool_abstract.h @@ -51,8 +51,6 @@ public: virtual bool isVersionSupported(const unsigned int &revision, const bool &modified) = 0; virtual QString printVersion(const unsigned int &revision, const bool &modified) = 0; - //static const unsigned int REV_MULT = 10000; - signals: void statusChanged(const JobStatus &newStatus); void progressChanged(unsigned int newProgress); @@ -65,6 +63,7 @@ protected: static const unsigned int m_processTimeoutWarning = 24; virtual QString getBinaryPath(void) const = 0; + virtual QString getExtraPath(void) const { return QString(); } virtual void checkVersion_init(QList &patterns, QStringList &cmdLine) = 0; virtual void checkVersion_parseLine(const QString &line, QList &patterns, unsigned int &core, unsigned int &build, bool &modified) = 0; @@ -75,7 +74,7 @@ protected: void setProgress(unsigned int newProgress) { emit progressChanged(newProgress); } void setDetails(const QString &text) { emit detailsChanged(text); } - bool startProcess(QProcess &process, const QString &program, const QStringList &args, bool mergeChannels = true); + bool startProcess(QProcess &process, const QString &program, const QStringList &args, bool mergeChannels = true, const QString &extraPath = QString()); JobObject *const m_jobObject; const OptionsModel *const m_options; diff --git a/src/version.h b/src/version.h index 90361b3..088842c 100644 --- a/src/version.h +++ b/src/version.h @@ -26,7 +26,7 @@ #define VER_X264_MAJOR 2 #define VER_X264_MINOR 7 #define VER_X264_PATCH 5 -#define VER_X264_BUILD 1045 +#define VER_X264_BUILD 1051 #define VER_X264_PORTABLE_EDITION (0)