Fix dual pass effects (motion tracker using incorrect zone)

parent 9509dd0d
......@@ -7,7 +7,7 @@
<name>Target Program Loudness</name>
</parameter>
<parameter type="filterjob" filtertag="loudness" filterparams="%params" consumer="null" consumerparams="video_off=1 no_meta=1 all=1 terminate_on_pause=1">
<name>Analyse</name>
<name conditional="Reset">Analyse</name>
<jobparam name="key">results</jobparam>
<jobparam name="finalfilter">loudness</jobparam>
</parameter>
......
......@@ -80,12 +80,13 @@
<name>Tracking data</name>
<comment>Click to copy to clipboard</comment>
</parameter>
<parameter type="filterjob" filtertag="opencv.tracker" consumer="null" consumerparams=" all=1 terminate_on_pause=1">
<parameter type="filterjob" filtertag="opencv.tracker" consumer="null" consumerparams="all=1 terminate_on_pause=1 audio_off=1 no_meta=1 real_time=-1">
<name conditional="Reset">Analyse</name>
<jobparam name="conditionalinfo">Filter is in preview mode. Click Analyse to see real effect</jobparam>
<jobparam name="key">results</jobparam>
<jobparam name="finalfilter">opencv.tracker</jobparam>
<jobparam name="displaydataname">Motion tracking</jobparam>
<jobparam name="relativeInOut">1</jobparam>
</parameter>
</effect>
</group>
......@@ -349,6 +349,8 @@ QVariant AssetParameterModel::data(const QModelIndex &index, int role) const
return parseAttribute(m_ownerId, QStringLiteral("filter"), element);
case FilterParamsRole:
return parseAttribute(m_ownerId, QStringLiteral("filterparams"), element);
case FilterConsumerParamsRole:
return parseAttribute(m_ownerId, QStringLiteral("consumerparams"), element);
case FilterJobParamsRole:
return parseSubAttributes(QStringLiteral("jobparam"), element);
case AlternateNameRole: {
......@@ -591,7 +593,9 @@ QVector<QPair<QString, QVariant>> AssetParameterModel::getAllParameters() const
}
for (const auto &param : m_params) {
res.push_back(QPair<QString, QVariant>(param.first, param.second.value));
if (!param.first.isEmpty()) {
res.push_back(QPair<QString, QVariant>(param.first, param.second.value));
}
}
return res;
}
......
......@@ -93,6 +93,7 @@ public:
FilterRole,
FilterJobParamsRole,
FilterParamsRole,
FilterConsumerParamsRole,
ScaleRole,
OpacityRole,
RelativePosRole,
......
......@@ -45,6 +45,8 @@ ButtonParamWidget::ButtonParamWidget(std::shared_ptr<AssetParameterModel> model,
auto *layout = new QVBoxLayout(this);
QVariantList filterData = m_model->data(m_index, AssetParameterModel::FilterJobParamsRole).toList();
QStringList filterAddedParams = m_model->data(m_index, AssetParameterModel::FilterParamsRole).toString().split(QLatin1Char(' '), QString::SkipEmptyParts);
QStringList consumerParams = m_model->data(m_index, AssetParameterModel::FilterConsumerParamsRole).toString().split(QLatin1Char(' '), QString::SkipEmptyParts);
QString conditionalInfo;
for (const QVariant jobElement : filterData) {
QStringList d = jobElement.toStringList();
......@@ -79,7 +81,7 @@ ButtonParamWidget::ButtonParamWidget(std::shared_ptr<AssetParameterModel> model,
setMinimumHeight(m_button->sizeHint().height() + (m_label != nullptr ? m_label->sizeHint().height() : 0));
// emit the signal of the base class when appropriate
connect(this->m_button, &QPushButton::clicked, [&, filterData, filterAddedParams]() {
connect(this->m_button, &QPushButton::clicked, [&, filterData, filterAddedParams, consumerParams]() {
// Trigger job
if (!m_displayConditional) {
QVector<QPair<QString, QVariant>> values;
......@@ -114,14 +116,16 @@ ButtonParamWidget::ButtonParamWidget(std::shared_ptr<AssetParameterModel> model,
fData.insert({d.at(0), d.at(1)});
}
for (const auto &param : filterLastParams) {
fParams.insert({param.first, param.second});
if (param.first != m_keyParam) {
fParams.insert({param.first, param.second});
}
}
for (const QString &fparam : filterAddedParams) {
if (fparam.contains(QLatin1Char('='))) {
fParams.insert({fparam.section(QLatin1Char('='), 0, 0), fparam.section(QLatin1Char('='), 1)});
}
}
pCore->jobManager()->startJob<FilterClipJob>({binId}, -1, QString(), owner, m_model, assetId, in, out, assetId, fParams, fData);
pCore->jobManager()->startJob<FilterClipJob>({binId}, -1, QString(), owner, m_model, assetId, in, out, assetId, fParams, fData, consumerParams);
if (m_label) {
m_label->setVisible(false);
}
......
......@@ -31,13 +31,14 @@
#include <klocalizedstring.h>
FilterClipJob::FilterClipJob(const QString &binId, const ObjectId &owner, std::weak_ptr<AssetParameterModel> model, const QString &assetId, int in, int out, const QString &filterName, std::unordered_map<QString, QVariant> filterParams, std::unordered_map<QString, QString> filterData)
FilterClipJob::FilterClipJob(const QString &binId, const ObjectId &owner, std::weak_ptr<AssetParameterModel> model, const QString &assetId, int in, int out, const QString &filterName, std::unordered_map<QString, QVariant> filterParams, std::unordered_map<QString, QString> filterData, const QStringList consumerArgs)
: MeltJob(binId, FILTERCLIPJOB, false, in, out)
, m_model(model)
, m_filterName(filterName)
, m_assetId(assetId)
, m_filterParams(std::move(filterParams))
, m_filterData(std::move(filterData))
, m_consumerArgs(consumerArgs)
, m_owner(owner)
{
m_timelineClipId = -1;
......@@ -60,6 +61,10 @@ void FilterClipJob::configureProducer()
m_profile.reset(&pCore->getCurrentProfile()->profile());
m_producer = pCore->getTrackProducerInstance(m_owner.second);
}
length = m_producer->get_playtime();
if (length == 0) {
length = m_producer->get_length();
}
}
const QString FilterClipJob::getDescription() const
......@@ -70,9 +75,12 @@ const QString FilterClipJob::getDescription() const
void FilterClipJob::configureConsumer()
{
m_consumer = std::make_unique<Mlt::Consumer>(*m_profile.get(), "xml");
m_consumer->set("all", 1);
m_consumer->set("terminate_on_pause", 1);
m_consumer = std::make_unique<Mlt::Consumer>(*m_profile.get(), "null");
for (const QString param : m_consumerArgs) {
if (param.contains(QLatin1Char('='))) {
m_consumer->set(param.section(QLatin1Char('='), 0, 0).toUtf8().constData(), param.section(QLatin1Char('='), 1).toInt());
}
}
}
void FilterClipJob::configureFilter()
......@@ -94,6 +102,11 @@ void FilterClipJob::configureFilter()
m_filter->set(it.first.toUtf8().constData(), it.second.toString().toUtf8().constData());
}
}
if (m_filterData.find(QLatin1String("relativeInOut")) != m_filterData.end()) {
m_filter->set_in_and_out(0, length - 1);
} else {
m_filter->set_in_and_out(m_producer->get_in(), m_producer->get_out());
}
}
bool FilterClipJob::commitResult(Fun &undo, Fun &redo)
......@@ -104,8 +117,8 @@ bool FilterClipJob::commitResult(Fun &undo, Fun &redo)
return false;
}
m_resultConsumed = true;
m_producer->detach(*m_filter.get());
if (!m_successful) {
m_producer->detach(*m_filter.get());
m_filter.reset();
m_producer.reset();
m_wholeProducer.reset();
......@@ -116,7 +129,7 @@ bool FilterClipJob::commitResult(Fun &undo, Fun &redo)
if (m_filterData.find(QStringLiteral("key")) != m_filterData.end()) {
key = m_filterData.at(QStringLiteral("key"));
}
QString resultData = QString::fromLatin1(m_filter->get(key.toUtf8().constData()));
QString resultData = qstrdup(m_filter->get(key.toUtf8().constData()));
params.append({key,QVariant(resultData)});
qDebug()<<"= = = GOT FILTER RESULTS: "<<params;
if (m_filterData.find(QStringLiteral("storedata")) != m_filterData.end()) {
......@@ -143,6 +156,7 @@ bool FilterClipJob::commitResult(Fun &undo, Fun &redo)
return true;
};
bool ok = operation();
m_producer->detach(*m_filter.get());
m_filter.reset();
m_producer.reset();
m_wholeProducer.reset();
......
......@@ -33,7 +33,7 @@ class FilterClipJob : public MeltJob
Q_OBJECT
public:
FilterClipJob(const QString &binId, const ObjectId &owner, std::weak_ptr<AssetParameterModel> model, const QString &assetId, int in, int out, const QString &filterName, std::unordered_map<QString, QVariant> filterParams, std::unordered_map<QString, QString> filterData);
FilterClipJob(const QString &binId, const ObjectId &owner, std::weak_ptr<AssetParameterModel> model, const QString &assetId, int in, int out, const QString &filterName, std::unordered_map<QString, QVariant> filterParams, std::unordered_map<QString, QString> filterData, const QStringList consumerArgs);
const QString getDescription() const override;
/** @brief This is to be called after the job finished.
By design, the job should store the result of the computation but not share it with the rest of the code. This happens when we call commitResult */
......@@ -56,6 +56,7 @@ protected:
QString m_assetId;
std::unordered_map<QString, QVariant> m_filterParams;
std::unordered_map<QString, QString> m_filterData;
QStringList m_consumerArgs;
ObjectId m_owner;
};
......
......@@ -114,6 +114,12 @@ bool MeltJob::startJob()
} else {
// Filter applied on a track of master producer, leave config to source job
}
if (m_producer != nullptr) {
length = m_producer->get_playtime();
if (length == 0) {
length = m_producer->get_length();
}
}
configureProducer();
if ((m_producer == nullptr) || !m_producer->is_valid()) {
......@@ -195,18 +201,11 @@ bool MeltJob::startJob()
}
Mlt::Tractor tractor(*m_profile.get());
Mlt::Playlist playlist(*m_profile.get());
tractor.set_track(playlist, 0);
playlist.append(*m_producer.get());
tractor.set_track(*m_producer.get(), 0);
m_consumer->connect(tractor);
m_producer->set_speed(0);
m_producer->seek(0);
length = m_producer->get_playtime();
if (length == 0) {
length = m_producer->get_length();
}
if (m_filter) {
m_filter->set_in_and_out(0, length - 1);
m_producer->attach(*m_filter.get());
}
m_showFrameEvent.reset(m_consumer->listen("consumer-frame-show", this, (mlt_listener)consumer_frame_render));
......
......@@ -71,6 +71,7 @@ void SceneSplitJob::configureFilter()
m_filter->set("shot_change_list", 0);
m_filter->set("denoise", 0);
m_filter->set_in_and_out(0, length - 1);
}
void SceneSplitJob::configureProfile()
......
......@@ -71,6 +71,7 @@ void StabilizeJob::configureFilter()
}
QString targetFile = m_destUrl + QStringLiteral(".trf");
m_filter->set("filename", targetFile.toUtf8().constData());
m_filter->set_in_and_out(0, length - 1);
}
// static
......
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