Skip to content
GitLab
Menu
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
d8b2a256
Commit
d8b2a256
authored
Jan 18, 2022
by
Jean-Baptiste Mardelle
Browse files
Fix various bugs in timeremap (keyframes random move, crashes)
parent
c7d53f8a
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/dialogs/timeremap.cpp
View file @
d8b2a256
...
...
@@ -100,7 +100,6 @@ void RemapView::updateInPos(int pos)
void
RemapView
::
updateOutPos
(
int
pos
)
{
qDebug
()
<<
"=== MOVING TO POS: "
<<
pos
<<
", CURRENT KFR: "
<<
m_currentKeyframe
.
first
;
if
(
m_currentKeyframe
.
first
>
-
1
)
{
if
(
m_keyframes
.
contains
(
pos
))
{
// Cannot move kfr over an existing one
...
...
@@ -495,8 +494,23 @@ void RemapView::mouseMoveEvent(QMouseEvent *event)
QMapIterator
<
int
,
int
>
i
(
m_selectedKeyframes
);
while
(
i
.
hasNext
())
{
i
.
next
();
if
(
i
.
value
()
+
delta
>
m_sourceDuration
)
{
return
;
if
(
i
.
value
()
+
delta
>=
m_sourceDuration
)
{
delta
=
qMin
(
delta
,
m_sourceDuration
-
i
.
value
()
-
1
);
realPos
=
m_currentKeyframe
.
second
+
delta
;
pos
=
realPos
-
m_inFrame
;
if
(
delta
==
0
)
{
pCore
->
displayMessage
(
i18n
(
"Cannot move last source keyframe past clip end"
),
MessageType
::
ErrorMessage
,
500
);
return
;
}
}
if
(
i
.
value
()
+
delta
<
0
)
{
delta
=
qMax
(
delta
,
-
i
.
value
());
realPos
=
m_currentKeyframe
.
second
+
delta
;
pos
=
realPos
-
m_inFrame
;
if
(
delta
==
0
)
{
pCore
->
displayMessage
(
i18n
(
"Cannot move first source keyframe before clip start"
),
MessageType
::
ErrorMessage
,
500
);
return
;
}
}
}
i
.
toFront
();
...
...
@@ -675,17 +689,26 @@ void RemapView::centerCurrentTopKeyframe()
}
//std::pair<int,int> range = getRange(m_currentKeyframe);
QMap
<
int
,
int
>
nextKeyframes
;
int
offset
=
m_position
+
m_inFrame
-
m_currentKeyframe
.
second
;
if
(
m_moveNext
)
{
QMap
<
int
,
int
>::
iterator
it
=
m_keyframes
.
find
(
m_currentKeyframe
.
first
);
if
(
*
it
!=
m_keyframes
.
last
()
&&
it
!=
m_keyframes
.
end
())
{
it
++
;
while
(
it
!=
m_keyframes
.
end
())
{
nextKeyframes
.
insert
(
it
.
key
(),
it
.
value
());
// Check that the move is possible
if
(
it
.
value
()
+
offset
>=
m_sourceDuration
)
{
pCore
->
displayMessage
(
i18n
(
"Cannot move last source keyframe past clip end"
),
MessageType
::
ErrorMessage
,
500
);
return
;
}
if
(
it
.
value
()
+
offset
<
0
)
{
pCore
->
displayMessage
(
i18n
(
"Cannot move first source keyframe before clip start"
),
MessageType
::
ErrorMessage
,
500
);
return
;
}
it
++
;
}
}
}
int
offset
=
m_position
+
m_inFrame
-
m_currentKeyframe
.
second
;
m_currentKeyframe
.
second
=
m_position
+
m_inFrame
;
m_keyframes
.
insert
(
m_currentKeyframe
.
first
,
m_currentKeyframe
.
second
);
QMapIterator
<
int
,
int
>
i
(
nextKeyframes
);
...
...
@@ -739,7 +762,6 @@ void RemapView::mouseReleaseEvent(QMouseEvent *event)
if
(
keyframesEdited
)
{
emit
updateKeyframesWithUndo
(
m_keyframes
,
m_keyframesOrigin
);
}
qDebug
()
<<
"=== MOUSE RELEASE!!!!!!!!!!!!!"
;
}
void
RemapView
::
mousePressEvent
(
QMouseEvent
*
event
)
...
...
@@ -1103,10 +1125,12 @@ void RemapView::goPrev()
void
RemapView
::
updateBeforeSpeed
(
double
speed
)
{
QMutexLocker
lock
(
&
m_kfrMutex
);
QMap
<
int
,
int
>::
iterator
it
=
m_keyframes
.
find
(
m_currentKeyframe
.
first
);
QMap
<
int
,
int
>
updatedKfrs
;
QList
<
int
>
toDelete
;
if
(
*
it
!=
m_keyframes
.
first
()
&&
it
!=
m_keyframes
.
end
())
{
m_keyframesOrigin
=
m_keyframes
;
it
--
;
int
updatedLength
=
qFuzzyIsNull
(
speed
)
?
0
:
(
m_currentKeyframe
.
second
-
it
.
value
())
*
100.
/
speed
;
int
offset
=
it
.
key
()
+
updatedLength
-
m_currentKeyframe
.
first
;
...
...
@@ -1116,12 +1140,15 @@ void RemapView::updateBeforeSpeed(double speed)
m_bottomPosition
=
m_currentKeyframe
.
first
;
m_selectedKeyframes
.
clear
();
m_selectedKeyframes
.
insert
(
m_currentKeyframe
.
first
,
m_currentKeyframe
.
second
);
it
+=
2
;
// Update all keyframes after that so that we don't alter the speeds
while
(
m_moveNext
&&
it
!=
m_keyframes
.
end
())
{
toDelete
<<
it
.
key
();
updatedKfrs
.
insert
(
it
.
key
()
+
offset
,
it
.
value
());
it
++
;
if
(
*
it
!=
m_keyframes
.
last
())
{
it
++
;
// Update all keyframes after that so that we don't alter the speeds
while
(
m_moveNext
&&
it
!=
m_keyframes
.
end
())
{
toDelete
<<
it
.
key
();
updatedKfrs
.
insert
(
it
.
key
()
+
offset
,
it
.
value
());
it
++
;
}
}
for
(
int
p
:
qAsConst
(
toDelete
))
{
m_keyframes
.
remove
(
p
);
...
...
@@ -1131,15 +1158,21 @@ void RemapView::updateBeforeSpeed(double speed)
i
.
next
();
m_keyframes
.
insert
(
i
.
key
(),
i
.
value
());
}
emit
updateKeyframes
(
true
);
int
maxWidth
=
width
()
-
(
2
*
m_offset
);
m_scale
=
maxWidth
/
double
(
qMax
(
1
,
remapMax
()));
m_zoomStart
=
m_zoomHandle
.
x
()
*
maxWidth
;
m_zoomFactor
=
maxWidth
/
(
m_zoomHandle
.
y
()
*
maxWidth
-
m_zoomStart
);
emit
updateKeyframesWithUndo
(
m_keyframes
,
m_keyframesOrigin
);
update
();
}
}
void
RemapView
::
updateAfterSpeed
(
double
speed
)
{
QMutexLocker
lock
(
&
m_kfrMutex
);
QMap
<
int
,
int
>::
iterator
it
=
m_keyframes
.
find
(
m_currentKeyframe
.
first
);
if
(
*
it
!=
m_keyframes
.
last
())
{
m_keyframesOrigin
=
m_keyframes
;
it
++
;
QMap
<
int
,
int
>
updatedKfrs
;
QList
<
int
>
toDelete
;
...
...
@@ -1164,7 +1197,11 @@ void RemapView::updateAfterSpeed(double speed)
i
.
next
();
m_keyframes
.
insert
(
i
.
key
(),
i
.
value
());
}
emit
updateKeyframes
(
true
);
int
maxWidth
=
width
()
-
(
2
*
m_offset
);
m_scale
=
maxWidth
/
double
(
qMax
(
1
,
remapMax
()));
m_zoomStart
=
m_zoomHandle
.
x
()
*
maxWidth
;
m_zoomFactor
=
maxWidth
/
(
m_zoomHandle
.
y
()
*
maxWidth
-
m_zoomStart
);
emit
updateKeyframesWithUndo
(
m_keyframes
,
m_keyframesOrigin
);
update
();
}
}
...
...
@@ -1183,7 +1220,9 @@ const QString RemapView::getKeyframesData(QMap<int,int> keyframes) const
// HACK: we always set last keyframe 1 frame after in MLT to ensure we have a correct last frame
offset
=
1
;
}
result
<<
QString
(
"%1=%2"
).
arg
(
m_service
->
frames_to_time
(
i
.
key
()
+
offset
,
mlt_time_clock
)).
arg
(
GenTime
(
i
.
value
(),
pCore
->
getCurrentFps
()).
seconds
());
Mlt
::
Properties
props
;
props
.
set
(
"_profile"
,
pCore
->
getProjectProfile
()
->
get_profile
(),
0
);
result
<<
QString
(
"%1=%2"
).
arg
(
props
.
frames_to_time
(
i
.
key
()
+
offset
,
mlt_time_clock
)).
arg
(
GenTime
(
i
.
value
(),
pCore
->
getCurrentFps
()).
seconds
());
}
return
result
.
join
(
QLatin1Char
(
';'
));
}
...
...
@@ -1303,6 +1342,8 @@ void RemapView::addKeyframe()
void
RemapView
::
toggleMoveNext
(
bool
moveNext
)
{
m_moveNext
=
moveNext
;
// Reset keyframe selection
m_selectedKeyframes
.
clear
();
}
void
RemapView
::
refreshOnDurationChanged
(
int
remapDuration
)
...
...
src/dialogs/timeremap.h
View file @
d8b2a256
...
...
@@ -14,6 +14,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include <QWidget>
#include <QTimer>
#include <QMutex>
#include "mlt++/Mlt.h"
...
...
@@ -118,6 +119,7 @@ private:
bool
m_moveNext
;
int
m_clickEnd
;
int
m_offset
;
QMutex
m_kfrMutex
;
QMap
<
int
,
int
>
m_selectedKeyframes
;
QMap
<
int
,
int
>
m_previousSelection
;
std
::
pair
<
int
,
int
>
getClosestKeyframe
(
int
pos
,
bool
bottomKeyframe
=
false
)
const
;
...
...
src/timeline2/model/clipmodel.cpp
View file @
d8b2a256
...
...
@@ -905,6 +905,7 @@ bool ClipModel::useTimeRemapProducer(bool enable, Fun &undo, Fun &redo)
std
::
function
<
bool
(
void
)
>
local_redo
=
[]()
{
return
true
;
};
int
audioStream
=
getIntProperty
(
QStringLiteral
(
"audio_index"
));
QMap
<
QString
,
QString
>
remapProperties
;
remapProperties
.
insert
(
QStringLiteral
(
"image_mode"
),
QStringLiteral
(
"nearest"
));
if
(
!
enable
)
{
// Store the remap properties
if
(
m_producer
->
parent
().
type
()
==
mlt_service_chain_type
)
{
...
...
src/ui/timeremap_ui.ui
View file @
d8b2a256
...
...
@@ -60,6 +60,19 @@
<item>
<layout
class=
"QHBoxLayout"
name=
"inLayout"
/>
</item>
<item>
<spacer
name=
"horizontalSpacer"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
40
</width>
<height>
20
</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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