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
3dcf36a6
Commit
3dcf36a6
authored
May 13, 2022
by
Jean-Baptiste Mardelle
Browse files
Various small fixes for proxy status and job (Fixes
#1426
)
Small improvements to thumbnail cache
parent
93118c5d
Changes
13
Hide whitespace changes
Inline
Side-by-side
src/bin/bin.cpp
View file @
3dcf36a6
...
...
@@ -4500,12 +4500,12 @@ void Bin::reloadAllProducers(bool reloadThumbs)
}
}
if
(
!
xml
.
isNull
())
{
clip
->
setClipStatus
(
FileStatus
::
StatusWaiting
);
pCore
->
taskManager
.
discardJobs
({
ObjectType
::
BinClip
,
clip
->
clipId
().
toInt
()},
AbstractTask
::
NOJOBTYPE
,
true
);
clip
->
discardAudioThumb
();
if
(
reloadThumbs
)
{
ThumbnailCache
::
get
()
->
invalidateThumbsForClip
(
clip
->
clipId
());
}
clip
->
setClipStatus
(
FileStatus
::
StatusWaiting
);
pCore
->
taskManager
.
discardJobs
({
ObjectType
::
BinClip
,
clip
->
clipId
().
toInt
()},
AbstractTask
::
NOJOBTYPE
,
true
,
{
AbstractTask
::
TRANSCODEJOB
,
AbstractTask
::
PROXYJOB
,
AbstractTask
::
AUDIOTHUMBJOB
});
ClipLoadTask
::
start
({
ObjectType
::
BinClip
,
clip
->
clipId
().
toInt
()},
xml
,
false
,
-
1
,
-
1
,
this
);
}
}
...
...
src/bin/projectclip.cpp
View file @
3dcf36a6
...
...
@@ -1258,12 +1258,6 @@ double ProjectClip::getOriginalFps() const
return
originalFps
();
}
bool
ProjectClip
::
hasProxy
()
const
{
QString
proxy
=
getProducerProperty
(
QStringLiteral
(
"kdenlive:proxy"
));
return
proxy
.
size
()
>
2
;
}
void
ProjectClip
::
setProperties
(
const
QMap
<
QString
,
QString
>
&
properties
,
bool
refreshPanel
)
{
qDebug
()
<<
"// SETTING CLIP PROPERTIES: "
<<
properties
;
...
...
src/bin/projectclip.h
View file @
3dcf36a6
...
...
@@ -147,9 +147,6 @@ public:
/** @brief Callculate a file hash from a path. */
static
const
QPair
<
QByteArray
,
qint64
>
calculateHash
(
const
QString
&
path
);
/** @brief Returns true if we are using a proxy for this clip. */
bool
hasProxy
()
const
;
/** Cache for every audio Frame with 10 Bytes */
/** format is frame -> channel ->bytes */
bool
audioThumbCreated
()
const
;
...
...
src/doc/kdenlivedoc.cpp
View file @
3dcf36a6
...
...
@@ -1411,7 +1411,7 @@ void KdenliveDoc::loadDocumentProperties()
void
KdenliveDoc
::
updateProjectProfile
(
bool
reloadProducers
,
bool
reloadThumbs
)
{
pCore
->
taskManager
.
slotCancelJobs
();
pCore
->
taskManager
.
slotCancelJobs
(
{
AbstractTask
::
PROXYJOB
,
AbstractTask
::
AUDIOTHUMBJOB
,
AbstractTask
::
TRANSCODEJOB
}
);
double
fps
=
pCore
->
getCurrentFps
();
double
fpsChanged
=
m_timecode
.
fps
()
/
fps
;
m_timecode
.
setFormat
(
fps
);
...
...
@@ -1430,8 +1430,8 @@ void KdenliveDoc::resetProfile(bool reloadThumbs)
void
KdenliveDoc
::
slotSwitchProfile
(
const
QString
&
profile_path
,
bool
reloadThumbs
)
{
// Discard all current jobs
pCore
->
taskManager
.
slotCancelJobs
();
// Discard all current jobs
except proxy and audio thumbs
pCore
->
taskManager
.
slotCancelJobs
(
{
AbstractTask
::
PROXYJOB
,
AbstractTask
::
AUDIOTHUMBJOB
,
AbstractTask
::
TRANSCODEJOB
}
);
pCore
->
setCurrentProfile
(
profile_path
);
updateProjectProfile
(
true
,
reloadThumbs
);
// In case we only have one clip in timeline,
...
...
@@ -1496,7 +1496,7 @@ void KdenliveDoc::switchProfile(ProfileParam* pf, const QString clipName)
switch
(
answer
)
{
case
KMessageBox
::
Yes
:
// Discard all current jobs
pCore
->
taskManager
.
slotCancelJobs
();
pCore
->
taskManager
.
slotCancelJobs
(
{
AbstractTask
::
PROXYJOB
,
AbstractTask
::
AUDIOTHUMBJOB
,
AbstractTask
::
TRANSCODEJOB
}
);
KdenliveSettings
::
setDefault_profile
(
profile
->
path
());
pCore
->
setCurrentProfile
(
profile
->
path
());
updateProjectProfile
(
true
,
true
);
...
...
@@ -1531,7 +1531,7 @@ void KdenliveDoc::switchProfile(ProfileParam* pf, const QString clipName)
.
arg
(
QString
::
number
(
double
(
profile
->
m_frame_rate_num
)
/
profile
->
m_frame_rate_den
,
'f'
,
2
));
QString
profilePath
=
ProfileRepository
::
get
()
->
saveProfile
(
profile
.
get
());
// Discard all current jobs
pCore
->
taskManager
.
slotCancelJobs
();
pCore
->
taskManager
.
slotCancelJobs
(
{
AbstractTask
::
PROXYJOB
,
AbstractTask
::
AUDIOTHUMBJOB
,
AbstractTask
::
TRANSCODEJOB
}
);
pCore
->
setCurrentProfile
(
profilePath
);
updateProjectProfile
(
true
,
true
);
emit
docModified
(
true
);
...
...
src/jobs/abstracttask.cpp
View file @
3dcf36a6
...
...
@@ -73,7 +73,7 @@ void AbstractTask::cancelJob(bool softDelete)
if
(
softDelete
)
{
m_softDelete
.
testAndSetAcquire
(
0
,
1
);
}
qDebug
()
<<
"====== SETTING TASK CANCELED: "
<<
m_isCanceled
;
qDebug
()
<<
"====== SETTING TASK CANCELED: "
<<
m_isCanceled
<<
", TYPE: "
<<
m_type
;
emit
jobCanceled
();
}
...
...
src/jobs/taskmanager.cpp
View file @
3dcf36a6
...
...
@@ -38,9 +38,9 @@ void TaskManager::updateConcurrency()
m_transcodePool
.
setMaxThreadCount
(
KdenliveSettings
::
proxythreads
());
}
void
TaskManager
::
discardJobs
(
const
ObjectId
&
owner
,
AbstractTask
::
JOBTYPE
type
,
bool
softDelete
)
void
TaskManager
::
discardJobs
(
const
ObjectId
&
owner
,
AbstractTask
::
JOBTYPE
type
,
bool
softDelete
,
const
QVector
<
AbstractTask
::
JOBTYPE
>
exceptions
)
{
qDebug
()
<<
"========== READY FOR TASK D
ELETION
ON: "
<<
owner
.
second
;
qDebug
()
<<
"========== READY FOR TASK D
ISCARD
ON: "
<<
owner
.
second
;
m_tasksListLock
.
lockForRead
();
// See if there is already a task for this MLT service and resource.
if
(
m_taskList
.
find
(
owner
.
second
)
==
m_taskList
.
end
())
{
...
...
@@ -52,6 +52,10 @@ void TaskManager::discardJobs(const ObjectId &owner, AbstractTask::JOBTYPE type,
for
(
AbstractTask
*
t
:
taskList
)
{
if
((
type
==
AbstractTask
::
NOJOBTYPE
||
type
==
t
->
m_type
)
&&
t
->
m_progress
<
100
)
{
// If so, then just add ourselves to be notified upon completion.
if
(
exceptions
.
contains
(
t
->
m_type
))
{
// Don't abort
continue
;
}
t
->
cancelJob
(
softDelete
);
qDebug
()
<<
"========== DELETING JOB!!!!"
;
// Block until the task is finished
...
...
@@ -120,19 +124,23 @@ void TaskManager::taskDone(int cid, AbstractTask *task)
}
void
TaskManager
::
slotCancelJobs
()
void
TaskManager
::
slotCancelJobs
(
const
QVector
<
AbstractTask
::
JOBTYPE
>
exceptions
)
{
m_tasksListLock
.
lockForRead
();
// See if there is already a task for this MLT service and resource.
for
(
const
auto
&
task
:
m_taskList
)
{
for
(
AbstractTask
*
t
:
task
.
second
)
{
// If so, then just add ourselves to be notified upon completion.
t
->
cancelJob
();
if
(
!
exceptions
.
contains
(
t
->
m_type
))
{
// If so, then just add ourselves to be notified upon completion.
t
->
cancelJob
();
}
}
}
m_tasksListLock
.
unlock
();
m_taskPool
.
waitForDone
();
m_transcodePool
.
waitForDone
();
if
(
exceptions
.
isEmpty
())
{
m_taskPool
.
waitForDone
();
m_transcodePool
.
waitForDone
();
}
updateJobCount
();
}
...
...
src/jobs/taskmanager.h
View file @
3dcf36a6
...
...
@@ -41,7 +41,7 @@ public:
* @param owner the owner item for this task
* @param type The type of job that you want to abort, leave to NOJOBTYPE to abort all jobs
*/
void
discardJobs
(
const
ObjectId
&
owner
,
AbstractTask
::
JOBTYPE
type
=
AbstractTask
::
NOJOBTYPE
,
bool
softDelete
=
false
);
void
discardJobs
(
const
ObjectId
&
owner
,
AbstractTask
::
JOBTYPE
type
=
AbstractTask
::
NOJOBTYPE
,
bool
softDelete
=
false
,
const
QVector
<
AbstractTask
::
JOBTYPE
>
exceptions
=
{}
);
/** @brief Check if there is a pending / running job a clip.
* @param owner the owner item for this task
...
...
@@ -68,7 +68,7 @@ public:
public
slots
:
/** @brief Discard all running jobs. */
void
slotCancelJobs
();
void
slotCancelJobs
(
const
QVector
<
AbstractTask
::
JOBTYPE
>
exceptions
=
{}
);
private
slots
:
/** @brief Update number of running jobs. */
...
...
src/main.cpp
View file @
3dcf36a6
...
...
@@ -109,7 +109,7 @@ int main(int argc, char *argv[])
#endif
#if defined(Q_OS_WIN) || defined (Q_OS_MACOS)
const
QStringList
themes
{
"/icons/breeze/breeze-icons.rcc"
,
"/icons/breeze-dark/breeze-icons-dark.rcc"
};
for
(
const
QString
theme
:
themes
)
{
for
(
const
QString
&
theme
:
themes
)
{
const
QString
themePath
=
QStandardPaths
::
locate
(
QStandardPaths
::
AppDataLocation
,
theme
);
if
(
!
themePath
.
isEmpty
())
{
const
QString
iconSubdir
=
theme
.
left
(
theme
.
lastIndexOf
(
'/'
));
...
...
src/mltcontroller/clipcontroller.cpp
View file @
3dcf36a6
...
...
@@ -178,12 +178,14 @@ void ClipController::getInfoForProducer()
proxy
.
prepend
(
pCore
->
currentDoc
()
->
documentRoot
());
m_properties
->
set
(
"kdenlive:proxy"
,
proxy
.
toUtf8
().
constData
());
}
// This is a proxy producer, read original url from kdenlive property
path
=
m_properties
->
get
(
"kdenlive:originalurl"
);
if
(
QFileInfo
(
path
).
isRelative
())
{
path
.
prepend
(
pCore
->
currentDoc
()
->
documentRoot
());
if
(
proxy
==
path
)
{
// This is a proxy producer, read original url from kdenlive property
path
=
m_properties
->
get
(
"kdenlive:originalurl"
);
if
(
QFileInfo
(
path
).
isRelative
())
{
path
.
prepend
(
pCore
->
currentDoc
()
->
documentRoot
());
}
m_usesProxy
=
true
;
}
m_usesProxy
=
true
;
}
else
if
(
m_service
!=
QLatin1String
(
"color"
)
&&
m_service
!=
QLatin1String
(
"colour"
)
&&
!
path
.
isEmpty
()
&&
QFileInfo
(
path
).
isRelative
()
&&
path
!=
QLatin1String
(
"<producer>"
))
{
path
.
prepend
(
pCore
->
currentDoc
()
->
documentRoot
());
...
...
@@ -336,7 +338,7 @@ void ClipController::updateProducer(const std::shared_ptr<Mlt::Producer> &produc
Mlt
::
Properties
passProperties
;
// Keep track of necessary properties
QString
proxy
=
producer
->
get
(
"kdenlive:proxy"
);
if
(
proxy
.
length
()
>
2
)
{
if
(
proxy
.
length
()
>
2
&&
producer
->
get
(
"resource"
)
==
proxy
)
{
// This is a proxy producer, read original url from kdenlive property
m_usesProxy
=
true
;
}
else
{
...
...
@@ -1022,3 +1024,10 @@ const QString ClipController::getOriginalUrl()
}
return
path
;
}
bool
ClipController
::
hasProxy
()
const
{
QString
proxy
=
getProducerProperty
(
QStringLiteral
(
"kdenlive:proxy"
));
//qDebug()<<"::: PROXY: "<<proxy<<" = "<<clipUrl();
return
proxy
.
size
()
>
2
&&
proxy
==
clipUrl
();
}
src/mltcontroller/clipcontroller.h
View file @
3dcf36a6
...
...
@@ -207,6 +207,8 @@ public:
int
audioStreamsCount
()
const
;
/** @brief Get the path to the original clip url (in case it is proxied) */
const
QString
getOriginalUrl
();
/** @brief Returns true if we are using a proxy for this clip. */
bool
hasProxy
()
const
;
protected:
/** @brief Mutex to protect the producer properties on read/write */
...
...
src/mltcontroller/clippropertiescontroller.cpp
View file @
3dcf36a6
...
...
@@ -440,7 +440,7 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
// Proxy codec label
QLabel
*
lab
=
new
QLabel
(
this
);
pbox
->
setObjectName
(
QStringLiteral
(
"kdenlive:proxy"
));
bool
hasProxy
=
proxy
.
length
()
>
2
;
bool
hasProxy
=
m_controller
->
hasProxy
()
;
if
(
hasProxy
)
{
bg
->
setToolTip
(
proxy
);
bool
proxyReady
=
(
QFileInfo
(
proxy
).
fileName
()
==
QFileInfo
(
m_properties
->
get
(
"resource"
)).
fileName
());
...
...
src/timeline2/view/timelinecontroller.cpp
View file @
3dcf36a6
...
...
@@ -1292,13 +1292,14 @@ void TimelineController::switchGuide(int frame, bool deleteOnly, bool showGui)
void
TimelineController
::
addAsset
(
const
QVariantMap
&
data
)
{
QString
effect
=
data
.
value
(
QStringLiteral
(
"kdenlive/effect"
)).
toString
();
const
auto
selection
=
m_model
->
getCurrentSelection
();
bool
audioEffect
=
EffectsRepository
::
get
()
->
isAudioEffect
(
effect
);
int
affectedClips
=
0
;
int
cid
=
-
1
;
if
(
!
selection
.
empty
())
{
QList
<
int
>
effectSelection
;
int
affectedClips
=
0
;
int
cid
=
-
1
;
QString
effect
=
data
.
value
(
QStringLiteral
(
"kdenlive/effect"
)).
toString
();
bool
audioEffect
=
EffectsRepository
::
get
()
->
isAudioEffect
(
effect
);
for
(
int
id
:
selection
)
{
if
(
m_model
->
isClip
(
id
)
&&
audioEffect
==
m_model
->
m_allClips
.
at
(
id
)
->
isAudioOnly
())
{
effectSelection
<<
id
;
...
...
src/utils/thumbnailcache.cpp
View file @
3dcf36a6
...
...
@@ -115,6 +115,7 @@ bool ThumbnailCache::hasThumbnail(const QString &binId, int pos, bool volatileOn
if
(
!
ok
||
volatileOnly
)
{
return
false
;
}
locker
.
unlock
();
QDir
thumbFolder
=
getDir
(
pos
<
0
,
&
ok
);
return
ok
&&
thumbFolder
.
exists
(
key
);
}
...
...
@@ -132,7 +133,10 @@ QImage ThumbnailCache::getAudioThumbnail(const QString &binId, bool volatileOnly
}
QDir
thumbFolder
=
getDir
(
true
,
&
ok
);
if
(
ok
&&
thumbFolder
.
exists
(
key
))
{
m_storedOnDisk
[
binId
].
push_back
(
-
1
);
if
(
std
::
find
(
m_storedOnDisk
[
binId
].
begin
(),
m_storedOnDisk
[
binId
].
end
(),
-
1
)
!=
m_storedOnDisk
[
binId
].
end
())
{
m_storedOnDisk
[
binId
].
push_back
(
-
1
);
}
locker
.
unlock
();
return
QImage
(
thumbFolder
.
absoluteFilePath
(
key
));
}
return
QImage
();
...
...
@@ -140,7 +144,6 @@ QImage ThumbnailCache::getAudioThumbnail(const QString &binId, bool volatileOnly
const
QList
<
QUrl
>
ThumbnailCache
::
getAudioThumbPath
(
const
QString
&
binId
)
const
{
QReadLocker
locker
(
&
m_mutex
);
bool
ok
=
false
;
auto
key
=
getAudioKey
(
binId
,
&
ok
);
QDir
thumbFolder
=
getDir
(
true
,
&
ok
);
...
...
@@ -174,6 +177,7 @@ QImage ThumbnailCache::getThumbnail(QString hash, const QString &binId, int 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
);
}
locker
.
unlock
();
return
QImage
(
thumbFolder
.
absoluteFilePath
(
hash
));
}
return
QImage
();
...
...
@@ -195,6 +199,7 @@ QImage ThumbnailCache::getThumbnail(const QString &binId, int pos, bool volatile
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
);
}
locker
.
unlock
();
return
QImage
(
thumbFolder
.
absoluteFilePath
(
key
));
}
return
QImage
();
...
...
@@ -208,24 +213,25 @@ void ThumbnailCache::storeThumbnail(const QString &binId, int pos, const QImage
if
(
!
ok
)
{
return
;
}
// if volatile cache also contains this entry, update it
if
(
m_volatileCache
->
contains
(
key
))
{
m_volatileCache
->
remove
(
key
);
}
else
{
m_storedVolatile
[
binId
].
push_back
(
pos
);
}
m_volatileCache
->
insert
(
key
,
img
,
(
int
)
img
.
sizeInBytes
());
if
(
persistent
)
{
QDir
thumbFolder
=
getDir
(
false
,
&
ok
);
if
(
ok
)
{
if
(
!
img
.
save
(
thumbFolder
.
absoluteFilePath
(
key
)))
{
qDebug
()
<<
".............
\n
!!!!!!!! ERROR SAVING THUMB in: "
<<
thumbFolder
.
absoluteFilePath
(
key
);
}
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
);
}
m_mutex
.
unlock
();
if
(
!
img
.
save
(
thumbFolder
.
absoluteFilePath
(
key
)))
{
qDebug
()
<<
".............
\n
!!!!!!!! ERROR SAVING THUMB in: "
<<
thumbFolder
.
absoluteFilePath
(
key
);
}
}
}
// if volatile cache also contains this entry, update it
if
(
m_volatileCache
->
contains
(
key
))
{
m_volatileCache
->
remove
(
key
);
}
else
{
m_storedVolatile
[
binId
].
push_back
(
pos
);
}
m_volatileCache
->
insert
(
key
,
img
,
(
int
)
img
.
sizeInBytes
());
}
bool
ThumbnailCache
::
checkIntegrity
()
const
...
...
@@ -278,19 +284,29 @@ void ThumbnailCache::invalidateThumbsForClip(const QString &binId)
}
bool
ok
=
false
;
// Video thumbs
Q
Dir
thumbFolder
=
getDir
(
false
,
&
ok
)
;
if
(
ok
&&
m_storedOnDisk
.
find
(
binId
)
!=
m_storedOnDisk
.
end
())
{
Q
StringList
files
;
if
(
m_storedOnDisk
.
find
(
binId
)
!=
m_storedOnDisk
.
end
())
{
// Remove persistent cache
for
(
const
auto
&
pos
:
m_storedOnDisk
.
at
(
binId
))
{
if
(
pos
>=
0
)
{
auto
key
=
getKey
(
binId
,
pos
,
&
ok
);
if
(
ok
)
{
QF
ile
::
remove
(
thumbFolder
.
absoluteFilePath
(
key
))
;
f
ile
s
<<
key
;
}
}
}
m_storedOnDisk
.
erase
(
binId
);
}
// Release mutex before deleting files
locker
.
unlock
();
if
(
!
files
.
isEmpty
())
{
QDir
thumbFolder
=
getDir
(
false
,
&
ok
);
if
(
ok
)
{
while
(
!
files
.
isEmpty
())
{
thumbFolder
.
remove
(
files
.
takeFirst
());
}
}
}
}
void
ThumbnailCache
::
clearCache
()
...
...
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