OSDN Git Service

Added preliminary NVEncC encoding support.
authorlordmulder <mulder2@gmx.de>
Sat, 7 May 2016 15:39:12 +0000 (17:39 +0200)
committerlordmulder <mulder2@gmx.de>
Sat, 7 May 2016 15:39:12 +0000 (17:39 +0200)
16 files changed:
HISTORY.txt
src/encoder_abstract.cpp
src/encoder_abstract.h
src/encoder_factory.cpp
src/encoder_nvenc.cpp [new file with mode: 0644]
src/encoder_nvenc.h [new file with mode: 0644]
src/encoder_x264.cpp
src/encoder_x264.h
src/encoder_x265.cpp
src/encoder_x265.h
src/model_options.h
src/thread_binaries.cpp
src/version.h
src/win_addJob.cpp
x264_launcher_MSVC2015.vcxproj
x264_launcher_MSVC2015.vcxproj.filters

index 4747b2f..5c1bb4f 100644 (file)
@@ -2,6 +2,9 @@
 Simple x264/x265 Launcher version history 
 ----------------------------------------- 
 
+Version 2.71 [2016-??-??]
+* Added NVEncC encoding support.
+
 Version 2.70 [2016-04-29]
 * Fixed potential VapourSynth error, when Avisynth is *not* installed
 * Some installer improvements
index 179c9ac..8ca9e44 100644 (file)
@@ -164,12 +164,12 @@ bool AbstractEncoder::runEncodingPass(AbstractSource* pipedSource, const QString
                }
 
                //Process all output
-               PROCESS_PENDING_LINES(processEncode, runEncodingPass_parseLine, patterns, pass, last_progress, size_estimate);
+               PROCESS_PENDING_LINES(processEncode, runEncodingPass_parseLine, patterns, frames, pass, last_progress, size_estimate);
        }
        
        if(!(bTimeout || bAborted))
        {
-               PROCESS_PENDING_LINES(processEncode, runEncodingPass_parseLine, patterns, pass, last_progress, size_estimate);
+               PROCESS_PENDING_LINES(processEncode, runEncodingPass_parseLine, patterns, frames, pass, last_progress, size_estimate);
        }
 
        processEncode.waitForFinished(5000);
@@ -297,3 +297,8 @@ const AbstractEncoderInfo& AbstractEncoder::getEncoderInfo(void)
 {
        MUTILS_THROW("[getEncoderInfo] This function must be overwritten in sub-classes!");
 }
+
+QStringList AbstractEncoderInfo::getDependencies(const SysinfoModel *sysinfo, const OptionsModel::EncArch &encArch, const OptionsModel::EncVariant &encVariant) const
+{
+       return QStringList();
+}
\ No newline at end of file
index 01b9044..731ea62 100644 (file)
@@ -39,6 +39,7 @@ public:
        virtual bool isRCModeSupported(const OptionsModel::RCMode &rcMode) const = 0;
        virtual bool isInputTypeSupported(const int format) const = 0;
        virtual QString getBinaryPath(const SysinfoModel *sysinfo, const OptionsModel::EncArch &encArch, const OptionsModel::EncVariant &encVariant) const = 0;
+       virtual QStringList getDependencies(const SysinfoModel *sysinfo, const OptionsModel::EncArch &encArch, const OptionsModel::EncVariant &encVariant) const;
 };
 
 class AbstractEncoder : public AbstractTool
@@ -55,7 +56,7 @@ protected:
        virtual void buildCommandLine(QStringList &cmdLine, const bool &usePipe, const unsigned int &frames, const QString &indexFile, const int &pass, const QString &passLogFile) = 0;
 
        virtual void runEncodingPass_init(QList<QRegExp*> &patterns) = 0;
-       virtual void runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const int &pass, double &last_progress, double &size_estimate) = 0;
+       virtual void runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const unsigned int &totalFrames, const int &pass, double &last_progress, double &size_estimate) = 0;
 
        static double estimateSize(const QString &fileName, const double &progress);
        static QString sizeToString(qint64 size);
index 3bc792d..bc8bb9d 100644 (file)
@@ -14,7 +14,7 @@
 //
 // You should have received a copy of the GNU General Public License along
 // with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+// 51 Franklin Street, Fifth Floory, Boston, MA 02110-1301 USA.
 //
 // http://www.gnu.org/licenses/gpl-2.0.txt
 ///////////////////////////////////////////////////////////////////////////////
@@ -26,6 +26,7 @@
 #include "model_options.h"
 #include "encoder_x264.h"
 #include "encoder_x265.h"
+#include "encoder_nvenc.h"
 
 //MUtils
 #include <MUtils/Exception.h>
@@ -42,6 +43,9 @@ AbstractEncoder *EncoderFactory::createEncoder(JobObject *jobObject, const Optio
        case OptionsModel::EncType_X265:
                encoder = new X265Encoder(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause, sourceFile, outputFile);
                break;
+       case OptionsModel::EncType_NVEnc:
+               encoder = new NVEncEncoder(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause, sourceFile, outputFile);
+               break;
        default:
                MUTILS_THROW("Unknown encoder type encountered!");
        }
@@ -57,6 +61,8 @@ const AbstractEncoderInfo& EncoderFactory::getEncoderInfo(const OptionsModel::En
                return X264Encoder::getEncoderInfo();
        case OptionsModel::EncType_X265:
                return X265Encoder::getEncoderInfo();
+       case OptionsModel::EncType_NVEnc:
+               return NVEncEncoder::getEncoderInfo();
        default:
                MUTILS_THROW("Unknown encoder type encountered!");
        }
diff --git a/src/encoder_nvenc.cpp b/src/encoder_nvenc.cpp
new file mode 100644 (file)
index 0000000..75ccbd3
--- /dev/null
@@ -0,0 +1,385 @@
+///////////////////////////////////////////////////////////////////////////////
+// Simple x264 Launcher
+// Copyright (C) 2004-2016 LoRd_MuldeR <MuldeR2@GMX.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// http://www.gnu.org/licenses/gpl-2.0.txt
+///////////////////////////////////////////////////////////////////////////////
+
+#include "encoder_nvenc.h"
+
+//Internal
+#include "global.h"
+#include "model_options.h"
+#include "model_status.h"
+#include "mediainfo.h"
+#include "model_sysinfo.h"
+
+//MUtils
+#include <MUtils/Exception.h>
+
+//Qt
+#include <QStringList>
+#include <QDir>
+#include <QRegExp>
+
+//x265 version info
+static const unsigned int VERSION_NVENCC_MINIMUM_VER = 206;
+static const unsigned int VERSION_NVENCC_MINIMUM_API =  60;
+
+// ------------------------------------------------------------
+// Helper Macros
+// ------------------------------------------------------------
+
+#define NVENCC_UPDATE_PROGRESS(X) do \
+{ \
+       bool ok = false; \
+       unsigned int progressFrames = (X)->cap(1).toUInt(&ok); \
+       setStatus(JobStatus_Running); \
+       if(ok && (totalFrames > 0) && (totalFrames != UINT_MAX)) \
+       { \
+               const double progress = (double(progressFrames) / double(totalFrames)); \
+               if(!qFuzzyCompare(progress, last_progress)) \
+               { \
+                       setProgress(floor(progress * 100.0)); \
+                       size_estimate = qFuzzyIsNull(size_estimate) ? estimateSize(m_outputFile, progress) : ((0.667 * size_estimate) + (0.333 * estimateSize(m_outputFile, progress))); \
+                       last_progress = progress; \
+               } \
+       } \
+       setDetails(tr("%1, est. file size %2").arg(line.mid(offset).trimmed(), sizeToString(qRound64(size_estimate)))); \
+} \
+while(0)
+
+#define REMOVE_CUSTOM_ARG(LIST, ITER, FLAG, PARAM) do \
+{ \
+       if(ITER != LIST.end()) \
+       { \
+               if((*ITER).compare(PARAM, Qt::CaseInsensitive) == 0) \
+               { \
+                       log(tr("WARNING: Custom parameter \"" PARAM "\" will be ignored in Pipe'd mode!\n")); \
+                       ITER = LIST.erase(ITER); \
+                       if(ITER != LIST.end()) \
+                       { \
+                               if(!((*ITER).startsWith("--", Qt::CaseInsensitive))) ITER = LIST.erase(ITER); \
+                       } \
+                       FLAG = true; \
+               } \
+       } \
+} \
+while(0)
+
+// ------------------------------------------------------------
+// Encoder Info
+// ------------------------------------------------------------
+
+class NVEncEncoderInfo : public AbstractEncoderInfo
+{
+public:
+       virtual QFlags<OptionsModel::EncVariant> getVariants(void) const
+       {
+               QFlags<OptionsModel::EncVariant> variants;
+               variants |= OptionsModel::EncVariant_8Bit;
+               return variants;
+       }
+
+       virtual QStringList getTunings(void) const
+       {
+               return QStringList();
+       }
+
+       virtual QStringList getPresets(void) const
+       {
+               return QStringList();
+       }
+
+       virtual QStringList getProfiles(const OptionsModel::EncVariant &variant) const
+       {
+               QStringList profiles;
+               switch(variant)
+               {
+               case OptionsModel::EncVariant_8Bit:
+                       profiles << "baseline" << "main" << "high";
+                       break;
+               }
+               return profiles;
+       }
+
+       virtual QStringList supportedOutputFormats(void) const
+       {
+               QStringList extLst;
+               extLst << "mp4";
+               return extLst;
+       }
+
+       virtual bool isRCModeSupported(const OptionsModel::RCMode &rcMode) const
+       {
+               switch(rcMode)
+               {
+               case OptionsModel::RCMode_CQ:
+               case OptionsModel::RCMode_ABR:
+                       return true;
+               default:
+                       return false;
+               }
+       }
+
+       virtual bool isInputTypeSupported(const int format) const
+       {
+               switch(format)
+               {
+               case MediaInfo::FILETYPE_YUV4MPEG2:
+                       return true;
+               default:
+                       return false;
+               }
+       }
+
+       virtual QString getBinaryPath(const SysinfoModel *sysinfo, const OptionsModel::EncArch &encArch, const OptionsModel::EncVariant &encVariant) const
+       {
+               QString arch, variant;
+               switch(encArch)
+               {
+                       case OptionsModel::EncArch_x86_32: arch = "x86"; break;
+                       case OptionsModel::EncArch_x86_64: arch = "x64"; break;
+                       default: MUTILS_THROW("Unknown encoder arch!");
+               }
+               switch(encVariant)
+               {
+                       case OptionsModel::EncVariant_8Bit:  variant = "8bit";  break;
+                       default: MUTILS_THROW("Unknown encoder arch!");
+               }
+               return QString("%1/toolset/%2/nvencc_%2.exe").arg(sysinfo->getAppPath(), arch);
+       }
+
+       virtual QStringList getDependencies(const SysinfoModel *sysinfo, const OptionsModel::EncArch &encArch, const OptionsModel::EncVariant &encVariant) const
+       {
+               QString arch, variant;
+               switch (encArch)
+               {
+                       case OptionsModel::EncArch_x86_32: arch = "x86"; break;
+                       case OptionsModel::EncArch_x86_64: arch = "x64"; break;
+                       default: MUTILS_THROW("Unknown encoder arch!");
+               }
+               switch (encVariant)
+               {
+                       case OptionsModel::EncVariant_8Bit:  variant = "8bit";  break;
+                       default: MUTILS_THROW("Unknown encoder arch!");
+               }
+               QStringList dependencies;
+               dependencies << QString("%1/toolset/%2/avcodec-57.dll"  ).arg(sysinfo->getAppPath(), arch);
+               dependencies << QString("%1/toolset/%2/avfilter-6.dll"  ).arg(sysinfo->getAppPath(), arch);
+               dependencies << QString("%1/toolset/%2/avformat-57.dll" ).arg(sysinfo->getAppPath(), arch);
+               dependencies << QString("%1/toolset/%2/avutil-55.dll"   ).arg(sysinfo->getAppPath(), arch);
+               dependencies << QString("%1/toolset/%2/swresample-2.dll").arg(sysinfo->getAppPath(), arch);
+               return dependencies;
+       }
+};
+
+static const NVEncEncoderInfo s_x265EncoderInfo;
+
+const AbstractEncoderInfo &NVEncEncoder::getEncoderInfo(void)
+{
+       return s_x265EncoderInfo;
+}
+
+// ------------------------------------------------------------
+// Constructor & Destructor
+// ------------------------------------------------------------
+
+NVEncEncoder::NVEncEncoder(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, const QString &outputFile)
+:
+       AbstractEncoder(jobObject, options, sysinfo, preferences, jobStatus, abort, pause, semaphorePause, sourceFile, outputFile)
+{
+       if(options->encType() != OptionsModel::EncType_NVEnc)
+       {
+               MUTILS_THROW("Invalid encoder type!");
+       }
+}
+
+NVEncEncoder::~NVEncEncoder(void)
+{
+       /*Nothing to do here*/
+}
+
+QString NVEncEncoder::getName(void) const
+{
+       QString arch, variant;
+       switch(m_options->encArch())
+       {
+               case OptionsModel::EncArch_x86_32: arch = "x86"; break;
+               case OptionsModel::EncArch_x86_64: arch = "x64"; break;
+               default: MUTILS_THROW("Unknown encoder arch!");
+       }
+       switch(m_options->encVariant())
+       {
+               case OptionsModel::EncVariant_8Bit:  variant = "8-Bit";  break;
+               default: MUTILS_THROW("Unknown encoder arch!");
+       }
+       return QString("NVEncC, %1, %2").arg(arch, variant);
+}
+
+// ------------------------------------------------------------
+// Check Version
+// ------------------------------------------------------------
+
+void NVEncEncoder::checkVersion_init(QList<QRegExp*> &patterns, QStringList &cmdLine)
+{
+       cmdLine << "--version";
+       patterns << new QRegExp("\\bNVEncC\\s+\\(\\w+\\)\\s+(\\d)\\.(\\d+)\\s+by\\s+rigaya\\s+\\[NVENC\\s+API\\s+v(\\d+)\\.(\\d+)\\]", Qt::CaseInsensitive);
+}
+
+void NVEncEncoder::checkVersion_parseLine(const QString &line, QList<QRegExp*> &patterns, unsigned int &core, unsigned int &build, bool &modified)
+{
+       int offset = -1;
+
+       if((offset = patterns[0]->lastIndexIn(line)) >= 0)
+       {
+               bool ok[4] = { false, false, false, false };
+               unsigned int temp[4];
+               temp[0] = patterns[0]->cap(1).toUInt(&ok[0]);
+               temp[1] = patterns[0]->cap(2).toUInt(&ok[1]);
+               temp[2] = patterns[0]->cap(2).toUInt(&ok[2]);
+               temp[3] = patterns[0]->cap(2).toUInt(&ok[3]);
+               if(ok[0] && ok[1])
+               {
+                       core = (100 * temp[0]) + temp[1];
+               }
+               if (ok[2] && ok[3])
+               {
+                       build = (10 * temp[2]) + temp[3];
+               }
+       }
+
+       if(!line.isEmpty())
+       {
+               log(line);
+       }
+}
+
+bool NVEncEncoder::checkVersion_succeeded(const int &exitCode)
+{
+       return (exitCode == 0) || (exitCode == 1);
+}
+
+QString NVEncEncoder::printVersion(const unsigned int &revision, const bool &modified)
+{
+       unsigned int core, build;
+       splitRevision(revision, core, build);
+
+       return tr("NVEncC version: %1.%2").arg(QString::number(core / 100), QString::number(core % 100).leftJustified(2, QLatin1Char('0')));
+}
+
+bool NVEncEncoder::isVersionSupported(const unsigned int &revision, const bool &modified)
+{
+       unsigned int core, build;
+       splitRevision(revision, core, build);
+
+       if(core < VERSION_NVENCC_MINIMUM_VER)
+       {
+               log(tr("\nERROR: Your version of NVEncC is too old! (Minimum required version is %1.%2)").arg(QString::number(VERSION_NVENCC_MINIMUM_VER / 100), QString::number(VERSION_NVENCC_MINIMUM_VER % 100)));
+               return false;
+       }
+       else if(core > VERSION_NVENCC_MINIMUM_VER)
+       {
+               log(tr("\nWARNING: Your version of NVEncC is newer than the latest tested version, take care!"));
+               log(tr("This application works best with NVEncC version %1.%2. Newer versions may work or not.").arg(QString::number(VERSION_NVENCC_MINIMUM_VER / 100), QString::number(VERSION_NVENCC_MINIMUM_VER % 100)));
+       }
+
+       if (build < VERSION_NVENCC_MINIMUM_API)
+       {
+               log(tr("\nERROR: Your version of NVENC API is too old! (Minimum required version is %1.%2)").arg(QString::number(VERSION_NVENCC_MINIMUM_API / 10), QString::number(VERSION_NVENCC_MINIMUM_API % 10)));
+               return false;
+       }
+
+       return true;
+}
+
+// ------------------------------------------------------------
+// Encoding Functions
+// ------------------------------------------------------------
+
+void NVEncEncoder::buildCommandLine(QStringList &cmdLine, const bool &usePipe, const unsigned int &frames, const QString &indexFile, const int &pass, const QString &passLogFile)
+{
+       double crf_int = 0.0, crf_frc = 0.0;
+
+       switch(m_options->rcMode())
+       {
+       case OptionsModel::RCMode_ABR:
+               cmdLine << "--vbr" << QString::number(m_options->bitrate());
+               break;
+       case OptionsModel::RCMode_CQ:
+               cmdLine << "--cqp" << QString::number(qRound(m_options->quantizer()));
+               break;
+       default:
+               MUTILS_THROW("Bad rate-control mode !!!");
+               break;
+       }
+       
+       const QString profile = m_options->profile().simplified().toLower();
+       if(!profile.isEmpty())
+       {
+               if(profile.compare(QString::fromLatin1(OptionsModel::PROFILE_UNRESTRICTED), Qt::CaseInsensitive) != 0)
+               {
+                       cmdLine << "--profile" << profile;
+               }
+       }
+
+       if(!m_options->customEncParams().isEmpty())
+       {
+               QStringList customArgs = splitParams(m_options->customEncParams(), m_sourceFile, m_outputFile);
+               if(usePipe)
+               {
+                       QStringList::iterator i = customArgs.begin();
+                       while(i != customArgs.end())
+                       {
+                               bool bModified = false;
+                               REMOVE_CUSTOM_ARG(customArgs, i, bModified, "--fps");
+                               REMOVE_CUSTOM_ARG(customArgs, i, bModified, "--frames");
+                               if(!bModified) i++;
+                       }
+               }
+               cmdLine.append(customArgs);
+       }
+
+       cmdLine << "--output" << QDir::toNativeSeparators(m_outputFile);
+       
+       if(usePipe)
+       {
+               cmdLine << "--y4m" << "--input" << "-";
+       }
+       else
+       {
+               cmdLine << "--input" << QDir::toNativeSeparators(m_sourceFile);
+       }
+}
+
+void NVEncEncoder::runEncodingPass_init(QList<QRegExp*> &patterns)
+{
+       patterns << new QRegExp("^(\\d+) frames:"); //regExpFrameCnt
+}
+
+void NVEncEncoder::runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const unsigned int &totalFrames, const int &pass, double &last_progress, double &size_estimate)
+{
+       int offset = -1;
+       if((offset = patterns[0]->lastIndexIn(line)) >= 0)
+       {
+               NVENCC_UPDATE_PROGRESS(patterns[0]);
+       }
+       else if(!line.isEmpty())
+       {
+               log(line);
+       }
+}
diff --git a/src/encoder_nvenc.h b/src/encoder_nvenc.h
new file mode 100644 (file)
index 0000000..430cdde
--- /dev/null
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////
+// Simple x264 Launcher
+// Copyright (C) 2004-2016 LoRd_MuldeR <MuldeR2@GMX.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// http://www.gnu.org/licenses/gpl-2.0.txt
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include "encoder_abstract.h"
+
+class NVEncEncoder : public AbstractEncoder
+{
+public:
+       NVEncEncoder(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, const QString &outputFile);
+       virtual ~NVEncEncoder(void);
+
+       virtual QString getName(void) const;
+
+       virtual QString printVersion(const unsigned int &revision, const bool &modified);
+       virtual bool isVersionSupported(const unsigned int &revision, const bool &modified);
+
+       static const AbstractEncoderInfo& getEncoderInfo(void);
+
+protected:
+       virtual QString getBinaryPath() const { return getEncoderInfo().getBinaryPath(m_sysinfo, m_options->encArch(), m_options->encVariant()); }
+       virtual void buildCommandLine(QStringList &cmdLine, const bool &usePipe, const unsigned int &frames, const QString &indexFile, const int &pass, const QString &passLogFile);
+
+       virtual void checkVersion_init(QList<QRegExp*> &patterns, QStringList &cmdLine);
+       virtual void checkVersion_parseLine(const QString &line, QList<QRegExp*> &patterns, unsigned int &core, unsigned int &build, bool &modified);
+       virtual bool checkVersion_succeeded(const int &exitCode);
+
+       virtual void runEncodingPass_init(QList<QRegExp*> &patterns);
+       virtual void runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const unsigned int &totalFrames, const int &pass, double &last_progress, double &size_estimate);
+};
index ce1a957..83367a1 100644 (file)
@@ -406,7 +406,7 @@ void X264Encoder::runEncodingPass_init(QList<QRegExp*> &patterns)
        patterns << new QRegExp("\\[\\s*(\\d+)\\.(\\d+)%\\]\\s+(\\d+)/(\\d+)\\s(\\d+).(\\d+)\\s(\\d+).(\\d+)\\s+(\\d+):(\\d+):(\\d+)\\s+(\\d+):(\\d+):(\\d+)"); //regExpModified
 }
 
-void X264Encoder::runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const int &pass, double &last_progress, double &size_estimate)
+void X264Encoder::runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const unsigned int &totalFrames, const int &pass, double &last_progress, double &size_estimate)
 {
        int offset = -1;
        if((offset = patterns[0]->lastIndexIn(line)) >= 0)
index ce3f9d2..746e337 100644 (file)
@@ -44,6 +44,6 @@ protected:
        virtual void checkVersion_parseLine(const QString &line, QList<QRegExp*> &patterns, unsigned int &core, unsigned int &build, bool &modified);
 
        virtual void runEncodingPass_init(QList<QRegExp*> &patterns);
-       virtual void runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const int &pass, double &last_progress, double &size_estimate);
+       virtual void runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const unsigned int &totalFrames, const int &pass, double &last_progress, double &size_estimate);
 
 };
index 7e0f7a2..fcf8ff5 100644 (file)
@@ -400,7 +400,7 @@ void X265Encoder::runEncodingPass_init(QList<QRegExp*> &patterns)
        patterns << new QRegExp("\\[\\s*(\\d+)\\.(\\d+)%\\]\\s+(\\d+)/(\\d+)\\s(\\d+).(\\d+)\\s(\\d+).(\\d+)\\s+(\\d+):(\\d+):(\\d+)\\s+(\\d+):(\\d+):(\\d+)"); //regExpModified
 }
 
-void X265Encoder::runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const int &pass, double &last_progress, double &size_estimate)
+void X265Encoder::runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const unsigned int &totalFrames, const int &pass, double &last_progress, double &size_estimate)
 {
        int offset = -1;
        if((offset = patterns[0]->lastIndexIn(line)) >= 0)
index 978f388..4d6f28d 100644 (file)
@@ -44,5 +44,5 @@ protected:
        virtual void checkVersion_parseLine(const QString &line, QList<QRegExp*> &patterns, unsigned int &core, unsigned int &build, bool &modified);
 
        virtual void runEncodingPass_init(QList<QRegExp*> &patterns);
-       virtual void runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const int &pass, double &last_progress, double &size_estimate);
+       virtual void runEncodingPass_parseLine(const QString &line, QList<QRegExp*> &patterns, const unsigned int &totalFrames, const int &pass, double &last_progress, double &size_estimate);
 };
index 00b31b6..38f1f3c 100644 (file)
@@ -37,11 +37,12 @@ public:
 
        enum EncType
        {
-               EncType_X264 = 0,
-               EncType_X265 = 1,
+               EncType_X264  = 0,
+               EncType_X265  = 1,
+               EncType_NVEnc = 2,
 
                EncType_MIN  = EncType_X264,
-               EncType_MAX  = EncType_X265,
+               EncType_MAX  = EncType_NVEnc,
        };
 
        enum EncArch
@@ -91,9 +92,9 @@ public:
        QString customAvs2YUV(void)   const { return m_custom_avs2yuv; }
 
        //Setter
-       void setEncType(EncType type)                  { m_encoderType = qBound(EncType_X264, type, EncType_X265); }
-       void setEncArch(EncArch arch)                  { m_encoderArch = qBound(EncArch_x86_32, arch, EncArch_x86_64); }
-       void setEncVariant(EncVariant variant)         { m_encoderVariant = qBound(EncVariant_8Bit, variant, EncVariant_12Bit); }
+       void setEncType(EncType type)                  { m_encoderType = qBound(EncType_MIN, type, EncType_MAX); }
+       void setEncArch(EncArch arch)                  { m_encoderArch = qBound(EncArch_MIN, arch, EncArch_MAX); }
+       void setEncVariant(EncVariant variant)         { m_encoderVariant = qBound(EncVariant_MIN, variant, EncVariant_MAX); }
        void setRCMode(RCMode mode)                    { m_rcMode = qBound(RCMode_CRF, mode, RCMode_ABR); }
        void setBitrate(unsigned int bitrate)          { m_bitrate = qBound(10U, bitrate, 800000U); }
        void setQuantizer(double quantizer)            { m_quantizer = qBound(0.0, quantizer, 52.0); }
index a210085..8041456 100644 (file)
@@ -145,8 +145,9 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, const SysinfoMo
        success = true;
 
        //Create list of all required binary files
-       QStringList binFiles;
-       for(OptionsModel::EncType encdr = OptionsModel::EncType_X264; encdr <= OptionsModel::EncType_X265; NEXT(encdr))
+       typedef QPair<QString, bool> FileEntry;
+       QList<FileEntry> binFiles;
+       for(OptionsModel::EncType encdr = OptionsModel::EncType_MIN; encdr <= OptionsModel::EncType_MAX; NEXT(encdr))
        {
                const AbstractEncoderInfo &encInfo = EncoderFactory::getEncoderInfo(encdr);
                const QFlags<OptionsModel::EncVariant> variants = encInfo.getVariants();
@@ -156,34 +157,42 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, const SysinfoMo
                        {
                                if(variants.testFlag(varnt))
                                {
-                                       binFiles << encInfo.getBinaryPath(sysinfo, arch, varnt);
+                                       binFiles << qMakePair(encInfo.getBinaryPath(sysinfo, arch, varnt), false);
+                                       const QStringList dependencies = encInfo.getDependencies(sysinfo, arch, varnt);
+                                       if (!dependencies.empty())
+                                       {
+                                               for (QStringList::ConstIterator iter = dependencies.constBegin(); iter != dependencies.constEnd(); iter++)
+                                               {
+                                                       binFiles << qMakePair(*iter, true);
+                                               }
+                                       }
                                }
                        }
                }
        }
        for(int i = 0; i < 2; i++)
        {
-               binFiles << SourceFactory::getSourceInfo(SourceFactory::SourceType_AVS).getBinaryPath(sysinfo, bool(i));
-               binFiles << AVS_CHECK_BINARY(sysinfo, bool(i));
+               binFiles << qMakePair(SourceFactory::getSourceInfo(SourceFactory::SourceType_AVS).getBinaryPath(sysinfo, bool(i)), false);
+               binFiles << qMakePair(AVS_CHECK_BINARY(sysinfo, bool(i)), false);
        }
        for(size_t i = 0; UpdaterDialog::BINARIES[i].name; i++)
        {
                if(UpdaterDialog::BINARIES[i].exec)
                {
-                       binFiles << QString("%1/toolset/common/%2").arg(sysinfo->getAppPath(), QString::fromLatin1(UpdaterDialog::BINARIES[i].name));
+                       binFiles << qMakePair(QString("%1/toolset/common/%2").arg(sysinfo->getAppPath(), QString::fromLatin1(UpdaterDialog::BINARIES[i].name)), false);
                }
        }
 
        //Actually validate the binaries
        size_t currentFile = 0;
-       for(QStringList::ConstIterator iter = binFiles.constBegin(); iter != binFiles.constEnd(); iter++)
+       for(QList<FileEntry>::ConstIterator iter = binFiles.constBegin(); iter != binFiles.constEnd(); iter++)
        {
-               QScopedPointer<QFile> file(new QFile(*iter));
+               QScopedPointer<QFile> file(new QFile(iter->first));
                qDebug("%s", MUTILS_UTF8(file->fileName()));
 
                if(file->open(QIODevice::ReadOnly))
                {
-                       if(!MUtils::OS::is_executable_file(file->fileName()))
+                       if(!(iter->second || MUtils::OS::is_executable_file(file->fileName())))
                        {
                                success = false;
                                qWarning("Required tool does NOT look like a valid Win32/Win64 binary:\n%s\n", MUTILS_UTF8(file->fileName()));
index e55ab3a..8164c4d 100644 (file)
@@ -26,7 +26,7 @@
 #define VER_X264_MAJOR 2
 #define VER_X264_MINOR 7
 #define VER_X264_PATCH 0
-#define VER_X264_BUILD 1026
+#define VER_X264_BUILD 1028
 
 #define VER_X264_PORTABLE_EDITION (0)
 
index f503ca0..eacbd80 100644 (file)
@@ -322,8 +322,9 @@ AddJobDialog::AddJobDialog(QWidget *parent, OptionsModel *const options, Recentl
        setMaximumHeight(height());
 
        //Init encoder combobox
-       ui->cbxEncoderType->addItem(tr("x264 (AVC)"), OptionsModel::EncType_X264);
+       ui->cbxEncoderType->addItem(tr("x264 (AVC)"),  OptionsModel::EncType_X264);
        ui->cbxEncoderType->addItem(tr("x265 (HEVC)"), OptionsModel::EncType_X265);
+       ui->cbxEncoderType->addItem(tr("NVEncC"),      OptionsModel::EncType_NVEnc);
 
        //Init arch combobox
        ui->cbxEncoderArch->addItem(tr("32-Bit"), OptionsModel::EncArch_x86_32);
index 885c41e..2c3ef5b 100644 (file)
@@ -167,6 +167,8 @@ mkdir "$(TargetDir)\imageformats"
 
 copy /Y "$(SolutionDir)res\toolset\x86\*.exe" "$(TargetDir)\toolset\x86\"
 copy /Y "$(SolutionDir)res\toolset\x64\*.exe" "$(TargetDir)\toolset\x64\"
+copy /Y "$(SolutionDir)res\toolset\x86\*.dll" "$(TargetDir)\toolset\x86\"
+copy /Y "$(SolutionDir)res\toolset\x64\*.dll" "$(TargetDir)\toolset\x64\"
 copy /Y "$(SolutionDir)res\toolset\common\*.exe" "$(TargetDir)\toolset\common\"
 copy /Y "$(SolutionDir)res\toolset\common\*.gpg" "$(TargetDir)\toolset\common\"
 
@@ -285,6 +287,7 @@ copy /Y "$(ProjectDir)\..\Prerequisites\Qt4\$(PlatformToolset)\Shared\plugins\im
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)tmp\$(ProjectName)\MOC_%(Filename).cpp;%(Outputs)</Outputs>
     </CustomBuild>
+    <ClInclude Include="src\encoder_nvenc.h" />
     <ClInclude Include="src\source_factory.h" />
     <ClInclude Include="tmp\x264_launcher\UIC_win_about.h" />
     <ClInclude Include="tmp\x264_launcher\UIC_win_addJob.h" />
@@ -428,6 +431,7 @@ copy /Y "$(ProjectDir)\..\Prerequisites\Qt4\$(PlatformToolset)\Shared\plugins\im
   <ItemGroup>
     <ClCompile Include="src\encoder_abstract.cpp" />
     <ClCompile Include="src\encoder_factory.cpp" />
+    <ClCompile Include="src\encoder_nvenc.cpp" />
     <ClCompile Include="src\encoder_x264.cpp" />
     <ClCompile Include="src\encoder_x265.cpp" />
     <ClCompile Include="src\job_object.cpp" />
index 2aa795a..40db07c 100644 (file)
     <ClInclude Include="src\source_factory.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="src\encoder_nvenc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\main.cpp">
     <ClCompile Include="src\source_factory.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="src\encoder_nvenc.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="src\win_main.h">