Commit 0fbe083d by hoangtc Committed by Oliver Woodman

Return empty track groups and track selections when user seeks to unprepared period

When user seeks to an unprepared period, since there is no period being played, currently the track groups and track selections are still the ones from previous period. This CL changes it so that when such seeking happens, PlaybackInfo's track groups and track selections are changed to empty.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=206916109
parent 45c1e9ee
......@@ -47,9 +47,16 @@ import java.util.concurrent.CopyOnWriteArraySet;
private static final String TAG = "ExoPlayerImpl";
/**
* This empty track selector result can only be used for {@link PlaybackInfo#trackSelectorResult}
* when the player does not have any track selection made (such as when player is reset, or when
* player seeks to an unprepared period). It will not be used as result of any {@link
* TrackSelector#selectTracks(RendererCapabilities[], TrackGroupArray)} operation.
*/
/* package */ final TrackSelectorResult emptyTrackSelectorResult;
private final Renderer[] renderers;
private final TrackSelector trackSelector;
private final TrackSelectorResult emptyTrackSelectorResult;
private final Handler eventHandler;
private final ExoPlayerImplInternal internalPlayer;
private final Handler internalPlayerHandler;
......
......@@ -700,6 +700,9 @@ import java.util.Collections;
maybeContinueLoading();
} else {
queue.clear(/* keepFrontPeriodUid= */ true);
// New period has not been prepared.
playbackInfo =
playbackInfo.copyWithTrackInfo(TrackGroupArray.EMPTY, emptyTrackSelectorResult);
resetRendererPosition(periodPositionUs);
}
......
......@@ -29,6 +29,7 @@ import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.ShuffleOrder;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
......@@ -48,6 +49,8 @@ import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinit
import com.google.android.exoplayer2.testutil.FakeTrackSelection;
import com.google.android.exoplayer2.testutil.FakeTrackSelector;
import com.google.android.exoplayer2.testutil.RobolectricUtil;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Clock;
......@@ -2288,6 +2291,59 @@ public final class ExoPlayerTest {
.isAtLeast(C.usToMs(expectedDurationUs));
}
@Test
public void testUpdateTrackSelectorThenSeekToUnpreparedPeriod_returnsEmptyTrackGroups()
throws Exception {
Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1);
MediaSource[] fakeMediaSources = {
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
new FakeMediaSource(fakeTimeline, null, Builder.AUDIO_FORMAT)
};
MediaSource mediaSource =
new ConcatenatingMediaSource(
/* isAtomic= */ false,
/* useLazyPreparation= */ true,
new ShuffleOrder.DefaultShuffleOrder(0),
fakeMediaSources);
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
ActionSchedule actionSchedule =
new ActionSchedule.Builder("testSendMessages")
.pause()
.waitForPlaybackState(Player.STATE_READY)
.seek(/* windowIndex= */ 1, /* positionMs= */ 0)
.play()
.build();
List<TrackGroupArray> trackGroupsList = new ArrayList<>();
List<TrackSelectionArray> trackSelectionsList = new ArrayList<>();
new Builder()
.setMediaSource(mediaSource)
.setTrackSelector(trackSelector)
.setRenderers(renderer)
.setActionSchedule(actionSchedule)
.setEventListener(
new EventListener() {
@Override
public void onTracksChanged(
TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
trackGroupsList.add(trackGroups);
trackSelectionsList.add(trackSelections);
}
})
.build(context)
.start()
.blockUntilEnded(TIMEOUT_MS);
assertThat(trackGroupsList).hasSize(3);
// First track groups of the 1st period are reported.
// Then the seek to an unprepared period will result in empty track groups and selections being
// returned.
// Then the track groups of the 2nd period are reported.
assertThat(trackGroupsList.get(0).get(0).getFormat(0)).isEqualTo(Builder.VIDEO_FORMAT);
assertThat(trackGroupsList.get(1)).isEqualTo(TrackGroupArray.EMPTY);
assertThat(trackSelectionsList.get(1).get(0)).isNull();
assertThat(trackGroupsList.get(2).get(0).getFormat(0)).isEqualTo(Builder.AUDIO_FORMAT);
}
// Internal methods.
private static ActionSchedule.Builder addSurfaceSwitch(ActionSchedule.Builder builder) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment