From 1f202f0aee198fe9fae4290a5707f497e2ce7ac0 Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Thu, 12 Mar 2020 11:47:47 +0000 Subject: [PATCH] Make DataSource extend DataReader and upcast uses This means DataSource.read now may throw InterruptedException. PiperOrigin-RevId: 300523430 --- .../exoplayer2/upstream/DataReader.java | 5 +++ .../exoplayer2/upstream/DataSource.java | 24 ++----------- .../source/BundledExtractorsAdapter.java | 10 +++--- .../source/ProgressiveMediaExtractor.java | 10 +++--- .../source/ProgressiveMediaPeriod.java | 3 +- .../extractor/DefaultExtractorInput.java | 34 +++++++++---------- 6 files changed, 37 insertions(+), 49 deletions(-) diff --git a/library/common/src/main/java/com/google/android/exoplayer2/upstream/DataReader.java b/library/common/src/main/java/com/google/android/exoplayer2/upstream/DataReader.java index d3971171ea..eeddc9984e 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/upstream/DataReader.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/upstream/DataReader.java @@ -23,6 +23,11 @@ public interface DataReader { /** * Reads up to {@code length} bytes of data from the input. * + *

If {@code readLength} is zero then 0 is returned. Otherwise, if no data is available because + * the end of the opened range has been reached, then {@link C#RESULT_END_OF_INPUT} is returned. + * Otherwise, the call will block until at least one byte of data has been read and the number of + * bytes read is returned. + * * @param target A target array into which data should be written. * @param offset The offset into the target array at which to write. * @param length The maximum number of bytes to read from the input. diff --git a/library/common/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java b/library/common/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java index 204b9d4d66..9a321fbdd8 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/upstream/DataSource.java @@ -23,10 +23,8 @@ import java.util.Collections; import java.util.List; import java.util.Map; -/** - * A component from which streams of data can be read. - */ -public interface DataSource { +/** Reads data from URI-identified resources. */ +public interface DataSource extends DataReader { /** * A factory for {@link DataSource} instances. @@ -63,24 +61,6 @@ public interface DataSource { */ long open(DataSpec dataSpec) throws IOException; - /** - * Reads up to {@code readLength} bytes of data and stores them into {@code buffer}, starting at - * index {@code offset}. - * - *

If {@code readLength} is zero then 0 is returned. Otherwise, if no data is available because - * the end of the opened range has been reached, then {@link C#RESULT_END_OF_INPUT} is returned. - * Otherwise, the call will block until at least one byte of data has been read and the number of - * bytes read is returned. - * - * @param buffer The buffer into which the read data should be stored. - * @param offset The start offset into {@code buffer} at which data should be written. - * @param readLength The maximum number of bytes to read. - * @return The number of bytes read, or {@link C#RESULT_END_OF_INPUT} if no data is available - * because the end of the opened range has been reached. - * @throws IOException If an error occurs reading from the source. - */ - int read(byte[] buffer, int offset, int readLength) throws IOException; - /** * When the source is open, returns the {@link Uri} from which data is being read. The returned * {@link Uri} will be identical to the one passed {@link #open(DataSpec)} in the {@link DataSpec} diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/BundledExtractorsAdapter.java b/library/core/src/main/java/com/google/android/exoplayer2/source/BundledExtractorsAdapter.java index e13d5edb34..f8764585aa 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/BundledExtractorsAdapter.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/BundledExtractorsAdapter.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.source; +import android.net.Uri; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.extractor.DefaultExtractorInput; @@ -23,7 +24,7 @@ import com.google.android.exoplayer2.extractor.ExtractorInput; import com.google.android.exoplayer2.extractor.ExtractorOutput; import com.google.android.exoplayer2.extractor.PositionHolder; import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor; -import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DataReader; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Util; import java.io.EOFException; @@ -50,9 +51,10 @@ import java.io.IOException; } @Override - public void init(DataSource dataSource, long position, long length, ExtractorOutput output) + public void init( + DataReader dataReader, Uri uri, long position, long length, ExtractorOutput output) throws IOException { - extractorInput = new DefaultExtractorInput(dataSource, position, length); + extractorInput = new DefaultExtractorInput(dataReader, position, length); if (extractor != null) { return; } @@ -76,7 +78,7 @@ import java.io.IOException; "None of the available extractors (" + Util.getCommaDelimitedSimpleClassNames(extractors) + ") could read the stream.", - Assertions.checkNotNull(dataSource.getUri())); + Assertions.checkNotNull(uri)); } } extractor.init(output); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaExtractor.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaExtractor.java index 7e7d4e4d8d..6cc7c91232 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaExtractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaExtractor.java @@ -15,11 +15,12 @@ */ package com.google.android.exoplayer2.source; +import android.net.Uri; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.extractor.Extractor; import com.google.android.exoplayer2.extractor.ExtractorOutput; import com.google.android.exoplayer2.extractor.PositionHolder; -import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DataReader; import java.io.IOException; /** Extracts the contents of a container file from a progressive media stream. */ @@ -28,15 +29,16 @@ import java.io.IOException; /** * Initializes the underlying infrastructure for reading from the input. * - * @param dataSource The {@link DataSource} from which data should be read. - * @param position The initial position of the {@code dataSource} in the stream. + * @param dataReader The {@link DataReader} from which data should be read. + * @param uri The {@link Uri} from which the media is obtained. + * @param position The initial position of the {@code dataReader} in the stream. * @param length The length of the stream, or {@link C#LENGTH_UNSET} if length is unknown. * @param output The {@link ExtractorOutput} that will be used to initialize the selected * extractor. * @throws UnrecognizedInputFormatException Thrown if the input format could not be detected. * @throws IOException Thrown if the input could not be read. */ - void init(DataSource dataSource, long position, long length, ExtractorOutput output) + void init(DataReader dataReader, Uri uri, long position, long length, ExtractorOutput output) throws IOException; /** Releases any held resources. */ diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java index 9c60280dd4..e88112a74f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ProgressiveMediaPeriod.java @@ -976,7 +976,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; icyTrackOutput = icyTrack(); icyTrackOutput.format(ICY_FORMAT); } - progressiveMediaExtractor.init(extractorDataSource, position, length, extractorOutput); + progressiveMediaExtractor.init( + extractorDataSource, uri, position, length, extractorOutput); if (icyHeaders != null) { progressiveMediaExtractor.disableSeekingOnMp3Streams(); diff --git a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorInput.java b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorInput.java index 4979854d4c..4ab306a234 100644 --- a/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorInput.java +++ b/library/extractor/src/main/java/com/google/android/exoplayer2/extractor/DefaultExtractorInput.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer2.extractor; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DataReader; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Util; import java.io.EOFException; @@ -24,9 +24,7 @@ import java.io.IOException; import java.io.InterruptedIOException; import java.util.Arrays; -/** - * An {@link ExtractorInput} that wraps a {@link DataSource}. - */ +/** An {@link ExtractorInput} that wraps a {@link DataReader}. */ public final class DefaultExtractorInput implements ExtractorInput { private static final int PEEK_MIN_FREE_SPACE_AFTER_RESIZE = 64 * 1024; @@ -34,7 +32,7 @@ public final class DefaultExtractorInput implements ExtractorInput { private static final int SCRATCH_SPACE_SIZE = 4096; private final byte[] scratchSpace; - private final DataSource dataSource; + private final DataReader dataReader; private final long streamLength; private long position; @@ -43,12 +41,12 @@ public final class DefaultExtractorInput implements ExtractorInput { private int peekBufferLength; /** - * @param dataSource The wrapped {@link DataSource}. + * @param dataReader The wrapped {@link DataReader}. * @param position The initial position in the stream. * @param length The length of the stream, or {@link C#LENGTH_UNSET} if it is unknown. */ - public DefaultExtractorInput(DataSource dataSource, long position, long length) { - this.dataSource = dataSource; + public DefaultExtractorInput(DataReader dataReader, long position, long length) { + this.dataReader = dataReader; this.position = position; this.streamLength = length; peekBuffer = new byte[PEEK_MIN_FREE_SPACE_AFTER_RESIZE]; @@ -60,7 +58,7 @@ public final class DefaultExtractorInput implements ExtractorInput { int bytesRead = readFromPeekBuffer(target, offset, length); if (bytesRead == 0) { bytesRead = - readFromDataSource( + readFromUpstream( target, offset, length, /* bytesAlreadyRead= */ 0, /* allowEndOfInput= */ true); } commitBytesRead(bytesRead); @@ -72,7 +70,7 @@ public final class DefaultExtractorInput implements ExtractorInput { throws IOException { int bytesRead = readFromPeekBuffer(target, offset, length); while (bytesRead < length && bytesRead != C.RESULT_END_OF_INPUT) { - bytesRead = readFromDataSource(target, offset, length, bytesRead, allowEndOfInput); + bytesRead = readFromUpstream(target, offset, length, bytesRead, allowEndOfInput); } commitBytesRead(bytesRead); return bytesRead != C.RESULT_END_OF_INPUT; @@ -88,7 +86,7 @@ public final class DefaultExtractorInput implements ExtractorInput { int bytesSkipped = skipFromPeekBuffer(length); if (bytesSkipped == 0) { bytesSkipped = - readFromDataSource(scratchSpace, 0, Math.min(length, scratchSpace.length), 0, true); + readFromUpstream(scratchSpace, 0, Math.min(length, scratchSpace.length), 0, true); } commitBytesRead(bytesSkipped); return bytesSkipped; @@ -100,7 +98,7 @@ public final class DefaultExtractorInput implements ExtractorInput { while (bytesSkipped < length && bytesSkipped != C.RESULT_END_OF_INPUT) { int minLength = Math.min(length, bytesSkipped + scratchSpace.length); bytesSkipped = - readFromDataSource(scratchSpace, -bytesSkipped, minLength, bytesSkipped, allowEndOfInput); + readFromUpstream(scratchSpace, -bytesSkipped, minLength, bytesSkipped, allowEndOfInput); } commitBytesRead(bytesSkipped); return bytesSkipped != C.RESULT_END_OF_INPUT; @@ -118,7 +116,7 @@ public final class DefaultExtractorInput implements ExtractorInput { int bytesPeeked; if (peekBufferRemainingBytes == 0) { bytesPeeked = - readFromDataSource( + readFromUpstream( peekBuffer, peekBufferPosition, length, @@ -156,8 +154,8 @@ public final class DefaultExtractorInput implements ExtractorInput { ensureSpaceForPeek(length); int bytesPeeked = peekBufferLength - peekBufferPosition; while (bytesPeeked < length) { - bytesPeeked = readFromDataSource(peekBuffer, peekBufferPosition, length, bytesPeeked, - allowEndOfInput); + bytesPeeked = + readFromUpstream(peekBuffer, peekBufferPosition, length, bytesPeeked, allowEndOfInput); if (bytesPeeked == C.RESULT_END_OF_INPUT) { return false; } @@ -259,7 +257,7 @@ public final class DefaultExtractorInput implements ExtractorInput { } /** - * Starts or continues a read from the data source. + * Starts or continues a read from the data reader. * * @param target A target array into which data should be written. * @param offset The offset into the target array at which to write. @@ -275,13 +273,13 @@ public final class DefaultExtractorInput implements ExtractorInput { * read and {@code allowEndOfInput} is false. * @throws IOException If an error occurs reading from the input. */ - private int readFromDataSource( + private int readFromUpstream( byte[] target, int offset, int length, int bytesAlreadyRead, boolean allowEndOfInput) throws IOException { if (Thread.interrupted()) { throw new InterruptedIOException(); } - int bytesRead = dataSource.read(target, offset + bytesAlreadyRead, length - bytesAlreadyRead); + int bytesRead = dataReader.read(target, offset + bytesAlreadyRead, length - bytesAlreadyRead); if (bytesRead == C.RESULT_END_OF_INPUT) { if (bytesAlreadyRead == 0 && allowEndOfInput) { return C.RESULT_END_OF_INPUT;