CompositeSequenceableLoader
: Prefer buffered position of A/V tracks
Preferring audio and video tracks matches logic we already have in
[`ProgressiveMediaPeriod.getBufferedPositionUs`](f6fe90f30b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ProgressiveMediaPeriod.java (L403)
).
PiperOrigin-RevId: 599154217
This commit is contained in:
parent
80bfa819c0
commit
406c0a15be
@ -15,39 +15,80 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.exoplayer.source;
|
package androidx.media3.exoplayer.source;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||||
import static java.lang.Math.min;
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.exoplayer.LoadingInfo;
|
import androidx.media3.exoplayer.LoadingInfo;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/** A {@link SequenceableLoader} that encapsulates multiple other {@link SequenceableLoader}s. */
|
/** A {@link SequenceableLoader} that encapsulates multiple other {@link SequenceableLoader}s. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final class CompositeSequenceableLoader implements SequenceableLoader {
|
public final class CompositeSequenceableLoader implements SequenceableLoader {
|
||||||
|
|
||||||
private final SequenceableLoader[] loaders;
|
private final ImmutableList<SequenceableLoaderWithTrackTypes> loadersWithTrackTypes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link CompositeSequenceableLoader#CompositeSequenceableLoader(List, List)}
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public CompositeSequenceableLoader(SequenceableLoader[] loaders) {
|
public CompositeSequenceableLoader(SequenceableLoader[] loaders) {
|
||||||
this.loaders = loaders;
|
this(
|
||||||
|
ImmutableList.copyOf(loaders),
|
||||||
|
Collections.nCopies(loaders.length, ImmutableList.of(C.TRACK_TYPE_UNKNOWN)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompositeSequenceableLoader(
|
||||||
|
List<? extends SequenceableLoader> loaders,
|
||||||
|
List<List<@C.TrackType Integer>> loaderTrackTypes) {
|
||||||
|
ImmutableList.Builder<SequenceableLoaderWithTrackTypes> loaderAndTrackTypes =
|
||||||
|
ImmutableList.builder();
|
||||||
|
checkArgument(loaders.size() == loaderTrackTypes.size());
|
||||||
|
for (int i = 0; i < loaders.size(); i++) {
|
||||||
|
loaderAndTrackTypes.add(
|
||||||
|
new SequenceableLoaderWithTrackTypes(loaders.get(i), loaderTrackTypes.get(i)));
|
||||||
|
}
|
||||||
|
this.loadersWithTrackTypes = loaderAndTrackTypes.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getBufferedPositionUs() {
|
public long getBufferedPositionUs() {
|
||||||
long bufferedPositionUs = Long.MAX_VALUE;
|
long bufferedPositionUs = Long.MAX_VALUE;
|
||||||
for (SequenceableLoader loader : loaders) {
|
boolean hasAudioVideoTracks = false;
|
||||||
|
long bufferedPositionAudioVideoUs = Long.MAX_VALUE;
|
||||||
|
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
|
||||||
|
SequenceableLoaderWithTrackTypes loader = loadersWithTrackTypes.get(i);
|
||||||
long loaderBufferedPositionUs = loader.getBufferedPositionUs();
|
long loaderBufferedPositionUs = loader.getBufferedPositionUs();
|
||||||
|
if (loader.getTrackTypes().contains(C.TRACK_TYPE_AUDIO)
|
||||||
|
|| loader.getTrackTypes().contains(C.TRACK_TYPE_VIDEO)) {
|
||||||
|
hasAudioVideoTracks = true;
|
||||||
|
if (loaderBufferedPositionUs != C.TIME_END_OF_SOURCE) {
|
||||||
|
bufferedPositionAudioVideoUs =
|
||||||
|
min(bufferedPositionAudioVideoUs, loaderBufferedPositionUs);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (loaderBufferedPositionUs != C.TIME_END_OF_SOURCE) {
|
if (loaderBufferedPositionUs != C.TIME_END_OF_SOURCE) {
|
||||||
bufferedPositionUs = min(bufferedPositionUs, loaderBufferedPositionUs);
|
bufferedPositionUs = min(bufferedPositionUs, loaderBufferedPositionUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bufferedPositionUs == Long.MAX_VALUE ? C.TIME_END_OF_SOURCE : bufferedPositionUs;
|
if (hasAudioVideoTracks) {
|
||||||
|
return bufferedPositionAudioVideoUs != Long.MAX_VALUE
|
||||||
|
? bufferedPositionAudioVideoUs
|
||||||
|
: C.TIME_END_OF_SOURCE;
|
||||||
|
} else {
|
||||||
|
return bufferedPositionUs != Long.MAX_VALUE ? bufferedPositionUs : C.TIME_END_OF_SOURCE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getNextLoadPositionUs() {
|
public long getNextLoadPositionUs() {
|
||||||
long nextLoadPositionUs = Long.MAX_VALUE;
|
long nextLoadPositionUs = Long.MAX_VALUE;
|
||||||
for (SequenceableLoader loader : loaders) {
|
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
|
||||||
long loaderNextLoadPositionUs = loader.getNextLoadPositionUs();
|
long loaderNextLoadPositionUs = loadersWithTrackTypes.get(i).getNextLoadPositionUs();
|
||||||
if (loaderNextLoadPositionUs != C.TIME_END_OF_SOURCE) {
|
if (loaderNextLoadPositionUs != C.TIME_END_OF_SOURCE) {
|
||||||
nextLoadPositionUs = min(nextLoadPositionUs, loaderNextLoadPositionUs);
|
nextLoadPositionUs = min(nextLoadPositionUs, loaderNextLoadPositionUs);
|
||||||
}
|
}
|
||||||
@ -57,8 +98,8 @@ public final class CompositeSequenceableLoader implements SequenceableLoader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reevaluateBuffer(long positionUs) {
|
public void reevaluateBuffer(long positionUs) {
|
||||||
for (SequenceableLoader loader : loaders) {
|
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
|
||||||
loader.reevaluateBuffer(positionUs);
|
loadersWithTrackTypes.get(i).reevaluateBuffer(positionUs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,13 +113,13 @@ public final class CompositeSequenceableLoader implements SequenceableLoader {
|
|||||||
if (nextLoadPositionUs == C.TIME_END_OF_SOURCE) {
|
if (nextLoadPositionUs == C.TIME_END_OF_SOURCE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (SequenceableLoader loader : loaders) {
|
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
|
||||||
long loaderNextLoadPositionUs = loader.getNextLoadPositionUs();
|
long loaderNextLoadPositionUs = loadersWithTrackTypes.get(i).getNextLoadPositionUs();
|
||||||
boolean isLoaderBehind =
|
boolean isLoaderBehind =
|
||||||
loaderNextLoadPositionUs != C.TIME_END_OF_SOURCE
|
loaderNextLoadPositionUs != C.TIME_END_OF_SOURCE
|
||||||
&& loaderNextLoadPositionUs <= loadingInfo.playbackPositionUs;
|
&& loaderNextLoadPositionUs <= loadingInfo.playbackPositionUs;
|
||||||
if (loaderNextLoadPositionUs == nextLoadPositionUs || isLoaderBehind) {
|
if (loaderNextLoadPositionUs == nextLoadPositionUs || isLoaderBehind) {
|
||||||
madeProgressThisIteration |= loader.continueLoading(loadingInfo);
|
madeProgressThisIteration |= loadersWithTrackTypes.get(i).continueLoading(loadingInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
madeProgress |= madeProgressThisIteration;
|
madeProgress |= madeProgressThisIteration;
|
||||||
@ -88,11 +129,54 @@ public final class CompositeSequenceableLoader implements SequenceableLoader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoading() {
|
public boolean isLoading() {
|
||||||
for (SequenceableLoader loader : loaders) {
|
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
|
||||||
if (loader.isLoading()) {
|
if (loadersWithTrackTypes.get(i).isLoading()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class SequenceableLoaderWithTrackTypes implements SequenceableLoader {
|
||||||
|
|
||||||
|
private final SequenceableLoader loader;
|
||||||
|
private final ImmutableList<@C.TrackType Integer> trackTypes;
|
||||||
|
|
||||||
|
public SequenceableLoaderWithTrackTypes(
|
||||||
|
SequenceableLoader loader, List<@C.TrackType Integer> trackTypes) {
|
||||||
|
this.loader = loader;
|
||||||
|
this.trackTypes = ImmutableList.copyOf(trackTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutableList<@C.TrackType Integer> getTrackTypes() {
|
||||||
|
return trackTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SequenceableLoader implementation
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBufferedPositionUs() {
|
||||||
|
return loader.getBufferedPositionUs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getNextLoadPositionUs() {
|
||||||
|
return loader.getNextLoadPositionUs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean continueLoading(LoadingInfo loadingInfo) {
|
||||||
|
return loader.continueLoading(loadingInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLoading() {
|
||||||
|
return loader.isLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reevaluateBuffer(long positionUs) {
|
||||||
|
loader.reevaluateBuffer(positionUs);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,17 +15,33 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.exoplayer.source;
|
package androidx.media3.exoplayer.source;
|
||||||
|
|
||||||
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/** A factory to create composite {@link SequenceableLoader}s. */
|
/** A factory to create composite {@link SequenceableLoader}s. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public interface CompositeSequenceableLoaderFactory {
|
public interface CompositeSequenceableLoaderFactory {
|
||||||
|
|
||||||
|
/** Returns an empty composite {@link SequenceableLoader}, with no delegate loaders. */
|
||||||
|
SequenceableLoader empty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #empty()} for an empty composite loader, or {@link #create(List, List)}
|
||||||
|
* for a non-empty one.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
SequenceableLoader createCompositeSequenceableLoader(SequenceableLoader... loaders);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a composite {@link SequenceableLoader}.
|
* Creates a composite {@link SequenceableLoader}.
|
||||||
*
|
*
|
||||||
* @param loaders The sub-loaders that make up the {@link SequenceableLoader} to be built.
|
* @param loaders The sub-loaders that make up the {@link SequenceableLoader} to be built.
|
||||||
|
* @param loaderTrackTypes The track types handled by each entry in {@code loaders}. Must be the
|
||||||
|
* same as {@code loaders}.
|
||||||
* @return A composite {@link SequenceableLoader} that comprises the given loaders.
|
* @return A composite {@link SequenceableLoader} that comprises the given loaders.
|
||||||
*/
|
*/
|
||||||
SequenceableLoader createCompositeSequenceableLoader(SequenceableLoader... loaders);
|
SequenceableLoader create(
|
||||||
|
List<? extends SequenceableLoader> loaders,
|
||||||
|
List<List<@C.TrackType Integer>> loaderTrackTypes);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.exoplayer.source;
|
package androidx.media3.exoplayer.source;
|
||||||
|
|
||||||
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/** Default implementation of {@link CompositeSequenceableLoaderFactory}. */
|
/** Default implementation of {@link CompositeSequenceableLoaderFactory}. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
@ -23,7 +26,21 @@ public final class DefaultCompositeSequenceableLoaderFactory
|
|||||||
implements CompositeSequenceableLoaderFactory {
|
implements CompositeSequenceableLoaderFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public SequenceableLoader empty() {
|
||||||
|
return new CompositeSequenceableLoader(ImmutableList.of(), ImmutableList.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation") // Calling deprecated constructor
|
||||||
public SequenceableLoader createCompositeSequenceableLoader(SequenceableLoader... loaders) {
|
public SequenceableLoader createCompositeSequenceableLoader(SequenceableLoader... loaders) {
|
||||||
return new CompositeSequenceableLoader(loaders);
|
return new CompositeSequenceableLoader(loaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SequenceableLoader create(
|
||||||
|
List<? extends SequenceableLoader> loaders,
|
||||||
|
List<List<@C.TrackType Integer>> loaderTrackTypes) {
|
||||||
|
return new CompositeSequenceableLoader(loaders, loaderTrackTypes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import androidx.media3.exoplayer.source.chunk.Chunk;
|
|||||||
import androidx.media3.exoplayer.source.chunk.MediaChunk;
|
import androidx.media3.exoplayer.source.chunk.MediaChunk;
|
||||||
import androidx.media3.exoplayer.source.chunk.MediaChunkIterator;
|
import androidx.media3.exoplayer.source.chunk.MediaChunkIterator;
|
||||||
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -58,8 +59,7 @@ import java.util.List;
|
|||||||
this.periods = periods;
|
this.periods = periods;
|
||||||
childrenPendingPreparation = new ArrayList<>();
|
childrenPendingPreparation = new ArrayList<>();
|
||||||
childTrackGroupByMergedTrackGroup = new HashMap<>();
|
childTrackGroupByMergedTrackGroup = new HashMap<>();
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader = compositeSequenceableLoaderFactory.empty();
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader();
|
|
||||||
streamPeriodIndices = new IdentityHashMap<>();
|
streamPeriodIndices = new IdentityHashMap<>();
|
||||||
enabledPeriods = new MediaPeriod[0];
|
enabledPeriods = new MediaPeriod[0];
|
||||||
for (int i = 0; i < periods.length; i++) {
|
for (int i = 0; i < periods.length; i++) {
|
||||||
@ -172,7 +172,9 @@ import java.util.List;
|
|||||||
// Update the local state.
|
// Update the local state.
|
||||||
enabledPeriods = enabledPeriodsList.toArray(new MediaPeriod[0]);
|
enabledPeriods = enabledPeriodsList.toArray(new MediaPeriod[0]);
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader =
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(enabledPeriods);
|
compositeSequenceableLoaderFactory.create(
|
||||||
|
enabledPeriodsList,
|
||||||
|
Lists.transform(enabledPeriodsList, period -> period.getTrackGroups().getTrackTypes()));
|
||||||
return positionUs;
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import androidx.media3.common.util.Log;
|
|||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,6 +91,11 @@ public final class TrackGroupArray implements Bundleable {
|
|||||||
return length == 0;
|
return length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the {@link TrackGroup#type} of each track group in this array. */
|
||||||
|
public ImmutableList<@C.TrackType Integer> getTrackTypes() {
|
||||||
|
return ImmutableList.copyOf(Lists.transform(trackGroups, t -> t.type));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
if (hashCode == 0) {
|
if (hashCode == 0) {
|
||||||
|
@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.exoplayer.LoadingInfo;
|
import androidx.media3.exoplayer.LoadingInfo;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
@ -38,7 +39,10 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
FakeSequenceableLoader loader2 =
|
FakeSequenceableLoader loader2 =
|
||||||
new FakeSequenceableLoader(/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ 2001);
|
new FakeSequenceableLoader(/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ 2001);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO), ImmutableList.of(C.TRACK_TYPE_VIDEO)));
|
||||||
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(1000);
|
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +61,12 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
/* bufferedPositionUs */ C.TIME_END_OF_SOURCE,
|
/* bufferedPositionUs */ C.TIME_END_OF_SOURCE,
|
||||||
/* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
/* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2, loader3});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2, loader3),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO),
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_VIDEO),
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO)));
|
||||||
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(1000);
|
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,10 +85,73 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
/* bufferedPositionUs */ C.TIME_END_OF_SOURCE,
|
/* bufferedPositionUs */ C.TIME_END_OF_SOURCE,
|
||||||
/* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
/* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO), ImmutableList.of(C.TRACK_TYPE_VIDEO)));
|
||||||
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(C.TIME_END_OF_SOURCE);
|
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(C.TIME_END_OF_SOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link CompositeSequenceableLoader#getBufferedPositionUs()} returns the minimum
|
||||||
|
* buffered position of loaders with audio or video tracks (if at least one loader has tracks of
|
||||||
|
* these types).
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void getBufferedPositionUs_prefersLoadersWithAudioAndVideoTracks() {
|
||||||
|
FakeSequenceableLoader loaderWithTextOnly =
|
||||||
|
new FakeSequenceableLoader(/* bufferedPositionUs= */ 999, /* nextLoadPositionUs= */ 2000);
|
||||||
|
FakeSequenceableLoader loaderWithAudioVideoAndText =
|
||||||
|
new FakeSequenceableLoader(/* bufferedPositionUs= */ 1000, /* nextLoadPositionUs= */ 2000);
|
||||||
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loaderWithTextOnly, loaderWithAudioVideoAndText),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_TEXT),
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_TEXT)));
|
||||||
|
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link CompositeSequenceableLoader#getBufferedPositionUs()} returns the minimum
|
||||||
|
* buffered position of loaders with audio or video tracks (if at least one loader has tracks of
|
||||||
|
* these types).
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void getBufferedPositionUs_prefersLoadersWithAudioAndVideoTracks_endOfSource() {
|
||||||
|
FakeSequenceableLoader loaderWithTextOnly =
|
||||||
|
new FakeSequenceableLoader(/* bufferedPositionUs= */ 999, /* nextLoadPositionUs= */ 2000);
|
||||||
|
FakeSequenceableLoader loaderWithAudioVideoAndText =
|
||||||
|
new FakeSequenceableLoader(
|
||||||
|
/* bufferedPositionUs */ C.TIME_END_OF_SOURCE, /* nextLoadPositionUs */
|
||||||
|
C.TIME_END_OF_SOURCE);
|
||||||
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loaderWithTextOnly, loaderWithAudioVideoAndText),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_TEXT),
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_TEXT)));
|
||||||
|
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(C.TIME_END_OF_SOURCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that {@link CompositeSequenceableLoader#getBufferedPositionUs()} returns the minimum
|
||||||
|
* buffered position of all loaders if no loader has audio or video tracks.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void getBufferedPositionUs_considersAllTracksIfNoneAreAudioOrVideo() {
|
||||||
|
FakeSequenceableLoader loaderWithTextOnly =
|
||||||
|
new FakeSequenceableLoader(/* bufferedPositionUs= */ 999, /* nextLoadPositionUs= */ 2000);
|
||||||
|
FakeSequenceableLoader loaderWithMetadataOnly =
|
||||||
|
new FakeSequenceableLoader(/* bufferedPositionUs= */ 1000, /* nextLoadPositionUs= */ 2000);
|
||||||
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loaderWithTextOnly, loaderWithMetadataOnly),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_TEXT), ImmutableList.of(C.TRACK_TYPE_METADATA)));
|
||||||
|
assertThat(compositeSequenceableLoader.getBufferedPositionUs()).isEqualTo(999);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that {@link CompositeSequenceableLoader#getNextLoadPositionUs()} returns minimum next
|
* Tests that {@link CompositeSequenceableLoader#getNextLoadPositionUs()} returns minimum next
|
||||||
* load position among all sub-loaders.
|
* load position among all sub-loaders.
|
||||||
@ -91,7 +163,10 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
FakeSequenceableLoader loader2 =
|
FakeSequenceableLoader loader2 =
|
||||||
new FakeSequenceableLoader(/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ 2000);
|
new FakeSequenceableLoader(/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ 2000);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO), ImmutableList.of(C.TRACK_TYPE_VIDEO)));
|
||||||
assertThat(compositeSequenceableLoader.getNextLoadPositionUs()).isEqualTo(2000);
|
assertThat(compositeSequenceableLoader.getNextLoadPositionUs()).isEqualTo(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +184,12 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
new FakeSequenceableLoader(
|
new FakeSequenceableLoader(
|
||||||
/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2, loader3});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2, loader3),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO),
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_VIDEO),
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO)));
|
||||||
assertThat(compositeSequenceableLoader.getNextLoadPositionUs()).isEqualTo(2000);
|
assertThat(compositeSequenceableLoader.getNextLoadPositionUs()).isEqualTo(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +206,10 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
new FakeSequenceableLoader(
|
new FakeSequenceableLoader(
|
||||||
/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO), ImmutableList.of(C.TRACK_TYPE_VIDEO)));
|
||||||
assertThat(compositeSequenceableLoader.getNextLoadPositionUs()).isEqualTo(C.TIME_END_OF_SOURCE);
|
assertThat(compositeSequenceableLoader.getNextLoadPositionUs()).isEqualTo(C.TIME_END_OF_SOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +225,10 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
FakeSequenceableLoader loader2 =
|
FakeSequenceableLoader loader2 =
|
||||||
new FakeSequenceableLoader(/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ 2001);
|
new FakeSequenceableLoader(/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ 2001);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO), ImmutableList.of(C.TRACK_TYPE_VIDEO)));
|
||||||
compositeSequenceableLoader.continueLoading(
|
compositeSequenceableLoader.continueLoading(
|
||||||
new LoadingInfo.Builder().setPlaybackPositionUs(100).build());
|
new LoadingInfo.Builder().setPlaybackPositionUs(100).build());
|
||||||
|
|
||||||
@ -163,7 +249,12 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
FakeSequenceableLoader loader3 =
|
FakeSequenceableLoader loader3 =
|
||||||
new FakeSequenceableLoader(/* bufferedPositionUs */ 1002, /* nextLoadPositionUs */ 2002);
|
new FakeSequenceableLoader(/* bufferedPositionUs */ 1002, /* nextLoadPositionUs */ 2002);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2, loader3});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2, loader3),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO),
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_VIDEO),
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO)));
|
||||||
compositeSequenceableLoader.continueLoading(
|
compositeSequenceableLoader.continueLoading(
|
||||||
new LoadingInfo.Builder().setPlaybackPositionUs(3000).build());
|
new LoadingInfo.Builder().setPlaybackPositionUs(3000).build());
|
||||||
|
|
||||||
@ -185,7 +276,10 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
new FakeSequenceableLoader(
|
new FakeSequenceableLoader(
|
||||||
/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
/* bufferedPositionUs */ 1001, /* nextLoadPositionUs */ C.TIME_END_OF_SOURCE);
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO), ImmutableList.of(C.TRACK_TYPE_VIDEO)));
|
||||||
compositeSequenceableLoader.continueLoading(
|
compositeSequenceableLoader.continueLoading(
|
||||||
new LoadingInfo.Builder().setPlaybackPositionUs(3000).build());
|
new LoadingInfo.Builder().setPlaybackPositionUs(3000).build());
|
||||||
|
|
||||||
@ -207,7 +301,10 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
loader1.setNextChunkDurationUs(1000);
|
loader1.setNextChunkDurationUs(1000);
|
||||||
|
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO), ImmutableList.of(C.TRACK_TYPE_VIDEO)));
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
compositeSequenceableLoader.continueLoading(
|
compositeSequenceableLoader.continueLoading(
|
||||||
@ -230,7 +327,10 @@ public final class CompositeSequenceableLoaderTest {
|
|||||||
loader2.setNextChunkDurationUs(1000);
|
loader2.setNextChunkDurationUs(1000);
|
||||||
|
|
||||||
CompositeSequenceableLoader compositeSequenceableLoader =
|
CompositeSequenceableLoader compositeSequenceableLoader =
|
||||||
new CompositeSequenceableLoader(new SequenceableLoader[] {loader1, loader2});
|
new CompositeSequenceableLoader(
|
||||||
|
ImmutableList.of(loader1, loader2),
|
||||||
|
ImmutableList.of(
|
||||||
|
ImmutableList.of(C.TRACK_TYPE_AUDIO), ImmutableList.of(C.TRACK_TYPE_VIDEO)));
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
compositeSequenceableLoader.continueLoading(
|
compositeSequenceableLoader.continueLoading(
|
||||||
|
@ -60,6 +60,7 @@ import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
|||||||
import androidx.media3.exoplayer.upstream.LoaderErrorThrower;
|
import androidx.media3.exoplayer.upstream.LoaderErrorThrower;
|
||||||
import androidx.media3.extractor.text.SubtitleParser;
|
import androidx.media3.extractor.text.SubtitleParser;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -154,8 +155,7 @@ import java.util.regex.Pattern;
|
|||||||
sampleStreams = newSampleStreamArray(0);
|
sampleStreams = newSampleStreamArray(0);
|
||||||
eventSampleStreams = new EventSampleStream[0];
|
eventSampleStreams = new EventSampleStream[0];
|
||||||
trackEmsgHandlerBySampleStream = new IdentityHashMap<>();
|
trackEmsgHandlerBySampleStream = new IdentityHashMap<>();
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader = compositeSequenceableLoaderFactory.empty();
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(sampleStreams);
|
|
||||||
Period period = manifest.getPeriod(periodIndex);
|
Period period = manifest.getPeriod(periodIndex);
|
||||||
eventStreams = period.eventStreams;
|
eventStreams = period.eventStreams;
|
||||||
Pair<TrackGroupArray, TrackGroupInfo[]> result =
|
Pair<TrackGroupArray, TrackGroupInfo[]> result =
|
||||||
@ -304,7 +304,9 @@ import java.util.regex.Pattern;
|
|||||||
eventSampleStreamList.toArray(eventSampleStreams);
|
eventSampleStreamList.toArray(eventSampleStreams);
|
||||||
|
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader =
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(sampleStreams);
|
compositeSequenceableLoaderFactory.create(
|
||||||
|
sampleStreamList,
|
||||||
|
Lists.transform(sampleStreamList, s -> ImmutableList.of(s.primaryTrackType)));
|
||||||
return positionUs;
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,8 @@ import androidx.media3.exoplayer.upstream.CmcdConfiguration;
|
|||||||
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
||||||
import androidx.media3.extractor.Extractor;
|
import androidx.media3.extractor.Extractor;
|
||||||
import androidx.media3.extractor.text.SubtitleParser;
|
import androidx.media3.extractor.text.SubtitleParser;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -160,8 +162,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
this.playerId = playerId;
|
this.playerId = playerId;
|
||||||
this.timestampAdjusterInitializationTimeoutMs = timestampAdjusterInitializationTimeoutMs;
|
this.timestampAdjusterInitializationTimeoutMs = timestampAdjusterInitializationTimeoutMs;
|
||||||
sampleStreamWrapperCallback = new SampleStreamWrapperCallback();
|
sampleStreamWrapperCallback = new SampleStreamWrapperCallback();
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader = compositeSequenceableLoaderFactory.empty();
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader();
|
|
||||||
streamWrapperIndices = new IdentityHashMap<>();
|
streamWrapperIndices = new IdentityHashMap<>();
|
||||||
timestampAdjusterProvider = new TimestampAdjusterProvider();
|
timestampAdjusterProvider = new TimestampAdjusterProvider();
|
||||||
sampleStreamWrappers = new HlsSampleStreamWrapper[0];
|
sampleStreamWrappers = new HlsSampleStreamWrapper[0];
|
||||||
@ -376,9 +377,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
// Update the local state.
|
// Update the local state.
|
||||||
enabledSampleStreamWrappers =
|
enabledSampleStreamWrappers =
|
||||||
Util.nullSafeArrayCopy(newEnabledSampleStreamWrappers, newEnabledSampleStreamWrapperCount);
|
Util.nullSafeArrayCopy(newEnabledSampleStreamWrappers, newEnabledSampleStreamWrapperCount);
|
||||||
|
ImmutableList<HlsSampleStreamWrapper> enabledSampleStreamWrappersList =
|
||||||
|
ImmutableList.copyOf(enabledSampleStreamWrappers);
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader =
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(
|
compositeSequenceableLoaderFactory.create(
|
||||||
enabledSampleStreamWrappers);
|
enabledSampleStreamWrappersList,
|
||||||
|
Lists.transform(
|
||||||
|
enabledSampleStreamWrappersList,
|
||||||
|
sampleStreamWrapper -> sampleStreamWrapper.getTrackGroups().getTrackTypes()));
|
||||||
return positionUs;
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ import androidx.media3.exoplayer.upstream.CmcdConfiguration;
|
|||||||
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
||||||
import androidx.media3.exoplayer.upstream.LoaderErrorThrower;
|
import androidx.media3.exoplayer.upstream.LoaderErrorThrower;
|
||||||
import androidx.media3.extractor.text.SubtitleParser;
|
import androidx.media3.extractor.text.SubtitleParser;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -94,8 +96,7 @@ import java.util.List;
|
|||||||
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
|
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
|
||||||
trackGroups = buildTrackGroups(manifest, drmSessionManager, subtitleParserFactory);
|
trackGroups = buildTrackGroups(manifest, drmSessionManager, subtitleParserFactory);
|
||||||
sampleStreams = newSampleStreamArray(0);
|
sampleStreams = newSampleStreamArray(0);
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader = compositeSequenceableLoaderFactory.empty();
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(sampleStreams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateManifest(SsManifest manifest) {
|
public void updateManifest(SsManifest manifest) {
|
||||||
@ -161,7 +162,9 @@ import java.util.List;
|
|||||||
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
|
sampleStreams = newSampleStreamArray(sampleStreamsList.size());
|
||||||
sampleStreamsList.toArray(sampleStreams);
|
sampleStreamsList.toArray(sampleStreams);
|
||||||
compositeSequenceableLoader =
|
compositeSequenceableLoader =
|
||||||
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(sampleStreams);
|
compositeSequenceableLoaderFactory.create(
|
||||||
|
sampleStreamsList,
|
||||||
|
Lists.transform(sampleStreamsList, s -> ImmutableList.of(s.primaryTrackType)));
|
||||||
return positionUs;
|
return positionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,9 @@ import androidx.media3.exoplayer.source.chunk.ChunkSampleStream;
|
|||||||
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
|
||||||
import androidx.media3.exoplayer.upstream.Allocator;
|
import androidx.media3.exoplayer.upstream.Allocator;
|
||||||
import androidx.media3.exoplayer.upstream.DefaultLoadErrorHandlingPolicy;
|
import androidx.media3.exoplayer.upstream.DefaultLoadErrorHandlingPolicy;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -86,7 +88,9 @@ public class FakeAdaptiveMediaPeriod
|
|||||||
this.durationUs = durationUs;
|
this.durationUs = durationUs;
|
||||||
this.transferListener = transferListener;
|
this.transferListener = transferListener;
|
||||||
sampleStreams = new ArrayList<>();
|
sampleStreams = new ArrayList<>();
|
||||||
sequenceableLoader = new CompositeSequenceableLoader(new SequenceableLoader[0]);
|
sequenceableLoader =
|
||||||
|
new CompositeSequenceableLoader(
|
||||||
|
/* loaders= */ ImmutableList.of(), /* loaderTrackTypes= */ ImmutableList.of());
|
||||||
fakePreparationLoadTaskId = LoadEventInfo.getNewId();
|
fakePreparationLoadTaskId = LoadEventInfo.getNewId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +101,9 @@ public class FakeAdaptiveMediaPeriod
|
|||||||
sampleStream.release();
|
sampleStream.release();
|
||||||
}
|
}
|
||||||
sampleStreams.clear();
|
sampleStreams.clear();
|
||||||
sequenceableLoader = new CompositeSequenceableLoader(new SequenceableLoader[0]);
|
sequenceableLoader =
|
||||||
|
new CompositeSequenceableLoader(
|
||||||
|
/* loaders= */ ImmutableList.of(), /* loaderTrackTypes= */ ImmutableList.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -143,7 +149,7 @@ public class FakeAdaptiveMediaPeriod
|
|||||||
return trackGroupArray;
|
return trackGroupArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"}) // Casting sample streams created by this class.
|
@SuppressWarnings({"unchecked"}) // Casting sample streams created by this class.
|
||||||
@Override
|
@Override
|
||||||
public long selectTracks(
|
public long selectTracks(
|
||||||
@NullableType ExoTrackSelection[] selections,
|
@NullableType ExoTrackSelection[] selections,
|
||||||
@ -188,7 +194,9 @@ public class FakeAdaptiveMediaPeriod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sequenceableLoader =
|
sequenceableLoader =
|
||||||
new CompositeSequenceableLoader(sampleStreams.toArray(new ChunkSampleStream[0]));
|
new CompositeSequenceableLoader(
|
||||||
|
sampleStreams,
|
||||||
|
Lists.transform(sampleStreams, s -> ImmutableList.of(s.primaryTrackType)));
|
||||||
return seekToUs(positionUs);
|
return seekToUs(positionUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user