Improved VapourSynth detection code.

This commit is contained in:
LoRd_MuldeR 2013-11-08 17:39:16 +01:00
parent b1ff469728
commit fe48035eae
5 changed files with 77 additions and 28 deletions

View File

@ -44,16 +44,14 @@ int AvisynthCheckThread::detect(volatile double *version)
QEventLoop loop; QEventLoop loop;
AvisynthCheckThread thread; AvisynthCheckThread thread;
QTimer timer;
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
connect(&thread, SIGNAL(finished()), &loop, SLOT(quit())); connect(&thread, SIGNAL(finished()), &loop, SLOT(quit()));
connect(&thread, SIGNAL(terminated()), &loop, SLOT(quit())); connect(&thread, SIGNAL(terminated()), &loop, SLOT(quit()));
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
thread.start(); thread.start();
timer.start(8000); QTimer::singleShot(15000, &loop, SLOT(quit()));
qDebug("Avisynth thread has been created, please wait..."); qDebug("Avisynth thread has been created, please wait...");
loop.exec(QEventLoop::ExcludeUserInputEvents); loop.exec(QEventLoop::ExcludeUserInputEvents);

View File

@ -36,6 +36,21 @@ QFile *VapourSynthCheckThread::m_vpsExePath = NULL;
QFile *VapourSynthCheckThread::m_vpsDllPath = NULL; QFile *VapourSynthCheckThread::m_vpsDllPath = NULL;
QLibrary *VapourSynthCheckThread::m_vpsLib = NULL; QLibrary *VapourSynthCheckThread::m_vpsLib = NULL;
#define VALID_DIR(STR) ((!(STR).isEmpty()) && QDir((STR)).exists())
static inline QString &cleanDir(QString &path)
{
if(!path.isEmpty())
{
path = QDir::fromNativeSeparators(path);
while(path.endsWith('/'))
{
path.chop(1);
}
}
return path;
}
//------------------------------------- //-------------------------------------
// External API // External API
//------------------------------------- //-------------------------------------
@ -47,16 +62,14 @@ int VapourSynthCheckThread::detect(QString &path)
QEventLoop loop; QEventLoop loop;
VapourSynthCheckThread thread; VapourSynthCheckThread thread;
QTimer timer;
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
connect(&thread, SIGNAL(finished()), &loop, SLOT(quit())); connect(&thread, SIGNAL(finished()), &loop, SLOT(quit()));
connect(&thread, SIGNAL(terminated()), &loop, SLOT(quit())); connect(&thread, SIGNAL(terminated()), &loop, SLOT(quit()));
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
thread.start(); thread.start();
timer.start(8000); QTimer::singleShot(15000, &loop, SLOT(quit()));
qDebug("VapourSynth thread has been created, please wait..."); qDebug("VapourSynth thread has been created, please wait...");
loop.exec(QEventLoop::ExcludeUserInputEvents); loop.exec(QEventLoop::ExcludeUserInputEvents);
@ -178,18 +191,44 @@ bool VapourSynthCheckThread::detectVapourSynthPath3(QString &path)
X264_DELETE(m_vpsDllPath); X264_DELETE(m_vpsDllPath);
path.clear(); path.clear();
static const char *VPS_REG_KEY = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VapourSynth_is1"; static const char *VPS_REG_KEYS[] =
QString vapoursynthPath = x264_query_reg_string(false, VPS_REG_KEY, "InstallLocation");
if(vapoursynthPath.isEmpty())
{ {
qWarning("Vapoursynth install location entry not found -> not installed!"); "SOFTWARE\\VapourSynth",
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VapourSynth_is1",
NULL
};
static const char *VPS_REG_NAME[] =
{
"Path",
"InstallLocation",
"Inno Setup: App Path",
NULL
};
//Read VapourSynth path from registry
QString vapoursynthPath;
for(size_t i = 0; VPS_REG_KEYS[i]; i++)
{
for(size_t j = 0; VPS_REG_NAME[j]; j++)
{
vapoursynthPath = cleanDir(x264_query_reg_string(false, VPS_REG_KEYS[i], VPS_REG_NAME[j]));
if(VALID_DIR(vapoursynthPath)) break;
}
if(VALID_DIR(vapoursynthPath)) break;
}
//Make sure VapourSynth does exist
if(!VALID_DIR(vapoursynthPath))
{
qWarning("VapourSynth install path not found -> disable Vapousynth support!");
vapoursynthPath.clear();
} }
//Make sure that 'vapoursynth.dll' and 'vspipe.exe' are available //Make sure that 'vapoursynth.dll' and 'vspipe.exe' are available
bool vapoursynthComplete = false; bool vapoursynthComplete = false;
if(!vapoursynthPath.isEmpty()) if(!vapoursynthPath.isEmpty())
{ {
qDebug("VapourSynth Dir: %s", vapoursynthPath.toUtf8().constData());
m_vpsExePath = new QFile(QString("%1/core/vspipe.exe").arg(vapoursynthPath)); m_vpsExePath = new QFile(QString("%1/core/vspipe.exe").arg(vapoursynthPath));
m_vpsDllPath = new QFile(QString("%1/core/vapoursynth.dll").arg(vapoursynthPath)); m_vpsDllPath = new QFile(QString("%1/core/vapoursynth.dll").arg(vapoursynthPath));
qDebug("VapourSynth EXE: %s", m_vpsExePath->fileName().toUtf8().constData()); qDebug("VapourSynth EXE: %s", m_vpsExePath->fileName().toUtf8().constData());

View File

@ -26,7 +26,7 @@
#define VER_X264_MAJOR 2 #define VER_X264_MAJOR 2
#define VER_X264_MINOR 2 #define VER_X264_MINOR 2
#define VER_X264_PATCH 5 #define VER_X264_PATCH 5
#define VER_X264_BUILD 612 #define VER_X264_BUILD 620
#define VER_X264_MINIMUM_REV 2363 #define VER_X264_MINIMUM_REV 2363
#define VER_X264_CURRENT_API 140 #define VER_X264_CURRENT_API 140

View File

@ -55,9 +55,10 @@ const char *home_url = "http://muldersoft.com/";
const char *update_url = "http://code.google.com/p/mulder/downloads/list"; const char *update_url = "http://code.google.com/p/mulder/downloads/list";
const char *tpl_last = "<LAST_USED>"; const char *tpl_last = "<LAST_USED>";
#define SET_FONT_BOLD(WIDGET,BOLD) { QFont _font = WIDGET->font(); _font.setBold(BOLD); WIDGET->setFont(_font); } #define SET_FONT_BOLD(WIDGET,BOLD) do { QFont _font = WIDGET->font(); _font.setBold(BOLD); WIDGET->setFont(_font); } while(0)
#define SET_TEXT_COLOR(WIDGET,COLOR) { QPalette _palette = WIDGET->palette(); _palette.setColor(QPalette::WindowText, (COLOR)); _palette.setColor(QPalette::Text, (COLOR)); WIDGET->setPalette(_palette); } #define SET_TEXT_COLOR(WIDGET,COLOR) do { QPalette _palette = WIDGET->palette(); _palette.setColor(QPalette::WindowText, (COLOR)); _palette.setColor(QPalette::Text, (COLOR)); WIDGET->setPalette(_palette); } while(0)
#define LINK(URL) "<a href=\"" URL "\">" URL "</a>" #define LINK(URL) "<a href=\"" URL "\">" URL "</a>"
#define INIT_ERROR_EXIT() do { m_initialized = true; close(); qApp->exit(-1); return; } while(0)
//static int exceptionFilter(_EXCEPTION_RECORD *dst, _EXCEPTION_POINTERS *src) { memcpy(dst, src->ExceptionRecord, sizeof(_EXCEPTION_RECORD)); return EXCEPTION_EXECUTE_HANDLER; } //static int exceptionFilter(_EXCEPTION_RECORD *dst, _EXCEPTION_POINTERS *src) { memcpy(dst, src->ExceptionRecord, sizeof(_EXCEPTION_RECORD)); return EXCEPTION_EXECUTE_HANDLER; }
@ -79,7 +80,8 @@ MainWindow::MainWindow(const x264_cpu_t *const cpuFeatures)
m_recentlyUsed(NULL), m_recentlyUsed(NULL),
m_skipVersionTest(false), m_skipVersionTest(false),
m_abortOnTimeout(true), m_abortOnTimeout(true),
m_firstShow(true) m_firstShow(true),
m_initialized(false)
{ {
//Init the dialog, from the .ui file //Init the dialog, from the .ui file
setupUi(this); setupUi(this);
@ -720,7 +722,7 @@ void MainWindow::init(void)
m_ipcThread->terminate(); m_ipcThread->terminate();
m_ipcThread->wait(); m_ipcThread->wait();
} }
close(); qApp->exit(-1); return; INIT_ERROR_EXIT();
} }
} }
@ -736,7 +738,7 @@ void MainWindow::init(void)
{ {
QMessageBox::critical(this, tr("Invalid File!"), tr("<nobr>At least on required tool is not a valid Win32 or Win64 binary:<br><tt style=\"whitespace:nowrap\">%1</tt><br><br>Please re-install the program in order to fix the problem!</nobr>").arg(QDir::toNativeSeparators(QString("%1/toolset/%2").arg(m_appDir, current))).replace("-", "&minus;")); QMessageBox::critical(this, tr("Invalid File!"), tr("<nobr>At least on required tool is not a valid Win32 or Win64 binary:<br><tt style=\"whitespace:nowrap\">%1</tt><br><br>Please re-install the program in order to fix the problem!</nobr>").arg(QDir::toNativeSeparators(QString("%1/toolset/%2").arg(m_appDir, current))).replace("-", "&minus;"));
qFatal(QString("Binary is invalid: %1/toolset/%2").arg(m_appDir, current).toLatin1().constData()); qFatal(QString("Binary is invalid: %1/toolset/%2").arg(m_appDir, current).toLatin1().constData());
close(); qApp->exit(-1); return; INIT_ERROR_EXIT();
} }
m_toolsList << file; m_toolsList << file;
} }
@ -745,7 +747,7 @@ void MainWindow::init(void)
X264_DELETE(file); X264_DELETE(file);
QMessageBox::critical(this, tr("File Not Found!"), tr("<nobr>At least on required tool could not be found:<br><tt style=\"whitespace:nowrap\">%1</tt><br><br>Please re-install the program in order to fix the problem!</nobr>").arg(QDir::toNativeSeparators(QString("%1/toolset/%2").arg(m_appDir, current))).replace("-", "&minus;")); QMessageBox::critical(this, tr("File Not Found!"), tr("<nobr>At least on required tool could not be found:<br><tt style=\"whitespace:nowrap\">%1</tt><br><br>Please re-install the program in order to fix the problem!</nobr>").arg(QDir::toNativeSeparators(QString("%1/toolset/%2").arg(m_appDir, current))).replace("-", "&minus;"));
qFatal(QString("Binary not found: %1/toolset/%2").arg(m_appDir, current).toLatin1().constData()); qFatal(QString("Binary not found: %1/toolset/%2").arg(m_appDir, current).toLatin1().constData());
close(); qApp->exit(-1); return; INIT_ERROR_EXIT();
} }
} }
@ -763,7 +765,7 @@ void MainWindow::init(void)
if(!ok) if(!ok)
{ {
int val = QMessageBox::warning(this, tr("Write Test Failed"), tr("<nobr>The application was launched in portable mode, but the program path is <b>not</b> writable!</nobr>"), tr("Quit"), tr("Ignore")); int val = QMessageBox::warning(this, tr("Write Test Failed"), tr("<nobr>The application was launched in portable mode, but the program path is <b>not</b> writable!</nobr>"), tr("Quit"), tr("Ignore"));
if(val != 1) { close(); qApp->exit(-1); return; } if(val != 1) INIT_ERROR_EXIT();
} }
} }
@ -772,7 +774,7 @@ void MainWindow::init(void)
{ {
qsrand(time(NULL)); int rnd = qrand() % 3; qsrand(time(NULL)); int rnd = qrand() % 3;
int val = QMessageBox::information(this, tr("Pre-Release Version"), tr("Note: This is a pre-release version. Please do NOT use for production!<br>Click the button #%1 in order to continue...<br><br>(There will be no such message box in the final version of this application)").arg(QString::number(rnd + 1)), tr("(1)"), tr("(2)"), tr("(3)"), qrand() % 3); int val = QMessageBox::information(this, tr("Pre-Release Version"), tr("Note: This is a pre-release version. Please do NOT use for production!<br>Click the button #%1 in order to continue...<br><br>(There will be no such message box in the final version of this application)").arg(QString::number(rnd + 1)), tr("(1)"), tr("(2)"), tr("(3)"), qrand() % 3);
if(rnd != val) { close(); qApp->exit(-1); return; } if(rnd != val) INIT_ERROR_EXIT();
} }
//Make sure this CPU can run x264 (requires MMX + MMXEXT/iSSE to run x264 with ASM enabled, additionally requires SSE1 for most x264 builds) //Make sure this CPU can run x264 (requires MMX + MMXEXT/iSSE to run x264 with ASM enabled, additionally requires SSE1 for most x264 builds)
@ -780,13 +782,13 @@ void MainWindow::init(void)
{ {
QMessageBox::critical(this, tr("Unsupported CPU"), tr("<nobr>Sorry, but this machine is <b>not</b> physically capable of running x264 (with assembly).<br>Please get a CPU that supports at least the MMX and MMXEXT instruction sets!</nobr>"), tr("Quit")); QMessageBox::critical(this, tr("Unsupported CPU"), tr("<nobr>Sorry, but this machine is <b>not</b> physically capable of running x264 (with assembly).<br>Please get a CPU that supports at least the MMX and MMXEXT instruction sets!</nobr>"), tr("Quit"));
qFatal("System does not support MMX and MMXEXT, x264 will not work !!!"); qFatal("System does not support MMX and MMXEXT, x264 will not work !!!");
close(); qApp->exit(-1); return; INIT_ERROR_EXIT();
} }
else if(!(m_cpuFeatures->mmx && m_cpuFeatures->sse)) else if(!(m_cpuFeatures->mmx && m_cpuFeatures->sse))
{ {
qWarning("WARNING: System does not support SSE1, most x264 builds will not work !!!\n"); qWarning("WARNING: System does not support SSE1, most x264 builds will not work !!!\n");
int val = QMessageBox::warning(this, tr("Unsupported CPU"), tr("<nobr>It appears that this machine does <b>not</b> support the SSE1 instruction set.<br>Thus most builds of x264 will <b>not</b> run on this computer at all.<br><br>Please get a CPU that supports the MMX and SSE1 instruction sets!</nobr>"), tr("Quit"), tr("Ignore")); int val = QMessageBox::warning(this, tr("Unsupported CPU"), tr("<nobr>It appears that this machine does <b>not</b> support the SSE1 instruction set.<br>Thus most builds of x264 will <b>not</b> run on this computer at all.<br><br>Please get a CPU that supports the MMX and SSE1 instruction sets!</nobr>"), tr("Quit"), tr("Ignore"));
if(val != 1) { close(); qApp->exit(-1); return; } if(val != 1) INIT_ERROR_EXIT();
} }
//Skip version check (not recommended!) //Skip version check (not recommended!)
@ -815,7 +817,7 @@ void MainWindow::init(void)
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>");
text += tr("We suggest to move all .dll and .avsi files out of your Avisynth Plugins folder and try again."); text += tr("We suggest to move all .dll and .avsi files out of your Avisynth Plugins folder and try again.");
int val = QMessageBox::critical(this, tr("Avisynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore")); int val = QMessageBox::critical(this, tr("Avisynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore"));
if(val != 1) { close(); qApp->exit(-1); return; } if(val != 1) INIT_ERROR_EXIT();
} }
if((!result) || (avisynthVersion < 2.5)) if((!result) || (avisynthVersion < 2.5))
{ {
@ -824,10 +826,10 @@ void MainWindow::init(void)
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>"); 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>");
text += tr("Please download and install Avisynth:").append("<br>").append(LINK("http://sourceforge.net/projects/avisynth2/files/AviSynth%202.5/")); text += tr("Please download and install Avisynth:").append("<br>").append(LINK("http://sourceforge.net/projects/avisynth2/files/AviSynth%202.5/"));
int val = QMessageBox::warning(this, tr("Avisynth Missing"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore")); int val = QMessageBox::warning(this, tr("Avisynth Missing"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore"));
if(val != 1) { close(); qApp->exit(-1); return; } if(val != 1) INIT_ERROR_EXIT();
} }
} }
qDebug(""); qDebug(" ");
} }
//Check for VapourSynth support //Check for VapourSynth support
@ -842,7 +844,7 @@ void MainWindow::init(void)
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>");
text += tr("We suggest to move all .dll files out of your VapourSynth Filters folder and try again."); text += tr("We suggest to move all .dll files out of your VapourSynth Filters folder and try again.");
int val = QMessageBox::critical(this, tr("VapourSynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore")); int val = QMessageBox::critical(this, tr("VapourSynth Error"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore"));
if(val != 1) { close(); qApp->exit(-1); return; } if(val != 1) INIT_ERROR_EXIT();
} }
if((!result) || (m_vapoursynthPath.isEmpty())) if((!result) || (m_vapoursynthPath.isEmpty()))
{ {
@ -852,10 +854,10 @@ void MainWindow::init(void)
text += tr("Please download and install VapourSynth for Windows (R19 or later):").append("<br>").append(LINK("http://www.vapoursynth.com/")).append("<br><br>"); text += tr("Please download and install VapourSynth for Windows (R19 or later):").append("<br>").append(LINK("http://www.vapoursynth.com/")).append("<br><br>");
text += tr("Note that Python 3.3 (x86) is a prerequisite for installing VapourSynth:").append("<br>").append(LINK("http://www.python.org/getit/")).append("<br>"); text += tr("Note that Python 3.3 (x86) is a prerequisite for installing VapourSynth:").append("<br>").append(LINK("http://www.python.org/getit/")).append("<br>");
int val = QMessageBox::warning(this, tr("VapourSynth Missing"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore")); int val = QMessageBox::warning(this, tr("VapourSynth Missing"), QString("<nobr>%1</nobr>").arg(text).replace("-", "&minus;"), tr("Quit"), tr("Ignore"));
if(val != 1) { close(); qApp->exit(-1); return; } if(val != 1) INIT_ERROR_EXIT();
} }
} }
qDebug(""); qDebug(" ");
} }
//Check for expiration //Check for expiration
@ -898,6 +900,9 @@ void MainWindow::init(void)
//Enable drag&drop support for this window, required for Qt v4.8.4+ //Enable drag&drop support for this window, required for Qt v4.8.4+
setAcceptDrops(true); setAcceptDrops(true);
//Update initialized flag
m_initialized = true;
} }
/* /*
@ -971,6 +976,12 @@ void MainWindow::showEvent(QShowEvent *e)
*/ */
void MainWindow::closeEvent(QCloseEvent *e) void MainWindow::closeEvent(QCloseEvent *e)
{ {
if(!m_initialized)
{
e->ignore();
return;
}
if(countRunningJobs() > 0) if(countRunningJobs() > 0)
{ {
e->ignore(); e->ignore();

View File

@ -55,6 +55,7 @@ private:
bool m_firstShow; bool m_firstShow;
bool m_skipVersionTest; bool m_skipVersionTest;
bool m_abortOnTimeout; bool m_abortOnTimeout;
bool m_initialized;
QLabel *m_label; QLabel *m_label;
IPCThread *m_ipcThread; IPCThread *m_ipcThread;