listeners;
private final Timeline.Window window;
private final Timeline.Period period;
+ private final Timeline timeline;
private boolean prepared;
- private Timeline timeline;
private int state;
private boolean playWhenReady;
private long position;
diff --git a/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java b/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java
index f75607f268..d6759245c0 100644
--- a/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java
+++ b/extensions/jobdispatcher/src/main/java/com/google/android/exoplayer2/ext/jobdispatcher/JobDispatcherScheduler.java
@@ -23,7 +23,6 @@ import com.firebase.jobdispatcher.Constraint;
import com.firebase.jobdispatcher.FirebaseJobDispatcher;
import com.firebase.jobdispatcher.GooglePlayDriver;
import com.firebase.jobdispatcher.Job;
-import com.firebase.jobdispatcher.Job.Builder;
import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;
import com.firebase.jobdispatcher.Lifetime;
@@ -38,6 +37,7 @@ import com.google.android.exoplayer2.util.Util;
*
* {@literal
*
+ *
*
* queue = mediaController.getQueue();
for (int i = 0; i < queue.size(); i++) {
if (equalityChecker.equals(queue.get(i).getDescription(), description)) {
- onRemoveQueueItemAt(player, i);
+ queueDataAdapter.remove(i);
+ queueMediaSource.removeMediaSource(i);
return;
}
}
}
- @Override
- public void onRemoveQueueItemAt(Player player, int index) {
- queueDataAdapter.remove(index);
- queueMediaSource.removeMediaSource(index);
- }
-
// CommandReceiver implementation.
@NonNull
diff --git a/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java b/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java
index 1d0dfddb3f..ba5640c4e0 100644
--- a/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java
+++ b/extensions/okhttp/src/main/java/com/google/android/exoplayer2/ext/okhttp/OkHttpDataSource.java
@@ -161,8 +161,8 @@ public class OkHttpDataSource extends BaseDataSource implements HttpDataSource {
responseBody = Assertions.checkNotNull(response.body());
responseByteStream = responseBody.byteStream();
} catch (IOException e) {
- throw new HttpDataSourceException("Unable to connect to " + dataSpec.uri.toString(), e,
- dataSpec, HttpDataSourceException.TYPE_OPEN);
+ throw new HttpDataSourceException(
+ "Unable to connect to " + dataSpec.uri, e, dataSpec, HttpDataSourceException.TYPE_OPEN);
}
int responseCode = response.code();
diff --git a/extensions/opus/build.gradle b/extensions/opus/build.gradle
index dc530d05aa..cb12442de8 100644
--- a/extensions/opus/build.gradle
+++ b/extensions/opus/build.gradle
@@ -27,6 +27,7 @@ android {
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
consumerProguardFiles 'proguard-rules.txt'
+ testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
sourceSets.main {
@@ -37,6 +38,7 @@ android {
dependencies {
implementation project(modulePrefix + 'library-core')
+ androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
}
ext {
diff --git a/extensions/opus/src/androidTest/AndroidManifest.xml b/extensions/opus/src/androidTest/AndroidManifest.xml
index 9e7f05051e..5ba0f3c0f4 100644
--- a/extensions/opus/src/androidTest/AndroidManifest.xml
+++ b/extensions/opus/src/androidTest/AndroidManifest.xml
@@ -26,6 +26,6 @@
+ android:name="androidx.test.runner.AndroidJUnitRunner"/>
diff --git a/extensions/opus/src/androidTest/java/com/google/android/exoplayer2/ext/opus/OpusPlaybackTest.java b/extensions/opus/src/androidTest/java/com/google/android/exoplayer2/ext/opus/OpusPlaybackTest.java
index 8e3a213af1..c457514c87 100644
--- a/extensions/opus/src/androidTest/java/com/google/android/exoplayer2/ext/opus/OpusPlaybackTest.java
+++ b/extensions/opus/src/androidTest/java/com/google/android/exoplayer2/ext/opus/OpusPlaybackTest.java
@@ -15,10 +15,13 @@
*/
package com.google.android.exoplayer2.ext.opus;
+import static androidx.test.InstrumentationRegistry.getContext;
+import static org.junit.Assert.fail;
+
import android.content.Context;
import android.net.Uri;
import android.os.Looper;
-import android.test.InstrumentationTestCase;
+import androidx.test.runner.AndroidJUnit4;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
@@ -29,36 +32,34 @@ import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Playback tests using {@link LibopusAudioRenderer}.
- */
-public class OpusPlaybackTest extends InstrumentationTestCase {
+/** Playback tests using {@link LibopusAudioRenderer}. */
+@RunWith(AndroidJUnit4.class)
+public class OpusPlaybackTest {
private static final String BEAR_OPUS_URI = "asset:///bear-opus.webm";
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
if (!OpusLibrary.isAvailable()) {
fail("Opus library not available.");
}
}
- public void testBasicPlayback() throws ExoPlaybackException {
+ @Test
+ public void testBasicPlayback() throws Exception {
playUri(BEAR_OPUS_URI);
}
- private void playUri(String uri) throws ExoPlaybackException {
- TestPlaybackRunnable testPlaybackRunnable = new TestPlaybackRunnable(Uri.parse(uri),
- getInstrumentation().getContext());
+ private void playUri(String uri) throws Exception {
+ TestPlaybackRunnable testPlaybackRunnable =
+ new TestPlaybackRunnable(Uri.parse(uri), getContext());
Thread thread = new Thread(testPlaybackRunnable);
thread.start();
- try {
- thread.join();
- } catch (InterruptedException e) {
- fail(); // Should never happen.
- }
+ thread.join();
if (testPlaybackRunnable.playbackException != null) {
throw testPlaybackRunnable.playbackException;
}
diff --git a/extensions/rtmp/src/main/java/com/google/android/exoplayer2/ext/rtmp/RtmpDataSourceFactory.java b/extensions/rtmp/src/main/java/com/google/android/exoplayer2/ext/rtmp/RtmpDataSourceFactory.java
index 3cf9b8de37..d1350276f2 100644
--- a/extensions/rtmp/src/main/java/com/google/android/exoplayer2/ext/rtmp/RtmpDataSourceFactory.java
+++ b/extensions/rtmp/src/main/java/com/google/android/exoplayer2/ext/rtmp/RtmpDataSourceFactory.java
@@ -38,7 +38,11 @@ public final class RtmpDataSourceFactory implements DataSource.Factory {
@Override
public DataSource createDataSource() {
- return new RtmpDataSource(listener);
+ RtmpDataSource dataSource = new RtmpDataSource();
+ if (listener != null) {
+ dataSource.addTransferListener(listener);
+ }
+ return dataSource;
}
}
diff --git a/extensions/vp9/build.gradle b/extensions/vp9/build.gradle
index 3fb627fd77..96c58d7a57 100644
--- a/extensions/vp9/build.gradle
+++ b/extensions/vp9/build.gradle
@@ -27,6 +27,7 @@ android {
minSdkVersion project.ext.minSdkVersion
targetSdkVersion project.ext.targetSdkVersion
consumerProguardFiles 'proguard-rules.txt'
+ testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
sourceSets.main {
@@ -38,6 +39,7 @@ android {
dependencies {
implementation project(modulePrefix + 'library-core')
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
+ androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
androidTestImplementation 'com.google.truth:truth:' + truthVersion
}
diff --git a/extensions/vp9/src/androidTest/AndroidManifest.xml b/extensions/vp9/src/androidTest/AndroidManifest.xml
index c7ed3d7fb2..214427c4f0 100644
--- a/extensions/vp9/src/androidTest/AndroidManifest.xml
+++ b/extensions/vp9/src/androidTest/AndroidManifest.xml
@@ -26,6 +26,6 @@
+ android:name="androidx.test.runner.AndroidJUnitRunner"/>
diff --git a/extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java b/extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java
index bab7cb6fd7..d06e2934fb 100644
--- a/extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java
+++ b/extensions/vp9/src/androidTest/java/com/google/android/exoplayer2/ext/vp9/VpxPlaybackTest.java
@@ -15,13 +15,15 @@
*/
package com.google.android.exoplayer2.ext.vp9;
+import static androidx.test.InstrumentationRegistry.getContext;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
import android.content.Context;
import android.net.Uri;
import android.os.Looper;
-import android.test.InstrumentationTestCase;
import android.util.Log;
+import androidx.test.runner.AndroidJUnit4;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
@@ -32,11 +34,13 @@ import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-/**
- * Playback tests using {@link LibvpxVideoRenderer}.
- */
-public class VpxPlaybackTest extends InstrumentationTestCase {
+/** Playback tests using {@link LibvpxVideoRenderer}. */
+@RunWith(AndroidJUnit4.class)
+public class VpxPlaybackTest {
private static final String BEAR_URI = "asset:///bear-vp9.webm";
private static final String BEAR_ODD_DIMENSIONS_URI = "asset:///bear-vp9-odd-dimensions.webm";
@@ -45,23 +49,25 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
private static final String TAG = "VpxPlaybackTest";
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setUp() {
if (!VpxLibrary.isAvailable()) {
fail("Vpx library not available.");
}
}
- public void testBasicPlayback() throws ExoPlaybackException {
+ @Test
+ public void testBasicPlayback() throws Exception {
playUri(BEAR_URI);
}
- public void testOddDimensionsPlayback() throws ExoPlaybackException {
+ @Test
+ public void testOddDimensionsPlayback() throws Exception {
playUri(BEAR_ODD_DIMENSIONS_URI);
}
- public void test10BitProfile2Playback() throws ExoPlaybackException {
+ @Test
+ public void test10BitProfile2Playback() throws Exception {
if (VpxLibrary.isHighBitDepthSupported()) {
Log.d(TAG, "High Bit Depth supported.");
playUri(ROADTRIP_10BIT_URI);
@@ -70,6 +76,7 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
Log.d(TAG, "High Bit Depth not supported.");
}
+ @Test
public void testInvalidBitstream() {
try {
playUri(INVALID_BITSTREAM_URI);
@@ -80,16 +87,12 @@ public class VpxPlaybackTest extends InstrumentationTestCase {
}
}
- private void playUri(String uri) throws ExoPlaybackException {
- TestPlaybackRunnable testPlaybackRunnable = new TestPlaybackRunnable(Uri.parse(uri),
- getInstrumentation().getContext());
+ private void playUri(String uri) throws Exception {
+ TestPlaybackRunnable testPlaybackRunnable =
+ new TestPlaybackRunnable(Uri.parse(uri), getContext());
Thread thread = new Thread(testPlaybackRunnable);
thread.start();
- try {
- thread.join();
- } catch (InterruptedException e) {
- fail(); // Should never happen.
- }
+ thread.join();
if (testPlaybackRunnable.playbackException != null) {
throw testPlaybackRunnable.playbackException;
}
diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java
index 08c413aba7..f0986d08be 100644
--- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java
+++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/LibvpxVideoRenderer.java
@@ -39,8 +39,10 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
+import com.google.android.exoplayer2.util.TimedValueQueue;
import com.google.android.exoplayer2.util.TraceUtil;
import com.google.android.exoplayer2.util.Util;
+import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import com.google.android.exoplayer2.video.VideoRendererEventListener.EventDispatcher;
import java.lang.annotation.Retention;
@@ -109,11 +111,14 @@ public class LibvpxVideoRenderer extends BaseRenderer {
private final boolean playClearSamplesWithoutKeys;
private final EventDispatcher eventDispatcher;
private final FormatHolder formatHolder;
+ private final TimedValueQueue formatQueue;
private final DecoderInputBuffer flagsOnlyBuffer;
private final DrmSessionManager drmSessionManager;
private final boolean useSurfaceYuvOutput;
private Format format;
+ private Format pendingFormat;
+ private Format outputFormat;
private VpxDecoder decoder;
private VpxInputBuffer inputBuffer;
private VpxOutputBuffer outputBuffer;
@@ -142,6 +147,8 @@ public class LibvpxVideoRenderer extends BaseRenderer {
private int consecutiveDroppedFrameCount;
private int buffersInCodecCount;
private long lastRenderTimeUs;
+ private long outputStreamOffsetUs;
+ private VideoFrameMetadataListener frameMetadataListener;
protected DecoderCounters decoderCounters;
@@ -219,6 +226,7 @@ public class LibvpxVideoRenderer extends BaseRenderer {
joiningDeadlineMs = C.TIME_UNSET;
clearReportedVideoSize();
formatHolder = new FormatHolder();
+ formatQueue = new TimedValueQueue<>();
flagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance();
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
outputMode = VpxDecoder.OUTPUT_MODE_NONE;
@@ -328,6 +336,7 @@ public class LibvpxVideoRenderer extends BaseRenderer {
} else {
joiningDeadlineMs = C.TIME_UNSET;
}
+ formatQueue.clear();
}
@Override
@@ -371,6 +380,12 @@ public class LibvpxVideoRenderer extends BaseRenderer {
}
}
+ @Override
+ protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException {
+ outputStreamOffsetUs = offsetUs;
+ super.onStreamChanged(formats, offsetUs);
+ }
+
/**
* Called when a decoder has been created and configured.
*
@@ -437,6 +452,7 @@ public class LibvpxVideoRenderer extends BaseRenderer {
protected void onInputFormatChanged(Format newFormat) throws ExoPlaybackException {
Format oldFormat = format;
format = newFormat;
+ pendingFormat = newFormat;
boolean drmInitDataChanged = !Util.areEqual(format.drmInitData, oldFormat == null ? null
: oldFormat.drmInitData);
@@ -629,6 +645,8 @@ public class LibvpxVideoRenderer extends BaseRenderer {
setOutput((Surface) message, null);
} else if (messageType == MSG_SET_OUTPUT_BUFFER_RENDERER) {
setOutput(null, (VpxOutputBufferRenderer) message);
+ } else if (messageType == C.MSG_SET_VIDEO_FRAME_METADATA_LISTENER) {
+ frameMetadataListener = (VideoFrameMetadataListener) message;
} else {
super.handleMessage(messageType, message);
}
@@ -772,6 +790,10 @@ public class LibvpxVideoRenderer extends BaseRenderer {
if (waitingForKeys) {
return false;
}
+ if (pendingFormat != null) {
+ formatQueue.add(inputBuffer.timeUs, pendingFormat);
+ pendingFormat = null;
+ }
inputBuffer.flip();
inputBuffer.colorInfo = formatHolder.format.colorInfo;
onQueueInputBuffer(inputBuffer);
@@ -851,11 +873,21 @@ public class LibvpxVideoRenderer extends BaseRenderer {
return false;
}
+ long presentationTimeUs = outputBuffer.timeUs - outputStreamOffsetUs;
+ Format format = formatQueue.pollFloor(presentationTimeUs);
+ if (format != null) {
+ outputFormat = format;
+ }
+
long elapsedRealtimeNowUs = SystemClock.elapsedRealtime() * 1000;
boolean isStarted = getState() == STATE_STARTED;
if (!renderedFirstFrame
|| (isStarted
&& shouldForceRenderOutputBuffer(earlyUs, elapsedRealtimeNowUs - lastRenderTimeUs))) {
+ if (frameMetadataListener != null) {
+ frameMetadataListener.onVideoFrameAboutToBeRendered(
+ presentationTimeUs, System.nanoTime(), outputFormat);
+ }
renderOutputBuffer(outputBuffer);
return true;
}
@@ -873,6 +905,10 @@ public class LibvpxVideoRenderer extends BaseRenderer {
}
if (earlyUs < 30000) {
+ if (frameMetadataListener != null) {
+ frameMetadataListener.onVideoFrameAboutToBeRendered(
+ presentationTimeUs, System.nanoTime(), outputFormat);
+ }
renderOutputBuffer(outputBuffer);
return true;
}
diff --git a/javadoc_combined.gradle b/javadoc_combined.gradle
index aea65d4d97..209ad3a1a3 100644
--- a/javadoc_combined.gradle
+++ b/javadoc_combined.gradle
@@ -39,7 +39,7 @@ class CombinedJavadocPlugin implements Plugin {
libraryModules.each { libraryModule ->
libraryModule.android.libraryVariants.all { variant ->
def name = variant.buildType.name
- if (name.equals("release")) {
+ if (name == "release") {
classpath +=
libraryModule.project.files(
variant.javaCompile.classpath.files,
@@ -63,7 +63,7 @@ class CombinedJavadocPlugin implements Plugin {
}
// Returns Android library modules that declare a generateJavadoc task.
- private Set getLibraryModules(Project project) {
+ private static Set getLibraryModules(Project project) {
project.subprojects.findAll {
it.plugins.findPlugin("com.android.library") &&
it.tasks.findByName("generateJavadoc")
diff --git a/library/core/build.gradle b/library/core/build.gradle
index 947972392f..606033fdea 100644
--- a/library/core/build.gradle
+++ b/library/core/build.gradle
@@ -28,7 +28,7 @@ android {
targetSdkVersion project.ext.targetSdkVersion
consumerProguardFiles 'proguard-rules.txt'
- testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
// The following argument makes the Android Test Orchestrator run its
// "pm clear" command after each test invocation. This command ensures
@@ -39,11 +39,11 @@ android {
// Workaround to prevent circular dependency on project :testutils.
sourceSets {
androidTest {
- java.srcDirs += "../../testutils/src/main/java/"
+ java.srcDirs += '../../testutils/src/main/java/'
}
test {
- java.srcDirs += "../../testutils/src/main/java/"
- java.srcDirs += "../../testutils_robolectric/src/main/java/"
+ java.srcDirs += '../../testutils/src/main/java/'
+ java.srcDirs += '../../testutils_robolectric/src/main/java/'
}
}
@@ -60,12 +60,12 @@ dependencies {
implementation 'com.android.support:support-annotations:' + supportLibraryVersion
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
compileOnly 'org.checkerframework:checker-compat-qual:' + checkerframeworkVersion
+ androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
+ androidTestImplementation 'com.google.auto.value:auto-value-annotations:' + autoValueVersion
androidTestImplementation 'com.google.dexmaker:dexmaker:' + dexmakerVersion
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:' + dexmakerVersion
androidTestImplementation 'com.google.truth:truth:' + truthVersion
androidTestImplementation 'org.mockito:mockito-core:' + mockitoVersion
- androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
- androidTestImplementation 'com.google.auto.value:auto-value-annotations:' + autoValueVersion
androidTestAnnotationProcessor 'com.google.auto.value:auto-value:' + autoValueVersion
testImplementation 'com.google.truth:truth:' + truthVersion
testImplementation 'junit:junit:' + junitVersion
diff --git a/library/core/src/androidTest/AndroidManifest.xml b/library/core/src/androidTest/AndroidManifest.xml
index 1aa47c10f6..d9104b1077 100644
--- a/library/core/src/androidTest/AndroidManifest.xml
+++ b/library/core/src/androidTest/AndroidManifest.xml
@@ -29,6 +29,6 @@
+ android:name="androidx.test.runner.AndroidJUnitRunner"/>
diff --git a/library/core/src/androidTest/java/com/google/android/exoplayer2/upstream/ContentDataSourceTest.java b/library/core/src/androidTest/java/com/google/android/exoplayer2/upstream/ContentDataSourceTest.java
index 49329c38c0..45b784e30f 100644
--- a/library/core/src/androidTest/java/com/google/android/exoplayer2/upstream/ContentDataSourceTest.java
+++ b/library/core/src/androidTest/java/com/google/android/exoplayer2/upstream/ContentDataSourceTest.java
@@ -87,7 +87,7 @@ public final class ContentDataSourceTest {
fail();
} catch (ContentDataSource.ContentDataSourceException e) {
// Expected.
- assertThat(e.getCause()).isInstanceOf(FileNotFoundException.class);
+ assertThat(e).hasCauseThat().isInstanceOf(FileNotFoundException.class);
} finally {
dataSource.close();
}
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/C.java b/library/core/src/main/java/com/google/android/exoplayer2/C.java
index 87499a9cb1..0cbdc14b1c 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/C.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/C.java
@@ -26,6 +26,8 @@ import android.view.Surface;
import com.google.android.exoplayer2.PlayerMessage.Target;
import com.google.android.exoplayer2.audio.AuxEffectInfo;
import com.google.android.exoplayer2.util.Util;
+import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
+import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.UUID;
@@ -109,7 +111,8 @@ public final class C {
public static final String SANS_SERIF_NAME = "sans-serif";
/**
- * Crypto modes for a codec.
+ * Crypto modes for a codec. One of {@link #CRYPTO_MODE_UNENCRYPTED}, {@link #CRYPTO_MODE_AES_CTR}
+ * or {@link #CRYPTO_MODE_AES_CBC}.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({CRYPTO_MODE_UNENCRYPTED, CRYPTO_MODE_AES_CTR, CRYPTO_MODE_AES_CBC})
@@ -133,7 +136,14 @@ public final class C {
*/
public static final int AUDIO_SESSION_ID_UNSET = AudioManager.AUDIO_SESSION_ID_GENERATE;
- /** Represents an audio encoding, or an invalid or unset value. */
+ /**
+ * Represents an audio encoding, or an invalid or unset value. One of {@link Format#NO_VALUE},
+ * {@link #ENCODING_INVALID}, {@link #ENCODING_PCM_8BIT}, {@link #ENCODING_PCM_16BIT}, {@link
+ * #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT}, {@link #ENCODING_PCM_FLOAT}, {@link
+ * #ENCODING_PCM_MU_LAW}, {@link #ENCODING_PCM_A_LAW}, {@link #ENCODING_AC3}, {@link
+ * #ENCODING_E_AC3}, {@link #ENCODING_DTS}, {@link #ENCODING_DTS_HD} or {@link
+ * #ENCODING_DOLBY_TRUEHD}.
+ */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
Format.NO_VALUE,
@@ -153,7 +163,12 @@ public final class C {
})
public @interface Encoding {}
- /** Represents a PCM audio encoding, or an invalid or unset value. */
+ /**
+ * Represents a PCM audio encoding, or an invalid or unset value. One of {@link Format#NO_VALUE},
+ * {@link #ENCODING_INVALID}, {@link #ENCODING_PCM_8BIT}, {@link #ENCODING_PCM_16BIT}, {@link
+ * #ENCODING_PCM_24BIT}, {@link #ENCODING_PCM_32BIT}, {@link #ENCODING_PCM_FLOAT}, {@link
+ * #ENCODING_PCM_MU_LAW} or {@link #ENCODING_PCM_A_LAW}.
+ */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
Format.NO_VALUE,
@@ -195,11 +210,22 @@ public final class C {
public static final int ENCODING_DOLBY_TRUEHD = AudioFormat.ENCODING_DOLBY_TRUEHD;
/**
- * Stream types for an {@link android.media.AudioTrack}.
+ * Stream types for an {@link android.media.AudioTrack}. One of {@link #STREAM_TYPE_ALARM}, {@link
+ * #STREAM_TYPE_DTMF}, {@link #STREAM_TYPE_MUSIC}, {@link #STREAM_TYPE_NOTIFICATION}, {@link
+ * #STREAM_TYPE_RING}, {@link #STREAM_TYPE_SYSTEM}, {@link #STREAM_TYPE_VOICE_CALL} or {@link
+ * #STREAM_TYPE_USE_DEFAULT}.
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({STREAM_TYPE_ALARM, STREAM_TYPE_DTMF, STREAM_TYPE_MUSIC, STREAM_TYPE_NOTIFICATION,
- STREAM_TYPE_RING, STREAM_TYPE_SYSTEM, STREAM_TYPE_VOICE_CALL, STREAM_TYPE_USE_DEFAULT})
+ @IntDef({
+ STREAM_TYPE_ALARM,
+ STREAM_TYPE_DTMF,
+ STREAM_TYPE_MUSIC,
+ STREAM_TYPE_NOTIFICATION,
+ STREAM_TYPE_RING,
+ STREAM_TYPE_SYSTEM,
+ STREAM_TYPE_VOICE_CALL,
+ STREAM_TYPE_USE_DEFAULT
+ })
public @interface StreamType {}
/**
* @see AudioManager#STREAM_ALARM
@@ -239,11 +265,18 @@ public final class C {
public static final int STREAM_TYPE_DEFAULT = STREAM_TYPE_MUSIC;
/**
- * Content types for {@link com.google.android.exoplayer2.audio.AudioAttributes}.
+ * Content types for {@link com.google.android.exoplayer2.audio.AudioAttributes}. One of {@link
+ * #CONTENT_TYPE_MOVIE}, {@link #CONTENT_TYPE_MUSIC}, {@link #CONTENT_TYPE_SONIFICATION}, {@link
+ * #CONTENT_TYPE_SPEECH} or {@link #CONTENT_TYPE_UNKNOWN}.
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({CONTENT_TYPE_MOVIE, CONTENT_TYPE_MUSIC, CONTENT_TYPE_SONIFICATION, CONTENT_TYPE_SPEECH,
- CONTENT_TYPE_UNKNOWN})
+ @IntDef({
+ CONTENT_TYPE_MOVIE,
+ CONTENT_TYPE_MUSIC,
+ CONTENT_TYPE_SONIFICATION,
+ CONTENT_TYPE_SPEECH,
+ CONTENT_TYPE_UNKNOWN
+ })
public @interface AudioContentType {}
/**
* @see android.media.AudioAttributes#CONTENT_TYPE_MOVIE
@@ -270,13 +303,16 @@ public final class C {
android.media.AudioAttributes.CONTENT_TYPE_UNKNOWN;
/**
- * Flags for {@link com.google.android.exoplayer2.audio.AudioAttributes}.
- *
- * Note that {@code FLAG_HW_AV_SYNC} is not available because the player takes care of setting the
- * flag when tunneling is enabled via a track selector.
+ * Flags for {@link com.google.android.exoplayer2.audio.AudioAttributes}. Possible flag value is
+ * {@link #FLAG_AUDIBILITY_ENFORCED}.
+ *
+ *
Note that {@code FLAG_HW_AV_SYNC} is not available because the player takes care of setting
+ * the flag when tunneling is enabled via a track selector.
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, value = {FLAG_AUDIBILITY_ENFORCED})
+ @IntDef(
+ flag = true,
+ value = {FLAG_AUDIBILITY_ENFORCED})
public @interface AudioFlags {}
/**
* @see android.media.AudioAttributes#FLAG_AUDIBILITY_ENFORCED
@@ -284,7 +320,17 @@ public final class C {
public static final int FLAG_AUDIBILITY_ENFORCED =
android.media.AudioAttributes.FLAG_AUDIBILITY_ENFORCED;
- /** Usage types for {@link com.google.android.exoplayer2.audio.AudioAttributes}. */
+ /**
+ * Usage types for {@link com.google.android.exoplayer2.audio.AudioAttributes}. One of {@link
+ * #USAGE_ALARM}, {@link #USAGE_ASSISTANCE_ACCESSIBILITY}, {@link
+ * #USAGE_ASSISTANCE_NAVIGATION_GUIDANCE}, {@link #USAGE_ASSISTANCE_SONIFICATION}, {@link
+ * #USAGE_ASSISTANT}, {@link #USAGE_GAME}, {@link #USAGE_MEDIA}, {@link #USAGE_NOTIFICATION},
+ * {@link #USAGE_NOTIFICATION_COMMUNICATION_DELAYED}, {@link
+ * #USAGE_NOTIFICATION_COMMUNICATION_INSTANT}, {@link #USAGE_NOTIFICATION_COMMUNICATION_REQUEST},
+ * {@link #USAGE_NOTIFICATION_EVENT}, {@link #USAGE_NOTIFICATION_RINGTONE}, {@link
+ * #USAGE_UNKNOWN}, {@link #USAGE_VOICE_COMMUNICATION} or {@link
+ * #USAGE_VOICE_COMMUNICATION_SIGNALLING}.
+ */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
USAGE_ALARM,
@@ -376,7 +422,11 @@ public final class C {
public static final int USAGE_VOICE_COMMUNICATION_SIGNALLING =
android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING;
- /** Audio focus types. */
+ /**
+ * Audio focus types. One of {@link #AUDIOFOCUS_NONE}, {@link #AUDIOFOCUS_GAIN}, {@link
+ * #AUDIOFOCUS_GAIN_TRANSIENT}, {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} or {@link
+ * #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
+ */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
AUDIOFOCUS_NONE,
@@ -400,11 +450,19 @@ public final class C {
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
/**
- * Flags which can apply to a buffer containing a media sample.
+ * Flags which can apply to a buffer containing a media sample. Possible flag values are {@link
+ * #BUFFER_FLAG_KEY_FRAME}, {@link #BUFFER_FLAG_END_OF_STREAM}, {@link #BUFFER_FLAG_ENCRYPTED} and
+ * {@link #BUFFER_FLAG_DECODE_ONLY}.
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, value = {BUFFER_FLAG_KEY_FRAME, BUFFER_FLAG_END_OF_STREAM,
- BUFFER_FLAG_ENCRYPTED, BUFFER_FLAG_DECODE_ONLY})
+ @IntDef(
+ flag = true,
+ value = {
+ BUFFER_FLAG_KEY_FRAME,
+ BUFFER_FLAG_END_OF_STREAM,
+ BUFFER_FLAG_ENCRYPTED,
+ BUFFER_FLAG_DECODE_ONLY
+ })
public @interface BufferFlags {}
/**
* Indicates that a buffer holds a synchronization sample.
@@ -417,10 +475,12 @@ public final class C {
/** Indicates that a buffer is (at least partially) encrypted. */
public static final int BUFFER_FLAG_ENCRYPTED = 1 << 30; // 0x40000000
/** Indicates that a buffer should be decoded but not rendered. */
+ @SuppressWarnings("NumericOverflow")
public static final int BUFFER_FLAG_DECODE_ONLY = 1 << 31; // 0x80000000
/**
- * Video scaling modes for {@link MediaCodec}-based {@link Renderer}s.
+ * Video scaling modes for {@link MediaCodec}-based {@link Renderer}s. One of {@link
+ * #VIDEO_SCALING_MODE_SCALE_TO_FIT} or {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {VIDEO_SCALING_MODE_SCALE_TO_FIT, VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING})
@@ -441,11 +501,13 @@ public final class C {
public static final int VIDEO_SCALING_MODE_DEFAULT = VIDEO_SCALING_MODE_SCALE_TO_FIT;
/**
- * Track selection flags.
+ * Track selection flags. Possible flag values are {@link #SELECTION_FLAG_DEFAULT}, {@link
+ * #SELECTION_FLAG_FORCED} and {@link #SELECTION_FLAG_AUTOSELECT}.
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, value = {SELECTION_FLAG_DEFAULT, SELECTION_FLAG_FORCED,
- SELECTION_FLAG_AUTOSELECT})
+ @IntDef(
+ flag = true,
+ value = {SELECTION_FLAG_DEFAULT, SELECTION_FLAG_FORCED, SELECTION_FLAG_AUTOSELECT})
public @interface SelectionFlags {}
/**
* Indicates that the track should be selected if user preferences do not state otherwise.
@@ -465,7 +527,8 @@ public final class C {
public static final String LANGUAGE_UNDETERMINED = "und";
/**
- * Represents a streaming or other media type.
+ * Represents a streaming or other media type. One of {@link #TYPE_DASH}, {@link #TYPE_SS}, {@link
+ * #TYPE_HLS} or {@link #TYPE_OTHER}.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_DASH, TYPE_SS, TYPE_HLS, TYPE_OTHER})
@@ -533,34 +596,22 @@ public final class C {
*/
public static final int DATA_TYPE_CUSTOM_BASE = 10000;
- /**
- * A type constant for tracks of unknown type.
- */
+ /** A type constant for tracks of unknown type. */
public static final int TRACK_TYPE_UNKNOWN = -1;
- /**
- * A type constant for tracks of some default type, where the type itself is unknown.
- */
+ /** A type constant for tracks of some default type, where the type itself is unknown. */
public static final int TRACK_TYPE_DEFAULT = 0;
- /**
- * A type constant for audio tracks.
- */
+ /** A type constant for audio tracks. */
public static final int TRACK_TYPE_AUDIO = 1;
- /**
- * A type constant for video tracks.
- */
+ /** A type constant for video tracks. */
public static final int TRACK_TYPE_VIDEO = 2;
- /**
- * A type constant for text tracks.
- */
+ /** A type constant for text tracks. */
public static final int TRACK_TYPE_TEXT = 3;
- /**
- * A type constant for metadata tracks.
- */
+ /** A type constant for metadata tracks. */
public static final int TRACK_TYPE_METADATA = 4;
- /**
- * A type constant for a dummy or empty track.
- */
- public static final int TRACK_TYPE_NONE = 5;
+ /** A type constant for camera motion tracks. */
+ public static final int TRACK_TYPE_CAMERA_MOTION = 5;
+ /** A type constant for a dummy or empty track. */
+ public static final int TRACK_TYPE_NONE = 6;
/**
* Applications or extensions may define custom {@code TRACK_TYPE_*} constants greater than or
* equal to this value.
@@ -593,55 +644,42 @@ public final class C {
*/
public static final int SELECTION_REASON_CUSTOM_BASE = 10000;
- /**
- * A default size in bytes for an individual allocation that forms part of a larger buffer.
- */
+ /** A default size in bytes for an individual allocation that forms part of a larger buffer. */
public static final int DEFAULT_BUFFER_SEGMENT_SIZE = 64 * 1024;
- /**
- * A default size in bytes for a video buffer.
- */
+ /** A default size in bytes for a video buffer. */
public static final int DEFAULT_VIDEO_BUFFER_SIZE = 200 * DEFAULT_BUFFER_SEGMENT_SIZE;
- /**
- * A default size in bytes for an audio buffer.
- */
+ /** A default size in bytes for an audio buffer. */
public static final int DEFAULT_AUDIO_BUFFER_SIZE = 54 * DEFAULT_BUFFER_SEGMENT_SIZE;
- /**
- * A default size in bytes for a text buffer.
- */
+ /** A default size in bytes for a text buffer. */
public static final int DEFAULT_TEXT_BUFFER_SIZE = 2 * DEFAULT_BUFFER_SEGMENT_SIZE;
- /**
- * A default size in bytes for a metadata buffer.
- */
+ /** A default size in bytes for a metadata buffer. */
public static final int DEFAULT_METADATA_BUFFER_SIZE = 2 * DEFAULT_BUFFER_SEGMENT_SIZE;
- /**
- * A default size in bytes for a muxed buffer (e.g. containing video, audio and text).
- */
- public static final int DEFAULT_MUXED_BUFFER_SIZE = DEFAULT_VIDEO_BUFFER_SIZE
- + DEFAULT_AUDIO_BUFFER_SIZE + DEFAULT_TEXT_BUFFER_SIZE;
+ /** A default size in bytes for a camera motion buffer. */
+ public static final int DEFAULT_CAMERA_MOTION_BUFFER_SIZE = 2 * DEFAULT_BUFFER_SEGMENT_SIZE;
- /**
- * "cenc" scheme type name as defined in ISO/IEC 23001-7:2016.
- */
+ /** A default size in bytes for a muxed buffer (e.g. containing video, audio and text). */
+ public static final int DEFAULT_MUXED_BUFFER_SIZE =
+ DEFAULT_VIDEO_BUFFER_SIZE + DEFAULT_AUDIO_BUFFER_SIZE + DEFAULT_TEXT_BUFFER_SIZE;
+
+ /** "cenc" scheme type name as defined in ISO/IEC 23001-7:2016. */
+ @SuppressWarnings("ConstantField")
public static final String CENC_TYPE_cenc = "cenc";
- /**
- * "cbc1" scheme type name as defined in ISO/IEC 23001-7:2016.
- */
+ /** "cbc1" scheme type name as defined in ISO/IEC 23001-7:2016. */
+ @SuppressWarnings("ConstantField")
public static final String CENC_TYPE_cbc1 = "cbc1";
- /**
- * "cens" scheme type name as defined in ISO/IEC 23001-7:2016.
- */
+ /** "cens" scheme type name as defined in ISO/IEC 23001-7:2016. */
+ @SuppressWarnings("ConstantField")
public static final String CENC_TYPE_cens = "cens";
- /**
- * "cbcs" scheme type name as defined in ISO/IEC 23001-7:2016.
- */
+ /** "cbcs" scheme type name as defined in ISO/IEC 23001-7:2016. */
+ @SuppressWarnings("ConstantField")
public static final String CENC_TYPE_cbcs = "cbcs";
/**
@@ -733,6 +771,20 @@ public final class C {
*/
public static final int MSG_SET_AUX_EFFECT_INFO = 5;
+ /**
+ * The type of a message that can be passed to a video {@link Renderer} via {@link
+ * ExoPlayer#createMessage(Target)}. The message payload should be a {@link
+ * VideoFrameMetadataListener} instance, or null.
+ */
+ public static final int MSG_SET_VIDEO_FRAME_METADATA_LISTENER = 6;
+
+ /**
+ * The type of a message that can be passed to a camera motion {@link Renderer} via {@link
+ * ExoPlayer#createMessage(Target)}. The message payload should be a {@link CameraMotionListener}
+ * instance, or null.
+ */
+ public static final int MSG_SET_CAMERA_MOTION_LISTENER = 7;
+
/**
* Applications or extensions may define custom {@code MSG_*} constants that can be passed to
* {@link Renderer}s. These custom constants must be greater than or equal to this value.
@@ -740,15 +792,17 @@ public final class C {
public static final int MSG_CUSTOM_BASE = 10000;
/**
- * The stereo mode for 360/3D/VR videos.
+ * The stereo mode for 360/3D/VR videos. One of {@link Format#NO_VALUE}, {@link
+ * #STEREO_MODE_MONO}, {@link #STEREO_MODE_TOP_BOTTOM}, {@link #STEREO_MODE_LEFT_RIGHT} or {@link
+ * #STEREO_MODE_STEREO_MESH}.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({
- Format.NO_VALUE,
- STEREO_MODE_MONO,
- STEREO_MODE_TOP_BOTTOM,
- STEREO_MODE_LEFT_RIGHT,
- STEREO_MODE_STEREO_MESH
+ Format.NO_VALUE,
+ STEREO_MODE_MONO,
+ STEREO_MODE_TOP_BOTTOM,
+ STEREO_MODE_LEFT_RIGHT,
+ STEREO_MODE_STEREO_MESH
})
public @interface StereoMode {}
/**
@@ -770,7 +824,8 @@ public final class C {
public static final int STEREO_MODE_STEREO_MESH = 3;
/**
- * Video colorspaces.
+ * Video colorspaces. One of {@link Format#NO_VALUE}, {@link #COLOR_SPACE_BT709}, {@link
+ * #COLOR_SPACE_BT601} or {@link #COLOR_SPACE_BT2020}.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, COLOR_SPACE_BT709, COLOR_SPACE_BT601, COLOR_SPACE_BT2020})
@@ -789,7 +844,8 @@ public final class C {
public static final int COLOR_SPACE_BT2020 = MediaFormat.COLOR_STANDARD_BT2020;
/**
- * Video color transfer characteristics.
+ * Video color transfer characteristics. One of {@link Format#NO_VALUE}, {@link
+ * #COLOR_TRANSFER_SDR}, {@link #COLOR_TRANSFER_ST2084} or {@link #COLOR_TRANSFER_HLG}.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, COLOR_TRANSFER_SDR, COLOR_TRANSFER_ST2084, COLOR_TRANSFER_HLG})
@@ -808,7 +864,8 @@ public final class C {
public static final int COLOR_TRANSFER_HLG = MediaFormat.COLOR_TRANSFER_HLG;
/**
- * Video color range.
+ * Video color range. One of {@link Format#NO_VALUE}, {@link #COLOR_RANGE_LIMITED} or {@link
+ * #COLOR_RANGE_FULL}.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({Format.NO_VALUE, COLOR_RANGE_LIMITED, COLOR_RANGE_FULL})
@@ -836,7 +893,12 @@ public final class C {
*/
public static final int PRIORITY_DOWNLOAD = PRIORITY_PLAYBACK - 1000;
- /** Network connection type. */
+ /**
+ * Network connection type. One of {@link #NETWORK_TYPE_UNKNOWN}, {@link #NETWORK_TYPE_OFFLINE},
+ * {@link #NETWORK_TYPE_WIFI}, {@link #NETWORK_TYPE_2G}, {@link #NETWORK_TYPE_3G}, {@link
+ * #NETWORK_TYPE_4G}, {@link #NETWORK_TYPE_CELLULAR_UNKNOWN}, {@link #NETWORK_TYPE_ETHERNET} or
+ * {@link #NETWORK_TYPE_OTHER}.
+ */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
NETWORK_TYPE_UNKNOWN,
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java b/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java
index f8b7f5f5c2..c466815c79 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/DefaultLoadControl.java
@@ -154,6 +154,7 @@ public class DefaultLoadControl implements LoadControl {
}
/** Creates a {@link DefaultLoadControl}. */
+ @SuppressWarnings("deprecation")
public DefaultLoadControl createDefaultLoadControl() {
if (allocator == null) {
allocator = new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE);
@@ -183,15 +184,15 @@ public class DefaultLoadControl implements LoadControl {
private int targetBufferSize;
private boolean isBuffering;
- /**
- * Constructs a new instance, using the {@code DEFAULT_*} constants defined in this class.
- */
+ /** Constructs a new instance, using the {@code DEFAULT_*} constants defined in this class. */
+ @SuppressWarnings("deprecation")
public DefaultLoadControl() {
this(new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE));
}
/** @deprecated Use {@link Builder} instead. */
@Deprecated
+ @SuppressWarnings("deprecation")
public DefaultLoadControl(DefaultAllocator allocator) {
this(
allocator,
@@ -205,6 +206,7 @@ public class DefaultLoadControl implements LoadControl {
/** @deprecated Use {@link Builder} instead. */
@Deprecated
+ @SuppressWarnings("deprecation")
public DefaultLoadControl(
DefaultAllocator allocator,
int minBufferMs,
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java
index 6cab53b78a..c0a117c241 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java
@@ -35,6 +35,7 @@ import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
+import com.google.android.exoplayer2.video.spherical.CameraMotionRenderer;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
@@ -52,11 +53,11 @@ public class DefaultRenderersFactory implements RenderersFactory {
public static final long DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS = 5000;
/**
- * Modes for using extension renderers.
+ * Modes for using extension renderers. One of {@link #EXTENSION_RENDERER_MODE_OFF}, {@link
+ * #EXTENSION_RENDERER_MODE_ON} or {@link #EXTENSION_RENDERER_MODE_PREFER}.
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({EXTENSION_RENDERER_MODE_OFF, EXTENSION_RENDERER_MODE_ON,
- EXTENSION_RENDERER_MODE_PREFER})
+ @IntDef({EXTENSION_RENDERER_MODE_OFF, EXTENSION_RENDERER_MODE_ON, EXTENSION_RENDERER_MODE_PREFER})
public @interface ExtensionRendererMode {}
/**
* Do not allow use of extension renderers.
@@ -82,7 +83,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
protected static final int MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY = 50;
private final Context context;
- @Nullable private final DrmSessionManager drmSessionManager;
+ private final @Nullable DrmSessionManager drmSessionManager;
private final @ExtensionRendererMode int extensionRendererMode;
private final long allowedVideoJoiningTimeMs;
@@ -98,6 +99,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
* directly to {@link SimpleExoPlayer} or {@link ExoPlayerFactory}.
*/
@Deprecated
+ @SuppressWarnings("deprecation")
public DefaultRenderersFactory(
Context context, @Nullable DrmSessionManager drmSessionManager) {
this(context, drmSessionManager, EXTENSION_RENDERER_MODE_OFF);
@@ -111,7 +113,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
*/
public DefaultRenderersFactory(
Context context, @ExtensionRendererMode int extensionRendererMode) {
- this(context, null, extensionRendererMode, DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS);
+ this(context, extensionRendererMode, DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS);
}
/**
@@ -119,6 +121,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
* DrmSessionManager} directly to {@link SimpleExoPlayer} or {@link ExoPlayerFactory}.
*/
@Deprecated
+ @SuppressWarnings("deprecation")
public DefaultRenderersFactory(
Context context,
@Nullable DrmSessionManager drmSessionManager,
@@ -138,7 +141,10 @@ public class DefaultRenderersFactory implements RenderersFactory {
Context context,
@ExtensionRendererMode int extensionRendererMode,
long allowedVideoJoiningTimeMs) {
- this(context, null, extensionRendererMode, allowedVideoJoiningTimeMs);
+ this.context = context;
+ this.extensionRendererMode = extensionRendererMode;
+ this.allowedVideoJoiningTimeMs = allowedVideoJoiningTimeMs;
+ this.drmSessionManager = null;
}
/**
@@ -177,6 +183,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
extensionRendererMode, renderersList);
buildMetadataRenderers(context, metadataRendererOutput, eventHandler.getLooper(),
extensionRendererMode, renderersList);
+ buildCameraMotionRenderers(context, extensionRendererMode, renderersList);
buildMiscellaneousRenderers(context, eventHandler, extensionRendererMode, renderersList);
return renderersList.toArray(new Renderer[renderersList.size()]);
}
@@ -355,12 +362,14 @@ public class DefaultRenderersFactory implements RenderersFactory {
*
* @param context The {@link Context} associated with the player.
* @param output An output for the renderers.
- * @param outputLooper The looper associated with the thread on which the output should be
- * called.
+ * @param outputLooper The looper associated with the thread on which the output should be called.
* @param extensionRendererMode The extension renderer mode.
* @param out An array to which the built renderers should be appended.
*/
- protected void buildTextRenderers(Context context, TextOutput output, Looper outputLooper,
+ protected void buildTextRenderers(
+ Context context,
+ TextOutput output,
+ Looper outputLooper,
@ExtensionRendererMode int extensionRendererMode,
ArrayList out) {
out.add(new TextRenderer(output, outputLooper));
@@ -371,16 +380,31 @@ public class DefaultRenderersFactory implements RenderersFactory {
*
* @param context The {@link Context} associated with the player.
* @param output An output for the renderers.
- * @param outputLooper The looper associated with the thread on which the output should be
- * called.
+ * @param outputLooper The looper associated with the thread on which the output should be called.
* @param extensionRendererMode The extension renderer mode.
* @param out An array to which the built renderers should be appended.
*/
- protected void buildMetadataRenderers(Context context, MetadataOutput output, Looper outputLooper,
- @ExtensionRendererMode int extensionRendererMode, ArrayList out) {
+ protected void buildMetadataRenderers(
+ Context context,
+ MetadataOutput output,
+ Looper outputLooper,
+ @ExtensionRendererMode int extensionRendererMode,
+ ArrayList out) {
out.add(new MetadataRenderer(output, outputLooper));
}
+ /**
+ * Builds camera motion renderers for use by the player.
+ *
+ * @param context The {@link Context} associated with the player.
+ * @param extensionRendererMode The extension renderer mode.
+ * @param out An array to which the built renderers should be appended.
+ */
+ protected void buildCameraMotionRenderers(
+ Context context, @ExtensionRendererMode int extensionRendererMode, ArrayList out) {
+ out.add(new CameraMotionRenderer());
+ }
+
/**
* Builds any miscellaneous renderers used by the player.
*
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlaybackException.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlaybackException.java
index ca7367f1b0..ba00d1163f 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlaybackException.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlaybackException.java
@@ -28,7 +28,8 @@ import java.lang.annotation.RetentionPolicy;
public final class ExoPlaybackException extends Exception {
/**
- * The type of source that produced the error.
+ * The type of source that produced the error. One of {@link #TYPE_SOURCE}, {@link #TYPE_RENDERER}
+ * or {@link #TYPE_UNEXPECTED}.
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_SOURCE, TYPE_RENDERER, TYPE_UNEXPECTED})
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
index 5780f7b418..452c1043a3 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
@@ -227,6 +227,7 @@ public interface ExoPlayer extends Player {
/** @deprecated Use {@link #createMessage(PlayerMessage.Target)} instead. */
@Deprecated
+ @SuppressWarnings("deprecation")
void sendMessages(ExoPlayerMessage... messages);
/**
@@ -234,6 +235,7 @@ public interface ExoPlayer extends Player {
* PlayerMessage#blockUntilDelivered()}.
*/
@Deprecated
+ @SuppressWarnings("deprecation")
void blockingSendMessages(ExoPlayerMessage... messages);
/**
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java
index 648168816f..5e0dd905b9 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java
@@ -327,10 +327,10 @@ import java.util.concurrent.CopyOnWriteArraySet;
} else {
long windowPositionUs = positionMs == C.TIME_UNSET
? timeline.getWindow(windowIndex, window).getDefaultPositionUs() : C.msToUs(positionMs);
- Pair periodIndexAndPosition =
+ Pair