Commit 421b1137 authored by Eric Jiang's avatar Eric Jiang Committed by Jean-Baptiste Mardelle
Browse files

Lower proxy rendering priority

This adds a Kdenlive setting to lower the priority of the proxy rendering QProcess. This helps keep the main UI responsive when proxies are rendering.

One problem is that setting the niceness this way only works on Unix. I'm not sure how to do the same on Windows so any tips there would be appreciated. (I also can't build Kdenlive on Windows.)
parent 262872af
Pipeline #173294 passed with stage
in 7 minutes and 6 seconds
......@@ -10,12 +10,25 @@
#include "bin/projectclip.h"
#include "bin/projectitemmodel.h"
#include "core.h"
#include "kdenlivesettings.h"
#ifdef Q_OS_UNIX
// on Unix systems we can use setpriority() to make proxy-rendering tasks lower
// priority
#include "sys/resource.h"
#endif
#ifdef Q_OS_WIN
// on Windows we can use SetPriorityClass() instead
#include <windows.h>
#endif
#include <QElapsedTimer>
#include <QFile>
#include <QImage>
#include <QList>
#include <QMutex>
#include <QProcess>
#include <QRgb>
#include <QString>
#include <QThreadPool>
......@@ -82,3 +95,29 @@ void AbstractTask::run()
{
qDebug()<<"============0\n\nABSTRACT TASKSTARTRING\n\n==================";
}
// Background tasks should not slow down the main UI too much. Unless the user
// has opted out, lower the priority of proxy and transcode tasks.
void AbstractTask::setPreferredPriority(qint64 pid) {
if (!KdenliveSettings::nice_tasks()) {
qDebug() << "Not changing process priority for PID" << pid;
return;
}
#ifdef Q_OS_UNIX
qDebug() << "Lowering task priority for PID" << pid;
int err = setpriority(PRIO_PROCESS, pid, 10);
if (err != 0) {
qWarning() << "Failed to lower task priority for PID" << pid << " - error" << strerror(errno);
}
#endif
#ifdef Q_OS_WIN
HANDLE processHandle = OpenProcess(PROCESS_SET_INFORMATION, FALSE, pid);
if (processHandle) {
qDebug() << "Lowering priority for PID" << pid;
SetPriorityClass(processHandle, BELOW_NORMAL_PRIORITY_CLASS);
CloseHandle(processHandle);
} else {
qWarning() << "Could not get HANDLE for PID" << pid;
}
#endif
}
......@@ -36,6 +36,7 @@ public:
AbstractTask(const ObjectId &owner, JOBTYPE type, QObject* object);
virtual ~AbstractTask();
static void closeAll();
static void setPreferredPriority(qint64 pid);
const ObjectId ownerId() const;
bool operator==(const AbstractTask& b);
......
......@@ -181,6 +181,7 @@ void ProxyTask::run()
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);
AbstractTask::setPreferredPriority(m_jobProcess->processId());
m_jobProcess->waitForFinished(-1);
result = m_jobProcess->exitStatus() == QProcess::NormalExit;
delete playlist;
......@@ -276,7 +277,7 @@ void ProxyTask::run()
QStringList supportedPixFmts{QStringLiteral("yuv420p"), QStringLiteral("yuyv422"), QStringLiteral("rgb24"),
QStringLiteral("bgr24"), QStringLiteral("yuv422p"), QStringLiteral("yuv444p"),
QStringLiteral("rgb32"), QStringLiteral("yuv410p"), QStringLiteral("yuv411p")};
// Check if the transcoded file uses a cuda supported codec (we don't check for specific cards so not 100% exact)
bool supported = supportedCodecs.contains(codec) && supportedPixFmts.contains(pix_fmt);
if (proxyParams.contains(QStringLiteral("scale_npp")) && !KdenliveSettings::nvScalingEnabled()) {
......@@ -343,6 +344,7 @@ void ProxyTask::run()
QObject::connect(m_jobProcess.get(), &QProcess::readyReadStandardError, this, &ProxyTask::processLogInfo);
QObject::connect(this, &ProxyTask::jobCanceled, m_jobProcess.get(), &QProcess::kill, Qt::DirectConnection);
m_jobProcess->start(KdenliveSettings::ffmpegpath(), parameters, QIODevice::ReadOnly);
AbstractTask::setPreferredPriority(m_jobProcess->processId());
m_jobProcess->waitForFinished(-1);
result = m_jobProcess->exitStatus() == QProcess::NormalExit;
}
......
......@@ -169,6 +169,7 @@ void TranscodeTask::run()
QObject::connect(this, &TranscodeTask::jobCanceled, m_jobProcess.get(), &QProcess::kill, Qt::DirectConnection);
QObject::connect(m_jobProcess.get(), &QProcess::readyReadStandardError, this, &TranscodeTask::processLogInfo);
m_jobProcess->start(KdenliveSettings::rendererpath(), mltParameters);
AbstractTask::setPreferredPriority(m_jobProcess->processId());
m_jobProcess->waitForFinished(-1);
result = m_jobProcess->exitStatus() == QProcess::NormalExit;
} else {
......@@ -213,6 +214,7 @@ void TranscodeTask::run()
QObject::connect(this, &TranscodeTask::jobCanceled, m_jobProcess.get(), &QProcess::kill, Qt::DirectConnection);
QObject::connect(m_jobProcess.get(), &QProcess::readyReadStandardError, this, &TranscodeTask::processLogInfo);
m_jobProcess->start(KdenliveSettings::ffmpegpath(), parameters, QIODevice::ReadOnly);
AbstractTask::setPreferredPriority(m_jobProcess->processId());
m_jobProcess->waitForFinished(-1);
result = m_jobProcess->exitStatus() == QProcess::NormalExit;
}
......
......@@ -607,6 +607,11 @@
<default></default>
</entry>
<entry name="nice_tasks" type="Bool">
<label>Use lower CPU priority for proxy and transcode tasks</label>
<default>true</default>
</entry>
</group>
......
......@@ -43,6 +43,13 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="kcfg_nice_tasks">
<property name="text">
<string>Use lower CPU priority for proxy and transcode tasks</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment