Much improved VapourSynth detection + added option "--no-deadlock-detection" to disable process termination on timeout.

This commit is contained in:
LoRd_MuldeR 2013-08-04 18:44:53 +02:00
parent 2aa2c7385f
commit 9635f092f6
6 changed files with 118 additions and 53 deletions

View File

@ -213,12 +213,14 @@ in older versions of the Simple x264 Launcher is *NOT* needed anymore!!
The following command-line switches are available:
--add <file> [<file>] ... Create new job(s) from files(s)
--console ............... Show the "debug" console
--no-console ............ Don't show the "debug" console
--no-style .............. Don't use the Qt "Plastique" style
--skip-avisynth-check ... Skip Avisynth check (not recommended!)
--force-cpu-no-64bit .... Forcefully disable 64-Bit support
--add <file> [<file>] ..... Create new job(s) from files(s)
--console ................. Show the "debug" console
--no-console .............. Don't show the "debug" console
--no-style ................ Don't use the Qt "Plastique" style
--skip-avisynth-check ..... Skip Avisynth check, disable .AVS input
--skip-vapoursynth-check .. Skip VapourSynth check, disables .VPY input
--force-cpu-no-64bit ...... Forcefully disable 64-Bit support
--no-deadlock-detection ... Don't abort processes on timeout/deadlock
These are parameters you can pass to Simple x264 Launcher, they can NOT
be passed to x264 itself as "custom" parameters!

View File

@ -92,8 +92,9 @@ while(0)
} \
while(0)
#define AVS2_BINARY(BIN_DIR, IS_X64) QString("%1/%2/avs2yuv_%2.exe").arg((BIN_DIR), ((IS_X64) ? "x64" : "x86"))
#define X264_BINARY(BIN_DIR, IS_10BIT, IS_X64) QString("%1/%2/x264_%3_%2.exe").arg((BIN_DIR), ((IS_X64) ? "x64" : "x86"), ((IS_10BIT) ? "10bit" : "8bit"))
#define AVS2_BINARY(BIN_DIR, IS_X64) (QString("%1/%2/avs2yuv_%2.exe").arg((BIN_DIR), ((IS_X64) ? "x64" : "x86")))
#define X264_BINARY(BIN_DIR, IS_10BIT, IS_X64) (QString("%1/%2/x264_%3_%2.exe").arg((BIN_DIR), ((IS_X64) ? "x64" : "x86"), ((IS_10BIT) ? "10bit" : "8bit")))
#define VPSP_BINARY(VPS_DIR) (QString("%1/vspipe.exe").arg((VPS_DIR)))
/*
* Static vars
@ -105,7 +106,7 @@ static const char *VPS_TEST_FILE = "import vapoursynth as vs\ncore = vs.get_core
// Constructor & Destructor
///////////////////////////////////////////////////////////////////////////////
EncodeThread::EncodeThread(const QString &sourceFileName, const QString &outputFileName, const OptionsModel *options, const QString &binDir, const QString &vpsDir, bool x264_x64, bool x264_10bit, bool avs2yuv_x64, bool const skipVersionTest, int processPriroity)
EncodeThread::EncodeThread(const QString &sourceFileName, const QString &outputFileName, const OptionsModel *options, const QString &binDir, const QString &vpsDir, const bool &x264_x64, const bool &x264_10bit, const bool &avs2yuv_x64, const bool &skipVersionTest, const int &processPriroity, const bool &abortOnTimeout)
:
m_jobId(QUuid::createUuid()),
m_sourceFileName(sourceFileName),
@ -118,6 +119,7 @@ EncodeThread::EncodeThread(const QString &sourceFileName, const QString &outputF
m_avs2yuv_x64(avs2yuv_x64),
m_skipVersionTest(skipVersionTest),
m_processPriority(processPriroity),
m_abortOnTimeout(abortOnTimeout),
m_handle_jobObject(NULL),
m_semaphorePaused(0)
{
@ -248,7 +250,7 @@ void EncodeThread::encode(void)
CHECK_STATUS(m_abort, ok);
break;
case INPUT_VAPOUR:
ok = checkVersionVapoursynth(QString("%1/vspipe.exe").arg(m_vpsDir));
ok = checkVersionVapoursynth();
CHECK_STATUS(m_abort, ok);
break;
}
@ -288,7 +290,7 @@ void EncodeThread::encode(void)
CHECK_STATUS(m_abort, ok);
break;
case INPUT_VAPOUR:
ok = checkPropertiesVapoursynth(QString("%1/vspipe.exe").arg(m_vpsDir), frames);
ok = checkPropertiesVapoursynth(frames);
CHECK_STATUS(m_abort, ok);
break;
}
@ -358,7 +360,7 @@ bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_
cmdLine_Input << pathToLocal(QDir::toNativeSeparators(m_sourceFileName));
cmdLine_Input << "-" << "-y4m";
log("Creating Vapoursynth process:");
if(!startProcess(processInput, QString("%1/vspipe.exe").arg(m_vpsDir), cmdLine_Input, false))
if(!startProcess(processInput, VPSP_BINARY(m_vpsDir), cmdLine_Input, false))
{
return false;
}
@ -426,13 +428,16 @@ bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_
{
if(processEncode.state() == QProcess::Running)
{
if(waitCounter++ > m_processTimeoutMaxCounter)
if(++waitCounter > m_processTimeoutMaxCounter)
{
processEncode.kill();
qWarning("x264 process timed out <-- killing!");
log("\nPROCESS TIMEOUT !!!");
bTimeout = true;
break;
if(m_abortOnTimeout)
{
processEncode.kill();
qWarning("x264 process timed out <-- killing!");
log("\nPROCESS TIMEOUT !!!");
bTimeout = true;
break;
}
}
else if(waitCounter == m_processTimeoutWarning)
{
@ -877,12 +882,19 @@ unsigned int EncodeThread::checkVersionAvs2yuv(bool x64)
return (ver_maj * REV_MULT) + ((ver_min % REV_MULT) * 10) + (ver_mod % 10);
}
bool EncodeThread::checkVersionVapoursynth(const QString &vspipePath)
bool EncodeThread::checkVersionVapoursynth(/*const QString &vspipePath*/)
{
//Is VapourSynth available at all?
if(m_vpsDir.isEmpty() || (!QFileInfo(VPSP_BINARY(m_vpsDir)).isFile()))
{
log(tr("\nVPY INPUT REQUIRES VAPOURSYNTH, BUT IT IS *NOT* AVAILABLE !!!"));
return false;
}
QProcess process;
log("\nCreating process:");
if(!startProcess(process, vspipePath, QStringList()))
if(!startProcess(process, VPSP_BINARY(m_vpsDir), QStringList()))
{
return false;;
}
@ -1004,14 +1016,17 @@ bool EncodeThread::checkPropertiesAvisynth(bool x64, unsigned int &frames)
{
if(process.state() == QProcess::Running)
{
if(waitCounter++ > m_processTimeoutMaxCounter)
if(++waitCounter > m_processTimeoutMaxCounter)
{
process.kill();
qWarning("Avs2YUV process timed out <-- killing!");
log("\nPROCESS TIMEOUT !!!");
log("\nAvisynth has encountered a deadlock or your script takes EXTREMELY long to initialize!");
bTimeout = true;
break;
if(m_abortOnTimeout)
{
process.kill();
qWarning("Avs2YUV process timed out <-- killing!");
log("\nPROCESS TIMEOUT !!!");
log("\nAvisynth has encountered a deadlock or your script takes EXTREMELY long to initialize!");
bTimeout = true;
break;
}
}
else if(waitCounter == m_processTimeoutWarning)
{
@ -1119,7 +1134,7 @@ bool EncodeThread::checkPropertiesAvisynth(bool x64, unsigned int &frames)
return true;
}
bool EncodeThread::checkPropertiesVapoursynth(const QString &vspipePath, unsigned int &frames)
bool EncodeThread::checkPropertiesVapoursynth(/*const QString &vspipePath,*/ unsigned int &frames)
{
QProcess process;
QStringList cmdLine;
@ -1128,7 +1143,7 @@ bool EncodeThread::checkPropertiesVapoursynth(const QString &vspipePath, unsigne
cmdLine << "-" << "-info";
log("Creating process:");
if(!startProcess(process, vspipePath, cmdLine))
if(!startProcess(process, VPSP_BINARY(m_vpsDir), cmdLine))
{
return false;;
}
@ -1161,14 +1176,17 @@ bool EncodeThread::checkPropertiesVapoursynth(const QString &vspipePath, unsigne
{
if(process.state() == QProcess::Running)
{
if(waitCounter++ > m_processTimeoutMaxCounter)
if(++waitCounter > m_processTimeoutMaxCounter)
{
process.kill();
qWarning("VSPipe process timed out <-- killing!");
log("\nPROCESS TIMEOUT !!!");
log("\nVapoursynth has encountered a deadlock or your script takes EXTREMELY long to initialize!");
bTimeout = true;
break;
if(m_abortOnTimeout)
{
process.kill();
qWarning("VSPipe process timed out <-- killing!");
log("\nPROCESS TIMEOUT !!!");
log("\nVapoursynth has encountered a deadlock or your script takes EXTREMELY long to initialize!");
bTimeout = true;
break;
}
}
else if(waitCounter == m_processTimeoutWarning)
{

View File

@ -37,7 +37,7 @@ class EncodeThread : public QThread
Q_OBJECT
public:
EncodeThread(const QString &sourceFileName, const QString &outputFileName, const OptionsModel *options, const QString &binDir, const QString &vpsDir, bool x264_x64, bool x264_10bit, bool avs2yuv_x64, bool const skipVersionTest, int processPriroity);
EncodeThread(const QString &sourceFileName, const QString &outputFileName, const OptionsModel *options, const QString &binDir, const QString &vpsDir, const bool &x264_x64, const bool &x264_10bit, const bool &avs2yuv_x64, const bool &skipVersionTest, const int &processPriroity, const bool &abortOnTimeout);
~EncodeThread(void);
QUuid getId(void) { return this->m_jobId; };
@ -79,6 +79,7 @@ protected:
const bool m_avs2yuv_x64;
const bool m_skipVersionTest;
const int m_processPriority;
const bool m_abortOnTimeout;
//Types
enum inputType_t
@ -112,9 +113,9 @@ protected:
QStringList buildCommandLine(bool usePipe, bool use10Bit, unsigned int frames, const QString &indexFile, int pass = 0, const QString &passLogFile = QString());
unsigned int checkVersionX264(bool use_x64, bool use_10bit, bool &modified);
unsigned int checkVersionAvs2yuv(bool x64);
bool checkVersionVapoursynth(const QString &vspipePath);
bool checkVersionVapoursynth(void);
bool checkPropertiesAvisynth(bool x64, unsigned int &frames);
bool checkPropertiesVapoursynth(const QString &vspipePath, unsigned int &frames);
bool checkPropertiesVapoursynth(unsigned int &frames);
//Auxiallary Stuff
void log(const QString &text) { emit messageLogged(m_jobId, text); }

View File

@ -22,7 +22,7 @@
#define VER_X264_MAJOR 2
#define VER_X264_MINOR 1
#define VER_X264_PATCH 8
#define VER_X264_BUILD 530
#define VER_X264_BUILD 537
#define VER_X264_MINIMUM_REV 2339
#define VER_X264_CURRENT_API 135

View File

@ -76,6 +76,7 @@ MainWindow::MainWindow(const x264_cpu_t *const cpuFeatures)
m_preferences(NULL),
m_recentlyUsed(NULL),
m_skipVersionTest(false),
m_abortOnTimeout(true),
m_firstShow(true)
{
//Init the dialog, from the .ui file
@ -775,6 +776,13 @@ void MainWindow::init(void)
m_skipVersionTest = true;
}
//Don't abort encoding process on timeout (not recommended!)
if(qApp->arguments().contains("--no-deadlock-detection", Qt::CaseInsensitive))
{
qWarning("Deadlock detection disabled, you have been warned!\n");
m_abortOnTimeout = false;
}
//Check for Avisynth support
if(!qApp->arguments().contains("--skip-avisynth-check", Qt::CaseInsensitive))
{
@ -804,20 +812,11 @@ void MainWindow::init(void)
const QString vapursynthPath = getVapoursynthLocation();
if(!vapursynthPath.isEmpty())
{
bool okay = false;
QFile *vpsExePath = new QFile(QString("%1/core/vspipe.exe").arg(vapursynthPath));
QFile *vpsDllPath = new QFile(QString("%1/core/vapoursynth.dll").arg(vapursynthPath));
qDebug("VapourSynth EXE: %s", vpsExePath->fileName().toUtf8().constData());
qDebug("VapourSynth DLL: %s", vpsDllPath->fileName().toUtf8().constData());
if(vpsExePath->open(QIODevice::ReadOnly) && vpsDllPath->open(QIODevice::ReadOnly))
{
DWORD binaryType;
if(GetBinaryType(QWCHAR(QDir::toNativeSeparators(vpsExePath->fileName())), &binaryType))
{
okay = (binaryType == SCS_32BIT_BINARY || binaryType == SCS_64BIT_BINARY);
}
}
if(okay)
if(checkVapourSynth(vpsExePath, vpsDllPath))
{
qDebug("VapourSynth support enabled.");
m_vapoursynthPath = QFileInfo(vpsExePath->fileName()).canonicalPath();
@ -826,7 +825,7 @@ void MainWindow::init(void)
}
else
{
qDebug("VapourSynth binaries not found -> disable Vapousynth support!");
qDebug("VapourSynth not avilable -> disable Vapousynth support!");
X264_DELETE(vpsExePath);
X264_DELETE(vpsDllPath);
int val = QMessageBox::warning(this, tr("VapourSynth Missing"), tr("<nobr>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!<br><br>Please download and install VapourSynth (r19 or later) here:<br><a href=\"http://www.vapoursynth.com/\">http://www.vapoursynth.com/</a></nobr>").replace("-", "&minus;"), tr("Quit"), tr("Ignore"));
@ -1169,7 +1168,8 @@ bool MainWindow::appendJob(const QString &sourceFileName, const QString &outputF
m_preferences->use10BitEncoding(),
m_cpuFeatures->x64 && m_preferences->useAvisyth64Bit(),
m_skipVersionTest,
m_preferences->processPriority()
m_preferences->processPriority(),
m_abortOnTimeout
);
QModelIndex newIndex = m_jobList->insertJob(thrd);
@ -1307,6 +1307,7 @@ QString MainWindow::getVapoursynthLocation(void)
QString vapoursynthPath;
static const wchar_t *VPS_REG_KEY = L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VapourSynth_is1";
HKEY hKey = NULL;
if(RegOpenKey(HKEY_LOCAL_MACHINE, VPS_REG_KEY, &hKey) == ERROR_SUCCESS)
{
const size_t DATA_LEN = 2048;
@ -1325,7 +1326,46 @@ QString MainWindow::getVapoursynthLocation(void)
}
else
{
qDebug("Vapoursynth registry key not found -> not installed!");
qWarning("Vapoursynth registry key not found -> not installed!");
}
return vapoursynthPath;
}
bool MainWindow::checkVapourSynth(QFile *vpsExePath, QFile *vpsDllPath)
{
bool okay = false;
static const char *VSSCRIPT_ENTRY = "_vsscript_init@0";
if(vpsExePath->open(QIODevice::ReadOnly) && vpsDllPath->open(QIODevice::ReadOnly))
{
DWORD binaryType;
if(GetBinaryType(QWCHAR(QDir::toNativeSeparators(vpsExePath->fileName())), &binaryType))
{
okay = (binaryType == SCS_32BIT_BINARY || binaryType == SCS_64BIT_BINARY);
}
}
if(okay)
{
qDebug("VapourSynth binaries found -> load VSSCRIPT.DLL");
QLibrary vspLibrary("vsscript.dll");
if(okay = vspLibrary.load())
{
if(!(okay = (vspLibrary.resolve(VSSCRIPT_ENTRY) != NULL)))
{
qWarning("Entrypoint '%s' not found in VSSCRIPT.DLL !!!", VSSCRIPT_ENTRY);
}
}
else
{
qWarning("Failed to load VSSCRIPT.DLL !!!");
}
}
else
{
qWarning("VapourSynth binaries could not be found !!!");
}
return okay;
}

View File

@ -54,6 +54,8 @@ protected:
private:
bool m_firstShow;
bool m_skipVersionTest;
bool m_abortOnTimeout;
QLabel *m_label;
IPCThread *m_ipcThread;
@ -64,6 +66,7 @@ private:
PreferencesModel *m_preferences;
RecentlyUsed *m_recentlyUsed;
QString m_vapoursynthPath;
const x264_cpu_t *const m_cpuFeatures;
@ -79,6 +82,7 @@ private:
unsigned int countRunningJobs(void);
static QString getVapoursynthLocation(void);
static bool checkVapourSynth(QFile *vpsExePath, QFile *vpsDllPath);
private slots:
void addButtonPressed();