Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Multimedia
Kdenlive
Commits
3331cba0
Commit
3331cba0
authored
Mar 17, 2020
by
Jean-Baptiste Mardelle
Browse files
Fix dual pass effects (motion tracker using incorrect zone)
parent
9509dd0d
Changes
10
Hide whitespace changes
Inline
Side-by-side
data/effects/loudness.xml
View file @
3331cba0
...
...
@@ -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>
...
...
data/effects/tracker.xml
View file @
3331cba0
...
...
@@ -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>
src/assets/model/assetparametermodel.cpp
View file @
3331cba0
...
...
@@ -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
;
}
...
...
src/assets/model/assetparametermodel.hpp
View file @
3331cba0
...
...
@@ -93,6 +93,7 @@ public:
FilterRole
,
FilterJobParamsRole
,
FilterParamsRole
,
FilterConsumerParamsRole
,
ScaleRole
,
OpacityRole
,
RelativePosRole
,
...
...
src/assets/view/widgets/buttonparamwidget.cpp
View file @
3331cba0
...
...
@@ -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
);
}
...
...
src/jobs/filterclipjob.cpp
View file @
3331cba0
...
...
@@ -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
();
...
...
src/jobs/filterclipjob.h
View file @
3331cba0
...
...
@@ -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
;
};
...
...
src/jobs/meltjob.cpp
View file @
3331cba0
...
...
@@ -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
));
...
...
src/jobs/scenesplitjob.cpp
View file @
3331cba0
...
...
@@ -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
()
...
...
src/jobs/stabilizejob.cpp
View file @
3331cba0
...
...
@@ -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
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment