services/pipewire: match node and stream channels in peak sampling

Also fixes potentially requeuing a null buffer
This commit is contained in:
outfoxxed committed 2026-08-15 20:53:19 -07:00
1 parent 8f1316d0c2
commit 7e6c7ae3fb
2 files changed
+24 -2

No files matched your search

+1
View File
@@ -17,3 +17,4 @@
- Fixed intermittent `FileView` crashes when updating watched files.
- Fixed `ColorQuantizer` deletion crashing if an operation was live.
- Fixed crashes when failing to create a `ScreencopyView`.
- Fixed `PwNodePeakMonitor` crashing when sampling a stream with mismatched channels from the node.
+23 -2
View File
@@ -245,13 +245,14 @@ void PwPeakStream::handleProcess() {
if (!this->formatReady || this->stream == nullptr) return;
auto* buffer = pw_stream_dequeue_buffer(this->stream);
auto requeue = qScopeGuard([&, this] { pw_stream_queue_buffer(this->stream, buffer); });
if (buffer == nullptr) {
qCWarning(logPeak) << "Peak monitor ran out of buffers.";
return;
}
auto requeue = qScopeGuard([&, this] { pw_stream_queue_buffer(this->stream, buffer); });
auto* spaBuffer = buffer->buffer;
if (spaBuffer == nullptr || spaBuffer->n_datas < 1) {
return;
@@ -277,7 +278,27 @@ void PwPeakStream::handleProcess() {
QVector<float> volumes;
if (auto* audioData = dynamic_cast<PwNodeBoundAudio*>(this->node->boundData)) {
if (!this->node->shouldUseDevice()) volumes = audioData->volumes();
// Device volumes don't require inverse scaling
if (!this->node->shouldUseDevice()) {
const auto& nchannels = audioData->channels();
const auto& nvolumes = audioData->volumes();
for (const auto channel: this->monitor->mChannels) {
for (auto i = 0; i != nchannels.length(); i++) {
if (nchannels[i] == channel) {
volumes.push_back(nvolumes[i]);
break;
}
}
}
if (volumes.length() != channelCount) {
qCCritical(logPeak) << this->node
<< "is missing channels present in capture stream. Node channels:"
<< nchannels << "Stream channels:" << this->monitor->mChannels;
return;
}
}
}
this->channelPeaks.fill(0.0f, channelCount);