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
57152173
Commit
57152173
authored
Mar 25, 2022
by
Jean-Baptiste Mardelle
Browse files
Fix thumbnail cache bug causing incorrect thumbs to sometimes display after saving project
parent
2933fe30
Pipeline
#154822
passed with stage
in 11 minutes and 51 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/bin/projectclip.cpp
View file @
57152173
...
...
@@ -426,7 +426,6 @@ void ProjectClip::reloadProducer(bool refreshOnly, bool isProxy, bool forceAudio
m_audioThumbCreated
=
false
;
// Reset uuid to enforce reloading thumbnails from qml cache
m_uuid
=
QUuid
::
createUuid
();
updateTimelineClips
({
TimelineModel
::
ClipThumbRole
});
if
(
forceAudioReload
||
(
!
isProxy
&&
hashChanged
))
{
discardAudioThumb
();
}
...
...
@@ -516,6 +515,8 @@ bool ProjectClip::setProducer(std::shared_ptr<Mlt::Producer> producer, bool gene
qDebug
()
<<
"################### ProjectClip::setproducer #################"
;
QMutexLocker
locker
(
&
m_producerMutex
);
FileStatus
::
ClipStatus
currentStatus
=
m_clipStatus
;
// Make sure we have a hash for this clip
getFileHash
();
updateProducer
(
producer
);
emit
producerChanged
(
m_binId
,
producer
);
m_thumbsProducer
.
reset
();
...
...
@@ -541,7 +542,7 @@ bool ProjectClip::setProducer(std::shared_ptr<Mlt::Producer> producer, bool gene
QVector
<
int
>
updateRoles
;
if
(
m_clipStatus
!=
currentStatus
)
{
updateRoles
=
{
AbstractProjectItem
::
ClipStatus
,
AbstractProjectItem
::
IconOverlay
};
updateTimelineClips
({
TimelineModel
::
StatusRole
});
updateTimelineClips
({
TimelineModel
::
StatusRole
,
TimelineModel
::
ClipThumbRole
});
}
setTags
(
getProducerProperty
(
QStringLiteral
(
"kdenlive:tags"
)));
AbstractProjectItem
::
setRating
(
uint
(
getProducerIntProperty
(
QStringLiteral
(
"kdenlive:rating"
))));
...
...
@@ -551,8 +552,6 @@ bool ProjectClip::setProducer(std::shared_ptr<Mlt::Producer> producer, bool gene
updateRoles
);
std
::
static_pointer_cast
<
ProjectItemModel
>
(
ptr
)
->
updateWatcher
(
std
::
static_pointer_cast
<
ProjectClip
>
(
shared_from_this
()));
}
// Make sure we have a hash for this clip
getFileHash
();
// set parent again (some info need to be stored in producer)
updateParent
(
parentItem
().
lock
());
if
(
generateThumb
&&
m_clipType
!=
ClipType
::
Audio
)
{
...
...
src/project/projectmanager.cpp
View file @
57152173
...
...
@@ -360,8 +360,7 @@ bool ProjectManager::saveFileAs(const QString &outputFileName, bool saveACopy)
}
QUrl
url
=
QUrl
::
fromLocalFile
(
outputFileName
);
// Save timeline thumbnails
QStringList
thumbKeys
=
pCore
->
window
()
->
getMainTimeline
()
->
controller
()
->
getThumbKeys
();
ThumbnailCache
::
get
()
->
saveCachedThumbs
(
thumbKeys
);
ThumbnailCache
::
get
()
->
saveCachedThumbs
(
pCore
->
window
()
->
getMainTimeline
()
->
controller
()
->
getThumbKeys
());
if
(
!
saveACopy
)
{
m_project
->
setUrl
(
url
);
// setting up autosave file in ~/.kde/data/stalefiles/kdenlive/
...
...
src/timeline2/view/timelinecontroller.cpp
View file @
57152173
...
...
@@ -4184,17 +4184,24 @@ bool TimelineController::endFakeGroupMove(int clipId, int groupId, int delta_tra
return
true
;
}
QStringList
TimelineController
::
getThumbKeys
()
const
std
::
unordered_map
<
QString
,
std
::
vector
<
int
>>
TimelineController
::
getThumbKeys
()
{
QStringList
result
;
std
::
unordered_map
<
QString
,
std
::
vector
<
int
>>
framesToStore
;
for
(
const
auto
&
clp
:
m_model
->
m_allClips
)
{
if
(
clp
.
second
->
isAudioOnly
())
{
//Don't process audio clips
continue
;
}
const
QString
binId
=
getClipBinId
(
clp
.
first
);
std
::
shared_ptr
<
ProjectClip
>
binClip
=
pCore
->
bin
()
->
getBinClip
(
binId
);
result
<<
binClip
->
hash
()
+
QLatin1Char
(
'#'
)
+
QString
::
number
(
clp
.
second
->
getIn
())
+
QStringLiteral
(
".jpg"
);
result
<<
binClip
->
hash
()
+
QLatin1Char
(
'#'
)
+
QString
::
number
(
clp
.
second
->
getOut
())
+
QStringLiteral
(
".jpg"
);
framesToStore
[
binId
].
push_back
(
clp
.
second
->
getIn
());
framesToStore
[
binId
].
push_back
(
clp
.
second
->
getOut
());
}
result
.
removeDuplicates
();
return
result
;
for
(
auto
p
:
framesToStore
)
{
std
::
sort
(
p
.
second
.
begin
(),
p
.
second
.
end
());
auto
last
=
std
::
unique
(
p
.
second
.
begin
(),
p
.
second
.
end
());
p
.
second
.
erase
(
last
,
p
.
second
.
end
());
}
return
framesToStore
;
}
bool
TimelineController
::
isInSelection
(
int
itemId
)
...
...
src/timeline2/view/timelinecontroller.h
View file @
57152173
...
...
@@ -601,7 +601,7 @@ public:
/** @brief Set keyboard grabbing on current selection */
Q_INVOKABLE
void
grabCurrent
();
/** @brief Returns keys for all used thumbnails */
QStringList
getThumbKeys
();
const
std
::
unordered_map
<
QString
,
std
::
vector
<
int
>>
getThumbKeys
();
/** @brief Returns true if a drag operation is currently running in timeline */
bool
dragOperationRunning
();
/** @brief Returns true if the timeline is in trimming mode (slip, slide, ripple, rolle) */
...
...
src/utils/thumbnailcache.cpp
View file @
57152173
...
...
@@ -155,7 +155,9 @@ QImage ThumbnailCache::getThumbnail(const QString &binId, int pos, bool volatile
}
QDir
thumbFolder
=
getDir
(
false
,
&
ok
);
if
(
ok
&&
thumbFolder
.
exists
(
key
))
{
m_storedOnDisk
[
binId
].
push_back
(
pos
);
if
(
m_storedOnDisk
.
find
(
binId
)
==
m_storedOnDisk
.
end
()
||
std
::
find
(
m_storedOnDisk
[
binId
].
begin
(),
m_storedOnDisk
[
binId
].
end
(),
pos
)
==
m_storedOnDisk
[
binId
].
end
())
{
m_storedOnDisk
[
binId
].
push_back
(
pos
);
}
return
QImage
(
thumbFolder
.
absoluteFilePath
(
key
));
}
return
QImage
();
...
...
@@ -175,7 +177,9 @@ void ThumbnailCache::storeThumbnail(const QString &binId, int pos, const QImage
if
(
!
img
.
save
(
thumbFolder
.
absoluteFilePath
(
key
)))
{
qDebug
()
<<
".............
\n
!!!!!!!! ERROR SAVING THUMB in: "
<<
thumbFolder
.
absoluteFilePath
(
key
);
}
m_storedOnDisk
[
binId
].
push_back
(
pos
);
if
(
m_storedOnDisk
.
find
(
binId
)
==
m_storedOnDisk
.
end
()
||
std
::
find
(
m_storedOnDisk
[
binId
].
begin
(),
m_storedOnDisk
[
binId
].
end
(),
pos
)
==
m_storedOnDisk
[
binId
].
end
())
{
m_storedOnDisk
[
binId
].
push_back
(
pos
);
}
// if volatile cache also contains this entry, update it
if
(
m_volatileCache
->
contains
(
key
))
{
m_volatileCache
->
remove
(
key
);
...
...
@@ -190,19 +194,30 @@ void ThumbnailCache::storeThumbnail(const QString &binId, int pos, const QImage
}
}
void
ThumbnailCache
::
saveCachedThumbs
(
const
QStringList
&
keys
)
void
ThumbnailCache
::
saveCachedThumbs
(
const
std
::
unordered_map
<
QString
,
std
::
vector
<
int
>>
&
keys
)
{
bool
ok
;
QDir
thumbFolder
=
getDir
(
false
,
&
ok
);
if
(
!
ok
)
{
return
;
}
for
(
const
QString
&
key
:
keys
)
{
if
(
!
thumbFolder
.
exists
(
key
)
&&
m_volatileCache
->
contains
(
key
))
{
QImage
img
=
m_volatileCache
->
get
(
key
);
if
(
!
img
.
save
(
thumbFolder
.
absoluteFilePath
(
key
)))
{
qDebug
()
<<
"// Error writing thumbnails to "
<<
thumbFolder
.
absolutePath
();
break
;
for
(
auto
&
key
:
keys
)
{
bool
ok
;
for
(
const
auto
&
pos
:
key
.
second
)
{
if
(
m_storedOnDisk
.
find
(
key
.
first
)
==
m_storedOnDisk
.
end
()
||
std
::
find
(
m_storedOnDisk
[
key
.
first
].
begin
(),
m_storedOnDisk
[
key
.
first
].
end
(),
pos
)
==
m_storedOnDisk
[
key
.
first
].
end
())
{
const
QString
thumbKey
=
getKey
(
key
.
first
,
pos
,
&
ok
);
if
(
!
ok
)
{
continue
;
}
if
(
!
thumbFolder
.
exists
(
thumbKey
)
&&
m_volatileCache
->
contains
(
thumbKey
))
{
QImage
img
=
m_volatileCache
->
get
(
thumbKey
);
if
(
!
img
.
save
(
thumbFolder
.
absoluteFilePath
(
thumbKey
)))
{
qDebug
()
<<
"// Error writing thumbnails to "
<<
thumbFolder
.
absolutePath
();
break
;
}
else
{
m_storedOnDisk
[
key
.
first
].
push_back
(
pos
);
}
}
}
}
}
...
...
@@ -226,7 +241,7 @@ void ThumbnailCache::invalidateThumbsForClip(const QString &binId)
QDir
thumbFolder
=
getDir
(
false
,
&
ok
);
if
(
ok
&&
m_storedOnDisk
.
find
(
binId
)
!=
m_storedOnDisk
.
end
())
{
// Remove persistent cache
for
(
int
pos
:
m_storedOnDisk
.
at
(
binId
))
{
for
(
const
auto
&
pos
:
m_storedOnDisk
.
at
(
binId
))
{
if
(
pos
>=
0
)
{
auto
key
=
getKey
(
binId
,
pos
,
&
ok
);
if
(
ok
)
{
...
...
src/utils/thumbnailcache.hpp
View file @
57152173
...
...
@@ -58,7 +58,7 @@ public:
void
invalidateThumbsForClip
(
const
QString
&
binId
);
/** @brief Save all cached thumbs to disk */
void
saveCachedThumbs
(
const
QStringList
&
keys
);
void
saveCachedThumbs
(
const
std
::
unordered_map
<
QString
,
std
::
vector
<
int
>>
&
keys
);
/** @brief Reset cache (discarding all thumbs stored in memory) */
void
clearCache
();
...
...
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