diff --git a/src/encoder_abstract.cpp b/src/encoder_abstract.cpp index b9fa88c..6f1fec8 100644 --- a/src/encoder_abstract.cpp +++ b/src/encoder_abstract.cpp @@ -303,11 +303,6 @@ static T getElementAt(const QList &list, const quint32 &index) 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 quint32 &encArch, const quint32 &encVariant) const { return QStringList(); @@ -320,7 +315,12 @@ QString AbstractEncoderInfo::getFullName(const quint32 &encArch, const quint32 & QString AbstractEncoderInfo::archToString(const quint32 &index) const { - return getElementAt(getArchitectures(), index); + return getElementAt(getArchitectures(), index).first; +} + +AbstractEncoderInfo::ArchBit AbstractEncoderInfo::archToType(const quint32 &index) const +{ + return getElementAt(getArchitectures(), index).second; } QString AbstractEncoderInfo::variantToString(const quint32 &index) const diff --git a/src/encoder_abstract.h b/src/encoder_abstract.h index f51ca95..6913cbd 100644 --- a/src/encoder_abstract.h +++ b/src/encoder_abstract.h @@ -40,11 +40,19 @@ public: } RCType; - typedef QPair RCMode; + typedef enum _ArchBit + { + ARCH_TYPE_X86 = 0, + ARCH_TYPE_X64 = 1, + } + ArchBit; + + typedef QPair RCMode; + typedef QPair ArchId; virtual QString getName(void) const = 0; virtual QString getFullName(const quint32 &encArch, const quint32 &encVariant) const; - virtual QStringList getArchitectures(void) const = 0; + virtual QList getArchitectures(void) const = 0; virtual QStringList getVariants(void) const = 0; virtual QList getRCModes(void) const = 0; virtual QStringList getProfiles(const quint32 &variant) const = 0; @@ -57,6 +65,7 @@ public: //Utilities QString archToString (const quint32 &index) const; + ArchBit archToType (const quint32 &index) const; QString variantToString(const quint32 &index) const; QString rcModeToString (const quint32 &index) const; RCType rcModeToType (const quint32 &index) const; @@ -70,7 +79,7 @@ public: virtual bool runEncodingPass(AbstractSource* pipedSource, const QString outputFile, const unsigned int &frames, const int &pass = 0, const QString &passLogFile = QString()); - static const AbstractEncoderInfo& getEncoderInfo(void); + virtual const AbstractEncoderInfo& getEncoderInfo(void) const = 0; protected: virtual void buildCommandLine(QStringList &cmdLine, const bool &usePipe, const unsigned int &frames, const QString &indexFile, const int &pass, const QString &passLogFile) = 0; diff --git a/src/encoder_factory.cpp b/src/encoder_factory.cpp index bc8bb9d..a70a5d7 100644 --- a/src/encoder_factory.cpp +++ b/src/encoder_factory.cpp @@ -58,11 +58,11 @@ const AbstractEncoderInfo& EncoderFactory::getEncoderInfo(const OptionsModel::En switch(encoderType) { case OptionsModel::EncType_X264: - return X264Encoder::getEncoderInfo(); + return X264Encoder::encoderInfo(); case OptionsModel::EncType_X265: - return X265Encoder::getEncoderInfo(); + return X265Encoder::encoderInfo(); case OptionsModel::EncType_NVEnc: - return NVEncEncoder::getEncoderInfo(); + return NVEncEncoder::encoderInfo(); default: MUTILS_THROW("Unknown encoder type encountered!"); } diff --git a/src/encoder_nvenc.cpp b/src/encoder_nvenc.cpp index 299da31..7b16fd0 100644 --- a/src/encoder_nvenc.cpp +++ b/src/encoder_nvenc.cpp @@ -94,9 +94,11 @@ public: return "NVEncC"; } - virtual QStringList getArchitectures(void) const + virtual QList getArchitectures(void) const { - return QStringList() << "32-Bit (x86)" << "64-Bit (x64)"; + return QList() + << qMakePair(QString("32-Bit (x86)"), ARCH_TYPE_X86) + << qMakePair(QString("64-Bit (x64)"), ARCH_TYPE_X64); } virtual QStringList getVariants(void) const @@ -198,11 +200,16 @@ public: static const NVEncEncoderInfo s_nvencEncoderInfo; -const AbstractEncoderInfo &NVEncEncoder::getEncoderInfo(void) +const AbstractEncoderInfo& NVEncEncoder::encoderInfo(void) { return s_nvencEncoderInfo; } +const AbstractEncoderInfo &NVEncEncoder::getEncoderInfo(void) const +{ + return encoderInfo(); +} + // ------------------------------------------------------------ // Constructor & Destructor // ------------------------------------------------------------ diff --git a/src/encoder_nvenc.h b/src/encoder_nvenc.h index 430cdde..3af5b5d 100644 --- a/src/encoder_nvenc.h +++ b/src/encoder_nvenc.h @@ -34,7 +34,8 @@ public: 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); + virtual const AbstractEncoderInfo& getEncoderInfo(void) const; + static const AbstractEncoderInfo& encoderInfo(void); protected: virtual QString getBinaryPath() const { return getEncoderInfo().getBinaryPath(m_sysinfo, m_options->encArch(), m_options->encVariant()); } diff --git a/src/encoder_x264.cpp b/src/encoder_x264.cpp index d784c18..c4b6f76 100644 --- a/src/encoder_x264.cpp +++ b/src/encoder_x264.cpp @@ -95,9 +95,11 @@ public: return "x264 (AVC/H.264)"; } - virtual QStringList getArchitectures(void) const + virtual QList getArchitectures(void) const { - return QStringList() << "32-Bit (x86)" << "64-Bit (x64)"; + return QList() + << qMakePair(QString("32-Bit (x86)"), ARCH_TYPE_X86) + << qMakePair(QString("64-Bit (x64)"), ARCH_TYPE_X64); } virtual QStringList getVariants(void) const @@ -180,11 +182,16 @@ public: static const X264EncoderInfo s_x264EncoderInfo; -const AbstractEncoderInfo &X264Encoder::getEncoderInfo(void) +const AbstractEncoderInfo& X264Encoder::encoderInfo(void) { return s_x264EncoderInfo; } +const AbstractEncoderInfo &X264Encoder::getEncoderInfo(void) const +{ + return encoderInfo(); +} + // ------------------------------------------------------------ // Constructor & Destructor // ------------------------------------------------------------ diff --git a/src/encoder_x264.h b/src/encoder_x264.h index 746e337..8b21cd7 100644 --- a/src/encoder_x264.h +++ b/src/encoder_x264.h @@ -34,7 +34,8 @@ public: 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); + virtual const AbstractEncoderInfo& getEncoderInfo(void) const; + static const AbstractEncoderInfo& encoderInfo(void); protected: virtual QString getBinaryPath() const { return getEncoderInfo().getBinaryPath(m_sysinfo, m_options->encArch(), m_options->encVariant()); } diff --git a/src/encoder_x265.cpp b/src/encoder_x265.cpp index 22ebe3b..8e36364 100644 --- a/src/encoder_x265.cpp +++ b/src/encoder_x265.cpp @@ -95,9 +95,11 @@ public: return "x265 (HEVC/H.265)"; } - virtual QStringList getArchitectures(void) const + virtual QList getArchitectures(void) const { - return QStringList() << "32-Bit (x86)" << "64-Bit (x64)"; + return QList() + << qMakePair(QString("32-Bit (x86)"), ARCH_TYPE_X86) + << qMakePair(QString("64-Bit (x64)"), ARCH_TYPE_X64); } virtual QStringList getVariants(void) const @@ -176,11 +178,16 @@ public: static const X265EncoderInfo s_x265EncoderInfo; -const AbstractEncoderInfo &X265Encoder::getEncoderInfo(void) +const AbstractEncoderInfo& X265Encoder::encoderInfo(void) { return s_x265EncoderInfo; } +const AbstractEncoderInfo &X265Encoder::getEncoderInfo(void) const +{ + return encoderInfo(); +} + // ------------------------------------------------------------ // Constructor & Destructor // ------------------------------------------------------------ diff --git a/src/encoder_x265.h b/src/encoder_x265.h index 4d6f28d..ee6a741 100644 --- a/src/encoder_x265.h +++ b/src/encoder_x265.h @@ -34,7 +34,8 @@ public: 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); + virtual const AbstractEncoderInfo& getEncoderInfo(void) const; + static const AbstractEncoderInfo& encoderInfo(void); protected: virtual QString getBinaryPath() const { return getEncoderInfo().getBinaryPath(m_sysinfo, m_options->encArch(), m_options->encVariant()); } diff --git a/src/thread_binaries.cpp b/src/thread_binaries.cpp index 9a6a974..b520505 100644 --- a/src/thread_binaries.cpp +++ b/src/thread_binaries.cpp @@ -151,10 +151,11 @@ 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 QStringList archs = encInfo.getArchitectures(), variants = encInfo.getVariants(); + const quint32 archCount = encInfo.getArchitectures().count(); QSet dependencySet; - for (quint32 archIdx = 0; archIdx < quint32(archs.count()); ++archIdx) + for (quint32 archIdx = 0; archIdx < archCount; ++archIdx) { + const QStringList variants = encInfo.getVariants(); for (quint32 varntIdx = 0; varntIdx < quint32(variants.count()); ++varntIdx) { const QStringList dependencies = encInfo.getDependencies(sysinfo, archIdx, varntIdx); diff --git a/src/win_addJob.cpp b/src/win_addJob.cpp index eacbd80..d3eac58 100644 --- a/src/win_addJob.cpp +++ b/src/win_addJob.cpp @@ -260,15 +260,15 @@ protected: } }; -class StringValidatorX264 : public StringValidator +class StringValidatorEncoder : public StringValidator { public: - StringValidatorX264(QLabel *notifier, QLabel *icon) : StringValidator(notifier, icon) {} + StringValidatorEncoder(QLabel *notifier, QLabel *icon) : StringValidator(notifier, icon) {} virtual State validate(QString &input, int &pos) const { static const char *const params[] = {"B", "o", "h", "p", "q", /*"fps", "frames",*/ "preset", "tune", "profile", - "stdin", "crf", "bitrate", "qp", "pass", "stats", "output", "help", "quiet", NULL}; + "stdin", "crf", "bitrate", "qp", "pass", "stats", "output", "help", "quiet", "codec", "y4m", NULL}; const QString commandLine = input.trimmed(); const QStringList tokens = commandLine.isEmpty() ? QStringList() : MUtils::OS::crack_command_line(commandLine); @@ -326,16 +326,6 @@ AddJobDialog::AddJobDialog(QWidget *parent, OptionsModel *const options, Recentl 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); - ui->cbxEncoderArch->addItem(tr("64-Bit"), OptionsModel::EncArch_x86_64); - - //Init rc-mode combobox - ui->cbxRateControlMode->addItem(tr("CRF"), OptionsModel::RCMode_CRF); - ui->cbxRateControlMode->addItem(tr("CQ"), OptionsModel::RCMode_CQ); - ui->cbxRateControlMode->addItem(tr("2-Pass"), OptionsModel::RCMode_2Pass); - ui->cbxRateControlMode->addItem(tr("ABR"), OptionsModel::RCMode_ABR); - //Init combobox items ui->cbxTuning ->addItem(QString::fromLatin1(OptionsModel::SETTING_UNSPECIFIED)); ui->cbxProfile->addItem(QString::fromLatin1(OptionsModel::PROFILE_UNRESTRICTED)); @@ -356,7 +346,7 @@ AddJobDialog::AddJobDialog(QWidget *parent, OptionsModel *const options, Recentl //Setup validator ui->editCustomX264Params->installEventFilter(this); - ui->editCustomX264Params->setValidator(new StringValidatorX264(ui->labelNotificationX264, ui->iconNotificationX264)); + ui->editCustomX264Params->setValidator(new StringValidatorEncoder(ui->labelNotificationX264, ui->iconNotificationX264)); ui->editCustomX264Params->clear(); ui->editCustomAvs2YUVParams->installEventFilter(this); ui->editCustomAvs2YUVParams->setValidator(new StringValidatorAvs2YUV(ui->labelNotificationAvs2YUV, ui->iconNotificationAvs2YUV)); @@ -537,23 +527,28 @@ void AddJobDialog::encoderIndexChanged(int index) const OptionsModel::EncType encType = static_cast(ui->cbxEncoderType->itemData(ui->cbxEncoderType->currentIndex()).toInt()); const AbstractEncoderInfo &encoderInfo = EncoderFactory::getEncoderInfo(encType); - //Update encoder variants - const QFlags variants = encoderInfo.getVariants(); - ui->cbxEncoderVariant->clear(); - for(OptionsModel::EncVariant varnt = OptionsModel::EncVariant_MIN; varnt <= OptionsModel::EncVariant_MAX; SHFL(varnt)) + //Update encoder architectures + const QList archs = encoderInfo.getArchitectures(); + ui->cbxEncoderArch->clear(); + for (quint32 archIdx = 0; archIdx < quint32(archs.count()); ++archIdx) { - if(variants.testFlag(varnt)) - { - QString varntText; - switch(varnt) - { - case OptionsModel::EncVariant_8Bit: varntText = tr("8-Bit"); break; - case OptionsModel::EncVariant_10Bit: varntText = tr("10-Bit"); break; - case OptionsModel::EncVariant_12Bit: varntText = tr("12-Bit"); break; - default: MUTILS_THROW("Bad encoder variant!"); - } - ui->cbxEncoderVariant->addItem(varntText, QVariant(varnt)); - } + ui->cbxEncoderArch->addItem(archs[archIdx].first, archIdx); + } + + //Update encoder variants + const QStringList variants = encoderInfo.getVariants(); + ui->cbxEncoderVariant->clear(); + for(quint32 varntIdx = 0; varntIdx < quint32(variants.count()); ++varntIdx) + { + ui->cbxEncoderVariant->addItem(variants[varntIdx], varntIdx); + } + + //Update encoder RC modes + const QList rcModes = encoderInfo.getRCModes(); + ui->cbxRateControlMode->clear(); + for (quint32 rcIndex = 0; rcIndex < quint32(rcModes.count()); ++rcIndex) + { + ui->cbxRateControlMode->addItem(rcModes[rcIndex].first, rcIndex); } //Update presets @@ -595,7 +590,7 @@ void AddJobDialog::variantIndexChanged(int index) const AbstractEncoderInfo &encoderInfo = EncoderFactory::getEncoderInfo(encType); //Update encoder profiles - const QStringList profiles = encoderInfo.getProfiles(static_cast(ui->cbxEncoderVariant->itemData(index).toInt())); + const QStringList profiles = encoderInfo.getProfiles(ui->cbxEncoderVariant->itemData(index).toUInt()); if(profiles.empty()) { ui->cbxProfile->setEnabled(false); @@ -614,18 +609,30 @@ void AddJobDialog::variantIndexChanged(int index) void AddJobDialog::modeIndexChanged(int index) { - ui->spinQuantizer->setEnabled(index == OptionsModel::RCMode_CRF || index == OptionsModel::RCMode_CQ); - ui->spinBitrate ->setEnabled(index == OptionsModel::RCMode_ABR || index == OptionsModel::RCMode_2Pass); + const OptionsModel::EncType encType = static_cast(ui->cbxEncoderType->itemData(ui->cbxEncoderType->currentIndex()).toInt()); + const AbstractEncoderInfo &encoderInfo = EncoderFactory::getEncoderInfo(encType); + + //Update bitrate/quantizer boxes + const AbstractEncoderInfo::RCType rcType = encoderInfo.rcModeToType(ui->cbxRateControlMode->itemData(index).toUInt()); + ui->spinQuantizer->setEnabled(rcType == AbstractEncoderInfo::RC_TYPE_QUANTIZER); + ui->spinBitrate ->setEnabled(rcType != AbstractEncoderInfo::RC_TYPE_QUANTIZER); } void AddJobDialog::accept(void) { + //Get encoder info + const OptionsModel::EncType encType = static_cast(ui->cbxEncoderType->itemData(ui->cbxEncoderType->currentIndex()).toInt()); + const AbstractEncoderInfo &encoderInfo = EncoderFactory::getEncoderInfo(encType); + //Check 64-Bit support - if((ui->cbxEncoderArch->currentIndex() == OptionsModel::EncArch_x86_64) && (!m_sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64))) + if (encoderInfo.archToType(ui->cbxEncoderArch->itemData(ui->cbxEncoderArch->currentIndex()).toUInt()) == AbstractEncoderInfo::ARCH_TYPE_X64) { - QMessageBox::warning(this, tr("64-Bit unsupported!"), tr("Sorry, this computer does not support 64-Bit encoders!")); - ui->cbxEncoderArch->setCurrentIndex(OptionsModel::EncArch_x86_32); - return; + if (!m_sysinfo->getCPUFeatures(SysinfoModel::CPUFeatures_X64)) + { + QMessageBox::warning(this, tr("64-Bit unsupported!"), tr("Sorry, this computer does not support 64-Bit encoders!")); + ui->cbxEncoderArch->setCurrentIndex(AbstractEncoderInfo::ARCH_TYPE_X86); + return; + } } //Selection complete? @@ -648,25 +655,6 @@ void AddJobDialog::accept(void) return; } - //Get encoder info - const OptionsModel::EncType encType = static_cast(ui->cbxEncoderType->itemData(ui->cbxEncoderType->currentIndex()).toInt()); - const AbstractEncoderInfo &encoderInfo = EncoderFactory::getEncoderInfo(encType); - - //Is selected RC mode supported? - if(!encoderInfo.isRCModeSupported(static_cast(ui->cbxRateControlMode->currentIndex()))) - { - QMessageBox::warning(this, tr("Bad RC Mode!"), tr("The selected RC mode is not supported by the selected encoder!")); - for(int i = 0; i < ui->cbxRateControlMode->count(); i++) - { - if(encoderInfo.isRCModeSupported(static_cast(i))) - { - ui->cbxRateControlMode->setCurrentIndex(i); - break; - } - } - return; - } - //Is the type of the source file supported? const int sourceType = MediaInfo::analyze(sourceFile.canonicalFilePath()); if(sourceType == MediaInfo::FILETYPE_AVISYNTH) @@ -1097,13 +1085,30 @@ void AddJobDialog::updateComboBox(QComboBox *const cbox, const QString &text) } void AddJobDialog::updateComboBox(QComboBox *const cbox, const int &data) +{ + int index = 0; + if (QAbstractItemModel *model = cbox->model()) + { + for (int i = 0; i < cbox->model()->rowCount(); i++) + { + if (cbox->itemData(i).toInt() == data) + { + index = i; + break; + } + } + } + cbox->setCurrentIndex(index); +} + +void AddJobDialog::updateComboBox(QComboBox *const cbox, const quint32 &data) { int index = 0; if(QAbstractItemModel *model = cbox->model()) { for(int i = 0; i < cbox->model()->rowCount(); i++) { - if(cbox->itemData(i).toInt() == data) + if(cbox->itemData(i).toUInt() == data) { index = i; break; @@ -1115,7 +1120,7 @@ void AddJobDialog::updateComboBox(QComboBox *const cbox, const int &data) void AddJobDialog::restoreOptions(const OptionsModel *options) { - DisableHelperRAII disbale(&m_monitorConfigChanges); + DisableHelperRAII disable(&m_monitorConfigChanges); updateComboBox(ui->cbxEncoderType, options->encType()); updateComboBox(ui->cbxEncoderArch, options->encArch()); @@ -1135,19 +1140,20 @@ void AddJobDialog::restoreOptions(const OptionsModel *options) void AddJobDialog::saveOptions(OptionsModel *options) { - options->setEncType (static_cast (ui->cbxEncoderType ->itemData(ui->cbxEncoderType ->currentIndex()).toInt())); - options->setEncArch (static_cast (ui->cbxEncoderArch ->itemData(ui->cbxEncoderArch ->currentIndex()).toInt())); - options->setEncVariant(static_cast(ui->cbxEncoderVariant ->itemData(ui->cbxEncoderVariant ->currentIndex()).toInt())); - options->setRCMode (static_cast (ui->cbxRateControlMode->itemData(ui->cbxRateControlMode->currentIndex()).toInt())); + options->setEncType(static_cast(ui->cbxEncoderType->itemData(ui->cbxEncoderType->currentIndex()).toInt())); + + options->setEncArch (ui->cbxEncoderArch ->itemData(ui->cbxEncoderArch ->currentIndex()).toUInt()); + options->setEncVariant(ui->cbxEncoderVariant ->itemData(ui->cbxEncoderVariant ->currentIndex()).toUInt()); + options->setRCMode (ui->cbxRateControlMode->itemData(ui->cbxRateControlMode->currentIndex()).toUInt()); options->setQuantizer(ui->spinQuantizer->value()); - options->setBitrate(ui->spinBitrate->value()); + options->setBitrate (ui->spinBitrate ->value()); options->setPreset (ui->cbxPreset ->model()->data(ui->cbxPreset ->model()->index(ui->cbxPreset ->currentIndex(), 0)).toString()); options->setTune (ui->cbxTuning ->model()->data(ui->cbxTuning ->model()->index(ui->cbxTuning ->currentIndex(), 0)).toString()); options->setProfile(ui->cbxProfile->model()->data(ui->cbxProfile->model()->index(ui->cbxProfile->currentIndex(), 0)).toString()); - options->setCustomEncParams(ui->editCustomX264Params->hasAcceptableInput() ? ui->editCustomX264Params->text().simplified() : QString()); + options->setCustomEncParams(ui->editCustomX264Params->hasAcceptableInput() ? ui->editCustomX264Params->text().simplified() : QString()); options->setCustomAvs2YUV(ui->editCustomAvs2YUVParams->hasAcceptableInput() ? ui->editCustomAvs2YUVParams->text().simplified() : QString()); } diff --git a/src/win_addJob.h b/src/win_addJob.h index 478dae9..97fc644 100644 --- a/src/win_addJob.h +++ b/src/win_addJob.h @@ -99,6 +99,7 @@ private: void saveOptions(OptionsModel *options); void updateComboBox(QComboBox *const cbox, const QString &text); void updateComboBox(QComboBox *const cbox, const int &data); + void updateComboBox(QComboBox *const cbox, const quint32 &data); QString currentSourcePath(const bool bWithName = false); QString currentOutputPath(const bool bWithName = false);