[multimedia/kwave] /: codec_flac: parallelized decoding + added check for > 8 channels
Thomas Eschenbacher <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 8702df3ebdb946a7d36b7c057a9c90993b525597 by Thomas Eschenbacher.
Committed on 18/08/2026 at 14:31.
Pushed by eschenbacher into branch 'master'.
codec_flac: parallelized decoding + added check for > 8 channels
M +2 -1 CHANGES
M +28 -17 plugins/codec_flac/FlacDecoder.cpp
M +7 -0 plugins/codec_flac/FlacEncoder.cpp
M +2 -0 plugins/codec_ogg/OpusDecoder.cpp
M +1 -1 plugins/codec_ogg/VorbisEncoder.cpp
https://invent.kde.org/multimedia/kwave/-/commit/8702df3ebdb946a7d36b7c057a9c90993b525597
diff --git a/CHANGES b/CHANGES
index d1ef8093..ae964744 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,5 @@
-26.11.70 [2026-08-17]
+26.11.70 [2026-08-18]
+ * codec_flac: parallelized decoding + added check for > 8 channels
* codec_mp3: workaround for broken MBS conversion in ID3LIB
* codec_mp3: do no longer explicitly link against libstdc++ and libz
* codec_ogg: parallelized decoding of ogg/opus and ogg/vorbis
diff --git a/plugins/codec_flac/FlacDecoder.cpp b/plugins/codec_flac/FlacDecoder.cpp
index 77f315cd..3060924e 100644
--- a/plugins/codec_flac/FlacDecoder.cpp
+++ b/plugins/codec_flac/FlacDecoder.cpp
@@ -20,7 +20,9 @@
#include <new>
#include <QDateTime>
+#include <QFutureSynchronizer>
#include <QIODevice>
+#include <QtConcurrentRun>
#include <KLocalizedString>
@@ -109,31 +111,40 @@ Kwave::Decoder *Kwave::FlacDecoder::instance()
if (shift < 0) shift = 0;
unsigned int mul = (1 << shift);
- // decode the samples into a temporary buffer and
- // flush it to the Writer(s), track by track
- for (unsigned int track=0; track < tracks; track++) {
+ QFutureSynchronizer<void> synchronizer;
+ for (unsigned int track = 0; track < tracks; ++track) {
Kwave::Writer *writer = (*m_dest)[track];
- Q_ASSERT(writer);
if (!writer) continue;
- const FLAC__int32 *src = buffer[track];
- sample_t *d = dst.data();
- for (unsigned int sample = 0; sample < samples; sample++) {
- // the following cast is only necessary if
- // sample_t is not equal to a quint32
- sample_t s = static_cast<sample_t>(*src++);
+ const FLAC__int32 *buf = buffer[track];
- // correct precision
- if (shift) s *= mul;
+ synchronizer.addFuture(QtConcurrent::run(
+ [buf, samples, shift, mul, writer]() {
+ Kwave::SampleArray dst(samples);
+ sample_t *d = dst.data();
+ const FLAC__int32 *src = buf;
- // write to destination buffer
- *d++ = s;
- }
+ for (unsigned int sample = 0; sample < samples; ++sample) {
+ // the following cast is only necessary if
+ // sample_t is not equal to a quint32
+ sample_t s = static_cast<sample_t>(*src++);
+
+ // correct precision
+ if (shift) s *= mul;
- // flush the temporary buffer
- (*writer) << dst;
+ // write to destination buffer
+ *d++ = s;
+ }
+
+ // write converted samples to destination track
+ (*writer) << dst;
+ }
+ ));
}
+ // wait for all channels in this frame to complete
+ synchronizer.waitForFinished();
+
// at this point we check for a user-cancel
return (m_dest->isCanceled()) ?
FLAC__STREAM_DECODER_WRITE_STATUS_ABORT :
diff --git a/plugins/codec_flac/FlacEncoder.cpp b/plugins/codec_flac/FlacEncoder.cpp
index 8812e6c8..20d1274e 100644
--- a/plugins/codec_flac/FlacEncoder.cpp
+++ b/plugins/codec_flac/FlacEncoder.cpp
@@ -183,6 +183,13 @@ bool Kwave::FlacEncoder::encode(QWidget *widget,
unsigned int bits = info.bits();
sample_index_t length = info.length();
+ if ((tracks == 0) || (tracks > 8)) {
+ Kwave::MessageBox::sorry(widget,
+ i18n("This codec supports only 1 ... 8 channels, "
+ "%1 channels are not supported.", tracks));
+ return false;
+ }
+
set_compression_level(5); // @todo make the FLAC compression configurable
set_channels(static_cast<unsigned>(tracks));
set_bits_per_sample(static_cast<unsigned>(bits));
diff --git a/plugins/codec_ogg/OpusDecoder.cpp b/plugins/codec_ogg/OpusDecoder.cpp
index 2651f62d..60554f71 100644
--- a/plugins/codec_ogg/OpusDecoder.cpp
+++ b/plugins/codec_ogg/OpusDecoder.cpp
@@ -26,8 +26,10 @@
#include <QApplication>
#include <QDate>
+#include <QFutureSynchronizer>
#include <QIODevice>
#include <QString>
+#include <QtConcurrentRun>
#include <QtEndian>
#include <KLocalizedString>
diff --git a/plugins/codec_ogg/VorbisEncoder.cpp b/plugins/codec_ogg/VorbisEncoder.cpp
index c1e8cf2e..65f6cd49 100644
--- a/plugins/codec_ogg/VorbisEncoder.cpp
+++ b/plugins/codec_ogg/VorbisEncoder.cpp
@@ -101,7 +101,7 @@ bool Kwave::VorbisEncoder::open(QWidget *widget, const Kwave::FileInfo &info,
long int sample_rate = static_cast<long int>(info.rate());
int default_bitrate = (DEFAULT_BITRATE / 2) * tracks;
- if ((tracks ==0) || (tracks > 255)) {
+ if ((tracks == 0) || (tracks > 255)) {
Kwave::MessageBox::sorry(widget,
i18n("This codec supports only 1 ... 255 channels, "
"%1 channels are not supported.", tracks));