summaryrefslogtreecommitdiffstats
path: root/src/plugins/multimedia/windows
diff options
context:
space:
mode:
authorPiotr Srebrny <piotr.srebrny@qt.io>2022-04-07 16:29:39 +0200
committerPiotr Srebrny <piotr.srebrny@qt.io>2022-04-26 19:35:28 +0200
commit65772a78718d44bee65f7846cec55cf3078d24ba (patch)
treed6de632c706484cc67c690b073ff9da4c0e842b9 /src/plugins/multimedia/windows
parent983e50fbef960086e05d7de4f13a534216f76d66 (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.cpp23
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;