Fixed the use of the "m_abort" and "m_pause" flags. Also various fixes to encoder output parsing.

This commit is contained in:
LoRd_MuldeR 2014-02-25 23:52:10 +01:00
parent 6279ee6b58
commit 65e7bc32e0
5 changed files with 126 additions and 35 deletions

View File

@ -38,6 +38,10 @@
#include <QThread> #include <QThread>
#include <QLocale> #include <QLocale>
// ------------------------------------------------------------
// Helper Macros
// ------------------------------------------------------------
#define APPEND_AND_CLEAR(LIST, STR) do \ #define APPEND_AND_CLEAR(LIST, STR) do \
{ \ { \
if(!((STR).isEmpty())) \ if(!((STR).isEmpty())) \
@ -48,6 +52,24 @@
} \ } \
while(0) while(0)
#define PROCESS_PENDING_LINES(PROC, HANDLER, ...) do \
{ \
while((PROC).bytesAvailable() > 0) \
{ \
QList<QByteArray> lines = (PROC).readLine().split('\r'); \
while(!lines.isEmpty()) \
{ \
const QString text = QString::fromUtf8(lines.takeFirst().constData()).simplified(); \
HANDLER(text, __VA_ARGS__); \
} \
} \
} \
while(0)
// ------------------------------------------------------------
// Constructor & Destructor
// ------------------------------------------------------------
AbstractEncoder::AbstractEncoder(JobObject *jobObject, const OptionsModel *options, const SysinfoModel *const sysinfo, const PreferencesModel *const preferences, JobStatus &jobStatus, volatile bool *abort, volatile bool *pause, QSemaphore *semaphorePause, const QString &sourceFile, const QString &outputFile) AbstractEncoder::AbstractEncoder(JobObject *jobObject, const OptionsModel *options, const SysinfoModel *const sysinfo, const PreferencesModel *const preferences, JobStatus &jobStatus, volatile bool *abort, volatile bool *pause, QSemaphore *semaphorePause, const QString &sourceFile, const QString &outputFile)
: :
AbstractTool(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause), AbstractTool(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause),
@ -63,6 +85,10 @@ AbstractEncoder::~AbstractEncoder(void)
/*Nothing to do here*/ /*Nothing to do here*/
} }
// ------------------------------------------------------------
// Encoding Functions
// ------------------------------------------------------------
bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString outputFile, const unsigned int &frames, const int &pass, const QString &passLogFile) bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString outputFile, const unsigned int &frames, const int &pass, const QString &passLogFile)
{ {
QProcess processEncode, processInput; QProcess processEncode, processInput;
@ -84,8 +110,6 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
QList<QRegExp*> patterns; QList<QRegExp*> patterns;
runEncodingPass_init(patterns); runEncodingPass_init(patterns);
QTextCodec *localCodec = QTextCodec::codecForName("System");
bool bTimeout = false; bool bTimeout = false;
bool bAborted = false; bool bAborted = false;
@ -101,14 +125,14 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
//Wait until new output is available //Wait until new output is available
forever forever
{ {
if(m_abort) if(*m_abort)
{ {
processEncode.kill(); processEncode.kill();
processInput.kill(); processInput.kill();
bAborted = true; bAborted = true;
break; break;
} }
if(m_pause && (processEncode.state() == QProcess::Running)) if((*m_pause) && (processEncode.state() == QProcess::Running))
{ {
JobStatus previousStatus = m_jobStatus; JobStatus previousStatus = m_jobStatus;
setStatus(JobStatus_Paused); setStatus(JobStatus_Paused);
@ -117,11 +141,11 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
QProcess *proc[2] = { &processEncode, &processInput }; QProcess *proc[2] = { &processEncode, &processInput };
ok[0] = x264_suspendProcess(proc[0], true); ok[0] = x264_suspendProcess(proc[0], true);
ok[1] = x264_suspendProcess(proc[1], true); ok[1] = x264_suspendProcess(proc[1], true);
while(m_pause) m_semaphorePause->tryAcquire(1, 5000); while(*m_pause) m_semaphorePause->tryAcquire(1, 5000);
while(m_semaphorePause->tryAcquire(1, 0)); while(m_semaphorePause->tryAcquire(1, 0));
ok[0] = x264_suspendProcess(proc[0], false); ok[0] = x264_suspendProcess(proc[0], false);
ok[1] = x264_suspendProcess(proc[1], false); ok[1] = x264_suspendProcess(proc[1], false);
if(!m_abort) setStatus(previousStatus); if(!(*m_abort)) setStatus(previousStatus);
log(tr("Job resumed by user at %1, %2.").arg(QDate::currentDate().toString(Qt::ISODate), QTime::currentTime().toString( Qt::ISODate))); log(tr("Job resumed by user at %1, %2.").arg(QDate::currentDate().toString(Qt::ISODate), QTime::currentTime().toString( Qt::ISODate)));
waitCounter = 0; waitCounter = 0;
continue; continue;
@ -149,7 +173,7 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
continue; continue;
} }
} }
if(m_abort || (m_pause && (processEncode.state() == QProcess::Running))) if((*m_abort) || ((*m_pause) && (processEncode.state() == QProcess::Running)))
{ {
continue; continue;
} }
@ -163,15 +187,12 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
} }
//Process all output //Process all output
while(processEncode.bytesAvailable() > 0) PROCESS_PENDING_LINES(processEncode, runEncodingPass_parseLine, patterns, pass);
{
QList<QByteArray> lines = processEncode.readLine().split('\r');
while(!lines.isEmpty())
{
const QString text = localCodec->toUnicode(lines.takeFirst().constData()).simplified();
runEncodingPass_parseLine(text, patterns, pass);
}
} }
if(!(bTimeout || bAborted))
{
PROCESS_PENDING_LINES(processEncode, runEncodingPass_parseLine, patterns, pass);
} }
processEncode.waitForFinished(5000); processEncode.waitForFinished(5000);
@ -243,6 +264,10 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
return true; return true;
} }
// ------------------------------------------------------------
// Utilities
// ------------------------------------------------------------
QStringList AbstractEncoder::splitParams(const QString &params, const QString &sourceFile, const QString &outputFile) QStringList AbstractEncoder::splitParams(const QString &params, const QString &sourceFile, const QString &outputFile)
{ {
QStringList list; QStringList list;

View File

@ -33,6 +33,10 @@
static const unsigned int X264_VERSION_X264_MINIMUM_REV = 2380; static const unsigned int X264_VERSION_X264_MINIMUM_REV = 2380;
static const unsigned int X264_VERSION_X264_CURRENT_API = 142; static const unsigned int X264_VERSION_X264_CURRENT_API = 142;
// ------------------------------------------------------------
// Helper Macros
// ------------------------------------------------------------
#define REMOVE_CUSTOM_ARG(LIST, ITER, FLAG, PARAM) do \ #define REMOVE_CUSTOM_ARG(LIST, ITER, FLAG, PARAM) do \
{ \ { \
if(ITER != LIST.end()) \ if(ITER != LIST.end()) \
@ -65,6 +69,10 @@ while(0)
} \ } \
while(0) while(0)
// ------------------------------------------------------------
// Constructor & Destructor
// ------------------------------------------------------------
X264Encoder::X264Encoder(JobObject *jobObject, const OptionsModel *options, const SysinfoModel *const sysinfo, const PreferencesModel *const preferences, JobStatus &jobStatus, volatile bool *abort, volatile bool *pause, QSemaphore *semaphorePause, const QString &sourceFile, const QString &outputFile) X264Encoder::X264Encoder(JobObject *jobObject, const OptionsModel *options, const SysinfoModel *const sysinfo, const PreferencesModel *const preferences, JobStatus &jobStatus, volatile bool *abort, volatile bool *pause, QSemaphore *semaphorePause, const QString &sourceFile, const QString &outputFile)
: :
AbstractEncoder(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause, sourceFile, outputFile), AbstractEncoder(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause, sourceFile, outputFile),
@ -81,6 +89,10 @@ X264Encoder::~X264Encoder(void)
/*Nothing to do here*/ /*Nothing to do here*/
} }
// ------------------------------------------------------------
// Check Version
// ------------------------------------------------------------
void X264Encoder::checkVersion_init(QList<QRegExp*> &patterns, QStringList &cmdLine) void X264Encoder::checkVersion_init(QList<QRegExp*> &patterns, QStringList &cmdLine)
{ {
cmdLine << "--version"; cmdLine << "--version";
@ -132,6 +144,10 @@ bool X264Encoder::isVersionSupported(const unsigned int &revision, const bool &m
return true; return true;
} }
// ------------------------------------------------------------
// Encoding Functions
// ------------------------------------------------------------
void X264Encoder::buildCommandLine(QStringList &cmdLine, const bool &usePipe, const unsigned int &frames, const QString &indexFile, const int &pass, const QString &passLogFile) void X264Encoder::buildCommandLine(QStringList &cmdLine, const bool &usePipe, const unsigned int &frames, const QString &indexFile, const int &pass, const QString &passLogFile)
{ {
double crf_int = 0.0, crf_frc = 0.0; double crf_int = 0.0, crf_frc = 0.0;
@ -210,14 +226,16 @@ void X264Encoder::buildCommandLine(QStringList &cmdLine, const bool &usePipe, co
void X264Encoder::runEncodingPass_init(QList<QRegExp*> &patterns) void X264Encoder::runEncodingPass_init(QList<QRegExp*> &patterns)
{ {
patterns << new QRegExp("\\[(\\d+)\\.(\\d+)%\\].+frames"); //regExpProgress patterns << new QRegExp("\\[(\\d+)\\.(\\d+)%\\].+frames");
patterns << new QRegExp("indexing.+\\[(\\d+)\\.(\\d+)%\\]"); //regExpIndexing patterns << new QRegExp("indexing.+\\[(\\d+)\\.(\\d+)%\\]");
patterns << new QRegExp("^(\\d+) frames:"); //regExpFrameCnt patterns << new QRegExp("^(\\d+) frames:");
patterns << new QRegExp("\\[\\s*(\\d+)\\.(\\d+)%\\]\\s+(\\d+)/(\\d+)\\s(\\d+).(\\d+)\\s(\\d+).(\\d+)\\s+(\\d+):(\\d+):(\\d+)\\s+(\\d+):(\\d+):(\\d+)"); //regExpModified patterns << new QRegExp("\\[\\s*(\\d+)\\.(\\d+)%\\]\\s+(\\d+)/(\\d+)\\s(\\d+).(\\d+)\\s(\\d+).(\\d+)\\s+(\\d+):(\\d+):(\\d+)\\s+(\\d+):(\\d+):(\\d+)"); //regExpModified
} }
void X264Encoder::runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const int &pass) void X264Encoder::runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const int &pass)
{ {
log(tr("PARSE: \"%1\"").arg(line));
int offset = -1; int offset = -1;
if((offset = patterns[0]->lastIndexIn(line)) >= 0) if((offset = patterns[0]->lastIndexIn(line)) >= 0)
{ {

View File

@ -34,6 +34,10 @@
static const unsigned int X265_VERSION_X264_MINIMUM_VER = 7; static const unsigned int X265_VERSION_X264_MINIMUM_VER = 7;
static const unsigned int X265_VERSION_X264_MINIMUM_REV = 167; static const unsigned int X265_VERSION_X264_MINIMUM_REV = 167;
// ------------------------------------------------------------
// Helper Macros
// ------------------------------------------------------------
#define X264_UPDATE_PROGRESS(X) do \ #define X264_UPDATE_PROGRESS(X) do \
{ \ { \
bool ok = false; qint64 size_estimate = 0; \ bool ok = false; qint64 size_estimate = 0; \
@ -66,6 +70,10 @@ while(0)
} \ } \
while(0) while(0)
// ------------------------------------------------------------
// Constructor & Destructor
// ------------------------------------------------------------
X265Encoder::X265Encoder(JobObject *jobObject, const OptionsModel *options, const SysinfoModel *const sysinfo, const PreferencesModel *const preferences, JobStatus &jobStatus, volatile bool *abort, volatile bool *pause, QSemaphore *semaphorePause, const QString &sourceFile, const QString &outputFile) X265Encoder::X265Encoder(JobObject *jobObject, const OptionsModel *options, const SysinfoModel *const sysinfo, const PreferencesModel *const preferences, JobStatus &jobStatus, volatile bool *abort, volatile bool *pause, QSemaphore *semaphorePause, const QString &sourceFile, const QString &outputFile)
: :
AbstractEncoder(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause, sourceFile, outputFile), AbstractEncoder(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause, sourceFile, outputFile),
@ -82,6 +90,10 @@ X265Encoder::~X265Encoder(void)
/*Nothing to do here*/ /*Nothing to do here*/
} }
// ------------------------------------------------------------
// Check Version
// ------------------------------------------------------------
void X265Encoder::checkVersion_init(QList<QRegExp*> &patterns, QStringList &cmdLine) void X265Encoder::checkVersion_init(QList<QRegExp*> &patterns, QStringList &cmdLine)
{ {
cmdLine << "--version"; cmdLine << "--version";
@ -120,6 +132,10 @@ bool X265Encoder::isVersionSupported(const unsigned int &revision, const bool &m
return true; return true;
} }
// ------------------------------------------------------------
// Encoding Functions
// ------------------------------------------------------------
void X265Encoder::buildCommandLine(QStringList &cmdLine, const bool &usePipe, const unsigned int &frames, const QString &indexFile, const int &pass, const QString &passLogFile) void X265Encoder::buildCommandLine(QStringList &cmdLine, const bool &usePipe, const unsigned int &frames, const QString &indexFile, const int &pass, const QString &passLogFile)
{ {
double crf_int = 0.0, crf_frc = 0.0; double crf_int = 0.0, crf_frc = 0.0;

View File

@ -35,6 +35,32 @@
QMutex AbstractTool::s_mutexStartProcess; QMutex AbstractTool::s_mutexStartProcess;
// ------------------------------------------------------------
// Helper Macros
// ------------------------------------------------------------
#define PROCESS_PENDING_LINES(PROC, HANDLER, ...) do \
{ \
while((PROC).bytesAvailable() > 0) \
{ \
QList<QByteArray> lines = (PROC).readLine().split('\r'); \
while(!lines.isEmpty()) \
{ \
const QString text = QString::fromUtf8(lines.takeFirst().constData()).simplified(); \
HANDLER(text, __VA_ARGS__); \
if(!text.isEmpty()) \
{ \
log(text); \
} \
} \
} \
} \
while(0)
// ------------------------------------------------------------
// Constructor & Destructor
// ------------------------------------------------------------
AbstractTool::AbstractTool(JobObject *jobObject, const OptionsModel *options, const SysinfoModel *const sysinfo, const PreferencesModel *const preferences, JobStatus &jobStatus, volatile bool *abort, volatile bool *pause, QSemaphore *semaphorePause) AbstractTool::AbstractTool(JobObject *jobObject, const OptionsModel *options, const SysinfoModel *const sysinfo, const PreferencesModel *const preferences, JobStatus &jobStatus, volatile bool *abort, volatile bool *pause, QSemaphore *semaphorePause)
: :
m_jobObject(jobObject), m_jobObject(jobObject),
@ -49,6 +75,10 @@ AbstractTool::AbstractTool(JobObject *jobObject, const OptionsModel *options, co
/*nothing to do here*/ /*nothing to do here*/
} }
// ------------------------------------------------------------
// Check Version
// ------------------------------------------------------------
unsigned int AbstractTool::checkVersion(bool &modified) unsigned int AbstractTool::checkVersion(bool &modified)
{ {
if(m_preferences->getSkipVersionTest()) if(m_preferences->getSkipVersionTest())
@ -79,7 +109,7 @@ unsigned int AbstractTool::checkVersion(bool &modified)
while(process.state() != QProcess::NotRunning) while(process.state() != QProcess::NotRunning)
{ {
if(m_abort) if(*m_abort)
{ {
process.kill(); process.kill();
bAborted = true; bAborted = true;
@ -96,19 +126,12 @@ unsigned int AbstractTool::checkVersion(bool &modified)
break; break;
} }
} }
while(process.bytesAvailable() > 0) PROCESS_PENDING_LINES(process, checkVersion_parseLine, patterns, coreVers, revision, modified);
{
QList<QByteArray> lines = process.readLine().split('\r');
while(!lines.isEmpty())
{
const QString text = QString::fromUtf8(lines.takeFirst().constData()).simplified();
checkVersion_parseLine(text, patterns, coreVers, revision, modified);
if(!text.isEmpty())
{
log(text);
}
}
} }
if(!(bTimeout || bAborted))
{
PROCESS_PENDING_LINES(process, checkVersion_parseLine, patterns, coreVers, revision, modified);
} }
process.waitForFinished(); process.waitForFinished();
@ -142,6 +165,10 @@ unsigned int AbstractTool::checkVersion(bool &modified)
return (coreVers * REV_MULT) + (revision % REV_MULT); return (coreVers * REV_MULT) + (revision % REV_MULT);
} }
// ------------------------------------------------------------
// Process Creation
// ------------------------------------------------------------
bool AbstractTool::startProcess(QProcess &process, const QString &program, const QStringList &args, bool mergeChannels) bool AbstractTool::startProcess(QProcess &process, const QString &program, const QStringList &args, bool mergeChannels)
{ {
QMutexLocker lock(&s_mutexStartProcess); QMutexLocker lock(&s_mutexStartProcess);
@ -179,9 +206,14 @@ bool AbstractTool::startProcess(QProcess &process, const QString &program, const
return false; return false;
} }
// ------------------------------------------------------------
// Utilities
// ------------------------------------------------------------
QString AbstractTool::commandline2string(const QString &program, const QStringList &arguments) QString AbstractTool::commandline2string(const QString &program, const QStringList &arguments)
{ {
QString commandline = (program.contains(' ') ? QString("\"%1\"").arg(program) : program); const QString nativeProgfram = QDir::toNativeSeparators(program);
QString commandline = (nativeProgfram.contains(' ') ? QString("\"%1\"").arg(nativeProgfram) : nativeProgfram);
for(int i = 0; i < arguments.count(); i++) for(int i = 0; i < arguments.count(); i++)
{ {

View File

@ -26,7 +26,7 @@
#define VER_X264_MAJOR 2 #define VER_X264_MAJOR 2
#define VER_X264_MINOR 3 #define VER_X264_MINOR 3
#define VER_X264_PATCH 2 #define VER_X264_PATCH 2
#define VER_X264_BUILD 793 #define VER_X264_BUILD 795
#define VER_X264_PORTABLE_EDITION (0) #define VER_X264_PORTABLE_EDITION (0)