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
faf77816
Commit
faf77816
authored
Apr 16, 2021
by
Jean-Baptiste Mardelle
Browse files
Implement check and transcoding for non seekable files.
BUG: 371062
parent
543b8cc7
Changes
12
Hide whitespace changes
Inline
Side-by-side
data/kdenlivetranscodingrc
View file @
faf77816
...
...
@@ -33,3 +33,10 @@ DVD PAL 4:3=-f dvd -r 25 -vf scale=720:576 -aspect 4:3 -minrate 0 -maxrate 8000k
DVD PAL 16:9=-f dvd -r 25 -vf scale=720:576 -aspect 16:9 -minrate 0 -maxrate 8000k -muxrate 10080000 -g 15 -bufsize 1835008 -packetsize 2048 -trellis 1 -me_range 63 -acodec ac3 -ab 192k -ar 48000 -vcodec mpeg2video -vb 5000k %1.vob;Dvd PAL wide
DVD NTSC 4:3=-f dvd -r 23.976 -vf scale=720:480 -aspect 4:3 -minrate 0 -maxrate 9000k -muxrate 10080000 -g 18 -bufsize 1835008 -packetsize 2048 -trellis 1 -me_range 63 -acodec ac3 -ab 192k -ar 48000 -vcodec mpeg2video -vb 6000k %1.vob;Dvd NTSC
DVD NTSC 16:9=-f dvd -r 23.976 -vf scale=720:480 -aspect 16:9 -minrate 0 -maxrate 9000k -muxrate 10080000 -g 18 -bufsize 1835008 -packetsize 2048 -trellis 1 -me_range 63 -acodec ac3 -ab 192k -ar 48000 -vcodec mpeg2video -vb 6000k %1.vob;Dvd NTSC wide
[intermediate]
Lossy x264 I frame only=-f mp4 -codec:v libx264 -g 1 -bf 0 -crf 15 -preset medium -codec:a aac -ab 256k %1.mp4
Lossy x264 I frame only (NVidia GPU)=-f mp4 -vsync 0 -c:v %nvcodec -i -codec:v h264_nvenc -g 1 -bf 0 -codec:a aac -ab 256k %1.mp4
Lossy x264 I frame only (NVidia GPU)=-f mp4 -vsync 0 -c:v %nvcodec -i -codec:v h264_nvenc -g 1 -bf 0 -codec:a aac -ab 256k %1.mp4
Intermediate DNxHR HQ (Large files)=-f mov -codec:a alac -codec:v dnxhd -profile:v dnxhr_hq -pix_fmt yuv422p %1.mov
Lossless (Huge files)=-f matroska -codec:a pcm_f32le -codec:v utvideo -pix_fmt yuv422p %1.mkv
src/bin/bin.cpp
View file @
faf77816
...
...
@@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "doc/kdenlivedoc.h"
#include "effects/effectstack/model/effectstackmodel.hpp"
#include "jobs/audiothumbjob.hpp"
#include "jobs/transcodeclipjob.h"
#include "jobs/jobmanager.h"
#include "jobs/loadjob.hpp"
#include "jobs/thumbjob.hpp"
...
...
@@ -42,6 +43,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "monitor/monitor.h"
#include "project/dialogs/slideshowclip.h"
#include "project/invaliddialog.h"
#include "project/transcodeseek.h"
#include "project/projectcommands.h"
#include "project/projectmanager.h"
#include "projectclip.h"
...
...
@@ -883,6 +885,7 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
,
m_filterRateGroup
(
this
)
,
m_filterTypeGroup
(
this
)
,
m_invalidClipDialog
(
nullptr
)
,
m_transcodingDialog
(
nullptr
)
,
m_gainedFocus
(
false
)
,
m_audioDuration
(
0
)
,
m_processedAudio
(
0
)
...
...
@@ -4483,3 +4486,22 @@ void Bin::savePlaylist(const QString &binId, QString savePath, QVector<QPoint> z
selectClipById
(
id
);
}
}
void
Bin
::
requestTranscoding
(
const
QString
&
url
,
const
QString
&
id
)
{
if
(
m_transcodingDialog
==
nullptr
)
{
m_transcodingDialog
=
new
TranscodeSeek
(
this
);
connect
(
m_transcodingDialog
,
&
QDialog
::
accepted
,
this
,
[
=
]
()
{
qDebug
()
<<
"==== STARTING TCODE JOB: "
<<
m_transcodingDialog
->
ids
().
front
()
<<
" = "
<<
m_transcodingDialog
->
params
();
pCore
->
jobManager
()
->
startJob
<
TranscodeJob
>
(
m_transcodingDialog
->
ids
(),
-
1
,
QString
(),
m_transcodingDialog
->
params
(),
true
);
delete
m_transcodingDialog
;
m_transcodingDialog
=
nullptr
;
});
connect
(
m_transcodingDialog
,
&
QDialog
::
rejected
,
this
,
[
=
]
()
{
delete
m_transcodingDialog
;
m_transcodingDialog
=
nullptr
;
});
}
m_transcodingDialog
->
addUrl
(
url
,
id
);
m_transcodingDialog
->
show
();
}
src/bin/bin.h
View file @
faf77816
...
...
@@ -51,6 +51,7 @@ class BinListItemDelegate;
class
ClipController
;
class
EffectStackModel
;
class
InvalidDialog
;
class
TranscodeSeek
;
class
KdenliveDoc
;
class
TagWidget
;
class
Monitor
;
...
...
@@ -348,6 +349,8 @@ public:
* @param properties some extra properties that will be set on the producer
* @param createNew if true, the playlist will be added as a new clip in project binId */
void
savePlaylist
(
const
QString
&
binId
,
QString
savePath
,
QVector
<
QPoint
>
zones
,
QMap
<
QString
,
QString
>
properties
,
bool
createNew
);
/** @brief A non seekable clip was added to project, propose transcoding */
void
requestTranscoding
(
const
QString
&
url
,
const
QString
&
id
);
private
slots
:
void
slotAddClip
();
...
...
@@ -528,7 +531,10 @@ private:
KMessageWidget
*
m_infoMessage
;
BinMessage
::
BinCategory
m_currentMessage
;
QStringList
m_errorLog
;
/** @brief Dialog listing invalid clips on load. */
InvalidDialog
*
m_invalidClipDialog
;
/** @brief Dialog listing non seekable clips on load. */
TranscodeSeek
*
m_transcodingDialog
;
/** @brief Set to true if widget just gained focus (means we have to update effect stack . */
bool
m_gainedFocus
;
/** @brief List of Clip Ids that want an audio thumb. */
...
...
src/bin/projectclip.cpp
View file @
faf77816
...
...
@@ -491,6 +491,10 @@ bool ProjectClip::setProducer(std::shared_ptr<Mlt::Producer> producer, bool repl
FileStatus
::
ClipStatus
currentStatus
=
m_clipStatus
;
updateProducer
(
producer
);
emit
producerChanged
(
m_binId
,
producer
);
if
(
producer
->
get_int
(
"kdenlive:transcodingrequired"
)
==
1
)
{
pCore
->
bin
()
->
requestTranscoding
(
clipUrl
(),
clipId
());
producer
->
set
(
"kdenlive:transcodingrequired"
,
nullptr
);
}
m_thumbsProducer
.
reset
();
connectEffectStack
();
...
...
src/jobs/loadjob.cpp
View file @
faf77816
...
...
@@ -528,6 +528,12 @@ bool LoadJob::startJob()
m_producer
->
set
(
"out"
,
fixedLength
-
1
);
}
}
else
if
(
mltService
==
QLatin1String
(
"avformat"
))
{
// Check if file is seekable
bool
seekable
=
m_producer
->
get_int
(
"seekable"
);
if
(
!
seekable
)
{
m_producer
->
set
(
"kdenlive:transcodingrequired"
,
1
);
qDebug
()
<<
"================0
\n\n
FOUND UNSEEKABLE FILE: "
<<
m_producer
->
get
(
"resource"
)
<<
"
\n\n
==================="
;
}
// check if there are multiple streams
vindex
=
m_producer
->
get_int
(
"video_index"
);
// List streams
...
...
src/jobs/transcodeclipjob.cpp
View file @
faf77816
...
...
@@ -35,13 +35,14 @@
#include <klocalizedstring.h>
TranscodeJob
::
TranscodeJob
(
const
QString
&
binId
,
QString
params
)
TranscodeJob
::
TranscodeJob
(
const
QString
&
binId
,
QString
params
,
bool
replaceProducer
)
:
AbstractClipJob
(
TRANSCODEJOB
,
binId
,
{
ObjectType
::
BinClip
,
binId
.
toInt
()})
,
m_jobDuration
(
0
)
,
m_isFfmpegJob
(
true
)
,
m_jobProcess
(
nullptr
)
,
m_done
(
false
)
,
m_transcodeParams
(
std
::
move
(
params
))
,
m_replaceProducer
(
replaceProducer
)
{
}
...
...
@@ -242,7 +243,20 @@ bool TranscodeJob::commitResult(Fun &undo, Fun &redo)
return
false
;
}
m_resultConsumed
=
true
;
QString
folderId
=
QStringLiteral
(
"-1"
);
auto
id
=
ClipCreator
::
createClipFromFile
(
m_destUrl
,
folderId
,
pCore
->
projectItemModel
(),
undo
,
redo
);
QString
id
;
if
(
m_replaceProducer
)
{
id
=
m_clipId
;
QMap
<
QString
,
QString
>
sourceProps
;
QMap
<
QString
,
QString
>
newProps
;
auto
binClip
=
pCore
->
projectItemModel
()
->
getClipByBinID
(
m_clipId
);
sourceProps
.
insert
(
QStringLiteral
(
"resource"
),
binClip
->
url
());
sourceProps
.
insert
(
QStringLiteral
(
"kdenlive:clipname"
),
binClip
->
clipName
());
newProps
.
insert
(
QStringLiteral
(
"resource"
),
m_destUrl
);
newProps
.
insert
(
QStringLiteral
(
"kdenlive:clipname"
),
QFileInfo
(
m_destUrl
).
fileName
());
pCore
->
bin
()
->
slotEditClipCommand
(
m_clipId
,
sourceProps
,
newProps
);
}
else
{
QString
folderId
=
QStringLiteral
(
"-1"
);
id
=
ClipCreator
::
createClipFromFile
(
m_destUrl
,
folderId
,
pCore
->
projectItemModel
(),
undo
,
redo
);
}
return
id
!=
QStringLiteral
(
"-1"
);
}
src/jobs/transcodeclipjob.h
View file @
faf77816
...
...
@@ -30,7 +30,7 @@ class TranscodeJob : public AbstractClipJob
Q_OBJECT
public:
TranscodeJob
(
const
QString
&
binId
,
QString
params
);
TranscodeJob
(
const
QString
&
binId
,
QString
params
,
bool
replaceProducer
=
false
);
const
QString
getDescription
()
const
override
;
bool
startJob
()
override
;
/** @brief This is to be called after the job finished.
...
...
@@ -47,6 +47,7 @@ private:
bool
m_done
;
QString
m_destUrl
;
QString
m_transcodeParams
;
bool
m_replaceProducer
;
};
#endif
src/mainwindow.cpp
View file @
faf77816
...
...
@@ -3596,7 +3596,7 @@ void MainWindow::buildDynamicActions()
}
connect
(
a
,
&
QAction
::
triggered
,
[
&
,
a
]()
{
QStringList
transcodeData
=
a
->
data
().
toStringList
();
emit
pCore
->
jobManager
()
->
startJob
<
TranscodeJob
>
(
pCore
->
bin
()
->
selectedClipsIds
(
true
),
-
1
,
QString
(),
transcodeData
.
first
());
emit
pCore
->
jobManager
()
->
startJob
<
TranscodeJob
>
(
pCore
->
bin
()
->
selectedClipsIds
(
true
),
-
1
,
QString
(),
transcodeData
.
first
()
,
false
);
});
if
(
transList
.
count
()
>
2
&&
transList
.
at
(
2
)
==
QLatin1String
(
"audio"
))
{
// This is an audio transcoding action
...
...
src/project/CMakeLists.txt
View file @
faf77816
...
...
@@ -8,4 +8,5 @@ set(kdenlive_SRCS
project/projectmanager.cpp
project/effectsettings.cpp
project/notesplugin.cpp
project/transcodeseek.cpp
PARENT_SCOPE
)
src/project/transcodeseek.cpp
0 → 100644
View file @
faf77816
/*
Copyright (C) 2021 by Jean-Baptiste Mardelle (jb@kdenlive.org)
*
This file is part of Kdenlive. See www.kdenlive.org.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "transcodeseek.h"
#include "kdenlivesettings.h"
#include "kxmlgui_version.h"
#include <QFontDatabase>
#include <QStandardPaths>
#include <KMessageBox>
#include <klocalizedstring.h>
TranscodeSeek
::
TranscodeSeek
(
QWidget
*
parent
)
:
QDialog
(
parent
)
{
setFont
(
QFontDatabase
::
systemFont
(
QFontDatabase
::
SmallestReadableFont
));
setupUi
(
this
);
setAttribute
(
Qt
::
WA_DeleteOnClose
,
false
);
setWindowTitle
(
i18n
(
"Transcode Clip"
));
KConfig
conf
(
QStringLiteral
(
"kdenlivetranscodingrc"
),
KConfig
::
CascadeConfig
,
QStandardPaths
::
AppDataLocation
);
KConfigGroup
group
(
&
conf
,
"intermediate"
);
m_encodeParams
=
group
.
entryMap
();
encodingprofiles
->
addItems
(
group
.
keyList
());
}
TranscodeSeek
::~
TranscodeSeek
()
{
}
void
TranscodeSeek
::
addUrl
(
const
QString
&
file
,
const
QString
&
id
)
{
QListWidgetItem
*
it
=
new
QListWidgetItem
(
file
,
listWidget
);
it
->
setData
(
Qt
::
UserRole
,
id
);
}
std
::
vector
<
QString
>
TranscodeSeek
::
ids
()
const
{
std
::
vector
<
QString
>
urls
;
for
(
int
i
=
0
;
i
<
listWidget
->
count
();
i
++
)
{
urls
.
push_back
(
listWidget
->
item
(
i
)
->
data
(
Qt
::
UserRole
).
toString
());
}
return
urls
;
}
QString
TranscodeSeek
::
params
()
const
{
return
m_encodeParams
.
value
(
encodingprofiles
->
currentText
());
}
src/project/transcodeseek.h
0 → 100644
View file @
faf77816
/*
Copyright (C) 2021 by Jean-Baptiste Mardelle (jb@kdenlive.org)
*
This file is part of Kdenlive. See www.kdenlive.org.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License or (at your option) version 3 or any later version
accepted by the membership of KDE e.V. (or its successor approved
by the membership of KDE e.V.), which shall act as a proxy
defined in Section 14 of version 3 of the license.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRANSCODESEEK_H
#define TRANSCODESEEK_H
#include "ui_transcodeseekable_ui.h"
#include <QUrl>
#include <QProcess>
class
TranscodeSeek
:
public
QDialog
,
public
Ui
::
TranscodeSeekable_UI
{
Q_OBJECT
public:
TranscodeSeek
(
QWidget
*
parent
=
nullptr
);
~
TranscodeSeek
()
override
;
void
addUrl
(
const
QString
&
file
,
const
QString
&
id
);
std
::
vector
<
QString
>
ids
()
const
;
QString
params
()
const
;
private:
QMap
<
QString
,
QString
>
m_encodeParams
;
};
#endif
src/ui/transcodeseekable_ui.ui
0 → 100644
View file @
faf77816
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
TranscodeSeekable_UI
</class>
<widget
class=
"QDialog"
name=
"TranscodeSeekable_UI"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
302
</width>
<height>
328
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
Dialog
</string>
</property>
<layout
class=
"QGridLayout"
name=
"gridLayout"
>
<item
row=
"0"
column=
"0"
colspan=
"2"
>
<widget
class=
"QLabel"
name=
"label"
>
<property
name=
"text"
>
<string>
The following clips are not usable for editing. Do you want to transcode them in an edit friendly format ? The converted clips will replace the original ones in your project once created.
</string>
</property>
<property
name=
"alignment"
>
<set>
Qt::AlignJustify|Qt::AlignVCenter
</set>
</property>
<property
name=
"wordWrap"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item
row=
"1"
column=
"0"
colspan=
"2"
>
<widget
class=
"QListWidget"
name=
"listWidget"
>
<property
name=
"alternatingRowColors"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item
row=
"2"
column=
"0"
>
<widget
class=
"QLabel"
name=
"label_2"
>
<property
name=
"text"
>
<string>
Convert to
</string>
</property>
</widget>
</item>
<item
row=
"2"
column=
"1"
>
<widget
class=
"QComboBox"
name=
"encodingprofiles"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"MinimumExpanding"
vsizetype=
"Fixed"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item
row=
"3"
column=
"0"
colspan=
"2"
>
<widget
class=
"QDialogButtonBox"
name=
"buttonBox"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"standardButtons"
>
<set>
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>
buttonBox
</sender>
<signal>
accepted()
</signal>
<receiver>
TranscodeSeekable_UI
</receiver>
<slot>
accept()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
248
</x>
<y>
254
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
157
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
buttonBox
</sender>
<signal>
rejected()
</signal>
<receiver>
TranscodeSeekable_UI
</receiver>
<slot>
reject()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
316
</x>
<y>
260
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
286
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
</connections>
</ui>
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