summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorJøger Hansegård <joger.hansegard@qt.io>2024-02-26 20:01:03 +0100
committerJøger Hansegård <joger.hansegard@qt.io>2024-02-27 13:21:13 +0100
commit7d16111777350deec9ebc5ee1f08288af19534e2 (patch)
treeb780b313a39882ee8994998868b12d9b9a5a7638 /src/multimedia
parentb4147824c6dcf192dfc62e603a5a919a353e88c5 (diff)
Fix QWaveDecoder handling of padding bytes in RIFF chunks
This patch adds support for reading WAV files with odd sized payloads in QWaveDecoder. This allows playing WAV files that contains odd-sized chunks before the 'data' chunk that contains the audio data. According to the specification, Multimedia Programming Interface and Data Specifications 1.0. IBM / Microsoft. pp. 10-11, the payload of RIFF chunks should be padded to an even length, so the fix is to round odd payload sizes up to next even size. Tests are extended with two files where a bext section patched in. One file has an odd length bext chunk with padding byte, the second file has an even length bext chunk without padding byte. Fixes: QTBUG-122193 Pick-to: 6.7 6.6 6.5 Change-Id: I6940db47db91a61e6b97f8f41043b2967b0d155a Reviewed-by: Mikko Hallamaa <mikko.hallamaa@qt.io> Reviewed-by: Artem Dyomin <artem.dyomin@qt.io> Reviewed-by: Tim Blechmann <tim@klingt.org>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/audio/qwavedecoder.cpp8
-rw-r--r--src/multimedia/audio/qwavedecoder.h6
2 files changed, 11 insertions, 3 deletions
diff --git a/src/multimedia/audio/qwavedecoder.cpp b/src/multimedia/audio/qwavedecoder.cpp
index 2d2e04e87..0df50bcbf 100644
--- a/src/multimedia/audio/qwavedecoder.cpp
+++ b/src/multimedia/audio/qwavedecoder.cpp
@@ -439,9 +439,15 @@ bool QWaveDecoder::findChunk(const char *chunkId)
if (qstrncmp(descriptor.id, chunkId, 4) == 0)
return true;
+ // A program reading a RIFF file can skip over any chunk whose chunk
+ // ID it doesn't recognize; it simply skips the number of bytes specified
+ // by ckSize plus the pad byte, if present. See Multimedia Programming
+ // Interface and Data Specifications 1.0. IBM / Microsoft. August 1991. pp. 10-11.
+ const quint32 sizeWithPad = descriptor.size + (descriptor.size & 1);
+
// It's possible that bytes->available() is less than the chunk size
// if it's corrupt.
- junkToSkip = qint64(sizeof(chunk) + descriptor.size);
+ junkToSkip = qint64(sizeof(chunk) + sizeWithPad);
// Skip the current amount
if (junkToSkip > 0)
diff --git a/src/multimedia/audio/qwavedecoder.h b/src/multimedia/audio/qwavedecoder.h
index 11846aaaa..a96e731db 100644
--- a/src/multimedia/audio/qwavedecoder.h
+++ b/src/multimedia/audio/qwavedecoder.h
@@ -62,9 +62,11 @@ private:
struct chunk
{
- char id[4];
- quint32 size;
+ char id[4]; // A four-character code that identifies the representation of the chunk data
+ // padded on the right with blank characters (ASCII 32)
+ quint32 size; // Does not include the size of the id or size fields or the pad byte at the end of payload
};
+
bool peekChunk(chunk* pChunk, bool handleEndianness = true);
struct RIFFHeader