OSDN Git Service

Refactored source types (Avisynth, VapourSynth, etc) into separate classes + loads...
[x264-launcher/x264-launcher.git] / src / source_abstract.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Simple x264 Launcher
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
21
22 #include "source_abstract.h"
23
24 #include "global.h"
25 #include "model_sysinfo.h"
26 #include "model_options.h"
27 #include "model_preferences.h"
28
29 #include <QProcess>
30 #include <QTextCodec>
31 #include <QDir>
32
33 AbstractSource::AbstractSource(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)
34 :
35         AbstractTool(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause),
36         m_sourceFile(sourceFile)
37 {
38         /*Nothing to do here*/
39 }
40
41 AbstractSource::~AbstractSource(void)
42 {
43         /*Nothing to do here*/
44 }
45
46 bool AbstractSource::checkSourceProperties(unsigned int &frames)
47 {
48         QStringList cmdLine;
49         QList<QRegExp*> patterns;
50         QProcess process;
51
52         checkSourceProperties_init(patterns, cmdLine);
53
54         log("Creating process:");
55         if(!startProcess(process, getBinaryPath(), cmdLine))
56         {
57                 return false;;
58         }
59         
60         QTextCodec *localCodec = QTextCodec::codecForName("System");
61
62         bool bTimeout = false;
63         bool bAborted = false;
64
65         frames = 0;
66         
67         unsigned int fpsNom = 0;
68         unsigned int fpsDen = 0;
69         unsigned int fSizeW = 0;
70         unsigned int fSizeH = 0;
71         
72         unsigned int waitCounter = 0;
73
74         while(process.state() != QProcess::NotRunning)
75         {
76                 if(m_abort)
77                 {
78                         process.kill();
79                         bAborted = true;
80                         break;
81                 }
82                 if(!process.waitForReadyRead(m_processTimeoutInterval))
83                 {
84                         if(process.state() == QProcess::Running)
85                         {
86                                 if(++waitCounter > m_processTimeoutMaxCounter)
87                                 {
88                                         if(m_preferences->getAbortOnTimeout())
89                                         {
90                                                 process.kill();
91                                                 qWarning("Source process timed out <-- killing!");
92                                                 log("\nPROCESS TIMEOUT !!!");
93                                                 log("\nInput process has encountered a deadlock or your script takes EXTREMELY long to initialize!");
94                                                 bTimeout = true;
95                                                 break;
96                                         }
97                                 }
98                                 else if(waitCounter == m_processTimeoutWarning)
99                                 {
100                                         unsigned int timeOut = (waitCounter * m_processTimeoutInterval) / 1000U;
101                                         log(tr("Warning: Input process did not respond for %1 seconds, potential deadlock...").arg(QString::number(timeOut)));
102                                 }
103                         }
104                         continue;
105                 }
106                 
107                 waitCounter = 0;
108                 
109                 while(process.bytesAvailable() > 0)
110                 {
111                         QList<QByteArray> lines = process.readLine().split('\r');
112                         while(!lines.isEmpty())
113                         {
114                                 QString text = localCodec->toUnicode(lines.takeFirst().constData()).simplified();
115                         }
116                 }
117         }
118
119         process.waitForFinished();
120         if(process.state() != QProcess::NotRunning)
121         {
122                 process.kill();
123                 process.waitForFinished(-1);
124         }
125
126         if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
127         {
128                 if(!(bTimeout || bAborted))
129                 {
130                         const int exitCode = process.exitCode();
131                         log(tr("\nPROCESS EXITED WITH ERROR CODE: %1").arg(QString::number(exitCode)));
132                         if((exitCode < 0) || (exitCode >= 32))
133                         {
134                                 log(tr("\nIMPORTANT: The Avs2YUV process terminated abnormally. This means Avisynth or one of your Avisynth-Plugin's just crashed."));
135                                 log(tr("IMPORTANT: Please fix your Avisynth script and try again! If you use Avisynth-MT, try using a *stable* Avisynth instead!"));
136                         }
137                 }
138                 return false;
139         }
140
141         if(frames == 0)
142         {
143                 log(tr("\nFAILED TO DETERMINE AVS PROPERTIES !!!"));
144                 return false;
145         }
146         
147         log("");
148
149         if((fSizeW > 0) && (fSizeH > 0))
150         {
151                 log(tr("Resolution: %1x%2").arg(QString::number(fSizeW), QString::number(fSizeH)));
152         }
153         if((fpsNom > 0) && (fpsDen > 0))
154         {
155                 log(tr("Frame Rate: %1/%2").arg(QString::number(fpsNom), QString::number(fpsDen)));
156         }
157         if((fpsNom > 0) && (fpsDen == 0))
158         {
159                 log(tr("Frame Rate: %1").arg(QString::number(fpsNom)));
160         }
161         if(frames > 0)
162         {
163                 log(tr("No. Frames: %1").arg(QString::number(frames)));
164         }
165
166         return true;
167 }
168
169 bool AbstractSource::createProcess(QProcess &processEncode, QProcess&processInput)
170 {
171         processInput.setStandardOutputProcess(&processEncode);
172         
173         QStringList cmdLine_Input;
174         buildCommandLine(cmdLine_Input);
175
176         log("Creating input process:");
177         if(!startProcess(processInput, getBinaryPath(), cmdLine_Input, false))
178         {
179                 return false;
180         }
181
182         return true;
183 }