Improved Avisynth detection code. We now detect 32-Bit and 64-Bit Avisynth separately.
This commit is contained in:
parent
2658b4c628
commit
0187a00f4d
@ -93,7 +93,9 @@ QString AVS_BINARY(const SysinfoModel *sysinfo, const bool& x64)
|
|||||||
|
|
||||||
QString AVS_BINARY(const SysinfoModel *sysinfo, const PreferencesModel *preferences)
|
QString AVS_BINARY(const SysinfoModel *sysinfo, const PreferencesModel *preferences)
|
||||||
{
|
{
|
||||||
return AVS_BINARY(sysinfo, preferences->getPrefer64BitSource() && sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64));
|
const bool avs32 = sysinfo->getAvisynth(SysinfoModel::Avisynth_X86);
|
||||||
|
const bool avs64 = sysinfo->getAvisynth(SysinfoModel::Avisynth_X64) && sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64);
|
||||||
|
return AVS_BINARY(sysinfo, (avs32 && avs64) ? preferences->getPrefer64BitSource() : avs64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- VapurSynth --- */
|
/* --- VapurSynth --- */
|
||||||
@ -109,3 +111,10 @@ QString VPS_BINARY(const SysinfoModel *sysinfo, const PreferencesModel *preferen
|
|||||||
const bool vps64 = sysinfo->getVapourSynth(SysinfoModel::VapourSynth_X64) && sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64);
|
const bool vps64 = sysinfo->getVapourSynth(SysinfoModel::VapourSynth_X64) && sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64);
|
||||||
return VPS_BINARY(sysinfo, (vps32 && vps64) ? preferences->getPrefer64BitSource() : vps64);
|
return VPS_BINARY(sysinfo, (vps32 && vps64) ? preferences->getPrefer64BitSource() : vps64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- AVS Checker--- */
|
||||||
|
|
||||||
|
QString CHK_BINARY(const SysinfoModel *sysinfo, const bool& x64)
|
||||||
|
{
|
||||||
|
return QString("%1/toolset/%2/avs_check_%2.exe").arg(sysinfo->getAppPath(), (x64 ? "x64": "x86"));
|
||||||
|
}
|
||||||
|
@ -32,3 +32,5 @@ QString AVS_BINARY(const SysinfoModel *sysinfo, const PreferencesModel *preferen
|
|||||||
|
|
||||||
QString VPS_BINARY(const SysinfoModel *sysinfo, const bool& x64);
|
QString VPS_BINARY(const SysinfoModel *sysinfo, const bool& x64);
|
||||||
QString VPS_BINARY(const SysinfoModel *sysinfo, const PreferencesModel *preferences);
|
QString VPS_BINARY(const SysinfoModel *sysinfo, const PreferencesModel *preferences);
|
||||||
|
|
||||||
|
QString CHK_BINARY(const SysinfoModel *sysinfo, const bool &x64);
|
||||||
|
@ -46,6 +46,11 @@
|
|||||||
{ \
|
{ \
|
||||||
QMutexLocker lock(&m_mutex); \
|
QMutexLocker lock(&m_mutex); \
|
||||||
return !!m_flag##NAME; \
|
return !!m_flag##NAME; \
|
||||||
|
} \
|
||||||
|
inline void clear##NAME(void) \
|
||||||
|
{ \
|
||||||
|
QMutexLocker lock(&m_mutex); \
|
||||||
|
m_flag##NAME &= 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SYSINFO_MAKE_PATH(NAME) \
|
#define SYSINFO_MAKE_PATH(NAME) \
|
||||||
@ -62,6 +67,11 @@
|
|||||||
QMutexLocker lock(&m_mutex); \
|
QMutexLocker lock(&m_mutex); \
|
||||||
const QString path = m_path##NAME; \
|
const QString path = m_path##NAME; \
|
||||||
return path; \
|
return path; \
|
||||||
|
} \
|
||||||
|
inline void clear##NAME##Path(void) \
|
||||||
|
{ \
|
||||||
|
QMutexLocker lock(&m_mutex); \
|
||||||
|
m_path##NAME.clear(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -26,28 +26,59 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
//Internal
|
//Internal
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "3rd_party/avisynth_c.h"
|
#include "model_sysinfo.h"
|
||||||
|
#include "binaries.h"
|
||||||
|
|
||||||
//MUtils
|
//MUtils
|
||||||
#include <MUtils/Global.h>
|
#include <MUtils/Global.h>
|
||||||
|
#include <MUtils/OSSupport.h>
|
||||||
|
|
||||||
|
//Static
|
||||||
QMutex AvisynthCheckThread::m_avsLock;
|
QMutex AvisynthCheckThread::m_avsLock;
|
||||||
QScopedPointer<QLibrary> AvisynthCheckThread::m_avsLib;
|
QScopedPointer<QFile> AvisynthCheckThread::m_avsDllPath[2];
|
||||||
|
|
||||||
|
#define BOOLIFY(X) ((X) ? '1' : '0')
|
||||||
|
|
||||||
|
class Wow64RedirectionDisabler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Wow64RedirectionDisabler(void)
|
||||||
|
{
|
||||||
|
m_oldValue = NULL;
|
||||||
|
m_disabled = MUtils::OS::wow64fsredir_disable(m_oldValue);
|
||||||
|
}
|
||||||
|
~Wow64RedirectionDisabler(void)
|
||||||
|
{
|
||||||
|
if(m_disabled)
|
||||||
|
{
|
||||||
|
if(!MUtils::OS::wow64fsredir_revert(m_oldValue))
|
||||||
|
{
|
||||||
|
qWarning("Failed to renable WOW64 filesystem redirection!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
bool m_disabled;
|
||||||
|
void* m_oldValue;
|
||||||
|
};
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// External API
|
// External API
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
int AvisynthCheckThread::detect(volatile double *version)
|
bool AvisynthCheckThread::detect(SysinfoModel *sysinfo)
|
||||||
{
|
{
|
||||||
*version = 0.0;
|
sysinfo->clearAvisynth();
|
||||||
|
double version = 0.0;
|
||||||
QMutexLocker lock(&m_avsLock);
|
QMutexLocker lock(&m_avsLock);
|
||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
AvisynthCheckThread thread;
|
AvisynthCheckThread thread(sysinfo);
|
||||||
|
|
||||||
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
|
||||||
|
|
||||||
@ -68,35 +99,39 @@ int AvisynthCheckThread::detect(volatile double *version)
|
|||||||
qWarning("Avisynth thread encountered timeout -> probably deadlock!");
|
qWarning("Avisynth thread encountered timeout -> probably deadlock!");
|
||||||
thread.terminate();
|
thread.terminate();
|
||||||
thread.wait();
|
thread.wait();
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thread.getException())
|
if(thread.getException())
|
||||||
{
|
{
|
||||||
qWarning("Avisynth thread encountered an exception !!!");
|
qWarning("Avisynth thread encountered an exception !!!");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thread.getSuccess())
|
if(thread.getSuccess())
|
||||||
{
|
{
|
||||||
*version = thread.getVersion();
|
sysinfo->setAvisynth(SysinfoModel::Avisynth_X86, thread.getSuccess() & AVISYNTH_X86);
|
||||||
qDebug("Version check completed: %.2f", *version);
|
sysinfo->setAvisynth(SysinfoModel::Avisynth_X64, thread.getSuccess() & AVISYNTH_X64);
|
||||||
return 1;
|
qDebug("Avisynth support is officially enabled now! [x86=%c, x64=%c]", BOOLIFY(sysinfo->getAvisynth(SysinfoModel::Avisynth_X86)), BOOLIFY(sysinfo->getAvisynth(SysinfoModel::Avisynth_X64)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qWarning("Avisynth could not be found -> Avisynth support disabled!");
|
||||||
}
|
}
|
||||||
|
|
||||||
qWarning("Avisynth thread failed to determine the version!");
|
return true;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
// Thread class
|
// Thread class
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
AvisynthCheckThread::AvisynthCheckThread(void)
|
AvisynthCheckThread::AvisynthCheckThread(const SysinfoModel *const sysinfo)
|
||||||
|
:
|
||||||
|
m_sysinfo(sysinfo)
|
||||||
{
|
{
|
||||||
m_success = false;
|
m_success = false;
|
||||||
m_exception = false;
|
m_exception = false;
|
||||||
m_version = 0.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AvisynthCheckThread::~AvisynthCheckThread(void)
|
AvisynthCheckThread::~AvisynthCheckThread(void)
|
||||||
@ -105,106 +140,179 @@ AvisynthCheckThread::~AvisynthCheckThread(void)
|
|||||||
|
|
||||||
void AvisynthCheckThread::run(void)
|
void AvisynthCheckThread::run(void)
|
||||||
{
|
{
|
||||||
m_exception = m_success = false;
|
m_exception = false;
|
||||||
m_success = detectAvisynthVersion1(&m_version, &m_exception);
|
m_success &= 0;
|
||||||
|
|
||||||
|
detectAvisynthVersion1(m_success, m_sysinfo, &m_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvisynthCheckThread::detectAvisynthVersion1(volatile double *version_number, volatile bool *exception)
|
void AvisynthCheckThread::detectAvisynthVersion1(int &success, const SysinfoModel *const sysinfo, volatile bool *exception)
|
||||||
{
|
{
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
return detectAvisynthVersion2(version_number, exception);
|
detectAvisynthVersion2(success, sysinfo, exception);
|
||||||
}
|
}
|
||||||
__except(1)
|
__except(1)
|
||||||
{
|
{
|
||||||
*exception = true;
|
*exception = true;
|
||||||
qWarning("Unhandled exception error in Avisynth thread !!!");
|
qWarning("Unhandled exception error in Avisynth thread !!!");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvisynthCheckThread::detectAvisynthVersion2(volatile double *version_number, volatile bool *exception)
|
void AvisynthCheckThread::detectAvisynthVersion2(int &success, const SysinfoModel *const sysinfo, volatile bool *exception)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return detectAvisynthVersion3(version_number);
|
return detectAvisynthVersion3(success, sysinfo);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
*exception = true;
|
*exception = true;
|
||||||
qWarning("Avisynth initializdation raised an C++ exception!");
|
qWarning("Avisynth initializdation raised an C++ exception!");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvisynthCheckThread::detectAvisynthVersion3(volatile double *version_number)
|
void AvisynthCheckThread::detectAvisynthVersion3(int &success, const SysinfoModel *const sysinfo)
|
||||||
{
|
{
|
||||||
bool success = false;
|
success &= 0;
|
||||||
*version_number = 0.0;
|
|
||||||
|
|
||||||
m_avsLib.reset(new QLibrary("avisynth.dll"));
|
QFile *avsPath32;
|
||||||
if(m_avsLib->isLoaded() || m_avsLib->load())
|
if(checkAvisynth(sysinfo, avsPath32, false))
|
||||||
{
|
{
|
||||||
avs_create_script_environment_func avs_create_script_environment_ptr = (avs_create_script_environment_func) m_avsLib->resolve("avs_create_script_environment");
|
m_avsDllPath[0].reset(avsPath32);
|
||||||
avs_invoke_func avs_invoke_ptr = (avs_invoke_func) m_avsLib->resolve("avs_invoke");
|
success |= AVISYNTH_X86;
|
||||||
avs_function_exists_func avs_function_exists_ptr = (avs_function_exists_func) m_avsLib->resolve("avs_function_exists");
|
qDebug("Avisynth 32-Bit edition found!");
|
||||||
avs_delete_script_environment_func avs_delete_script_environment_ptr = (avs_delete_script_environment_func) m_avsLib->resolve("avs_delete_script_environment");
|
}
|
||||||
avs_release_value_func avs_release_value_ptr = (avs_release_value_func) m_avsLib->resolve("avs_release_value");
|
else
|
||||||
|
{
|
||||||
if((avs_create_script_environment_ptr != NULL) && (avs_invoke_ptr != NULL) && (avs_function_exists_ptr != NULL))
|
qDebug("Avisynth 32-Bit edition *not* found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile *avsPath64;
|
||||||
|
if(checkAvisynth(sysinfo, avsPath64, true))
|
||||||
|
{
|
||||||
|
m_avsDllPath[1].reset(avsPath64);
|
||||||
|
success |= AVISYNTH_X64;
|
||||||
|
qDebug("Avisynth 64-Bit edition found!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug("Avisynth 64-Bit edition *not* found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AvisynthCheckThread::checkAvisynth(const SysinfoModel *const sysinfo, QFile *&path, const bool &x64)
|
||||||
|
{
|
||||||
|
qDebug("Avisynth %s-Bit support is being tested.", x64 ? "64" : "32");
|
||||||
|
|
||||||
|
QProcess process;
|
||||||
|
QStringList output;
|
||||||
|
|
||||||
|
//Setup process object
|
||||||
|
process.setWorkingDirectory(QDir::tempPath());
|
||||||
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
process.setReadChannel(QProcess::StandardOutput);
|
||||||
|
|
||||||
|
//Try to start VSPIPE.EXE
|
||||||
|
process.start(CHK_BINARY(sysinfo, x64), QStringList());
|
||||||
|
if(!process.waitForStarted())
|
||||||
|
{
|
||||||
|
qWarning("Failed to launch AVS_CHECK.EXE -> %s", process.errorString().toUtf8().constData());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Wait for process to finish
|
||||||
|
while(process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
if(process.waitForReadyRead(12000))
|
||||||
{
|
{
|
||||||
qDebug("avs_create_script_environment_ptr(AVS_INTERFACE_25)");
|
while(process.canReadLine())
|
||||||
AVS_ScriptEnvironment* avs_env = avs_create_script_environment_ptr(AVS_INTERFACE_25);
|
|
||||||
if(avs_env != NULL)
|
|
||||||
{
|
{
|
||||||
qDebug("avs_function_exists_ptr(avs_env, \"VersionNumber\")");
|
output << QString::fromUtf8(process.readLine()).simplified();
|
||||||
if(avs_function_exists_ptr(avs_env, "VersionNumber"))
|
|
||||||
{
|
|
||||||
qDebug("avs_invoke_ptr(avs_env, \"VersionNumber\", avs_new_value_array(NULL, 0), NULL)");
|
|
||||||
AVS_Value avs_version = avs_invoke_ptr(avs_env, "VersionNumber", avs_new_value_array(NULL, 0), NULL);
|
|
||||||
if(!avs_is_error(avs_version))
|
|
||||||
{
|
|
||||||
if(avs_is_float(avs_version))
|
|
||||||
{
|
|
||||||
qDebug("Avisynth version: v%.2f", avs_as_float(avs_version));
|
|
||||||
*version_number = avs_as_float(avs_version);
|
|
||||||
if(avs_release_value_ptr) avs_release_value_ptr(avs_version);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qWarning("Failed to determine version number, Avisynth didn't return a float!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qWarning("Failed to determine version number, Avisynth returned an error!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qWarning("The 'VersionNumber' function does not exist in your Avisynth DLL, can't determine version!");
|
|
||||||
}
|
|
||||||
if(avs_delete_script_environment_ptr != NULL)
|
|
||||||
{
|
|
||||||
avs_delete_script_environment_ptr(avs_env);
|
|
||||||
avs_env = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
continue;
|
||||||
|
}
|
||||||
|
if(process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
qWarning("AVS_CHECK.EXE process encountered a deadlock -> aborting now!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Make sure VSPIPE.EXE has terminated!
|
||||||
|
process.waitForFinished(2500);
|
||||||
|
if(process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
qWarning("AVS_CHECK.EXE process still running, going to kill it!");
|
||||||
|
process.kill();
|
||||||
|
process.waitForFinished(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Read pending lines
|
||||||
|
while(process.canReadLine())
|
||||||
|
{
|
||||||
|
output << QString::fromUtf8(process.readLine()).simplified();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check exit code
|
||||||
|
if(process.exitCode() != 0)
|
||||||
|
{
|
||||||
|
qWarning("AVS_CHECK.EXE failed with code 0x%08X -> disable Avisynth support!", process.exitCode());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Init regular expressions
|
||||||
|
QRegExp avsLogo("Avisynth\\s+Checker\\s+(x86|x64)");
|
||||||
|
QRegExp avsPath("Avisynth_DLLPath=(.+)");
|
||||||
|
QRegExp avsVers("Avisynth_Version=(\\d+)\\.(\\d+)");
|
||||||
|
|
||||||
|
//Check for version info
|
||||||
|
bool avisynthLogo = false;
|
||||||
|
quint32 avisynthVersion[2] = { 0, 0 };
|
||||||
|
QString avisynthPath;
|
||||||
|
for(QStringList::ConstIterator iter = output.constBegin(); iter != output.constEnd(); iter++)
|
||||||
|
{
|
||||||
|
if(avisynthLogo)
|
||||||
|
{
|
||||||
|
if(avsPath.indexIn(*iter) >= 0)
|
||||||
{
|
{
|
||||||
qWarning("The Avisynth DLL failed to create the script environment!");
|
avisynthPath = avsPath.cap(1).trimmed();
|
||||||
|
}
|
||||||
|
else if(avsVers.indexIn(*iter) >= 0)
|
||||||
|
{
|
||||||
|
quint32 temp[2];
|
||||||
|
if(MUtils::regexp_parse_uint32(avsVers, temp, 2))
|
||||||
|
{
|
||||||
|
avisynthVersion[0] = temp[0];
|
||||||
|
avisynthVersion[1] = temp[1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qWarning("It seems the Avisynth DLL is missing required API functions!");
|
if(avsLogo.lastIndexIn(*iter) >= 0)
|
||||||
|
{
|
||||||
|
avisynthLogo = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
//Minimum required version found?
|
||||||
|
if((avisynthVersion[0] >= 2) && (avisynthVersion[1] >= 50) && (!avisynthPath.isEmpty()))
|
||||||
{
|
{
|
||||||
qWarning("Failed to load Avisynth.dll library!");
|
Wow64RedirectionDisabler disableWow64Redir;
|
||||||
}
|
path = new QFile(avisynthPath);
|
||||||
|
if(!path->open(QIODevice::ReadOnly))
|
||||||
|
{
|
||||||
|
MUTILS_DELETE(path);
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
qDebug("Avisynth was detected successfully (current version: %u.%02u).", avisynthVersion[0], avisynthVersion[1]);
|
||||||
|
qDebug("Avisynth DLL path: %s", MUTILS_UTF8(avisynthPath));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Failed to determine version
|
||||||
|
qWarning("Failed to determine Avisynth version!");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -25,38 +25,49 @@
|
|||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
|
||||||
class QLibrary;
|
class QLibrary;
|
||||||
|
class SysinfoModel;
|
||||||
|
class QFile;
|
||||||
|
|
||||||
class AvisynthCheckThread : public QThread
|
class AvisynthCheckThread : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static int detect(volatile double *version);
|
static bool detect(SysinfoModel *sysinfo);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AvisynthCheckThread(void);
|
AvisynthCheckThread(const SysinfoModel *const sysinfo);
|
||||||
~AvisynthCheckThread(void);
|
~AvisynthCheckThread(void);
|
||||||
|
|
||||||
bool getSuccess(void) { return m_success; }
|
int getSuccess(void) { return m_success; }
|
||||||
bool getException(void) { return m_exception; }
|
bool getException(void) { return m_exception; }
|
||||||
double getVersion(void) { return m_version; }
|
|
||||||
|
typedef enum _AvisynthFlags
|
||||||
|
{
|
||||||
|
AVISYNTH_X86 = 0x1,
|
||||||
|
AVISYNTH_X64 = 0x2
|
||||||
|
}
|
||||||
|
AvisynthFlags;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void start(Priority priority = InheritPriority) { QThread::start(priority); }
|
void start(Priority priority = InheritPriority) { QThread::start(priority); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
volatile bool m_exception;
|
volatile bool m_exception;
|
||||||
volatile bool m_success;
|
int m_success;
|
||||||
volatile double m_version;
|
const SysinfoModel *const m_sysinfo;
|
||||||
|
|
||||||
static QMutex m_avsLock;
|
static QMutex m_avsLock;
|
||||||
static QScopedPointer<QLibrary> m_avsLib;
|
static QScopedPointer<QFile> m_avsDllPath[2];
|
||||||
|
|
||||||
//Entry point
|
//Entry point
|
||||||
virtual void run(void);
|
virtual void run(void);
|
||||||
|
|
||||||
//Functions
|
//Functions
|
||||||
static bool detectAvisynthVersion1(volatile double *version_number, volatile bool *exception);
|
static void detectAvisynthVersion1(int &success, const SysinfoModel *const sysinfo, volatile bool *exception);
|
||||||
static bool detectAvisynthVersion2(volatile double *version_number, volatile bool *exception);
|
static void detectAvisynthVersion2(int &success, const SysinfoModel *const sysinfo, volatile bool *exception);
|
||||||
static bool detectAvisynthVersion3(volatile double *version_number);
|
static void detectAvisynthVersion3(int &success, const SysinfoModel *const sysinfo);
|
||||||
|
|
||||||
|
//Internal functions
|
||||||
|
static bool checkAvisynth(const SysinfoModel *const sysinfo, QFile *&path, const bool &x64);
|
||||||
};
|
};
|
||||||
|
@ -35,15 +35,18 @@
|
|||||||
|
|
||||||
//Internal
|
//Internal
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "model_sysinfo.h"
|
||||||
|
|
||||||
//CRT
|
//CRT
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
//Static
|
||||||
QMutex VapourSynthCheckThread::m_vpsLock;
|
QMutex VapourSynthCheckThread::m_vpsLock;
|
||||||
QScopedPointer<QFile> VapourSynthCheckThread::m_vpsExePath[2];
|
QScopedPointer<QFile> VapourSynthCheckThread::m_vpsExePath[2];
|
||||||
QScopedPointer<QFile> VapourSynthCheckThread::m_vpsDllPath[2];
|
QScopedPointer<QFile> VapourSynthCheckThread::m_vpsDllPath[2];
|
||||||
|
|
||||||
#define VALID_DIR(STR) ((!(STR).isEmpty()) && QDir((STR)).exists())
|
#define VALID_DIR(STR) ((!(STR).isEmpty()) && QDir((STR)).exists())
|
||||||
|
#define BOOLIFY(X) ((X) ? '1' : '0')
|
||||||
|
|
||||||
static inline QString &cleanDir(QString &path)
|
static inline QString &cleanDir(QString &path)
|
||||||
{
|
{
|
||||||
@ -62,10 +65,11 @@ static inline QString &cleanDir(QString &path)
|
|||||||
// External API
|
// External API
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
|
|
||||||
int VapourSynthCheckThread::detect(QString &path, VapourSynthType &type)
|
bool VapourSynthCheckThread::detect(SysinfoModel *sysinfo)
|
||||||
{
|
{
|
||||||
path.clear();
|
sysinfo->clearVapourSynth();
|
||||||
type &= 0;
|
sysinfo->clearVPSPath();
|
||||||
|
|
||||||
QMutexLocker lock(&m_vpsLock);
|
QMutexLocker lock(&m_vpsLock);
|
||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
@ -90,25 +94,28 @@ int VapourSynthCheckThread::detect(QString &path, VapourSynthType &type)
|
|||||||
qWarning("VapourSynth thread encountered timeout -> probably deadlock!");
|
qWarning("VapourSynth thread encountered timeout -> probably deadlock!");
|
||||||
thread.terminate();
|
thread.terminate();
|
||||||
thread.wait();
|
thread.wait();
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thread.getException())
|
if(thread.getException())
|
||||||
{
|
{
|
||||||
qWarning("VapourSynth thread encountered an exception !!!");
|
qWarning("VapourSynth thread encountered an exception !!!");
|
||||||
return -1;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(!!thread.getSuccess())
|
|
||||||
{
|
|
||||||
type |= thread.getSuccess();
|
|
||||||
path = thread.getPath();
|
|
||||||
qDebug("VapourSynth check completed successfully.");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qWarning("VapourSynth thread failed to detect installation!");
|
if(thread.getSuccess())
|
||||||
return 0;
|
{
|
||||||
|
sysinfo->setVapourSynth(SysinfoModel::VapourSynth_X86, thread.getSuccess() & VAPOURSYNTH_X86);
|
||||||
|
sysinfo->setVapourSynth(SysinfoModel::VapourSynth_X64, thread.getSuccess() & VAPOURSYNTH_X64);
|
||||||
|
sysinfo->setVPSPath(thread.getPath());
|
||||||
|
qDebug("VapourSynth support is officially enabled now! [x86=%c, x64=%c]", BOOLIFY(sysinfo->getVapourSynth(SysinfoModel::VapourSynth_X86)), BOOLIFY(sysinfo->getVapourSynth(SysinfoModel::VapourSynth_X64)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qWarning("VapourSynth could not be found -> VapourSynth support disabled!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
@ -135,7 +142,7 @@ void VapourSynthCheckThread::run(void)
|
|||||||
detectVapourSynthPath1(m_success, m_vpsPath, &m_exception);
|
detectVapourSynthPath1(m_success, m_vpsPath, &m_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VapourSynthCheckThread::detectVapourSynthPath1(VapourSynthType &success, QString &path, volatile bool *exception)
|
void VapourSynthCheckThread::detectVapourSynthPath1(int &success, QString &path, volatile bool *exception)
|
||||||
{
|
{
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
@ -148,7 +155,7 @@ void VapourSynthCheckThread::detectVapourSynthPath1(VapourSynthType &success, QS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VapourSynthCheckThread::detectVapourSynthPath2(VapourSynthType &success, QString &path, volatile bool *exception)
|
void VapourSynthCheckThread::detectVapourSynthPath2(int &success, QString &path, volatile bool *exception)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -161,7 +168,7 @@ void VapourSynthCheckThread::detectVapourSynthPath2(VapourSynthType &success, QS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VapourSynthCheckThread::detectVapourSynthPath3(VapourSynthType &success, QString &path)
|
void VapourSynthCheckThread::detectVapourSynthPath3(int &success, QString &path)
|
||||||
{
|
{
|
||||||
success &= 0;
|
success &= 0;
|
||||||
path.clear();
|
path.clear();
|
||||||
|
@ -21,41 +21,42 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
//Qt
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
|
||||||
class QLibrary;
|
class QLibrary;
|
||||||
class QFile;
|
class QFile;
|
||||||
|
class SysinfoModel;
|
||||||
|
|
||||||
class VapourSynthCheckThread : public QThread
|
class VapourSynthCheckThread : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef enum _VapourSynthType_t
|
static bool detect(SysinfoModel *sysinfo);
|
||||||
{
|
|
||||||
VAPOURSYNTH_X86 = 0x1,
|
|
||||||
VAPOURSYNTH_X64 = 0x2
|
|
||||||
}
|
|
||||||
VapourSynthType_t;
|
|
||||||
|
|
||||||
typedef QFlags<VapourSynthType_t> VapourSynthType;
|
|
||||||
static int detect(QString &path, VapourSynthType &type);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VapourSynthCheckThread(void);
|
VapourSynthCheckThread(void);
|
||||||
~VapourSynthCheckThread(void);
|
~VapourSynthCheckThread(void);
|
||||||
|
|
||||||
bool getException(void) { return m_exception; }
|
bool getException(void) { return m_exception; }
|
||||||
VapourSynthType &getSuccess(void) { return m_success; }
|
int getSuccess(void) { return m_success; }
|
||||||
QString getPath(void) { return m_vpsPath; }
|
QString getPath(void) { return m_vpsPath; }
|
||||||
|
|
||||||
|
typedef enum _VapourSynthFlags
|
||||||
|
{
|
||||||
|
VAPOURSYNTH_X86 = 0x1,
|
||||||
|
VAPOURSYNTH_X64 = 0x2
|
||||||
|
}
|
||||||
|
VapourSynthFlags;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void start(Priority priority = InheritPriority) { QThread::start(priority); }
|
void start(Priority priority = InheritPriority) { QThread::start(priority); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
volatile bool m_exception;
|
volatile bool m_exception;
|
||||||
VapourSynthType m_success;
|
int m_success;
|
||||||
QString m_vpsPath;
|
QString m_vpsPath;
|
||||||
|
|
||||||
static QMutex m_vpsLock;
|
static QMutex m_vpsLock;
|
||||||
@ -66,9 +67,9 @@ private:
|
|||||||
virtual void run(void);
|
virtual void run(void);
|
||||||
|
|
||||||
//Functions
|
//Functions
|
||||||
static void detectVapourSynthPath1(VapourSynthType &success, QString &path, volatile bool *exception);
|
static void detectVapourSynthPath1(int &success, QString &path, volatile bool *exception);
|
||||||
static void detectVapourSynthPath2(VapourSynthType &success, QString &path, volatile bool *exception);
|
static void detectVapourSynthPath2(int &success, QString &path, volatile bool *exception);
|
||||||
static void detectVapourSynthPath3(VapourSynthType &success, QString &path);
|
static void detectVapourSynthPath3(int &success, QString &path);
|
||||||
|
|
||||||
//Internal functions
|
//Internal functions
|
||||||
static bool isVapourSynthComplete(const QString &vsCorePath, QFile *&vpsExeFile, QFile *&vpsDllFile);
|
static bool isVapourSynthComplete(const QString &vsCorePath, QFile *&vpsExeFile, QFile *&vpsDllFile);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
#define VER_X264_MAJOR 2
|
#define VER_X264_MAJOR 2
|
||||||
#define VER_X264_MINOR 5
|
#define VER_X264_MINOR 5
|
||||||
#define VER_X264_PATCH 0
|
#define VER_X264_PATCH 0
|
||||||
#define VER_X264_BUILD 925
|
#define VER_X264_BUILD 932
|
||||||
|
|
||||||
#define VER_X264_PORTABLE_EDITION (0)
|
#define VER_X264_PORTABLE_EDITION (0)
|
||||||
|
|
||||||
|
@ -781,6 +781,7 @@ void MainWindow::init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
binFiles << AVS_BINARY(m_sysinfo.data(), arch == OptionsModel::EncArch_x64);
|
binFiles << AVS_BINARY(m_sysinfo.data(), arch == OptionsModel::EncArch_x64);
|
||||||
|
binFiles << CHK_BINARY(m_sysinfo.data(), arch == OptionsModel::EncArch_x64);
|
||||||
}
|
}
|
||||||
for(size_t i = 0; UpdaterDialog::BINARIES[i].name; i++)
|
for(size_t i = 0; UpdaterDialog::BINARIES[i].name; i++)
|
||||||
{
|
{
|
||||||
@ -889,9 +890,7 @@ void MainWindow::init(void)
|
|||||||
if(!arguments.contains(CLI_PARAM_SKIP_AVS_CHECK))
|
if(!arguments.contains(CLI_PARAM_SKIP_AVS_CHECK))
|
||||||
{
|
{
|
||||||
qDebug("[Check for Avisynth support]");
|
qDebug("[Check for Avisynth support]");
|
||||||
volatile double avisynthVersion = 0.0;
|
if(!AvisynthCheckThread::detect(m_sysinfo.data()))
|
||||||
const int result = AvisynthCheckThread::detect(&avisynthVersion);
|
|
||||||
if(result < 0)
|
|
||||||
{
|
{
|
||||||
QString text = tr("A critical error was encountered while checking your Avisynth version.").append("<br>");
|
QString text = tr("A critical error was encountered while checking your Avisynth version.").append("<br>");
|
||||||
text += tr("This is most likely caused by an erroneous Avisynth Plugin, please try to clean your Plugins folder!").append("<br>");
|
text += tr("This is most likely caused by an erroneous Avisynth Plugin, please try to clean your Plugins folder!").append("<br>");
|
||||||
@ -899,25 +898,15 @@ void MainWindow::init(void)
|
|||||||
int val = QMessageBox::critical(this, tr("Avisynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "−"), tr("Quit"), tr("Ignore"));
|
int val = QMessageBox::critical(this, tr("Avisynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "−"), tr("Quit"), tr("Ignore"));
|
||||||
if(val != 1) INIT_ERROR_EXIT();
|
if(val != 1) INIT_ERROR_EXIT();
|
||||||
}
|
}
|
||||||
if(result && (avisynthVersion >= 2.5))
|
else if((!m_sysinfo->hasAvisynth()) && (!m_preferences->getDisableWarnings()))
|
||||||
{
|
{
|
||||||
qDebug("Avisynth support is officially enabled now!");
|
QString text = tr("It appears that Avisynth is <b>not</b> currently installed on your computer.<br>Therefore Avisynth (.avs) input will <b>not</b> be working at all!").append("<br><br>");
|
||||||
m_sysinfo->setAvisynth(SysinfoModel::Avisynth_X86, true);
|
text += tr("Please download and install Avisynth:").append("<br>").append(LINK(avs_dl_url));
|
||||||
m_sysinfo->setAvisynth(SysinfoModel::Avisynth_X64, true);
|
int val = QMessageBox::warning(this, tr("Avisynth Missing"), QString("<nobr>%1</nobr>").arg(text).replace("-", "−"), tr("Close"), tr("Disable this Warning"));
|
||||||
}
|
if(val == 1)
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!m_preferences->getDisableWarnings())
|
|
||||||
{
|
{
|
||||||
QString text = tr("It appears that Avisynth is <b>not</b> currently installed on your computer.<br>Therefore Avisynth (.avs) input will <b>not</b> be working at all!").append("<br><br>");
|
m_preferences->setDisableWarnings(true);
|
||||||
text += tr("Please download and install Avisynth:").append("<br>").append(LINK(avs_dl_url));
|
PreferencesModel::savePreferences(m_preferences.data());
|
||||||
int val = QMessageBox::warning(this, tr("Avisynth Missing"), QString("<nobr>%1</nobr>").arg(text).replace("-", "−"), tr("Close"), tr("Disable this Warning"));
|
|
||||||
if(val == 1)
|
|
||||||
{
|
|
||||||
m_preferences->setDisableWarnings(true);
|
|
||||||
PreferencesModel::savePreferences(m_preferences.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qDebug(" ");
|
qDebug(" ");
|
||||||
@ -930,10 +919,7 @@ void MainWindow::init(void)
|
|||||||
if(!arguments.contains(CLI_PARAM_SKIP_VPS_CHECK))
|
if(!arguments.contains(CLI_PARAM_SKIP_VPS_CHECK))
|
||||||
{
|
{
|
||||||
qDebug("[Check for VapourSynth support]");
|
qDebug("[Check for VapourSynth support]");
|
||||||
VapourSynthCheckThread::VapourSynthType vapoursynthType;
|
if(!VapourSynthCheckThread::detect(m_sysinfo.data()))
|
||||||
QString vapoursynthPath;
|
|
||||||
const int result = VapourSynthCheckThread::detect(vapoursynthPath, vapoursynthType);
|
|
||||||
if(result < 0)
|
|
||||||
{
|
{
|
||||||
QString text = tr("A critical error was encountered while checking your VapourSynth installation.").append("<br>");
|
QString text = tr("A critical error was encountered while checking your VapourSynth installation.").append("<br>");
|
||||||
text += tr("This is most likely caused by an erroneous VapourSynth Plugin, please try to clean your Filters folder!").append("<br>");
|
text += tr("This is most likely caused by an erroneous VapourSynth Plugin, please try to clean your Filters folder!").append("<br>");
|
||||||
@ -941,26 +927,16 @@ void MainWindow::init(void)
|
|||||||
const int val = QMessageBox::critical(this, tr("VapourSynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "−"), tr("Quit"), tr("Ignore"));
|
const int val = QMessageBox::critical(this, tr("VapourSynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "−"), tr("Quit"), tr("Ignore"));
|
||||||
if(val != 1) INIT_ERROR_EXIT();
|
if(val != 1) INIT_ERROR_EXIT();
|
||||||
}
|
}
|
||||||
if(result && (!!vapoursynthType) && (!vapoursynthPath.isEmpty()))
|
else if((!m_sysinfo->hasVapourSynth()) && (!m_preferences->getDisableWarnings()))
|
||||||
{
|
{
|
||||||
qDebug("VapourSynth support is officially enabled now!");
|
QString text = tr("It appears that VapourSynth is <b>not</b> currently installed on your computer.<br>Therefore VapourSynth (.vpy) input will <b>not</b> be working at all!").append("<br><br>");
|
||||||
m_sysinfo->setVapourSynth(SysinfoModel::VapourSynth_X86, (vapoursynthType.testFlag(VapourSynthCheckThread::VAPOURSYNTH_X86)));
|
text += tr("Please download and install VapourSynth (<b>r%1</b> or later) for Windows:").arg(QString::number(vsynth_rev)).append("<br>").append(LINK(vsynth_url)).append("<br><br>");
|
||||||
m_sysinfo->setVapourSynth(SysinfoModel::VapourSynth_X64, (vapoursynthType.testFlag(VapourSynthCheckThread::VAPOURSYNTH_X64)));
|
text += tr("Note that Python v3.4 is a prerequisite for installing VapourSynth:").append("<br>").append(LINK(python_url)).append("<br>");
|
||||||
m_sysinfo->setVPSPath(vapoursynthPath);
|
const int val = QMessageBox::warning(this, tr("VapourSynth Missing"), QString("<nobr>%1</nobr>").arg(text).replace("-", "−"), tr("Close"), tr("Disable this Warning"));
|
||||||
}
|
if(val == 1)
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!m_preferences->getDisableWarnings())
|
|
||||||
{
|
{
|
||||||
QString text = tr("It appears that VapourSynth is <b>not</b> currently installed on your computer.<br>Therefore VapourSynth (.vpy) input will <b>not</b> be working at all!").append("<br><br>");
|
m_preferences->setDisableWarnings(true);
|
||||||
text += tr("Please download and install VapourSynth (<b>r%1</b> or later) for Windows:").arg(QString::number(vsynth_rev)).append("<br>").append(LINK(vsynth_url)).append("<br><br>");
|
PreferencesModel::savePreferences(m_preferences.data());
|
||||||
text += tr("Note that Python v3.4 is a prerequisite for installing VapourSynth:").append("<br>").append(LINK(python_url)).append("<br>");
|
|
||||||
const int val = QMessageBox::warning(this, tr("VapourSynth Missing"), QString("<nobr>%1</nobr>").arg(text).replace("-", "−"), tr("Close"), tr("Disable this Warning"));
|
|
||||||
if(val == 1)
|
|
||||||
{
|
|
||||||
m_preferences->setDisableWarnings(true);
|
|
||||||
PreferencesModel::savePreferences(m_preferences.data());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qDebug(" ");
|
qDebug(" ");
|
||||||
|
Loading…
Reference in New Issue
Block a user