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

Append fps to clip name when transcoding a variable fps clip.

Fixes #1309
parent bf6565da
Pipeline #126506 passed with stage
in 10 minutes and 56 seconds
......@@ -4832,22 +4832,24 @@ void Bin::savePlaylist(const QString &binId, const QString &savePath, const QVec
}
}
void Bin::requestTranscoding(const QString &url, const QString &id, bool checkProfile)
void Bin::requestTranscoding(const QString &url, const QString &id, bool checkProfile, const QString suffix)
{
if (m_transcodingDialog == nullptr) {
m_transcodingDialog = new TranscodeSeek(this);
connect(m_transcodingDialog, &QDialog::accepted, this, [&, checkProfile] () {
QString firstId = m_transcodingDialog->ids().front();
std::vector<QString> ids = m_transcodingDialog->ids();
for (const QString &id : ids) {
std::shared_ptr<ProjectClip> clip = m_itemModel->getClipByBinID(id);
TranscodeTask::start({ObjectType::BinClip,id.toInt()}, m_transcodingDialog->preParams(), m_transcodingDialog->params(), -1, -1, true, clip.get(), false, id == firstId ? checkProfile : false);
QMap<QString,QString> ids = m_transcodingDialog->ids();
QString firstId = ids.firstKey();
QMapIterator<QString, QString> i(ids);
while (i.hasNext()) {
i.next();
std::shared_ptr<ProjectClip> clip = m_itemModel->getClipByBinID(i.key());
TranscodeTask::start({ObjectType::BinClip,i.key().toInt()}, i.value(), m_transcodingDialog->preParams(), m_transcodingDialog->params(), -1, -1, true, clip.get(), false, i.key() == firstId ? checkProfile : false);
}
m_transcodingDialog->deleteLater();
m_transcodingDialog = nullptr;
});
connect(m_transcodingDialog, &QDialog::rejected, this, [&, checkProfile] () {
QString firstId = m_transcodingDialog->ids().front();
QString firstId = m_transcodingDialog->ids().firstKey();
m_transcodingDialog->deleteLater();
m_transcodingDialog = nullptr;
if (checkProfile) {
......@@ -4859,10 +4861,10 @@ void Bin::requestTranscoding(const QString &url, const QString &id, bool checkPr
std::shared_ptr<ProjectClip> clip = m_itemModel->getClipByBinID(id);
if (clip) {
QString resource = clip->clipUrl();
m_transcodingDialog->addUrl(resource, id);
m_transcodingDialog->addUrl(resource, id, suffix);
}
} else {
m_transcodingDialog->addUrl(url, id);
m_transcodingDialog->addUrl(url, id, suffix);
}
m_transcodingDialog->show();
}
......
......@@ -458,7 +458,7 @@ public slots:
/** @brief Check if a clip profile matches project, propose switch otherwise */
void slotCheckProfile(const QString &binId);
/** @brief A non seekable clip was added to project, propose transcoding */
void requestTranscoding(const QString &url, const QString &id, bool checkProfile);
void requestTranscoding(const QString &url, const QString &id, bool checkProfile, const QString suffix = QString());
protected:
/* This function is called whenever an item is selected to propagate signals
......
......@@ -596,14 +596,7 @@ void ClipLoadTask::run()
}
QMetaObject::invokeMethod(pCore->bin(), "requestTranscoding", Qt::QueuedConnection, Q_ARG(QString, resource), Q_ARG(QString, QString::number(m_owner.second)), Q_ARG(bool, checkProfile));
}
// Check for variable frame rate
isVariableFrameRate = producer->get_int("meta.media.variable_frame_rate");
if (isVariableFrameRate && seekable) {
if (checkProfile) {
pCore->bin()->shouldCheckProfile = false;
}
QMetaObject::invokeMethod(pCore->bin(), "requestTranscoding", Qt::QueuedConnection, Q_ARG(QString, resource), Q_ARG(QString, QString::number(m_owner.second)), Q_ARG(bool, checkProfile));
}
// check if there are multiple streams
// List streams
int streams = producer->get_int("meta.media.nb_streams");
......@@ -624,6 +617,20 @@ void ClipLoadTask::run()
fps = producer->get_double(property);
}
// Check for variable frame rate
isVariableFrameRate = producer->get_int("meta.media.variable_frame_rate");
if (isVariableFrameRate && seekable) {
if (checkProfile) {
pCore->bin()->shouldCheckProfile = false;
}
QString adjustedFpsString;
if (fps > 0) {
int integerFps = qRound(fps);
adjustedFpsString = QString("-%1fps").arg(integerFps);
}
QMetaObject::invokeMethod(pCore->bin(), "requestTranscoding", Qt::QueuedConnection, Q_ARG(QString, resource), Q_ARG(QString, QString::number(m_owner.second)), Q_ARG(bool, checkProfile), Q_ARG(QString, adjustedFpsString));
}
if (fps <= 0 && !m_isCanceled) {
if (producer->get_double("meta.media.frame_rate_den") > 0) {
fps = producer->get_double("meta.media.frame_rate_num") / producer->get_double("meta.media.frame_rate_den");
......
......@@ -23,10 +23,11 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include <klocalizedstring.h>
TranscodeTask::TranscodeTask(const ObjectId &owner, const QString &preParams, const QString &params, int in, int out, bool replaceProducer, QObject* object, bool checkProfile)
TranscodeTask::TranscodeTask(const ObjectId &owner, const QString &suffix, const QString &preParams, const QString &params, int in, int out, bool replaceProducer, QObject* object, bool checkProfile)
: AbstractTask(owner, AbstractTask::TRANSCODEJOB, object)
, m_jobDuration(0)
, m_isFfmpegJob(true)
, m_suffix(suffix)
, m_transcodeParams(params)
, m_transcodePreParams(preParams)
, m_replaceProducer(replaceProducer)
......@@ -37,9 +38,9 @@ TranscodeTask::TranscodeTask(const ObjectId &owner, const QString &preParams, co
{
}
void TranscodeTask::start(const ObjectId &owner, const QString &preParams, const QString &params, int in, int out, bool replaceProducer, QObject* object, bool force, bool checkProfile)
void TranscodeTask::start(const ObjectId &owner, const QString &suffix, const QString &preParams, const QString &params, int in, int out, bool replaceProducer, QObject* object, bool force, bool checkProfile)
{
TranscodeTask* task = new TranscodeTask(owner, preParams, params, in, out, replaceProducer, object, checkProfile);
TranscodeTask* task = new TranscodeTask(owner, suffix, preParams, params, in, out, replaceProducer, object, checkProfile);
// See if there is already a task for this MLT service and resource.
if (pCore->taskManager.hasPendingJob(owner, AbstractTask::TRANSCODEJOB)) {
delete task;
......@@ -100,14 +101,19 @@ void TranscodeTask::run()
}
int fileCount = 1;
QString num = QString::number(fileCount).rightJustified(4, '0', false);
QString path = fileName + num + transcoderExt;
QString path;
if (m_suffix.isEmpty()) {
path = fileName + num + transcoderExt;
} else {
path = fileName + m_suffix + transcoderExt;
fileCount = 0;
}
while (dir.exists(path)) {
++fileCount;
num = QString::number(fileCount).rightJustified(4, '0', false);
path = fileName + num + transcoderExt;
path = fileName + num + m_suffix + transcoderExt;
}
QString destUrl = dir.absoluteFilePath(fileName);
destUrl.append(QString::number(fileCount).rightJustified(4, '0', false));
QString destUrl = dir.absoluteFilePath(path.section(QLatin1Char('.'), 0, -2));
bool result;
if (type == ClipType::Playlist || type == ClipType::SlideShow || type == ClipType::Text) {
......
......@@ -14,8 +14,8 @@ class QProcess;
class TranscodeTask : public AbstractTask
{
public:
TranscodeTask(const ObjectId &owner, const QString &preParams, const QString &params, int in, int out, bool replaceProducer, QObject* object, bool checkProfile);
static void start(const ObjectId &owner, const QString &preParams, const QString &params, int in, int out, bool replaceProducer, QObject* object, bool force = false, bool checkProfile = false);
TranscodeTask(const ObjectId &owner, const QString &suffix, const QString &preParams, const QString &params, int in, int out, bool replaceProducer, QObject* object, bool checkProfile);
static void start(const ObjectId &owner, const QString &suffix, const QString &preParams, const QString &params, int in, int out, bool replaceProducer, QObject* object, bool force = false, bool checkProfile = false);
protected:
void run() override;
......@@ -26,6 +26,7 @@ private slots:
private:
int m_jobDuration;
bool m_isFfmpegJob;
QString m_suffix;
QString m_transcodeParams;
QString m_transcodePreParams;
bool m_replaceProducer;
......
......@@ -3528,7 +3528,7 @@ void MainWindow::buildDynamicActions()
std::vector<QString> ids = pCore->bin()->selectedClipsIds(true);
for (const QString &id : ids) {
std::shared_ptr<ProjectClip> clip = pCore->projectItemModel()->getClipByBinID(id);
TranscodeTask::start({ObjectType::BinClip,id.toInt()}, QString(), transcodeData.first(), -1, -1, false, clip.get());
TranscodeTask::start({ObjectType::BinClip,id.toInt()}, QString(), QString(), transcodeData.first(), -1, -1, false, clip.get());
}
});
if (transList.count() > 2 && transList.at(2) == QLatin1String("audio")) {
......
......@@ -37,18 +37,18 @@ TranscodeSeek::~TranscodeSeek()
{
}
void TranscodeSeek::addUrl(const QString &file, const QString &id)
void TranscodeSeek::addUrl(const QString &file, const QString &id, const QString &suffix)
{
QListWidgetItem *it = new QListWidgetItem(file, listWidget);
it->setData(Qt::UserRole, id);
it->setData(Qt::UserRole + 1, suffix);
}
std::vector<QString> TranscodeSeek::ids() const
QMap<QString,QString> TranscodeSeek::ids() const
{
std::vector<QString> urls;
urls.reserve(listWidget->count());
QMap<QString,QString> urls;
for (int i = 0; i < listWidget->count(); i++) {
urls.push_back(listWidget->item(i)->data(Qt::UserRole).toString());
urls.insert(listWidget->item(i)->data(Qt::UserRole).toString(), listWidget->item(i)->data(Qt::UserRole + 1).toString());
}
return urls;
}
......
......@@ -21,8 +21,8 @@ public:
TranscodeSeek(QWidget *parent = nullptr);
~TranscodeSeek() override;
void addUrl(const QString &file, const QString &id);
std::vector<QString> ids() const;
void addUrl(const QString &file, const QString &id, const QString &suffix);
QMap<QString,QString> ids() const;
QString params() const;
QString preParams() const;
......
Markdown is supported
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