From 55a86b8a00aa8bd57881a94bc98d71a97b7ff08d Mon Sep 17 00:00:00 2001 From: Kasem SAEED Date: Tue, 5 Oct 2021 10:35:07 -0700 Subject: [PATCH] Add support for RF64 wave files --- .../android/exoplayer2/audio/WavUtil.java | 4 ++++ .../extractor/wav/WavHeaderReader.java | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/audio/WavUtil.java b/library/extractor/src/main/java/com/google/android/exoplayer2/audio/WavUtil.java index 208989124a..ff8f5175bf 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/audio/WavUtil.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/audio/WavUtil.java @@ -22,6 +22,10 @@ import com.google.android.exoplayer2.util.Util; /** Utilities for handling WAVE files. */ public final class WavUtil { + /** Four character code for "RF64". */ + public static final int RF64_FOURCC = 0x52463634; + /** Four character code for "ds64". */ + public static final int DS64_FOURCC = 0x64733634; /** Four character code for "RIFF". */ public static final int RIFF_FOURCC = 0x52494646; /** Four character code for "WAVE". */ diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeaderReader.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeaderReader.java index f794933d16..b5813ae2c2 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeaderReader.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeaderReader.java @@ -50,7 +50,7 @@ import java.io.IOException; // Attempt to read the RIFF chunk. ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch); - if (chunkHeader.id != WavUtil.RIFF_FOURCC) { + if (chunkHeader.id != WavUtil.RIFF_FOURCC && chunkHeader.id != WavUtil.RF64_FOURCC) { return null; } @@ -117,14 +117,23 @@ import java.io.IOException; ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES); // Skip all chunks until we find the data header. ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch); + long dataSize = -1; while (chunkHeader.id != WavUtil.DATA_FOURCC) { if (chunkHeader.id != WavUtil.RIFF_FOURCC && chunkHeader.id != WavUtil.FMT_FOURCC) { Log.w(TAG, "Ignoring unknown WAV chunk: " + chunkHeader.id); } long bytesToSkip = ChunkHeader.SIZE_IN_BYTES + chunkHeader.size; // Override size of RIFF chunk, since it describes its size as the entire file. - if (chunkHeader.id == WavUtil.RIFF_FOURCC) { + // Also, ignore the size of RF64 chunk, since its always going to be 0xFFFFFFFF + if (chunkHeader.id == WavUtil.RIFF_FOURCC || chunkHeader.id == WavUtil.RF64_FOURCC) { bytesToSkip = ChunkHeader.SIZE_IN_BYTES + 4; + } else if (chunkHeader.id == WavUtil.DS64_FOURCC) { + int ds64Size = (int) chunkHeader.size; + ParsableByteArray ds64Bytes = new ParsableByteArray(ds64Size); + input.peekFully(ds64Bytes.getData(), 0, ds64Size); + // ds64 chunk contains 64bit sizes. From position 12 to 20 is the data size + ds64Bytes.setPosition(12); + dataSize = ds64Bytes.readLong(); } if (bytesToSkip > Integer.MAX_VALUE) { throw ParserException.createForUnsupportedContainerFeature( @@ -133,11 +142,15 @@ import java.io.IOException; input.skipFully((int) bytesToSkip); chunkHeader = ChunkHeader.peek(input, scratch); } + // Use size from data chunk if it wasn't determined from ds64 chunk + if (dataSize == -1) { + dataSize = chunkHeader.size; + } // Skip past the "data" header. input.skipFully(ChunkHeader.SIZE_IN_BYTES); long dataStartPosition = input.getPosition(); - long dataEndPosition = dataStartPosition + chunkHeader.size; + long dataEndPosition = dataStartPosition + dataSize; long inputLength = input.getLength(); if (inputLength != C.LENGTH_UNSET && dataEndPosition > inputLength) { Log.w(TAG, "Data exceeds input length: " + dataEndPosition + ", " + inputLength);