Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Fix various crashes in subclips (clip zones)

parent 906f457a
......@@ -173,7 +173,19 @@ bool ProjectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action
if (data->hasFormat(QStringLiteral("kdenlive/producerslist"))) {
// Dropping an Bin item
const QStringList ids = QString(data->data(QStringLiteral("kdenlive/producerslist"))).split(QLatin1Char(';'));
emit itemDropped(ids, parent);
if (ids.constFirst().contains(QLatin1Char('#'))) {
// subclip zone
QStringList clipData = ids.constFirst().split(QLatin1Char('#'));
if (clipData.length() >= 3) {
QString id;
return requestAddBinSubClip(id, clipData.at(1).toInt(), clipData.at(2).toInt(), clipData.at(0));
} else {
// error, malformed clip zone, abort
return false;
}
} else {
emit itemDropped(ids, parent);
}
return true;
}
......
......@@ -92,8 +92,17 @@ bool ProjectSortProxyModel::lessThan(const QModelIndex &left, const QModelIndex
int rightType = sourceModel()->data(right, AbstractProjectItem::ItemTypeRole).toInt();
if (leftType == rightType) {
// Let the normal alphabetical sort happen
QVariant leftData = sourceModel()->data(left, Qt::DisplayRole);
QVariant rightData = sourceModel()->data(right, Qt::DisplayRole);
// Let the normal alphabetical sort happen
QVariant leftData;
QVariant rightData;
if (leftType == AbstractProjectItem::SubClipItem) {
// Subclips, sort by start position
leftData = sourceModel()->data(left, AbstractProjectItem::DataDuration);
rightData = sourceModel()->data(right, AbstractProjectItem::DataDuration);
} else {
leftData = sourceModel()->data(left, Qt::DisplayRole);
rightData = sourceModel()->data(right, Qt::DisplayRole);
}
if (leftData.type() == QVariant::DateTime) {
return leftData.toDateTime() < rightData.toDateTime();
}
......
......@@ -36,6 +36,7 @@ ProjectSubClip::ProjectSubClip(const QString &id, const std::shared_ptr<ProjectC
, m_in(in)
, m_out(out)
{
m_duration = timecode;
QPixmap pix(64, 36);
pix.fill(Qt::lightGray);
m_thumbnail = QIcon(pix);
......@@ -45,8 +46,6 @@ ProjectSubClip::ProjectSubClip(const QString &id, const std::shared_ptr<ProjectC
m_name = name;
}
m_clipStatus = StatusReady;
changeParent(parent);
m_duration = timecode;
// Save subclip in MLT
parent->setProducerProperty("kdenlive:clipzone." + m_name, QString::number(in) + QLatin1Char(';') + QString::number(out));
connect(parent.get(), &ProjectClip::thumbReady, this, &ProjectSubClip::gotThumb);
......@@ -55,8 +54,9 @@ ProjectSubClip::ProjectSubClip(const QString &id, const std::shared_ptr<ProjectC
std::shared_ptr<ProjectSubClip> ProjectSubClip::construct(const QString &id, std::shared_ptr<ProjectClip> parent, std::shared_ptr<ProjectItemModel> model,
int in, int out, const QString &timecode, const QString &name)
{
std::shared_ptr<ProjectSubClip> self(new ProjectSubClip(id, parent, std::move(model), in, out, timecode, name));
std::shared_ptr<ProjectSubClip> self(new ProjectSubClip(id, parent, model, in, out, timecode, name));
baseFinishConstruct(self);
self->changeParent(parent);
return self;
}
......
......@@ -39,6 +39,7 @@
AudioThumbJob::AudioThumbJob(const QString &binId)
: AbstractClipJob(AUDIOTHUMBJOB, binId)
, m_ffmpegProcess(nullptr)
{
}
......@@ -146,11 +147,11 @@ bool AudioThumbJob::computeWithFFMPEG()
<< QStringLiteral("-f") << QStringLiteral("data") << channelFiles[size_t(i)]->fileName();
}
}
QProcess ffmpegProcess;
ffmpegProcess.start(KdenliveSettings::ffmpegpath(), args);
connect(&ffmpegProcess, &QProcess::readyReadStandardOutput, this, &AudioThumbJob::updateFfmpegProgress);
ffmpegProcess.waitForFinished(-1);
if (ffmpegProcess.exitStatus() != QProcess::CrashExit) {
m_ffmpegProcess = new QProcess;
m_ffmpegProcess->start(KdenliveSettings::ffmpegpath(), args);
connect(m_ffmpegProcess, &QProcess::readyReadStandardOutput, this, &AudioThumbJob::updateFfmpegProgress);
m_ffmpegProcess->waitForFinished(-1);
if (m_ffmpegProcess->exitStatus() != QProcess::CrashExit) {
int dataSize = 0;
std::vector<const qint16 *> rawChannels;
std::vector<QByteArray> sourceChannels;
......@@ -205,7 +206,8 @@ bool AudioThumbJob::computeWithFFMPEG()
m_done = true;
return true;
}
QString err = ffmpegProcess.readAllStandardError();
QString err = m_ffmpegProcess->readAllStandardError();
delete m_ffmpegProcess;
m_errorMessage += err;
m_errorMessage.append(i18n("Failed to create FFmpeg audio thumbnails, we now try to use MLT"));
return false;
......@@ -213,8 +215,8 @@ bool AudioThumbJob::computeWithFFMPEG()
void AudioThumbJob::updateFfmpegProgress()
{
QProcess *ffmpegProcess = qobject_cast<QProcess *>(QObject::sender());
QString result = ffmpegProcess->readAllStandardOutput();
//QProcess *m_ffmpegProcess = qobject_cast<QProcess *>(QObject::sender());
QString result = m_ffmpegProcess->readAllStandardOutput();
const QStringList lines = result.split(QLatin1Char('\n'));
for (const QString &data : lines) {
if (data.startsWith(QStringLiteral("out_time_ms"))) {
......
......@@ -69,4 +69,5 @@ private:
bool m_done{false}, m_successful{false};
int m_channels, m_frequency, m_lengthInFrames, m_audioStream;
QVariantList m_audioLevels;
QProcess *m_ffmpegProcess;
};
......@@ -80,9 +80,9 @@ bool ThumbJob::startJob()
m_frameNumber = std::min(max - 1, m_frameNumber);
// m_frameNumber = ProjectClip::getXmlProperty(info.xml, QStringLiteral("kdenlive:thumbnailFrame"), QStringLiteral("-1")).toInt();
if (ThumbnailCache::get()->hasThumbnail(m_clipId, m_frameNumber, !m_persistent)) {
if (ThumbnailCache::get()->hasThumbnail(m_binClip->clipId(), m_frameNumber, !m_persistent)) {
m_done = true;
m_result = ThumbnailCache::get()->getThumbnail(m_clipId, m_frameNumber);
m_result = ThumbnailCache::get()->getThumbnail(m_binClip->clipId(), m_frameNumber);
m_inCache = true;
return true;
}
......@@ -109,7 +109,7 @@ bool ThumbJob::commitResult(Fun &undo, Fun &redo)
}
m_resultConsumed = true;
if (!m_inCache) {
ThumbnailCache::get()->storeThumbnail(m_clipId, m_frameNumber, m_result, m_persistent);
ThumbnailCache::get()->storeThumbnail(m_binClip->clipId(), m_frameNumber, m_result, m_persistent);
}
// TODO a refactor of ProjectClip and ProjectSubClip should make that possible without branching (both classes implement setThumbnail)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment