Implemented VaporSynth input support.
This commit is contained in:
parent
78f882f1ad
commit
2aa2c7385f
@ -99,18 +99,20 @@ while(0)
|
|||||||
* Static vars
|
* Static vars
|
||||||
*/
|
*/
|
||||||
static const unsigned int REV_MULT = 10000;
|
static const unsigned int REV_MULT = 10000;
|
||||||
|
static const char *VPS_TEST_FILE = "import vapoursynth as vs\ncore = vs.get_core()\nv = core.std.BlankClip()\nv.set_output()\n";
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Constructor & Destructor
|
// Constructor & Destructor
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
EncodeThread::EncodeThread(const QString &sourceFileName, const QString &outputFileName, const OptionsModel *options, const QString &binDir, 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, bool x264_x64, bool x264_10bit, bool avs2yuv_x64, bool const skipVersionTest, int processPriroity)
|
||||||
:
|
:
|
||||||
m_jobId(QUuid::createUuid()),
|
m_jobId(QUuid::createUuid()),
|
||||||
m_sourceFileName(sourceFileName),
|
m_sourceFileName(sourceFileName),
|
||||||
m_outputFileName(outputFileName),
|
m_outputFileName(outputFileName),
|
||||||
m_options(new OptionsModel(*options)),
|
m_options(new OptionsModel(*options)),
|
||||||
m_binDir(binDir),
|
m_binDir(binDir),
|
||||||
|
m_vpsDir(vpsDir),
|
||||||
m_x264_x64(x264_x64),
|
m_x264_x64(x264_x64),
|
||||||
m_x264_10bit(x264_10bit),
|
m_x264_10bit(x264_10bit),
|
||||||
m_avs2yuv_x64(avs2yuv_x64),
|
m_avs2yuv_x64(avs2yuv_x64),
|
||||||
@ -140,6 +142,7 @@ EncodeThread::~EncodeThread(void)
|
|||||||
|
|
||||||
void EncodeThread::run(void)
|
void EncodeThread::run(void)
|
||||||
{
|
{
|
||||||
|
#if !defined(_DEBUG)
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
checkedRun();
|
checkedRun();
|
||||||
@ -148,6 +151,9 @@ void EncodeThread::run(void)
|
|||||||
{
|
{
|
||||||
qWarning("STRUCTURED EXCEPTION ERROR IN ENCODE THREAD !!!");
|
qWarning("STRUCTURED EXCEPTION ERROR IN ENCODE THREAD !!!");
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
checkedRun();
|
||||||
|
#endif
|
||||||
|
|
||||||
if(m_handle_jobObject)
|
if(m_handle_jobObject)
|
||||||
{
|
{
|
||||||
@ -217,11 +223,13 @@ void EncodeThread::encode(void)
|
|||||||
log(tr("Profile: %1").arg(m_options->profile()));
|
log(tr("Profile: %1").arg(m_options->profile()));
|
||||||
log(tr("Custom: %1").arg(m_options->customX264().isEmpty() ? tr("(None)") : m_options->customX264()));
|
log(tr("Custom: %1").arg(m_options->customX264().isEmpty() ? tr("(None)") : m_options->customX264()));
|
||||||
|
|
||||||
|
log(m_binDir);
|
||||||
|
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
unsigned int frames = 0;
|
unsigned int frames = 0;
|
||||||
|
|
||||||
//Use Avisynth?
|
//Seletct type of input
|
||||||
const bool usePipe = (QFileInfo(m_sourceFileName).suffix().compare("avs", Qt::CaseInsensitive) == 0);
|
const int inputType = getInputType(QFileInfo(m_sourceFileName).suffix());
|
||||||
const QString indexFile = QString("%1/%2.ffindex").arg(QDir::tempPath(), m_jobId.toString());
|
const QString indexFile = QString("%1/%2.ffindex").arg(QDir::tempPath(), m_jobId.toString());
|
||||||
|
|
||||||
//Checking x264 version
|
//Checking x264 version
|
||||||
@ -233,10 +241,16 @@ void EncodeThread::encode(void)
|
|||||||
|
|
||||||
//Checking avs2yuv version
|
//Checking avs2yuv version
|
||||||
unsigned int revision_avs2yuv = UINT_MAX;
|
unsigned int revision_avs2yuv = UINT_MAX;
|
||||||
if(usePipe)
|
switch(inputType)
|
||||||
{
|
{
|
||||||
|
case INPUT_AVISYN:
|
||||||
ok = ((revision_avs2yuv = checkVersionAvs2yuv(m_avs2yuv_x64)) != UINT_MAX);
|
ok = ((revision_avs2yuv = checkVersionAvs2yuv(m_avs2yuv_x64)) != UINT_MAX);
|
||||||
CHECK_STATUS(m_abort, ok);
|
CHECK_STATUS(m_abort, ok);
|
||||||
|
break;
|
||||||
|
case INPUT_VAPOUR:
|
||||||
|
ok = checkVersionVapoursynth(QString("%1/vspipe.exe").arg(m_vpsDir));
|
||||||
|
CHECK_STATUS(m_abort, ok);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Print versions
|
//Print versions
|
||||||
@ -264,11 +278,20 @@ void EncodeThread::encode(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Detect source info
|
//Detect source info
|
||||||
if(usePipe)
|
if(inputType != INPUT_NATIVE)
|
||||||
{
|
{
|
||||||
log(tr("\n--- AVS INFO ---\n"));
|
log(tr("\n--- SOURCE INFO ---\n"));
|
||||||
ok = checkProperties(m_avs2yuv_x64, frames);
|
switch(inputType)
|
||||||
CHECK_STATUS(m_abort, ok);
|
{
|
||||||
|
case INPUT_AVISYN:
|
||||||
|
ok = checkPropertiesAvisynth(m_avs2yuv_x64, frames);
|
||||||
|
CHECK_STATUS(m_abort, ok);
|
||||||
|
break;
|
||||||
|
case INPUT_VAPOUR:
|
||||||
|
ok = checkPropertiesVapoursynth(QString("%1/vspipe.exe").arg(m_vpsDir), frames);
|
||||||
|
CHECK_STATUS(m_abort, ok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Run encoding passes
|
//Run encoding passes
|
||||||
@ -287,17 +310,17 @@ void EncodeThread::encode(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
log(tr("\n--- PASS 1 ---\n"));
|
log(tr("\n--- PASS 1 ---\n"));
|
||||||
ok = runEncodingPass(m_x264_x64, m_x264_10bit, m_avs2yuv_x64, usePipe, frames, indexFile, 1, passLogFile);
|
ok = runEncodingPass(m_x264_x64, m_x264_10bit, m_avs2yuv_x64, inputType, frames, indexFile, 1, passLogFile);
|
||||||
CHECK_STATUS(m_abort, ok);
|
CHECK_STATUS(m_abort, ok);
|
||||||
|
|
||||||
log(tr("\n--- PASS 2 ---\n"));
|
log(tr("\n--- PASS 2 ---\n"));
|
||||||
ok = runEncodingPass(m_x264_x64, m_x264_10bit, m_avs2yuv_x64, usePipe, frames, indexFile, 2, passLogFile);
|
ok = runEncodingPass(m_x264_x64, m_x264_10bit, m_avs2yuv_x64, inputType, frames, indexFile, 2, passLogFile);
|
||||||
CHECK_STATUS(m_abort, ok);
|
CHECK_STATUS(m_abort, ok);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log(tr("\n--- ENCODING ---\n"));
|
log(tr("\n--- ENCODING ---\n"));
|
||||||
ok = runEncodingPass(m_x264_x64, m_x264_10bit, m_avs2yuv_x64, usePipe, frames, indexFile);
|
ok = runEncodingPass(m_x264_x64, m_x264_10bit, m_avs2yuv_x64, inputType, frames, indexFile);
|
||||||
CHECK_STATUS(m_abort, ok);
|
CHECK_STATUS(m_abort, ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,29 +331,44 @@ void EncodeThread::encode(void)
|
|||||||
setStatus(JobStatus_Completed);
|
setStatus(JobStatus_Completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_x64, bool usePipe, unsigned int frames, const QString &indexFile, int pass, const QString &passLogFile)
|
bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_x64, int inputType, unsigned int frames, const QString &indexFile, int pass, const QString &passLogFile)
|
||||||
{
|
{
|
||||||
QProcess processEncode, processAvisynth;
|
QProcess processEncode, processInput;
|
||||||
|
|
||||||
if(usePipe)
|
if(inputType != INPUT_NATIVE)
|
||||||
{
|
{
|
||||||
QStringList cmdLine_Avisynth;
|
QStringList cmdLine_Input;
|
||||||
if(!m_options->customAvs2YUV().isEmpty())
|
processInput.setStandardOutputProcess(&processEncode);
|
||||||
|
switch(inputType)
|
||||||
{
|
{
|
||||||
cmdLine_Avisynth.append(splitParams(m_options->customAvs2YUV()));
|
case INPUT_AVISYN:
|
||||||
}
|
if(!m_options->customAvs2YUV().isEmpty())
|
||||||
cmdLine_Avisynth << pathToLocal(QDir::toNativeSeparators(m_sourceFileName));
|
{
|
||||||
cmdLine_Avisynth << "-";
|
cmdLine_Input.append(splitParams(m_options->customAvs2YUV()));
|
||||||
processAvisynth.setStandardOutputProcess(&processEncode);
|
}
|
||||||
|
cmdLine_Input << pathToLocal(QDir::toNativeSeparators(m_sourceFileName));
|
||||||
log("Creating Avisynth process:");
|
cmdLine_Input << "-";
|
||||||
if(!startProcess(processAvisynth, AVS2_BINARY(m_binDir, avs2yuv_x64), cmdLine_Avisynth, false))
|
log("Creating Avisynth process:");
|
||||||
{
|
if(!startProcess(processInput, AVS2_BINARY(m_binDir, avs2yuv_x64), cmdLine_Input, false))
|
||||||
return false;
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case INPUT_VAPOUR:
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw "Bad input type encontered!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList cmdLine_Encode = buildCommandLine(usePipe, x264_10bit, frames, indexFile, pass, passLogFile);
|
QStringList cmdLine_Encode = buildCommandLine((inputType != INPUT_NATIVE), x264_10bit, frames, indexFile, pass, passLogFile);
|
||||||
|
|
||||||
log("Creating x264 process:");
|
log("Creating x264 process:");
|
||||||
if(!startProcess(processEncode, X264_BINARY(m_binDir, x264_10bit, x264_x64), cmdLine_Encode))
|
if(!startProcess(processEncode, X264_BINARY(m_binDir, x264_10bit, x264_x64), cmdLine_Encode))
|
||||||
@ -362,7 +400,7 @@ bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_
|
|||||||
if(m_abort)
|
if(m_abort)
|
||||||
{
|
{
|
||||||
processEncode.kill();
|
processEncode.kill();
|
||||||
processAvisynth.kill();
|
processInput.kill();
|
||||||
bAborted = true;
|
bAborted = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -372,7 +410,7 @@ bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_
|
|||||||
setStatus(JobStatus_Paused);
|
setStatus(JobStatus_Paused);
|
||||||
log(tr("Job paused by user at %1, %2.").arg(QDate::currentDate().toString(Qt::ISODate), QTime::currentTime().toString( Qt::ISODate)));
|
log(tr("Job paused by user at %1, %2.").arg(QDate::currentDate().toString(Qt::ISODate), QTime::currentTime().toString( Qt::ISODate)));
|
||||||
bool ok[2] = {false, false};
|
bool ok[2] = {false, false};
|
||||||
Q_PID pid[2] = {processEncode.pid(), processAvisynth.pid()};
|
Q_PID pid[2] = {processEncode.pid(), processInput.pid()};
|
||||||
if(pid[0]) { ok[0] = (SuspendThread(pid[0]->hThread) != (DWORD)(-1)); }
|
if(pid[0]) { ok[0] = (SuspendThread(pid[0]->hThread) != (DWORD)(-1)); }
|
||||||
if(pid[1]) { ok[1] = (SuspendThread(pid[1]->hThread) != (DWORD)(-1)); }
|
if(pid[1]) { ok[1] = (SuspendThread(pid[1]->hThread) != (DWORD)(-1)); }
|
||||||
while(m_pause) m_semaphorePaused.tryAcquire(1, 5000);
|
while(m_pause) m_semaphorePaused.tryAcquire(1, 5000);
|
||||||
@ -475,27 +513,35 @@ bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_
|
|||||||
processEncode.waitForFinished(-1);
|
processEncode.waitForFinished(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
processAvisynth.waitForFinished(5000);
|
processInput.waitForFinished(5000);
|
||||||
if(processAvisynth.state() != QProcess::NotRunning)
|
if(processInput.state() != QProcess::NotRunning)
|
||||||
{
|
{
|
||||||
qWarning("Avisynth process still running, going to kill it!");
|
qWarning("Input process still running, going to kill it!");
|
||||||
processAvisynth.kill();
|
processInput.kill();
|
||||||
processAvisynth.waitForFinished(-1);
|
processInput.waitForFinished(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(bTimeout || bAborted))
|
if(!(bTimeout || bAborted))
|
||||||
{
|
{
|
||||||
while(processAvisynth.bytesAvailable() > 0)
|
while(processInput.bytesAvailable() > 0)
|
||||||
{
|
{
|
||||||
log(tr("av2y [info]: %1").arg(QString::fromUtf8(processAvisynth.readLine()).simplified()));
|
switch(inputType)
|
||||||
|
{
|
||||||
|
case INPUT_AVISYN:
|
||||||
|
log(tr("av2y [info]: %1").arg(QString::fromUtf8(processInput.readLine()).simplified()));
|
||||||
|
break;
|
||||||
|
case INPUT_VAPOUR:
|
||||||
|
log(tr("vpyp [info]: %1").arg(QString::fromUtf8(processInput.readLine()).simplified()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(usePipe && (processAvisynth.exitCode() != EXIT_SUCCESS))
|
if((inputType != INPUT_NATIVE) && (processInput.exitCode() != EXIT_SUCCESS))
|
||||||
{
|
{
|
||||||
if(!(bTimeout || bAborted))
|
if(!(bTimeout || bAborted))
|
||||||
{
|
{
|
||||||
log(tr("\nWARNING: Avisynth process exited with error code: %1").arg(QString::number(processAvisynth.exitCode())));
|
log(tr("\nWARNING: Input process exited with error code: %1").arg(QString::number(processInput.exitCode())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,7 +552,7 @@ bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_
|
|||||||
log(tr("\nPROCESS EXITED WITH ERROR CODE: %1").arg(QString::number(processEncode.exitCode())));
|
log(tr("\nPROCESS EXITED WITH ERROR CODE: %1").arg(QString::number(processEncode.exitCode())));
|
||||||
}
|
}
|
||||||
processEncode.close();
|
processEncode.close();
|
||||||
processAvisynth.close();
|
processInput.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +580,7 @@ bool EncodeThread::runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_
|
|||||||
|
|
||||||
setProgress(100);
|
setProgress(100);
|
||||||
processEncode.close();
|
processEncode.close();
|
||||||
processAvisynth.close();
|
processInput.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,7 +877,86 @@ unsigned int EncodeThread::checkVersionAvs2yuv(bool x64)
|
|||||||
return (ver_maj * REV_MULT) + ((ver_min % REV_MULT) * 10) + (ver_mod % 10);
|
return (ver_maj * REV_MULT) + ((ver_min % REV_MULT) * 10) + (ver_mod % 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EncodeThread::checkProperties(bool x64, unsigned int &frames)
|
bool EncodeThread::checkVersionVapoursynth(const QString &vspipePath)
|
||||||
|
{
|
||||||
|
QProcess process;
|
||||||
|
|
||||||
|
log("\nCreating process:");
|
||||||
|
if(!startProcess(process, vspipePath, QStringList()))
|
||||||
|
{
|
||||||
|
return false;;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegExp regExpSignature("\\bVSPipe\\s+usage\\b", Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
bool bTimeout = false;
|
||||||
|
bool bAborted = false;
|
||||||
|
|
||||||
|
bool vspipeSignature = false;
|
||||||
|
|
||||||
|
while(process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
if(m_abort)
|
||||||
|
{
|
||||||
|
process.kill();
|
||||||
|
bAborted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!process.waitForReadyRead())
|
||||||
|
{
|
||||||
|
if(process.state() == QProcess::Running)
|
||||||
|
{
|
||||||
|
process.kill();
|
||||||
|
qWarning("VSPipe process timed out <-- killing!");
|
||||||
|
log("\nPROCESS TIMEOUT !!!");
|
||||||
|
bTimeout = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(process.bytesAvailable() > 0)
|
||||||
|
{
|
||||||
|
QList<QByteArray> lines = process.readLine().split('\r');
|
||||||
|
while(!lines.isEmpty())
|
||||||
|
{
|
||||||
|
QString text = QString::fromUtf8(lines.takeFirst().constData()).simplified();
|
||||||
|
if(regExpSignature.lastIndexIn(text) >= 0)
|
||||||
|
{
|
||||||
|
vspipeSignature = true;
|
||||||
|
}
|
||||||
|
if(!text.isEmpty())
|
||||||
|
{
|
||||||
|
log(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process.waitForFinished();
|
||||||
|
if(process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
process.kill();
|
||||||
|
process.waitForFinished(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bTimeout || bAborted || ((process.exitCode() != EXIT_SUCCESS) && (process.exitCode() != 1)))
|
||||||
|
{
|
||||||
|
if(!(bTimeout || bAborted))
|
||||||
|
{
|
||||||
|
log(tr("\nPROCESS EXITED WITH ERROR CODE: %1").arg(QString::number(process.exitCode())));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!vspipeSignature)
|
||||||
|
{
|
||||||
|
log(tr("\nFAILED TO DETECT VSPIPE SIGNATURE !!!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vspipeSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EncodeThread::checkPropertiesAvisynth(bool x64, unsigned int &frames)
|
||||||
{
|
{
|
||||||
QProcess process;
|
QProcess process;
|
||||||
QStringList cmdLine;
|
QStringList cmdLine;
|
||||||
@ -994,6 +1119,137 @@ bool EncodeThread::checkProperties(bool x64, unsigned int &frames)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EncodeThread::checkPropertiesVapoursynth(const QString &vspipePath, unsigned int &frames)
|
||||||
|
{
|
||||||
|
QProcess process;
|
||||||
|
QStringList cmdLine;
|
||||||
|
|
||||||
|
cmdLine << pathToLocal(QDir::toNativeSeparators(m_sourceFileName));
|
||||||
|
cmdLine << "-" << "-info";
|
||||||
|
|
||||||
|
log("Creating process:");
|
||||||
|
if(!startProcess(process, vspipePath, cmdLine))
|
||||||
|
{
|
||||||
|
return false;;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegExp regExpFrm("\\bFrames:\\s+(\\d+)\\b");
|
||||||
|
QRegExp regExpSzW("\\bWidth:\\s+(\\d+)\\b");
|
||||||
|
QRegExp regExpSzH("\\bHeight:\\s+(\\d+)\\b");
|
||||||
|
|
||||||
|
QTextCodec *localCodec = QTextCodec::codecForName("System");
|
||||||
|
|
||||||
|
bool bTimeout = false;
|
||||||
|
bool bAborted = false;
|
||||||
|
|
||||||
|
frames = 0;
|
||||||
|
|
||||||
|
unsigned int fSizeW = 0;
|
||||||
|
unsigned int fSizeH = 0;
|
||||||
|
|
||||||
|
unsigned int waitCounter = 0;
|
||||||
|
|
||||||
|
while(process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
if(m_abort)
|
||||||
|
{
|
||||||
|
process.kill();
|
||||||
|
bAborted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!process.waitForReadyRead(m_processTimeoutInterval))
|
||||||
|
{
|
||||||
|
if(process.state() == QProcess::Running)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else if(waitCounter == m_processTimeoutWarning)
|
||||||
|
{
|
||||||
|
unsigned int timeOut = (waitCounter * m_processTimeoutInterval) / 1000U;
|
||||||
|
log(tr("Warning: nVapoursynth did not respond for %1 seconds, potential deadlock...").arg(QString::number(timeOut)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitCounter = 0;
|
||||||
|
|
||||||
|
while(process.bytesAvailable() > 0)
|
||||||
|
{
|
||||||
|
QList<QByteArray> lines = process.readLine().split('\r');
|
||||||
|
while(!lines.isEmpty())
|
||||||
|
{
|
||||||
|
QString text = localCodec->toUnicode(lines.takeFirst().constData()).simplified();
|
||||||
|
int offset = -1;
|
||||||
|
if((offset = regExpFrm.lastIndexIn(text)) >= 0)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
unsigned int temp = regExpFrm.cap(1).toUInt(&ok);
|
||||||
|
if(ok) frames = temp;
|
||||||
|
}
|
||||||
|
if((offset = regExpSzW.lastIndexIn(text)) >= 0)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
unsigned int temp = regExpSzW.cap(1).toUInt(&ok);
|
||||||
|
if(ok) fSizeW = temp;
|
||||||
|
}
|
||||||
|
if((offset = regExpSzH.lastIndexIn(text)) >= 0)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
unsigned int temp = regExpSzH.cap(1).toUInt(&ok);
|
||||||
|
if(ok) fSizeH = temp;
|
||||||
|
}
|
||||||
|
if(!text.isEmpty())
|
||||||
|
{
|
||||||
|
log(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process.waitForFinished();
|
||||||
|
if(process.state() != QProcess::NotRunning)
|
||||||
|
{
|
||||||
|
process.kill();
|
||||||
|
process.waitForFinished(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
|
||||||
|
{
|
||||||
|
if(!(bTimeout || bAborted))
|
||||||
|
{
|
||||||
|
log(tr("\nPROCESS EXITED WITH ERROR CODE: %1").arg(QString::number(process.exitCode())));
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(frames == 0)
|
||||||
|
{
|
||||||
|
log(tr("\nFAILED TO DETERMINE VPY PROPERTIES !!!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("");
|
||||||
|
|
||||||
|
if((fSizeW > 0) && (fSizeH > 0))
|
||||||
|
{
|
||||||
|
log(tr("Resolution: %1x%2").arg(QString::number(fSizeW), QString::number(fSizeH)));
|
||||||
|
}
|
||||||
|
if(frames > 0)
|
||||||
|
{
|
||||||
|
log(tr("No. Frames: %1").arg(QString::number(frames)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Misc functions
|
// Misc functions
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -1220,6 +1476,16 @@ QString EncodeThread::sizeToString(qint64 size)
|
|||||||
return tr("N/A");
|
return tr("N/A");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EncodeThread::getInputType(const QString &fileExt)
|
||||||
|
{
|
||||||
|
int type = INPUT_NATIVE;
|
||||||
|
if(fileExt.compare("avs", Qt::CaseInsensitive) == 0) type = INPUT_AVISYN;
|
||||||
|
else if(fileExt.compare("avsi", Qt::CaseInsensitive) == 0) type = INPUT_AVISYN;
|
||||||
|
else if(fileExt.compare("vpy", Qt::CaseInsensitive) == 0) type = INPUT_VAPOUR;
|
||||||
|
else if(fileExt.compare("py", Qt::CaseInsensitive) == 0) type = INPUT_VAPOUR;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
void EncodeThread::setPorcessPriority(void *processId, int priroity)
|
void EncodeThread::setPorcessPriority(void *processId, int priroity)
|
||||||
{
|
{
|
||||||
switch(priroity)
|
switch(priroity)
|
||||||
|
@ -37,7 +37,7 @@ class EncodeThread : public QThread
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EncodeThread(const QString &sourceFileName, const QString &outputFileName, const OptionsModel *options, const QString &binDir, 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, bool x264_x64, bool x264_10bit, bool avs2yuv_x64, bool const skipVersionTest, int processPriroity);
|
||||||
~EncodeThread(void);
|
~EncodeThread(void);
|
||||||
|
|
||||||
QUuid getId(void) { return this->m_jobId; };
|
QUuid getId(void) { return this->m_jobId; };
|
||||||
@ -73,12 +73,21 @@ protected:
|
|||||||
const QString m_outputFileName;
|
const QString m_outputFileName;
|
||||||
const OptionsModel *m_options;
|
const OptionsModel *m_options;
|
||||||
const QString m_binDir;
|
const QString m_binDir;
|
||||||
|
const QString m_vpsDir;
|
||||||
const bool m_x264_x64;
|
const bool m_x264_x64;
|
||||||
const bool m_x264_10bit;
|
const bool m_x264_10bit;
|
||||||
const bool m_avs2yuv_x64;
|
const bool m_avs2yuv_x64;
|
||||||
const bool m_skipVersionTest;
|
const bool m_skipVersionTest;
|
||||||
const int m_processPriority;
|
const int m_processPriority;
|
||||||
|
|
||||||
|
//Types
|
||||||
|
enum inputType_t
|
||||||
|
{
|
||||||
|
INPUT_NATIVE = 0,
|
||||||
|
INPUT_AVISYN = 1,
|
||||||
|
INPUT_VAPOUR = 2
|
||||||
|
};
|
||||||
|
|
||||||
//Flags
|
//Flags
|
||||||
volatile bool m_abort;
|
volatile bool m_abort;
|
||||||
volatile bool m_pause;
|
volatile bool m_pause;
|
||||||
@ -99,11 +108,13 @@ protected:
|
|||||||
|
|
||||||
//Encode functions
|
//Encode functions
|
||||||
void encode(void);
|
void encode(void);
|
||||||
bool runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_x64, bool usePipe, unsigned int frames, const QString &indexFile, int pass = 0, const QString &passLogFile = QString());
|
bool runEncodingPass(bool x264_x64, bool x264_10bit, bool avs2yuv_x64, int inputType, unsigned int frames, const QString &indexFile, int pass = 0, const QString &passLogFile = QString());
|
||||||
QStringList buildCommandLine(bool usePipe, bool use10Bit, unsigned int frames, const QString &indexFile, int pass = 0, const QString &passLogFile = QString());
|
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 checkVersionX264(bool use_x64, bool use_10bit, bool &modified);
|
||||||
unsigned int checkVersionAvs2yuv(bool x64);
|
unsigned int checkVersionAvs2yuv(bool x64);
|
||||||
bool checkProperties(bool x64, unsigned int &frames);
|
bool checkVersionVapoursynth(const QString &vspipePath);
|
||||||
|
bool checkPropertiesAvisynth(bool x64, unsigned int &frames);
|
||||||
|
bool checkPropertiesVapoursynth(const QString &vspipePath, unsigned int &frames);
|
||||||
|
|
||||||
//Auxiallary Stuff
|
//Auxiallary Stuff
|
||||||
void log(const QString &text) { emit messageLogged(m_jobId, text); }
|
void log(const QString &text) { emit messageLogged(m_jobId, text); }
|
||||||
@ -119,6 +130,7 @@ protected:
|
|||||||
static QString commandline2string(const QString &program, const QStringList &arguments);
|
static QString commandline2string(const QString &program, const QStringList &arguments);
|
||||||
static QString sizeToString(qint64 size);
|
static QString sizeToString(qint64 size);
|
||||||
static void setPorcessPriority(void *processId, int priroity);
|
static void setPorcessPriority(void *processId, int priroity);
|
||||||
|
static int getInputType(const QString &fileExt);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void statusChanged(const QUuid &jobId, JobStatus newStatus);
|
void statusChanged(const QUuid &jobId, JobStatus newStatus);
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
#define VER_X264_MAJOR 2
|
#define VER_X264_MAJOR 2
|
||||||
#define VER_X264_MINOR 1
|
#define VER_X264_MINOR 1
|
||||||
#define VER_X264_PATCH 7
|
#define VER_X264_PATCH 8
|
||||||
#define VER_X264_BUILD 519
|
#define VER_X264_BUILD 530
|
||||||
|
|
||||||
#define VER_X264_MINIMUM_REV 2339
|
#define VER_X264_MINIMUM_REV 2339
|
||||||
#define VER_X264_CURRENT_API 135
|
#define VER_X264_CURRENT_API 135
|
||||||
|
@ -958,6 +958,7 @@ QString AddJobDialog::getInputFilterLst(void)
|
|||||||
s_filters[] =
|
s_filters[] =
|
||||||
{
|
{
|
||||||
{"Avisynth Scripts", "avs"},
|
{"Avisynth Scripts", "avs"},
|
||||||
|
{"VapourSynth Scripts", "vpy"},
|
||||||
{"Matroska Files", "mkv"},
|
{"Matroska Files", "mkv"},
|
||||||
{"MPEG-4 Part 14 Container", "mp4"},
|
{"MPEG-4 Part 14 Container", "mp4"},
|
||||||
{"Audio Video Interleaved", "avi"},
|
{"Audio Video Interleaved", "avi"},
|
||||||
|
@ -820,7 +820,7 @@ void MainWindow::init(void)
|
|||||||
if(okay)
|
if(okay)
|
||||||
{
|
{
|
||||||
qDebug("VapourSynth support enabled.");
|
qDebug("VapourSynth support enabled.");
|
||||||
m_vapoursynthPath = QFileInfo(vpsExePath->fileName()).canonicalFilePath();
|
m_vapoursynthPath = QFileInfo(vpsExePath->fileName()).canonicalPath();
|
||||||
m_toolsList << vpsExePath;
|
m_toolsList << vpsExePath;
|
||||||
m_toolsList << vpsDllPath;
|
m_toolsList << vpsDllPath;
|
||||||
}
|
}
|
||||||
@ -1164,6 +1164,7 @@ bool MainWindow::appendJob(const QString &sourceFileName, const QString &outputF
|
|||||||
outputFileName,
|
outputFileName,
|
||||||
options,
|
options,
|
||||||
QString("%1/toolset").arg(m_appDir),
|
QString("%1/toolset").arg(m_appDir),
|
||||||
|
m_vapoursynthPath,
|
||||||
m_cpuFeatures->x64,
|
m_cpuFeatures->x64,
|
||||||
m_preferences->use10BitEncoding(),
|
m_preferences->use10BitEncoding(),
|
||||||
m_cpuFeatures->x64 && m_preferences->useAvisyth64Bit(),
|
m_cpuFeatures->x64 && m_preferences->useAvisyth64Bit(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user