Improved VapourSynth detection code.

This commit is contained in:
LoRd_MuldeR 2015-02-27 19:05:18 +01:00
parent 27e79e5e4e
commit 0c6c00202e
11 changed files with 133 additions and 138 deletions

View File

@ -100,10 +100,17 @@ 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)
{ {
return QString("%1/vspipe.exe").arg(sysinfo->getVPSPath()); return QString("%1/core%2/vspipe.exe").arg(sysinfo->getVPSPath(), (x64 ? "64" : "32"));
} }
QString VPS_BINARY(const SysinfoModel *sysinfo, const PreferencesModel *preferences) QString VPS_BINARY(const SysinfoModel *sysinfo, const PreferencesModel *preferences)
{ {
return VPS_BINARY(sysinfo, sysinfo->hasX64Support()); if(sysinfo->hasVPS32Support() && sysinfo->hasVPS64Support() && sysinfo->hasX64Support())
{
return VPS_BINARY(sysinfo, preferences->getUseAvisyth64Bit());
}
else
{
return VPS_BINARY(sysinfo, (sysinfo->hasVPS64Support() && sysinfo->hasX64Support()));
}
} }

View File

@ -66,11 +66,12 @@ class SysinfoModel
public: public:
SysinfoModel(void) { m_flags = 0; } SysinfoModel(void) { m_flags = 0; }
SYSINFO_MAKE_FLAG(X64, 0x00000001) SYSINFO_MAKE_FLAG(X64, 0x00000001)
SYSINFO_MAKE_FLAG(MMX, 0x00000002) SYSINFO_MAKE_FLAG(MMX, 0x00000002)
SYSINFO_MAKE_FLAG(SSE, 0x00000004) SYSINFO_MAKE_FLAG(SSE, 0x00000004)
SYSINFO_MAKE_FLAG(AVS, 0x00000008) SYSINFO_MAKE_FLAG(AVS, 0x00000008)
SYSINFO_MAKE_FLAG(VPS, 0x00000010) SYSINFO_MAKE_FLAG(VPS32, 0x00000010)
SYSINFO_MAKE_FLAG(VPS64, 0x00000020)
SYSINFO_MAKE_PATH(VPS) SYSINFO_MAKE_PATH(VPS)
SYSINFO_MAKE_PATH(App) SYSINFO_MAKE_PATH(App)

View File

@ -59,7 +59,8 @@ const QString &VapoursynthSource::getName(void)
bool VapoursynthSource::isSourceAvailable() bool VapoursynthSource::isSourceAvailable()
{ {
if(!(m_sysinfo->hasVPSSupport() && (!m_sysinfo->getVPSPath().isEmpty()) && QFileInfo(VPS_BINARY(m_sysinfo, m_preferences)).isFile())) bool vpsSupport = m_sysinfo->hasVPS32Support() || m_sysinfo->hasVPS32Support();
if(!(vpsSupport && (!m_sysinfo->getVPSPath().isEmpty()) && QFileInfo(VPS_BINARY(m_sysinfo, m_preferences)).isFile()))
{ {
log(tr("\nVPY INPUT REQUIRES VAPOURSYNTH, BUT IT IS *NOT* AVAILABLE !!!")); log(tr("\nVPY INPUT REQUIRES VAPOURSYNTH, BUT IT IS *NOT* AVAILABLE !!!"));
return false; return false;

View File

@ -35,7 +35,7 @@
#include <MUtils/Global.h> #include <MUtils/Global.h>
QMutex AvisynthCheckThread::m_avsLock; QMutex AvisynthCheckThread::m_avsLock;
QLibrary *AvisynthCheckThread::m_avsLib = NULL; QScopedPointer<QLibrary> AvisynthCheckThread::m_avsLib;
//------------------------------------- //-------------------------------------
// External API // External API
@ -88,21 +88,6 @@ int AvisynthCheckThread::detect(volatile double *version)
return 0; return 0;
} }
void AvisynthCheckThread::unload(void)
{
QMutexLocker lock(&m_avsLock);
if(m_avsLib)
{
if(m_avsLib->isLoaded())
{
m_avsLib->unload();
}
}
MUTILS_DELETE(m_avsLib);
}
//------------------------------------- //-------------------------------------
// Thread class // Thread class
//------------------------------------- //-------------------------------------
@ -157,11 +142,7 @@ bool AvisynthCheckThread::detectAvisynthVersion3(volatile double *version_number
bool success = false; bool success = false;
*version_number = 0.0; *version_number = 0.0;
if(!m_avsLib) m_avsLib.reset(new QLibrary("avisynth.dll"));
{
m_avsLib = new QLibrary("avisynth.dll");
}
if(m_avsLib->isLoaded() || m_avsLib->load()) if(m_avsLib->isLoaded() || m_avsLib->load())
{ {
avs_create_script_environment_func avs_create_script_environment_ptr = (avs_create_script_environment_func) m_avsLib->resolve("avs_create_script_environment"); avs_create_script_environment_func avs_create_script_environment_ptr = (avs_create_script_environment_func) m_avsLib->resolve("avs_create_script_environment");

View File

@ -32,7 +32,6 @@ class AvisynthCheckThread : public QThread
public: public:
static int detect(volatile double *version); static int detect(volatile double *version);
static void unload(void);
protected: protected:
AvisynthCheckThread(void); AvisynthCheckThread(void);
@ -51,7 +50,7 @@ private:
volatile double m_version; volatile double m_version;
static QMutex m_avsLock; static QMutex m_avsLock;
static QLibrary *m_avsLib; static QScopedPointer<QLibrary> m_avsLib;
//Entry point //Entry point
virtual void run(void); virtual void run(void);

View File

@ -143,7 +143,7 @@ EncodeThread::EncodeThread(const QString &sourceFileName, const QString &outputF
} }
break; break;
case MediaInfo::FILETYPE_VAPOURSYNTH: case MediaInfo::FILETYPE_VAPOURSYNTH:
if(m_sysinfo->hasVPSSupport()) if(m_sysinfo->hasVPS32Support() || m_sysinfo->hasVPS64Support())
{ {
m_pipedSource = new VapoursynthSource(m_jobObject, m_options, m_sysinfo, m_preferences, m_status, &m_abort, &m_pause, &m_semaphorePaused, m_sourceFileName); m_pipedSource = new VapoursynthSource(m_jobObject, m_options, m_sysinfo, m_preferences, m_status, &m_abort, &m_pause, &m_semaphorePaused, m_sourceFileName);
} }
@ -256,7 +256,7 @@ void EncodeThread::encode(void)
log(tr("\n--- SYSTEMINFO ---\n")); log(tr("\n--- SYSTEMINFO ---\n"));
log(tr("Binary Path : %1").arg(QDir::toNativeSeparators(m_sysinfo->getAppPath()))); log(tr("Binary Path : %1").arg(QDir::toNativeSeparators(m_sysinfo->getAppPath())));
log(tr("Avisynth : %1").arg(m_sysinfo->hasAVSSupport() ? tr("Yes") : tr("No"))); log(tr("Avisynth : %1").arg(m_sysinfo->hasAVSSupport() ? tr("Yes") : tr("No")));
log(tr("VapourSynth : %1").arg(m_sysinfo->hasVPSSupport() ? QDir::toNativeSeparators(m_sysinfo->getVPSPath()) : tr("N/A"))); log(tr("VapourSynth : %1").arg((m_sysinfo->hasVPS32Support() || m_sysinfo->hasVPS64Support()) ? tr("Yes") : tr("No")));
//Print encoder settings //Print encoder settings
log(tr("\n--- SETTINGS ---\n")); log(tr("\n--- SETTINGS ---\n"));

View File

@ -33,12 +33,15 @@
#include <QDir> #include <QDir>
#include <QProcess> #include <QProcess>
//Internal
#include "global.h" #include "global.h"
//CRT
#include <cassert>
QMutex VapourSynthCheckThread::m_vpsLock; QMutex VapourSynthCheckThread::m_vpsLock;
QFile *VapourSynthCheckThread::m_vpsExePath = NULL; QScopedPointer<QFile> VapourSynthCheckThread::m_vpsExePath[2];
QFile *VapourSynthCheckThread::m_vpsDllPath = NULL; QScopedPointer<QFile> VapourSynthCheckThread::m_vpsDllPath[2];
QLibrary *VapourSynthCheckThread::m_vpsLib = NULL;
#define VALID_DIR(STR) ((!(STR).isEmpty()) && QDir((STR)).exists()) #define VALID_DIR(STR) ((!(STR).isEmpty()) && QDir((STR)).exists())
@ -59,9 +62,10 @@ static inline QString &cleanDir(QString &path)
// External API // External API
//------------------------------------- //-------------------------------------
int VapourSynthCheckThread::detect(QString &path) int VapourSynthCheckThread::detect(QString &path, int &vapourSynthType)
{ {
path.clear(); path.clear();
vapourSynthType = VAPOURSYNTH_OFF;
QMutexLocker lock(&m_vpsLock); QMutexLocker lock(&m_vpsLock);
QEventLoop loop; QEventLoop loop;
@ -95,8 +99,9 @@ int VapourSynthCheckThread::detect(QString &path)
return -1; return -1;
} }
if(thread.getSuccess()) if(thread.getSuccess() & (VAPOURSYNTH_X86 | VAPOURSYNTH_X64))
{ {
vapourSynthType = thread.getSuccess();
path = thread.getPath(); path = thread.getPath();
qDebug("VapourSynth check completed successfully."); qDebug("VapourSynth check completed successfully.");
return 1; return 1;
@ -106,46 +111,13 @@ int VapourSynthCheckThread::detect(QString &path)
return 0; return 0;
} }
void VapourSynthCheckThread::unload(void)
{
QMutexLocker lock(&m_vpsLock);
if(m_vpsLib)
{
if(m_vpsLib->isLoaded())
{
m_vpsLib->unload();
}
}
if(m_vpsExePath)
{
if (m_vpsExePath->isOpen())
{
m_vpsExePath->close();
}
}
if(m_vpsDllPath)
{
if(m_vpsDllPath->isOpen())
{
m_vpsDllPath->close();
}
}
MUTILS_DELETE(m_vpsExePath);
MUTILS_DELETE(m_vpsDllPath);
MUTILS_DELETE(m_vpsLib);
}
//------------------------------------- //-------------------------------------
// Thread class // Thread class
//------------------------------------- //-------------------------------------
VapourSynthCheckThread::VapourSynthCheckThread(void) VapourSynthCheckThread::VapourSynthCheckThread(void)
{ {
m_success = false; m_success = VAPOURSYNTH_OFF;
m_exception = false; m_exception = false;
m_vpsPath.clear(); m_vpsPath.clear();
} }
@ -156,11 +128,13 @@ VapourSynthCheckThread::~VapourSynthCheckThread(void)
void VapourSynthCheckThread::run(void) void VapourSynthCheckThread::run(void)
{ {
m_exception = m_success = false; m_success = VAPOURSYNTH_OFF;
m_exception = false;
m_success = detectVapourSynthPath1(m_vpsPath, &m_exception); m_success = detectVapourSynthPath1(m_vpsPath, &m_exception);
} }
bool VapourSynthCheckThread::detectVapourSynthPath1(QString &path, volatile bool *exception) int VapourSynthCheckThread::detectVapourSynthPath1(QString &path, volatile bool *exception)
{ {
__try __try
{ {
@ -174,7 +148,7 @@ bool VapourSynthCheckThread::detectVapourSynthPath1(QString &path, volatile bool
} }
} }
bool VapourSynthCheckThread::detectVapourSynthPath2(QString &path, volatile bool *exception) int VapourSynthCheckThread::detectVapourSynthPath2(QString &path, volatile bool *exception)
{ {
try try
{ {
@ -188,11 +162,9 @@ bool VapourSynthCheckThread::detectVapourSynthPath2(QString &path, volatile bool
} }
} }
bool VapourSynthCheckThread::detectVapourSynthPath3(QString &path) int VapourSynthCheckThread::detectVapourSynthPath3(QString &path)
{ {
bool success = false; int success = VAPOURSYNTH_OFF;
MUTILS_DELETE(m_vpsExePath);
MUTILS_DELETE(m_vpsDllPath);
path.clear(); path.clear();
static const char *VPS_REG_KEYS[] = static const char *VPS_REG_KEYS[] =
@ -225,48 +197,51 @@ bool VapourSynthCheckThread::detectVapourSynthPath3(QString &path)
if(!VALID_DIR(vapoursynthPath)) if(!VALID_DIR(vapoursynthPath))
{ {
qWarning("VapourSynth install path not found -> disable VapouSynth support!"); qWarning("VapourSynth install path not found -> disable VapouSynth support!");
vapoursynthPath.clear(); return VAPOURSYNTH_OFF;
} }
//Make sure that 'vapoursynth.dll' and 'vspipe.exe' are available qDebug("VapourSynth Dir: %s", vapoursynthPath.toUtf8().constData());
bool vapoursynthComplete = false;
if(!vapoursynthPath.isEmpty()) //Look for 32-Bit edition of VapourSynth first
QFile *vpsExeFile32, *vpsDllFile32;
if(isVapourSynthComplete(QString("%1/core32").arg(vapoursynthPath), vpsExeFile32, vpsDllFile32))
{ {
static const char *CORE_PATH[3] = { "core32", "core64", "core" }; if(vpsExeFile32 && checkVapourSynth(vpsExeFile32->fileName()))
qDebug("VapourSynth Dir: %s", vapoursynthPath.toUtf8().constData());
for(int i = 0; (i < 3) && (!vapoursynthComplete); i++)
{ {
QFileInfo vpsExeInfo(QString("%1/%2/vspipe.exe" ).arg(vapoursynthPath, CORE_PATH[i])); success |= VAPOURSYNTH_X86;
QFileInfo vpsDllInfo(QString("%1/%2/vapoursynth.dll").arg(vapoursynthPath, CORE_PATH[i])); qDebug("VapourSynth 32-Bit edition found!");
qDebug("VapourSynth EXE: %s", vpsExeInfo.absoluteFilePath().toUtf8().constData()); m_vpsExePath[0].reset(vpsExeFile32);
qDebug("VapourSynth DLL: %s", vpsDllInfo.absoluteFilePath().toUtf8().constData()); m_vpsDllPath[0].reset(vpsDllFile32);
if(vpsExeInfo.exists() && vpsDllInfo.exists())
{
m_vpsExePath = new QFile(vpsExeInfo.canonicalFilePath());
m_vpsDllPath = new QFile(vpsDllInfo.canonicalFilePath());
if(m_vpsExePath->open(QIODevice::ReadOnly) && m_vpsDllPath->open(QIODevice::ReadOnly))
{
if(vapoursynthComplete = MUtils::OS::is_executable_file(m_vpsExePath->fileName()))
{
vapoursynthPath.append("/").append(CORE_PATH[i]);
}
break;
}
MUTILS_DELETE(m_vpsExePath);
MUTILS_DELETE(m_vpsDllPath);
}
} }
if(!vapoursynthComplete) else
{ {
qWarning("VapourSynth installation incomplete -> disable VapouSynth support!"); qWarning("VapourSynth 32-Bit edition was found, but version check has failed!");
} }
} }
else
//Make sure 'vsscript.dll' can be loaded successfully
if(vapoursynthComplete && m_vpsExePath)
{ {
qDebug("VapourSynth detection is running, please stand by..."); qDebug("VapourSynth 32-Bit edition *not* found!");
success = checkVapourSynth(m_vpsExePath->fileName()); }
//Look for 64-Bit edition of VapourSynth next
QFile *vpsExeFile64, *vpsDllFile64;
if(isVapourSynthComplete(QString("%1/core64").arg(vapoursynthPath), vpsExeFile64, vpsDllFile64))
{
if(vpsExeFile64 && checkVapourSynth(vpsExeFile64->fileName()))
{
success |= VAPOURSYNTH_X64;
qDebug("VapourSynth 64-Bit edition found!");
m_vpsExePath[1].reset(vpsExeFile64);
m_vpsDllPath[1].reset(vpsDllFile64);
}
else
{
qWarning("VapourSynth 64-Bit edition was found, but version check has failed!");
}
}
else
{
qDebug("VapourSynth 64-Bit edition *not* found!");
} }
//Return VapourSynth path //Return VapourSynth path
@ -278,7 +253,37 @@ bool VapourSynthCheckThread::detectVapourSynthPath3(QString &path)
return success; return success;
} }
bool VapourSynthCheckThread::checkVapourSynth(const QString vspipePath) bool VapourSynthCheckThread::isVapourSynthComplete(const QString &vsCorePath, QFile *&vpsExeFile, QFile *&vpsDllFile)
{
bool complete = false;
vpsExeFile = vpsDllFile = NULL;
QFileInfo vpsExeInfo(QString("%1/vspipe.exe" ).arg(vsCorePath));
QFileInfo vpsDllInfo(QString("%1/vapoursynth.dll").arg(vsCorePath));
qDebug("VapourSynth EXE: %s", vpsExeInfo.absoluteFilePath().toUtf8().constData());
qDebug("VapourSynth DLL: %s", vpsDllInfo.absoluteFilePath().toUtf8().constData());
if(vpsExeInfo.exists() && vpsDllInfo.exists())
{
vpsExeFile = new QFile(vpsExeInfo.canonicalFilePath());
vpsDllFile = new QFile(vpsDllInfo.canonicalFilePath());
if(vpsExeFile->open(QIODevice::ReadOnly) && vpsDllFile->open(QIODevice::ReadOnly))
{
complete = MUtils::OS::is_executable_file(vpsExeFile->fileName());
}
}
if(!complete)
{
MUTILS_DELETE(vpsExeFile);
MUTILS_DELETE(vpsDllFile);
}
return complete;
}
bool VapourSynthCheckThread::checkVapourSynth(const QString &vspipePath)
{ {
QProcess process; QProcess process;
QStringList output; QStringList output;
@ -353,12 +358,11 @@ bool VapourSynthCheckThread::checkVapourSynth(const QString vspipePath)
//Minimum required version found? //Minimum required version found?
if(vapoursynthLogo) if(vapoursynthLogo)
{ {
qDebug("VapourSynth was detected successfully."); qDebug("VapourSynth version was detected successfully.");
return true; return true;
} }
//Failed to determine version //Failed to determine version
qWarning("Failed to determine VapourSynth version -> disable Vapousynth support!"); qWarning("Failed to determine VapourSynth version!");
qWarning("VapourSynth version is unsupported or VapourSynth installation is corrupted.");
return false; return false;
} }

View File

@ -32,14 +32,17 @@ class VapourSynthCheckThread : public QThread
Q_OBJECT Q_OBJECT
public: public:
static int detect(QString &path); static int detect(QString &path, int &vapourSynthType);
static void unload(void);
static const int VAPOURSYNTH_OFF = 0;
static const int VAPOURSYNTH_X86 = 1;
static const int VAPOURSYNTH_X64 = 2;
protected: protected:
VapourSynthCheckThread(void); VapourSynthCheckThread(void);
~VapourSynthCheckThread(void); ~VapourSynthCheckThread(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; }
QString getPath(void) { return m_vpsPath; } QString getPath(void) { return m_vpsPath; }
@ -47,23 +50,23 @@ private slots:
void start(Priority priority = InheritPriority) { QThread::start(priority); } void start(Priority priority = InheritPriority) { QThread::start(priority); }
private: private:
int m_success;
volatile bool m_exception; volatile bool m_exception;
volatile bool m_success;
QString m_vpsPath; QString m_vpsPath;
static QMutex m_vpsLock; static QMutex m_vpsLock;
static QFile *m_vpsExePath; static QScopedPointer<QFile> VapourSynthCheckThread::m_vpsExePath[2];
static QFile *m_vpsDllPath; static QScopedPointer<QFile> VapourSynthCheckThread::m_vpsDllPath[2];
static QLibrary *m_vpsLib;
//Entry point //Entry point
virtual void run(void); virtual void run(void);
//Functions //Functions
static bool detectVapourSynthPath1(QString &path, volatile bool *exception); static int detectVapourSynthPath1(QString &path, volatile bool *exception);
static bool detectVapourSynthPath2(QString &path, volatile bool *exception); static int detectVapourSynthPath2(QString &path, volatile bool *exception);
static bool detectVapourSynthPath3(QString &path); static int detectVapourSynthPath3(QString &path);
//Internal functions //Internal functions
static bool checkVapourSynth(const QString vspipePath); static bool isVapourSynthComplete(const QString &vsCorePath, QFile *&vpsExeFile, QFile *&vpsDllFile);
static bool checkVapourSynth(const QString &vspipePath);
}; };

View File

@ -24,9 +24,9 @@
#endif #endif
#define VER_X264_MAJOR 2 #define VER_X264_MAJOR 2
#define VER_X264_MINOR 4 #define VER_X264_MINOR 5
#define VER_X264_PATCH 6 #define VER_X264_PATCH 0
#define VER_X264_BUILD 918 #define VER_X264_BUILD 922
#define VER_X264_PORTABLE_EDITION (0) #define VER_X264_PORTABLE_EDITION (0)

View File

@ -564,7 +564,7 @@ void AddJobDialog::accept(void)
} }
else if(sourceType == MediaInfo::FILETYPE_VAPOURSYNTH) else if(sourceType == MediaInfo::FILETYPE_VAPOURSYNTH)
{ {
if(!m_sysinfo->hasVPSSupport()) if(!(m_sysinfo->hasVPS32Support() || m_sysinfo->hasVPS64Support()))
{ {
if(QMessageBox::warning(this, tr("VapurSynth unsupported!"), tr("<nobr>A VapourSynth script was selected as input, although VapourSynth is <b>not/<b> available!</nobr>"), tr("Abort"), tr("Ignore (at your own risk!)")) != 1) if(QMessageBox::warning(this, tr("VapurSynth unsupported!"), tr("<nobr>A VapourSynth script was selected as input, although VapourSynth is <b>not/<b> available!</nobr>"), tr("Abort"), tr("Ignore (at your own risk!)")) != 1)
{ {

View File

@ -293,9 +293,6 @@ MainWindow::~MainWindow(void)
} }
} }
VapourSynthCheckThread::unload();
AvisynthCheckThread::unload();
delete ui; delete ui;
} }
@ -933,7 +930,8 @@ void MainWindow::init(void)
{ {
qDebug("[Check for VapourSynth support]"); qDebug("[Check for VapourSynth support]");
QString vapoursynthPath; QString vapoursynthPath;
const int result = VapourSynthCheckThread::detect(vapoursynthPath); int vapoursynthType;
const int result = VapourSynthCheckThread::detect(vapoursynthPath, vapoursynthType);
if(result < 0) 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>");
@ -942,10 +940,11 @@ void MainWindow::init(void)
const int val = QMessageBox::critical(this, tr("VapourSynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore")); const int val = QMessageBox::critical(this, tr("VapourSynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore"));
if(val != 1) INIT_ERROR_EXIT(); if(val != 1) INIT_ERROR_EXIT();
} }
if(result && (!vapoursynthPath.isEmpty())) if(result && vapoursynthType && (!vapoursynthPath.isEmpty()))
{ {
qDebug("VapourSynth support is officially enabled now!"); qDebug("VapourSynth support is officially enabled now!");
m_sysinfo->setVPSSupport(true); m_sysinfo->setVPS32Support(vapoursynthType & VapourSynthCheckThread::VAPOURSYNTH_X86);
m_sysinfo->setVPS64Support(vapoursynthType & VapourSynthCheckThread::VAPOURSYNTH_X64);
m_sysinfo->setVPSPath(vapoursynthPath); m_sysinfo->setVPSPath(vapoursynthPath);
} }
else else