summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorMikko Hallamaa <mikko.hallamaa@qt.io>2024-02-19 15:36:17 +0100
committerMikko Hallamaa <mikko.hallamaa@qt.io>2024-02-21 16:38:51 +0100
commit57bf3f66359ad193dff0925fba6a5799bc40f757 (patch)
tree5b0f2556ccd637a20b6ba17f88f052812c8d14bb /src/multimedia
parenta43f30ee4c4aedefaee7e870edbd309180c48ccb (diff)
PulseAudio: Fix tlength setting of QPulseAudioSink
With PA_STREAM_ADJUST_LATENCY set, PulseAudio will use the requested tlength value to configure playback buffer size + overall sink latency. The configured stream has a tlength of actual buffer size, which was then used as the requested tlenght on subsequent playback streams. This lead to buffer size getting smaller after multiple restarts, and leading to underflows and "static" glitches caused by skipped samples. This patch changes the requested tlength attribute to always be either the buffer size set by the user, or the default buffer size if no buffer size is set. Fixes: QTBUG-116519 Pick-to: 6.7 6.6 6.5 Change-Id: Ib9ad0dc72ad7f70f172b3cc484672c9f426bde06 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/pulseaudio/qpulseaudiosink.cpp29
-rw-r--r--src/multimedia/pulseaudio/qpulseaudiosink_p.h5
2 files changed, 23 insertions, 11 deletions
diff --git a/src/multimedia/pulseaudio/qpulseaudiosink.cpp b/src/multimedia/pulseaudio/qpulseaudiosink.cpp
index 39d21b560..ff526e1b1 100644
--- a/src/multimedia/pulseaudio/qpulseaudiosink.cpp
+++ b/src/multimedia/pulseaudio/qpulseaudiosink.cpp
@@ -303,8 +303,9 @@ bool QPulseAudioSink::open()
pa_buffer_attr requestedBuffer;
// Request a target buffer size
- auto targetBufferSize = bufferSize();
- requestedBuffer.tlength = targetBufferSize ? targetBufferSize : static_cast<uint32_t>(-1);
+ auto targetBufferSize = m_userBufferSize ? *m_userBufferSize : defaultBufferSize();
+ requestedBuffer.tlength =
+ targetBufferSize ? static_cast<uint32_t>(targetBufferSize) : static_cast<uint32_t>(-1);
// Rest should be determined by PulseAudio
requestedBuffer.fragsize = static_cast<uint32_t>(-1);
requestedBuffer.maxlength = static_cast<uint32_t>(-1);
@@ -537,7 +538,7 @@ qsizetype QPulseAudioSink::bytesFree() const
void QPulseAudioSink::setBufferSize(qsizetype value)
{
- m_bufferSize = value;
+ m_userBufferSize = value;
}
qsizetype QPulseAudioSink::bufferSize() const
@@ -545,14 +546,10 @@ qsizetype QPulseAudioSink::bufferSize() const
if (m_bufferSize)
return m_bufferSize;
- if (m_spec.rate > 0)
- return pa_usec_to_bytes(DefaultBufferLengthMs * 1000, &m_spec);
+ if (m_userBufferSize)
+ return *m_userBufferSize;
- auto spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format);
- if (pa_sample_spec_valid(&spec))
- return pa_usec_to_bytes(DefaultBufferLengthMs * 1000, &spec);
-
- return 0;
+ return defaultBufferSize();
}
static qint64 operator-(timeval t1, timeval t2)
@@ -732,6 +729,18 @@ PAOperationUPtr QPulseAudioSink::exchangeDrainOperation(pa_operation *newOperati
return PAOperationUPtr(m_drainOperation.exchange(newOperation));
}
+qsizetype QPulseAudioSink::defaultBufferSize() const
+{
+ if (m_spec.rate > 0)
+ return pa_usec_to_bytes(DefaultBufferLengthMs * 1000, &m_spec);
+
+ auto spec = QPulseAudioInternal::audioFormatToSampleSpec(m_format);
+ if (pa_sample_spec_valid(&spec))
+ return pa_usec_to_bytes(DefaultBufferLengthMs * 1000, &spec);
+
+ return 0;
+}
+
QT_END_NAMESPACE
#include "moc_qpulseaudiosink_p.cpp"
diff --git a/src/multimedia/pulseaudio/qpulseaudiosink_p.h b/src/multimedia/pulseaudio/qpulseaudiosink_p.h
index d7c320f7c..cf0b181ec 100644
--- a/src/multimedia/pulseaudio/qpulseaudiosink_p.h
+++ b/src/multimedia/pulseaudio/qpulseaudiosink_p.h
@@ -80,6 +80,8 @@ private Q_SLOTS:
PAOperationUPtr exchangeDrainOperation(pa_operation *newOperation);
private:
+ qsizetype defaultBufferSize() const;
+
pa_sample_spec m_spec = {};
// calculate timing manually, as pulseaudio doesn't give us good enough data
mutable timeval lastTimingInfo = {};
@@ -102,8 +104,9 @@ private:
qreal m_volume = 1.0;
std::atomic<pa_operation *> m_drainOperation = nullptr;
+ qsizetype m_bufferSize = 0;
+ std::optional<qsizetype> m_userBufferSize = std::nullopt;
int m_pullingPeriodSize = 0;
- int m_bufferSize = 0;
int m_pullingPeriodTime = 0;
bool m_pullMode = true;
bool m_opened = false;