From 36ecf72d93a58f3fded2bdffd07d5b166669f5c9 Mon Sep 17 00:00:00 2001 From: lordmulder Date: Sun, 8 May 2016 15:33:09 +0200 Subject: [PATCH] Some re-design of AbstractEncoderInfo to allow more flexible encoder variants and RC modes. --- src/encoder_abstract.cpp | 39 +++++++++++++- src/encoder_abstract.h | 40 +++++++++++---- src/encoder_nvenc.cpp | 129 +++++++++++++++++++++++++---------------------- src/encoder_x264.cpp | 111 +++++++++++++++++----------------------- src/encoder_x265.cpp | 107 +++++++++++++++------------------------ src/model_jobList.cpp | 24 ++++----- src/model_options.cpp | 56 +++++++------------- src/model_options.h | 50 ++++-------------- src/thread_binaries.cpp | 42 +++++++++------ src/thread_encode.cpp | 4 +- 10 files changed, 292 insertions(+), 310 deletions(-) diff --git a/src/encoder_abstract.cpp b/src/encoder_abstract.cpp index 8ca9e44..b9fa88c 100644 --- a/src/encoder_abstract.cpp +++ b/src/encoder_abstract.cpp @@ -293,12 +293,47 @@ QString AbstractEncoder::sizeToString(qint64 size) // Encoder Info // ------------------------------------------------------------ +template +static T getElementAt(const QList &list, const quint32 &index) +{ + if (index >= quint32(list.count())) + { + MUTILS_THROW("Index is out of bounds!"); + } + return list[index]; +} + 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 +QStringList AbstractEncoderInfo::getDependencies(const SysinfoModel *sysinfo, const quint32 &encArch, const quint32 &encVariant) const { return QStringList(); -} \ No newline at end of file +} + +QString AbstractEncoderInfo::getFullName(const quint32 &encArch, const quint32 &encVariant) const +{ + return QString("%1, %2, %3").arg(getName(), archToString(encArch), variantToString(encVariant)); +} + +QString AbstractEncoderInfo::archToString(const quint32 &index) const +{ + return getElementAt(getArchitectures(), index); +} + +QString AbstractEncoderInfo::variantToString(const quint32 &index) const +{ + return getElementAt(getVariants(), index); +} + +QString AbstractEncoderInfo::rcModeToString(const quint32 &index) const +{ + return getElementAt(getRCModes(), index).first; +} + +AbstractEncoderInfo::RCType AbstractEncoderInfo::rcModeToType(const quint32 &index) const +{ + return getElementAt(getRCModes(), index).second; +} diff --git a/src/encoder_abstract.h b/src/encoder_abstract.h index 731ea62..f51ca95 100644 --- a/src/encoder_abstract.h +++ b/src/encoder_abstract.h @@ -17,7 +17,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // http://www.gnu.org/licenses/gpl-2.0.txt -/////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// #pragma once @@ -26,20 +26,40 @@ class QRegExp; template class QList; +template struct QPair; class AbstractSource; class AbstractEncoderInfo { public: - virtual QFlags getVariants(void) const = 0; - virtual QStringList getProfiles(const OptionsModel::EncVariant &variant) const = 0; - virtual QStringList getTunings(void) const = 0; - virtual QStringList getPresets(void) const = 0; - virtual QStringList supportedOutputFormats(void) const = 0; - 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; + typedef enum _RCType + { + RC_TYPE_QUANTIZER = 0, + RC_TYPE_RATE_KBPS = 1, + RC_TYPE_MULTIPASS = 2 + } + RCType; + + typedef QPair RCMode; + + virtual QString getName(void) const = 0; + virtual QString getFullName(const quint32 &encArch, const quint32 &encVariant) const; + virtual QStringList getArchitectures(void) const = 0; + virtual QStringList getVariants(void) const = 0; + virtual QList getRCModes(void) const = 0; + virtual QStringList getProfiles(const quint32 &variant) const = 0; + virtual QStringList getTunings(void) const = 0; + virtual QStringList getPresets(void) const = 0; + virtual QStringList supportedOutputFormats(void) const = 0; + virtual bool isInputTypeSupported(const int format) const = 0; + virtual QString getBinaryPath(const SysinfoModel *sysinfo, const quint32 &encArch, const quint32 &encVariant) const = 0; + virtual QStringList getDependencies(const SysinfoModel *sysinfo, const quint32 &encArch, const quint32 &encVariant) const; + + //Utilities + QString archToString (const quint32 &index) const; + QString variantToString(const quint32 &index) const; + QString rcModeToString (const quint32 &index) const; + RCType rcModeToType (const quint32 &index) const; }; class AbstractEncoder : public AbstractTool diff --git a/src/encoder_nvenc.cpp b/src/encoder_nvenc.cpp index 75ccbd3..299da31 100644 --- a/src/encoder_nvenc.cpp +++ b/src/encoder_nvenc.cpp @@ -35,6 +35,7 @@ #include #include #include +#include //x265 version info static const unsigned int VERSION_NVENCC_MINIMUM_VER = 206; @@ -88,11 +89,28 @@ while(0) class NVEncEncoderInfo : public AbstractEncoderInfo { public: - virtual QFlags getVariants(void) const + virtual QString getName(void) const { - QFlags variants; - variants |= OptionsModel::EncVariant_8Bit; - return variants; + return "NVEncC"; + } + + virtual QStringList getArchitectures(void) const + { + return QStringList() << "32-Bit (x86)" << "64-Bit (x64)"; + } + + virtual QStringList getVariants(void) const + { + return QStringList() << "AVC" << "HEVC"; + } + + virtual QList getRCModes(void) const + { + return QList() + << qMakePair(QString("CQP"), RC_TYPE_QUANTIZER) + << qMakePair(QString("VBR"), RC_TYPE_RATE_KBPS) + << qMakePair(QString("VBR2"), RC_TYPE_RATE_KBPS) + << qMakePair(QString("CBR"), RC_TYPE_RATE_KBPS); } virtual QStringList getTunings(void) const @@ -105,14 +123,14 @@ public: return QStringList(); } - virtual QStringList getProfiles(const OptionsModel::EncVariant &variant) const + virtual QStringList getProfiles(const quint32 &variant) const { QStringList profiles; switch(variant) { - case OptionsModel::EncVariant_8Bit: - profiles << "baseline" << "main" << "high"; - break; + case 0: profiles << "baseline" << "main" << "high"; break; + case 1: profiles << "main"; break; + default: MUTILS_THROW("Unknown encoder variant!"); } return profiles; } @@ -124,18 +142,6 @@ public: 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) @@ -147,52 +153,54 @@ public: } } - virtual QString getBinaryPath(const SysinfoModel *sysinfo, const OptionsModel::EncArch &encArch, const OptionsModel::EncVariant &encVariant) const + virtual QString getBinaryPath(const SysinfoModel *sysinfo, const quint32 &encArch, const quint32 &encVariant) const { - QString arch, variant; + QString arch; switch(encArch) { - case OptionsModel::EncArch_x86_32: arch = "x86"; break; - case OptionsModel::EncArch_x86_64: arch = "x64"; break; + case 0: arch = "x86"; break; + case 1: arch = "x64"; break; default: MUTILS_THROW("Unknown encoder arch!"); } switch(encVariant) { - case OptionsModel::EncVariant_8Bit: variant = "8bit"; break; - default: MUTILS_THROW("Unknown encoder arch!"); + case 0: break; + case 1: break; + default: MUTILS_THROW("Unknown encoder variant!"); } 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 + virtual QStringList getDependencies(const SysinfoModel *sysinfo, const quint32 &encArch, const quint32 &encVariant) const { - QString arch, variant; + QString arch; switch (encArch) { - case OptionsModel::EncArch_x86_32: arch = "x86"; break; - case OptionsModel::EncArch_x86_64: arch = "x64"; break; + case 0: arch = "x86"; break; + case 1: arch = "x64"; break; default: MUTILS_THROW("Unknown encoder arch!"); } switch (encVariant) { - case OptionsModel::EncVariant_8Bit: variant = "8bit"; break; - default: MUTILS_THROW("Unknown encoder arch!"); + case 0: break; + case 1: break; + default: MUTILS_THROW("Unknown encoder variant!"); + } - 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; + return QStringList() + << QString("%1/toolset/%2/avcodec-57.dll" ).arg(sysinfo->getAppPath(), arch) + << QString("%1/toolset/%2/avfilter-6.dll" ).arg(sysinfo->getAppPath(), arch) + << QString("%1/toolset/%2/avformat-57.dll" ).arg(sysinfo->getAppPath(), arch) + << QString("%1/toolset/%2/avutil-55.dll" ).arg(sysinfo->getAppPath(), arch) + << QString("%1/toolset/%2/swresample-2.dll").arg(sysinfo->getAppPath(), arch); } }; -static const NVEncEncoderInfo s_x265EncoderInfo; +static const NVEncEncoderInfo s_nvencEncoderInfo; const AbstractEncoderInfo &NVEncEncoder::getEncoderInfo(void) { - return s_x265EncoderInfo; + return s_nvencEncoderInfo; } // ------------------------------------------------------------ @@ -216,19 +224,7 @@ NVEncEncoder::~NVEncEncoder(void) 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); + return s_nvencEncoderInfo.getFullName(m_options->encArch(), m_options->encVariant()); } // ------------------------------------------------------------ @@ -313,19 +309,34 @@ bool NVEncEncoder::isVersionSupported(const unsigned int &revision, const bool & 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->encVariant()) + { + case 0: + cmdLine << "--codec" << "avc"; + break; + case 1: + cmdLine << "--codec" << "hevc"; + break; + default: + MUTILS_THROW("Bad encoder variant !!!"); + } switch(m_options->rcMode()) { - case OptionsModel::RCMode_ABR: + case 0: + cmdLine << "--cqp" << QString::number(qRound(m_options->quantizer())); + break; + case 1: cmdLine << "--vbr" << QString::number(m_options->bitrate()); break; - case OptionsModel::RCMode_CQ: - cmdLine << "--cqp" << QString::number(qRound(m_options->quantizer())); + case 2: + cmdLine << "--vbr2" << QString::number(m_options->bitrate()); + break; + case 3: + cmdLine << "--cbr" << QString::number(m_options->bitrate()); break; default: MUTILS_THROW("Bad rate-control mode !!!"); - break; } const QString profile = m_options->profile().simplified().toLower(); diff --git a/src/encoder_x264.cpp b/src/encoder_x264.cpp index 83367a1..d784c18 100644 --- a/src/encoder_x264.cpp +++ b/src/encoder_x264.cpp @@ -35,6 +35,7 @@ #include #include #include +#include //x264 version info static const unsigned int VERSION_X264_MINIMUM_REV = 2668; @@ -89,67 +90,60 @@ while(0) class X264EncoderInfo : public AbstractEncoderInfo { public: - virtual QFlags getVariants(void) const + virtual QString getName(void) const { - QFlags variants; - variants |= OptionsModel::EncVariant_8Bit; - variants |= OptionsModel::EncVariant_10Bit; - return variants; + return "x264 (AVC/H.264)"; + } + + virtual QStringList getArchitectures(void) const + { + return QStringList() << "32-Bit (x86)" << "64-Bit (x64)"; + } + + virtual QStringList getVariants(void) const + { + return QStringList() << "8-Bit" << "10-Bit"; + } + + virtual QList getRCModes(void) const + { + return QList() + << qMakePair(QString("CRF"), RC_TYPE_QUANTIZER) + << qMakePair(QString("CQ"), RC_TYPE_QUANTIZER) + << qMakePair(QString("2-Pass"), RC_TYPE_MULTIPASS) + << qMakePair(QString("ABR"), RC_TYPE_RATE_KBPS); } virtual QStringList getTunings(void) const { - QStringList tunings; - tunings << "Film" << "Animation" << "Grain"; - tunings << "StillImage" << "PSNR" << "SSIM"; - tunings << "FastDecode" << "ZeroLatency" << "Touhou"; - - return tunings; + return QStringList() + << "Film" << "Animation" << "Grain" + << "StillImage" << "PSNR" << "SSIM" + << "FastDecode" << "ZeroLatency" << "Touhou"; } virtual QStringList getPresets(void) const { - QStringList presets; - presets << "ultrafast" << "superfast" << "veryfast" << "faster" << "fast"; - presets << "medium" << "slow" << "slower" << "veryslow" << "placebo"; - return presets; + return QStringList() + << "ultrafast" << "superfast" << "veryfast" << "faster" << "fast" + << "medium" << "slow" << "slower" << "veryslow" << "placebo"; } - virtual QStringList getProfiles(const OptionsModel::EncVariant &variant) const + virtual QStringList getProfiles(const quint32 &variant) const { QStringList profiles; - - if(variant == OptionsModel::EncVariant_8Bit) + switch(variant) { - profiles << "Baseline" << "Main" << "High"; + case 0: profiles << "Baseline" << "Main" << "High"; break; + case 1: profiles << "High10" << "High422" << "High444"; break; + default: MUTILS_THROW("Unknown encoder variant!"); } - if((variant == OptionsModel::EncVariant_8Bit) || (variant == OptionsModel::EncVariant_10Bit)) - { - profiles << "High10" << "High422" << "High444"; - } - return profiles; } virtual QStringList supportedOutputFormats(void) const { - QStringList extLst; - extLst << "264" << "mkv" << "mp4"; - return extLst; - } - - virtual bool isRCModeSupported(const OptionsModel::RCMode &rcMode) const - { - switch(rcMode) - { - case OptionsModel::RCMode_CRF: - case OptionsModel::RCMode_CQ: - case OptionsModel::RCMode_2Pass: - case OptionsModel::RCMode_ABR: - return true; - default: - return false; - } + return QStringList() << "264" << "mkv" << "mp4"; } virtual bool isInputTypeSupported(const int format) const @@ -165,20 +159,20 @@ public: } } - virtual QString getBinaryPath(const SysinfoModel *sysinfo, const OptionsModel::EncArch &encArch, const OptionsModel::EncVariant &encVariant) const + virtual QString getBinaryPath(const SysinfoModel *sysinfo, const quint32 &encArch, const quint32 &encVariant) const { QString arch, variant; switch(encArch) { - case OptionsModel::EncArch_x86_32: arch = "x86"; break; - case OptionsModel::EncArch_x86_64: arch = "x64"; break; + case 0: arch = "x86"; break; + case 1: arch = "x64"; break; default: MUTILS_THROW("Unknown encoder arch!"); } switch(encVariant) { - case OptionsModel::EncVariant_8Bit: variant = "8bit"; break; - case OptionsModel::EncVariant_10Bit: variant = "10bit"; break; - default: MUTILS_THROW("Unknown encoder arch!"); + case 0: variant = "8bit"; break; + case 1: variant = "10bit"; break; + default: MUTILS_THROW("Unknown encoder variant!"); } return QString("%1/toolset/%2/x264_%3_%2.exe").arg(sysinfo->getAppPath(), arch, variant); } @@ -212,20 +206,7 @@ X264Encoder::~X264Encoder(void) QString X264Encoder::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; - case OptionsModel::EncVariant_10Bit: variant = "10-Bit"; break; - default: MUTILS_THROW("Unknown encoder arch!"); - } - return QString("x264 (H.264/AVC), %1, %2").arg(arch, variant); + return s_x264EncoderInfo.getFullName(m_options->encArch(), m_options->encVariant()); } // ------------------------------------------------------------ @@ -317,15 +298,15 @@ void X264Encoder::buildCommandLine(QStringList &cmdLine, const bool &usePipe, co switch(m_options->rcMode()) { - case OptionsModel::RCMode_CQ: + case 0: cmdLine << "--qp" << QString::number(qRound(m_options->quantizer())); break; - case OptionsModel::RCMode_CRF: + case 1: crf_frc = modf(m_options->quantizer(), &crf_int); cmdLine << "--crf" << QString("%1.%2").arg(QString::number(qRound(crf_int)), QString::number(qRound(crf_frc * 10.0))); break; - case OptionsModel::RCMode_2Pass: - case OptionsModel::RCMode_ABR: + case 2: + case 3: cmdLine << "--bitrate" << QString::number(m_options->bitrate()); break; default: diff --git a/src/encoder_x265.cpp b/src/encoder_x265.cpp index fcf8ff5..22ebe3b 100644 --- a/src/encoder_x265.cpp +++ b/src/encoder_x265.cpp @@ -35,6 +35,7 @@ #include #include #include +#include //x265 version info static const unsigned int VERSION_X265_MINIMUM_VER = 19; @@ -89,67 +90,57 @@ while(0) class X265EncoderInfo : public AbstractEncoderInfo { public: - virtual QFlags getVariants(void) const + virtual QString getName(void) const { - QFlags variants; - variants |= OptionsModel::EncVariant_8Bit; - variants |= OptionsModel::EncVariant_10Bit; - variants |= OptionsModel::EncVariant_12Bit; - return variants; + return "x265 (HEVC/H.265)"; + } + + virtual QStringList getArchitectures(void) const + { + return QStringList() << "32-Bit (x86)" << "64-Bit (x64)"; + } + + virtual QStringList getVariants(void) const + { + return QStringList() << "8-Bit" << "10-Bit" << "12-Bit"; + } + virtual QList getRCModes(void) const + { + return QList() + << qMakePair(QString("CRF"), RC_TYPE_QUANTIZER) + << qMakePair(QString("CQ"), RC_TYPE_QUANTIZER) + << qMakePair(QString("2-Pass"), RC_TYPE_MULTIPASS) + << qMakePair(QString("ABR"), RC_TYPE_RATE_KBPS); } virtual QStringList getTunings(void) const { - QStringList tunings; - tunings << "Grain" << "PSNR" << "SSIM" << "FastDecode" << "ZeroLatency"; - return tunings; + return QStringList() << "Grain" << "PSNR" << "SSIM" << "FastDecode" << "ZeroLatency"; } virtual QStringList getPresets(void) const { - QStringList presets; - presets << "ultrafast" << "superfast" << "veryfast" << "faster" << "fast"; - presets << "medium" << "slow" << "slower" << "veryslow" << "placebo"; - return presets; + return QStringList() + << "ultrafast" << "superfast" << "veryfast" << "faster" << "fast" + << "medium" << "slow" << "slower" << "veryslow" << "placebo"; } - virtual QStringList getProfiles(const OptionsModel::EncVariant &variant) const + virtual QStringList getProfiles(const quint32 &variant) const { QStringList profiles; switch(variant) { - case OptionsModel::EncVariant_8Bit: - profiles << "main" << "main-intra" << "mainstillpicture" << "main444-8" << "main444-intra" << "main444-stillpicture"; - break; - case OptionsModel::EncVariant_10Bit: - profiles << "main10" << "main10-intra" << "main422-10" << "main422-10-intra" << "main444-10" << "main444-10-intra"; - break; - case OptionsModel::EncVariant_12Bit: - profiles << "main12" << "main12-intra" << "main422-12" << "main422-12-intra" << "main444-12" << "main444-12-intra"; - break; + case 0: profiles << "main" << "main-intra" << "mainstillpicture" << "main444-8" << "main444-intra" << "main444-stillpicture"; break; + case 1: profiles << "main10" << "main10-intra" << "main422-10" << "main422-10-intra" << "main444-10" << "main444-10-intra"; break; + case 2: profiles << "main12" << "main12-intra" << "main422-12" << "main422-12-intra" << "main444-12" << "main444-12-intra"; break; + default: MUTILS_THROW("Unknown encoder variant!"); } return profiles; } virtual QStringList supportedOutputFormats(void) const { - QStringList extLst; - extLst << "hevc"; - return extLst; - } - - virtual bool isRCModeSupported(const OptionsModel::RCMode &rcMode) const - { - switch(rcMode) - { - case OptionsModel::RCMode_CRF: - case OptionsModel::RCMode_CQ: - case OptionsModel::RCMode_2Pass: - case OptionsModel::RCMode_ABR: - return true; - default: - return false; - } + return QStringList() << "hevc"; } virtual bool isInputTypeSupported(const int format) const @@ -163,20 +154,20 @@ public: } } - virtual QString getBinaryPath(const SysinfoModel *sysinfo, const OptionsModel::EncArch &encArch, const OptionsModel::EncVariant &encVariant) const + virtual QString getBinaryPath(const SysinfoModel *sysinfo, const quint32 &encArch, const quint32 &encVariant) const { QString arch, variant; switch(encArch) { - case OptionsModel::EncArch_x86_32: arch = "x86"; break; - case OptionsModel::EncArch_x86_64: arch = "x64"; break; + case 0: arch = "x86"; break; + case 1: arch = "x64"; break; default: MUTILS_THROW("Unknown encoder arch!"); } switch(encVariant) { - case OptionsModel::EncVariant_8Bit: variant = "8bit"; break; - case OptionsModel::EncVariant_10Bit: variant = "10bit"; break; - case OptionsModel::EncVariant_12Bit: variant = "12bit"; break; + case 0: variant = "8bit"; break; + case 1: variant = "10bit"; break; + case 2: variant = "12bit"; break; default: MUTILS_THROW("Unknown encoder arch!"); } return QString("%1/toolset/%2/x265_%3_%2.exe").arg(sysinfo->getAppPath(), arch, variant); @@ -211,21 +202,7 @@ X265Encoder::~X265Encoder(void) QString X265Encoder::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; - case OptionsModel::EncVariant_10Bit: variant = "10-Bit"; break; - case OptionsModel::EncVariant_12Bit: variant = "12-Bit"; break; - default: MUTILS_THROW("Unknown encoder arch!"); - } - return QString("x265 (H.265/HEVC), %1, %2").arg(arch, variant); + return s_x265EncoderInfo.getFullName(m_options->encArch(), m_options->encVariant()); } // ------------------------------------------------------------ @@ -312,15 +289,15 @@ void X265Encoder::buildCommandLine(QStringList &cmdLine, const bool &usePipe, co switch(m_options->rcMode()) { - case OptionsModel::RCMode_CQ: + case 0: cmdLine << "--qp" << QString::number(qRound(m_options->quantizer())); break; - case OptionsModel::RCMode_CRF: + case 1: crf_frc = modf(m_options->quantizer(), &crf_int); cmdLine << "--crf" << QString("%1.%2").arg(QString::number(qRound(crf_int)), QString::number(qRound(crf_frc * 10.0))); break; - case OptionsModel::RCMode_2Pass: - case OptionsModel::RCMode_ABR: + case 2: + case 3: cmdLine << "--bitrate" << QString::number(m_options->bitrate()); break; default: diff --git a/src/model_jobList.cpp b/src/model_jobList.cpp index 7a83a9e..d30c673 100644 --- a/src/model_jobList.cpp +++ b/src/model_jobList.cpp @@ -23,6 +23,7 @@ #include "global.h" #include "model_jobList.h" #include "thread_encode.h" +#include "encoder_factory.h" #include "model_options.h" #include "model_preferences.h" #include "resource.h" @@ -245,24 +246,21 @@ QModelIndex JobListModel::insertJob(EncodeThread *thread) return QModelIndex(); } - QString config = QLatin1String("N/A"); - switch(thread->options()->encType()) + const AbstractEncoderInfo &encoderInfo = EncoderFactory::getEncoderInfo(thread->options()->encType()); + QString config = encoderInfo.getName(); + switch(encoderInfo.rcModeToType(thread->options()->rcMode())) { - case OptionsModel::EncType_X264: config = QLatin1String("x264"); break; - case OptionsModel::EncType_X265: config = QLatin1String("x265"); break; - } - - switch(thread->options()->rcMode()) - { - case OptionsModel::RCMode_CRF: config.append(QString(" CRF@%1") .arg(QString::number(thread->options()->quantizer()))); break; - case OptionsModel::RCMode_CQ: config.append(QString(" CQ@%1") .arg(QString::number(qRound(thread->options()->quantizer())))); break; - case OptionsModel::RCMode_2Pass: config.append(QString(" 2Pass@%1").arg(QString::number(thread->options()->bitrate()))); break; - case OptionsModel::RCMode_ABR: config.append(QString(" ABR@%1") .arg(QString::number(thread->options()->bitrate()))); break; + case AbstractEncoderInfo::RC_TYPE_QUANTIZER: + config.append(QString(", %1@%2").arg(encoderInfo.rcModeToString(thread->options()->rcMode()), QString::number(qRound(thread->options()->quantizer())))); + break; + case AbstractEncoderInfo::RC_TYPE_RATE_KBPS: + case AbstractEncoderInfo::RC_TYPE_MULTIPASS: + config.append(QString(", %1@%2").arg(encoderInfo.rcModeToString(thread->options()->rcMode()), QString::number(thread->options()->bitrate()))); + break; } int n = 2; QString jobName = QString("%1 (%2)").arg(QFileInfo(thread->sourceFileName()).completeBaseName().simplified(), config); - forever { bool unique = true; diff --git a/src/model_options.cpp b/src/model_options.cpp index 8d5b203..41a4866 100644 --- a/src/model_options.cpp +++ b/src/model_options.cpp @@ -57,9 +57,9 @@ const char *const OptionsModel::PROFILE_UNRESTRICTED = ""; OptionsModel::OptionsModel(const SysinfoModel *sysinfo) { m_encoderType = EncType_X264; - m_encoderArch = sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64) ? EncArch_x86_64 : EncArch_x86_32; - m_encoderVariant = EncVariant_8Bit; - m_rcMode = RCMode_CRF; + m_encoderArch = sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64) ? 0 : 1; + m_encoderVariant = 0; + m_rcMode = 0; m_bitrate = 1200; m_quantizer = 22; m_preset = "Medium"; @@ -88,28 +88,6 @@ OptionsModel::~OptionsModel(void) { } -QString OptionsModel::rcMode2String(RCMode mode) -{ - switch(mode) - { - case RCMode_CRF: - return QObject::tr("CRF"); - break; - case RCMode_CQ: - return QObject::tr("CQ"); - break; - case RCMode_2Pass: - return QObject::tr("2-Pass"); - break; - case RCMode_ABR: - return QObject::tr("ABR"); - break; - default: - return QString(); - break; - } -} - bool OptionsModel::equals(const OptionsModel *model) { bool equal = true; @@ -251,17 +229,17 @@ bool OptionsModel::loadOptions(OptionsModel *model, QSettings &settingsFile) if(complete) { - model->setEncType (static_cast (settingsFile.value(KEY_ENCODER_TYPE, model->m_encoderType) .toInt())); - model->setEncArch (static_cast (settingsFile.value(KEY_ENCODER_ARCH, model->m_encoderArch) .toInt())); - model->setEncVariant (static_cast(settingsFile.value(KEY_ENCODER_VARIANT, model->m_encoderVariant).toInt())); - model->setRCMode (static_cast (settingsFile.value(KEY_RATECTRL_MODE, model->m_rcMode) .toInt())); - model->setBitrate (settingsFile.value(KEY_TARGET_BITRATE, model->m_bitrate) .toUInt() ); - model->setQuantizer (settingsFile.value(KEY_TARGET_QUANT, model->m_quantizer) .toDouble()); - model->setPreset (settingsFile.value(KEY_PRESET_NAME, model->m_preset) .toString()); - model->setTune (settingsFile.value(KEY_TUNING_NAME, model->m_tune) .toString()); - model->setProfile (settingsFile.value(KEY_PROFILE_NAME, model->m_profile) .toString()); - model->setCustomEncParams(settingsFile.value(KEY_CUSTOM_ENCODER, model->m_custom_encoder).toString()); - model->setCustomAvs2YUV (settingsFile.value(KEY_CUSTOM_AVS2YUV, model->m_custom_avs2yuv).toString()); + model->setEncType (settingsFile.value(KEY_ENCODER_TYPE, model->m_encoderType) .toInt()); + model->setEncArch (settingsFile.value(KEY_ENCODER_ARCH, model->m_encoderArch) .toInt()); + model->setEncVariant (settingsFile.value(KEY_ENCODER_VARIANT, model->m_encoderVariant).toInt()); + model->setRCMode (settingsFile.value(KEY_RATECTRL_MODE, model->m_rcMode) .toInt()); + model->setBitrate (settingsFile.value(KEY_TARGET_BITRATE, model->m_bitrate) .toUInt()); + model->setQuantizer (settingsFile.value(KEY_TARGET_QUANT, model->m_quantizer) .toDouble()); + model->setPreset (settingsFile.value(KEY_PRESET_NAME, model->m_preset) .toString()); + model->setTune (settingsFile.value(KEY_TUNING_NAME, model->m_tune) .toString()); + model->setProfile (settingsFile.value(KEY_PROFILE_NAME, model->m_profile) .toString()); + model->setCustomEncParams(settingsFile.value(KEY_CUSTOM_ENCODER, model->m_custom_encoder).toString()); + model->setCustomAvs2YUV (settingsFile.value(KEY_CUSTOM_AVS2YUV, model->m_custom_avs2yuv).toString()); } return complete; @@ -271,9 +249,9 @@ void OptionsModel::fixTemplate(QSettings &settingsFile) { if(!(settingsFile.contains(KEY_ENCODER_TYPE) || settingsFile.contains(KEY_ENCODER_ARCH) || settingsFile.contains(KEY_ENCODER_VARIANT))) { - settingsFile.setValue(KEY_ENCODER_TYPE, OptionsModel::EncType_X264); - settingsFile.setValue(KEY_ENCODER_ARCH, OptionsModel::EncArch_x86_32); - settingsFile.setValue(KEY_ENCODER_VARIANT, OptionsModel::EncVariant_8Bit); + settingsFile.setValue(KEY_ENCODER_TYPE, 0); + settingsFile.setValue(KEY_ENCODER_ARCH, 0); + settingsFile.setValue(KEY_ENCODER_VARIANT, 0); } static const char *legacyKey[] = { "custom_params", "custom_params_x264", NULL }; diff --git a/src/model_options.h b/src/model_options.h index 38f1f3c..4ffe831 100644 --- a/src/model_options.h +++ b/src/model_options.h @@ -45,44 +45,14 @@ public: EncType_MAX = EncType_NVEnc, }; - enum EncArch - { - EncArch_x86_32 = 0, - EncArch_x86_64 = 1, - - EncArch_MIN = EncArch_x86_32, - EncArch_MAX = EncArch_x86_64 - }; - - enum EncVariant - { - EncVariant_8Bit = 1, - EncVariant_10Bit = 2, - EncVariant_12Bit = 4, - - EncVariant_MIN = EncVariant_8Bit, - EncVariant_MAX = EncVariant_12Bit - }; - - enum RCMode - { - RCMode_CRF = 0, - RCMode_CQ = 1, - RCMode_2Pass = 2, - RCMode_ABR = 3, - - RCMode_MIN = RCMode_CRF, - RCMode_MAX = RCMode_ABR, - }; - static const char *const SETTING_UNSPECIFIED; static const char *const PROFILE_UNRESTRICTED; //Getter EncType encType(void) const { return m_encoderType; } - EncArch encArch(void) const { return m_encoderArch; } - EncVariant encVariant(void) const { return m_encoderVariant; } - RCMode rcMode(void) const { return m_rcMode; } + quint32 encArch(void) const { return m_encoderArch; } + quint32 encVariant(void) const { return m_encoderVariant; } + quint32 rcMode(void) const { return m_rcMode; } unsigned int bitrate(void) const { return m_bitrate; } double quantizer(void) const { return m_quantizer; } QString preset(void) const { return m_preset; } @@ -92,10 +62,11 @@ public: QString customAvs2YUV(void) const { return m_custom_avs2yuv; } //Setter + void setEncType(quint32 type) { setEncType(static_cast(type)); } 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 setEncArch(quint32 arch) { m_encoderArch = arch; } + void setEncVariant(quint32 variant) { m_encoderVariant = variant; } + void setRCMode(quint32 mode) { m_rcMode = mode; } void setBitrate(unsigned int bitrate) { m_bitrate = qBound(10U, bitrate, 800000U); } void setQuantizer(double quantizer) { m_quantizer = qBound(0.0, quantizer, 52.0); } void setPreset(const QString &preset) { m_preset = preset.trimmed(); } @@ -108,7 +79,6 @@ public: bool equals(const OptionsModel *model); //Static functions - static QString rcMode2String(RCMode mode); static bool saveTemplate(const OptionsModel *model, const QString &name); static bool loadTemplate(OptionsModel *model, const QString &name); static QMap loadAllTemplates(const SysinfoModel *sysinfo); @@ -119,9 +89,9 @@ public: protected: EncType m_encoderType; - EncArch m_encoderArch; - EncVariant m_encoderVariant; - RCMode m_rcMode; + quint32 m_encoderArch; + quint32 m_encoderVariant; + quint32 m_rcMode; unsigned int m_bitrate; double m_quantizer; QString m_preset; diff --git a/src/thread_binaries.cpp b/src/thread_binaries.cpp index 8041456..9a6a974 100644 --- a/src/thread_binaries.cpp +++ b/src/thread_binaries.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -150,23 +151,22 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, const SysinfoMo for(OptionsModel::EncType encdr = OptionsModel::EncType_MIN; encdr <= OptionsModel::EncType_MAX; NEXT(encdr)) { const AbstractEncoderInfo &encInfo = EncoderFactory::getEncoderInfo(encdr); - const QFlags variants = encInfo.getVariants(); - for(OptionsModel::EncArch arch = OptionsModel::EncArch_x86_32; arch <= OptionsModel::EncArch_x86_64; NEXT(arch)) + const QStringList archs = encInfo.getArchitectures(), variants = encInfo.getVariants(); + QSet dependencySet; + for (quint32 archIdx = 0; archIdx < quint32(archs.count()); ++archIdx) { - for(OptionsModel::EncVariant varnt = OptionsModel::EncVariant_MIN; varnt <= OptionsModel::EncVariant_MAX; SHFL(varnt)) + for (quint32 varntIdx = 0; varntIdx < quint32(variants.count()); ++varntIdx) { - if(variants.testFlag(varnt)) + const QStringList dependencies = encInfo.getDependencies(sysinfo, archIdx, varntIdx); + for (QStringList::ConstIterator iter = dependencies.constBegin(); iter != dependencies.constEnd(); iter++) { - binFiles << qMakePair(encInfo.getBinaryPath(sysinfo, arch, varnt), false); - const QStringList dependencies = encInfo.getDependencies(sysinfo, arch, varnt); - if (!dependencies.empty()) + if (!dependencySet.contains(*iter)) { - for (QStringList::ConstIterator iter = dependencies.constBegin(); iter != dependencies.constEnd(); iter++) - { - binFiles << qMakePair(*iter, true); - } + dependencySet << (*iter); + binFiles << qMakePair(*iter, true); } } + binFiles << qMakePair(encInfo.getBinaryPath(sysinfo, archIdx, varntIdx), false); } } } @@ -192,11 +192,23 @@ void BinariesCheckThread::checkBinaries3(volatile bool &success, const SysinfoMo if(file->open(QIODevice::ReadOnly)) { - if(!(iter->second || MUtils::OS::is_executable_file(file->fileName()))) + if(!iter->second) { - success = false; - qWarning("Required tool does NOT look like a valid Win32/Win64 binary:\n%s\n", MUTILS_UTF8(file->fileName())); - return; + if (!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())); + return; + } + } + else + { + if (!MUtils::OS::is_library_file(file->fileName())) + { + success = false; + qWarning("Required tool does NOT look like a valid Win32/Win64 library:\n%s\n", MUTILS_UTF8(file->fileName())); + return; + } } if(currentFile < MAX_BINARIES) { diff --git a/src/thread_encode.cpp b/src/thread_encode.cpp index 82c439f..318c9c2 100644 --- a/src/thread_encode.cpp +++ b/src/thread_encode.cpp @@ -260,7 +260,7 @@ void EncodeThread::encode(void) log(tr("\n--- SETTINGS ---\n")); log(tr("Encoder : %1").arg(m_encoder->getName())); log(tr("Source : %1").arg(m_pipedSource ? m_pipedSource->getName() : tr("Native"))); - log(tr("RC Mode : %1").arg(OptionsModel::rcMode2String(m_options->rcMode()))); + log(tr("RC Mode : %1").arg(m_encoder->getEncoderInfo().rcModeToString(m_options->rcMode()))); log(tr("Preset : %1").arg(m_options->preset())); log(tr("Tuning : %1").arg(m_options->tune())); log(tr("Profile : %1").arg(m_options->profile())); @@ -326,7 +326,7 @@ void EncodeThread::encode(void) // ----------------------------------------------------------------------------------- //Run encoding passes - if(m_options->rcMode() == OptionsModel::RCMode_2Pass) + if(m_encoder->getEncoderInfo().rcModeToType(m_options->rcMode()) == AbstractEncoderInfo::RC_TYPE_MULTIPASS) { const QString passLogFile = getPasslogFile(m_outputFileName); -- 2.11.4.GIT