Skip to content

Commit

Permalink
Allow AdtsExtractor to encounter EOF
Browse files Browse the repository at this point in the history
Fixes issue:#6700

sample_cbs_truncated.adts test file produced using
`$ split -b 31795 sample_truncated.adts` to remove the last 10 bytes

PiperOrigin-RevId: 283530136
  • Loading branch information
icbaker authored and ojw28 committed Dec 6, 2019
1 parent 668e8b1 commit a6098bb
Show file tree
Hide file tree
Showing 9 changed files with 2,029 additions and 28 deletions.
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@
([#5782](https://github.com/google/ExoPlayer/issues/5782)).
* Reconfigure audio sink when PCM encoding changes
([#6601](https://github.com/google/ExoPlayer/issues/6601)).
* Allow `AdtsExtractor` to encounter EoF when calculating average frame size
([#6700](https://github.com/google/ExoPlayer/issues/6700)).
* UI:
* Make showing and hiding player controls accessible to TalkBack in
`PlayerView`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.ParsableBitArray;
import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.EOFException;
import java.io.IOException;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
Expand Down Expand Up @@ -218,7 +219,7 @@ private int peekId3Header(ExtractorInput input) throws IOException, InterruptedE
}
scratch.skipBytes(3);
int length = scratch.readSynchSafeInt();
firstFramePosition += 10 + length;
firstFramePosition += ID3_HEADER_LENGTH + length;
input.advancePeekPosition(length);
}
input.resetPeekPosition();
Expand Down Expand Up @@ -266,36 +267,43 @@ private void calculateAverageFrameSize(ExtractorInput input)

int numValidFrames = 0;
long totalValidFramesSize = 0;
while (input.peekFully(
scratch.data, /* offset= */ 0, /* length= */ 2, /* allowEndOfInput= */ true)) {
scratch.setPosition(0);
int syncBytes = scratch.readUnsignedShort();
if (!AdtsReader.isAdtsSyncWord(syncBytes)) {
// Invalid sync byte pattern.
// Constant bit-rate seeking will probably fail for this stream.
numValidFrames = 0;
break;
} else {
// Read the frame size.
if (!input.peekFully(
scratch.data, /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true)) {
break;
}
scratchBits.setPosition(14);
int currentFrameSize = scratchBits.readBits(13);
// Either the stream is malformed OR we're not parsing an ADTS stream.
if (currentFrameSize <= 6) {
hasCalculatedAverageFrameSize = true;
throw new ParserException("Malformed ADTS stream");
}
totalValidFramesSize += currentFrameSize;
if (++numValidFrames == NUM_FRAMES_FOR_AVERAGE_FRAME_SIZE) {
break;
}
if (!input.advancePeekPosition(currentFrameSize - 6, /* allowEndOfInput= */ true)) {
try {
while (input.peekFully(
scratch.data, /* offset= */ 0, /* length= */ 2, /* allowEndOfInput= */ true)) {
scratch.setPosition(0);
int syncBytes = scratch.readUnsignedShort();
if (!AdtsReader.isAdtsSyncWord(syncBytes)) {
// Invalid sync byte pattern.
// Constant bit-rate seeking will probably fail for this stream.
numValidFrames = 0;
break;
} else {
// Read the frame size.
if (!input.peekFully(
scratch.data, /* offset= */ 0, /* length= */ 4, /* allowEndOfInput= */ true)) {
break;
}
scratchBits.setPosition(14);
int currentFrameSize = scratchBits.readBits(13);
// Either the stream is malformed OR we're not parsing an ADTS stream.
if (currentFrameSize <= 6) {
hasCalculatedAverageFrameSize = true;
throw new ParserException("Malformed ADTS stream");
}
totalValidFramesSize += currentFrameSize;
if (++numValidFrames == NUM_FRAMES_FOR_AVERAGE_FRAME_SIZE) {
break;
}
if (!input.advancePeekPosition(currentFrameSize - 6, /* allowEndOfInput= */ true)) {
break;
}
}
}
} catch (EOFException e) {
// We reached the end of the input during a peekFully() or advancePeekPosition() operation.
// This is OK, it just means the input has an incomplete ADTS frame at the end. Ideally
// ExtractorInput would these operations to encounter end-of-input without throwing an
// exception [internal: b/145586657].
}
input.resetPeekPosition();
if (numValidFrames > 0) {
Expand Down
Binary file not shown.
Loading

0 comments on commit a6098bb

Please sign in to comment.