diff options
author | Piotr Srebrny <piotr.srebrny@qt.io> | 2022-04-07 16:29:39 +0200 |
---|---|---|
committer | Piotr Srebrny <piotr.srebrny@qt.io> | 2022-04-26 19:35:28 +0200 |
commit | 65772a78718d44bee65f7846cec55cf3078d24ba (patch) | |
tree | d6de632c706484cc67c690b073ff9da4c0e842b9 /src/plugins/multimedia/windows | |
parent | 983e50fbef960086e05d7de4f13a534216f76d66 (diff) |
Restart pulling data if QIODevice signals readyRead
This patch improves handling of the QIODevice protocol by QAudioSink
in the pull mode. QAudioSink will restart pulling data when it receives
the readyRead signal. If the QIODevice source is atEnd(), QAudioSink
will no longer emit UnderrunError, but will switch to IdleState without
error. It will first check if the device is open and ask for
bytesAvailable before performing read.
Change-Id: Idd1d18419f7b77d2df2d76e7b1892194d652d63a
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/plugins/multimedia/windows')
-rw-r--r-- | src/plugins/multimedia/windows/audio/qwindowsaudiosink.cpp | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/src/plugins/multimedia/windows/audio/qwindowsaudiosink.cpp b/src/plugins/multimedia/windows/audio/qwindowsaudiosink.cpp index 046a91ab0..5d41e6ed6 100644 --- a/src/plugins/multimedia/windows/audio/qwindowsaudiosink.cpp +++ b/src/plugins/multimedia/windows/audio/qwindowsaudiosink.cpp @@ -170,24 +170,24 @@ void QWindowsAudioSink::setFormat(const QAudioFormat& fmt) void QWindowsAudioSink::pullSource() { qCDebug(qLcAudioOutput) << "Pull source"; + if (!m_pullSource) + return; - qsizetype freeSpace = bytesFree(); - QByteArray samples; - if (freeSpace > 0) { - samples.resize(freeSpace); - qint64 read = m_pullSource->read(samples.data(), freeSpace); - if (read < 0) { + auto bytesAvailable = m_pullSource->isOpen() ? qsizetype(m_pullSource->bytesAvailable()) : 0; + auto readLen = qMin(bytesFree(), bytesAvailable); + if (readLen > 0) { + QByteArray samples = m_pullSource->read(readLen); + if (samples.size() == 0) { deviceStateChange(QAudio::IdleState, QAudio::IOError); return; - } else if (read > 0) { - write(samples.data(), read); + } else { + write(samples.data(), samples.size()); } } auto playTimeUs = remainingPlayTimeUs(); - if (playTimeUs == 0) { - deviceStateChange(QAudio::IdleState, QAudio::UnderrunError); + deviceStateChange(QAudio::IdleState, m_pullSource->atEnd() ? QAudio::NoError : QAudio::UnderrunError); } else { deviceStateChange(QAudio::ActiveState, QAudio::NoError); m_timer.start(playTimeUs / 2000); @@ -208,6 +208,7 @@ void QWindowsAudioSink::start(QIODevice* device) m_pullSource = device; + connect(device, &QIODevice::readyRead, this, &QWindowsAudioSink::pullSource); m_timer.disconnect(); m_timer.callOnTimeout(this, &QWindowsAudioSink::pullSource); m_timer.start(0); @@ -317,6 +318,8 @@ void QWindowsAudioSink::close() deviceStateChange(QAudio::StoppedState, QAudio::NoError); + if (m_pullSource) + disconnect(m_pullSource, &QIODevice::readyRead, this, &QWindowsAudioSink::pullSource); m_audioClient.reset(); m_renderClient.reset(); m_pullSource = nullptr; |