Commit 515cfa5f authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Add widget to compare proxy profiles (speed and file size)

parent 33360d8e
......@@ -6,13 +6,14 @@ MPEG=qscale=4 ab=192k vcodec=mpeg2video acodec=mp2 threads=%threads;mpg
[proxy]
# proxy settings should be FFmpeg type parameters, like: -vcodec libx264
x264=-vf scale=640:-2 -vcodec libx264 -g 1 -bf 0 -vb 0 -crf 20 -preset veryfast -acodec aac -ab 128k;mov
x264-vaapi=-init_hw_device vaapi=vaapi0:,connection_type=x11 -filter_hw_device vaapi0 -vf format=nv12,hwupload -codec:v h264_vaapi -g 1 -bf 0 -qp 26 -acodec ac3 -ab 128k;mov
x264=-vf scale=%width:-2 -vcodec libx264 -g 1 -bf 0 -vb 0 -crf 20 -preset veryfast -acodec aac -ab 128k;mov
x264-vaapi=-hwaccel vaapi -hwaccel_output_format vaapi -i -vf format=nv12,hwupload -codec:v h264_vaapi -g 1 -bf 0 -qp 26 -acodec ac3 -ab 128k;mov
x264-vaapi-scale=-hwaccel vaapi -hwaccel_output_format vaapi -i -vf scale_vaapi=w=%width:h=-2:format=nv12,hwupload -codec:v h264_vaapi -g 1 -bf 0 -qp 26 -acodec ac3 -ab 128k;mov
x264-nvenc=-vsync 0 -c:v %nvcodec -resize %frameSize -i -vcodec h264_nvenc -g 1 -bf 0 -acodec copy;mov
MPEG2=-vf scale=640:-2 -g 1 -bf 0 -vb 0 -qscale 6 -ab 128k -vcodec mpeg2video -acodec ac3;mpg
MJPEG=-vf yadif,scale=640:-2 -qscale 3 -vcodec mjpeg -acodec pcm_s16le;mkv
MPEG2=-vf scale=%width:-2 -g 1 -bf 0 -vb 0 -qscale 6 -ab 128k -vcodec mpeg2video -acodec ac3;mpg
MJPEG=-vf yadif,scale=%width:-2 -qscale 3 -vcodec mjpeg -acodec pcm_s16le;mkv
MJPEG-vaapi=-init_hw_device vaapi=vaapi0:,connection_type=x11 -filter_hw_device vaapi0 -vf format=nv12,hwupload -codec:v mjpeg_vaapi -codec:a copy;mkv
ProRes=-vcodec prores_ks -vb 0 -g 1 -bf 0 -vprofile 1 -vendor ap10 -qscale 1;mov
ProRes=-vf scale=%width:-2 -vcodec prores_ks -vb 0 -g 1 -bf 0 -vprofile 1 -vendor ap10 -qscale 1;mov
NVENC H264=-vcodec h264_nvenc -vb 30000k -rc cbr -acodec aac -ab 192k;mp4
NVENC H265=-vcodec hevc_nvenc -vb 30000k -acodec aac -ab 192k;mp4
......
......@@ -30,6 +30,7 @@ the Free Software Foundation, either version 3 of the License, or
#include "timeline2/view/timelinewidget.h"
#include "dialogs/subtitleedit.h"
#include "dialogs/textbasededit.h"
#include "dialogs/proxytest.h"
#include <mlt++/MltRepository.h>
#include <KMessageBox>
......@@ -1035,3 +1036,9 @@ void Core::updateMasterZones()
m_mainWindow->getCurrentTimeline()->controller()->updateMasterZones(m_mainWindow->getCurrentTimeline()->controller()->getModel()->getMasterEffectZones());
}
}
void Core::testProxies()
{
QScopedPointer<ProxyTest> dialog(new ProxyTest(QApplication::activeWindow()));
dialog->exec();
}
......@@ -298,6 +298,8 @@ public slots:
/** @brief Show currently selected effect zone in timeline ruler. */
void showEffectZone(ObjectId id, QPair <int, int>inOut, bool checked);
void updateMasterZones();
/** @brief Open the proxies test dialog. */
void testProxies();
signals:
void coreIsReady();
......
......@@ -5,6 +5,7 @@ set(kdenlive_SRCS
dialogs/kdenlivesettingsdialog.cpp
dialogs/markerdialog.cpp
dialogs/profilesdialog.cpp
dialogs/proxytest.cpp
dialogs/renderwidget.cpp
dialogs/speechdialog.cpp
dialogs/subtitleedit.cpp
......
/***************************************************************************
* Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* 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 *
***************************************************************************/
#include "proxytest.h"
#include "core.h"
#include "doc/kdenlivedoc.h"
#include "kdenlivesettings.h"
#include "kdenlive_debug.h"
#include <QFontDatabase>
#include <QPushButton>
#include <QTreeWidget>
#include <QDialogButtonBox>
#include <QWheelEvent>
#include <QProcess>
#include <QtConcurrent>
#include "klocalizedstring.h"
#include <kio/directorysizejob.h>
ProxyTest::ProxyTest(QWidget *parent)
: QDialog(parent)
,m_closing(false)
{
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
setupUi(this);
setWindowTitle(i18n("Compare proxy profile"));
buttonBox->button(QDialogButtonBox::Apply)->setText(i18n("Test Proxy profiles"));
infoWidget->hide();
connect(buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, [this]() {
infoWidget->setText(i18n("Starting process"));
infoWidget->animatedShow();
resultList->setCursor(Qt::BusyCursor);
QtConcurrent::run(this, &ProxyTest::startTest);
});
}
void ProxyTest::addAnalysis(const QStringList &data)
{
resultList->addTopLevelItem(new QTreeWidgetItem(resultList, data));
}
void ProxyTest::showMessage(const QString &message)
{
infoWidget->setText(message);
if (!message.isEmpty()) {
infoWidget->animatedShow();
} else {
// Tests finished
infoWidget->animatedHide();
resultList->setCursor(Qt::ArrowCursor);
}
}
ProxyTest::~ProxyTest()
{
m_closing = true;
QMetaObject::invokeMethod(m_process.get(), "kill");
// Wait until concurrent tread is finished
QMutexLocker lk(&m_locker);
}
void ProxyTest::startTest()
{
buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
// load proxy profiles
KConfig conf(QStringLiteral("encodingprofiles.rc"), KConfig::CascadeConfig, QStandardPaths::AppDataLocation);
KConfigGroup group(&conf, "proxy");
QMap<QString, QString> values = group.entryMap();
QMapIterator<QString, QString> k(values);
int proxyResize = pCore->currentDoc()->getDocumentProperty(QStringLiteral("proxyresize")).toInt();
QElapsedTimer timer;
while (k.hasNext()) {
QMutexLocker lk(&m_locker);
k.next();
if (!k.key().isEmpty()) {
QMetaObject::invokeMethod(this, "showMessage", Qt::QueuedConnection, Q_ARG(const QString&,i18n("Processing %1", k.key())));
QString params = k.value().section(QLatin1Char(';'), 0, 0);
QString extension = k.value().section(QLatin1Char(';'), 1, 1);
// Testing vaapi support
QTemporaryFile tmp(QDir::temp().absoluteFilePath(QString("XXXXXX.%1").arg(extension)));
if (!tmp.open()) {
// Something went wrong
return;
}
tmp.close();
params.replace(QStringLiteral("%width"), QString::number(proxyResize));
m_process.reset(new QProcess());
QStringList parameters = {QStringLiteral("-hide_banner"), QStringLiteral("-y"), QStringLiteral("-stats"), QStringLiteral("-v"), QStringLiteral("error")};
QStringList source = {QStringLiteral("-f"),QStringLiteral("lavfi"),QStringLiteral("-i"),QStringLiteral("smptebars=duration=100:size=1920x1080:rate=25")};
if (params.contains(QLatin1String("-i "))) {
// we have some pre-filename parameters, filename will be inserted later
} else {
parameters << source;
}
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
for (const QString &s : params.split(QLatin1Char(' '), QString::SkipEmptyParts)) {
#else
for (const QString &s : params.split(QLatin1Char(' '), Qt::SkipEmptyParts)) {
#endif
QString t = s.simplified();
if (t != QLatin1String("-noautorotate")) {
if (t == QLatin1String("-i")) {
parameters << source;
} else {
parameters << t;
}
}
}
parameters << tmp.fileName();
qDebug()<<"==== STARTING TEST PROFILE : "<<k.key()<<" = "<<parameters;
m_process->start(KdenliveSettings::ffmpegpath(), parameters);
m_process->waitForStarted();
timer.start();
bool success = false;
QStringList results;
if (m_process->waitForFinished()) {
if (m_closing) {
return;
}
qint64 elapsed = timer.elapsed();
qint64 size = tmp.size();
if (size > 0) {
success = true;
results = QStringList({k.key(),QString::number(elapsed), KIO::convertSize(size)});
}
}
if (!success) {
if (m_closing) {
return;
}
qDebug()<<"==== PROFILE FAILED: "<<k.key()<<" !!!!!!!!!!!!";
results = QStringList({k.key(),i18n("failed"), i18n("failed")});
}
QMetaObject::invokeMethod(this, "addAnalysis", Qt::QueuedConnection, Q_ARG(const QStringList&,results));
}
if (m_closing) {
return;
}
}
QMetaObject::invokeMethod(this, "showMessage", Qt::QueuedConnection, Q_ARG(const QString&,QString()));
}
/***************************************************************************
* Copyright (C) 2021 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
* *
* 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 *
***************************************************************************/
#ifndef PROXYTEST_H
#define PROXYTEST_H
#include "ui_testproxy_ui.h"
#include "definitions.h"
#include "timecode.h"
#include "timecodedisplay.h"
#include <QProcess>
#include <QMutex>
/**
* @class ProxyTest
* @brief A dialog to compare the proxy profiles.
* @author Jean-Baptiste Mardelle
*/
class ProxyTest : public QDialog, public Ui::TestProxy_UI
{
Q_OBJECT
public:
explicit ProxyTest(QWidget *parent = nullptr);
~ProxyTest() override;
private slots:
void startTest();
void addAnalysis(const QStringList &data);
void showMessage(const QString &message);
private:
bool m_closing;
std::unique_ptr<QProcess> m_process;
QMutex m_locker;
};
#endif
......@@ -1008,6 +1008,43 @@ void Wizard::testHwEncoders()
}
KdenliveSettings::setVaapiEnabled(vaapiSupported);
// VAAPI with scaling support
QStringList scaleargs{"-hide_banner", "-y"
,"-hwaccel"
,"vaapi"
,"-hwaccel_output_format"
,"vaapi"
,"/dev/dri/renderD128"
,"-f"
,"lavfi"
,"-i"
,"smptebars=duration=5:size=1280x720:rate=25"
,"-vf"
,"scale_vaapi=w=640:h=-2:format=nv12,hwupload"
,"-c:v"
,"h264_vaapi"
,"-an"
,"-f"
,"mp4"
,tmp.fileName()};
qDebug() << "// FFMPEG ARGS: " << scaleargs;
hwEncoders.start(KdenliveSettings::ffmpegpath(), scaleargs);
bool vaapiScalingSupported = false;
if (hwEncoders.waitForFinished()) {
if (hwEncoders.exitStatus() == QProcess::CrashExit) {
qDebug() << "/// ++ VAAPI NOT SUPPORTED";
} else {
if (tmp.exists() && tmp.size() > 0) {
qDebug() << "/// ++ VAAPI YES SUPPORTED ::::::";
// vaapi support enabled
vaapiScalingSupported = true;
} else {
qDebug() << "/// ++ VAAPI FAILED ::::::";
// vaapi support not enabled
}
}
}
KdenliveSettings::setVaapiScalingEnabled(vaapiScalingSupported);
// NVIDIA testing
QTemporaryFile tmp2(QDir::temp().absoluteFilePath(QStringLiteral("XXXXXX.mp4")));
if (!tmp2.open()) {
......
......@@ -107,6 +107,7 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, QString projectFolder, QUndoGroup *und
m_documentProperties[QStringLiteral("generateimageproxy")] = QString::number(int(KdenliveSettings::generateimageproxy()));
m_documentProperties[QStringLiteral("proxyimageminsize")] = QString::number(KdenliveSettings::proxyimageminsize());
m_documentProperties[QStringLiteral("proxyimagesize")] = QString::number(KdenliveSettings::proxyimagesize());
m_documentProperties[QStringLiteral("proxyresize")] = QString::number(KdenliveSettings::proxyscale());
m_documentProperties[QStringLiteral("videoTarget")] = QString::number(tracks.second);
m_documentProperties[QStringLiteral("audioTarget")] = QString::number(tracks.second - 1);
m_documentProperties[QStringLiteral("activeTrack")] = QString::number(tracks.second);
......@@ -1632,8 +1633,12 @@ void KdenliveDoc::initProxySettings()
// Select best proxy profile depending on hw encoder support
if (KdenliveSettings::nvencEnabled() && values.contains(QStringLiteral("x264-nvenc"))) {
params = values.value(QStringLiteral("x264-nvenc"));
} else if (KdenliveSettings::vaapiEnabled() && values.contains(QStringLiteral("x264-vaapi"))) {
params = values.value(QStringLiteral("x264-vaapi"));
} else if (KdenliveSettings::vaapiEnabled()) {
if (KdenliveSettings::vaapiScalingEnabled() && values.contains(QStringLiteral("x264-vaapi-scale"))) {
params = values.value(QStringLiteral("x264-vaapi-scale"));
} else if (values.contains(QStringLiteral("x264-vaapi"))) {
params = values.value(QStringLiteral("x264-vaapi"));
}
} else {
params = values.value(QStringLiteral("MJPEG"));
}
......
......@@ -36,6 +36,8 @@
#include <QProcess>
#include <KIO/RenameDialog>
#include <KLineEdit>
#include <QComboBox>
#include <QObject>
#include <klocalizedstring.h>
CutTask::CutTask(const ObjectId &owner, const QString &destination, const QStringList encodingParams, int in, int out, bool addToProject, QObject* object)
......@@ -58,28 +60,113 @@ void CutTask::start(const ObjectId &owner, int in , int out, QObject* object, bo
return;
}
const QString source = binClip->url();
QString videoCodec = binClip->codec(false);
QString audioCodec = binClip->codec(true);
// Check if the audio/video codecs are supported for encoding (required for the codec copy feature)
QProcess checkProcess;
QStringList params = {QStringLiteral("-codecs")};
checkProcess.start(KdenliveSettings::ffmpegpath(), params);
checkProcess.waitForFinished(); // sets current thread to sleep and waits for pingProcess end
QString output(checkProcess.readAllStandardOutput());
QString line;
QTextStream stream(&output);
bool videoOk = videoCodec.isEmpty();
bool audioOk = audioCodec.isEmpty();
while (stream.readLineInto(&line)) {
if (!videoOk && line.contains(videoCodec)) {
if (line.simplified().section(QLatin1Char(' '), 0, 0).contains(QLatin1Char('E'))) {
videoOk = true;
}
} else if (!audioOk && line.contains(audioCodec)) {
if (line.simplified().section(QLatin1Char(' '), 0, 0).contains(QLatin1Char('E'))) {
audioOk = true;
}
}
if (audioOk && videoOk) {
break;
}
}
QString warnMessage;
if (!videoOk) {
warnMessage = i18n("Cannot copy video codec %1, will re-encode.", videoCodec);
}
if (!audioOk) {
if (!videoOk) {
warnMessage.append(QLatin1Char('\n'));
}
warnMessage.append(i18n("Cannot copy audio codec %1, will re-encode.", audioCodec));
}
QString transcoderExt = source.section(QLatin1Char('.'), -1);
transcoderExt.prepend(QLatin1Char('.'));
QFileInfo finfo(source);
QString fileName = finfo.fileName().section(QLatin1Char('.'), 0, -2);
QDir dir = finfo.absoluteDir();
QString inString = QString::number(int(GenTime(in, pCore->getCurrentFps()).seconds()));
QString outString = QString::number(int(GenTime(out, pCore->getCurrentFps()).seconds()));
QString path = dir.absoluteFilePath(fileName + QString("-%1-%2.").arg(inString, outString) + transcoderExt);
QString path = dir.absoluteFilePath(fileName + QString("-%1-%2").arg(inString, outString) + transcoderExt);
QPointer<QDialog> d = new QDialog(QApplication::activeWindow());
Ui::CutJobDialog_UI ui;
ui.setupUi(d);
ui.extra_params->setVisible(false);
ui.message->setText(warnMessage);
ui.message->setVisible(!warnMessage.isEmpty());
if (videoCodec.isEmpty()) {
ui.video_codec->setText(i18n("none"));
ui.vcodec->setEnabled(false);
} else {
ui.video_codec->setText(videoCodec);
ui.vcodec->addItem(i18n("Copy stream"), QStringLiteral("copy"));
ui.vcodec->addItem(i18n("X264 encoding"), QStringLiteral("libx264"));
}
if (audioCodec.isEmpty()) {
ui.audio_codec->setText(i18n("none"));
ui.acodec->setEnabled(false);
} else {
ui.audio_codec->setText(audioCodec);
ui.acodec->addItem(i18n("Copy stream"), QStringLiteral("copy"));
ui.acodec->addItem(i18n("PCM encoding"), QStringLiteral("pcm_s24le"));
ui.acodec->addItem(i18n("AAC encoding"), QStringLiteral("aac"));
}
ui.audio_codec->setText(audioCodec);
ui.add_clip->setChecked(KdenliveSettings::add_new_clip());
ui.file_url->setMode(KFile::File);
ui.extra_params->setMaximumHeight(QFontMetrics(QApplication::font()).lineSpacing() * 5);
ui.file_url->setUrl(QUrl::fromLocalFile(path));
QObject::connect(ui.acodec, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), d.data(), [&ui, transcoderExt]() {
ui.extra_params->setPlainText(QString("-c:a %1 -c:v %2").arg(ui.acodec->currentData().toString()).arg(ui.vcodec->currentData().toString()));
QString path = ui.file_url->url().toLocalFile();
QString fileName = path.section(QLatin1Char('.'), 0, -2);
if (ui.acodec->currentData() == QLatin1String("copy") && ui.vcodec->currentData() == QLatin1String("copy")) {
fileName.append(transcoderExt);
} else {
fileName.append(QStringLiteral(".mov"));
}
ui.file_url->setUrl(QUrl::fromLocalFile(fileName));
});
QObject::connect(ui.vcodec, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), d.data(), [&ui, transcoderExt]() {
ui.extra_params->setPlainText(QString("-c:a %1 -c:v %2").arg(ui.acodec->currentData().toString()).arg(ui.vcodec->currentData().toString()));
QString path = ui.file_url->url().toLocalFile();
QString fileName = path.section(QLatin1Char('.'), 0, -2);
if (ui.acodec->currentData() == QLatin1String("copy") && ui.vcodec->currentData() == QLatin1String("copy")) {
fileName.append(transcoderExt);
} else {
fileName.append(QStringLiteral(".mov"));
}
ui.file_url->setUrl(QUrl::fromLocalFile(fileName));
});
QFontMetrics fm = ui.file_url->lineEdit()->fontMetrics();
ui.file_url->setMinimumWidth(int(fm.boundingRect(ui.file_url->text().left(50)).width() * 1.4));
ui.button_more->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
ui.extra_params->setPlainText(QStringLiteral("-acodec copy -vcodec copy"));
ui.extra_params->setPlainText(QStringLiteral("-c:a copy -c:v copy"));
QString mess = i18n("Extracting %1 out of %2", Timecode::getStringTimecode(out - in, pCore->getCurrentFps(), true), binClip->getStringDuration());
ui.info_label->setText(mess);
if (!videoOk) {
ui.vcodec->setCurrentIndex(1);
}
if (!audioOk) {
ui.acodec->setCurrentIndex(1);
}
if (d->exec() != QDialog::Accepted) {
delete d;
return;
......@@ -141,11 +228,12 @@ void CutTask::run()
pCore->taskManager.taskDone(m_owner.second, this);
return;
}
QStringList params = {QStringLiteral("-y"),QStringLiteral("-stats"),QStringLiteral("-v"),QStringLiteral("error"),QStringLiteral("-noaccurate_seek"),QStringLiteral("-ss"),QString::number(m_inPoint.seconds()),QStringLiteral("-i"),url, QStringLiteral("-t"), QString::number((m_outPoint-m_inPoint).seconds()),QStringLiteral("-avoid_negative_ts"),QStringLiteral("make_zero")};
QStringList params = {QStringLiteral("-y"),QStringLiteral("-stats"),QStringLiteral("-v"),QStringLiteral("error"),QStringLiteral("-noaccurate_seek"),QStringLiteral("-ss"),QString::number(m_inPoint.seconds()),QStringLiteral("-i"),url, QStringLiteral("-t"), QString::number((m_outPoint-m_inPoint).seconds()),QStringLiteral("-avoid_negative_ts"),QStringLiteral("make_zero"),QStringLiteral("-sn"),QStringLiteral("-dn"),QStringLiteral("-map"),QStringLiteral("0")};
params << m_encodingParams << m_destination;
m_jobProcess = std::make_unique<QProcess>(new QProcess);
connect(m_jobProcess.get(), &QProcess::readyReadStandardError, this, &CutTask::processLogInfo);
connect(this, &CutTask::jobCanceled, m_jobProcess.get(), &QProcess::kill, Qt::DirectConnection);
qDebug()<<"=== STARTING CUT JOB: "<<params;
m_jobProcess->start(KdenliveSettings::ffmpegpath(), params, QIODevice::ReadOnly);
m_jobProcess->waitForFinished(-1);
bool result = m_jobProcess->exitStatus() == QProcess::NormalExit;
......
......@@ -122,6 +122,8 @@ void ProxyTask::run()
parameter.prepend(QStringLiteral("-pix_fmt yuv420p"));
}
}
int proxyResize = pCore->currentDoc()->getDocumentProperty(QStringLiteral("proxyresize")).toInt();
parameter.replace(QStringLiteral("%width"), QString::number(proxyResize));
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
QStringList params = parameter.split(QLatin1Char('-'), QString::SkipEmptyParts);
......@@ -189,6 +191,7 @@ void ProxyTask::run()
m_jobProcess.reset(new QProcess);
// m_jobProcess->setProcessChannelMode(QProcess::MergedChannels);
qDebug()<<" :: STARTING PLAYLIST PROXY: "<<mltParameters;
QObject::connect(this, &ProxyTask::jobCanceled, m_jobProcess.get(), &QProcess::kill, Qt::DirectConnection);
QObject::connect(m_jobProcess.get(), &QProcess::readyReadStandardError, this, &ProxyTask::processLogInfo);
m_jobProcess->start(KdenliveSettings::rendererpath(), mltParameters);
......@@ -317,6 +320,8 @@ void ProxyTask::run()
}
}
}
int proxyResize = pCore->currentDoc()->getDocumentProperty(QStringLiteral("proxyresize")).toInt();
proxyParams.replace(QStringLiteral("%width"), QString::number(proxyResize));
bool disableAutorotate = binClip->getProducerProperty(QStringLiteral("autorotate")) == QLatin1String("0");
if (disableAutorotate || proxyParams.contains(QStringLiteral("-noautorotate"))) {
// The noautorotate flag must be passed before input source
......
......@@ -223,6 +223,10 @@
<label>Rescale size for image proxy creation.</label>
<default>800</default>
</entry>
<entry name="proxyscale" type="Int">
<label>Default frame width for proxy clips.</label>
<default>640</default>
</entry>
<entry name="proxyextension" type="String">
<label>File extension for proxy clips.</label>
<default></default>
......@@ -267,6 +271,10 @@
<label>Enables vaapi hw accel in encoders.</label>
<default>false</default>
</entry>
<entry name="vaapiScalingEnabled" type="Bool">
<label>Enables scale_vaapi hw accel in encoders.</label>
<default>false</default>
</entry>
<entry name="nvencEnabled" type="Bool">
<label>Enables nvenc hw accel in encoders.</label>
<default>false</default>
......
......@@ -2038,6 +2038,10 @@ void MainWindow::slotEditProjectSettings()
modified = true;
project->setDocumentProperty(QStringLiteral("proxyimagesize"), QString::number(w->proxyImageSize()));
}
if (project->getDocumentProperty(QStringLiteral("proxyresize")) != QString::number(w->proxyResize())) {
modified = true;
project->setDocumentProperty(QStringLiteral("proxyresize"), QString::number(w->proxyResize()));
}
if (QString::number(int(w->useProxy())) != project->getDocumentProperty(QStringLiteral("enableproxy"))) {
project->setDocumentProperty(QStringLiteral("enableproxy"), QString::number(int(w->useProxy())));
modified = true;
......
......@@ -93,6 +93,7 @@ ProjectSettings::ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metada
audio_channels->setCurrentIndex(2);
}
connect(generate_proxy, &QAbstractButton::toggled, proxy_minsize, &QWidget::setEnabled);
connect(checkProxy, &QToolButton::clicked, pCore.get(), &Core::testProxies);
connect(generate_imageproxy, &QAbstractButton::toggled, proxy_imageminsize, &QWidget::setEnabled);
connect(generate_imageproxy, &QAbstractButton::toggled, image_label, &QWidget::setEnabled);
connect(generate_imageproxy, &QAbstractButton::toggled, proxy_imagesize, &QWidget::setEnabled);
......@@ -118,6 +119,7 @@ ProjectSettings::ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metada
generate_imageproxy->setChecked(doc->getDocumentProperty(QStringLiteral("generateimageproxy")).toInt() != 0);
proxy_imageminsize->setValue(doc->getDocumentProperty(QStringLiteral("proxyimageminsize")).toInt());
proxy_imagesize->setValue(doc->getDocumentProperty(QStringLiteral("proxyimagesize")).toInt());
proxy_resize->setValue(doc->getDocumentProperty(QStringLiteral("proxyresize")).toInt());
m_proxyextension = doc->getDocumentProperty(QStringLiteral("proxyextension"));
external_proxy->setChecked(doc->getDocumentProperty(QStringLiteral("enableexternalproxy")).toInt() != 0);
m_previewparams = doc->getDocumentProperty(QStringLiteral("previewparameters"));
......@@ -164,6 +166,8 @@ ProjectSettings::ProjectSettings(KdenliveDoc *doc, QMap<QString, QString> metada
proxy_showprofileinfo->setToolTip(i18n("Show default profile parameters"));
proxy_manageprofile->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
proxy_manageprofile->setToolTip(i18n("Manage proxy profiles"));
checkProxy->setIcon(QIcon::fromTheme(QStringLiteral("run-build")));
checkProxy->setToolTip(i18n("Compare proxy profiles efficiency"));
connect(proxy_manageprofile, &QAbstractButton::clicked, this, &ProjectSettings::slotManageEncodingProfile);
proxy_profile->setToolTip(i18n("Select default proxy profile"));
......@@ -540,6 +544,11 @@ int ProjectSettings::proxyImageSize() const
return proxy_imagesize->value();
}
int ProjectSettings::proxyResize() const
{
return proxy_resize->value();
}
QString ProjectSettings::externalProxyParams() const
{
return external_proxy_profile->currentData().toString();
......
......@@ -48,6 +48,7 @@ public:
bool generateImageProxy() const;
int proxyImageMinSize() const;
int proxyImageSize() const;
int proxyResize() const;
QString externalProxyParams() const;
QString proxyParams() const;
QString proxyExtension() const;
......