File indexing completed on 2024-04-21 04:52:01
0001 /* 0002 SPDX-FileCopyrightText: 2017 Nicolas Carion 0003 SPDX-FileCopyrightText: 2022 Julius Künzel <jk.kdedev@smartlab.uber.space> 0004 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 This file is part of Kdenlive. See www.kdenlive.org. 0006 */ 0007 0008 #include "renderpresetmodel.hpp" 0009 #include "core.h" 0010 #include "kdenlive_debug.h" 0011 #include "kdenlivesettings.h" 0012 #include "profiles/profilemodel.hpp" 0013 #include "profiles/profilerepository.hpp" 0014 #include "renderpresetrepository.hpp" 0015 0016 #include <mlt++/MltRepository.h> 0017 0018 #include <KLocalizedString> 0019 #include <KMessageWidget> 0020 #include <QDir> 0021 #include <QFile> 0022 #include <QRegularExpression> 0023 #include <memory> 0024 0025 QString RenderPresetParams::toString() 0026 { 0027 QString string; 0028 RenderPresetParams::const_iterator i = this->constBegin(); 0029 while (i != this->constEnd()) { 0030 string.append(QStringLiteral("%1=%2 ").arg(i.key(), i.value())); 0031 ++i; 0032 } 0033 return string.simplified(); 0034 } 0035 0036 void RenderPresetParams::insertFromString(const QString ¶ms, bool overwrite) 0037 { 0038 // split only at white spaces followed by a new parameter 0039 // to avoid splitting values that contain whitespaces 0040 static const QRegularExpression regexp(R"(\s+(?=\S*=))"); 0041 0042 QStringList paramList = params.split(regexp, Qt::SkipEmptyParts); 0043 for (QString param : paramList) { 0044 if (!param.contains(QLatin1Char('='))) { 0045 // invalid param, skip 0046 continue; 0047 } 0048 const QString key = param.section(QLatin1Char('='), 0, 0); 0049 const QString value = param.section(QLatin1Char('='), 1); 0050 if (contains(key) && !overwrite) { 0051 // don't overwrite existing params 0052 continue; 0053 } 0054 insert(key, value); 0055 } 0056 } 0057 0058 void RenderPresetParams::replacePlaceholder(const QString &placeholder, const QString &newValue) 0059 { 0060 RenderPresetParams newParams; 0061 RenderPresetParams::const_iterator i = this->constBegin(); 0062 while (i != this->constEnd()) { 0063 QString value = i.value(); 0064 newParams.insert(i.key(), value.replace(placeholder, newValue)); 0065 ++i; 0066 } 0067 0068 clear(); 0069 QMap<QString, QString>::const_iterator j = newParams.constBegin(); 0070 while (j != newParams.constEnd()) { 0071 insert(j.key(), j.value()); 0072 ++j; 0073 } 0074 } 0075 0076 void RenderPresetParams::refreshX265Params() 0077 { 0078 if (!isX265()) { 0079 remove(QStringLiteral("x265-params")); 0080 return; 0081 } 0082 QStringList x265Params; 0083 if (contains(QStringLiteral("crf"))) { 0084 x265Params.append(QStringLiteral("crf=%1").arg(value(QStringLiteral("crf")))); 0085 } 0086 if (videoRateControl() == RenderPresetParams::Constant && contains(QStringLiteral("vb"))) { 0087 QString vb = value(QStringLiteral("vb")); 0088 QString newVal; 0089 if (vb == QStringLiteral("%bitrate") || vb == QStringLiteral("%bitrate+'k")) { 0090 newVal = QStringLiteral("%bitrate"); 0091 } else { 0092 newVal = vb.replace('k', QLatin1String("")).replace('M', QStringLiteral("000")); 0093 } 0094 x265Params.append(QStringLiteral("bitrate=%1").arg(newVal)); 0095 x265Params.append(QStringLiteral("vbv-maxrate=%1").arg(newVal)); 0096 } else if (videoRateControl() == RenderPresetParams::Constrained && contains(QStringLiteral("vmaxrate"))) { 0097 QString vmax = value(QStringLiteral("vmaxrate")); 0098 QString newVal; 0099 if (vmax == QStringLiteral("%bitrate") || vmax == QStringLiteral("%bitrate+'k")) { 0100 newVal = QStringLiteral("%bitrate"); 0101 } else { 0102 newVal = vmax.replace('k', QLatin1String("")).replace('M', QStringLiteral("000")); 0103 } 0104 x265Params.append(QStringLiteral("vbv-maxrate=%1").arg(newVal)); 0105 } 0106 if (contains(QStringLiteral("vbufsize"))) { 0107 int val = value(QStringLiteral("vbufsize")).toInt(); 0108 x265Params.append(QStringLiteral("vbv-bufsize=%1").arg(val / 1024)); 0109 } 0110 if (contains(QStringLiteral("bf"))) { 0111 x265Params.append(QStringLiteral("bframes=%1").arg(value(QStringLiteral("bf")))); 0112 } 0113 if (contains(QStringLiteral("g"))) { 0114 x265Params.append(QStringLiteral("keyint=%1").arg(value(QStringLiteral("g")))); 0115 } 0116 if (contains(QStringLiteral("top_field_first")) && value(QStringLiteral("progressive")).toInt() == 0) { 0117 int val = value(QStringLiteral("top_field_first")).toInt(); 0118 x265Params.append(QStringLiteral("interlace=%1").arg(val == 1 ? QStringLiteral("tff") : QStringLiteral("bff"))); 0119 } 0120 if (contains(QStringLiteral("sc_threshold")) && value(QStringLiteral("sc_threshold")).toInt() == 0) { 0121 x265Params.append(QStringLiteral("scenecut=0")); 0122 } 0123 if (contains(QStringLiteral("x265-params"))) { 0124 x265Params.append(value(QStringLiteral("x265-params"))); 0125 } 0126 0127 if (x265Params.isEmpty()) { 0128 remove(QStringLiteral("x265-params")); 0129 } else { 0130 insert(QStringLiteral("x265-params"), x265Params.join(QStringLiteral(":"))); 0131 } 0132 } 0133 0134 RenderPresetParams::RateControl RenderPresetParams::videoRateControl() const 0135 { 0136 QString vbufsize = value(QStringLiteral("vbufsize")); 0137 QString vcodec = value(QStringLiteral("vcodec")); 0138 if (contains(QStringLiteral("crf"))) { 0139 return !vbufsize.isEmpty() ? (vcodec.endsWith("_videotoolbox") ? RateControl::Average : RateControl::Quality) : RateControl::Constrained; 0140 } 0141 if (contains(QStringLiteral("vq")) || contains(QStringLiteral("vqp")) || contains(QStringLiteral("vglobal_quality")) || 0142 contains(QStringLiteral("qscale"))) { 0143 return vbufsize.isEmpty() ? RateControl::Quality : RateControl::Constrained; 0144 } else if (!vbufsize.isEmpty()) { 0145 return RateControl::Constant; 0146 } 0147 QString param = value(QStringLiteral("vb")); 0148 param = param.replace('+', "").replace('k', "").replace('k', "").replace('M', "000"); 0149 if (!param.isEmpty()) { 0150 return (param.contains(QStringLiteral("%bitrate")) || param.toInt() > 0) ? RateControl::Average : RateControl::Quality; 0151 } 0152 return RateControl::Unknown; 0153 } 0154 0155 bool RenderPresetParams::hasAlpha() 0156 { 0157 QStringList alphaFormats = {QLatin1String("argb"), QLatin1String("abgr"), QLatin1String("bgra"), QLatin1String("rgba"), 0158 QLatin1String("gbra"), QLatin1String("yuva"), QLatin1String("ya"), QLatin1String("yuva")}; 0159 const QString selected = value(QStringLiteral("pix_fmt")); 0160 for (auto &f : alphaFormats) { 0161 if (selected.startsWith(f)) { 0162 return true; 0163 } 0164 } 0165 return false; 0166 } 0167 0168 bool RenderPresetParams::isImageSequence() 0169 { 0170 return value(QStringLiteral("properties")).startsWith("stills/"); 0171 } 0172 0173 bool RenderPresetParams::isX265() 0174 { 0175 return value(QStringLiteral("vcodec")).toLower() == QStringLiteral("libx265"); 0176 } 0177 0178 RenderPresetModel::RenderPresetModel(QDomElement preset, const QString &presetFile, bool editable, const QString &groupName, const QString &renderer) 0179 : m_presetFile(presetFile) 0180 , m_editable(editable) 0181 , m_name(preset.attribute(QStringLiteral("name"))) 0182 , m_note() 0183 , m_standard(preset.attribute(QStringLiteral("standard"))) 0184 , m_params() 0185 , m_groupName(preset.attribute(QStringLiteral("category"), groupName)) 0186 , m_renderer(renderer) 0187 , m_url(preset.attribute(QStringLiteral("url"))) 0188 , m_speeds(preset.attribute(QStringLiteral("speeds"))) 0189 , m_defaultSpeedIndex(preset.attribute(QStringLiteral("defaultspeedindex"), QStringLiteral("-1")).toInt()) 0190 , m_topFieldFirst(preset.attribute(QStringLiteral("top_field_first"))) 0191 { 0192 if (m_groupName.isEmpty()) { 0193 m_groupName = i18nc("Category Name", "Custom"); 0194 } 0195 0196 m_extension = preset.attribute(QStringLiteral("extension")); 0197 m_manual = preset.attribute(QStringLiteral("manual")) == QLatin1String("1"); 0198 0199 QTextDocument docConvert; 0200 docConvert.setHtml(preset.attribute(QStringLiteral("args"))); 0201 // setParams after we know the extension to make setting the format automatically work 0202 setParams(docConvert.toPlainText().simplified()); 0203 0204 if (m_defaultSpeedIndex < 0) { 0205 m_defaultSpeedIndex = (speeds().count() - 1) * 0.75; 0206 } 0207 0208 m_vQualities = preset.attribute(QStringLiteral("qualities")); 0209 m_defaultVQuality = preset.attribute(QStringLiteral("defaultquality")); 0210 m_vBitrates = preset.attribute(QStringLiteral("bitrates")); 0211 m_defaultVBitrate = preset.attribute(QStringLiteral("defaultbitrate")); 0212 0213 m_aQualities = preset.attribute(QStringLiteral("audioqualities")); 0214 m_defaultAQuality = preset.attribute(QStringLiteral("defaultaudioquality")); 0215 m_aBitrates = preset.attribute(QStringLiteral("audiobitrates")); 0216 m_defaultABitrate = preset.attribute(QStringLiteral("defaultaudiobitrate")); 0217 0218 checkPreset(); 0219 } 0220 0221 RenderPresetModel::RenderPresetModel(const QString &groupName, const QString &path, QString presetName, const QString ¶ms, bool codecInName) 0222 : m_editable(false) 0223 , m_manual(false) 0224 , m_params() 0225 , m_groupName(groupName) 0226 , m_renderer(QStringLiteral("avformat")) 0227 , m_defaultSpeedIndex(-1) 0228 { 0229 KConfig config(path, KConfig::SimpleConfig); 0230 KConfigGroup group = config.group(QByteArray()); 0231 QString vcodec = group.readEntry("vcodec"); 0232 QString acodec = group.readEntry("acodec"); 0233 m_extension = group.readEntry("meta.preset.extension"); 0234 // setParams after we know the extension to make setting the format automatically work 0235 setParams(params); 0236 m_note = group.readEntry("meta.preset.note"); 0237 0238 if (codecInName && (!vcodec.isEmpty() || !acodec.isEmpty())) { 0239 presetName.append(" ("); 0240 if (!vcodec.isEmpty()) { 0241 presetName.append(vcodec); 0242 if (!acodec.isEmpty()) { 0243 presetName.append("+" + acodec); 0244 } 0245 } else if (!acodec.isEmpty()) { 0246 presetName.append(acodec); 0247 } 0248 presetName.append(QLatin1Char(')')); 0249 } 0250 m_name = presetName; 0251 checkPreset(); 0252 } 0253 0254 RenderPresetModel::RenderPresetModel(const QString &name, const QString &groupName, const QString ¶ms, const QString &extension, 0255 const QString &defaultVBitrate, const QString &defaultVQuality, const QString &defaultABitrate, 0256 const QString &defaultAQuality, const QString &speedsString, bool manualPreset) 0257 : m_presetFile() 0258 , m_editable() 0259 , m_name(name) 0260 , m_note() 0261 , m_standard() 0262 , m_extension(extension) 0263 , m_groupName(groupName) 0264 , m_renderer(QStringLiteral("avformat")) 0265 , m_url() 0266 , m_speeds(speedsString) 0267 , m_topFieldFirst() 0268 , m_vBitrates() 0269 , m_defaultVBitrate(defaultVBitrate) 0270 , m_vQualities() 0271 , m_defaultVQuality(defaultVQuality) 0272 , m_aBitrates() 0273 , m_defaultABitrate(defaultABitrate) 0274 , m_aQualities() 0275 , m_defaultAQuality(defaultAQuality) 0276 { 0277 setParams(params); 0278 if (m_groupName.isEmpty()) { 0279 m_groupName = i18nc("Category Name", "Custom"); 0280 } 0281 0282 m_defaultSpeedIndex = (speeds().count() - 1) * 0.75; 0283 m_manual = manualPreset; 0284 0285 checkPreset(); 0286 } 0287 0288 void RenderPresetModel::checkPreset() 0289 { 0290 QStringList acodecs = RenderPresetRepository::acodecs(); 0291 QStringList vcodecs = RenderPresetRepository::vcodecs(); 0292 QStringList supportedFormats = RenderPresetRepository::supportedFormats(); 0293 0294 bool replaceVorbisCodec = acodecs.contains(QStringLiteral("libvorbis")); 0295 bool replaceLibfaacCodec = acodecs.contains(QStringLiteral("libfaac")); 0296 0297 if (replaceVorbisCodec && (m_params.value(QStringLiteral("acodec")) == QStringLiteral("vorbis"))) { 0298 // replace vorbis with libvorbis 0299 m_params[QStringLiteral("acodec")] = QLatin1String("libvorbis"); 0300 } 0301 if (replaceLibfaacCodec && (m_params.value(QStringLiteral("acodec")) == QStringLiteral("aac"))) { 0302 // replace aac with libfaac 0303 m_params[QStringLiteral("acodec")] = QLatin1String("libfaac"); 0304 } 0305 0306 // We borrow a reference to the profile's pointer to query it more easily 0307 std::unique_ptr<ProfileModel> &profile = pCore->getCurrentProfile(); 0308 double project_framerate = double(profile->frame_rate_num()) / profile->frame_rate_den(); 0309 0310 if (m_standard.isEmpty() || 0311 (m_standard.contains(QStringLiteral("PAL"), Qt::CaseInsensitive) && profile->frame_rate_num() == 25 && profile->frame_rate_den() == 1) || 0312 (m_standard.contains(QStringLiteral("NTSC"), Qt::CaseInsensitive) && profile->frame_rate_num() == 30000 && profile->frame_rate_den() == 1001)) { 0313 // Standard OK 0314 } else { 0315 m_errors = i18n("Standard (%1) not compatible with project profile (%2)", m_standard, project_framerate); 0316 return; 0317 } 0318 0319 if (hasParam(QStringLiteral("mlt_profile"))) { 0320 QString profile_str = getParam(QStringLiteral("mlt_profile")); 0321 std::unique_ptr<ProfileModel> &target_profile = ProfileRepository::get()->getProfile(profile_str); 0322 if (target_profile->frame_rate_den() > 0) { 0323 double profile_rate = double(target_profile->frame_rate_num()) / target_profile->frame_rate_den(); 0324 if (int(1000.0 * profile_rate) != int(1000.0 * project_framerate)) { 0325 m_errors = i18n("Frame rate (%1) not compatible with project profile (%2)", profile_rate, project_framerate); 0326 return; 0327 } 0328 } 0329 } 0330 0331 if (hasParam(QStringLiteral("properties"))) { 0332 // This is a native MLT render profile, check the file for codec 0333 QString presetName = getParam(QStringLiteral("properties")); 0334 presetName.prepend(QStringLiteral("consumer/avformat/")); 0335 std::unique_ptr<Mlt::Properties> presets(pCore->getMltRepository()->presets()); 0336 std::unique_ptr<Mlt::Properties> preset(new Mlt::Properties(mlt_properties(presets->get_data(presetName.toUtf8().constData())))); 0337 const QString format = QString(preset->get("f")).toLower(); 0338 if (!format.isEmpty() && !supportedFormats.contains(format)) { 0339 m_errors = i18n("Unsupported video format: %1", format); 0340 return; 0341 } 0342 const QString vcodec = QString(preset->get("vcodec")).toLower(); 0343 if (!vcodec.isEmpty() && !vcodecs.contains(vcodec)) { 0344 m_errors = i18n("Unsupported video codec: %1", vcodec); 0345 return; 0346 } 0347 const QString acodec = QString(preset->get("acodec")).toLower(); 0348 if (!acodec.isEmpty() && !acodecs.contains(acodec)) { 0349 m_errors = i18n("Unsupported audio codec: %1", acodec); 0350 return; 0351 } 0352 } 0353 0354 // Make sure the selected preset uses an installed avformat codec / format 0355 QString format; 0356 format = getParam(QStringLiteral("f")).toLower(); 0357 if (!format.isEmpty() && !supportedFormats.contains(format)) { 0358 m_errors = i18n("Unsupported video format: %1", format); 0359 return; 0360 } 0361 0362 // check for missing audio codecs 0363 format = getParam(QStringLiteral("acodec")).toLower(); 0364 if (!format.isEmpty() && !acodecs.contains(format)) { 0365 m_errors = i18n("Unsupported audio codec: %1", format); 0366 return; 0367 } 0368 // check for missing video codecs 0369 format = getParam(QStringLiteral("vcodec")).toLower(); 0370 if (!format.isEmpty() && !vcodecs.contains(format)) { 0371 m_errors = i18n("Unsupported video codec: %1", format); 0372 return; 0373 } 0374 0375 if (hasParam(QStringLiteral("profile"))) { 0376 m_warnings = i18n("This render preset uses a 'profile' parameter.<br />Unless you know what you are doing you will probably " 0377 "have to change it to 'mlt_profile'."); 0378 return; 0379 } 0380 } 0381 0382 QDomElement RenderPresetModel::toXml() 0383 { 0384 QDomDocument doc; 0385 QDomElement profileElement = doc.createElement(QStringLiteral("profile")); 0386 doc.appendChild(profileElement); 0387 0388 profileElement.setAttribute(QStringLiteral("name"), m_name); 0389 profileElement.setAttribute(QStringLiteral("category"), m_groupName); 0390 if (!m_extension.isEmpty()) { 0391 profileElement.setAttribute(QStringLiteral("extension"), m_extension); 0392 } 0393 if (m_manual) { 0394 profileElement.setAttribute(QStringLiteral("manual"), QStringLiteral("1")); 0395 } 0396 profileElement.setAttribute(QStringLiteral("args"), m_params.toString()); 0397 if (!m_defaultVBitrate.isEmpty()) { 0398 profileElement.setAttribute(QStringLiteral("defaultbitrate"), m_defaultVBitrate); 0399 } 0400 if (!m_vBitrates.isEmpty()) { 0401 profileElement.setAttribute(QStringLiteral("bitrates"), m_vBitrates); 0402 } 0403 if (!m_defaultVQuality.isEmpty()) { 0404 profileElement.setAttribute(QStringLiteral("defaultquality"), m_defaultVQuality); 0405 } 0406 if (!m_vQualities.isEmpty()) { 0407 profileElement.setAttribute(QStringLiteral("qualities"), m_vQualities); 0408 } 0409 if (!m_defaultABitrate.isEmpty()) { 0410 profileElement.setAttribute(QStringLiteral("defaultaudiobitrate"), m_defaultABitrate); 0411 } 0412 if (!m_aBitrates.isEmpty()) { 0413 profileElement.setAttribute(QStringLiteral("audiobitrates"), m_aBitrates); 0414 } 0415 if (!m_defaultAQuality.isEmpty()) { 0416 profileElement.setAttribute(QStringLiteral("defaultaudioquality"), m_defaultAQuality); 0417 } 0418 if (!m_aQualities.isEmpty()) { 0419 profileElement.setAttribute(QStringLiteral("audioqualities"), m_aQualities); 0420 } 0421 if (!m_speeds.isEmpty()) { 0422 // profile has a variable speed 0423 profileElement.setAttribute(QStringLiteral("speeds"), m_speeds); 0424 if (m_defaultSpeedIndex > 0) { 0425 profileElement.setAttribute(QStringLiteral("defaultspeedindex"), m_defaultSpeedIndex); 0426 } 0427 } 0428 return doc.documentElement(); 0429 } 0430 0431 void RenderPresetModel::setParams(const QString ¶ms) 0432 { 0433 m_params.clear(); 0434 m_params.insertFromString(params, true); 0435 0436 if (!hasParam(QStringLiteral("f")) && !m_extension.isEmpty() && RenderPresetRepository::supportedFormats().contains(m_extension)) { 0437 m_params.insert(QStringLiteral("f"), m_extension); 0438 } 0439 } 0440 0441 RenderPresetParams RenderPresetModel::params(QStringList removeParams) const 0442 { 0443 RenderPresetParams newParams = m_params; 0444 for (QString toRemove : removeParams) { 0445 newParams.remove(toRemove); 0446 } 0447 return newParams; 0448 } 0449 0450 QStringList RenderPresetModel::defaultValues() const 0451 { 0452 QString defaultSpeedParams; 0453 QStringList presetSpeeds = speeds(); 0454 if (!presetSpeeds.isEmpty() && m_defaultSpeedIndex < presetSpeeds.count()) { 0455 defaultSpeedParams = presetSpeeds.at(m_defaultSpeedIndex); 0456 } 0457 return {defaultSpeedParams, m_defaultABitrate, m_defaultAQuality, m_defaultVBitrate, m_defaultVQuality}; 0458 } 0459 0460 QString RenderPresetModel::extension() const 0461 { 0462 if (!m_extension.isEmpty()) { 0463 return m_extension; 0464 } 0465 return getParam(QStringLiteral("f")); 0466 }; 0467 0468 QStringList RenderPresetModel::audioBitrates() const 0469 { 0470 return m_aBitrates.split(QLatin1Char(','), Qt::SkipEmptyParts); 0471 } 0472 0473 QString RenderPresetModel::defaultABitrate() const 0474 { 0475 return m_defaultABitrate; 0476 } 0477 0478 QStringList RenderPresetModel::audioQualities() const 0479 { 0480 if (!m_aQualities.isEmpty()) { 0481 return m_aQualities.split(QLatin1Char(','), Qt::SkipEmptyParts); 0482 } else { 0483 // ATTENTION: historically qualities are sorted from best to worse for some reason 0484 QString acodec = getParam(QStringLiteral("acodec")).toLower(); 0485 if (acodec == "libmp3lame") { 0486 return {"0", "9"}; 0487 } else if (acodec == "libvorbis" || acodec == "vorbis" || acodec == "libopus") { 0488 return {"10", "0"}; 0489 } else { 0490 return {"500", "0"}; 0491 } 0492 } 0493 } 0494 0495 QString RenderPresetModel::defaultAQuality() const 0496 { 0497 return m_defaultAQuality; 0498 } 0499 0500 QStringList RenderPresetModel::videoBitrates() const 0501 { 0502 return m_vBitrates.split(QLatin1Char(','), Qt::SkipEmptyParts); 0503 } 0504 0505 QString RenderPresetModel::defaultVBitrate() const 0506 { 0507 return m_defaultVBitrate; 0508 } 0509 0510 QStringList RenderPresetModel::videoQualities() const 0511 { 0512 if (!m_vQualities.isEmpty()) { 0513 return m_vQualities.split(QLatin1Char(','), Qt::SkipEmptyParts); 0514 } else { 0515 // ATTENTION: historically qualities are sorted from best to worse for some reason 0516 QString vcodec = getParam(QStringLiteral("vcodec")).toLower(); 0517 if (vcodec == "libx265" || vcodec.contains("nvenc") || vcodec.endsWith("_amf") || vcodec.startsWith("libx264") || vcodec.endsWith("_vaapi") || 0518 vcodec.endsWith("_qsv")) { 0519 return {"0", "51"}; 0520 } else if (vcodec.startsWith("libvpx") || vcodec.startsWith("libaom-")) { 0521 return {"0", "63"}; 0522 } else if (vcodec.startsWith("libwebp")) { 0523 return {"100", "0"}; 0524 } else { 0525 return {"1", "31"}; 0526 } 0527 } 0528 } 0529 0530 QString RenderPresetModel::defaultVQuality() const 0531 { 0532 return m_defaultVQuality; 0533 } 0534 0535 bool RenderPresetModel::editable() const 0536 { 0537 return m_editable; 0538 } 0539 0540 QStringList RenderPresetModel::speeds() const 0541 { 0542 return m_speeds.split(QLatin1Char(';'), Qt::SkipEmptyParts); 0543 } 0544 0545 QString RenderPresetModel::getParam(const QString &name) const 0546 { 0547 return params().value(name); 0548 } 0549 0550 bool RenderPresetModel::isManual() const 0551 { 0552 return m_manual; 0553 } 0554 0555 bool RenderPresetModel::hasParam(const QString &name) const 0556 { 0557 // return params().contains(name); 0558 return !getParam(name).isEmpty(); 0559 } 0560 0561 RenderPresetParams::RateControl RenderPresetModel::audioRateControl() const 0562 { 0563 QString value = getParam(QStringLiteral("vbr")); 0564 if (!value.isEmpty()) { 0565 // libopus rate mode 0566 if (value == QStringLiteral("off")) { 0567 return RenderPresetParams::Constant; 0568 } 0569 if (value == QStringLiteral("constrained")) { 0570 return RenderPresetParams::Average; 0571 } 0572 return RenderPresetParams::Quality; 0573 } 0574 if (hasParam(QStringLiteral("aq")) || hasParam(QStringLiteral("compression_level"))) { 0575 return RenderPresetParams::Quality; 0576 } 0577 if (hasParam(QStringLiteral("ab"))) { 0578 return RenderPresetParams::Constant; 0579 } 0580 return RenderPresetParams::Unknown; 0581 } 0582 0583 RenderPresetModel::InstallType RenderPresetModel::installType() const 0584 { 0585 if (m_editable) { 0586 if (m_presetFile.endsWith(QLatin1String("customprofiles.xml"))) { 0587 return InstallType::Custom; 0588 } else { 0589 return InstallType::Download; 0590 } 0591 } 0592 return InstallType::BuildIn; 0593 } 0594 0595 bool RenderPresetModel::hasFixedSize() const 0596 { 0597 // TODO 0598 return hasParam(QStringLiteral("s")) || m_params.contains(QLatin1String("%dv_standard")); 0599 } 0600 0601 QString RenderPresetModel::error() const 0602 { 0603 return m_errors; 0604 } 0605 0606 QString RenderPresetModel::warning() const 0607 { 0608 return m_warnings; 0609 } 0610 0611 int RenderPresetModel::estimateFileSize(int length) 0612 { 0613 Q_UNUSED(length) 0614 // TODO 0615 /*RateControl vrc = videoRateControl(); 0616 if (vrc == Average || vrc == Constant) { 0617 0618 return m_defaultVBitrate.toInt() * length; 0619 }*/ 0620 return -1; 0621 }