diff options
author | Axel Spoerl <axel.spoerl@qt.io> | 2022-05-10 17:41:23 +0200 |
---|---|---|
committer | Axel Spoerl <axel.spoerl@qt.io> | 2022-05-11 15:31:58 +0200 |
commit | d90207f88b64082fc87e6cb355f30b58fc17c444 (patch) | |
tree | 2d23850963fca995045c3e43e2ac59bfbe97caf1 | |
parent | 3fe9a114aefdaed6352dba99dd6d3ffa81712075 (diff) |
Fix chunk sizing in QPulseAudioSink
QPulseAudioSink:write() takes a length parameter which is set to the
qMin of itself and the return value of pa_stream_writable_size().
This method returns the number of bytes requested by the server,
but not yet written. Unless data is buffered, the value is 0.
That leads to length being set to 0 and no data being sent.
In PulseOutputPrivate::writeData(), a loop was implemented calling
QPulseAudioSink::write() up to 10 times for each data chunk.
That forced data buffering and subsequently the return value of
pa_stream_writable_size() to be > 0.
This patch replaces the query of pa_stream_writable_size() with the
nbytes value modified by pa_stream_begin_write(). It represents the
maximum amount of bytes the pulseaudio server is ready to accept.
The patch also removes the loop calling write up to 10 times as it
becomes unnecessary.
Fixes: QTBUG-60575
Change-Id: I316a5ac610c8540ab8f7fff4a3b0b1ee3d7e7ad5
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit f1829a24d4c9a393f95d55c415daa80275a90b93)
-rw-r--r-- | src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp b/src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp index 0521a5670..716bfa9a9 100644 --- a/src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp +++ b/src/multimedia/platform/pulseaudio/qpulseaudiosink.cpp @@ -512,26 +512,29 @@ qint64 QPulseAudioSink::write(const char *data, qint64 len) pulseEngine->lock(); - len = qMin(len, static_cast<qint64>(pa_stream_writable_size(m_stream))); + size_t nbytes = len; + void *dest = nullptr; + + if (pa_stream_begin_write(m_stream, &dest, &nbytes) < 0) { + qWarning("QAudioSink(pulseaudio): pa_stream_begin_write, error = %s", + pa_strerror(pa_context_errno(pulseEngine->context()))); + setError(QAudio::IOError); + return 0; + } + + len = qMin(len, qint64(nbytes)); if (m_volume < 1.0f) { // Don't use PulseAudio volume, as it might affect all other streams of the same category // or even affect the system volume if flat volumes are enabled - void *dest = nullptr; - size_t nbytes = len; - if (pa_stream_begin_write(m_stream, &dest, &nbytes) < 0) { - qWarning("QAudioSink(pulseaudio): pa_stream_begin_write, error = %s", - pa_strerror(pa_context_errno(pulseEngine->context()))); - setError(QAudio::IOError); - return 0; - } - - len = int(nbytes); QAudioHelperInternal::qMultiplySamples(m_volume, m_format, data, dest, len); - data = reinterpret_cast<char *>(dest); + } else { + memcpy(dest, data, len); } - if (pa_stream_write(m_stream, data, len, nullptr, 0, PA_SEEK_RELATIVE) < 0) { + data = reinterpret_cast<char *>(dest); + + if ((pa_stream_write(m_stream, data, len, nullptr, 0, PA_SEEK_RELATIVE)) < 0) { qWarning("QAudioSink(pulseaudio): pa_stream_write, error = %s", pa_strerror(pa_context_errno(pulseEngine->context()))); setError(QAudio::IOError); @@ -672,7 +675,6 @@ qint64 PulseOutputPrivate::readData(char *data, qint64 len) qint64 PulseOutputPrivate::writeData(const char *data, qint64 len) { - int retry = 0; qint64 written = 0; if ((m_audioDevice->m_deviceState == QAudio::ActiveState @@ -680,10 +682,8 @@ qint64 PulseOutputPrivate::writeData(const char *data, qint64 len) while(written < len) { int chunk = m_audioDevice->write(data+written, (len-written)); if (chunk <= 0) - retry++; - written+=chunk; - if (retry > 10) return written; + written+=chunk; } } |