OSDN Git Service

Added "Pause" support.
authorlordmulder <mulder2@gmx.de>
Thu, 2 Feb 2012 01:13:02 +0000 (02:13 +0100)
committerlordmulder <mulder2@gmx.de>
Thu, 2 Feb 2012 01:13:02 +0000 (02:13 +0100)
17 files changed:
gui/win_addJob.ui
gui/win_main.ui
res/buttons/clock_play.png [new file with mode: 0644]
res/buttons/control_pause.png [new file with mode: 0644]
res/buttons/hourglass.png [new file with mode: 0644]
res/buttons/pause.png [new file with mode: 0644]
res/buttons/suspended.png [new file with mode: 0644]
res/buttons/wrench.png [new file with mode: 0644]
res/resources.qrc
src/model_jobList.cpp
src/model_jobList.h
src/model_options.cpp
src/thread_encode.cpp
src/thread_encode.h
src/version.h
src/win_main.cpp
src/win_main.h

index e11cb95..b34df7a 100644 (file)
                </property>
                <item>
                 <property name="text">
-                 <string>High</string>
+                 <string>Auto</string>
+                </property>
+               </item>
+               <item>
+                <property name="text">
+                 <string>Baseline</string>
                 </property>
                </item>
                <item>
                </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>
index 08e5818..55a527a 100644 (file)
         </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>
        </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">
          <bool>false</bool>
     <property name="title">
      <string>File</string>
     </property>
+    <addaction name="actionPreferences"/>
+    <addaction name="separator"/>
     <addaction name="actionExit"/>
    </widget>
    <widget class="QMenu" name="menu">
     <addaction name="actionJob_New"/>
     <addaction name="separator"/>
     <addaction name="actionJob_Start"/>
+    <addaction name="actionJob_Pause"/>
     <addaction name="actionJob_Abort"/>
    </widget>
    <addaction name="menuFile"/>
     <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>
     </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>
diff --git a/res/buttons/clock_play.png b/res/buttons/clock_play.png
new file mode 100644 (file)
index 0000000..fb4ebc8
Binary files /dev/null and b/res/buttons/clock_play.png differ
diff --git a/res/buttons/control_pause.png b/res/buttons/control_pause.png
new file mode 100644 (file)
index 0000000..2d9ce9c
Binary files /dev/null and b/res/buttons/control_pause.png differ
diff --git a/res/buttons/hourglass.png b/res/buttons/hourglass.png
new file mode 100644 (file)
index 0000000..57b03ce
Binary files /dev/null and b/res/buttons/hourglass.png differ
diff --git a/res/buttons/pause.png b/res/buttons/pause.png
new file mode 100644 (file)
index 0000000..77918fb
Binary files /dev/null and b/res/buttons/pause.png differ
diff --git a/res/buttons/suspended.png b/res/buttons/suspended.png
new file mode 100644 (file)
index 0000000..a9b3113
Binary files /dev/null and b/res/buttons/suspended.png differ
diff --git a/res/buttons/wrench.png b/res/buttons/wrench.png
new file mode 100644 (file)
index 0000000..5c8213f
Binary files /dev/null and b/res/buttons/wrench.png differ
index 732b009..67e9230 100644 (file)
@@ -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>
index c63b7b5..9f3e9e2 100644 (file)
@@ -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())
index a78e818..b3463a8 100644 (file)
@@ -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);
index 5d25187..2d60651 100644 (file)
@@ -32,7 +32,7 @@ OptionsModel::OptionsModel(void)
        m_quantizer = 22;
        m_preset = "Medium";
        m_tune = "None";
-       m_profile = "High";
+       m_profile = "Auto";
        m_custom = "";
 }
 
index 2163764..8ae8bb2 100644 (file)
@@ -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
-       {
-               encode();
-       }
-       catch(char *msg)
+       __try
        {
-               log(tr("EXCEPTION ERROR: ").append(QString::fromLatin1(msg)));
+               checkedRun();
        }
-       catch(...)
+       __except(1)
        {
-               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
 ///////////////////////////////////////////////////////////////////////////////
@@ -133,7 +167,7 @@ void EncodeThread::run(void)
 void EncodeThread::encode(void)
 {
        QDateTime startTime = QDateTime::currentDateTime();
-       
+
        //Print some basic info
        log(tr("Job started at %1, %2.\n").arg(QDate::currentDate().toString(Qt::ISODate), QTime::currentTime().toString( Qt::ISODate)));
        log(tr("Source file: %1").arg(m_sourceFileName));
@@ -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)
-               {
-                       processEncode.kill();
-                       processAvisynth.kill();
-                       bAborted = true;
-                       break;
-               }
-               if(!processEncode.waitForReadyRead(m_processTimeoutInterval))
+               unsigned int waitCounter = 0;
+
+               //Wait until new output is available
+               forever
                {
-                       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);
                }
index 4ced328..6a467b8 100644 (file)
@@ -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,7 +89,11 @@ 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);
 };
 
index 9772932..ced0944 100644 (file)
@@ -24,3 +24,4 @@
 
 #define VER_X264_MINIMUM_REV (2146)
 #define VER_X264_CURRENT_API (120)
+#define VER_x264_AVS2YUV_VER (242)
index dcb2af4..d52a9d4 100644 (file)
@@ -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("-", "&minus;"), 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("-", "&minus;").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);
 }
index 593da2e..4e32bd4 100644 (file)
@@ -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);