1 ///////////////////////////////////////////////////////////////////////////////
2 // Simple x264 Launcher
3 // Copyright (C) 2004-2016 LoRd_MuldeR <MuldeR2@GMX.de>
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.
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 ///////////////////////////////////////////////////////////////////////////////
24 #include "source_vapoursynth.h"
32 static const unsigned int VER_X264_VSPIPE_API
= 3;
33 static const unsigned int VER_X264_VSPIPE_VER
= 24;
35 // ------------------------------------------------------------
37 // ------------------------------------------------------------
39 class VapoursyntSourceInfo
: public AbstractSourceInfo
42 virtual QString
getBinaryPath(const SysinfoModel
*const sysinfo
, const bool& x64
) const
44 return QString("%1/core%2/vspipe.exe").arg(sysinfo
->getVPSPath(), (x64
? "64" : "32"));
48 static const VapoursyntSourceInfo s_vapoursynthEncoderInfo
;
50 const AbstractSourceInfo
&VapoursynthSource::getSourceInfo(void)
52 return s_vapoursynthEncoderInfo
;
55 // ------------------------------------------------------------
56 // Constructor & Destructor
57 // ------------------------------------------------------------
59 VapoursynthSource::VapoursynthSource(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
)
61 AbstractSource(jobObject
, options
, sysinfo
, preferences
, jobStatus
, abort
, pause
, semaphorePause
, sourceFile
)
63 /*Nothing to do here*/
66 VapoursynthSource::~VapoursynthSource(void)
68 /*Nothing to do here*/
71 QString
VapoursynthSource::getName(void) const
73 return tr("VapourSynth (vpy)");
76 // ------------------------------------------------------------
78 // ------------------------------------------------------------
80 bool VapoursynthSource::isSourceAvailable()
82 if(!(m_sysinfo
->hasVapourSynth() && (!m_sysinfo
->getVPSPath().isEmpty()) && QFileInfo(getBinaryPath()).isFile()))
84 log(tr("\nVPY INPUT REQUIRES VAPOURSYNTH, BUT IT IS *NOT* AVAILABLE !!!"));
90 void VapoursynthSource::checkVersion_init(QList
<QRegExp
*> &patterns
, QStringList
&cmdLine
)
92 cmdLine
<< "--version";
93 patterns
<< new QRegExp("\\bVapourSynth\\b", Qt::CaseInsensitive
);
94 patterns
<< new QRegExp("\\bCore\\s+r(\\d+)\\b", Qt::CaseInsensitive
);
95 patterns
<< new QRegExp("\\bAPI\\s+r(\\d+)\\b", Qt::CaseInsensitive
);
98 void VapoursynthSource::checkVersion_parseLine(const QString
&line
, QList
<QRegExp
*> &patterns
, unsigned int &core
, unsigned int &build
, bool &modified
)
102 if((offset
= patterns
[1]->lastIndexIn(line
)) >= 0)
105 unsigned int temp
= patterns
[1]->cap(1).toUInt(&ok
);
108 else if((offset
= patterns
[2]->lastIndexIn(line
)) >= 0)
111 unsigned int temp
= patterns
[2]->cap(1).toUInt(&ok
);
121 QString
VapoursynthSource::printVersion(const unsigned int &revision
, const bool &modified
)
123 unsigned int core
, build
;
124 splitRevision(revision
, core
, build
);
126 return tr("\nVapourSynth version: r%1 (API r%2)").arg(QString::number(build
), QString::number(core
));
129 bool VapoursynthSource::isVersionSupported(const unsigned int &revision
, const bool &modified
)
131 unsigned int core
, build
;
132 splitRevision(revision
, core
, build
);
134 if((build
< VER_X264_VSPIPE_VER
) || (core
< VER_X264_VSPIPE_API
))
137 if(core
< VER_X264_VSPIPE_API
)
139 log(tr("\nERROR: Your version of VapourSynth is unsupported! (requires API r%1 or newer)").arg(QString::number(VER_X264_VSPIPE_API
)));
141 if(build
< VER_X264_VSPIPE_VER
)
143 log(tr("\nERROR: Your version of VapourSynth is unsupported! (requires version r%1 or newer)").arg(QString::number(VER_X264_VSPIPE_VER
)));
145 log(tr("You can find the latest VapourSynth version at: http://www.vapoursynth.com/"));
149 if(core
!= VER_X264_VSPIPE_API
)
151 log(tr("\nWARNING: Running with an unknown VapourSynth API version, problem may appear! (this application works best with API r%1)").arg(QString::number(VER_X264_VSPIPE_API
)));
157 // ------------------------------------------------------------
158 // Check Source Properties
159 // ------------------------------------------------------------
161 void VapoursynthSource::checkSourceProperties_init(QList
<QRegExp
*> &patterns
, QStringList
&cmdLine
)
164 cmdLine
<< QDir::toNativeSeparators(x264_path2ansi(m_sourceFile
, true));
167 patterns
<< new QRegExp("\\bFrames:\\s+(\\d+)\\b");
168 patterns
<< new QRegExp("\\bWidth:\\s+(\\d+)\\b");
169 patterns
<< new QRegExp("\\bHeight:\\s+(\\d+)\\b");
170 patterns
<< new QRegExp("\\bFPS:\\s+(\\d+)\\b");
171 patterns
<< new QRegExp("\\bFPS:\\s+(\\d+)/(\\d+)\\b");
174 void VapoursynthSource::checkSourceProperties_parseLine(const QString
&line
, QList
<QRegExp
*> &patterns
, ClipInfo
&clipInfo
)
178 if((offset
= patterns
[0]->lastIndexIn(line
)) >= 0)
181 unsigned int temp
= patterns
[0]->cap(1).toUInt(&ok
);
182 if(ok
) clipInfo
.setFrameCount(temp
);
184 if((offset
= patterns
[1]->lastIndexIn(line
)) >= 0)
187 unsigned int temp
=patterns
[1]->cap(1).toUInt(&ok
);
188 if(ok
) clipInfo
.setFrameSize(temp
, clipInfo
.getFrameSize().second
);
190 if((offset
= patterns
[2]->lastIndexIn(line
)) >= 0)
193 unsigned int temp
= patterns
[2]->cap(1).toUInt(&ok
);
194 if(ok
) clipInfo
.setFrameSize(clipInfo
.getFrameSize().first
, temp
);
196 if((offset
= patterns
[3]->lastIndexIn(line
)) >= 0)
199 unsigned int temp
= patterns
[3]->cap(1).toUInt(&ok
);
200 if(ok
) clipInfo
.setFrameRate(temp
, 0);
202 if((offset
= patterns
[4]->lastIndexIn(line
)) >= 0)
204 bool ok1
= false, ok2
= false;
205 unsigned int temp1
= patterns
[4]->cap(1).toUInt(&ok1
);
206 unsigned int temp2
= patterns
[4]->cap(2).toUInt(&ok2
);
209 clipInfo
.setFrameRate(temp1
, temp2
);
219 // ------------------------------------------------------------
220 // Check Source Properties
221 // ------------------------------------------------------------
223 void VapoursynthSource::buildCommandLine(QStringList
&cmdLine
)
226 cmdLine
<< QDir::toNativeSeparators(x264_path2ansi(m_sourceFile
, true));
230 void VapoursynthSource::flushProcess(QProcess
&processInput
)
232 while(processInput
.bytesAvailable() > 0)
234 log(tr("vpyp [info]: %1").arg(QString::fromUtf8(processInput
.readLine()).simplified()));
237 if(processInput
.exitCode() != EXIT_SUCCESS
)
239 const int exitCode
= processInput
.exitCode();
240 log(tr("\nWARNING: Input process exited with error (code: %1), your encode might be *incomplete* !!!").arg(QString::number(exitCode
)));
241 if((exitCode
< 0) || (exitCode
>= 32))
243 log(tr("\nIMPORTANT: The Vapoursynth process terminated abnormally. This means Vapoursynth or one of your Vapoursynth-Plugin's just crashed."));