Some nullness cleanup for extractor.ogg

PiperOrigin-RevId: 286203692
This commit is contained in:
olly 2019-12-18 17:08:04 +00:00 committed by Oliver Woodman
parent e8068f0fcb
commit 8b0f5b0a86
4 changed files with 55 additions and 24 deletions

View File

@ -24,9 +24,9 @@ import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.FlacConstants; import com.google.android.exoplayer2.util.FlacConstants;
import com.google.android.exoplayer2.util.FlacStreamMetadata; import com.google.android.exoplayer2.util.FlacStreamMetadata;
import com.google.android.exoplayer2.util.FlacStreamMetadata.SeekTable;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
/** /**
@ -70,15 +70,17 @@ import java.util.Arrays;
@Override @Override
protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData) { protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData) {
byte[] data = packet.data; byte[] data = packet.data;
@Nullable FlacStreamMetadata streamMetadata = this.streamMetadata;
if (streamMetadata == null) { if (streamMetadata == null) {
streamMetadata = new FlacStreamMetadata(data, 17); streamMetadata = new FlacStreamMetadata(data, 17);
this.streamMetadata = streamMetadata;
byte[] metadata = Arrays.copyOfRange(data, 9, packet.limit()); byte[] metadata = Arrays.copyOfRange(data, 9, packet.limit());
setupData.format = streamMetadata.getFormat(metadata, /* id3Metadata= */ null); setupData.format = streamMetadata.getFormat(metadata, /* id3Metadata= */ null);
} else if ((data[0] & 0x7F) == FlacConstants.METADATA_TYPE_SEEK_TABLE) { } else if ((data[0] & 0x7F) == FlacConstants.METADATA_TYPE_SEEK_TABLE) {
flacOggSeeker = new FlacOggSeeker(); SeekTable seekTable = FlacMetadataReader.readSeekTableMetadataBlock(packet);
FlacStreamMetadata.SeekTable seekTable =
FlacMetadataReader.readSeekTableMetadataBlock(packet);
streamMetadata = streamMetadata.copyWithSeekTable(seekTable); streamMetadata = streamMetadata.copyWithSeekTable(seekTable);
this.streamMetadata = streamMetadata;
flacOggSeeker = new FlacOggSeeker(streamMetadata, seekTable);
} else if (isAudioPacket(data)) { } else if (isAudioPacket(data)) {
if (flacOggSeeker != null) { if (flacOggSeeker != null) {
flacOggSeeker.setFirstFrameOffset(position); flacOggSeeker.setFirstFrameOffset(position);
@ -101,12 +103,16 @@ import java.util.Arrays;
return result; return result;
} }
private class FlacOggSeeker implements OggSeeker { private static final class FlacOggSeeker implements OggSeeker {
private FlacStreamMetadata streamMetadata;
private SeekTable seekTable;
private long firstFrameOffset; private long firstFrameOffset;
private long pendingSeekGranule; private long pendingSeekGranule;
public FlacOggSeeker() { public FlacOggSeeker(FlacStreamMetadata streamMetadata, SeekTable seekTable) {
this.streamMetadata = streamMetadata;
this.seekTable = seekTable;
firstFrameOffset = -1; firstFrameOffset = -1;
pendingSeekGranule = -1; pendingSeekGranule = -1;
} }
@ -116,7 +122,7 @@ import java.util.Arrays;
} }
@Override @Override
public long read(ExtractorInput input) throws IOException, InterruptedException { public long read(ExtractorInput input) {
if (pendingSeekGranule >= 0) { if (pendingSeekGranule >= 0) {
long result = -(pendingSeekGranule + 2); long result = -(pendingSeekGranule + 2);
pendingSeekGranule = -1; pendingSeekGranule = -1;
@ -127,9 +133,10 @@ import java.util.Arrays;
@Override @Override
public void startSeek(long targetGranule) { public void startSeek(long targetGranule) {
Assertions.checkNotNull(streamMetadata.seekTable); long[] seekPointGranules = seekTable.pointSampleNumbers;
long[] seekPointGranules = streamMetadata.seekTable.pointSampleNumbers; int index =
int index = Util.binarySearchFloor(seekPointGranules, targetGranule, true, true); Util.binarySearchFloor(
seekPointGranules, targetGranule, /* inclusive= */ true, /* stayInBounds= */ true);
pendingSeekGranule = seekPointGranules[index]; pendingSeekGranule = seekPointGranules[index];
} }

View File

@ -76,9 +76,19 @@ import java.util.List;
putNativeOrderLong(initializationData, preskip); putNativeOrderLong(initializationData, preskip);
putNativeOrderLong(initializationData, DEFAULT_SEEK_PRE_ROLL_SAMPLES); putNativeOrderLong(initializationData, DEFAULT_SEEK_PRE_ROLL_SAMPLES);
setupData.format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_OPUS, null, setupData.format =
Format.NO_VALUE, Format.NO_VALUE, channelCount, SAMPLE_RATE, initializationData, null, 0, Format.createAudioSampleFormat(
null); null,
MimeTypes.AUDIO_OPUS,
/* codecs= */ null,
Format.NO_VALUE,
Format.NO_VALUE,
channelCount,
SAMPLE_RATE,
initializationData,
/* drmInitData= */ null,
/* selectionFlags= */ 0,
/* language= */ null);
headerRead = true; headerRead = true;
} else { } else {
boolean headerPacket = packet.readInt() == OPUS_CODE; boolean headerPacket = packet.readInt() == OPUS_CODE;

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.extractor.ogg; package com.google.android.exoplayer2.extractor.ogg;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.Extractor;
@ -23,6 +24,7 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.PositionHolder; import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap; import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.extractor.TrackOutput; import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.ParsableByteArray; import com.google.android.exoplayer2.util.ParsableByteArray;
import java.io.IOException; import java.io.IOException;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -51,7 +53,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private long currentGranule; private long currentGranule;
private int state; private int state;
private int sampleRate; private int sampleRate;
private SetupData setupData; @Nullable private SetupData setupData;
private long lengthOfReadPacket; private long lengthOfReadPacket;
private boolean seekMapSet; private boolean seekMapSet;
private boolean formatSet; private boolean formatSet;
@ -149,7 +151,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
boolean isLastPage = (firstPayloadPageHeader.type & 0x04) != 0; // Type 4 is end of stream. boolean isLastPage = (firstPayloadPageHeader.type & 0x04) != 0; // Type 4 is end of stream.
oggSeeker = oggSeeker =
new DefaultOggSeeker( new DefaultOggSeeker(
this, /* streamReader= */ this,
payloadStartPosition, payloadStartPosition,
input.getLength(), input.getLength(),
firstPayloadPageHeader.headerSize + firstPayloadPageHeader.bodySize, firstPayloadPageHeader.headerSize + firstPayloadPageHeader.bodySize,
@ -173,8 +175,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} else if (position < -1) { } else if (position < -1) {
onSeekEnd(-(position + 2)); onSeekEnd(-(position + 2));
} }
if (!seekMapSet) { if (!seekMapSet) {
SeekMap seekMap = oggSeeker.createSeekMap(); SeekMap seekMap = Assertions.checkNotNull(oggSeeker.createSeekMap());
extractorOutput.seekMap(seekMap); extractorOutput.seekMap(seekMap);
seekMapSet = true; seekMapSet = true;
} }

View File

@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.extractor.ogg; package com.google.android.exoplayer2.extractor.ogg;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.ParserException;
@ -30,16 +31,16 @@ import java.util.ArrayList;
*/ */
/* package */ final class VorbisReader extends StreamReader { /* package */ final class VorbisReader extends StreamReader {
private VorbisSetup vorbisSetup; @Nullable private VorbisSetup vorbisSetup;
private int previousPacketBlockSize; private int previousPacketBlockSize;
private boolean seenFirstAudioPacket; private boolean seenFirstAudioPacket;
private VorbisUtil.VorbisIdHeader vorbisIdHeader; @Nullable private VorbisUtil.VorbisIdHeader vorbisIdHeader;
private VorbisUtil.CommentHeader commentHeader; @Nullable private VorbisUtil.CommentHeader commentHeader;
public static boolean verifyBitstreamType(ParsableByteArray data) { public static boolean verifyBitstreamType(ParsableByteArray data) {
try { try {
return VorbisUtil.verifyVorbisHeaderCapturePattern(0x01, data, true); return VorbisUtil.verifyVorbisHeaderCapturePattern(/* headerType= */ 0x01, data, true);
} catch (ParserException e) { } catch (ParserException e) {
return false; return false;
} }
@ -102,14 +103,24 @@ import java.util.ArrayList;
codecInitialisationData.add(vorbisSetup.idHeader.data); codecInitialisationData.add(vorbisSetup.idHeader.data);
codecInitialisationData.add(vorbisSetup.setupHeaderData); codecInitialisationData.add(vorbisSetup.setupHeaderData);
setupData.format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_VORBIS, null, setupData.format =
this.vorbisSetup.idHeader.bitrateNominal, Format.NO_VALUE, Format.createAudioSampleFormat(
this.vorbisSetup.idHeader.channels, (int) this.vorbisSetup.idHeader.sampleRate, null,
codecInitialisationData, null, 0, null); MimeTypes.AUDIO_VORBIS,
/* codecs= */ null,
this.vorbisSetup.idHeader.bitrateNominal,
Format.NO_VALUE,
this.vorbisSetup.idHeader.channels,
(int) this.vorbisSetup.idHeader.sampleRate,
codecInitialisationData,
null,
/* selectionFlags= */ 0,
/* language= */ null);
return true; return true;
} }
@VisibleForTesting @VisibleForTesting
@Nullable
/* package */ VorbisSetup readSetupHeaders(ParsableByteArray scratch) throws IOException { /* package */ VorbisSetup readSetupHeaders(ParsableByteArray scratch) throws IOException {
if (vorbisIdHeader == null) { if (vorbisIdHeader == null) {