mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add NonNull annotations to the most extractor packages
PiperOrigin-RevId: 285961788
This commit is contained in:
parent
f10bc37831
commit
dfc15733d2
@ -16,7 +16,6 @@
|
||||
package com.google.android.exoplayer2.extractor.amr;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
@ -28,6 +27,7 @@ import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.EOFException;
|
||||
@ -36,6 +36,9 @@ import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/**
|
||||
* Extracts data from the AMR containers format (either AMR or AMR-WB). This follows RFC-4867,
|
||||
@ -138,9 +141,9 @@ public final class AmrExtractor implements Extractor {
|
||||
private int numSamplesWithSameSize;
|
||||
private long timeOffsetUs;
|
||||
|
||||
private ExtractorOutput extractorOutput;
|
||||
private TrackOutput trackOutput;
|
||||
@Nullable private SeekMap seekMap;
|
||||
@MonotonicNonNull private ExtractorOutput extractorOutput;
|
||||
@MonotonicNonNull private TrackOutput trackOutput;
|
||||
@MonotonicNonNull private SeekMap seekMap;
|
||||
private boolean hasOutputFormat;
|
||||
|
||||
public AmrExtractor() {
|
||||
@ -171,6 +174,7 @@ public final class AmrExtractor implements Extractor {
|
||||
@Override
|
||||
public int read(ExtractorInput input, PositionHolder seekPosition)
|
||||
throws IOException, InterruptedException {
|
||||
assertInitialized();
|
||||
if (input.getPosition() == 0) {
|
||||
if (!readAmrHeader(input)) {
|
||||
throw new ParserException("Could not find AMR header.");
|
||||
@ -245,6 +249,7 @@ public final class AmrExtractor implements Extractor {
|
||||
return Arrays.equals(header, amrSignature);
|
||||
}
|
||||
|
||||
@RequiresNonNull("trackOutput")
|
||||
private void maybeOutputFormat() {
|
||||
if (!hasOutputFormat) {
|
||||
hasOutputFormat = true;
|
||||
@ -267,6 +272,7 @@ public final class AmrExtractor implements Extractor {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresNonNull("trackOutput")
|
||||
private int readSample(ExtractorInput extractorInput) throws IOException, InterruptedException {
|
||||
if (currentSampleBytesRemaining == 0) {
|
||||
try {
|
||||
@ -346,6 +352,7 @@ public final class AmrExtractor implements Extractor {
|
||||
return !isWideBand && (frameType < 12 || frameType > 14);
|
||||
}
|
||||
|
||||
@RequiresNonNull("extractorOutput")
|
||||
private void maybeOutputSeekMap(long inputLength, int sampleReadResult) {
|
||||
if (hasOutputSeekMap) {
|
||||
return;
|
||||
@ -370,6 +377,12 @@ public final class AmrExtractor implements Extractor {
|
||||
return new ConstantBitrateSeekMap(inputLength, firstSamplePosition, bitrate, firstSampleSize);
|
||||
}
|
||||
|
||||
@EnsuresNonNull({"extractorOutput", "trackOutput"})
|
||||
private void assertInitialized() {
|
||||
Assertions.checkStateNotNull(trackOutput);
|
||||
Util.castNonNull(extractorOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stream bitrate, given a frame size and the duration of that frame in microseconds.
|
||||
*
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.extractor.amr;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.extractor.flac;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -23,11 +23,14 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/**
|
||||
* Extracts data from the FLV container format.
|
||||
@ -71,7 +74,7 @@ public final class FlvExtractor implements Extractor {
|
||||
private final ParsableByteArray tagData;
|
||||
private final ScriptTagPayloadReader metadataReader;
|
||||
|
||||
private ExtractorOutput extractorOutput;
|
||||
@MonotonicNonNull private ExtractorOutput extractorOutput;
|
||||
private @States int state;
|
||||
private boolean outputFirstSample;
|
||||
private long mediaTagTimestampOffsetUs;
|
||||
@ -80,8 +83,8 @@ public final class FlvExtractor implements Extractor {
|
||||
private int tagDataSize;
|
||||
private long tagTimestampUs;
|
||||
private boolean outputSeekMap;
|
||||
private AudioTagPayloadReader audioReader;
|
||||
private VideoTagPayloadReader videoReader;
|
||||
@MonotonicNonNull private AudioTagPayloadReader audioReader;
|
||||
@MonotonicNonNull private VideoTagPayloadReader videoReader;
|
||||
|
||||
public FlvExtractor() {
|
||||
scratch = new ParsableByteArray(4);
|
||||
@ -143,6 +146,7 @@ public final class FlvExtractor implements Extractor {
|
||||
@Override
|
||||
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException,
|
||||
InterruptedException {
|
||||
Assertions.checkStateNotNull(extractorOutput); // Asserts that init has been called.
|
||||
while (true) {
|
||||
switch (state) {
|
||||
case STATE_READING_FLV_HEADER:
|
||||
@ -178,6 +182,7 @@ public final class FlvExtractor implements Extractor {
|
||||
* @throws IOException If an error occurred reading or parsing data from the source.
|
||||
* @throws InterruptedException If the thread was interrupted.
|
||||
*/
|
||||
@RequiresNonNull("extractorOutput")
|
||||
private boolean readFlvHeader(ExtractorInput input) throws IOException, InterruptedException {
|
||||
if (!input.readFully(headerBuffer.data, 0, FLV_HEADER_SIZE, true)) {
|
||||
// We've reached the end of the stream.
|
||||
@ -250,6 +255,7 @@ public final class FlvExtractor implements Extractor {
|
||||
* @throws IOException If an error occurred reading or parsing data from the source.
|
||||
* @throws InterruptedException If the thread was interrupted.
|
||||
*/
|
||||
@RequiresNonNull("extractorOutput")
|
||||
private boolean readTagData(ExtractorInput input) throws IOException, InterruptedException {
|
||||
boolean wasConsumed = true;
|
||||
boolean wasSampleOutput = false;
|
||||
@ -293,6 +299,7 @@ public final class FlvExtractor implements Extractor {
|
||||
return tagData;
|
||||
}
|
||||
|
||||
@RequiresNonNull("extractorOutput")
|
||||
private void ensureReadyForMediaOutput() {
|
||||
if (!outputSeekMap) {
|
||||
extractorOutput.seekMap(new SeekMap.Unseekable(C.TIME_UNSET));
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.extractor.flv;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.extractor.mkv;
|
||||
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
@ -26,6 +27,8 @@ import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayDeque;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link EbmlReader}.
|
||||
@ -52,7 +55,7 @@ import java.util.ArrayDeque;
|
||||
private final ArrayDeque<MasterElement> masterElementsStack;
|
||||
private final VarintReader varintReader;
|
||||
|
||||
private EbmlProcessor processor;
|
||||
@MonotonicNonNull private EbmlProcessor processor;
|
||||
private @ElementState int elementState;
|
||||
private int elementId;
|
||||
private long elementContentSize;
|
||||
@ -79,8 +82,8 @@ import java.util.ArrayDeque;
|
||||
public boolean read(ExtractorInput input) throws IOException, InterruptedException {
|
||||
Assertions.checkNotNull(processor);
|
||||
while (true) {
|
||||
if (!masterElementsStack.isEmpty()
|
||||
&& input.getPosition() >= masterElementsStack.peek().elementEndPosition) {
|
||||
MasterElement head = masterElementsStack.peek();
|
||||
if (head != null && input.getPosition() >= head.elementEndPosition) {
|
||||
processor.endMasterElement(masterElementsStack.pop().elementId);
|
||||
return true;
|
||||
}
|
||||
@ -159,8 +162,9 @@ import java.util.ArrayDeque;
|
||||
* @throws IOException If an error occurs reading from the input.
|
||||
* @throws InterruptedException If the thread is interrupted.
|
||||
*/
|
||||
private long maybeResyncToNextLevel1Element(ExtractorInput input) throws IOException,
|
||||
InterruptedException {
|
||||
@RequiresNonNull("processor")
|
||||
private long maybeResyncToNextLevel1Element(ExtractorInput input)
|
||||
throws IOException, InterruptedException {
|
||||
input.resetPeekPosition();
|
||||
while (true) {
|
||||
input.peekFully(scratch, 0, MAX_ID_BYTES);
|
||||
|
@ -57,6 +57,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/** Extracts data from the Matroska and WebM container formats. */
|
||||
public class MatroskaExtractor implements Extractor {
|
||||
@ -342,7 +344,7 @@ public class MatroskaExtractor implements Extractor {
|
||||
private long durationUs = C.TIME_UNSET;
|
||||
|
||||
// The track corresponding to the current TrackEntry element, or null.
|
||||
private Track currentTrack;
|
||||
@Nullable private Track currentTrack;
|
||||
|
||||
// Whether a seek map has been sent to the output.
|
||||
private boolean sentSeekMap;
|
||||
@ -356,8 +358,8 @@ public class MatroskaExtractor implements Extractor {
|
||||
private long cuesContentPosition = C.POSITION_UNSET;
|
||||
private long seekPositionAfterBuildingCues = C.POSITION_UNSET;
|
||||
private long clusterTimecodeUs = C.TIME_UNSET;
|
||||
private LongArray cueTimesUs;
|
||||
private LongArray cueClusterPositions;
|
||||
@Nullable private LongArray cueTimesUs;
|
||||
@Nullable private LongArray cueClusterPositions;
|
||||
private boolean seenClusterPositionForCurrentCuePoint;
|
||||
|
||||
// Reading state.
|
||||
@ -372,8 +374,7 @@ public class MatroskaExtractor implements Extractor {
|
||||
private int[] blockSampleSizes;
|
||||
private int blockTrackNumber;
|
||||
private int blockTrackNumberLength;
|
||||
@C.BufferFlags
|
||||
private int blockFlags;
|
||||
@C.BufferFlags private int blockFlags;
|
||||
private int blockAdditionalId;
|
||||
private boolean blockHasReferenceBlock;
|
||||
|
||||
@ -389,7 +390,7 @@ public class MatroskaExtractor implements Extractor {
|
||||
private boolean sampleInitializationVectorRead;
|
||||
|
||||
// Extractor outputs.
|
||||
private ExtractorOutput extractorOutput;
|
||||
@MonotonicNonNull private ExtractorOutput extractorOutput;
|
||||
|
||||
public MatroskaExtractor() {
|
||||
this(0);
|
||||
@ -415,6 +416,7 @@ public class MatroskaExtractor implements Extractor {
|
||||
encryptionInitializationVector = new ParsableByteArray(ENCRYPTION_IV_SIZE);
|
||||
encryptionSubsampleData = new ParsableByteArray();
|
||||
blockAdditionalData = new ParsableByteArray();
|
||||
blockSampleSizes = new int[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1924,7 +1926,7 @@ public class MatroskaExtractor implements Extractor {
|
||||
String mimeType;
|
||||
int maxInputSize = Format.NO_VALUE;
|
||||
@C.PcmEncoding int pcmEncoding = Format.NO_VALUE;
|
||||
List<byte[]> initializationData = null;
|
||||
@Nullable List<byte[]> initializationData = null;
|
||||
switch (codecId) {
|
||||
case CODEC_ID_VP8:
|
||||
mimeType = MimeTypes.VIDEO_VP8;
|
||||
@ -1958,7 +1960,8 @@ public class MatroskaExtractor implements Extractor {
|
||||
nalUnitLengthFieldLength = hevcConfig.nalUnitLengthFieldLength;
|
||||
break;
|
||||
case CODEC_ID_FOURCC:
|
||||
Pair<String, List<byte[]>> pair = parseFourCcPrivate(new ParsableByteArray(codecPrivate));
|
||||
Pair<String, @NullableType List<byte[]>> pair =
|
||||
parseFourCcPrivate(new ParsableByteArray(codecPrivate));
|
||||
mimeType = pair.first;
|
||||
initializationData = pair.second;
|
||||
break;
|
||||
@ -2220,8 +2223,8 @@ public class MatroskaExtractor implements Extractor {
|
||||
* is {@code null}.
|
||||
* @throws ParserException If the initialization data could not be built.
|
||||
*/
|
||||
private static Pair<String, List<byte[]>> parseFourCcPrivate(ParsableByteArray buffer)
|
||||
throws ParserException {
|
||||
private static Pair<String, @NullableType List<byte[]>> parseFourCcPrivate(
|
||||
ParsableByteArray buffer) throws ParserException {
|
||||
try {
|
||||
buffer.skipBytes(16); // size(4), width(4), height(4), planes(2), bitcount(2).
|
||||
long compression = buffer.readLittleEndianUnsignedInt();
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.extractor.mkv;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -34,12 +34,17 @@ import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.id3.Id3Decoder;
|
||||
import com.google.android.exoplayer2.metadata.id3.Id3Decoder.FramePredicate;
|
||||
import com.google.android.exoplayer2.metadata.id3.MlltFrame;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/**
|
||||
* Extracts data from the MP3 container format.
|
||||
@ -107,13 +112,13 @@ public final class Mp3Extractor implements Extractor {
|
||||
private final Id3Peeker id3Peeker;
|
||||
|
||||
// Extractor outputs.
|
||||
private ExtractorOutput extractorOutput;
|
||||
private TrackOutput trackOutput;
|
||||
@MonotonicNonNull private ExtractorOutput extractorOutput;
|
||||
@MonotonicNonNull private TrackOutput trackOutput;
|
||||
|
||||
private int synchronizedHeaderData;
|
||||
|
||||
private Metadata metadata;
|
||||
@Nullable private Seeker seeker;
|
||||
@Nullable private Metadata metadata;
|
||||
@MonotonicNonNull private Seeker seeker;
|
||||
private boolean disableSeeking;
|
||||
private long basisTimeUs;
|
||||
private long samplesRead;
|
||||
@ -176,6 +181,7 @@ public final class Mp3Extractor implements Extractor {
|
||||
@Override
|
||||
public int read(ExtractorInput input, PositionHolder seekPosition)
|
||||
throws IOException, InterruptedException {
|
||||
assertInitialized();
|
||||
if (synchronizedHeaderData == 0) {
|
||||
try {
|
||||
synchronize(input, false);
|
||||
@ -242,6 +248,7 @@ public final class Mp3Extractor implements Extractor {
|
||||
|
||||
// Internal methods.
|
||||
|
||||
@RequiresNonNull({"trackOutput", "seeker"})
|
||||
private int readSample(ExtractorInput extractorInput) throws IOException, InterruptedException {
|
||||
if (sampleBytesRemaining == 0) {
|
||||
extractorInput.resetPeekPosition();
|
||||
@ -390,6 +397,7 @@ public final class Mp3Extractor implements Extractor {
|
||||
* @throws InterruptedException Thrown if reading from the stream was interrupted. Not expected if
|
||||
* the next two frames were already peeked during synchronization.
|
||||
*/
|
||||
@Nullable
|
||||
private Seeker maybeReadSeekFrame(ExtractorInput input) throws IOException, InterruptedException {
|
||||
ParsableByteArray frame = new ParsableByteArray(synchronizedHeader.frameSize);
|
||||
input.peekFully(frame.data, 0, synchronizedHeader.frameSize);
|
||||
@ -397,7 +405,7 @@ public final class Mp3Extractor implements Extractor {
|
||||
? (synchronizedHeader.channels != 1 ? 36 : 21) // MPEG 1
|
||||
: (synchronizedHeader.channels != 1 ? 21 : 13); // MPEG 2 or 2.5
|
||||
int seekHeader = getSeekFrameHeader(frame, xingBase);
|
||||
Seeker seeker;
|
||||
@Nullable Seeker seeker;
|
||||
if (seekHeader == SEEK_HEADER_XING || seekHeader == SEEK_HEADER_INFO) {
|
||||
seeker = XingSeeker.create(input.getLength(), input.getPosition(), synchronizedHeader, frame);
|
||||
if (seeker != null && !gaplessInfoHolder.hasGaplessInfo()) {
|
||||
@ -435,6 +443,12 @@ public final class Mp3Extractor implements Extractor {
|
||||
return new ConstantBitrateSeeker(input.getLength(), input.getPosition(), synchronizedHeader);
|
||||
}
|
||||
|
||||
@EnsuresNonNull({"extractorOutput", "trackOutput"})
|
||||
private void assertInitialized() {
|
||||
Assertions.checkStateNotNull(trackOutput);
|
||||
Util.castNonNull(extractorOutput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the headers match in those bits masked by {@link #MPEG_AUDIO_HEADER_MASK}.
|
||||
*/
|
||||
@ -465,7 +479,8 @@ public final class Mp3Extractor implements Extractor {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static MlltSeeker maybeHandleSeekMetadata(Metadata metadata, long firstFramePosition) {
|
||||
private static MlltSeeker maybeHandleSeekMetadata(
|
||||
@Nullable Metadata metadata, long firstFramePosition) {
|
||||
if (metadata != null) {
|
||||
int length = metadata.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
@ -477,6 +492,4 @@ public final class Mp3Extractor implements Extractor {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -41,7 +41,8 @@ import com.google.android.exoplayer2.util.Util;
|
||||
* @return A {@link VbriSeeker} for seeking in the stream, or {@code null} if the required
|
||||
* information is not present.
|
||||
*/
|
||||
public static @Nullable VbriSeeker create(
|
||||
@Nullable
|
||||
public static VbriSeeker create(
|
||||
long inputLength, long position, MpegAudioHeader mpegAudioHeader, ParsableByteArray frame) {
|
||||
frame.skipBytes(10);
|
||||
int numFrames = frame.readInt();
|
||||
|
@ -42,7 +42,8 @@ import com.google.android.exoplayer2.util.Util;
|
||||
* @return A {@link XingSeeker} for seeking in the stream, or {@code null} if the required
|
||||
* information is not present.
|
||||
*/
|
||||
public static @Nullable XingSeeker create(
|
||||
@Nullable
|
||||
public static XingSeeker create(
|
||||
long inputLength, long position, MpegAudioHeader mpegAudioHeader, ParsableByteArray frame) {
|
||||
int samplesPerFrame = mpegAudioHeader.samplesPerFrame;
|
||||
int sampleRate = mpegAudioHeader.sampleRate;
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.extractor.mp3;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.extractor.ogg;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
@ -39,7 +40,7 @@ import java.io.IOException;
|
||||
private static final int STATE_SKIP = 3;
|
||||
private static final int STATE_IDLE = 4;
|
||||
|
||||
private final OggPageHeader pageHeader = new OggPageHeader();
|
||||
private final OggPageHeader pageHeader;
|
||||
private final long payloadStartPosition;
|
||||
private final long payloadEndPosition;
|
||||
private final StreamReader streamReader;
|
||||
@ -83,6 +84,7 @@ import java.io.IOException;
|
||||
} else {
|
||||
state = STATE_SEEK_TO_END;
|
||||
}
|
||||
pageHeader = new OggPageHeader();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -121,6 +123,7 @@ import java.io.IOException;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public OggSeekMap createSeekMap() {
|
||||
return totalGranules != 0 ? new OggSeekMap() : null;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.extractor.ogg;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.FlacFrameReader;
|
||||
import com.google.android.exoplayer2.extractor.FlacMetadataReader;
|
||||
@ -37,8 +38,8 @@ import java.util.Arrays;
|
||||
|
||||
private static final int FRAME_HEADER_SAMPLE_NUMBER_OFFSET = 4;
|
||||
|
||||
private FlacStreamMetadata streamMetadata;
|
||||
private FlacOggSeeker flacOggSeeker;
|
||||
@Nullable private FlacStreamMetadata streamMetadata;
|
||||
@Nullable private FlacOggSeeker flacOggSeeker;
|
||||
|
||||
public static boolean verifyBitstreamType(ParsableByteArray data) {
|
||||
return data.bytesLeft() >= 5 && data.readUnsignedByte() == 0x7F && // packet type
|
||||
|
@ -23,8 +23,11 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
|
||||
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.ParsableByteArray;
|
||||
import java.io.IOException;
|
||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* Extracts data from the Ogg container format.
|
||||
@ -36,8 +39,8 @@ public class OggExtractor implements Extractor {
|
||||
|
||||
private static final int MAX_VERIFICATION_BYTES = 8;
|
||||
|
||||
private ExtractorOutput output;
|
||||
private StreamReader streamReader;
|
||||
@MonotonicNonNull private ExtractorOutput output;
|
||||
@MonotonicNonNull private StreamReader streamReader;
|
||||
private boolean streamReaderInitialized;
|
||||
|
||||
@Override
|
||||
@ -69,6 +72,7 @@ public class OggExtractor implements Extractor {
|
||||
@Override
|
||||
public int read(ExtractorInput input, PositionHolder seekPosition)
|
||||
throws IOException, InterruptedException {
|
||||
Assertions.checkStateNotNull(output); // Asserts that init has been called.
|
||||
if (streamReader == null) {
|
||||
if (!sniffInternal(input)) {
|
||||
throw new ParserException("Failed to determine bitstream type");
|
||||
@ -84,6 +88,7 @@ public class OggExtractor implements Extractor {
|
||||
return streamReader.read(input, seekPosition);
|
||||
}
|
||||
|
||||
@EnsuresNonNullIf(expression = "streamReader", result = true)
|
||||
private boolean sniffInternal(ExtractorInput input) throws IOException, InterruptedException {
|
||||
OggPageHeader header = new OggPageHeader();
|
||||
if (!header.populate(input, true) || (header.type & 0x02) != 0x02) {
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.extractor.ogg;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import java.io.IOException;
|
||||
@ -27,9 +28,10 @@ import java.io.IOException;
|
||||
/* package */ interface OggSeeker {
|
||||
|
||||
/**
|
||||
* Returns a {@link SeekMap} that returns an initial estimated position for progressive seeking
|
||||
* or the final position for direct seeking. Returns null if {@link #read} has yet to return -1.
|
||||
* Returns a {@link SeekMap} that returns an initial estimated position for progressive seeking or
|
||||
* the final position for direct seeking. Returns null if {@link #read} has yet to return -1.
|
||||
*/
|
||||
@Nullable
|
||||
SeekMap createSeekMap();
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@ import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import java.io.IOException;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/** StreamReader abstract class. */
|
||||
@SuppressWarnings("UngroupedOverloads")
|
||||
@ -42,9 +43,9 @@ import java.io.IOException;
|
||||
|
||||
private final OggPacket oggPacket;
|
||||
|
||||
private TrackOutput trackOutput;
|
||||
private ExtractorOutput extractorOutput;
|
||||
private OggSeeker oggSeeker;
|
||||
@MonotonicNonNull private TrackOutput trackOutput;
|
||||
@MonotonicNonNull private ExtractorOutput extractorOutput;
|
||||
@MonotonicNonNull private OggSeeker oggSeeker;
|
||||
private long targetGranule;
|
||||
private long payloadStartPosition;
|
||||
private long currentGranule;
|
||||
|
@ -88,7 +88,7 @@ import java.util.ArrayList;
|
||||
|
||||
@Override
|
||||
protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData)
|
||||
throws IOException, InterruptedException {
|
||||
throws IOException {
|
||||
if (vorbisSetup != null) {
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.extractor.ogg;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -24,8 +24,11 @@ import com.google.android.exoplayer2.extractor.ExtractorOutput;
|
||||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.ParsableByteArray;
|
||||
import java.io.IOException;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/**
|
||||
* Extracts data from the RawCC container format.
|
||||
@ -44,11 +47,9 @@ public final class RawCcExtractor implements Extractor {
|
||||
private static final int STATE_READING_SAMPLES = 2;
|
||||
|
||||
private final Format format;
|
||||
|
||||
private final ParsableByteArray dataScratch;
|
||||
|
||||
private TrackOutput trackOutput;
|
||||
|
||||
@MonotonicNonNull private TrackOutput trackOutput;
|
||||
private int parserState;
|
||||
private int version;
|
||||
private long timestampUs;
|
||||
@ -79,6 +80,7 @@ public final class RawCcExtractor implements Extractor {
|
||||
@Override
|
||||
public int read(ExtractorInput input, PositionHolder seekPosition)
|
||||
throws IOException, InterruptedException {
|
||||
Assertions.checkStateNotNull(trackOutput); // Asserts that init has been called.
|
||||
while (true) {
|
||||
switch (parserState) {
|
||||
case STATE_READING_HEADER:
|
||||
@ -153,6 +155,7 @@ public final class RawCcExtractor implements Extractor {
|
||||
return true;
|
||||
}
|
||||
|
||||
@RequiresNonNull("trackOutput")
|
||||
private void parseSamples(ExtractorInput input) throws IOException, InterruptedException {
|
||||
for (; remainingSampleCount > 0; remainingSampleCount--) {
|
||||
dataScratch.reset();
|
||||
@ -166,5 +169,4 @@ public final class RawCcExtractor implements Extractor {
|
||||
trackOutput.sampleMetadata(timestampUs, C.BUFFER_FLAG_KEY_FRAME, sampleBytesWritten, 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.extractor.rawcc;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@NonNullApi
|
||||
package com.google.android.exoplayer2.extractor.wav;
|
||||
|
||||
import com.google.android.exoplayer2.util.NonNullApi;
|
Loading…
x
Reference in New Issue
Block a user