Skip to content

Commit dbb99fe

Browse files
icbakerSheenaChhabra
authored andcommitted
Rollback of 406c0a1
PiperOrigin-RevId: 605015994 (cherry picked from commit 3a7a665)
1 parent 1dc4377 commit dbb99fe

File tree

11 files changed

+322
-42
lines changed

11 files changed

+322
-42
lines changed

‎libraries/exoplayer/src/androidTest/java/androidx/media3/exoplayer/ClippedPlaybackTest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.google.common.collect.Iterables;
3535
import java.util.ArrayList;
3636
import java.util.List;
37+
import java.util.concurrent.atomic.AtomicBoolean;
3738
import java.util.concurrent.atomic.AtomicReference;
3839
import org.junit.Test;
3940
import org.junit.runner.RunWith;
@@ -94,7 +95,7 @@ public void subtitlesRespectClipping_singlePeriod() throws Exception {
9495
player.get().addListener(textCapturer);
9596
player.get().setMediaItem(mediaItem);
9697
player.get().prepare();
97-
player.get().play();
98+
playWhenLoadingIsDone(player.get());
9899
});
99100

100101
textCapturer.block();
@@ -146,6 +147,9 @@ public void subtitlesRespectClipping_multiplePeriods() throws Exception {
146147
player.get().addListener(textCapturer);
147148
player.get().setMediaItems(mediaItems);
148149
player.get().prepare();
150+
// We don't need playWhenLoadingIsDone here because playback already waits at the end
151+
// of the first period for subtitles to be fully loaded beforetransitioning to the
152+
// second period.
149153
player.get().play();
150154
});
151155

@@ -157,6 +161,21 @@ public void subtitlesRespectClipping_multiplePeriods() throws Exception {
157161
.isEqualTo("This is the first subtitle.");
158162
}
159163

164+
private static void playWhenLoadingIsDone(Player player) {
165+
AtomicBoolean loadingStarted = new AtomicBoolean(false);
166+
player.addListener(
167+
new Player.Listener() {
168+
@Override
169+
public void onEvents(Player player, Player.Events events) {
170+
if (events.contains(Player.EVENT_IS_LOADING_CHANGED)
171+
&& loadingStarted.getAndSet(player.isLoading())
172+
&& !player.isLoading()) {
173+
player.play();
174+
}
175+
}
176+
});
177+
}
178+
160179
private static class TextCapturingPlaybackListener implements Player.Listener {
161180

162181
private final ConditionVariable playbackEnded;

‎libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/CompositeSequenceableLoader.java

Lines changed: 105 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,38 +15,88 @@
1515
*/
1616
package androidx.media3.exoplayer.source;
1717

18+
import static androidx.media3.common.util.Assertions.checkArgument;
1819
import static java.lang.Math.min;
1920

2021
import androidx.media3.common.C;
2122
import androidx.media3.common.util.UnstableApi;
2223
import androidx.media3.exoplayer.LoadingInfo;
24+
import com.google.common.collect.ImmutableList;
25+
import java.util.Collections;
26+
import java.util.List;
2327

2428
/** A {@link SequenceableLoader} that encapsulates multiple other {@link SequenceableLoader}s. */
2529
@UnstableApi
2630
public final class CompositeSequenceableLoader implements SequenceableLoader {
2731

28-
private final SequenceableLoader[] loaders;
32+
private final ImmutableList<SequenceableLoaderWithTrackTypes> loadersWithTrackTypes;
33+
private long lastAudioVideoBufferedPositionUs;
2934

35+
/**
36+
* @deprecated Use {@link CompositeSequenceableLoader#CompositeSequenceableLoader(List, List)}
37+
* instead.
38+
*/
39+
@Deprecated
3040
public CompositeSequenceableLoader(SequenceableLoader[] loaders) {
31-
this.loaders = loaders;
41+
this(
42+
ImmutableList.copyOf(loaders),
43+
Collections.nCopies(loaders.length, ImmutableList.of(C.TRACK_TYPE_UNKNOWN)));
44+
}
45+
46+
public CompositeSequenceableLoader(
47+
List<? extends SequenceableLoader> loaders,
48+
List<List<@C.TrackType Integer>> loaderTrackTypes) {
49+
ImmutableList.Builder<SequenceableLoaderWithTrackTypes> loaderAndTrackTypes =
50+
ImmutableList.builder();
51+
checkArgument(loaders.size() == loaderTrackTypes.size());
52+
for (int i = 0; i < loaders.size(); i++) {
53+
loaderAndTrackTypes.add(
54+
new SequenceableLoaderWithTrackTypes(loaders.get(i), loaderTrackTypes.get(i)));
55+
}
56+
this.loadersWithTrackTypes = loaderAndTrackTypes.build();
57+
this.lastAudioVideoBufferedPositionUs = C.TIME_UNSET;
3258
}
3359

3460
@Override
3561
public long getBufferedPositionUs() {
3662
long bufferedPositionUs = Long.MAX_VALUE;
37-
for (SequenceableLoader loader : loaders) {
63+
long bufferedPositionAudioVideoUs = Long.MAX_VALUE;
64+
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
65+
SequenceableLoaderWithTrackTypes loader = loadersWithTrackTypes.get(i);
3866
long loaderBufferedPositionUs = loader.getBufferedPositionUs();
67+
68+
if (loader.getTrackTypes().contains(C.TRACK_TYPE_AUDIO)
69+
|| loader.getTrackTypes().contains(C.TRACK_TYPE_VIDEO)
70+
|| loader.getTrackTypes().contains(C.TRACK_TYPE_IMAGE)) {
71+
if (loaderBufferedPositionUs != C.TIME_END_OF_SOURCE) {
72+
bufferedPositionAudioVideoUs =
73+
min(bufferedPositionAudioVideoUs, loaderBufferedPositionUs);
74+
}
75+
}
3976
if (loaderBufferedPositionUs != C.TIME_END_OF_SOURCE) {
4077
bufferedPositionUs = min(bufferedPositionUs, loaderBufferedPositionUs);
4178
}
4279
}
43-
return bufferedPositionUs == Long.MAX_VALUE ? C.TIME_END_OF_SOURCE : bufferedPositionUs;
80+
if (bufferedPositionAudioVideoUs != Long.MAX_VALUE) {
81+
lastAudioVideoBufferedPositionUs = bufferedPositionAudioVideoUs;
82+
return bufferedPositionAudioVideoUs;
83+
} else if (bufferedPositionUs != Long.MAX_VALUE) {
84+
// If lastAudioVideoBufferedPositionUs != C.TIME_UNSET, then we know there's at least one a/v
85+
// track (because this is the only time we end up assigning lastAudioVideoBufferedPositionUs
86+
// on a previous invocation).
87+
return lastAudioVideoBufferedPositionUs != C.TIME_UNSET
88+
? lastAudioVideoBufferedPositionUs
89+
: bufferedPositionUs;
90+
} else {
91+
return C.TIME_END_OF_SOURCE;
92+
}
4493
}
4594

4695
@Override
4796
public long getNextLoadPositionUs() {
4897
long nextLoadPositionUs = Long.MAX_VALUE;
49-
for (SequenceableLoader loader : loaders) {
98+
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
99+
SequenceableLoaderWithTrackTypes loader = loadersWithTrackTypes.get(i);
50100
long loaderNextLoadPositionUs = loader.getNextLoadPositionUs();
51101
if (loaderNextLoadPositionUs != C.TIME_END_OF_SOURCE) {
52102
nextLoadPositionUs = min(nextLoadPositionUs, loaderNextLoadPositionUs);
@@ -57,8 +107,8 @@ public long getNextLoadPositionUs() {
57107

58108
@Override
59109
public void reevaluateBuffer(long positionUs) {
60-
for (SequenceableLoader loader : loaders) {
61-
loader.reevaluateBuffer(positionUs);
110+
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
111+
loadersWithTrackTypes.get(i).reevaluateBuffer(positionUs);
62112
}
63113
}
64114

@@ -72,13 +122,13 @@ public boolean continueLoading(LoadingInfo loadingInfo) {
72122
if (nextLoadPositionUs == C.TIME_END_OF_SOURCE) {
73123
break;
74124
}
75-
for (SequenceableLoader loader : loaders) {
76-
long loaderNextLoadPositionUs = loader.getNextLoadPositionUs();
125+
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
126+
long loaderNextLoadPositionUs = loadersWithTrackTypes.get(i).getNextLoadPositionUs();
77127
boolean isLoaderBehind =
78128
loaderNextLoadPositionUs != C.TIME_END_OF_SOURCE
79129
&& loaderNextLoadPositionUs <= loadingInfo.playbackPositionUs;
80130
if (loaderNextLoadPositionUs == nextLoadPositionUs || isLoaderBehind) {
81-
madeProgressThisIteration |= loader.continueLoading(loadingInfo);
131+
madeProgressThisIteration |= loadersWithTrackTypes.get(i).continueLoading(loadingInfo);
82132
}
83133
}
84134
madeProgress |= madeProgressThisIteration;
@@ -88,11 +138,54 @@ public boolean continueLoading(LoadingInfo loadingInfo) {
88138

89139
@Override
90140
public boolean isLoading() {
91-
for (SequenceableLoader loader : loaders) {
92-
if (loader.isLoading()) {
141+
for (int i = 0; i < loadersWithTrackTypes.size(); i++) {
142+
if (loadersWithTrackTypes.get(i).isLoading()) {
93143
return true;
94144
}
95145
}
96146
return false;
97147
}
148+
149+
private static final class SequenceableLoaderWithTrackTypes implements SequenceableLoader {
150+
151+
private final SequenceableLoader loader;
152+
private final ImmutableList<@C.TrackType Integer> trackTypes;
153+
154+
public SequenceableLoaderWithTrackTypes(
155+
SequenceableLoader loader, List<@C.TrackType Integer> trackTypes) {
156+
this.loader = loader;
157+
this.trackTypes = ImmutableList.copyOf(trackTypes);
158+
}
159+
160+
public ImmutableList<@C.TrackType Integer> getTrackTypes() {
161+
return trackTypes;
162+
}
163+
164+
// SequenceableLoader implementation
165+
166+
@Override
167+
public long getBufferedPositionUs() {
168+
return loader.getBufferedPositionUs();
169+
}
170+
171+
@Override
172+
public long getNextLoadPositionUs() {
173+
return loader.getNextLoadPositionUs();
174+
}
175+
176+
@Override
177+
public boolean continueLoading(LoadingInfo loadingInfo) {
178+
return loader.continueLoading(loadingInfo);
179+
}
180+
181+
@Override
182+
public boolean isLoading() {
183+
return loader.isLoading();
184+
}
185+
186+
@Override
187+
public void reevaluateBuffer(long positionUs) {
188+
loader.reevaluateBuffer(positionUs);
189+
}
190+
}
98191
}

‎libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/CompositeSequenceableLoaderFactory.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,33 @@
1515
*/
1616
package androidx.media3.exoplayer.source;
1717

18+
import androidx.media3.common.C;
1819
import androidx.media3.common.util.UnstableApi;
20+
import java.util.List;
1921

2022
/** A factory to create composite {@link SequenceableLoader}s. */
2123
@UnstableApi
2224
public interface CompositeSequenceableLoaderFactory {
2325

26+
/** Returns an empty composite {@link SequenceableLoader}, with no delegate loaders. */
27+
SequenceableLoader empty();
28+
29+
/**
30+
* @deprecated Use {@link #empty()} for an empty composite loader, or {@link #create(List, List)}
31+
* for a non-empty one.
32+
*/
33+
@Deprecated
34+
SequenceableLoader createCompositeSequenceableLoader(SequenceableLoader... loaders);
35+
2436
/**
2537
* Creates a composite {@link SequenceableLoader}.
2638
*
2739
* @param loaders The sub-loaders that make up the {@link SequenceableLoader} to be built.
40+
* @param loaderTrackTypes The track types handled by each entry in {@code loaders}. Must be the
41+
* same as {@code loaders}.
2842
* @return A composite {@link SequenceableLoader} that comprises the given loaders.
2943
*/
30-
SequenceableLoader createCompositeSequenceableLoader(SequenceableLoader... loaders);
44+
SequenceableLoader create(
45+
List<? extends SequenceableLoader> loaders,
46+
List<List<@C.TrackType Integer>> loaderTrackTypes);
3147
}

‎libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/DefaultCompositeSequenceableLoaderFactory.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,32 @@
1515
*/
1616
package androidx.media3.exoplayer.source;
1717

18+
import androidx.media3.common.C;
1819
import androidx.media3.common.util.UnstableApi;
20+
import com.google.common.collect.ImmutableList;
21+
import java.util.List;
1922

2023
/** Default implementation of {@link CompositeSequenceableLoaderFactory}. */
2124
@UnstableApi
2225
public final class DefaultCompositeSequenceableLoaderFactory
2326
implements CompositeSequenceableLoaderFactory {
2427

2528
@Override
29+
public SequenceableLoader empty() {
30+
return new CompositeSequenceableLoader(ImmutableList.of(), ImmutableList.of());
31+
}
32+
33+
@Deprecated
34+
@Override
35+
@SuppressWarnings("deprecation") // Calling deprecated constructor
2636
public SequenceableLoader createCompositeSequenceableLoader(SequenceableLoader... loaders) {
2737
return new CompositeSequenceableLoader(loaders);
2838
}
39+
40+
@Override
41+
public SequenceableLoader create(
42+
List<? extends SequenceableLoader> loaders,
43+
List<List<@C.TrackType Integer>> loaderTrackTypes) {
44+
return new CompositeSequenceableLoader(loaders, loaderTrackTypes);
45+
}
2946
}

‎libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MergingMediaPeriod.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import androidx.media3.exoplayer.source.chunk.MediaChunk;
3030
import androidx.media3.exoplayer.source.chunk.MediaChunkIterator;
3131
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
32+
import com.google.common.collect.Lists;
3233
import java.io.IOException;
3334
import java.util.ArrayList;
3435
import java.util.Collections;
@@ -58,8 +59,7 @@ public MergingMediaPeriod(
5859
this.periods = periods;
5960
childrenPendingPreparation = new ArrayList<>();
6061
childTrackGroupByMergedTrackGroup = new HashMap<>();
61-
compositeSequenceableLoader =
62-
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader();
62+
compositeSequenceableLoader = compositeSequenceableLoaderFactory.empty();
6363
streamPeriodIndices = new IdentityHashMap<>();
6464
enabledPeriods = new MediaPeriod[0];
6565
for (int i = 0; i < periods.length; i++) {
@@ -172,7 +172,9 @@ public long selectTracks(
172172
// Update the local state.
173173
enabledPeriods = enabledPeriodsList.toArray(new MediaPeriod[0]);
174174
compositeSequenceableLoader =
175-
compositeSequenceableLoaderFactory.createCompositeSequenceableLoader(enabledPeriods);
175+
compositeSequenceableLoaderFactory.create(
176+
enabledPeriodsList,
177+
Lists.transform(enabledPeriodsList, period -> period.getTrackGroups().getTrackTypes()));
176178
return positionUs;
177179
}
178180

‎libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/TrackGroupArray.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import androidx.media3.common.util.UnstableApi;
2626
import androidx.media3.common.util.Util;
2727
import com.google.common.collect.ImmutableList;
28+
import com.google.common.collect.Lists;
2829
import java.util.List;
2930

3031
/**
@@ -90,6 +91,11 @@ public boolean isEmpty() {
9091
return length == 0;
9192
}
9293

94+
/** Returns the {@link TrackGroup#type} of each track group in this array. */
95+
public ImmutableList<@C.TrackType Integer> getTrackTypes() {
96+
return ImmutableList.copyOf(Lists.transform(trackGroups, t -> t.type));
97+
}
98+
9399
@Override
94100
public int hashCode() {
95101
if (hashCode == 0) {

0 commit comments

Comments
 (0)