mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Fix a bug in retaining streams when preload a PreloadMediaPeriod again
The `PreloadMediaPeriod.selectTracksForPreloading` can be called for multiple times at the preloading stage (before the period is being played). For example, when the period resumes preloading. This change fix the assertion failure in `ProgressiveMediaPeriod.selectTracks` caused by the wrong implementation of `PreloadMediaPeriod.selectTracksForPreloading` when it is trying to retain the previously preloaded streams. Also the `TrackSelectorResult` parameter is changed to a list of `ExoTrackSelection`. We should compare the selections only rather than considering the `RendererConfiguration` in the `TrackSelectorResult` to decide whether to retain the streams, as for preloading case the renderers haven't consumed the samples yet. PiperOrigin-RevId: 609126868
This commit is contained in:
parent
fde6a32156
commit
d952a06214
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user