Commit f5e92134 by olly Committed by Oliver Woodman

Shorten data length if it exceeds length of input

Issue: #6241
PiperOrigin-RevId: 261126968
parent 6d20a5cf
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
tags instead of 3-letter ISO 639-2 language tags. tags instead of 3-letter ISO 639-2 language tags.
* Ensure the `SilenceMediaSource` position is in range * Ensure the `SilenceMediaSource` position is in range
([#6229](https://github.com/google/ExoPlayer/issues/6229)). ([#6229](https://github.com/google/ExoPlayer/issues/6229)).
* Calculate correct duration for clipped WAV streams
([#6241](https://github.com/google/ExoPlayer/issues/6241)).
* Fix issue where initial seek positions get ignored when playing a preroll ad * Fix issue where initial seek positions get ignored when playing a preroll ad
([#6201](https://github.com/google/ExoPlayer/issues/6201)). ([#6201](https://github.com/google/ExoPlayer/issues/6201)).
* Fix issue where invalid language tags were normalized to "und" instead of * Fix issue where invalid language tags were normalized to "und" instead of
......
...@@ -91,10 +91,10 @@ public final class WavExtractor implements Extractor { ...@@ -91,10 +91,10 @@ public final class WavExtractor implements Extractor {
input.skipFully(wavHeader.getDataStartPosition()); input.skipFully(wavHeader.getDataStartPosition());
} }
long dataLimit = wavHeader.getDataLimit(); long dataEndPosition = wavHeader.getDataEndPosition();
Assertions.checkState(dataLimit != C.POSITION_UNSET); Assertions.checkState(dataEndPosition != C.POSITION_UNSET);
long bytesLeft = dataLimit - input.getPosition(); long bytesLeft = dataEndPosition - input.getPosition();
if (bytesLeft <= 0) { if (bytesLeft <= 0) {
return Extractor.RESULT_END_OF_INPUT; return Extractor.RESULT_END_OF_INPUT;
} }
......
...@@ -33,17 +33,21 @@ import com.google.android.exoplayer2.util.Util; ...@@ -33,17 +33,21 @@ import com.google.android.exoplayer2.util.Util;
private final int blockAlignment; private final int blockAlignment;
/** Bits per sample for the audio data. */ /** Bits per sample for the audio data. */
private final int bitsPerSample; private final int bitsPerSample;
/** The PCM encoding */ /** The PCM encoding. */
@C.PcmEncoding @C.PcmEncoding private final int encoding;
private final int encoding;
/** Position of the start of the sample data, in bytes. */ /** Position of the start of the sample data, in bytes. */
private int dataStartPosition; private int dataStartPosition;
/** Total size of the sample data, in bytes. */ /** Position of the end of the sample data (exclusive), in bytes. */
private long dataSize; private long dataEndPosition;
public WavHeader(int numChannels, int sampleRateHz, int averageBytesPerSecond, int blockAlignment, public WavHeader(
int bitsPerSample, @C.PcmEncoding int encoding) { int numChannels,
int sampleRateHz,
int averageBytesPerSecond,
int blockAlignment,
int bitsPerSample,
@C.PcmEncoding int encoding) {
this.numChannels = numChannels; this.numChannels = numChannels;
this.sampleRateHz = sampleRateHz; this.sampleRateHz = sampleRateHz;
this.averageBytesPerSecond = averageBytesPerSecond; this.averageBytesPerSecond = averageBytesPerSecond;
...@@ -51,6 +55,7 @@ import com.google.android.exoplayer2.util.Util; ...@@ -51,6 +55,7 @@ import com.google.android.exoplayer2.util.Util;
this.bitsPerSample = bitsPerSample; this.bitsPerSample = bitsPerSample;
this.encoding = encoding; this.encoding = encoding;
dataStartPosition = C.POSITION_UNSET; dataStartPosition = C.POSITION_UNSET;
dataEndPosition = C.POSITION_UNSET;
} }
// Data bounds. // Data bounds.
...@@ -59,11 +64,11 @@ import com.google.android.exoplayer2.util.Util; ...@@ -59,11 +64,11 @@ import com.google.android.exoplayer2.util.Util;
* Sets the data start position and size in bytes of sample data in this WAV. * Sets the data start position and size in bytes of sample data in this WAV.
* *
* @param dataStartPosition The position of the start of the sample data, in bytes. * @param dataStartPosition The position of the start of the sample data, in bytes.
* @param dataSize The total size of the sample data, in bytes. * @param dataEndPosition The position of the end of the sample data (exclusive), in bytes.
*/ */
public void setDataBounds(int dataStartPosition, long dataSize) { public void setDataBounds(int dataStartPosition, long dataEndPosition) {
this.dataStartPosition = dataStartPosition; this.dataStartPosition = dataStartPosition;
this.dataSize = dataSize; this.dataEndPosition = dataEndPosition;
} }
/** /**
...@@ -75,11 +80,11 @@ import com.google.android.exoplayer2.util.Util; ...@@ -75,11 +80,11 @@ import com.google.android.exoplayer2.util.Util;
} }
/** /**
* Returns the limit of the sample data, in bytes, or {@link C#POSITION_UNSET} if the data bounds * Returns the position of the end of the sample data (exclusive), in bytes, or {@link
* have not been set. * C#POSITION_UNSET} if the data bounds have not been set.
*/ */
public long getDataLimit() { public long getDataEndPosition() {
return hasDataBounds() ? (dataStartPosition + dataSize) : C.POSITION_UNSET; return dataEndPosition;
} }
/** Returns whether the data start position and size have been set. */ /** Returns whether the data start position and size have been set. */
...@@ -96,12 +101,13 @@ import com.google.android.exoplayer2.util.Util; ...@@ -96,12 +101,13 @@ import com.google.android.exoplayer2.util.Util;
@Override @Override
public long getDurationUs() { public long getDurationUs() {
long numFrames = dataSize / blockAlignment; long numFrames = (dataEndPosition - dataStartPosition) / blockAlignment;
return (numFrames * C.MICROS_PER_SECOND) / sampleRateHz; return (numFrames * C.MICROS_PER_SECOND) / sampleRateHz;
} }
@Override @Override
public SeekPoints getSeekPoints(long timeUs) { public SeekPoints getSeekPoints(long timeUs) {
long dataSize = dataEndPosition - dataStartPosition;
long positionOffset = (timeUs * averageBytesPerSecond) / C.MICROS_PER_SECOND; long positionOffset = (timeUs * averageBytesPerSecond) / C.MICROS_PER_SECOND;
// Constrain to nearest preceding frame offset. // Constrain to nearest preceding frame offset.
positionOffset = (positionOffset / blockAlignment) * blockAlignment; positionOffset = (positionOffset / blockAlignment) * blockAlignment;
......
...@@ -91,8 +91,8 @@ import java.io.IOException; ...@@ -91,8 +91,8 @@ import java.io.IOException;
// If present, skip extensionSize, validBitsPerSample, channelMask, subFormatGuid, ... // If present, skip extensionSize, validBitsPerSample, channelMask, subFormatGuid, ...
input.advancePeekPosition((int) chunkHeader.size - 16); input.advancePeekPosition((int) chunkHeader.size - 16);
return new WavHeader(numChannels, sampleRateHz, averageBytesPerSecond, blockAlignment, return new WavHeader(
bitsPerSample, encoding); numChannels, sampleRateHz, averageBytesPerSecond, blockAlignment, bitsPerSample, encoding);
} }
/** /**
...@@ -139,7 +139,14 @@ import java.io.IOException; ...@@ -139,7 +139,14 @@ import java.io.IOException;
// Skip past the "data" header. // Skip past the "data" header.
input.skipFully(ChunkHeader.SIZE_IN_BYTES); input.skipFully(ChunkHeader.SIZE_IN_BYTES);
wavHeader.setDataBounds((int) input.getPosition(), chunkHeader.size); int dataStartPosition = (int) input.getPosition();
long dataEndPosition = dataStartPosition + chunkHeader.size;
long inputLength = input.getLength();
if (inputLength != C.LENGTH_UNSET && dataEndPosition > inputLength) {
Log.w(TAG, "Data exceeds input length: " + dataEndPosition + ", " + inputLength);
dataEndPosition = inputLength;
}
wavHeader.setDataBounds(dataStartPosition, dataEndPosition);
} }
private WavHeaderReader() { private WavHeaderReader() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment