From 80e64e58ec527b6e867fbb44172cefd447b1b7bf Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 4 Sep 2018 06:20:00 -0700 Subject: [PATCH] WAV: Don't output data beyond the data limit ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=211446207 --- RELEASENOTES.md | 2 ++ .../exoplayer2/extractor/wav/WavExtractor.java | 12 +++++++++++- .../exoplayer2/extractor/wav/WavHeader.java | 7 ++++++- .../exoplayer2/extractor/wav/WavHeaderReader.java | 14 ++++++++------ 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 9ab68c92a83..46f5985e671 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -2,6 +2,8 @@ ### dev-v2 (not yet released) ### +* WAV: Fix issue where white noise would be output at the end of playback + ([#4724](https://github.com/google/ExoPlayer/issues/4724)). * Add a flag to opt-in to automatic audio focus handling via `SimpleExoPlayer.setAudioAttributes`. * Distribute Cronet extension via jCenter. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavExtractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavExtractor.java index 7d6aa7024cc..68d252e318b 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavExtractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavExtractor.java @@ -24,6 +24,7 @@ import com.google.android.exoplayer2.extractor.ExtractorsFactory; import com.google.android.exoplayer2.extractor.PositionHolder; import com.google.android.exoplayer2.extractor.TrackOutput; +import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MimeTypes; import java.io.IOException; @@ -88,7 +89,16 @@ public int read(ExtractorInput input, PositionHolder seekPosition) extractorOutput.seekMap(wavHeader); } - int bytesAppended = trackOutput.sampleData(input, MAX_INPUT_SIZE - pendingBytes, true); + long dataLimit = wavHeader.getDataLimit(); + Assertions.checkState(dataLimit != C.POSITION_UNSET); + + long bytesLeft = dataLimit - input.getPosition(); + if (bytesLeft <= 0) { + return Extractor.RESULT_END_OF_INPUT; + } + + int maxBytesToRead = (int) Math.min(MAX_INPUT_SIZE - pendingBytes, bytesLeft); + int bytesAppended = trackOutput.sampleData(input, maxBytesToRead, true); if (bytesAppended != RESULT_END_OF_INPUT) { pendingBytes += bytesAppended; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeader.java index 33db6c1e6c9..c60117be607 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeader.java @@ -52,7 +52,7 @@ public WavHeader(int numChannels, int sampleRateHz, int averageBytesPerSecond, i this.encoding = encoding; } - // Setting bounds. + // Data bounds. /** * Sets the data start position and size in bytes of sample data in this WAV. @@ -65,6 +65,11 @@ public void setDataBounds(long dataStartPosition, long dataSize) { this.dataSize = dataSize; } + /** Returns the data limit, or {@link C#POSITION_UNSET} if the data bounds have not been set. */ + public long getDataLimit() { + return hasDataBounds() ? (dataStartPosition + dataSize) : C.POSITION_UNSET; + } + /** Returns whether the data start position and size have been set. */ public boolean hasDataBounds() { return dataStartPosition != 0 && dataSize != 0; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeaderReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeaderReader.java index 284b7501073..feba65ccd97 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeaderReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeaderReader.java @@ -97,13 +97,15 @@ public static WavHeader peek(ExtractorInput input) throws IOException, Interrupt } /** - * Skips to the data in the given WAV input stream and returns its data size. After calling, the - * input stream's position will point to the start of sample data in the WAV. - *

- * If an exception is thrown, the input position will be left pointing to a chunk header. + * Skips to the data in the given WAV input stream. After calling, the input stream's position + * will point to the start of sample data in the WAV, and the data bounds of the provided {@link + * WavHeader} will have been set. * - * @param input Input stream to skip to the data chunk in. Its peek position must be pointing to - * a valid chunk header. + *

If an exception is thrown, the input position will be left pointing to a chunk header and + * the bounds of the provided {@link WavHeader} will not have been set. + * + * @param input Input stream to skip to the data chunk in. Its peek position must be pointing to a + * valid chunk header. * @param wavHeader WAV header to populate with data bounds. * @throws ParserException If an error occurs parsing chunks. * @throws IOException If reading from the input fails.