shotcut: update to 26.2.26
This commit is contained in:
@@ -1,167 +0,0 @@
|
||||
From 9c022acb7356c92f73280a9c17f424b4b3945a4e Mon Sep 17 00:00:00 2001
|
||||
From: Dan Dennedy <dan@dennedy.org>
|
||||
Date: Thu, 12 Feb 2026 18:45:22 -0800
|
||||
Subject: [PATCH] Fix #1786 timeline waveform crash on long video
|
||||
|
||||
This is not an obvious direct fix. After reproduciung it, I looked for a way to make the existing code more efficient and then the problem went away. Maybe the old approach was having a problem with a QVariantList on Qt 6.10.1. A vector of uchar is more efficient by less data, less conversions, and less copies during conversion.
|
||||
---
|
||||
src/models/audiolevelstask.cpp | 38 +++++++++++++++++-----------------
|
||||
src/models/multitrackmodel.cpp | 4 ++--
|
||||
src/qmltypes/timelineitems.cpp | 11 +++++-----
|
||||
3 files changed, 26 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/src/models/audiolevelstask.cpp b/src/models/audiolevelstask.cpp
|
||||
index b88da67a94..f57adf7d78 100644
|
||||
--- a/src/models/audiolevelstask.cpp
|
||||
+++ b/src/models/audiolevelstask.cpp
|
||||
@@ -32,14 +32,14 @@
|
||||
#include <QString>
|
||||
#include <QThreadPool>
|
||||
#include <QTime>
|
||||
-#include <QVariantList>
|
||||
+#include <QVector>
|
||||
|
||||
static QList<AudioLevelsTask *> tasksList;
|
||||
static QMutex tasksListMutex;
|
||||
|
||||
-static void deleteQVariantList(QVariantList *list)
|
||||
+static void deleteAudioLevels(QVector<uchar> *levels)
|
||||
{
|
||||
- delete list;
|
||||
+ delete levels;
|
||||
}
|
||||
|
||||
AudioLevelsTask::AudioLevelsTask(Mlt::Producer &producer, QObject *object, const QModelIndex &index)
|
||||
@@ -172,7 +172,7 @@ QString AudioLevelsTask::cacheKey()
|
||||
void AudioLevelsTask::run()
|
||||
{
|
||||
// 2 channels interleaved of uchar values
|
||||
- QVariantList levels;
|
||||
+ QVector<uchar> levels;
|
||||
QImage image = DB.getThumbnail(cacheKey());
|
||||
if (image.isNull() || m_isForce) {
|
||||
const char *key[2] = {"meta.media.audio_level.0", "meta.media.audio_level.1"};
|
||||
@@ -203,9 +203,9 @@ void AudioLevelsTask::run()
|
||||
frame->get_audio(format, frequency, channels, samples);
|
||||
// for each channel
|
||||
for (int channel = 0; channel < channels; channel++)
|
||||
- // Convert real to uint for caching as image.
|
||||
+ // Convert real to uchar for caching as image.
|
||||
// Scale by 0.9 because values may exceed 1.0 to indicate clipping.
|
||||
- levels << 256 * qMin(frame->get_double(key[channel]) * 0.9, 1.0);
|
||||
+ levels << uchar(qBound(0.0, 256.0 * frame->get_double(key[channel]) * 0.9, 255.0));
|
||||
} else if (!levels.isEmpty()) {
|
||||
for (int channel = 0; channel < channels; channel++)
|
||||
levels << levels.last();
|
||||
@@ -216,12 +216,12 @@ void AudioLevelsTask::run()
|
||||
if (updateTime.elapsed() > 3 * 1000 && !m_isCanceled) {
|
||||
updateTime.restart();
|
||||
foreach (ProducerAndIndex p, m_producers) {
|
||||
- QVariantList *levelsCopy = new QVariantList(levels);
|
||||
+ QVector<uchar> *levelsCopy = new QVector<uchar>(levels);
|
||||
p.first->lock();
|
||||
p.first->set(kAudioLevelsProperty,
|
||||
levelsCopy,
|
||||
0,
|
||||
- (mlt_destructor) deleteQVariantList);
|
||||
+ (mlt_destructor) deleteAudioLevels);
|
||||
p.first->unlock();
|
||||
if (-1
|
||||
!= m_object->metaObject()->indexOfMethod(
|
||||
@@ -240,16 +240,16 @@ void AudioLevelsTask::run()
|
||||
for (int i = 0; i < n; i++) {
|
||||
QRgb p;
|
||||
if ((4 * i + 3) < count) {
|
||||
- p = qRgba(levels.at(4 * i).toInt(),
|
||||
- levels.at(4 * i + 1).toInt(),
|
||||
- levels.at(4 * i + 2).toInt(),
|
||||
- levels.at(4 * i + 3).toInt());
|
||||
+ p = qRgba(levels.at(4 * i),
|
||||
+ levels.at(4 * i + 1),
|
||||
+ levels.at(4 * i + 2),
|
||||
+ levels.at(4 * i + 3));
|
||||
} else {
|
||||
- int last = levels.last().toInt();
|
||||
- int r = (4 * i + 0) < count ? levels.at(4 * i + 0).toInt() : last;
|
||||
- int g = (4 * i + 1) < count ? levels.at(4 * i + 1).toInt() : last;
|
||||
- int b = (4 * i + 2) < count ? levels.at(4 * i + 2).toInt() : last;
|
||||
- int a = last;
|
||||
+ uchar last = levels.last();
|
||||
+ uchar r = (4 * i + 0) < count ? levels.at(4 * i + 0) : last;
|
||||
+ uchar g = (4 * i + 1) < count ? levels.at(4 * i + 1) : last;
|
||||
+ uchar b = (4 * i + 2) < count ? levels.at(4 * i + 2) : last;
|
||||
+ uchar a = last;
|
||||
p = qRgba(r, g, b, a);
|
||||
}
|
||||
image.setPixel(i / 2, i % channels, p);
|
||||
@@ -294,9 +294,9 @@ void AudioLevelsTask::run()
|
||||
|
||||
if (levels.size() > 0 && !m_isCanceled) {
|
||||
foreach (ProducerAndIndex p, m_producers) {
|
||||
- QVariantList *levelsCopy = new QVariantList(levels);
|
||||
+ QVector<uchar> *levelsCopy = new QVector<uchar>(levels);
|
||||
p.first->lock();
|
||||
- p.first->set(kAudioLevelsProperty, levelsCopy, 0, (mlt_destructor) deleteQVariantList);
|
||||
+ p.first->set(kAudioLevelsProperty, levelsCopy, 0, (mlt_destructor) deleteAudioLevels);
|
||||
p.first->unlock();
|
||||
if (-1
|
||||
!= m_object->metaObject()->indexOfMethod("audioLevelsReady(QPersistentModelIndex)"))
|
||||
diff --git a/src/models/multitrackmodel.cpp b/src/models/multitrackmodel.cpp
|
||||
index 1b50e38b07..a5518ec087 100644
|
||||
--- a/src/models/multitrackmodel.cpp
|
||||
+++ b/src/models/multitrackmodel.cpp
|
||||
@@ -155,8 +155,8 @@ QVariant MultitrackModel::data(const QModelIndex &index, int role) const
|
||||
if (info->producer && info->producer->is_valid()) {
|
||||
info->producer->lock();
|
||||
if (info->producer->get_data(kAudioLevelsProperty)) {
|
||||
- result = QVariant::fromValue(
|
||||
- *((QVariantList *) info->producer->get_data(kAudioLevelsProperty)));
|
||||
+ result = QVariant::fromValue(*(
|
||||
+ (QVector<uchar> *) info->producer->get_data(kAudioLevelsProperty)));
|
||||
}
|
||||
info->producer->unlock();
|
||||
}
|
||||
diff --git a/src/qmltypes/timelineitems.cpp b/src/qmltypes/timelineitems.cpp
|
||||
index 960b7e306d..e47194db12 100644
|
||||
--- a/src/qmltypes/timelineitems.cpp
|
||||
+++ b/src/qmltypes/timelineitems.cpp
|
||||
@@ -92,7 +92,7 @@ class TimelineTriangle : public QQuickPaintedItem
|
||||
class TimelineWaveform : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
- Q_PROPERTY(QVariant levels MEMBER m_audioLevels NOTIFY propertyChanged)
|
||||
+ Q_PROPERTY(QVector<uchar> levels MEMBER m_audioLevels NOTIFY propertyChanged)
|
||||
Q_PROPERTY(QColor fillColor MEMBER m_color NOTIFY propertyChanged)
|
||||
Q_PROPERTY(int inPoint MEMBER m_inPoint NOTIFY inPointChanged)
|
||||
Q_PROPERTY(int outPoint MEMBER m_outPoint NOTIFY outPointChanged)
|
||||
@@ -112,8 +112,7 @@ class TimelineWaveform : public QQuickPaintedItem
|
||||
{
|
||||
if (!m_isActive)
|
||||
return;
|
||||
- QVariantList data = m_audioLevels.toList();
|
||||
- if (data.isEmpty())
|
||||
+ if (m_audioLevels.isEmpty())
|
||||
return;
|
||||
|
||||
// In and out points are # frames at current fps,
|
||||
@@ -130,9 +129,9 @@ class TimelineWaveform : public QQuickPaintedItem
|
||||
int i = 0;
|
||||
for (; i < width(); ++i) {
|
||||
int idx = inPoint + int(i * indicesPrPixel);
|
||||
- if ((idx < 0) || (idx + 2 >= data.length()))
|
||||
+ if ((idx < 0) || (idx + 2 >= m_audioLevels.size()))
|
||||
break;
|
||||
- qreal level = qMax(data.at(idx).toReal(), data.at(idx + 1).toReal()) / 256;
|
||||
+ qreal level = qMax(m_audioLevels[idx], m_audioLevels[idx + 1]) / 256.0;
|
||||
path.lineTo(i, height() - level * height());
|
||||
}
|
||||
path.lineTo(i, height());
|
||||
@@ -149,7 +148,7 @@ class TimelineWaveform : public QQuickPaintedItem
|
||||
void outPointChanged();
|
||||
|
||||
private:
|
||||
- QVariant m_audioLevels;
|
||||
+ QVector<uchar> m_audioLevels;
|
||||
int m_inPoint;
|
||||
int m_outPoint;
|
||||
QColor m_color;
|
||||
@@ -1,6 +1,6 @@
|
||||
# Template file for 'shotcut'
|
||||
pkgname=shotcut
|
||||
version=26.1.30
|
||||
version=26.2.26
|
||||
revision=1
|
||||
build_style=cmake
|
||||
configure_args="-DSHOTCUT_VERSION=${version}"
|
||||
@@ -15,6 +15,6 @@ license="GPL-3.0-or-later"
|
||||
homepage="https://www.shotcut.org"
|
||||
changelog="https://github.com/mltframework/shotcut/releases"
|
||||
distfiles="https://github.com/mltframework/shotcut/archive/v${version}.tar.gz"
|
||||
checksum=921c3c927033fe85bbe0cf28ce62fd62b01b56d6a2926093643291928a7b76cc
|
||||
checksum=b5c840a459eaf4ad9e0ad7a02d782678207f9102cfce7f129f413fe2c0cb3ca8
|
||||
|
||||
CXXFLAGS="-DHAVE_LOCALE_H=1 -DSHOTCUT_NOUPGRADE"
|
||||
|
||||
Reference in New Issue
Block a user