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
5d12b66c
Commit
5d12b66c
authored
Dec 04, 2019
by
Jean-Baptiste Mardelle
Browse files
Fix video thumbnails from previous project showing up.
Various crash fixes on exit or project close.
BUG: 414813
parent
ba4adf7c
Changes
13
Hide whitespace changes
Inline
Side-by-side
src/bin/bin.cpp
View file @
5d12b66c
...
...
@@ -849,6 +849,7 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
Bin
::~
Bin
()
{
pCore
->
jobManager
()
->
slotCancelJobs
();
blockSignals
(
true
);
m_proxyModel
->
selectionModel
()
->
blockSignals
(
true
);
setEnabled
(
false
);
...
...
@@ -1181,6 +1182,7 @@ void Bin::setDocument(KdenliveDoc *project)
delete
m_itemView
;
m_itemView
=
nullptr
;
m_doc
=
project
;
m_infoLabel
->
slotSetJobCount
(
0
);
int
iconHeight
=
QFontInfo
(
font
()).
pixelSize
()
*
3.5
;
m_iconSize
=
QSize
(
iconHeight
*
pCore
->
getCurrentDar
(),
iconHeight
);
setEnabled
(
true
);
...
...
src/jobs/audiothumbjob.cpp
View file @
5d12b66c
...
...
@@ -185,7 +185,11 @@ bool AudioThumbJob::computeWithFFMPEG()
}
m_ffmpegProcess
.
reset
(
new
QProcess
);
connect
(
m_ffmpegProcess
.
get
(),
&
QProcess
::
readyReadStandardOutput
,
this
,
&
AudioThumbJob
::
updateFfmpegProgress
,
Qt
::
UniqueConnection
);
connect
(
this
,
&
AudioThumbJob
::
jobCanceled
,
m_ffmpegProcess
.
get
(),
&
QProcess
::
kill
,
Qt
::
DirectConnection
);
connect
(
this
,
&
AudioThumbJob
::
jobCanceled
,
[
&
]()
{
if
(
m_ffmpegProcess
)
{
m_ffmpegProcess
->
kill
();
}
});
m_ffmpegProcess
->
start
(
KdenliveSettings
::
ffmpegpath
(),
args
);
m_ffmpegProcess
->
waitForFinished
(
-
1
);
if
(
m_ffmpegProcess
->
exitStatus
()
!=
QProcess
::
CrashExit
)
{
...
...
src/jobs/cachejob.cpp
View file @
5d12b66c
...
...
@@ -51,8 +51,8 @@ CacheJob::CacheJob(const QString &binId, int imageHeight, int thumbsCount, int i
auto
item
=
pCore
->
projectItemModel
()
->
getItemByBinId
(
binId
);
Q_ASSERT
(
item
!=
nullptr
&&
item
->
itemType
()
==
AbstractProjectItem
::
ClipItem
);
connect
(
this
,
&
CacheJob
::
jobCanceled
,
[
&
]
()
{
m_clipId
.
clear
();
m_done
=
true
;
m_clipId
.
clear
();
});
}
...
...
@@ -103,7 +103,7 @@ bool CacheJob::startJob()
frame
->
set
(
"deinterlace_method"
,
"onefield"
);
frame
->
set
(
"top_field_first"
,
-
1
);
frame
->
set
(
"rescale.interp"
,
"nearest"
);
if
(
!
m_done
&&
(
frame
!=
nullptr
)
&&
frame
->
is_valid
())
{
if
(
frame
!=
nullptr
&&
frame
->
is_valid
())
{
QImage
result
=
KThumb
::
getFrame
(
frame
.
data
());
ThumbnailCache
::
get
()
->
storeThumbnail
(
m_clipId
,
i
,
result
,
true
);
}
...
...
src/jobs/jobmanager.cpp
View file @
5d12b66c
...
...
@@ -212,6 +212,7 @@ void JobManager::slotCancelJobs()
{
QWriteLocker
locker
(
&
m_lock
);
for
(
const
auto
&
j
:
m_jobs
)
{
j
.
second
->
m_processed
=
true
;
for
(
const
std
::
shared_ptr
<
AbstractClipJob
>
&
job
:
j
.
second
->
m_job
)
{
job
->
jobCanceled
();
}
...
...
@@ -249,7 +250,9 @@ void JobManager::createJob(const std::shared_ptr<Job_t> &job)
auto
binId
=
it
.
first
;
connect
(
job
->
m_job
[
i
].
get
(),
&
AbstractClipJob
::
jobProgress
,
[
job
,
i
,
binId
](
int
p
)
{
job
->
m_progress
[
i
]
=
std
::
max
(
job
->
m_progress
[
i
],
p
);
pCore
->
projectItemModel
()
->
onItemUpdated
(
binId
,
AbstractProjectItem
::
JobProgress
);
if
(
pCore
)
{
pCore
->
projectItemModel
()
->
onItemUpdated
(
binId
,
AbstractProjectItem
::
JobProgress
);
}
});
}
connect
(
&
job
->
m_future
,
&
QFutureWatcher
<
bool
>::
started
,
this
,
&
JobManager
::
updateJobCount
);
...
...
@@ -367,7 +370,9 @@ void JobManager::slotManageFinishedJob(int id)
if
(
m_jobsByParents
.
count
(
id
)
>
0
)
{
std
::
vector
<
int
>
children
=
m_jobsByParents
[
id
];
for
(
int
cid
:
children
)
{
QtConcurrent
::
run
(
this
,
&
JobManager
::
createJob
,
m_jobs
[
cid
]);
if
(
!
m_jobs
[
cid
]
->
m_processed
)
{
QtConcurrent
::
run
(
this
,
&
JobManager
::
createJob
,
m_jobs
[
cid
]);
}
}
m_jobsByParents
.
erase
(
id
);
}
...
...
src/jobs/meltjob.cpp
View file @
5d12b66c
...
...
@@ -246,6 +246,7 @@ bool MeltJob::startJob()
}
m_showFrameEvent
.
reset
(
m_consumer
->
listen
(
"consumer-frame-show"
,
this
,
(
mlt_listener
)
consumer_frame_render
));
connect
(
this
,
&
MeltJob
::
jobCanceled
,
[
&
]
()
{
m_showFrameEvent
.
reset
();
m_consumer
->
stop
();
return
false
;
});
...
...
src/project/projectmanager.cpp
View file @
5d12b66c
...
...
@@ -197,6 +197,7 @@ void ProjectManager::newFile(QString profileName, bool showProjectSettings)
KdenliveDoc
*
doc
=
new
KdenliveDoc
(
QUrl
(),
projectFolder
,
pCore
->
window
()
->
m_commandStack
,
profileName
,
documentProperties
,
documentMetadata
,
projectTracks
,
&
openBackup
,
pCore
->
window
());
doc
->
m_autosave
=
new
KAutoSaveFile
(
startFile
,
doc
);
ThumbnailCache
::
get
()
->
clearCache
();
pCore
->
bin
()
->
setDocument
(
doc
);
m_project
=
doc
;
pCore
->
monitorManager
()
->
activateMonitor
(
Kdenlive
::
ProjectMonitor
);
...
...
@@ -501,6 +502,7 @@ void ProjectManager::doOpenFile(const QUrl &url, KAutoSaveFile *stale)
m_fileRevert
->
setEnabled
(
true
);
delete
m_progressDialog
;
ThumbnailCache
::
get
()
->
clearCache
();
pCore
->
monitorManager
()
->
resetDisplay
();
pCore
->
monitorManager
()
->
activateMonitor
(
Kdenlive
::
ProjectMonitor
);
m_progressDialog
=
new
QProgressDialog
(
pCore
->
window
());
...
...
src/timeline2/view/qml/Clip.qml
View file @
5d12b66c
...
...
@@ -66,7 +66,6 @@ Rectangle {
property
bool
hasAudio
property
bool
canBeAudio
property
bool
canBeVideo
property
string
hash
:
'
ccc
'
//TODO
property
double
speed
:
1.0
property
color
borderColor
:
'
black
'
property
bool
forceReloadThumb
...
...
@@ -207,9 +206,7 @@ Rectangle {
*/
property
bool
variableThumbs
:
(
isAudio
||
itemType
==
ProducerType
.
Color
||
mltService
===
''
)
property
bool
isImage
:
itemType
==
ProducerType
.
Image
property
string
baseThumbPath
:
variableThumbs
?
''
:
'
image://thumbnail/
'
+
binId
+
'
/
'
+
(
isImage
?
'
#0
'
:
'
#
'
)
property
string
inThumbPath
:
(
variableThumbs
||
isImage
)
?
baseThumbPath
:
baseThumbPath
+
Math
.
floor
(
inPoint
*
speed
)
property
string
outThumbPath
:
(
variableThumbs
||
isImage
)
?
baseThumbPath
:
baseThumbPath
+
Math
.
floor
(
outPoint
*
speed
)
property
string
baseThumbPath
:
variableThumbs
?
''
:
'
image://thumbnail/
'
+
binId
+
'
/
'
+
documentId
+
'
/
'
+
(
isImage
?
'
#0
'
:
'
#
'
)
DropArea
{
//Drop area for clips
anchors.fill
:
clipRoot
...
...
src/timeline2/view/qml/ClipThumbs.qml
View file @
5d12b66c
...
...
@@ -15,8 +15,8 @@ Row {
property
bool
enableCache
:
clipRoot
.
itemType
==
ProducerType
.
Video
||
clipRoot
.
itemType
==
ProducerType
.
AV
function
reload
()
{
c
lipRoot
.
baseThumbPath
=
''
clipRoot
.
baseThumbPath
=
clipRoot
.
variableThumbs
?
''
:
'
image://thumbnail/
'
+
clipRoot
.
binId
+
'
/
'
+
(
clipRoot
.
isImage
?
'
#0
'
:
'
#
'
)
c
onsole
.
log
(
'
+++++
\n\n
triggered ML thumb reload
\n\n
++++++++++++++
'
)
clipRoot
.
baseThumbPath
=
clipRoot
.
variableThumbs
?
''
:
'
image://thumbnail/
'
+
clipRoot
.
binId
+
'
/
'
+
Math
.
random
()
+
'
/
'
+
(
clipRoot
.
isImage
?
'
#0
'
:
'
#
'
)
}
Repeater
{
...
...
src/timeline2/view/qmltypes/thumbnailprovider.cpp
View file @
5d12b66c
...
...
@@ -36,11 +36,6 @@ ThumbnailProvider::ThumbnailProvider()
ThumbnailProvider
::~
ThumbnailProvider
()
=
default
;
void
ThumbnailProvider
::
resetProject
()
{
// m_producers.clear();
}
QImage
ThumbnailProvider
::
requestImage
(
const
QString
&
id
,
QSize
*
size
,
const
QSize
&
requestedSize
)
{
QImage
result
;
...
...
src/timeline2/view/qmltypes/thumbnailprovider.h
View file @
5d12b66c
...
...
@@ -32,7 +32,6 @@ public:
explicit
ThumbnailProvider
();
~
ThumbnailProvider
()
override
;
QImage
requestImage
(
const
QString
&
id
,
QSize
*
size
,
const
QSize
&
requestedSize
)
override
;
void
resetProject
();
private:
QString
cacheKey
(
Mlt
::
Properties
&
properties
,
const
QString
&
service
,
const
QString
&
resource
,
const
QString
&
hash
,
int
frameNumber
);
...
...
src/timeline2/view/timelinewidget.cpp
View file @
5d12b66c
...
...
@@ -47,6 +47,7 @@
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickItem>
#include <QUuid>
#include <QSortFilterProxyModel>
const
int
TimelineWidget
::
comboScale
[]
=
{
1
,
2
,
4
,
8
,
15
,
30
,
50
,
75
,
100
,
150
,
200
,
300
,
500
,
800
,
1000
,
1500
,
2000
,
3000
,
6000
,
15000
,
30000
};
...
...
@@ -111,7 +112,6 @@ const QStringList TimelineWidget::sortedItems(const QStringList &items, bool isT
void
TimelineWidget
::
setModel
(
const
std
::
shared_ptr
<
TimelineItemModel
>
&
model
,
MonitorProxy
*
proxy
)
{
m_thumbnailer
->
resetProject
();
m_sortModel
=
std
::
make_unique
<
QSortFilterProxyModel
>
(
this
);
m_sortModel
->
setSourceModel
(
model
.
get
());
m_sortModel
->
setSortRole
(
TimelineItemModel
::
SortRole
);
...
...
@@ -122,6 +122,9 @@ void TimelineWidget::setModel(const std::shared_ptr<TimelineItemModel> &model, M
rootContext
()
->
setContextProperty
(
"controller"
,
model
.
get
());
rootContext
()
->
setContextProperty
(
"timeline"
,
m_proxy
);
rootContext
()
->
setContextProperty
(
"proxy"
,
proxy
);
// Create a unique id for this timeline to prevent thumbnails
// leaking from one project to another because of qml's image caching
rootContext
()
->
setContextProperty
(
"documentId"
,
QUuid
::
createUuid
());
rootContext
()
->
setContextProperty
(
"transitionModel"
,
sortedItems
(
KdenliveSettings
::
favorite_transitions
(),
true
));
// m_transitionProxyModel.get());
// rootContext()->setContextProperty("effectModel", m_effectsProxyModel.get());
rootContext
()
->
setContextProperty
(
"effectModel"
,
sortedItems
(
KdenliveSettings
::
favorite_effects
(),
false
));
...
...
src/utils/thumbnailcache.cpp
View file @
5d12b66c
...
...
@@ -80,6 +80,12 @@ public:
m_cache
[
key
]
=
m_data
.
emplace
(
m_data
.
begin
(),
std
::
move
(
data
));
// reinsert without copy and store iterator
return
result
;
}
void
clear
()
{
m_data
.
clear
();
m_cache
.
clear
();
m_currentCost
=
0
;
}
protected:
int
m_maxCost
;
...
...
@@ -247,12 +253,24 @@ void ThumbnailCache::invalidateThumbsForClip(const QString &binId, bool reloadAu
}
}
m_storedOnDisk
.
erase
(
binId
);
}
}
}
void
ThumbnailCache
::
clearCache
()
{
QMutexLocker
locker
(
&
m_mutex
);
m_volatileCache
->
clear
();
m_storedVolatile
.
clear
();
m_storedOnDisk
.
clear
();
}
// static
QString
ThumbnailCache
::
getKey
(
const
QString
&
binId
,
int
pos
,
bool
*
ok
)
{
if
(
binId
.
isEmpty
())
{
*
ok
=
false
;
return
QString
();
}
auto
binClip
=
pCore
->
projectItemModel
()
->
getClipByBinID
(
binId
);
*
ok
=
binClip
!=
nullptr
;
return
*
ok
?
binClip
->
hash
()
+
QLatin1Char
(
'#'
)
+
QString
::
number
(
pos
)
+
QStringLiteral
(
".png"
)
:
QString
();
...
...
src/utils/thumbnailcache.hpp
View file @
5d12b66c
...
...
@@ -76,6 +76,9 @@ public:
/* @brief Save all cached thumbs to disk */
void
saveCachedThumbs
(
QStringList
keys
);
/* @brief Reset cache (discarding all thumbs stored in memory) */
void
clearCache
();
protected:
// Constructor is protected because class is a Singleton
ThumbnailCache
();
...
...
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