Bump x265 minimum required version to 3.4.
[simple-x264-launcher.git] / src / source_abstract.cpp
blobe34f677676212d7a5df1b09bf087f107e27fe89b
1 ///////////////////////////////////////////////////////////////////////////////
2 // Simple x264 Launcher
3 // Copyright (C) 2004-2020 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.
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.
19 // http://www.gnu.org/licenses/gpl-2.0.txt
20 ///////////////////////////////////////////////////////////////////////////////
22 #include "source_abstract.h"
24 //Internal
25 #include "global.h"
26 #include "model_sysinfo.h"
27 #include "model_options.h"
28 #include "model_preferences.h"
30 //MUtils
31 #include <MUtils/Global.h>
32 #include <MUtils/OSSupport.h>
33 #include <MUtils/Exception.h>
35 //Qt
36 #include <QProcess>
37 #include <QTextCodec>
38 #include <QDir>
39 #include <QPair>
41 // ------------------------------------------------------------
42 // Constructor & Destructor
43 // ------------------------------------------------------------
45 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)
47 AbstractTool(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause),
48 m_sourceFile(sourceFile)
50 /*Nothing to do here*/
53 AbstractSource::~AbstractSource(void)
55 /*Nothing to do here*/
58 // ------------------------------------------------------------
59 // Check Source Properties
60 // ------------------------------------------------------------
62 bool AbstractSource::checkSourceProperties(ClipInfo &clipInfo)
64 QStringList cmdLine;
65 QList<QRegExp*> patterns;
66 QProcess process;
68 checkSourceProperties_init(patterns, cmdLine);
70 log("Creating process:");
71 if(!startProcess(process, getBinaryPath(), cmdLine, true, &getExtraPaths(), &getExtraEnv()))
73 return false;;
76 QTextCodec *localCodec = QTextCodec::codecForName("System");
78 bool bTimeout = false;
79 bool bAborted = false;
81 clipInfo.reset();
83 unsigned int waitCounter = 0;
85 while(process.state() != QProcess::NotRunning)
87 if(*m_abort)
89 process.kill();
90 bAborted = true;
91 break;
93 if(!process.waitForReadyRead(m_processTimeoutInterval))
95 if(process.state() == QProcess::Running)
97 if(++waitCounter > m_processTimeoutMaxCounter)
99 if(m_preferences->getAbortOnTimeout())
101 process.kill();
102 qWarning("Source process timed out <-- killing!");
103 log("\nPROCESS TIMEOUT !!!");
104 log("\nInput process has encountered a deadlock or your script takes EXTREMELY long to initialize!");
105 bTimeout = true;
106 break;
109 else if(waitCounter == m_processTimeoutWarning)
111 unsigned int timeOut = (waitCounter * m_processTimeoutInterval) / 1000U;
112 log(tr("Warning: Input process did not respond for %1 seconds, potential deadlock...").arg(QString::number(timeOut)));
115 continue;
118 waitCounter = 0;
119 PROCESS_PENDING_LINES(process, checkSourceProperties_parseLine, patterns, clipInfo);
122 if(!(bTimeout || bAborted))
124 PROCESS_PENDING_LINES(process, checkSourceProperties_parseLine, patterns, clipInfo);
127 process.waitForFinished();
128 if(process.state() != QProcess::NotRunning)
130 process.kill();
131 process.waitForFinished(-1);
134 while(!patterns.isEmpty())
136 QRegExp *pattern = patterns.takeFirst();
137 MUTILS_DELETE(pattern);
140 if(bTimeout || bAborted || process.exitCode() != EXIT_SUCCESS)
142 if(!(bTimeout || bAborted))
144 const int exitCode = process.exitCode();
145 log(tr("\nPROCESS EXITED WITH ERROR CODE: %1").arg(QString::number(exitCode)));
146 if((exitCode < 0) || (exitCode >= 32))
148 log(tr("\nIMPORTANT: The input process terminated abnormally. This means Avisynth/VapourSynth or one of its plugins crashed!"));
151 return false;
154 if(clipInfo.getFrameCount() < 1)
156 log(tr("\nFAILED TO DETERMINE CLIP PROPERTIES !!!"));
157 return false;
160 log("");
162 const QPair<quint32, quint32> frameSize = clipInfo.getFrameSize();
163 if((frameSize.first > 0) && (frameSize.second > 0))
165 log(tr("Resolution: %1 x %2").arg(QString::number(frameSize.first), QString::number(frameSize.second)));
168 const QPair<quint32, quint32> frameRate = clipInfo.getFrameRate();
169 if((frameRate.first > 0) && (frameRate.second > 0))
171 log(tr("Frame Rate: %1/%2").arg(QString::number(frameRate.first), QString::number(frameRate.second)));
173 else if(frameRate.first > 0)
175 log(tr("Frame Rate: %1").arg(QString::number(frameRate.first)));
178 log(tr("No. Frames: %1").arg(QString::number(clipInfo.getFrameCount())));
179 return true;
182 // ------------------------------------------------------------
183 // Source Processing
184 // ------------------------------------------------------------
186 bool AbstractSource::createProcess(QProcess &processEncode, QProcess&processInput)
188 processInput.setStandardOutputProcess(&processEncode);
190 QStringList cmdLine_Input;
191 buildCommandLine(cmdLine_Input);
193 log("Creating input process:");
194 if(!startProcess(processInput, getBinaryPath(), cmdLine_Input, false, &getExtraPaths(), &getExtraEnv()))
196 return false;
199 return true;
202 // ------------------------------------------------------------
203 // Source Info
204 // ------------------------------------------------------------
206 const AbstractSourceInfo& AbstractSource::getSourceInfo(void)
208 MUTILS_THROW("[getSourceInfo] This function must be overwritten in sub-classes!");
211 // ------------------------------------------------------------
212 // Auxiliary FUnctions
213 // ------------------------------------------------------------
215 QHash<QString, QString> AbstractSource::getExtraEnv(void) const
217 QHash<QString, QString> extraEnv;
219 const QString profilePath = MUtils::OS::known_folder(MUtils::OS::FOLDER_PROFILE_USER);
220 if (!profilePath.isEmpty())
222 extraEnv.insert("USERPROFILE", QDir::toNativeSeparators(profilePath));
225 const QString appDataPath = MUtils::OS::known_folder(MUtils::OS::FOLDER_APPDATA_ROAM);
226 if (!appDataPath.isEmpty())
228 extraEnv.insert("APPDATA", QDir::toNativeSeparators(appDataPath));
231 return extraEnv;