diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2022-06-28 10:35:20 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2022-08-29 07:53:13 +0000 |
commit | 924cf7a65804f3fe683696e8a9b0322076fd9350 (patch) | |
tree | ef6976015ac383425d8ed49b72d1f4d1db269e5e | |
parent | ddf562ea01b5c3a1205283540be8c43dbf51abf2 (diff) |
Fix crash when decoder loads too slowly
Don't try to dereference a non-existing buffer
when we run out of data, but simply fill in
the rest of the buffer with zeroes.
This fixes a crash introduced in change
c2b5a17851f7f240c39ab0305e91fa7c77612fae.
Change-Id: I4b25a9bbd2654fa71cc57eb68b5c5df40bbe2074
Reviewed-by: Lars Knoll <lars.knoll@gmail.com>
(cherry picked from commit 3e68011d1b042e151010aec66aeb4408763a8244)
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r-- | src/spatialaudio/qaudioengine.cpp | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/src/spatialaudio/qaudioengine.cpp b/src/spatialaudio/qaudioengine.cpp index e4bff71a4..fc74d6dc0 100644 --- a/src/spatialaudio/qaudioengine.cpp +++ b/src/spatialaudio/qaudioengine.cpp @@ -578,23 +578,32 @@ void QAmbientSoundPrivate::getBuffer(float *buf, int nframes, int channels) Q_ASSERT(channels == nchannels); QMutexLocker l(&mutex); if (!m_playing || currentBuffer >= buffers.size()) { - memset(buf, 0, nframes*sizeof(float)); + memset(buf, 0, channels * nframes * sizeof(float)); } else { int frames = nframes; float *ff = buf; while (frames) { - const QAudioBuffer &b = buffers.at(currentBuffer); + if (currentBuffer < buffers.size()) { + const QAudioBuffer &b = buffers.at(currentBuffer); // qDebug() << s << b.format().sampleRate() << b.format().channelCount() << b.format().sampleFormat(); - auto *f = b.constData<float>() + bufPos*nchannels; - int toCopy = qMin(b.frameCount() - bufPos, frames); - memcpy(ff, f, toCopy*sizeof(float)*nchannels); - ff += toCopy*nchannels; - frames -= toCopy; - bufPos += toCopy; - Q_ASSERT(bufPos <= b.frameCount()); - if (bufPos == b.frameCount()) { - ++currentBuffer; - bufPos = 0; + auto *f = b.constData<float>() + bufPos*nchannels; + int toCopy = qMin(b.frameCount() - bufPos, frames); + memcpy(ff, f, toCopy*sizeof(float)*nchannels); + ff += toCopy*nchannels; + frames -= toCopy; + bufPos += toCopy; + Q_ASSERT(bufPos <= b.frameCount()); + if (bufPos == b.frameCount()) { + ++currentBuffer; + bufPos = 0; + } + } else { + // no more data available + if (m_loading) + qDebug() << "underrun" << frames << "frames when loading" << url; + memset(ff, 0, frames * channels * sizeof(float)); + ff += frames * channels; + frames = 0; } if (!m_loading) { if (currentBuffer == buffers.size()) { @@ -623,7 +632,6 @@ void QAmbientSoundPrivate::bufferReady() void QAmbientSoundPrivate::finished() { -// qDebug() << "finished"; m_loading = false; } |