Commit 2137e158 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix render job sometimes not terminating correctly, fix play after render

parent 2fad9869
Pipeline #196620 passed with stage
in 9 minutes and 49 seconds
......@@ -8,6 +8,7 @@
#include "mlt++/Mlt.h"
#include "renderjob.h"
#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QDomDocument>
......@@ -138,7 +139,8 @@ int main(int argc, char **argv)
// Mlt::Factory::close();
fprintf(stderr, "+ + + RENDERING FINISHED + + + \n");
return 0;
} else if (args.count() > 1 && args.at(0) == QLatin1String("-subtitle")) {
}
if (args.count() > 1 && args.at(0) == QLatin1String("-subtitle")) {
args.removeFirst();
subtitleFile = args.takeFirst();
}
......@@ -158,12 +160,13 @@ int main(int argc, char **argv)
playlist.append(QStringLiteral("?multi=1"));
}
}
auto *rJob = new RenderJob(render, playlist, target, pid, in, out, subtitleFile, qApp);
rJob->start();
auto *rJob = new RenderJob(render, playlist, target, pid, in, out, subtitleFile, &app);
QObject::connect(rJob, &RenderJob::renderingFinished, rJob, [&]() {
rJob->deleteLater();
app.quit();
});
app.setQuitOnLastWindowClosed(false);
QMetaObject::invokeMethod(rJob, "start", Qt::QueuedConnection);
return app.exec();
} else {
fprintf(stderr,
......
......@@ -51,7 +51,7 @@ RenderJob::RenderJob(const QString &render, const QString &scenelist, const QStr
, m_dualpass(false)
, m_subtitleFile(subtitleFile)
{
m_renderProcess = new QProcess;
m_renderProcess = new QProcess(&m_looper);
m_renderProcess->setReadChannel(QProcess::StandardError);
connect(m_renderProcess, &QProcess::stateChanged, this, &RenderJob::slotCheckProcess);
......@@ -276,6 +276,7 @@ void RenderJob::start()
m_renderProcess->start(m_prog, m_args);
m_logstream << "Started render process: " << m_prog << ' ' << m_args.join(QLatin1Char(' ')) << "\n";
m_logstream.flush();
m_looper.exec();
}
#ifndef NODBUS
......@@ -344,19 +345,19 @@ void RenderJob::slotIsOver(QProcess::ExitStatus status, bool isWritable)
QProcess::startDetached(QStringLiteral("kdialog"), args);
emit renderingFinished();
} else {
if (!m_dualpass) {
sendFinish(-1, QString());
}
m_logstream << "Rendering of " << m_dest << " finished"
<< "\n";
if (!m_dualpass && m_player.length() > 3 && m_player.contains(QLatin1Char(' '))) {
/*
// Deprecated, we now play the rendering from Kdenlive's main application
if (!m_dualpass && m_player.length() > 3 && m_player.contains(QLatin1Char(' '))) {
QStringList args = m_player.split(QLatin1Char(' '));
QString exec = args.takeFirst();
// Decode url
QString url = QUrl::fromEncoded(args.takeLast().toUtf8()).toLocalFile();
args << url;
QProcess::startDetached(exec, args);
}
}*/
m_logstream.flush();
if (m_dualpass) {
deleteLater();
......@@ -372,25 +373,28 @@ void RenderJob::slotIsOver(QProcess::ExitStatus status, bool isWritable)
"-y", "-v", "quiet", "-stats", "-i", m_dest, "-i", m_subtitleFile, "-c", "copy", "-f", "matroska", m_temporaryRenderFile};
qDebug() << "::: JOB ARGS: " << args;
m_progress = 0;
delete m_renderProcess;
m_renderProcess = new QProcess;
/*disconnect(m_renderProcess, &QProcess::stateChanged, this, &RenderJob::slotCheckProcess);
disconnect(m_renderProcess, &QProcess::readyReadStandardError, this, &RenderJob::receivedStderr);*/
connect(m_renderProcess, &QProcess::readyReadStandardError, this, &RenderJob::receivedSubtitleProgress);
connect(m_renderProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &RenderJob::slotCheckSubtitleProcess);
m_renderProcess->start(ffmpegExe, args);
m_renderProcess->waitForFinished();
disconnect(m_renderProcess, &QProcess::stateChanged, this, &RenderJob::slotCheckProcess);
disconnect(m_renderProcess, &QProcess::readyReadStandardError, this, &RenderJob::receivedStderr);
m_subsProcess = new QProcess(&m_looper);
m_subsProcess->setProcessChannelMode(QProcess::MergedChannels);
connect(m_subsProcess, &QProcess::readyReadStandardOutput, this, &RenderJob::receivedSubtitleProgress);
m_subsProcess->start(ffmpegExe, args);
m_subsProcess->waitForStarted(-1);
m_subsProcess->waitForFinished(-1);
slotCheckSubtitleProcess(m_subsProcess->exitCode(), m_subsProcess->exitStatus());
return;
}
}
sendFinish(-1, QString());
}
}
emit renderingFinished();
m_looper.quit();
}
void RenderJob::receivedSubtitleProgress()
{
QString outputData = QString::fromLocal8Bit(m_renderProcess->readAllStandardError()).simplified();
QString outputData = QString::fromLocal8Bit(m_subsProcess->readAllStandardOutput()).simplified();
if (outputData.isEmpty()) {
return;
}
......@@ -399,7 +403,7 @@ void RenderJob::receivedSubtitleProgress()
QString result = output.takeFirst();
bool ok = false;
int frame = -1;
if (result == (QLatin1String("frame="))) {
if (result == (QLatin1String("frame=")) && !output.isEmpty()) {
// Frame number is the second parameter
result = output.takeFirst();
frame = result.toInt(&ok);
......@@ -409,7 +413,9 @@ void RenderJob::receivedSubtitleProgress()
if (ok && frame > 0) {
m_frame = frame;
m_progress = 100 * frame / (m_frameout - m_framein);
updateProgress();
if (m_progress > 0) {
updateProgress();
}
}
}
......@@ -417,8 +423,7 @@ void RenderJob::slotCheckSubtitleProcess(int exitCode, QProcess::ExitStatus exit
{
if (exitStatus == QProcess::CrashExit || !QFile::exists(m_temporaryRenderFile)) {
// rendering crashed
qDebug() << ":::: FOUND ERROR IN SUBS: " << m_renderProcess->exitStatus() << " / " << exitCode
<< ", FILE ESISTS: " << QFile::exists(m_temporaryRenderFile);
qDebug() << ":::: FOUND ERROR IN SUBS: " << exitStatus << " / " << exitCode << ", FILE ESISTS: " << QFile::exists(m_temporaryRenderFile);
QString error = tr("Rendering of %1 aborted when adding subtitles.").arg(m_dest);
m_errorMessage.append(error);
sendFinish(-2, m_errorMessage);
......@@ -432,6 +437,9 @@ void RenderJob::slotCheckSubtitleProcess(int exitCode, QProcess::ExitStatus exit
} else {
QFile::remove(m_dest);
QFile::rename(m_temporaryRenderFile, m_dest);
sendFinish(-1, QString());
}
QFile::remove(m_subtitleFile);
emit renderingFinished();
m_looper.quit();
}
......@@ -11,10 +11,11 @@
#else
#include <QDBusInterface>
#endif
#include <QObject>
#include <QProcess>
#include <QDateTime>
#include <QEventLoop>
#include <QFile>
#include <QObject>
#include <QProcess>
// Testing
#include <QTextStream>
......@@ -65,6 +66,8 @@ private:
QString m_subtitleFile;
QString m_temporaryRenderFile;
QProcess *m_renderProcess;
QProcess *m_subsProcess;
QEventLoop m_looper;
QString m_errorMessage;
QList<QVariant> m_dbusargs;
QDateTime m_startTime;
......
......@@ -24,6 +24,7 @@
#include <KColorScheme>
#include <KIO/DesktopExecParser>
#include <KIO/JobUiDelegate>
#include <KIO/OpenFileManagerWindowJob>
#include <KIO/OpenUrlJob>
#include <KLocalizedString>
......@@ -72,7 +73,8 @@ enum {
ExtraInfoRole = ProgressRole + 2, // vpinon: don't understand why, else spurious message displayed
LastTimeRole,
LastFrameRole,
OpenBrowserRole
OpenBrowserRole,
PlayAfterRole
};
// Running job status
......@@ -1037,6 +1039,7 @@ RenderJobItem *RenderWidget::createRenderJob(const QString &playlist, const QStr
renderItem->setData(1, ParametersRole, argsJob);
qDebug() << "* CREATED JOB WITH ARGS: " << argsJob;
renderItem->setData(1, OpenBrowserRole, m_view.open_browser->isChecked());
renderItem->setData(1, PlayAfterRole, m_view.play_after->isChecked());
if (!m_view.audio_box->isChecked()) {
renderItem->setData(1, ExtraInfoRole, i18n("Video without audio track"));
} else if (!m_view.video_box->isChecked()) {
......@@ -1545,10 +1548,17 @@ void RenderWidget::setRenderStatus(const QString &dest, int status, const QStrin
notify->setText(notif);
notify->setUrls({QUrl::fromLocalFile(dest)});
notify->sendEvent();
QUrl url = QUrl::fromLocalFile(item->text(1));
const QUrl url = QUrl::fromLocalFile(item->text(1));
bool exists = QFile(url.toLocalFile()).exists();
if (exists && item->data(1, OpenBrowserRole).toBool()) {
KIO::highlightInFileManager({url});
if (exists) {
if (item->data(1, OpenBrowserRole).toBool()) {
KIO::highlightInFileManager({url});
}
if (item->data(1, PlayAfterRole).toBool()) {
auto *job = new KIO::OpenUrlJob(url);
job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
job->start();
}
}
} else if (status == -2) {
// Rendering crashed
......@@ -1953,7 +1963,9 @@ void RenderWidget::slotPlayRendering(QTreeWidgetItem *item, int)
if (renderItem->status() != FINISHEDJOB) {
return;
}
KIO::OpenUrlJob(QUrl::fromLocalFile(item->text(1)));
auto *job = new KIO::OpenUrlJob(QUrl::fromLocalFile(item->text(1)));
job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
job->start();
}
void RenderWidget::errorMessage(RenderError type, const QString &message)
......
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