diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 4f3ed97933..77199435ca 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -4,6 +4,8 @@ * Common Library: * ExoPlayer: + * Fix issue where `PreloadMediaPeriod` cannot retain the streams when it + is preloaded again. * Transformer: * Add `audioConversionProcess` and `videoConversionProcess` to `ExportResult` indicating how the respective track in the output file diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaPeriod.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaPeriod.java index 0a6b7d606f..bd89e81d48 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaPeriod.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaPeriod.java @@ -27,7 +27,6 @@ import androidx.media3.exoplayer.source.MediaPeriod; import androidx.media3.exoplayer.source.SampleStream; import androidx.media3.exoplayer.source.TrackGroupArray; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; -import androidx.media3.exoplayer.trackselection.TrackSelectorResult; import java.io.IOException; import java.util.Objects; @@ -107,6 +106,16 @@ import java.util.Objects; @NullableType SampleStream[] streams, boolean[] streamResetFlags, long positionUs) { + return selectTracksInternal( + selections, mayRetainStreamFlags, streams, streamResetFlags, positionUs); + } + + private long selectTracksInternal( + @NullableType ExoTrackSelection[] selections, + boolean[] mayRetainStreamFlags, + @NullableType SampleStream[] streams, + boolean[] streamResetFlags, + long positionUs) { if (preloadTrackSelectionHolder == null) { // No preload track selection was done. return mediaPeriod.selectTracks( @@ -134,7 +143,7 @@ import java.util.Objects; preloadStreamResetFlags = new boolean[preloadStreamResetFlags.length]; trackSelectionPositionUs = mediaPeriod.selectTracks( - holder.trackSelectorResult.selections, + holder.selections, holder.mayRetainStreamFlags, holder.streams, preloadStreamResetFlags, @@ -157,8 +166,7 @@ import java.util.Objects; @NullableType ExoTrackSelection[] selections, PreloadTrackSelectionHolder preloadTrackSelectionHolder) { @NullableType - ExoTrackSelection[] preloadSelections = - checkNotNull(preloadTrackSelectionHolder).trackSelectorResult.selections; + ExoTrackSelection[] preloadSelections = checkNotNull(preloadTrackSelectionHolder).selections; boolean needsReselection = false; for (int i = 0; i < selections.length; i++) { ExoTrackSelection selection = selections[i]; @@ -169,15 +177,15 @@ import java.util.Objects; preloadTrackSelectionHolder.mayRetainStreamFlags[i] = false; if (selection == null) { // Preloaded track got disabled. Discard preloaded stream. - preloadTrackSelectionHolder.trackSelectorResult.selections[i] = null; + preloadTrackSelectionHolder.selections[i] = null; needsReselection = true; } else if (preloadSelection == null) { // Enabled track not preloaded. Update selection. - preloadTrackSelectionHolder.trackSelectorResult.selections[i] = selection; + preloadTrackSelectionHolder.selections[i] = selection; needsReselection = true; } else if (!isSameAdaptionSet(selection, preloadSelection)) { // Adaption set has changed. Discard preloaded stream. - preloadTrackSelectionHolder.trackSelectorResult.selections[i] = selection; + preloadTrackSelectionHolder.selections[i] = selection; needsReselection = true; } else if (selection.getTrackGroup().type == C.TRACK_TYPE_VIDEO || selection.getTrackGroup().type == C.TRACK_TYPE_AUDIO @@ -188,7 +196,7 @@ import java.util.Objects; preloadTrackSelectionHolder.mayRetainStreamFlags[i] = true; } else { // The selection in a non-audio or non-video track has changed. Discard preloaded stream. - preloadTrackSelectionHolder.trackSelectorResult.selections[i] = selection; + preloadTrackSelectionHolder.selections[i] = selection; needsReselection = true; } } @@ -210,20 +218,12 @@ import java.util.Objects; } /* package */ long selectTracksForPreloading( - TrackSelectorResult trackSelectorResult, long positionUs) { - @NullableType ExoTrackSelection[] selections = trackSelectorResult.selections; + @NullableType ExoTrackSelection[] selections, long positionUs) { @NullableType SampleStream[] preloadedSampleStreams = new SampleStream[selections.length]; boolean[] preloadedStreamResetFlags = new boolean[selections.length]; boolean[] mayRetainStreamFlags = new boolean[selections.length]; - if (preloadTrackSelectionHolder != null) { - for (int i = 0; i < trackSelectorResult.length; i++) { - mayRetainStreamFlags[i] = - trackSelectorResult.isEquivalent( - checkNotNull(preloadTrackSelectionHolder).trackSelectorResult, i); - } - } long trackSelectionPositionUs = - mediaPeriod.selectTracks( + selectTracksInternal( selections, mayRetainStreamFlags, preloadedSampleStreams, @@ -231,7 +231,7 @@ import java.util.Objects; positionUs); preloadTrackSelectionHolder = new PreloadTrackSelectionHolder( - trackSelectorResult, + selections, mayRetainStreamFlags, preloadedSampleStreams, preloadedStreamResetFlags, @@ -285,19 +285,19 @@ import java.util.Objects; } private static class PreloadTrackSelectionHolder { - public final TrackSelectorResult trackSelectorResult; + public final @NullableType ExoTrackSelection[] selections; public final boolean[] mayRetainStreamFlags; public final @NullableType SampleStream[] streams; public final boolean[] streamResetFlags; public final long trackSelectionPositionUs; public PreloadTrackSelectionHolder( - TrackSelectorResult trackSelectorResult, + @NullableType ExoTrackSelection[] selections, boolean[] mayRetainStreamFlags, @NullableType SampleStream[] streams, boolean[] streamResetFlags, long trackSelectionPositionUs) { - this.trackSelectorResult = trackSelectorResult; + this.selections = selections; this.mayRetainStreamFlags = mayRetainStreamFlags; this.streams = streams; this.streamResetFlags = streamResetFlags; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java index 61527dbe01..8db4160cf9 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/preload/PreloadMediaSource.java @@ -368,7 +368,8 @@ public final class PreloadMediaSource extends WrappingMediaSource { Log.e(TAG, "Failed to select tracks", e); } if (trackSelectorResult != null) { - preloadMediaPeriod.selectTracksForPreloading(trackSelectorResult, periodStartPositionUs); + preloadMediaPeriod.selectTracksForPreloading( + trackSelectorResult.selections, periodStartPositionUs); if (preloadControl.onPrepared(PreloadMediaSource.this)) { preloadMediaPeriod.continueLoading( new LoadingInfo.Builder().setPlaybackPositionUs(periodStartPositionUs).build()); diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadMediaPeriodTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadMediaPeriodTest.java index d64238d540..320b0b4d47 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadMediaPeriodTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/preload/PreloadMediaPeriodTest.java @@ -33,8 +33,6 @@ import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.MimeTypes; import androidx.media3.common.TrackGroup; -import androidx.media3.common.Tracks; -import androidx.media3.exoplayer.RendererConfiguration; import androidx.media3.exoplayer.drm.DrmSessionEventListener; import androidx.media3.exoplayer.drm.DrmSessionManager; import androidx.media3.exoplayer.source.EmptySampleStream; @@ -45,7 +43,6 @@ import androidx.media3.exoplayer.source.SampleStream; import androidx.media3.exoplayer.source.TrackGroupArray; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; import androidx.media3.exoplayer.trackselection.FixedTrackSelection; -import androidx.media3.exoplayer.trackselection.TrackSelectorResult; import androidx.media3.exoplayer.upstream.DefaultAllocator; import androidx.media3.test.utils.FakeMediaPeriod; import androidx.media3.test.utils.FakeTimeline; @@ -223,6 +220,409 @@ public final class PreloadMediaPeriodTest { assertThat(mediaPeriodReference.get()).isSameInstanceAs(preloadMediaPeriod); } + @Test + public void selectTracksForPreloadingSecondTime_forSameSelections_usePreloadedStreams() { + MediaPeriod wrappedMediaPeriod = mock(MediaPeriod.class); + ExoTrackSelection[] preloadTrackSelections = + new ExoTrackSelection[] { + new FixedTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()), + /* track= */ 0), + new FixedTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build()), + /* track= */ 0) + }; + when(wrappedMediaPeriod.selectTracks( + eq(preloadTrackSelections), any(), any(), any(), /* positionUs= */ eq(0L))) + .thenReturn(0L); + PreloadMediaPeriod preloadMediaPeriod = new PreloadMediaPeriod(wrappedMediaPeriod); + MediaPeriod.Callback callback = + new MediaPeriod.Callback() { + @Override + public void onPrepared(MediaPeriod mediaPeriod) {} + + @Override + public void onContinueLoadingRequested(MediaPeriod source) {} + }; + preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); + // Select tracks for preloading. + long preloadTrackSelectionStartPositionUs = + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); + verify(wrappedMediaPeriod).prepare(any(), anyLong()); + verify(wrappedMediaPeriod) + .selectTracks( + eq(preloadTrackSelections), + /* mayRetainStreamFlags= */ eq(new boolean[] {false, false}), + /* streams= */ any(), + /* streamResetFlags= */ any(), + /* positionUs= */ eq(0L)); + reset(wrappedMediaPeriod); + + // Select tracks for preloading the second time based on the same track selections. + long newTrackSelectionStartPositionUs = + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); + + verifyNoMoreInteractions(wrappedMediaPeriod); + assertThat(newTrackSelectionStartPositionUs).isEqualTo(preloadTrackSelectionStartPositionUs); + } + + @Test + public void + selectTracksForPreloadingSecondTime_forDifferentAdaptiveVideoSelection_usePreloadedStreams() { + MediaPeriod wrappedMediaPeriod = mock(MediaPeriod.class); + ExoTrackSelection[] preloadTrackSelections = + new ExoTrackSelection[] { + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setWidth(1920) + .setHeight(1080) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build(), + new Format.Builder() + .setWidth(3840) + .setHeight(2160) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build()), + /* selectedIndex= */ 1), + new FakeTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setSampleMimeType(MimeTypes.TEXT_VTT) + .setLanguage("de") + .build()), + /* selectedIndex= */ 0) + }; + when(wrappedMediaPeriod.selectTracks( + eq(preloadTrackSelections), any(), any(), any(), /* positionUs= */ eq(0L))) + .thenReturn(0L); + PreloadMediaPeriod preloadMediaPeriod = new PreloadMediaPeriod(wrappedMediaPeriod); + MediaPeriod.Callback callback = + new MediaPeriod.Callback() { + @Override + public void onPrepared(MediaPeriod mediaPeriod) {} + + @Override + public void onContinueLoadingRequested(MediaPeriod source) {} + }; + preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); + // Select tracks for preloading. + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); + verify(wrappedMediaPeriod).prepare(any(), anyLong()); + verify(wrappedMediaPeriod) + .selectTracks( + eq(preloadTrackSelections), + /* mayRetainStreamFlags= */ eq(new boolean[] {false, false, false}), + /* streams= */ any(), + /* streamResetFlags= */ any(), + /* positionUs= */ eq(0L)); + verifyNoMoreInteractions(wrappedMediaPeriod); + reset(wrappedMediaPeriod); + // Create a new track selections. + ExoTrackSelection[] newPreloadTrackSelections = + new ExoTrackSelection[] { + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setWidth(1920) + .setHeight(1080) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build(), + new Format.Builder() + .setWidth(3840) + .setHeight(2160) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setSampleMimeType(MimeTypes.TEXT_VTT) + .setLanguage("de") + .build()), + /* selectedIndex= */ 0) + }; + + // Select tracks for preloading the second time based on the new track selections. The + // selectTracks method of the wrapped media period must not be called again. + long newTrackSelectionStartPositionUs = + preloadMediaPeriod.selectTracksForPreloading( + newPreloadTrackSelections, /* positionUs= */ 0L); + + verifyNoMoreInteractions(wrappedMediaPeriod); + assertThat(newTrackSelectionStartPositionUs).isEqualTo(0L); + } + + @Test + public void + selectTracksForPreloadingSecondTime_forDifferentAdaptiveAudioSelection_usePreloadedStreams() { + MediaPeriod wrappedMediaPeriod = mock(MediaPeriod.class); + ExoTrackSelection[] preloadTrackSelections = + new ExoTrackSelection[] { + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setWidth(1920) + .setHeight(1080) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build(), + new Format.Builder() + .setWidth(3840) + .setHeight(2160) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setSampleMimeType(MimeTypes.TEXT_VTT) + .setLanguage("de") + .build()), + /* selectedIndex= */ 0) + }; + when(wrappedMediaPeriod.selectTracks( + eq(preloadTrackSelections), any(), any(), any(), /* positionUs= */ eq(0L))) + .thenReturn(0L); + PreloadMediaPeriod preloadMediaPeriod = new PreloadMediaPeriod(wrappedMediaPeriod); + MediaPeriod.Callback callback = + new MediaPeriod.Callback() { + @Override + public void onPrepared(MediaPeriod mediaPeriod) {} + + @Override + public void onContinueLoadingRequested(MediaPeriod source) {} + }; + preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); + // Select tracks for preloading. + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); + verify(wrappedMediaPeriod).prepare(any(), anyLong()); + verify(wrappedMediaPeriod) + .selectTracks( + eq(preloadTrackSelections), + /* mayRetainStreamFlags= */ eq(new boolean[] {false, false, false}), + /* streams= */ any(), + /* streamResetFlags= */ any(), + /* positionUs= */ eq(0L)); + verifyNoMoreInteractions(wrappedMediaPeriod); + reset(wrappedMediaPeriod); + // Create a new track selections. + ExoTrackSelection[] newPreloadTrackSelections = + new ExoTrackSelection[] { + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setWidth(1920) + .setHeight(1080) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build(), + new Format.Builder() + .setWidth(3840) + .setHeight(2160) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()), + /* selectedIndex= */ 1), + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setSampleMimeType(MimeTypes.TEXT_VTT) + .setLanguage("de") + .build()), + /* selectedIndex= */ 0) + }; + + // Select tracks for preloading the second time based on the new track selections. The + // selectTracks method of the wrapped media period must not be called again. + long newTrackSelectionStartPositionUs = + preloadMediaPeriod.selectTracksForPreloading( + newPreloadTrackSelections, /* positionUs= */ 0L); + + verifyNoMoreInteractions(wrappedMediaPeriod); + assertThat(newTrackSelectionStartPositionUs).isEqualTo(0L); + } + + @Test + public void + selectTracksForPreloadingSecondTime_forDifferentAdaptiveTextSelection_callOnWrappedPeriodRetainingPreloadedStreams() { + MediaPeriod wrappedMediaPeriod = mock(MediaPeriod.class); + ExoTrackSelection[] preloadTrackSelections = + new ExoTrackSelection[] { + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setWidth(1920) + .setHeight(1080) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build(), + new Format.Builder() + .setWidth(3840) + .setHeight(2160) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()), + /* selectedIndex= */ 0), // + // An adaptive track group for text is practically not possible. The hypothetical case has + // been created for test coverage. + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setSampleMimeType(MimeTypes.TEXT_VTT) + .setLanguage("de") + .build(), + new Format.Builder() + .setSampleMimeType(MimeTypes.TEXT_VTT) + .setLanguage("en") + .build()), + /* selectedIndex= */ 0) + }; + when(wrappedMediaPeriod.selectTracks( + eq(preloadTrackSelections), any(), any(), any(), /* positionUs= */ eq(0L))) + .thenReturn(0L); + PreloadMediaPeriod preloadMediaPeriod = new PreloadMediaPeriod(wrappedMediaPeriod); + MediaPeriod.Callback callback = + new MediaPeriod.Callback() { + @Override + public void onPrepared(MediaPeriod mediaPeriod) {} + + @Override + public void onContinueLoadingRequested(MediaPeriod source) {} + }; + preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); + // Select tracks for preloading. + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); + verify(wrappedMediaPeriod).prepare(any(), anyLong()); + verify(wrappedMediaPeriod) + .selectTracks(eq(preloadTrackSelections), any(), any(), any(), /* positionUs= */ eq(0L)); + verifyNoMoreInteractions(wrappedMediaPeriod); + reset(wrappedMediaPeriod); + // Create a new track selections. + ExoTrackSelection[] newTrackSelections = + new ExoTrackSelection[] { + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setWidth(1920) + .setHeight(1080) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build(), + new Format.Builder() + .setWidth(3840) + .setHeight(2160) + .setSampleMimeType(MimeTypes.VIDEO_H264) + .build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()), + /* selectedIndex= */ 0), + // An adaptive track group for text is practically not possible. The hypothetical case has + // been created for test coverage. + new FakeTrackSelection( + new TrackGroup( + new Format.Builder() + .setSampleMimeType(MimeTypes.TEXT_VTT) + .setLanguage("de") + .build(), + new Format.Builder() + .setSampleMimeType(MimeTypes.TEXT_VTT) + .setLanguage("en") + .build()), + /* selectedIndex= */ 1) + }; + when(wrappedMediaPeriod.selectTracks( + eq(newTrackSelections), any(), any(), any(), /* positionUs= */ eq(0L))) + .thenReturn(0L); + + // Select tracks for preloading the second time based on the new track selections. The + // selectTracks method of the wrapped media period must be called again. + long trackSelectionStartPositionUs = + preloadMediaPeriod.selectTracksForPreloading(newTrackSelections, /* positionUs= */ 0L); + + verify(wrappedMediaPeriod) + .selectTracks( + eq(newTrackSelections), + /* mayRetainStreamFlags= */ eq(new boolean[] {true, true, false}), + /* streams= */ any(), + /* streamResetFlags= */ any(), + /* positionUs= */ eq(0L)); + verifyNoMoreInteractions(wrappedMediaPeriod); + assertThat(trackSelectionStartPositionUs).isEqualTo(0L); + } + + @Test + public void + selectTracksForPreloadingSecondTime_forSameSelectionsButAtDifferentPosition_callOnWrappedPeriod() { + MediaPeriod wrappedMediaPeriod = mock(MediaPeriod.class); + ExoTrackSelection[] preloadTrackSelections = + new ExoTrackSelection[] { + new FakeTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_AAC).build()), + /* selectedIndex= */ 0), + new FakeTrackSelection( + new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build()), + /* selectedIndex= */ 0) + }; + when(wrappedMediaPeriod.selectTracks( + eq(preloadTrackSelections), any(), any(), any(), /* positionUs= */ eq(0L))) + .thenReturn(0L); + PreloadMediaPeriod preloadMediaPeriod = new PreloadMediaPeriod(wrappedMediaPeriod); + MediaPeriod.Callback callback = + new MediaPeriod.Callback() { + @Override + public void onPrepared(MediaPeriod mediaPeriod) {} + + @Override + public void onContinueLoadingRequested(MediaPeriod source) {} + }; + preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); + // Select tracks for preloading. + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); + verify(wrappedMediaPeriod).prepare(any(), anyLong()); + verify(wrappedMediaPeriod) + .selectTracks( + eq(preloadTrackSelections), + /* mayRetainStreamFlags= */ eq(new boolean[] {false, false}), + /* streams= */ any(), + /* streamResetFlags= */ any(), + /* positionUs= */ eq(0L)); + verifyNoMoreInteractions(wrappedMediaPeriod); + reset(wrappedMediaPeriod); + when(wrappedMediaPeriod.selectTracks( + eq(preloadTrackSelections), + /* mayRetainStreamFlags= */ eq(new boolean[] {false, false}), + /* streams= */ any(), + /* streamResetFlags= */ any(), + /* positionUs= */ eq(1234L))) + .thenReturn(1234L); + + // Select tracks for preloading based on the same track selections but at a different position. + long trackSelectionStartPositionUs = + preloadMediaPeriod.selectTracksForPreloading( + preloadTrackSelections, /* positionUs= */ 1234L); + + verify(wrappedMediaPeriod) + .selectTracks( + eq(preloadTrackSelections), + /* mayRetainStreamFlags= */ eq(new boolean[] {false, false}), + /* streams= */ any(), + /* streamResetFlags= */ any(), + /* positionUs= */ eq(1234L)); + verifyNoMoreInteractions(wrappedMediaPeriod); + assertThat(trackSelectionStartPositionUs).isEqualTo(1234L); + } + @Test public void selectTracks_afterPreloadingForSameSelections_usePreloadedStreams() { MediaPeriod wrappedMediaPeriod = mock(MediaPeriod.class); @@ -235,14 +635,6 @@ public final class PreloadMediaPeriodTest { new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build()), /* track= */ 0) }; - TrackSelectorResult preloadTrackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, RendererConfiguration.DEFAULT - }, - preloadTrackSelections, - Tracks.EMPTY, - /* info= */ null); SampleStream[] preloadedStreams = new SampleStream[] {new EmptySampleStream(), new EmptySampleStream()}; when(wrappedMediaPeriod.selectTracks( @@ -272,8 +664,7 @@ public final class PreloadMediaPeriodTest { preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); // Select tracks for preloading. long preloadTrackSelectionStartPositionUs = - preloadMediaPeriod.selectTracksForPreloading( - preloadTrackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); SampleStream[] streams = new SampleStream[2]; boolean[] streamResetFlags = new boolean[2]; @@ -315,16 +706,6 @@ public final class PreloadMediaPeriodTest { .build()), /* selectedIndex= */ 0) }; - TrackSelectorResult preloadTrackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT - }, - preloadTrackSelections, - Tracks.EMPTY, - /* info= */ null); SampleStream[] preloadedStreams = new SampleStream[] { new EmptySampleStream(), new EmptySampleStream(), new EmptySampleStream() @@ -359,7 +740,7 @@ public final class PreloadMediaPeriodTest { }; preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); // Select tracks for preloading. - preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); verify(wrappedMediaPeriod).prepare(any(), anyLong()); verify(wrappedMediaPeriod) .selectTracks( @@ -466,16 +847,6 @@ public final class PreloadMediaPeriodTest { .build()), /* selectedIndex= */ 0) }; - TrackSelectorResult preloadTrackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT - }, - preloadTrackSelections, - Tracks.EMPTY, - /* info= */ null); SampleStream[] preloadedStreams = new SampleStream[] { new EmptySampleStream(), new EmptySampleStream(), new EmptySampleStream() @@ -506,7 +877,7 @@ public final class PreloadMediaPeriodTest { }; preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); // Select tracks for preloading. - preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); verify(wrappedMediaPeriod).prepare(any(), anyLong()); verify(wrappedMediaPeriod) .selectTracks( @@ -557,7 +928,7 @@ public final class PreloadMediaPeriodTest { } @Test - public void selectTracks_afterPreloadingForDifferentAdaptiveAudioSelection_usePreloadStreams() { + public void selectTracks_afterPreloadingForDifferentAdaptiveAudioSelection_usePreloadedStreams() { MediaPeriod wrappedMediaPeriod = mock(MediaPeriod.class); ExoTrackSelection[] preloadTrackSelections = new ExoTrackSelection[] { @@ -587,16 +958,6 @@ public final class PreloadMediaPeriodTest { .build()), /* selectedIndex= */ 0) }; - TrackSelectorResult preloadTrackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT - }, - preloadTrackSelections, - Tracks.EMPTY, - /* info= */ null); SampleStream[] preloadedStreams = new SampleStream[] { new EmptySampleStream(), new EmptySampleStream(), new EmptySampleStream() @@ -627,7 +988,7 @@ public final class PreloadMediaPeriodTest { }; preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); // Select tracks for preloading. - preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); verify(wrappedMediaPeriod).prepare(any(), anyLong()); verify(wrappedMediaPeriod) .selectTracks( @@ -715,16 +1076,6 @@ public final class PreloadMediaPeriodTest { .build()), /* selectedIndex= */ 0) }; - TrackSelectorResult trackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT - }, - trackSelections, - Tracks.EMPTY, - /* info= */ null); SampleStream[] preloadedStreams = new SampleStream[] { new EmptySampleStream(), new EmptySampleStream(), new EmptySampleStream() @@ -752,7 +1103,7 @@ public final class PreloadMediaPeriodTest { }; preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); // Select tracks for preloading. - preloadMediaPeriod.selectTracksForPreloading(trackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(trackSelections, /* positionUs= */ 0L); verify(wrappedMediaPeriod).prepare(any(), anyLong()); verify(wrappedMediaPeriod) .selectTracks(eq(trackSelections), any(), any(), any(), /* positionUs= */ eq(0L)); @@ -863,16 +1214,6 @@ public final class PreloadMediaPeriodTest { .build()), /* selectedIndex= */ 0) }; - TrackSelectorResult preloadTrackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT - }, - preloadTrackSelections, - Tracks.EMPTY, - /* info= */ null); SampleStream[] preloadedStreams = new SampleStream[] { new EmptySampleStream(), new EmptySampleStream(), new EmptySampleStream() @@ -900,7 +1241,7 @@ public final class PreloadMediaPeriodTest { }; preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); // Select tracks for preloading. - preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); verify(wrappedMediaPeriod).prepare(any(), anyLong()); verify(wrappedMediaPeriod) .selectTracks( @@ -999,16 +1340,6 @@ public final class PreloadMediaPeriodTest { .build()), /* selectedIndex= */ 0) }; - TrackSelectorResult preloadTrackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT, - RendererConfiguration.DEFAULT - }, - preloadTrackSelections, - Tracks.EMPTY, - /* info= */ null); SampleStream[] preloadedStreams = new SampleStream[] {new EmptySampleStream(), null, new EmptySampleStream()}; when(wrappedMediaPeriod.selectTracks( @@ -1038,7 +1369,7 @@ public final class PreloadMediaPeriodTest { }; preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); // Select tracks for preloading. - preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); verify(wrappedMediaPeriod).prepare(any(), anyLong()); verify(wrappedMediaPeriod) .selectTracks( @@ -1135,14 +1466,6 @@ public final class PreloadMediaPeriodTest { new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build()), /* selectedIndex= */ 0) }; - TrackSelectorResult preloadTrackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, RendererConfiguration.DEFAULT - }, - preloadTrackSelections, - Tracks.EMPTY, - /* info= */ null); SampleStream[] preloadedStreams = new SampleStream[] {new EmptySampleStream(), new EmptySampleStream()}; when(wrappedMediaPeriod.selectTracks( @@ -1171,7 +1494,7 @@ public final class PreloadMediaPeriodTest { }; preloadMediaPeriod.prepare(callback, /* positionUs= */ 0L); // Select tracks for preloading. - preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(preloadTrackSelections, /* positionUs= */ 0L); verify(wrappedMediaPeriod).prepare(any(), anyLong()); verify(wrappedMediaPeriod) .selectTracks( @@ -1238,14 +1561,6 @@ public final class PreloadMediaPeriodTest { new TrackGroup(new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_H264).build()), /* track= */ 0) }; - TrackSelectorResult trackSelectorResult = - new TrackSelectorResult( - new RendererConfiguration[] { - RendererConfiguration.DEFAULT, RendererConfiguration.DEFAULT - }, - trackSelections, - Tracks.EMPTY, - /* info= */ null); when(wrappedMediaPeriod.selectTracks( eq(trackSelections), any(), any(), any(), /* positionUs= */ eq(0L))) .thenReturn(0L); @@ -1262,7 +1577,7 @@ public final class PreloadMediaPeriodTest { verify(wrappedMediaPeriod).prepare(any(), /* positionUs= */ eq(0L)); // Select tracks for preloading. - preloadMediaPeriod.selectTracksForPreloading(trackSelectorResult, /* positionUs= */ 0L); + preloadMediaPeriod.selectTracksForPreloading(trackSelections, /* positionUs= */ 0L); verify(wrappedMediaPeriod) .selectTracks(eq(trackSelections), any(), any(), any(), /* positionUs= */ eq(0L)); SampleStream[] streams = new SampleStream[2];