diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/DefaultCastOptionsProvider.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/DefaultCastOptionsProvider.java index 8948173f60..ebadb0a08a 100644 --- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/DefaultCastOptionsProvider.java +++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/DefaultCastOptionsProvider.java @@ -20,6 +20,7 @@ import com.google.android.gms.cast.CastMediaControlIntent; import com.google.android.gms.cast.framework.CastOptions; import com.google.android.gms.cast.framework.OptionsProvider; import com.google.android.gms.cast.framework.SessionProvider; +import java.util.Collections; import java.util.List; /** @@ -58,7 +59,7 @@ public final class DefaultCastOptionsProvider implements OptionsProvider { @Override public List getAdditionalSessionProviders(Context context) { - return null; + return Collections.emptyList(); } } diff --git a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java index 2d74bce5f1..9b15aff846 100644 --- a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java +++ b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.ext.flac; +import androidx.annotation.Nullable; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.SimpleDecoder; @@ -94,6 +95,7 @@ import java.util.List; } @Override + @Nullable protected FlacDecoderException decode( DecoderInputBuffer inputBuffer, SimpleOutputBuffer outputBuffer, boolean reset) { if (reset) { diff --git a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java index de038921aa..a97d99fa54 100644 --- a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java +++ b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java @@ -15,9 +15,11 @@ */ package com.google.android.exoplayer2.ext.flac; +import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.extractor.ExtractorInput; import com.google.android.exoplayer2.util.FlacStreamInfo; +import com.google.android.exoplayer2.util.Util; import java.io.IOException; import java.nio.ByteBuffer; @@ -37,15 +39,16 @@ import java.nio.ByteBuffer; } } - private static final int TEMP_BUFFER_SIZE = 8192; // The same buffer size which libflac has + private static final int TEMP_BUFFER_SIZE = 8192; // The same buffer size as libflac. private final long nativeDecoderContext; - private ByteBuffer byteBufferData; - private ExtractorInput extractorInput; + @Nullable private ByteBuffer byteBufferData; + @Nullable private ExtractorInput extractorInput; + @Nullable private byte[] tempBuffer; private boolean endOfExtractorInput; - private byte[] tempBuffer; + @SuppressWarnings("nullness:method.invocation.invalid") public FlacDecoderJni() throws FlacDecoderException { if (!FlacLibrary.isAvailable()) { throw new FlacDecoderException("Failed to load decoder native libraries."); @@ -58,7 +61,8 @@ import java.nio.ByteBuffer; /** * Sets data to be parsed by libflac. - * @param byteBufferData Source {@link ByteBuffer} + * + * @param byteBufferData Source {@link ByteBuffer}. */ public void setData(ByteBuffer byteBufferData) { this.byteBufferData = byteBufferData; @@ -68,7 +72,8 @@ import java.nio.ByteBuffer; /** * Sets data to be parsed by libflac. - * @param extractorInput Source {@link ExtractorInput} + * + * @param extractorInput Source {@link ExtractorInput}. */ public void setData(ExtractorInput extractorInput) { this.byteBufferData = null; @@ -90,15 +95,15 @@ import java.nio.ByteBuffer; /** * Reads up to {@code length} bytes from the data source. - *

- * This method blocks until at least one byte of data can be read, the end of the input is + * + *

This method blocks until at least one byte of data can be read, the end of the input is * detected or an exception is thrown. - *

- * This method is called from the native code. + * + *

This method is called from the native code. * * @param target A target {@link ByteBuffer} into which data should be written. - * @return Returns the number of bytes read, or -1 on failure. It's not an error if this returns - * zero; it just means all the data read from the source. + * @return Returns the number of bytes read, or -1 on failure. If all of the data has already been + * read from the source, then 0 is returned. */ public int read(ByteBuffer target) throws IOException, InterruptedException { int byteCount = target.remaining(); @@ -106,18 +111,20 @@ import java.nio.ByteBuffer; byteCount = Math.min(byteCount, byteBufferData.remaining()); int originalLimit = byteBufferData.limit(); byteBufferData.limit(byteBufferData.position() + byteCount); - target.put(byteBufferData); - byteBufferData.limit(originalLimit); } else if (extractorInput != null) { + ExtractorInput extractorInput = this.extractorInput; + byte[] tempBuffer = Util.castNonNull(this.tempBuffer); byteCount = Math.min(byteCount, TEMP_BUFFER_SIZE); - int read = readFromExtractorInput(0, byteCount); + int read = readFromExtractorInput(extractorInput, tempBuffer, /* offset= */ 0, byteCount); if (read < 4) { // Reading less than 4 bytes, most of the time, happens because of getting the bytes left in // the buffer of the input. Do another read to reduce the number of calls to this method // from the native code. - read += readFromExtractorInput(read, byteCount - read); + read += + readFromExtractorInput( + extractorInput, tempBuffer, read, /* length= */ byteCount - read); } byteCount = read; target.put(tempBuffer, 0, byteCount); @@ -234,7 +241,8 @@ import java.nio.ByteBuffer; flacRelease(nativeDecoderContext); } - private int readFromExtractorInput(int offset, int length) + private int readFromExtractorInput( + ExtractorInput extractorInput, byte[] tempBuffer, int offset, int length) throws IOException, InterruptedException { int read = extractorInput.read(tempBuffer, offset, length); if (read == C.RESULT_END_OF_INPUT) { diff --git a/extensions/opus/build.gradle b/extensions/opus/build.gradle index 56acbdb7d3..0795079c6b 100644 --- a/extensions/opus/build.gradle +++ b/extensions/opus/build.gradle @@ -39,6 +39,7 @@ android { dependencies { implementation project(modulePrefix + 'library-core') + implementation 'androidx.annotation:annotation:1.0.2' testImplementation project(modulePrefix + 'testutils-robolectric') androidTestImplementation 'androidx.test:runner:' + androidXTestVersion androidTestImplementation 'androidx.test.ext:junit:' + androidXTestVersion diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java index f8ec477b88..dbce33b923 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.ext.opus; +import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.decoder.CryptoInfo; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; @@ -150,6 +151,7 @@ import java.util.List; } @Override + @Nullable protected OpusDecoderException decode( DecoderInputBuffer inputBuffer, SimpleOutputBuffer outputBuffer, boolean reset) { if (reset) { diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusLibrary.java b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusLibrary.java index cd5d67f686..5529701c06 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusLibrary.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/OpusLibrary.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.ext.opus; +import androidx.annotation.Nullable; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.util.LibraryLoader; @@ -30,7 +31,7 @@ public final class OpusLibrary { } private static final LibraryLoader LOADER = new LibraryLoader("opusV2JNI"); - private static Class exoMediaCryptoType; + @Nullable private static Class exoMediaCryptoType; private OpusLibrary() {} @@ -56,9 +57,8 @@ public final class OpusLibrary { return LOADER.isAvailable(); } - /** - * Returns the version of the underlying library if available, or null otherwise. - */ + /** Returns the version of the underlying library if available, or null otherwise. */ + @Nullable public static String getVersion() { return isAvailable() ? opusGetVersion() : null; } diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java index 57e5481b55..0e13e82630 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxDecoder.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.ext.vp9; +import androidx.annotation.Nullable; import android.view.Surface; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.decoder.CryptoInfo; @@ -120,8 +121,9 @@ import java.nio.ByteBuffer; } @Override - protected VpxDecoderException decode(VpxInputBuffer inputBuffer, VpxOutputBuffer outputBuffer, - boolean reset) { + @Nullable + protected VpxDecoderException decode( + VpxInputBuffer inputBuffer, VpxOutputBuffer outputBuffer, boolean reset) { ByteBuffer inputData = inputBuffer.data; int inputSize = inputData.limit(); CryptoInfo cryptoInfo = inputBuffer.cryptoInfo; diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxLibrary.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxLibrary.java index 2c25f674d6..5106ab67ad 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxLibrary.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxLibrary.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.ext.vp9; +import androidx.annotation.Nullable; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; import com.google.android.exoplayer2.drm.ExoMediaCrypto; import com.google.android.exoplayer2.util.LibraryLoader; @@ -30,7 +31,7 @@ public final class VpxLibrary { } private static final LibraryLoader LOADER = new LibraryLoader("vpx", "vpxV2JNI"); - private static Class exoMediaCryptoType; + @Nullable private static Class exoMediaCryptoType; private VpxLibrary() {} @@ -56,9 +57,8 @@ public final class VpxLibrary { return LOADER.isAvailable(); } - /** - * Returns the version of the underlying library if available, or null otherwise. - */ + /** Returns the version of the underlying library if available, or null otherwise. */ + @Nullable public static String getVersion() { return isAvailable() ? vpxGetVersion() : null; } @@ -67,6 +67,7 @@ public final class VpxLibrary { * Returns the configuration string with which the underlying library was built if available, or * null otherwise. */ + @Nullable public static String getBuildConfig() { return isAvailable() ? vpxGetBuildConfig() : null; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/decoder/SimpleDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/decoder/SimpleDecoder.java index f8204f6be3..b5650860e9 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/decoder/SimpleDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/decoder/SimpleDecoder.java @@ -301,5 +301,6 @@ public abstract class SimpleDecoder< * @param reset Whether the decoder must be reset before decoding. * @return A decoder exception if an error occurred, or null if decoding was successful. */ - protected abstract @Nullable E decode(I inputBuffer, O outputBuffer, boolean reset); + @Nullable + protected abstract E decode(I inputBuffer, O outputBuffer, boolean reset); }