Added "Pause" support.
This commit is contained in:
parent
405e7d2382
commit
2a3325b02f
@ -621,7 +621,12 @@
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>High</string>
|
||||
<string>Auto</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Baseline</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
@ -631,7 +636,22 @@
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Baseline</string>
|
||||
<string>High</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>High10</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>High422</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>High444</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
|
@ -68,6 +68,12 @@
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="mouseTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -252,6 +258,29 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonPauseJob">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>104</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pause Job</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../res/resources.qrc">
|
||||
<normaloff>:/buttons/pause.png</normaloff>:/buttons/pause.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonAbortJob">
|
||||
<property name="enabled">
|
||||
@ -289,6 +318,8 @@
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<addaction name="actionPreferences"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu">
|
||||
@ -312,6 +343,7 @@
|
||||
<addaction name="actionJob_New"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionJob_Start"/>
|
||||
<addaction name="actionJob_Pause"/>
|
||||
<addaction name="actionJob_Abort"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
@ -423,6 +455,33 @@
|
||||
<string>Abort Job</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionJob_Pause">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../res/resources.qrc">
|
||||
<normaloff>:/buttons/pause.png</normaloff>:/buttons/pause.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pause Job</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPreferences">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../res/resources.qrc">
|
||||
<normaloff>:/buttons/wrench.png</normaloff>:/buttons/wrench.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>buttonAddJob</tabstop>
|
||||
@ -500,5 +559,21 @@
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>actionJob_Pause</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>buttonPauseJob</receiver>
|
||||
<slot>setChecked(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>547</x>
|
||||
<y>617</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
BIN
res/buttons/clock_play.png
Normal file
BIN
res/buttons/clock_play.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 943 B |
BIN
res/buttons/control_pause.png
Normal file
BIN
res/buttons/control_pause.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 598 B |
BIN
res/buttons/hourglass.png
Normal file
BIN
res/buttons/hourglass.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 744 B |
BIN
res/buttons/pause.png
Normal file
BIN
res/buttons/pause.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 799 B |
BIN
res/buttons/suspended.png
Normal file
BIN
res/buttons/suspended.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 484 B |
BIN
res/buttons/wrench.png
Normal file
BIN
res/buttons/wrench.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 610 B |
@ -7,19 +7,25 @@
|
||||
<file>buttons/book_open.png</file>
|
||||
<file>buttons/cancel.png</file>
|
||||
<file>buttons/clock_pause.png</file>
|
||||
<file>buttons/clock_play.png</file>
|
||||
<file>buttons/clock_stop.png</file>
|
||||
<file>buttons/control_pause.png</file>
|
||||
<file>buttons/cross.png</file>
|
||||
<file>buttons/disk.png</file>
|
||||
<file>buttons/door_in.png</file>
|
||||
<file>buttons/error.png</file>
|
||||
<file>buttons/exclamation.png</file>
|
||||
<file>buttons/find.png</file>
|
||||
<file>buttons/hourglass.png</file>
|
||||
<file>buttons/information.png</file>
|
||||
<file>buttons/lightning.png</file>
|
||||
<file>buttons/page_paste.png</file>
|
||||
<file>buttons/pause.png</file>
|
||||
<file>buttons/play.png</file>
|
||||
<file>buttons/play_big.png</file>
|
||||
<file>buttons/suspended.png</file>
|
||||
<file>buttons/world_link.png</file>
|
||||
<file>buttons/wrench.png</file>
|
||||
<file>images/x264.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -131,6 +131,15 @@ QVariant JobListModel::data(const QModelIndex &index, int role) const
|
||||
case EncodeThread::JobStatus_Failed:
|
||||
return QVariant::fromValue<QString>(tr("Failed!"));
|
||||
break;
|
||||
case EncodeThread::JobStatus_Pausing:
|
||||
return QVariant::fromValue<QString>(tr("Pausing..."));
|
||||
break;
|
||||
case EncodeThread::JobStatus_Paused:
|
||||
return QVariant::fromValue<QString>(tr("Paused."));
|
||||
break;
|
||||
case EncodeThread::JobStatus_Resuming:
|
||||
return QVariant::fromValue<QString>(tr("Resuming..."));
|
||||
break;
|
||||
case EncodeThread::JobStatus_Aborting:
|
||||
return QVariant::fromValue<QString>(tr("Aborting..."));
|
||||
break;
|
||||
@ -161,7 +170,7 @@ QVariant JobListModel::data(const QModelIndex &index, int role) const
|
||||
switch(m_status.value(m_jobs.at(index.row())))
|
||||
{
|
||||
case EncodeThread::JobStatus_Enqueued:
|
||||
return QIcon(":/buttons/clock_pause.png");
|
||||
return QIcon(":/buttons/hourglass.png");
|
||||
break;
|
||||
case EncodeThread::JobStatus_Starting:
|
||||
return QIcon(":/buttons/lightning.png");
|
||||
@ -180,6 +189,15 @@ QVariant JobListModel::data(const QModelIndex &index, int role) const
|
||||
case EncodeThread::JobStatus_Failed:
|
||||
return QIcon(":/buttons/exclamation.png");
|
||||
break;
|
||||
case EncodeThread::JobStatus_Pausing:
|
||||
return QIcon(":/buttons/clock_pause.png");
|
||||
break;
|
||||
case EncodeThread::JobStatus_Paused:
|
||||
return QIcon(":/buttons/suspended.png");
|
||||
break;
|
||||
case EncodeThread::JobStatus_Resuming:
|
||||
return QIcon(":/buttons/clock_play.png");
|
||||
break;
|
||||
case EncodeThread::JobStatus_Aborting:
|
||||
return QIcon(":/buttons/clock_stop.png");
|
||||
break;
|
||||
@ -267,6 +285,41 @@ bool JobListModel::startJob(const QModelIndex &index)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JobListModel::pauseJob(const QModelIndex &index)
|
||||
{
|
||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
||||
{
|
||||
QUuid id = m_jobs.at(index.row());
|
||||
EncodeThread::JobStatus status = m_status.value(id);
|
||||
if((status == EncodeThread::JobStatus_Indexing) || (status == EncodeThread::JobStatus_Running) ||
|
||||
(status == EncodeThread::JobStatus_Running_Pass1) || (status == EncodeThread::JobStatus_Running_Pass2))
|
||||
{
|
||||
updateStatus(id, EncodeThread::JobStatus_Pausing);
|
||||
m_threads.value(id)->pauseJob();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JobListModel::resumeJob(const QModelIndex &index)
|
||||
{
|
||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
||||
{
|
||||
QUuid id = m_jobs.at(index.row());
|
||||
EncodeThread::JobStatus status = m_status.value(id);
|
||||
if(status == EncodeThread::JobStatus_Paused)
|
||||
{
|
||||
updateStatus(id, EncodeThread::JobStatus_Resuming);
|
||||
m_threads.value(id)->resumeJob();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JobListModel::abortJob(const QModelIndex &index)
|
||||
{
|
||||
if(index.isValid() && index.row() >= 0 && index.row() < m_jobs.count())
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
|
||||
QModelIndex insertJob(EncodeThread *thread);
|
||||
bool startJob(const QModelIndex &index);
|
||||
bool pauseJob(const QModelIndex &index);
|
||||
bool resumeJob(const QModelIndex &index);
|
||||
bool abortJob(const QModelIndex &index);
|
||||
LogFileModel *getLogFile(const QModelIndex &index);
|
||||
EncodeThread::JobStatus getJobStatus(const QModelIndex &index);
|
||||
|
@ -32,7 +32,7 @@ OptionsModel::OptionsModel(void)
|
||||
m_quantizer = 22;
|
||||
m_preset = "Medium";
|
||||
m_tune = "None";
|
||||
m_profile = "High";
|
||||
m_profile = "Auto";
|
||||
m_custom = "";
|
||||
}
|
||||
|
||||
|
@ -81,9 +81,11 @@ EncodeThread::EncodeThread(const QString &sourceFileName, const QString &outputF
|
||||
m_options(new OptionsModel(*options)),
|
||||
m_binDir(binDir),
|
||||
m_x64(x64),
|
||||
m_handle_jobObject(NULL)
|
||||
m_handle_jobObject(NULL),
|
||||
m_semaphorePaused(0)
|
||||
{
|
||||
m_abort = false;
|
||||
m_pause = false;
|
||||
}
|
||||
|
||||
EncodeThread::~EncodeThread(void)
|
||||
@ -103,20 +105,13 @@ EncodeThread::~EncodeThread(void)
|
||||
|
||||
void EncodeThread::run(void)
|
||||
{
|
||||
m_progress = 0;
|
||||
m_status = JobStatus_Starting;
|
||||
|
||||
try
|
||||
__try
|
||||
{
|
||||
encode();
|
||||
checkedRun();
|
||||
}
|
||||
catch(char *msg)
|
||||
__except(1)
|
||||
{
|
||||
log(tr("EXCEPTION ERROR: ").append(QString::fromLatin1(msg)));
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
log(tr("EXCEPTION ERROR !!!"));
|
||||
qWarning("STRUCTURED EXCEPTION ERROR IN ENCODE THREAD !!!");
|
||||
}
|
||||
|
||||
if(m_handle_jobObject)
|
||||
@ -126,6 +121,45 @@ void EncodeThread::run(void)
|
||||
}
|
||||
}
|
||||
|
||||
void EncodeThread::checkedRun(void)
|
||||
{
|
||||
m_progress = 0;
|
||||
m_status = JobStatus_Starting;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
encode();
|
||||
}
|
||||
catch(char *msg)
|
||||
{
|
||||
log(tr("EXCEPTION ERROR IN THREAD: ").append(QString::fromLatin1(msg)));
|
||||
setStatus(JobStatus_Failed);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
log(tr("UNHANDLED EXCEPTION ERROR IN THREAD !!!"));
|
||||
setStatus(JobStatus_Failed);
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void EncodeThread::start(Priority priority)
|
||||
{
|
||||
qDebug("Thread starting...");
|
||||
|
||||
m_abort = false;
|
||||
m_pause = false;
|
||||
|
||||
while(m_semaphorePaused.tryAcquire(1, 0));
|
||||
QThread::start(priority);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Encode functions
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -183,9 +217,10 @@ void EncodeThread::encode(void)
|
||||
log(tr("\nWARNING: Your revision of x264 uses an unsupported core (API) version, take care!"));
|
||||
log(tr("This application works best with x264 core (API) version %2.").arg(QString::number(VER_X264_CURRENT_API)));
|
||||
}
|
||||
if((revision_avs2yuv != UINT_MAX) && ((revision_avs2yuv % REV_MULT) != 242))
|
||||
if((revision_avs2yuv != UINT_MAX) && ((revision_avs2yuv % REV_MULT) != VER_x264_AVS2YUV_VER))
|
||||
{
|
||||
log(tr("\nERROR: Your version of avs2yuv is unsupported (Required version is v0.24bm2)"));
|
||||
log(tr("\nERROR: Your version of avs2yuv is unsupported (Required version: v0.24 BugMaster's mod 2)"));
|
||||
log(tr("You can find the required version at: http://komisar.gin.by/tools/avs2yuv/"));
|
||||
setStatus(JobStatus_Failed);
|
||||
return;
|
||||
}
|
||||
@ -267,26 +302,68 @@ bool EncodeThread::runEncodingPass(bool x64, bool usePipe, unsigned int frames,
|
||||
bool bTimeout = false;
|
||||
bool bAborted = false;
|
||||
|
||||
//Main processing loop
|
||||
while(processEncode.state() != QProcess::NotRunning)
|
||||
{
|
||||
if(m_abort)
|
||||
unsigned int waitCounter = 0;
|
||||
|
||||
//Wait until new output is available
|
||||
forever
|
||||
{
|
||||
processEncode.kill();
|
||||
processAvisynth.kill();
|
||||
bAborted = true;
|
||||
break;
|
||||
}
|
||||
if(!processEncode.waitForReadyRead(m_processTimeoutInterval))
|
||||
{
|
||||
if(processEncode.state() == QProcess::Running)
|
||||
if(m_abort)
|
||||
{
|
||||
processEncode.kill();
|
||||
qWarning("x264 process timed out <-- killing!");
|
||||
log("\nPROCESS TIMEOUT !!!");
|
||||
bTimeout = true;
|
||||
processAvisynth.kill();
|
||||
bAborted = true;
|
||||
break;
|
||||
}
|
||||
if(m_pause && (processEncode.state() == QProcess::Running))
|
||||
{
|
||||
JobStatus previousStatus = m_status;
|
||||
setStatus(JobStatus_Paused);
|
||||
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};
|
||||
Q_PID pid[2] = {processEncode.pid(), processAvisynth.pid()};
|
||||
if(pid[0]) { ok[0] = (SuspendThread(pid[0]->hThread) != (DWORD)(-1)); }
|
||||
if(pid[1]) { ok[1] = (SuspendThread(pid[1]->hThread) != (DWORD)(-1)); }
|
||||
while(m_pause) m_semaphorePaused.acquire();
|
||||
while(m_semaphorePaused.tryAcquire(1, 0));
|
||||
if(pid[0]) { if(ok[0]) ResumeThread(pid[0]->hThread); }
|
||||
if(pid[1]) { if(ok[1]) ResumeThread(pid[1]->hThread); }
|
||||
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)));
|
||||
waitCounter = 0;
|
||||
continue;
|
||||
}
|
||||
if(!processEncode.waitForReadyRead(2500))
|
||||
{
|
||||
if(processEncode.state() == QProcess::Running)
|
||||
{
|
||||
if(waitCounter++ > m_processTimeoutCounter)
|
||||
{
|
||||
processEncode.kill();
|
||||
qWarning("x264 process timed out <-- killing!");
|
||||
log("\nPROCESS TIMEOUT !!!");
|
||||
bTimeout = true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(m_abort || (m_pause && (processEncode.state() == QProcess::Running)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//Exit main processing loop now?
|
||||
if(bAborted || bTimeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//Process all output
|
||||
while(processEncode.bytesAvailable() > 0)
|
||||
{
|
||||
QList<QByteArray> lines = processEncode.readLine().split('\r');
|
||||
@ -339,9 +416,12 @@ bool EncodeThread::runEncodingPass(bool x64, bool usePipe, unsigned int frames,
|
||||
processAvisynth.waitForFinished(-1);
|
||||
}
|
||||
|
||||
while(processAvisynth.bytesAvailable() > 0)
|
||||
if(!(bTimeout || bAborted))
|
||||
{
|
||||
log(tr("av2y [info]: %1").arg(QString::fromUtf8(processAvisynth.readLine()).simplified()));
|
||||
while(processAvisynth.bytesAvailable() > 0)
|
||||
{
|
||||
log(tr("av2y [info]: %1").arg(QString::fromUtf8(processAvisynth.readLine()).simplified()));
|
||||
}
|
||||
}
|
||||
|
||||
if(usePipe && (processAvisynth.exitCode() != EXIT_SUCCESS))
|
||||
@ -412,12 +492,17 @@ QStringList EncodeThread::buildCommandLine(bool usePipe, unsigned int frames, in
|
||||
cmdLine << "--stats" << QDir::toNativeSeparators(passLogFile);
|
||||
}
|
||||
|
||||
cmdLine << "--preset" << m_options->preset().toLower();
|
||||
|
||||
if(m_options->tune().compare("none", Qt::CaseInsensitive))
|
||||
{
|
||||
cmdLine << "--tune" << m_options->tune().toLower();
|
||||
}
|
||||
|
||||
cmdLine << "--preset" << m_options->preset().toLower();
|
||||
if(m_options->profile().compare("auto", Qt::CaseInsensitive))
|
||||
{
|
||||
cmdLine << "--profile" << m_options->profile().toLower();
|
||||
}
|
||||
|
||||
if(!m_options->custom().isEmpty())
|
||||
{
|
||||
@ -453,7 +538,7 @@ unsigned int EncodeThread::checkVersionX264(bool x64)
|
||||
return false;;
|
||||
}
|
||||
|
||||
QRegExp regExpVersion("x264 (\\d)\\.(\\d+)\\.(\\d+) ([0-9A-Fa-f]{7})");
|
||||
QRegExp regExpVersion("\\bx264 (\\d)\\.(\\d+)\\.(\\d+)\\b");
|
||||
|
||||
bool bTimeout = false;
|
||||
bool bAborted = false;
|
||||
@ -469,7 +554,7 @@ unsigned int EncodeThread::checkVersionX264(bool x64)
|
||||
bAborted = true;
|
||||
break;
|
||||
}
|
||||
if(!process.waitForReadyRead(m_processTimeoutInterval))
|
||||
if(!process.waitForReadyRead())
|
||||
{
|
||||
if(process.state() == QProcess::Running)
|
||||
{
|
||||
@ -538,14 +623,15 @@ unsigned int EncodeThread::checkVersionAvs2yuv(void)
|
||||
return false;;
|
||||
}
|
||||
|
||||
QRegExp regExpVersion("Avs2YUV (\\d+).(\\d+)bm(\\d)");
|
||||
QRegExp regExpVersionMod("\\bAvs2YUV (\\d+).(\\d+)bm(\\d)\\b");
|
||||
QRegExp regExpVersionOld("\\bAvs2YUV (\\d+).(\\d+)\\b");
|
||||
|
||||
bool bTimeout = false;
|
||||
bool bAborted = false;
|
||||
|
||||
unsigned int ver_maj = UINT_MAX;
|
||||
unsigned int ver_min = UINT_MAX;
|
||||
unsigned int ver_bld = UINT_MAX;
|
||||
unsigned int ver_mod = 0;
|
||||
|
||||
while(process.state() != QProcess::NotRunning)
|
||||
{
|
||||
@ -555,7 +641,7 @@ unsigned int EncodeThread::checkVersionAvs2yuv(void)
|
||||
bAborted = true;
|
||||
break;
|
||||
}
|
||||
if(!process.waitForReadyRead(m_processTimeoutInterval))
|
||||
if(!process.waitForReadyRead())
|
||||
{
|
||||
if(process.state() == QProcess::Running)
|
||||
{
|
||||
@ -573,22 +659,30 @@ unsigned int EncodeThread::checkVersionAvs2yuv(void)
|
||||
{
|
||||
QString text = QString::fromUtf8(lines.takeFirst().constData()).simplified();
|
||||
int offset = -1;
|
||||
if((ver_maj == UINT_MAX) || (ver_min == UINT_MAX) || (ver_bld == UINT_MAX))
|
||||
if((ver_maj == UINT_MAX) || (ver_min == UINT_MAX) || (ver_mod == UINT_MAX))
|
||||
{
|
||||
if(!text.isEmpty())
|
||||
{
|
||||
log(text);
|
||||
}
|
||||
}
|
||||
if((offset = regExpVersion.lastIndexIn(text)) >= 0)
|
||||
if((offset = regExpVersionMod.lastIndexIn(text)) >= 0)
|
||||
{
|
||||
bool ok1 = false, ok2 = false, ok3 = false;
|
||||
unsigned int temp1 = regExpVersion.cap(1).toUInt(&ok1);
|
||||
unsigned int temp2 = regExpVersion.cap(2).toUInt(&ok2);
|
||||
unsigned int temp3 = regExpVersion.cap(3).toUInt(&ok3);
|
||||
unsigned int temp1 = regExpVersionMod.cap(1).toUInt(&ok1);
|
||||
unsigned int temp2 = regExpVersionMod.cap(2).toUInt(&ok2);
|
||||
unsigned int temp3 = regExpVersionMod.cap(3).toUInt(&ok3);
|
||||
if(ok1) ver_maj = temp1;
|
||||
if(ok2) ver_min = temp2;
|
||||
if(ok3) ver_mod = temp3;
|
||||
}
|
||||
else if((offset = regExpVersionOld.lastIndexIn(text)) >= 0)
|
||||
{
|
||||
bool ok1 = false, ok2 = false;
|
||||
unsigned int temp1 = regExpVersionOld.cap(1).toUInt(&ok1);
|
||||
unsigned int temp2 = regExpVersionOld.cap(2).toUInt(&ok2);
|
||||
if(ok1) ver_maj = temp1;
|
||||
if(ok2) ver_min = temp2;
|
||||
if(ok3) ver_bld = temp3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -610,13 +704,13 @@ unsigned int EncodeThread::checkVersionAvs2yuv(void)
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
if((ver_maj == UINT_MAX) || (ver_min == UINT_MAX) || (ver_bld == UINT_MAX))
|
||||
if((ver_maj == UINT_MAX) || (ver_min == UINT_MAX))
|
||||
{
|
||||
log(tr("\nFAILED TO DETERMINE AVS2YUV VERSION !!!"));
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
return (ver_maj * REV_MULT) + ((ver_min % REV_MULT) * 10) + (ver_bld % 10);
|
||||
return (ver_maj * REV_MULT) + ((ver_min % REV_MULT) * 10) + (ver_mod % 10);
|
||||
}
|
||||
|
||||
bool EncodeThread::checkProperties(unsigned int &frames)
|
||||
@ -653,12 +747,12 @@ bool EncodeThread::checkProperties(unsigned int &frames)
|
||||
bAborted = true;
|
||||
break;
|
||||
}
|
||||
if(!process.waitForReadyRead(m_processTimeoutInterval))
|
||||
if(!process.waitForReadyRead())
|
||||
{
|
||||
if(process.state() == QProcess::Running)
|
||||
{
|
||||
process.kill();
|
||||
qWarning("x264 process timed out <-- killing!");
|
||||
qWarning("Avs2YUV process timed out <-- killing!");
|
||||
log("\nPROCESS TIMEOUT !!!");
|
||||
bTimeout = true;
|
||||
break;
|
||||
@ -760,7 +854,7 @@ void EncodeThread::setStatus(JobStatus newStatus)
|
||||
if(m_status != newStatus)
|
||||
{
|
||||
m_status = newStatus;
|
||||
if((newStatus != JobStatus_Completed) && (newStatus != JobStatus_Failed) && (newStatus != JobStatus_Aborted))
|
||||
if((newStatus != JobStatus_Completed) && (newStatus != JobStatus_Failed) && (newStatus != JobStatus_Aborted) && (newStatus != JobStatus_Paused))
|
||||
{
|
||||
setProgress(0);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <QUuid>
|
||||
#include <QMutex>
|
||||
#include <QStringList>
|
||||
#include <QSemaphore>
|
||||
|
||||
class OptionsModel;
|
||||
class QProcess;
|
||||
@ -44,8 +45,11 @@ public:
|
||||
JobStatus_Running_Pass2 = 5,
|
||||
JobStatus_Completed = 6,
|
||||
JobStatus_Failed = 7,
|
||||
JobStatus_Aborting = 8,
|
||||
JobStatus_Aborted = 9
|
||||
JobStatus_Pausing = 8,
|
||||
JobStatus_Paused = 9,
|
||||
JobStatus_Resuming = 10,
|
||||
JobStatus_Aborting = 11,
|
||||
JobStatus_Aborted = 12
|
||||
};
|
||||
|
||||
EncodeThread(const QString &sourceFileName, const QString &outputFileName, const OptionsModel *options, const QString &binDir, bool x64);
|
||||
@ -55,11 +59,25 @@ public:
|
||||
const QString &sourceFileName(void) { return this->m_sourceFileName; };
|
||||
const QString &outputFileName(void) { return this->m_outputFileName; };
|
||||
|
||||
void abortJob(void) { m_abort = true; }
|
||||
void pauseJob(void)
|
||||
{
|
||||
m_pause = true;
|
||||
}
|
||||
void resumeJob(void)
|
||||
{
|
||||
m_pause = false;
|
||||
m_semaphorePaused.release();
|
||||
}
|
||||
void abortJob(void)
|
||||
{
|
||||
m_abort = true;
|
||||
m_pause = false;
|
||||
m_semaphorePaused.release();
|
||||
}
|
||||
|
||||
protected:
|
||||
static QMutex m_mutex_startProcess;
|
||||
static const int m_processTimeoutInterval = 60000;
|
||||
static const int m_processTimeoutCounter = 24;
|
||||
|
||||
//Constants
|
||||
const QUuid m_jobId;
|
||||
@ -71,6 +89,10 @@ protected:
|
||||
|
||||
//Flags
|
||||
volatile bool m_abort;
|
||||
volatile bool m_pause;
|
||||
|
||||
//Synchronization
|
||||
QSemaphore m_semaphorePaused;
|
||||
|
||||
//Job handle
|
||||
void *m_handle_jobObject;
|
||||
@ -81,6 +103,7 @@ protected:
|
||||
|
||||
//Entry point
|
||||
virtual void run(void);
|
||||
virtual void checkedRun(void);
|
||||
|
||||
//Encode functions
|
||||
void encode(void);
|
||||
@ -104,5 +127,8 @@ signals:
|
||||
void progressChanged(const QUuid &jobId, unsigned int newProgress);
|
||||
void messageLogged(const QUuid &jobId, const QString &text);
|
||||
void detailsChanged(const QUuid &jobId, const QString &details);
|
||||
|
||||
public slots:
|
||||
void start(Priority priority = InheritPriority);
|
||||
};
|
||||
|
||||
|
@ -24,3 +24,4 @@
|
||||
|
||||
#define VER_X264_MINIMUM_REV (2146)
|
||||
#define VER_X264_CURRENT_API (120)
|
||||
#define VER_x264_AVS2YUV_VER (242)
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
const char *home_url = "http://mulder.brhack.net/";
|
||||
|
||||
#define PRE_RELEASE (1)
|
||||
#define PRE_RELEASE (0)
|
||||
|
||||
#define SET_FONT_BOLD(WIDGET,BOLD) { QFont _font = WIDGET->font(); _font.setBold(BOLD); WIDGET->setFont(_font); }
|
||||
#define SET_TEXT_COLOR(WIDGET,COLOR) { QPalette _palette = WIDGET->palette(); _palette.setColor(QPalette::WindowText, (COLOR)); _palette.setColor(QPalette::Text, (COLOR)); WIDGET->setPalette(_palette); }
|
||||
@ -96,6 +96,7 @@ MainWindow::MainWindow(bool x64supported)
|
||||
connect(buttonAddJob, SIGNAL(clicked()), this, SLOT(addButtonPressed()));
|
||||
connect(buttonStartJob, SIGNAL(clicked()), this, SLOT(startButtonPressed()));
|
||||
connect(buttonAbortJob, SIGNAL(clicked()), this, SLOT(abortButtonPressed()));
|
||||
connect(buttonPauseJob, SIGNAL(toggled(bool)), this, SLOT(pauseButtonPressed(bool)));
|
||||
|
||||
//Enable menu
|
||||
connect(actionAbout, SIGNAL(triggered()), this, SLOT(showAbout()));
|
||||
@ -182,6 +183,18 @@ void MainWindow::abortButtonPressed(void)
|
||||
m_jobList->abortJob(jobsView->currentIndex());
|
||||
}
|
||||
|
||||
void MainWindow::pauseButtonPressed(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
m_jobList->pauseJob(jobsView->currentIndex());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_jobList->resumeJob(jobsView->currentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::jobSelected(const QModelIndex & current, const QModelIndex & previous)
|
||||
{
|
||||
qDebug("Job selected: %d", current.row());
|
||||
@ -349,6 +362,23 @@ void MainWindow::init(void)
|
||||
int val = QMessageBox::warning(this, tr("Avisynth Missing"), tr("<nobr>It appears that Avisynth is not currently installed on your computer.<br>Thus Avisynth input will not be working at all!<br><br>Please download and install Avisynth:<br><a href=\"http://sourceforge.net/projects/avisynth2/files/AviSynth%202.5/\">http://sourceforge.net/projects/avisynth2/files/AviSynth 2.5/</a></nobr>").replace("-", "−"), tr("Quit"), tr("Ignore"));
|
||||
if(val != 1) { close(); qApp->exit(-1); return; }
|
||||
}
|
||||
|
||||
//Check for expiration
|
||||
if(x264_version_date().addMonths(6) < QDate::currentDate())
|
||||
{
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
msgBox.setWindowTitle(tr("Update Notification"));
|
||||
msgBox.setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
|
||||
msgBox.setText(tr("<nobr><tt>Oups, this version of 'Simple x264 Launcher' is more than 6 months old.<br><br>Please check the official web-site at <a href=\"%1\">%1</a> for updates!<br></tt></nobr>").replace("-", "−").arg(home_url));
|
||||
QPushButton *btn1 = msgBox.addButton(tr("Discard"), QMessageBox::NoRole);
|
||||
QPushButton *btn2 = msgBox.addButton(tr("Discard"), QMessageBox::AcceptRole);
|
||||
btn1->setEnabled(false);
|
||||
btn2->setVisible(false);
|
||||
QTimer::singleShot(5000, btn1, SLOT(hide()));
|
||||
QTimer::singleShot(5000, btn2, SLOT(show()));
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateLabel(void)
|
||||
@ -435,9 +465,14 @@ void MainWindow::updateButtons(EncodeThread::JobStatus status)
|
||||
qDebug("MainWindow::updateButtons(void)");
|
||||
|
||||
buttonStartJob->setEnabled(status == EncodeThread::JobStatus_Enqueued);
|
||||
buttonAbortJob->setEnabled(status == EncodeThread::JobStatus_Indexing || status == EncodeThread::JobStatus_Running ||
|
||||
status == EncodeThread::JobStatus_Running_Pass1 || status == EncodeThread::JobStatus_Running_Pass2 );
|
||||
buttonAbortJob->setEnabled(status == EncodeThread::JobStatus_Indexing || status == EncodeThread::JobStatus_Running || status == EncodeThread::JobStatus_Running_Pass1 || status == EncodeThread::JobStatus_Running_Pass2 || status == EncodeThread::JobStatus_Paused);
|
||||
buttonPauseJob->setEnabled(status == EncodeThread::JobStatus_Indexing || status == EncodeThread::JobStatus_Running || status == EncodeThread::JobStatus_Paused || status == EncodeThread::JobStatus_Running_Pass1 || status == EncodeThread::JobStatus_Running_Pass2);
|
||||
buttonPauseJob->setChecked(status == EncodeThread::JobStatus_Paused || status == EncodeThread::JobStatus_Pausing);
|
||||
|
||||
actionJob_Start->setEnabled(buttonStartJob->isEnabled());
|
||||
actionJob_Abort->setEnabled(buttonAbortJob->isEnabled());
|
||||
actionJob_Pause->setEnabled(buttonPauseJob->isEnabled());
|
||||
actionJob_Pause->setChecked(buttonPauseJob->isChecked());
|
||||
|
||||
editDetails->setEnabled(status != EncodeThread::JobStatus_Paused);
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ private slots:
|
||||
void jobChangedData(const QModelIndex &top, const QModelIndex &bottom);
|
||||
void jobLogExtended(const QModelIndex & parent, int start, int end);
|
||||
void launchNextJob(void);
|
||||
void pauseButtonPressed(bool checked);
|
||||
void showAbout(void);
|
||||
void showWebLink(void);
|
||||
void startButtonPressed(void);
|
||||
|
Loading…
Reference in New Issue
Block a user