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
c1a06607
Commit
c1a06607
authored
Mar 06, 2022
by
Jean-Baptiste Mardelle
Browse files
Ensure timeline clips are reloaded on change.
Should fix
#814
parent
1683e9ad
Pipeline
#145734
passed with stage
in 6 minutes and 42 seconds
Changes
10
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/bin/projectclip.cpp
View file @
c1a06607
...
...
@@ -72,6 +72,7 @@ ProjectClip::ProjectClip(const QString &id, const QIcon &thumb, const std::share
,
ClipController
(
id
,
producer
)
,
m_resetTimelineOccurences
(
false
)
,
m_audioCount
(
0
)
,
m_uuid
(
QUuid
::
createUuid
())
{
m_markerModel
=
std
::
make_shared
<
MarkerListModel
>
(
id
,
pCore
->
projectManager
()
->
undoStack
());
if
(
producer
->
get_int
(
"_placeholder"
)
==
1
)
{
...
...
@@ -142,6 +143,7 @@ ProjectClip::ProjectClip(const QString &id, const QDomElement &description, cons
,
ClipController
(
id
)
,
m_resetTimelineOccurences
(
false
)
,
m_audioCount
(
0
)
,
m_uuid
(
QUuid
::
createUuid
())
{
m_clipStatus
=
FileStatus
::
StatusWaiting
;
m_thumbnail
=
thumb
;
...
...
@@ -377,10 +379,13 @@ void ProjectClip::reloadProducer(bool refreshOnly, bool isProxy, bool forceAudio
// In that case, we only want a new thumbnail.
// We thus set up a thumb job. We must make sure that there is no pending LOADJOB
// Clear cache first
ThumbnailCache
::
get
()
->
invalidateThumbsForClip
(
clipId
()
);
ThumbnailCache
::
get
()
->
invalidateThumbsForClip
(
m_binId
);
pCore
->
taskManager
.
discardJobs
({
ObjectType
::
BinClip
,
m_binId
.
toInt
()},
AbstractTask
::
LOADJOB
,
true
);
pCore
->
taskManager
.
discardJobs
({
ObjectType
::
BinClip
,
m_binId
.
toInt
()},
AbstractTask
::
CACHEJOB
);
m_thumbsProducer
.
reset
();
// Reset uuid to enforce reloading thumbnails from qml cache
m_uuid
=
QUuid
::
createUuid
();
updateTimelineClips
({
TimelineModel
::
ClipThumbRole
});
ClipLoadTask
::
start
({
ObjectType
::
BinClip
,
m_binId
.
toInt
()},
QDomElement
(),
true
,
-
1
,
-
1
,
this
);
}
else
{
// If another load job is running?
...
...
@@ -419,6 +424,9 @@ void ProjectClip::reloadProducer(bool refreshOnly, bool isProxy, bool forceAudio
}
m_audioThumbCreated
=
false
;
ThumbnailCache
::
get
()
->
invalidateThumbsForClip
(
clipId
());
// Reset uuid to enforce reloading thumbnails from qml cache
m_uuid
=
QUuid
::
createUuid
();
updateTimelineClips
({
TimelineModel
::
ClipThumbRole
});
if
(
forceAudioReload
||
(
!
isProxy
&&
hashChanged
))
{
discardAudioThumb
();
}
...
...
@@ -475,7 +483,7 @@ void ProjectClip::setThumbnail(const QImage &img, int in, int out, bool inCache)
}
if
(
!
inCache
&&
(
m_clipType
==
ClipType
::
Text
||
m_clipType
==
ClipType
::
TextTemplate
))
{
// Title clips always use the same thumb as bin, refresh
updateTimelineClips
({
TimelineModel
::
Reload
ThumbRole
});
updateTimelineClips
({
TimelineModel
::
Clip
ThumbRole
});
}
}
...
...
@@ -2234,3 +2242,8 @@ const QStringList ProjectClip::enforcedParams() const
}
return
params
;
}
const
QString
ProjectClip
::
baseThumbPath
()
{
return
QString
(
"%1/%2/#"
).
arg
(
m_binId
).
arg
(
m_uuid
.
toString
());
}
src/bin/projectclip.h
View file @
c1a06607
...
...
@@ -17,6 +17,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include <QFuture>
#include <QMutex>
#include <QTimer>
#include <QUuid>
#include <memory>
class
ClipPropertiesController
;
...
...
@@ -237,6 +238,8 @@ public:
/** @brief Retuns a list of important enforces parameters in MLT format, for example to disable autorotate. */
const
QStringList
enforcedParams
()
const
;
const
QString
baseThumbPath
();
protected:
friend
class
ClipModel
;
/** @brief This is a call-back called by a ClipModel when it is created
...
...
@@ -318,6 +321,7 @@ private:
std
::
unordered_map
<
int
,
std
::
shared_ptr
<
Mlt
::
Producer
>>
m_videoProducers
;
std
::
unordered_map
<
int
,
std
::
shared_ptr
<
Mlt
::
Producer
>>
m_timewarpProducers
;
std
::
shared_ptr
<
Mlt
::
Producer
>
m_disabledProducer
;
QUuid
m_uuid
;
signals:
void
producerChanged
(
const
QString
&
,
const
std
::
shared_ptr
<
Mlt
::
Producer
>
&
);
...
...
src/timeline2/model/clipmodel.cpp
View file @
c1a06607
...
...
@@ -1474,3 +1474,12 @@ QString ClipModel::clipHash() const
container
.
appendChild
(
m_effectStack
->
toXml
(
document
));
return
document
.
toString
();
}
const
QString
ClipModel
::
clipThumbPath
()
{
std
::
shared_ptr
<
ProjectClip
>
binClip
=
pCore
->
projectItemModel
()
->
getClipByBinID
(
m_binClipId
);
if
(
binClip
)
{
return
binClip
->
baseThumbPath
();
}
return
QString
();
}
src/timeline2/model/clipmodel.hpp
View file @
c1a06607
...
...
@@ -147,6 +147,7 @@ public:
/** @brief Tracks have two sub playlists to enable same track transitions. This returns the index of the sub-playlist containing this clip */
int
getSubPlaylistIndex
()
const
;
void
setSubPlaylistIndex
(
int
index
,
int
trackId
);
const
QString
clipThumbPath
();
friend
class
TrackModel
;
friend
class
TimelineModel
;
...
...
src/timeline2/model/timelineitemmodel.cpp
View file @
c1a06607
...
...
@@ -228,7 +228,7 @@ QHash<int, QByteArray> TimelineItemModel::roleNames() const
roles
[
HasAudio
]
=
"hasAudio"
;
roles
[
CanBeAudioRole
]
=
"canBeAudio"
;
roles
[
CanBeVideoRole
]
=
"canBeVideo"
;
roles
[
Reload
ThumbRole
]
=
"
reload
Thumb"
;
roles
[
Clip
ThumbRole
]
=
"
clip
Thumb
Id
"
;
roles
[
ReloadAudioThumbRole
]
=
"reloadAudioThumb"
;
roles
[
PositionOffsetRole
]
=
"positionOffset"
;
roles
[
ThumbsFormatRole
]
=
"thumbsFormat"
;
...
...
@@ -340,8 +340,8 @@ QVariant TimelineItemModel::data(const QModelIndex &index, int role) const
return
clip
->
getMixDuration
();
case
MixCutRole
:
return
clip
->
getMixCutPosition
();
case
Reload
ThumbRole
:
return
clip
->
forceThumbReload
;
case
Clip
ThumbRole
:
return
clip
->
clipThumbPath
()
;
case
ReloadAudioThumbRole
:
return
clip
->
forceThumbReload
;
case
PositionOffsetRole
:
...
...
src/timeline2/model/timelinemodel.cpp
View file @
c1a06607
...
...
@@ -5499,7 +5499,7 @@ void TimelineModel::replugClip(int clipId)
void
TimelineModel
::
requestClipUpdate
(
int
clipId
,
const
QVector
<
int
>
&
roles
)
{
QModelIndex
modelIndex
=
makeClipIndexFromID
(
clipId
);
if
(
roles
.
contains
(
TimelineModel
::
ReloadThumbRole
)
||
roles
.
contains
(
TimelineModel
::
ReloadAudioThumbRole
))
{
if
(
roles
.
contains
(
TimelineModel
::
ReloadAudioThumbRole
))
{
m_allClips
[
clipId
]
->
forceThumbReload
=
!
m_allClips
[
clipId
]
->
forceThumbReload
;
}
notifyChange
(
modelIndex
,
modelIndex
,
roles
);
...
...
src/timeline2/model/timelinemodel.hpp
View file @
c1a06607
...
...
@@ -145,7 +145,7 @@ public:
FadeOutRole
,
/// clip only
FileHashRole
,
/// clip only
SpeedRole
,
/// clip only
Reload
ThumbRole
,
/// clip only
Clip
ThumbRole
,
/// clip only
ReloadAudioThumbRole
,
/// clip only
PositionOffsetRole
,
/// clip only
TimeRemapRole
,
/// clip only
...
...
src/timeline2/view/qml/Clip.qml
View file @
c1a06607
...
...
@@ -66,7 +66,7 @@ Rectangle {
property
bool
canBeVideo
property
double
speed
:
1.0
property
color
borderColor
:
"
#000000
"
property
bool
forceReload
Thumb
property
string
clip
Thumb
Id
property
bool
forceReloadAudioThumb
property
bool
isComposition
:
false
property
bool
hideClipViews
:
scrollStart
>
(
clipDuration
*
timeline
.
scaleFactor
)
||
scrollStart
+
scrollView
.
width
<
0
||
clipRoot
.
width
<
root
.
minClipWidthForViews
...
...
@@ -163,16 +163,6 @@ Rectangle {
}
}
onForceReloadThumbChanged
:
{
// TODO: find a way to force reload of clip thumbs
if
(
isAudio
)
{
return
;
}
if
(
thumbsLoader
.
item
)
{
thumbsLoader
.
item
.
reload
(
0
)
}
}
onForceReloadAudioThumbChanged
:
{
// TODO: find a way to force reload of clip thumbs
if
(
!
isAudio
)
{
...
...
@@ -260,7 +250,7 @@ Rectangle {
}
*/
property
bool
noThumbs
:
(
isAudio
||
itemType
===
ProducerType
.
Color
||
mltService
===
''
)
property
string
baseThumbPath
:
noThumbs
?
''
:
'
image://thumbnail/
'
+
binId
+
'
/
'
+
documentId
+
'
/#
'
property
string
baseThumbPath
:
noThumbs
?
''
:
'
image://thumbnail/
'
+
clipThumbId
DropArea
{
//Drop area for clips
anchors.fill
:
clipRoot
...
...
src/timeline2/view/qml/ClipThumbs.qml
View file @
c1a06607
...
...
@@ -19,10 +19,6 @@ Row {
property
bool
fixedThumbs
:
clipRoot
.
itemType
===
ProducerType
.
Image
||
clipRoot
.
itemType
===
ProducerType
.
Text
||
clipRoot
.
itemType
===
ProducerType
.
TextTemplate
property
int
thumbWidth
:
container
.
height
*
root
.
dar
property
bool
enableCache
:
clipRoot
.
itemType
===
ProducerType
.
Video
||
clipRoot
.
itemType
===
ProducerType
.
AV
function
reload
(
reset
)
{
//console.log('+++++\n\ntriggered ML thumb reload\n\n++++++++++++++')
clipRoot
.
baseThumbPath
=
clipRoot
.
variableThumbs
?
''
:
'
image://thumbnail/
'
+
clipRoot
.
binId
+
'
/
'
+
Math
.
random
()
+
'
/#
'
}
Repeater
{
id
:
thumbRepeater
...
...
src/timeline2/view/qml/Track.qml
View file @
c1a06607
...
...
@@ -236,8 +236,8 @@ Item{
}
Binding
{
target
:
loader
.
item
property
:
"
forceReload
Thumb
"
value
:
model
.
reload
Thumb
property
:
"
clip
Thumb
Id
"
value
:
model
.
clip
Thumb
Id
when
:
loader
.
status
==
Loader
.
Ready
&&
clipItem
}
Binding
{
...
...
Write
Preview
Markdown
is supported
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