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
9b57bb16
Commit
9b57bb16
authored
Jan 15, 2022
by
Jean-Baptiste Mardelle
Browse files
Protect timeline preview list with mutex
parent
510bc63b
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/timeline2/view/previewmanager.cpp
View file @
9b57bb16
...
...
@@ -18,6 +18,7 @@
#include <KLocalizedString>
#include <QCollator>
#include <QProcess>
#include <QMutexLocker>
#include <QStandardPaths>
PreviewManager
::
PreviewManager
(
TimelineController
*
controller
,
Mlt
::
Tractor
*
tractor
)
...
...
@@ -182,6 +183,7 @@ void PreviewManager::loadChunks(QVariantList previewChunks, QVariantList dirtyCh
emit
m_controller
->
renderedChunksChanged
();
}
if
(
!
dirtyChunks
.
isEmpty
())
{
QMutexLocker
lock
(
&
m_dirtyMutex
);
for
(
const
auto
&
i
:
qAsConst
(
dirtyChunks
))
{
if
(
!
m_dirtyChunks
.
contains
(
i
))
{
m_dirtyChunks
<<
i
;
...
...
@@ -319,7 +321,7 @@ bool PreviewManager::loadParams()
return
true
;
}
void
PreviewManager
::
invalidatePreviews
(
const
QVariantList
&
chunks
)
void
PreviewManager
::
invalidatePreviews
()
{
QMutexLocker
lock
(
&
m_previewMutex
);
bool
timer
=
KdenliveSettings
::
autopreview
();
...
...
@@ -335,7 +337,7 @@ void PreviewManager::invalidatePreviews(const QVariantList &chunks)
int
ix
=
stackIx
-
1
;
m_undoDir
.
mkdir
(
QString
::
number
(
ix
));
bool
foundPreviews
=
false
;
for
(
const
auto
&
i
:
c
hunks
)
{
for
(
const
auto
&
i
:
m_dirtyC
hunks
)
{
QString
current
=
QStringLiteral
(
"%1.%2"
).
arg
(
i
.
toInt
()).
arg
(
m_extension
);
if
(
m_cacheDir
.
rename
(
current
,
QStringLiteral
(
"undo/%1/%2"
).
arg
(
ix
).
arg
(
current
)))
{
foundPreviews
=
true
;
...
...
@@ -357,7 +359,7 @@ void PreviewManager::invalidatePreviews(const QVariantList &chunks)
lastUndo
=
true
;
bool
foundPreviews
=
false
;
m_undoDir
.
mkdir
(
QString
::
number
(
stackMax
));
for
(
const
auto
&
i
:
c
hunks
)
{
for
(
const
auto
&
i
:
m_dirtyC
hunks
)
{
QString
current
=
QStringLiteral
(
"%1.%2"
).
arg
(
i
.
toInt
()).
arg
(
m_extension
);
if
(
m_cacheDir
.
rename
(
current
,
QStringLiteral
(
"undo/%1/%2"
).
arg
(
stackMax
).
arg
(
current
)))
{
foundPreviews
=
true
;
...
...
@@ -374,7 +376,7 @@ void PreviewManager::invalidatePreviews(const QVariantList &chunks)
moveFile
=
false
;
}
QVariantList
foundChunks
;
for
(
const
auto
&
i
:
c
hunks
)
{
for
(
const
auto
&
i
:
m_dirtyC
hunks
)
{
QString
cacheFileName
=
QStringLiteral
(
"%1.%2"
).
arg
(
i
.
toInt
()).
arg
(
m_extension
);
if
(
!
lastUndo
)
{
m_cacheDir
.
remove
(
cacheFileName
);
...
...
@@ -382,8 +384,6 @@ void PreviewManager::invalidatePreviews(const QVariantList &chunks)
if
(
moveFile
)
{
if
(
QFile
::
copy
(
tmpDir
.
absoluteFilePath
(
cacheFileName
),
m_cacheDir
.
absoluteFilePath
(
cacheFileName
)))
{
foundChunks
<<
i
;
m_dirtyChunks
.
removeAll
(
i
);
m_renderedChunks
<<
i
;
}
else
{
qDebug
()
<<
"// ERROR PROCESSE CHUNK: "
<<
i
<<
", "
<<
cacheFileName
;
}
...
...
@@ -391,6 +391,12 @@ void PreviewManager::invalidatePreviews(const QVariantList &chunks)
}
if
(
!
foundChunks
.
isEmpty
())
{
std
::
sort
(
foundChunks
.
begin
(),
foundChunks
.
end
());
m_dirtyMutex
.
lock
();
for
(
auto
&
ck
:
foundChunks
)
{
m_dirtyChunks
.
removeAll
(
ck
);
m_renderedChunks
<<
ck
;
}
m_dirtyMutex
.
unlock
();
emit
m_controller
->
dirtyChunksChanged
();
emit
m_controller
->
renderedChunksChanged
();
reloadChunks
(
foundChunks
);
...
...
@@ -430,6 +436,7 @@ void PreviewManager::clearPreviewRange(bool resetZones)
abortRendering
();
m_tractor
->
lock
();
bool
hasPreview
=
m_previewTrack
!=
nullptr
;
QMutexLocker
lock
(
&
m_dirtyMutex
);
for
(
const
auto
&
ix
:
qAsConst
(
m_renderedChunks
))
{
m_cacheDir
.
remove
(
QStringLiteral
(
"%1.%2"
).
arg
(
ix
.
toInt
()).
arg
(
m_extension
));
if
(
!
m_dirtyChunks
.
contains
(
ix
))
{
...
...
@@ -465,6 +472,7 @@ void PreviewManager::addPreviewRange(const QPoint zone, bool add)
int
endChunk
=
int
(
rintl
(
zone
.
y
()
/
chunkSize
));
QList
<
int
>
toRemove
;
qDebug
()
<<
" // / RESUQEST CHUNKS; "
<<
startChunk
<<
" = "
<<
endChunk
;
QMutexLocker
lock
(
&
m_dirtyMutex
);
for
(
int
i
=
startChunk
;
i
<=
endChunk
;
i
++
)
{
int
frame
=
i
*
chunkSize
;
if
(
add
)
{
...
...
@@ -574,6 +582,7 @@ void PreviewManager::receivedStderr()
void
PreviewManager
::
doPreviewRender
(
const
QString
&
scene
)
{
// initialize progress bar
QMutexLocker
lock
(
&
m_dirtyMutex
);
std
::
sort
(
m_dirtyChunks
.
begin
(),
m_dirtyChunks
.
end
());
if
(
m_dirtyChunks
.
isEmpty
())
{
return
;
...
...
@@ -628,7 +637,7 @@ void PreviewManager::slotProcessDirtyChunks()
if
(
m_dirtyChunks
.
isEmpty
())
{
return
;
}
invalidatePreviews
(
m_dirtyChunks
);
invalidatePreviews
();
if
(
KdenliveSettings
::
autopreview
())
{
m_previewTimer
.
start
();
}
...
...
@@ -685,6 +694,7 @@ void PreviewManager::invalidatePreview(int startFrame, int endFrame)
QVariant
val
(
i
);
m_renderedChunks
.
removeAll
(
val
);
if
(
!
m_dirtyChunks
.
contains
(
val
))
{
QMutexLocker
lock
(
&
m_dirtyMutex
);
m_dirtyChunks
<<
val
;
chunksChanged
=
true
;
}
...
...
@@ -747,6 +757,7 @@ void PreviewManager::gotPreviewRender(int frame, const QString &file, int progre
if
(
m_previewTrack
->
is_blank_at
(
frame
))
{
Mlt
::
Producer
prod
(
pCore
->
getCurrentProfile
()
->
profile
(),
QString
(
"avformat:%1"
).
arg
(
file
).
toUtf8
().
constData
());
if
(
prod
.
is_valid
())
{
QMutexLocker
lock
(
&
m_dirtyMutex
);
m_dirtyChunks
.
removeAll
(
frame
);
m_renderedChunks
<<
frame
;
emit
m_controller
->
renderedChunksChanged
();
...
...
@@ -779,6 +790,7 @@ void PreviewManager::corruptedChunk(int frame, const QString &fileName)
emit
previewRender
(
0
,
m_errorLog
,
-
1
);
m_cacheDir
.
remove
(
fileName
);
if
(
!
m_dirtyChunks
.
contains
(
frame
))
{
QMutexLocker
lock
(
&
m_dirtyMutex
);
m_dirtyChunks
<<
frame
;
std
::
sort
(
m_dirtyChunks
.
begin
(),
m_dirtyChunks
.
end
());
}
...
...
@@ -806,6 +818,7 @@ QPair<QStringList, QStringList> PreviewManager::previewChunks() const
for
(
const
QVariant
&
frame
:
m_renderedChunks
)
{
renderedChunks
<<
frame
.
toString
();
}
QMutexLocker
lock
(
&
m_dirtyMutex
);
for
(
const
QVariant
&
frame
:
m_dirtyChunks
)
{
dirtyChunks
<<
frame
.
toString
();
}
...
...
src/timeline2/view/previewmanager.h
View file @
9b57bb16
...
...
@@ -45,7 +45,7 @@ public:
/** @brief: a timeline operation caused changes to frames between startFrame and endFrame. */
void
invalidatePreview
(
int
startFrame
,
int
endFrame
);
/** @brief: after a small delay (some operations trigger several invalidatePreview calls), take care of these invalidated chunks. */
void
invalidatePreviews
(
const
QVariantList
&
chunks
);
void
invalidatePreviews
();
/** @brief: user adds current timeline zone to the preview zone. */
void
addPreviewRange
(
const
QPoint
zone
,
bool
add
);
/** @brief: Remove all existing previews. */
...
...
@@ -138,6 +138,7 @@ public slots:
protected:
QVariantList
m_renderedChunks
;
QVariantList
m_dirtyChunks
;
mutable
QMutex
m_dirtyMutex
;
signals:
void
abortPreview
();
...
...
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