Commit ec437350 by krocard Committed by Ian Baker

Split mutations method out of TrackSelection

`TrackSelection` had mutation methods which were to be called only
internally by ExoPlayer components but were exposed in the
public `Player` interface.

The mutation methods have been moved out of `TrackSelection`
to a new class `ExoTrackSelection`.

Current track related read-only method have also been moved out,
because they are actually something quite unclear.
Even for a single item playlist, it's the track being buffered rather
than the track being played, which is unclear.
But when you have a playlist it starts to get really confusing,
because if the next item is being buffered, then it's actually
the last track to be buffered in the currently playing item.
As a final aside, the implementations don't do proper thread synchronization
to ensure visibility of updated state by the calling thread.

Exposing those mutable methods in the public `Player` interface
was problematic because they leaking internal concepts of `ExoPlayer`.
This is also required to minimize the `Player` interface for long term
stability.

`ExoTrackSelection` is a subclass of `TrackSelection`.
This is not ideal as an `TrackSelection` implementation could
break the current immutability.
This was done in order for this refactor to be simpler.
A future patch will fully split the two classes.

All `MediaPeriod` and `Sources` had to be updated to use the new
`TrackSelection` dynamic aspect class name.
An alternative would have been to break ExoPlayer's public API, keeping
`TrackSelection` as the dynamic aspect name, and calling the public static
aspect class `TrackSelectionState` or similar.
Nevertheless, while it would have impacted less files, it would have
many more small apps and casual users of ExoPlayer.

#player-to-common

PiperOrigin-RevId: 353637924
parent b069a567
Showing with 632 additions and 633 deletions
...@@ -167,6 +167,10 @@ ...@@ -167,6 +167,10 @@
([#8320](https://github.com/google/ExoPlayer/issues/8320)). ([#8320](https://github.com/google/ExoPlayer/issues/8320)).
* Add option to specify preferred audio role flags. * Add option to specify preferred audio role flags.
* Forward `Timeline` and `MediaPeriodId` to `TrackSelection.Factory`. * Forward `Timeline` and `MediaPeriodId` to `TrackSelection.Factory`.
* In order to make it immutable, `TrackSelection` in the `Player` API now
only contains methods related to static selection.
The rest of the methods have been moved to the child
class `ExoTrackSelection` which is used by all ExoPlayer components.
* DASH: * DASH:
* Support low-latency DASH playback (`availabilityTimeOffset` and * Support low-latency DASH playback (`availabilityTimeOffset` and
`ServiceDescription` tags) `ServiceDescription` tags)
......
...@@ -21,7 +21,7 @@ import static java.lang.Math.min; ...@@ -21,7 +21,7 @@ import static java.lang.Math.min;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DefaultAllocator; import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
...@@ -317,7 +317,7 @@ public class DefaultLoadControl implements LoadControl { ...@@ -317,7 +317,7 @@ public class DefaultLoadControl implements LoadControl {
@Override @Override
public void onTracksSelected( public void onTracksSelected(
Renderer[] renderers, TrackGroupArray trackGroups, TrackSelection[] trackSelections) { Renderer[] renderers, TrackGroupArray trackGroups, ExoTrackSelection[] trackSelections) {
targetBufferBytes = targetBufferBytes =
targetBufferBytesOverwrite == C.LENGTH_UNSET targetBufferBytesOverwrite == C.LENGTH_UNSET
? calculateTargetBufferBytes(renderers, trackSelections) ? calculateTargetBufferBytes(renderers, trackSelections)
...@@ -400,7 +400,7 @@ public class DefaultLoadControl implements LoadControl { ...@@ -400,7 +400,7 @@ public class DefaultLoadControl implements LoadControl {
* @return The target buffer size in bytes. * @return The target buffer size in bytes.
*/ */
protected int calculateTargetBufferBytes( protected int calculateTargetBufferBytes(
Renderer[] renderers, TrackSelection[] trackSelectionArray) { Renderer[] renderers, ExoTrackSelection[] trackSelectionArray) {
int targetBufferSize = 0; int targetBufferSize = 0;
for (int i = 0; i < renderers.length; i++) { for (int i = 0; i < renderers.length; i++) {
if (trackSelectionArray[i] != null) { if (trackSelectionArray[i] != null) {
......
...@@ -34,7 +34,7 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; ...@@ -34,7 +34,7 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSourceFactory; import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.source.ShuffleOrder; import com.google.android.exoplayer2.source.ShuffleOrder;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray; import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
...@@ -171,7 +171,7 @@ import java.util.List; ...@@ -171,7 +171,7 @@ import java.util.List;
emptyTrackSelectorResult = emptyTrackSelectorResult =
new TrackSelectorResult( new TrackSelectorResult(
new RendererConfiguration[renderers.length], new RendererConfiguration[renderers.length],
new TrackSelection[renderers.length], new ExoTrackSelection[renderers.length],
/* info= */ null); /* info= */ null);
period = new Timeline.Period(); period = new Timeline.Period();
maskingWindowIndex = C.INDEX_UNSET; maskingWindowIndex = C.INDEX_UNSET;
......
...@@ -40,7 +40,7 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; ...@@ -40,7 +40,7 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.SampleStream; import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.ShuffleOrder; import com.google.android.exoplayer2.source.ShuffleOrder;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
...@@ -725,7 +725,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -725,7 +725,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void notifyTrackSelectionPlayWhenReadyChanged(boolean playWhenReady) { private void notifyTrackSelectionPlayWhenReadyChanged(boolean playWhenReady) {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod(); MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) { while (periodHolder != null) {
for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) { for (ExoTrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onPlayWhenReadyChanged(playWhenReady); trackSelection.onPlayWhenReadyChanged(playWhenReady);
} }
...@@ -899,7 +899,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -899,7 +899,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void notifyTrackSelectionRebuffer() { private void notifyTrackSelectionRebuffer() {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod(); MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) { while (periodHolder != null) {
for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) { for (ExoTrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onRebuffer(); trackSelection.onRebuffer();
} }
...@@ -1689,7 +1689,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1689,7 +1689,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void updateTrackSelectionPlaybackSpeed(float playbackSpeed) { private void updateTrackSelectionPlaybackSpeed(float playbackSpeed) {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod(); MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) { while (periodHolder != null) {
for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) { for (ExoTrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onPlaybackSpeed(playbackSpeed); trackSelection.onPlaybackSpeed(playbackSpeed);
} }
...@@ -1701,7 +1701,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -1701,7 +1701,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
private void notifyTrackSelectionDiscontinuity() { private void notifyTrackSelectionDiscontinuity() {
MediaPeriodHolder periodHolder = queue.getPlayingPeriod(); MediaPeriodHolder periodHolder = queue.getPlayingPeriod();
while (periodHolder != null) { while (periodHolder != null) {
for (TrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) { for (ExoTrackSelection trackSelection : periodHolder.getTrackSelectorResult().selections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onDiscontinuity(); trackSelection.onDiscontinuity();
} }
...@@ -2268,10 +2268,10 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2268,10 +2268,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
} }
private ImmutableList<Metadata> extractMetadataFromTrackSelectionArray( private ImmutableList<Metadata> extractMetadataFromTrackSelectionArray(
TrackSelection[] trackSelections) { ExoTrackSelection[] trackSelections) {
ImmutableList.Builder<Metadata> result = new ImmutableList.Builder<>(); ImmutableList.Builder<Metadata> result = new ImmutableList.Builder<>();
boolean seenNonEmptyMetadata = false; boolean seenNonEmptyMetadata = false;
for (TrackSelection trackSelection : trackSelections) { for (ExoTrackSelection trackSelection : trackSelections) {
if (trackSelection != null) { if (trackSelection != null) {
Format format = trackSelection.getFormat(/* index= */ 0); Format format = trackSelection.getFormat(/* index= */ 0);
if (format.metadata == null) { if (format.metadata == null) {
...@@ -2319,7 +2319,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2319,7 +2319,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
TrackSelectorResult trackSelectorResult = periodHolder.getTrackSelectorResult(); TrackSelectorResult trackSelectorResult = periodHolder.getTrackSelectorResult();
RendererConfiguration rendererConfiguration = RendererConfiguration rendererConfiguration =
trackSelectorResult.rendererConfigurations[rendererIndex]; trackSelectorResult.rendererConfigurations[rendererIndex];
TrackSelection newSelection = trackSelectorResult.selections[rendererIndex]; ExoTrackSelection newSelection = trackSelectorResult.selections[rendererIndex];
Format[] formats = getFormats(newSelection); Format[] formats = getFormats(newSelection);
// The renderer needs enabling with its new track selection. // The renderer needs enabling with its new track selection.
boolean playing = shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY; boolean playing = shouldPlayWhenReady() && playbackInfo.playbackState == Player.STATE_READY;
...@@ -2793,7 +2793,7 @@ import java.util.concurrent.atomic.AtomicBoolean; ...@@ -2793,7 +2793,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
return newPeriodIndex == C.INDEX_UNSET ? null : newTimeline.getUidOfPeriod(newPeriodIndex); return newPeriodIndex == C.INDEX_UNSET ? null : newTimeline.getUidOfPeriod(newPeriodIndex);
} }
private static Format[] getFormats(TrackSelection newSelection) { private static Format[] getFormats(ExoTrackSelection newSelection) {
// Build an array of formats contained by the selection. // Build an array of formats contained by the selection.
int length = newSelection != null ? newSelection.length() : 0; int length = newSelection != null ? newSelection.length() : 0;
Format[] formats = new Format[length]; Format[] formats = new Format[length];
......
...@@ -17,7 +17,7 @@ package com.google.android.exoplayer2; ...@@ -17,7 +17,7 @@ package com.google.android.exoplayer2;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
/** Controls buffering of media. */ /** Controls buffering of media. */
...@@ -34,7 +34,7 @@ public interface LoadControl { ...@@ -34,7 +34,7 @@ public interface LoadControl {
* @param trackSelections The track selections that were made. * @param trackSelections The track selections that were made.
*/ */
void onTracksSelected( void onTracksSelected(
Renderer[] renderers, TrackGroupArray trackGroups, TrackSelection[] trackSelections); Renderer[] renderers, TrackGroupArray trackGroups, ExoTrackSelection[] trackSelections);
/** Called by the player when stopped. */ /** Called by the player when stopped. */
void onStopped(); void onStopped();
......
...@@ -24,7 +24,7 @@ import com.google.android.exoplayer2.source.MediaPeriod; ...@@ -24,7 +24,7 @@ import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.SampleStream; import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
...@@ -232,7 +232,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -232,7 +232,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
throws ExoPlaybackException { throws ExoPlaybackException {
TrackSelectorResult selectorResult = TrackSelectorResult selectorResult =
trackSelector.selectTracks(rendererCapabilities, getTrackGroups(), info.id, timeline); trackSelector.selectTracks(rendererCapabilities, getTrackGroups(), info.id, timeline);
for (TrackSelection trackSelection : selectorResult.selections) { for (ExoTrackSelection trackSelection : selectorResult.selections) {
if (trackSelection != null) { if (trackSelection != null) {
trackSelection.onPlaybackSpeed(playbackSpeed); trackSelection.onPlaybackSpeed(playbackSpeed);
} }
...@@ -359,7 +359,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -359,7 +359,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
for (int i = 0; i < trackSelectorResult.length; i++) { for (int i = 0; i < trackSelectorResult.length; i++) {
boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i); boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i);
TrackSelection trackSelection = trackSelectorResult.selections[i]; ExoTrackSelection trackSelection = trackSelectorResult.selections[i];
if (rendererEnabled && trackSelection != null) { if (rendererEnabled && trackSelection != null) {
trackSelection.enable(); trackSelection.enable();
} }
...@@ -372,7 +372,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -372,7 +372,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
for (int i = 0; i < trackSelectorResult.length; i++) { for (int i = 0; i < trackSelectorResult.length; i++) {
boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i); boolean rendererEnabled = trackSelectorResult.isRendererEnabled(i);
TrackSelection trackSelection = trackSelectorResult.selections[i]; ExoTrackSelection trackSelection = trackSelectorResult.selections[i];
if (rendererEnabled && trackSelection != null) { if (rendererEnabled && trackSelection != null) {
trackSelection.disable(); trackSelection.disable();
} }
......
...@@ -48,8 +48,8 @@ import com.google.android.exoplayer2.trackselection.BaseTrackSelection; ...@@ -48,8 +48,8 @@ import com.google.android.exoplayer2.trackselection.BaseTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.Parameters; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.Parameters;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo; import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
...@@ -465,8 +465,9 @@ public final class DownloadHelper { ...@@ -465,8 +465,9 @@ public final class DownloadHelper {
private @MonotonicNonNull MediaPreparer mediaPreparer; private @MonotonicNonNull MediaPreparer mediaPreparer;
private TrackGroupArray @MonotonicNonNull [] trackGroupArrays; private TrackGroupArray @MonotonicNonNull [] trackGroupArrays;
private MappedTrackInfo @MonotonicNonNull [] mappedTrackInfos; private MappedTrackInfo @MonotonicNonNull [] mappedTrackInfos;
private List<TrackSelection> @MonotonicNonNull [][] trackSelectionsByPeriodAndRenderer; private List<ExoTrackSelection> @MonotonicNonNull [][] trackSelectionsByPeriodAndRenderer;
private List<TrackSelection> @MonotonicNonNull [][] immutableTrackSelectionsByPeriodAndRenderer; private List<ExoTrackSelection> @MonotonicNonNull [][]
immutableTrackSelectionsByPeriodAndRenderer;
/** /**
* Creates download helper. * Creates download helper.
...@@ -573,14 +574,14 @@ public final class DownloadHelper { ...@@ -573,14 +574,14 @@ public final class DownloadHelper {
} }
/** /**
* Returns all {@link TrackSelection track selections} for a period and renderer. Must not be * Returns all {@link ExoTrackSelection track selections} for a period and renderer. Must not be
* called until after preparation completes. * called until after preparation completes.
* *
* @param periodIndex The period index. * @param periodIndex The period index.
* @param rendererIndex The renderer index. * @param rendererIndex The renderer index.
* @return A list of selected {@link TrackSelection track selections}. * @return A list of selected {@link ExoTrackSelection track selections}.
*/ */
public List<TrackSelection> getTrackSelections(int periodIndex, int rendererIndex) { public List<ExoTrackSelection> getTrackSelections(int periodIndex, int rendererIndex) {
assertPreparedWithMedia(); assertPreparedWithMedia();
return immutableTrackSelectionsByPeriodAndRenderer[periodIndex][rendererIndex]; return immutableTrackSelectionsByPeriodAndRenderer[periodIndex][rendererIndex];
} }
...@@ -751,7 +752,7 @@ public final class DownloadHelper { ...@@ -751,7 +752,7 @@ public final class DownloadHelper {
} }
assertPreparedWithMedia(); assertPreparedWithMedia();
List<StreamKey> streamKeys = new ArrayList<>(); List<StreamKey> streamKeys = new ArrayList<>();
List<TrackSelection> allSelections = new ArrayList<>(); List<ExoTrackSelection> allSelections = new ArrayList<>();
int periodCount = trackSelectionsByPeriodAndRenderer.length; int periodCount = trackSelectionsByPeriodAndRenderer.length;
for (int periodIndex = 0; periodIndex < periodCount; periodIndex++) { for (int periodIndex = 0; periodIndex < periodCount; periodIndex++) {
allSelections.clear(); allSelections.clear();
...@@ -773,9 +774,9 @@ public final class DownloadHelper { ...@@ -773,9 +774,9 @@ public final class DownloadHelper {
int periodCount = mediaPreparer.mediaPeriods.length; int periodCount = mediaPreparer.mediaPeriods.length;
int rendererCount = rendererCapabilities.length; int rendererCount = rendererCapabilities.length;
trackSelectionsByPeriodAndRenderer = trackSelectionsByPeriodAndRenderer =
(List<TrackSelection>[][]) new List<?>[periodCount][rendererCount]; (List<ExoTrackSelection>[][]) new List<?>[periodCount][rendererCount];
immutableTrackSelectionsByPeriodAndRenderer = immutableTrackSelectionsByPeriodAndRenderer =
(List<TrackSelection>[][]) new List<?>[periodCount][rendererCount]; (List<ExoTrackSelection>[][]) new List<?>[periodCount][rendererCount];
for (int i = 0; i < periodCount; i++) { for (int i = 0; i < periodCount; i++) {
for (int j = 0; j < rendererCount; j++) { for (int j = 0; j < rendererCount; j++) {
trackSelectionsByPeriodAndRenderer[i][j] = new ArrayList<>(); trackSelectionsByPeriodAndRenderer[i][j] = new ArrayList<>();
...@@ -847,15 +848,15 @@ public final class DownloadHelper { ...@@ -847,15 +848,15 @@ public final class DownloadHelper {
new MediaPeriodId(mediaPreparer.timeline.getUidOfPeriod(periodIndex)), new MediaPeriodId(mediaPreparer.timeline.getUidOfPeriod(periodIndex)),
mediaPreparer.timeline); mediaPreparer.timeline);
for (int i = 0; i < trackSelectorResult.length; i++) { for (int i = 0; i < trackSelectorResult.length; i++) {
@Nullable TrackSelection newSelection = trackSelectorResult.selections[i]; @Nullable ExoTrackSelection newSelection = trackSelectorResult.selections[i];
if (newSelection == null) { if (newSelection == null) {
continue; continue;
} }
List<TrackSelection> existingSelectionList = List<ExoTrackSelection> existingSelectionList =
trackSelectionsByPeriodAndRenderer[periodIndex][i]; trackSelectionsByPeriodAndRenderer[periodIndex][i];
boolean mergedWithExistingSelection = false; boolean mergedWithExistingSelection = false;
for (int j = 0; j < existingSelectionList.size(); j++) { for (int j = 0; j < existingSelectionList.size(); j++) {
TrackSelection existingSelection = existingSelectionList.get(j); ExoTrackSelection existingSelection = existingSelectionList.get(j);
if (existingSelection.getTrackGroup() == newSelection.getTrackGroup()) { if (existingSelection.getTrackGroup() == newSelection.getTrackGroup()) {
// Merge with existing selection. // Merge with existing selection.
scratchSet.clear(); scratchSet.clear();
...@@ -1066,15 +1067,15 @@ public final class DownloadHelper { ...@@ -1066,15 +1067,15 @@ public final class DownloadHelper {
private static final class DownloadTrackSelection extends BaseTrackSelection { private static final class DownloadTrackSelection extends BaseTrackSelection {
private static final class Factory implements TrackSelection.Factory { private static final class Factory implements ExoTrackSelection.Factory {
@Override @Override
public @NullableType TrackSelection[] createTrackSelections( public @NullableType ExoTrackSelection[] createTrackSelections(
@NullableType Definition[] definitions, @NullableType Definition[] definitions,
BandwidthMeter bandwidthMeter, BandwidthMeter bandwidthMeter,
MediaPeriodId mediaPeriodId, MediaPeriodId mediaPeriodId,
Timeline timeline) { Timeline timeline) {
@NullableType TrackSelection[] selections = new TrackSelection[definitions.length]; @NullableType ExoTrackSelection[] selections = new ExoTrackSelection[definitions.length];
for (int i = 0; i < definitions.length; i++) { for (int i = 0; i < definitions.length; i++) {
selections[i] = selections[i] =
definitions[i] == null definitions[i] == null
......
...@@ -21,7 +21,7 @@ import com.google.android.exoplayer2.Format; ...@@ -21,7 +21,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
...@@ -34,9 +34,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -34,9 +34,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
*/ */
public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callback { public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callback {
/** /** The {@link MediaPeriod} wrapped by this clipping media period. */
* The {@link MediaPeriod} wrapped by this clipping media period.
*/
public final MediaPeriod mediaPeriod; public final MediaPeriod mediaPeriod;
@Nullable private MediaPeriod.Callback callback; @Nullable private MediaPeriod.Callback callback;
...@@ -98,7 +96,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -98,7 +96,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -250,7 +248,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -250,7 +248,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
} }
private static boolean shouldKeepInitialDiscontinuity( private static boolean shouldKeepInitialDiscontinuity(
long startUs, @NullableType TrackSelection[] selections) { long startUs, @NullableType ExoTrackSelection[] selections) {
// If the clipping start position is non-zero, the clipping sample streams will adjust // If the clipping start position is non-zero, the clipping sample streams will adjust
// timestamps on buffers they read from the unclipped sample streams. These adjusted buffer // timestamps on buffers they read from the unclipped sample streams. These adjusted buffer
// timestamps can be negative, because sample streams provide buffers starting at a key-frame, // timestamps can be negative, because sample streams provide buffers starting at a key-frame,
...@@ -261,7 +259,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -261,7 +259,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
// However, for tracks where all samples are sync samples, we assume they have random access // However, for tracks where all samples are sync samples, we assume they have random access
// seek behaviour and do not need an initial discontinuity to reset the renderer. // seek behaviour and do not need an initial discontinuity to reset the renderer.
if (startUs != 0) { if (startUs != 0) {
for (TrackSelection trackSelection : selections) { for (ExoTrackSelection trackSelection : selections) {
if (trackSelection != null) { if (trackSelection != null) {
Format selectedFormat = trackSelection.getSelectedFormat(); Format selectedFormat = trackSelection.getSelectedFormat();
if (!MimeTypes.allSamplesAreSyncSamples( if (!MimeTypes.allSamplesAreSyncSamples(
...@@ -274,9 +272,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -274,9 +272,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
return false; return false;
} }
/** /** Wraps a {@link SampleStream} and clips its samples. */
* Wraps a {@link SampleStream} and clips its samples.
*/
private final class ClippingSampleStream implements SampleStream { private final class ClippingSampleStream implements SampleStream {
public final SampleStream childStream; public final SampleStream childStream;
...@@ -302,8 +298,8 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb ...@@ -302,8 +298,8 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb
} }
@Override @Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, public int readData(
boolean requireFormat) { FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) {
if (isPendingInitialDiscontinuity()) { if (isPendingInitialDiscontinuity()) {
return C.RESULT_NOTHING_READ; return C.RESULT_NOTHING_READ;
} }
......
...@@ -23,7 +23,7 @@ import androidx.annotation.Nullable; ...@@ -23,7 +23,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import java.io.IOException; import java.io.IOException;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
...@@ -173,7 +173,7 @@ public final class MaskingMediaPeriod implements MediaPeriod, MediaPeriod.Callba ...@@ -173,7 +173,7 @@ public final class MaskingMediaPeriod implements MediaPeriod, MediaPeriod.Callba
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
......
...@@ -21,7 +21,7 @@ import com.google.android.exoplayer2.SeekParameters; ...@@ -21,7 +21,7 @@ import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller; import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
...@@ -45,7 +45,7 @@ public interface MediaPeriod extends SequenceableLoader { ...@@ -45,7 +45,7 @@ public interface MediaPeriod extends SequenceableLoader {
* Called when preparation completes. * Called when preparation completes.
* *
* <p>Called on the playback thread. After invoking this method, the {@link MediaPeriod} can * <p>Called on the playback thread. After invoking this method, the {@link MediaPeriod} can
* expect for {@link #selectTracks(TrackSelection[], boolean[], SampleStream[], boolean[], * expect for {@link #selectTracks(ExoTrackSelection[], boolean[], SampleStream[], boolean[],
* long)} to be called with the initial track selection. * long)} to be called with the initial track selection.
* *
* @param mediaPeriod The prepared {@link MediaPeriod}. * @param mediaPeriod The prepared {@link MediaPeriod}.
...@@ -90,17 +90,17 @@ public interface MediaPeriod extends SequenceableLoader { ...@@ -90,17 +90,17 @@ public interface MediaPeriod extends SequenceableLoader {
/** /**
* Returns a list of {@link StreamKey StreamKeys} which allow to filter the media in this period * Returns a list of {@link StreamKey StreamKeys} which allow to filter the media in this period
* to load only the parts needed to play the provided {@link TrackSelection TrackSelections}. * to load only the parts needed to play the provided {@link ExoTrackSelection TrackSelections}.
* *
* <p>This method is only called after the period has been prepared. * <p>This method is only called after the period has been prepared.
* *
* @param trackSelections The {@link TrackSelection TrackSelections} describing the tracks for * @param trackSelections The {@link ExoTrackSelection TrackSelections} describing the tracks for
* which stream keys are requested. * which stream keys are requested.
* @return The corresponding {@link StreamKey StreamKeys} for the selected tracks, or an empty * @return The corresponding {@link StreamKey StreamKeys} for the selected tracks, or an empty
* list if filtering is not possible and the entire media needs to be loaded to play the * list if filtering is not possible and the entire media needs to be loaded to play the
* selected tracks. * selected tracks.
*/ */
default List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) { default List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
return Collections.emptyList(); return Collections.emptyList();
} }
...@@ -115,8 +115,8 @@ public interface MediaPeriod extends SequenceableLoader { ...@@ -115,8 +115,8 @@ public interface MediaPeriod extends SequenceableLoader {
* corresponding flag in {@code streamResetFlags} will be set to true. This flag will also be set * corresponding flag in {@code streamResetFlags} will be set to true. This flag will also be set
* if a new sample stream is created. * if a new sample stream is created.
* *
* <p>Note that previously passed {@link TrackSelection TrackSelections} are no longer valid, and * <p>Note that previously passed {@link ExoTrackSelection TrackSelections} are no longer valid,
* any references to them must be updated to point to the new selections. * and any references to them must be updated to point to the new selections.
* *
* <p>This method is only called after the period has been prepared. * <p>This method is only called after the period has been prepared.
* *
...@@ -135,7 +135,7 @@ public interface MediaPeriod extends SequenceableLoader { ...@@ -135,7 +135,7 @@ public interface MediaPeriod extends SequenceableLoader {
* @return The actual position at which the tracks were enabled, in microseconds. * @return The actual position at which the tracks were enabled, in microseconds.
*/ */
long selectTracks( long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
......
...@@ -23,7 +23,7 @@ import com.google.android.exoplayer2.FormatHolder; ...@@ -23,7 +23,7 @@ import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -33,9 +33,7 @@ import java.util.List; ...@@ -33,9 +33,7 @@ import java.util.List;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** /** Merges multiple {@link MediaPeriod}s. */
* Merges multiple {@link MediaPeriod}s.
*/
/* package */ final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callback { /* package */ final class MergingMediaPeriod implements MediaPeriod, MediaPeriod.Callback {
private final MediaPeriod[] periods; private final MediaPeriod[] periods;
...@@ -100,7 +98,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -100,7 +98,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -126,15 +124,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -126,15 +124,16 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// Select tracks for each child, copying the resulting streams back into a new streams array. // Select tracks for each child, copying the resulting streams back into a new streams array.
@NullableType SampleStream[] newStreams = new SampleStream[selections.length]; @NullableType SampleStream[] newStreams = new SampleStream[selections.length];
@NullableType SampleStream[] childStreams = new SampleStream[selections.length]; @NullableType SampleStream[] childStreams = new SampleStream[selections.length];
@NullableType TrackSelection[] childSelections = new TrackSelection[selections.length]; @NullableType ExoTrackSelection[] childSelections = new ExoTrackSelection[selections.length];
ArrayList<MediaPeriod> enabledPeriodsList = new ArrayList<>(periods.length); ArrayList<MediaPeriod> enabledPeriodsList = new ArrayList<>(periods.length);
for (int i = 0; i < periods.length; i++) { for (int i = 0; i < periods.length; i++) {
for (int j = 0; j < selections.length; j++) { for (int j = 0; j < selections.length; j++) {
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null; childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null; childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
} }
long selectPositionUs = periods[i].selectTracks(childSelections, mayRetainStreamFlags, long selectPositionUs =
childStreams, streamResetFlags, positionUs); periods[i].selectTracks(
childSelections, mayRetainStreamFlags, childStreams, streamResetFlags, positionUs);
if (i == 0) { if (i == 0) {
positionUs = selectPositionUs; positionUs = selectPositionUs;
} else if (selectPositionUs != positionUs) { } else if (selectPositionUs != positionUs) {
...@@ -314,13 +313,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -314,13 +313,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
@Override @Override
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) { public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
return mediaPeriod.getStreamKeys(trackSelections); return mediaPeriod.getStreamKeys(trackSelections);
} }
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
......
...@@ -40,7 +40,7 @@ import com.google.android.exoplayer2.extractor.TrackOutput; ...@@ -40,7 +40,7 @@ import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.metadata.Metadata; import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.icy.IcyHeaders; import com.google.android.exoplayer2.metadata.icy.IcyHeaders;
import com.google.android.exoplayer2.source.SampleQueue.UpstreamFormatChangedListener; import com.google.android.exoplayer2.source.SampleQueue.UpstreamFormatChangedListener;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
...@@ -252,7 +252,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -252,7 +252,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -277,7 +277,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -277,7 +277,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// Select new tracks. // Select new tracks.
for (int i = 0; i < selections.length; i++) { for (int i = 0; i < selections.length; i++) {
if (streams[i] == null && selections[i] != null) { if (streams[i] == null && selections[i] != null) {
TrackSelection selection = selections[i]; ExoTrackSelection selection = selections[i];
Assertions.checkState(selection.length() == 1); Assertions.checkState(selection.length() == 1);
Assertions.checkState(selection.getIndexInTrackGroup(0) == 0); Assertions.checkState(selection.getIndexInTrackGroup(0) == 0);
int track = tracks.indexOf(selection.getTrackGroup()); int track = tracks.indexOf(selection.getTrackGroup());
......
...@@ -25,7 +25,7 @@ import com.google.android.exoplayer2.FormatHolder; ...@@ -25,7 +25,7 @@ import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
...@@ -194,7 +194,7 @@ public final class SilenceMediaSource extends BaseMediaSource { ...@@ -194,7 +194,7 @@ public final class SilenceMediaSource extends BaseMediaSource {
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
......
...@@ -22,7 +22,7 @@ import com.google.android.exoplayer2.FormatHolder; ...@@ -22,7 +22,7 @@ import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
...@@ -41,15 +41,11 @@ import java.util.Arrays; ...@@ -41,15 +41,11 @@ import java.util.Arrays;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** /** A {@link MediaPeriod} with a single sample. */
* A {@link MediaPeriod} with a single sample. /* package */ final class SingleSampleMediaPeriod
*/ implements MediaPeriod, Loader.Callback<SingleSampleMediaPeriod.SourceLoadable> {
/* package */ final class SingleSampleMediaPeriod implements MediaPeriod,
Loader.Callback<SingleSampleMediaPeriod.SourceLoadable> {
/** /** The initial size of the allocation used to hold the sample data. */
* The initial size of the allocation used to hold the sample data.
*/
private static final int INITIAL_SAMPLE_SIZE = 1024; private static final int INITIAL_SAMPLE_SIZE = 1024;
private final DataSpec dataSpec; private final DataSpec dataSpec;
...@@ -113,7 +109,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -113,7 +109,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -348,8 +344,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -348,8 +344,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
@Override @Override
public int readData(FormatHolder formatHolder, DecoderInputBuffer buffer, public int readData(
boolean requireFormat) { FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) {
maybeNotifyDownstreamFormat(); maybeNotifyDownstreamFormat();
if (streamState == STREAM_STATE_END_OF_STREAM) { if (streamState == STREAM_STATE_END_OF_STREAM) {
buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM); buffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
......
...@@ -38,13 +38,13 @@ import java.util.List; ...@@ -38,13 +38,13 @@ import java.util.List;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /**
* A bandwidth based adaptive {@link TrackSelection}, whose selected track is updated to be the one * A bandwidth based adaptive {@link ExoTrackSelection}, whose selected track is updated to be the
* of highest quality given the current network conditions and the state of the buffer. * one of highest quality given the current network conditions and the state of the buffer.
*/ */
public class AdaptiveTrackSelection extends BaseTrackSelection { public class AdaptiveTrackSelection extends BaseTrackSelection {
/** Factory for {@link AdaptiveTrackSelection} instances. */ /** Factory for {@link AdaptiveTrackSelection} instances. */
public static class Factory implements TrackSelection.Factory { public static class Factory implements ExoTrackSelection.Factory {
private final int minDurationForQualityIncreaseMs; private final int minDurationForQualityIncreaseMs;
private final int maxDurationForQualityDecreaseMs; private final int maxDurationForQualityDecreaseMs;
...@@ -132,14 +132,14 @@ public class AdaptiveTrackSelection extends BaseTrackSelection { ...@@ -132,14 +132,14 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
} }
@Override @Override
public final @NullableType TrackSelection[] createTrackSelections( public final @NullableType ExoTrackSelection[] createTrackSelections(
@NullableType Definition[] definitions, @NullableType Definition[] definitions,
BandwidthMeter bandwidthMeter, BandwidthMeter bandwidthMeter,
MediaPeriodId mediaPeriodId, MediaPeriodId mediaPeriodId,
Timeline timeline) { Timeline timeline) {
ImmutableList<ImmutableList<AdaptationCheckpoint>> adaptationCheckpoints = ImmutableList<ImmutableList<AdaptationCheckpoint>> adaptationCheckpoints =
getAdaptationCheckpoints(definitions); getAdaptationCheckpoints(definitions);
TrackSelection[] selections = new TrackSelection[definitions.length]; ExoTrackSelection[] selections = new ExoTrackSelection[definitions.length];
for (int i = 0; i < definitions.length; i++) { for (int i = 0; i < definitions.length; i++) {
@Nullable Definition definition = definitions[i]; @Nullable Definition definition = definitions[i];
if (definition == null || definition.tracks.length == 0) { if (definition == null || definition.tracks.length == 0) {
......
...@@ -28,27 +28,17 @@ import com.google.android.exoplayer2.util.Util; ...@@ -28,27 +28,17 @@ import com.google.android.exoplayer2.util.Util;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
/** /** An abstract base class suitable for most {@link ExoTrackSelection} implementations. */
* An abstract base class suitable for most {@link TrackSelection} implementations. public abstract class BaseTrackSelection implements ExoTrackSelection {
*/
public abstract class BaseTrackSelection implements TrackSelection {
/** /** The selected {@link TrackGroup}. */
* The selected {@link TrackGroup}.
*/
protected final TrackGroup group; protected final TrackGroup group;
/** /** The number of selected tracks within the {@link TrackGroup}. Always greater than zero. */
* The number of selected tracks within the {@link TrackGroup}. Always greater than zero.
*/
protected final int length; protected final int length;
/** /** The indices of the selected tracks in {@link #group}, in order of decreasing bandwidth. */
* The indices of the selected tracks in {@link #group}, in order of decreasing bandwidth.
*/
protected final int[] tracks; protected final int[] tracks;
/** /** The {@link Format}s of the selected tracks, in order of decreasing bandwidth. */
* The {@link Format}s of the selected tracks, in order of decreasing bandwidth.
*/
private final Format[] formats; private final Format[] formats;
/** Selected track exclusion timestamps, in order of decreasing bandwidth. */ /** Selected track exclusion timestamps, in order of decreasing bandwidth. */
private final long[] excludeUntilTimes; private final long[] excludeUntilTimes;
......
...@@ -222,7 +222,6 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -222,7 +222,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* *
* @param context Any context. * @param context Any context.
*/ */
public ParametersBuilder(Context context) { public ParametersBuilder(Context context) {
super(context); super(context);
setInitialValuesWithoutContext(); setInitialValuesWithoutContext();
...@@ -826,9 +825,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -826,9 +825,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this; return this;
} }
/** /** Builds a {@link Parameters} instance with the selected values. */
* Builds a {@link Parameters} instance with the selected values.
*/
public Parameters build() { public Parameters build() {
return new Parameters( return new Parameters(
// Video // Video
...@@ -1614,6 +1611,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1614,6 +1611,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* dimension). * dimension).
*/ */
private static final float FRACTION_TO_CONSIDER_FULLSCREEN = 0.98f; private static final float FRACTION_TO_CONSIDER_FULLSCREEN = 0.98f;
private static final int[] NO_TRACKS = new int[0]; private static final int[] NO_TRACKS = new int[0];
/** Ordering of two format values. A known value is considered greater than Format#NO_VALUE. */ /** Ordering of two format values. A known value is considered greater than Format#NO_VALUE. */
private static final Ordering<Integer> FORMAT_VALUE_ORDERING = private static final Ordering<Integer> FORMAT_VALUE_ORDERING =
...@@ -1625,7 +1623,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1625,7 +1623,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/** Ordering where all elements are equal. */ /** Ordering where all elements are equal. */
private static final Ordering<Integer> NO_ORDER = Ordering.from((first, second) -> 0); private static final Ordering<Integer> NO_ORDER = Ordering.from((first, second) -> 0);
private final TrackSelection.Factory trackSelectionFactory; private final ExoTrackSelection.Factory trackSelectionFactory;
private final AtomicReference<Parameters> parametersReference; private final AtomicReference<Parameters> parametersReference;
/** @deprecated Use {@link #DefaultTrackSelector(Context)} instead. */ /** @deprecated Use {@link #DefaultTrackSelector(Context)} instead. */
...@@ -1634,9 +1632,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1634,9 +1632,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
this(Parameters.DEFAULT_WITHOUT_CONTEXT, new AdaptiveTrackSelection.Factory()); this(Parameters.DEFAULT_WITHOUT_CONTEXT, new AdaptiveTrackSelection.Factory());
} }
/** @deprecated Use {@link #DefaultTrackSelector(Context, TrackSelection.Factory)}. */ /** @deprecated Use {@link #DefaultTrackSelector(Context, ExoTrackSelection.Factory)}. */
@Deprecated @Deprecated
public DefaultTrackSelector(TrackSelection.Factory trackSelectionFactory) { public DefaultTrackSelector(ExoTrackSelection.Factory trackSelectionFactory) {
this(Parameters.DEFAULT_WITHOUT_CONTEXT, trackSelectionFactory); this(Parameters.DEFAULT_WITHOUT_CONTEXT, trackSelectionFactory);
} }
...@@ -1647,17 +1645,18 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1647,17 +1645,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/** /**
* @param context Any {@link Context}. * @param context Any {@link Context}.
* @param trackSelectionFactory A factory for {@link TrackSelection}s. * @param trackSelectionFactory A factory for {@link ExoTrackSelection}s.
*/ */
public DefaultTrackSelector(Context context, TrackSelection.Factory trackSelectionFactory) { public DefaultTrackSelector(Context context, ExoTrackSelection.Factory trackSelectionFactory) {
this(Parameters.getDefaults(context), trackSelectionFactory); this(Parameters.getDefaults(context), trackSelectionFactory);
} }
/** /**
* @param parameters Initial {@link Parameters}. * @param parameters Initial {@link Parameters}.
* @param trackSelectionFactory A factory for {@link TrackSelection}s. * @param trackSelectionFactory A factory for {@link ExoTrackSelection}s.
*/ */
public DefaultTrackSelector(Parameters parameters, TrackSelection.Factory trackSelectionFactory) { public DefaultTrackSelector(
Parameters parameters, ExoTrackSelection.Factory trackSelectionFactory) {
this.trackSelectionFactory = trackSelectionFactory; this.trackSelectionFactory = trackSelectionFactory;
parametersReference = new AtomicReference<>(parameters); parametersReference = new AtomicReference<>(parameters);
} }
...@@ -1700,7 +1699,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1700,7 +1699,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// MappingTrackSelector implementation. // MappingTrackSelector implementation.
@Override @Override
protected final Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> protected final Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]>
selectTracks( selectTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
@Capabilities int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
...@@ -1710,7 +1709,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1710,7 +1709,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
throws ExoPlaybackException { throws ExoPlaybackException {
Parameters params = parametersReference.get(); Parameters params = parametersReference.get();
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
TrackSelection.@NullableType Definition[] definitions = ExoTrackSelection.@NullableType Definition[] definitions =
selectAllTracks( selectAllTracks(
mappedTrackInfo, mappedTrackInfo,
rendererFormatSupports, rendererFormatSupports,
...@@ -1729,7 +1728,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1729,7 +1728,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
definitions[i] = definitions[i] =
override == null override == null
? null ? null
: new TrackSelection.Definition( : new ExoTrackSelection.Definition(
rendererTrackGroups.get(override.groupIndex), rendererTrackGroups.get(override.groupIndex),
override.tracks, override.tracks,
override.reason, override.reason,
...@@ -1738,14 +1737,14 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1738,14 +1737,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
@NullableType @NullableType
TrackSelection[] rendererTrackSelections = ExoTrackSelection[] rendererTrackSelections =
trackSelectionFactory.createTrackSelections( trackSelectionFactory.createTrackSelections(
definitions, getBandwidthMeter(), mediaPeriodId, timeline); definitions, getBandwidthMeter(), mediaPeriodId, timeline);
// Initialize the renderer configurations to the default configuration for all renderers with // Initialize the renderer configurations to the default configuration for all renderers with
// selections, and null otherwise. // selections, and null otherwise.
@NullableType RendererConfiguration[] rendererConfigurations = @NullableType
new RendererConfiguration[rendererCount]; RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCount];
for (int i = 0; i < rendererCount; i++) { for (int i = 0; i < rendererCount; i++) {
boolean forceRendererDisabled = params.getRendererDisabled(i); boolean forceRendererDisabled = params.getRendererDisabled(i);
boolean rendererEnabled = boolean rendererEnabled =
...@@ -1779,19 +1778,19 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1779,19 +1778,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* renderer, track group and track (in that order). * renderer, track group and track (in that order).
* @param rendererMixedMimeTypeAdaptationSupports The {@link AdaptiveSupport} for mixed MIME type * @param rendererMixedMimeTypeAdaptationSupports The {@link AdaptiveSupport} for mixed MIME type
* adaptation for the renderer. * adaptation for the renderer.
* @return The {@link TrackSelection.Definition}s for the renderers. A null entry indicates no * @return The {@link ExoTrackSelection.Definition}s for the renderers. A null entry indicates no
* selection was made. * selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected TrackSelection.@NullableType Definition[] selectAllTracks( protected ExoTrackSelection.@NullableType Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
@Capabilities int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports, @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports,
Parameters params) Parameters params)
throws ExoPlaybackException { throws ExoPlaybackException {
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
TrackSelection.@NullableType Definition[] definitions = ExoTrackSelection.@NullableType Definition[] definitions =
new TrackSelection.Definition[rendererCount]; new ExoTrackSelection.Definition[rendererCount];
boolean seenVideoRendererWithMappedTracks = false; boolean seenVideoRendererWithMappedTracks = false;
boolean selectedVideoTracks = false; boolean selectedVideoTracks = false;
...@@ -1819,7 +1818,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1819,7 +1818,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
boolean enableAdaptiveTrackSelection = boolean enableAdaptiveTrackSelection =
params.allowMultipleAdaptiveSelections || !seenVideoRendererWithMappedTracks; params.allowMultipleAdaptiveSelections || !seenVideoRendererWithMappedTracks;
@Nullable @Nullable
Pair<TrackSelection.Definition, AudioTrackScore> audioSelection = Pair<ExoTrackSelection.Definition, AudioTrackScore> audioSelection =
selectAudioTrack( selectAudioTrack(
mappedTrackInfo.getTrackGroups(i), mappedTrackInfo.getTrackGroups(i),
rendererFormatSupports[i], rendererFormatSupports[i],
...@@ -1834,7 +1833,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1834,7 +1833,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// score. Clear the selection for that renderer. // score. Clear the selection for that renderer.
definitions[selectedAudioRendererIndex] = null; definitions[selectedAudioRendererIndex] = null;
} }
TrackSelection.Definition definition = audioSelection.first; ExoTrackSelection.Definition definition = audioSelection.first;
definitions[i] = definition; definitions[i] = definition;
// We assume that audio tracks in the same group have matching language. // We assume that audio tracks in the same group have matching language.
selectedAudioLanguage = definition.group.getFormat(definition.tracks[0]).language; selectedAudioLanguage = definition.group.getFormat(definition.tracks[0]).language;
...@@ -1855,7 +1854,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1855,7 +1854,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
break; break;
case C.TRACK_TYPE_TEXT: case C.TRACK_TYPE_TEXT:
@Nullable @Nullable
Pair<TrackSelection.Definition, TextTrackScore> textSelection = Pair<ExoTrackSelection.Definition, TextTrackScore> textSelection =
selectTextTrack( selectTextTrack(
mappedTrackInfo.getTrackGroups(i), mappedTrackInfo.getTrackGroups(i),
rendererFormatSupports[i], rendererFormatSupports[i],
...@@ -1889,7 +1888,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1889,7 +1888,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/** /**
* Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a * Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
* {@link TrackSelection} for a video renderer. * {@link ExoTrackSelection} for a video renderer.
* *
* @param groups The {@link TrackGroupArray} mapped to the renderer. * @param groups The {@link TrackGroupArray} mapped to the renderer.
* @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and * @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
...@@ -1898,19 +1897,19 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1898,19 +1897,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* adaptation for the renderer. * adaptation for the renderer.
* @param params The selector's current constraint parameters. * @param params The selector's current constraint parameters.
* @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed. * @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed.
* @return The {@link TrackSelection.Definition} for the renderer, or null if no selection was * @return The {@link ExoTrackSelection.Definition} for the renderer, or null if no selection was
* made. * made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
@Nullable @Nullable
protected TrackSelection.Definition selectVideoTrack( protected ExoTrackSelection.Definition selectVideoTrack(
TrackGroupArray groups, TrackGroupArray groups,
@Capabilities int[][] formatSupport, @Capabilities int[][] formatSupport,
@AdaptiveSupport int mixedMimeTypeAdaptationSupports, @AdaptiveSupport int mixedMimeTypeAdaptationSupports,
Parameters params, Parameters params,
boolean enableAdaptiveTrackSelection) boolean enableAdaptiveTrackSelection)
throws ExoPlaybackException { throws ExoPlaybackException {
TrackSelection.Definition definition = null; ExoTrackSelection.Definition definition = null;
if (!params.forceHighestSupportedBitrate if (!params.forceHighestSupportedBitrate
&& !params.forceLowestBitrate && !params.forceLowestBitrate
&& enableAdaptiveTrackSelection) { && enableAdaptiveTrackSelection) {
...@@ -1924,7 +1923,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1924,7 +1923,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
@Nullable @Nullable
private static TrackSelection.Definition selectAdaptiveVideoTrack( private static ExoTrackSelection.Definition selectAdaptiveVideoTrack(
TrackGroupArray groups, TrackGroupArray groups,
@Capabilities int[][] formatSupport, @Capabilities int[][] formatSupport,
@AdaptiveSupport int mixedMimeTypeAdaptationSupports, @AdaptiveSupport int mixedMimeTypeAdaptationSupports,
...@@ -1956,7 +1955,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1956,7 +1955,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
params.viewportHeight, params.viewportHeight,
params.viewportOrientationMayChange); params.viewportOrientationMayChange);
if (adaptiveTracks.length > 0) { if (adaptiveTracks.length > 0) {
return new TrackSelection.Definition(group, adaptiveTracks); return new ExoTrackSelection.Definition(group, adaptiveTracks);
} }
} }
return null; return null;
...@@ -1982,8 +1981,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1982,8 +1981,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return NO_TRACKS; return NO_TRACKS;
} }
List<Integer> selectedTrackIndices = getViewportFilteredTrackIndices(group, viewportWidth, List<Integer> selectedTrackIndices =
viewportHeight, viewportOrientationMayChange); getViewportFilteredTrackIndices(
group, viewportWidth, viewportHeight, viewportOrientationMayChange);
if (selectedTrackIndices.size() < 2) { if (selectedTrackIndices.size() < 2) {
return NO_TRACKS; return NO_TRACKS;
} }
...@@ -2140,7 +2140,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2140,7 +2140,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
@Nullable @Nullable
private static TrackSelection.Definition selectFixedVideoTrack( private static ExoTrackSelection.Definition selectFixedVideoTrack(
TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params) { TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params) {
int selectedTrackIndex = C.INDEX_UNSET; int selectedTrackIndex = C.INDEX_UNSET;
@Nullable TrackGroup selectedGroup = null; @Nullable TrackGroup selectedGroup = null;
...@@ -2160,8 +2160,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2160,8 +2160,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Ignore trick-play tracks for now. // Ignore trick-play tracks for now.
continue; continue;
} }
if (isSupported(trackFormatSupport[trackIndex], if (isSupported(
params.exceedRendererCapabilitiesIfNecessary)) { trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
VideoTrackScore trackScore = VideoTrackScore trackScore =
new VideoTrackScore( new VideoTrackScore(
format, format,
...@@ -2183,14 +2183,14 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2183,14 +2183,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return selectedGroup == null return selectedGroup == null
? null ? null
: new TrackSelection.Definition(selectedGroup, selectedTrackIndex); : new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex);
} }
// Audio track selection implementation. // Audio track selection implementation.
/** /**
* Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a * Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
* {@link TrackSelection} for an audio renderer. * {@link ExoTrackSelection} for an audio renderer.
* *
* @param groups The {@link TrackGroupArray} mapped to the renderer. * @param groups The {@link TrackGroupArray} mapped to the renderer.
* @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and * @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
...@@ -2199,13 +2199,13 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2199,13 +2199,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* adaptation for the renderer. * adaptation for the renderer.
* @param params The selector's current constraint parameters. * @param params The selector's current constraint parameters.
* @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed. * @param enableAdaptiveTrackSelection Whether adaptive track selection is allowed.
* @return The {@link TrackSelection.Definition} and corresponding {@link AudioTrackScore}, or * @return The {@link ExoTrackSelection.Definition} and corresponding {@link AudioTrackScore}, or
* null if no selection was made. * null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Nullable @Nullable
protected Pair<TrackSelection.Definition, AudioTrackScore> selectAudioTrack( protected Pair<ExoTrackSelection.Definition, AudioTrackScore> selectAudioTrack(
TrackGroupArray groups, TrackGroupArray groups,
@Capabilities int[][] formatSupport, @Capabilities int[][] formatSupport,
@AdaptiveSupport int mixedMimeTypeAdaptationSupports, @AdaptiveSupport int mixedMimeTypeAdaptationSupports,
...@@ -2219,8 +2219,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2219,8 +2219,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup trackGroup = groups.get(groupIndex); TrackGroup trackGroup = groups.get(groupIndex);
@Capabilities int[] trackFormatSupport = formatSupport[groupIndex]; @Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], if (isSupported(
params.exceedRendererCapabilitiesIfNecessary)) { trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex); Format format = trackGroup.getFormat(trackIndex);
AudioTrackScore trackScore = AudioTrackScore trackScore =
new AudioTrackScore(format, params, trackFormatSupport[trackIndex]); new AudioTrackScore(format, params, trackFormatSupport[trackIndex]);
...@@ -2243,7 +2243,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2243,7 +2243,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup selectedGroup = groups.get(selectedGroupIndex); TrackGroup selectedGroup = groups.get(selectedGroupIndex);
TrackSelection.Definition definition = null; ExoTrackSelection.Definition definition = null;
if (!params.forceHighestSupportedBitrate if (!params.forceHighestSupportedBitrate
&& !params.forceLowestBitrate && !params.forceLowestBitrate
&& enableAdaptiveTrackSelection) { && enableAdaptiveTrackSelection) {
...@@ -2258,12 +2258,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2258,12 +2258,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
params.allowAudioMixedSampleRateAdaptiveness, params.allowAudioMixedSampleRateAdaptiveness,
params.allowAudioMixedChannelCountAdaptiveness); params.allowAudioMixedChannelCountAdaptiveness);
if (adaptiveTracks.length > 1) { if (adaptiveTracks.length > 1) {
definition = new TrackSelection.Definition(selectedGroup, adaptiveTracks); definition = new ExoTrackSelection.Definition(selectedGroup, adaptiveTracks);
} }
} }
if (definition == null) { if (definition == null) {
// We didn't make an adaptive selection, so make a fixed one instead. // We didn't make an adaptive selection, so make a fixed one instead.
definition = new TrackSelection.Definition(selectedGroup, selectedTrackIndex); definition = new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex);
} }
return Pair.create(definition, Assertions.checkNotNull(selectedTrackScore)); return Pair.create(definition, Assertions.checkNotNull(selectedTrackScore));
...@@ -2322,7 +2322,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2322,7 +2322,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/** /**
* Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a * Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
* {@link TrackSelection} for a text renderer. * {@link ExoTrackSelection} for a text renderer.
* *
* @param groups The {@link TrackGroupArray} mapped to the renderer. * @param groups The {@link TrackGroupArray} mapped to the renderer.
* @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and * @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
...@@ -2330,12 +2330,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2330,12 +2330,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* @param params The selector's current constraint parameters. * @param params The selector's current constraint parameters.
* @param selectedAudioLanguage The language of the selected audio track. May be null if the * @param selectedAudioLanguage The language of the selected audio track. May be null if the
* selected text track declares no language or no text track was selected. * selected text track declares no language or no text track was selected.
* @return The {@link TrackSelection.Definition} and corresponding {@link TextTrackScore}, or null * @return The {@link ExoTrackSelection.Definition} and corresponding {@link TextTrackScore}, or
* if no selection was made. * null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
@Nullable @Nullable
protected Pair<TrackSelection.Definition, TextTrackScore> selectTextTrack( protected Pair<ExoTrackSelection.Definition, TextTrackScore> selectTextTrack(
TrackGroupArray groups, TrackGroupArray groups,
@Capabilities int[][] formatSupport, @Capabilities int[][] formatSupport,
Parameters params, Parameters params,
...@@ -2348,8 +2348,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2348,8 +2348,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup trackGroup = groups.get(groupIndex); TrackGroup trackGroup = groups.get(groupIndex);
@Capabilities int[] trackFormatSupport = formatSupport[groupIndex]; @Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], if (isSupported(
params.exceedRendererCapabilitiesIfNecessary)) { trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex); Format format = trackGroup.getFormat(trackIndex);
TextTrackScore trackScore = TextTrackScore trackScore =
new TextTrackScore( new TextTrackScore(
...@@ -2366,7 +2366,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2366,7 +2366,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return selectedGroup == null return selectedGroup == null
? null ? null
: Pair.create( : Pair.create(
new TrackSelection.Definition(selectedGroup, selectedTrackIndex), new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex),
Assertions.checkNotNull(selectedTrackScore)); Assertions.checkNotNull(selectedTrackScore));
} }
...@@ -2374,18 +2374,18 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2374,18 +2374,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/** /**
* Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a * Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
* {@link TrackSelection} for a renderer whose type is neither video, audio or text. * {@link ExoTrackSelection} for a renderer whose type is neither video, audio or text.
* *
* @param trackType The type of the renderer. * @param trackType The type of the renderer.
* @param groups The {@link TrackGroupArray} mapped to the renderer. * @param groups The {@link TrackGroupArray} mapped to the renderer.
* @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and * @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
* track (in that order). * track (in that order).
* @param params The selector's current constraint parameters. * @param params The selector's current constraint parameters.
* @return The {@link TrackSelection} for the renderer, or null if no selection was made. * @return The {@link ExoTrackSelection} for the renderer, or null if no selection was made.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
@Nullable @Nullable
protected TrackSelection.Definition selectOtherTrack( protected ExoTrackSelection.Definition selectOtherTrack(
int trackType, TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params) int trackType, TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params)
throws ExoPlaybackException { throws ExoPlaybackException {
@Nullable TrackGroup selectedGroup = null; @Nullable TrackGroup selectedGroup = null;
...@@ -2395,8 +2395,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2395,8 +2395,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
TrackGroup trackGroup = groups.get(groupIndex); TrackGroup trackGroup = groups.get(groupIndex);
@Capabilities int[] trackFormatSupport = formatSupport[groupIndex]; @Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
if (isSupported(trackFormatSupport[trackIndex], if (isSupported(
params.exceedRendererCapabilitiesIfNecessary)) { trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
Format format = trackGroup.getFormat(trackIndex); Format format = trackGroup.getFormat(trackIndex);
OtherTrackScore trackScore = new OtherTrackScore(format, trackFormatSupport[trackIndex]); OtherTrackScore trackScore = new OtherTrackScore(format, trackFormatSupport[trackIndex]);
if (selectedTrackScore == null || trackScore.compareTo(selectedTrackScore) > 0) { if (selectedTrackScore == null || trackScore.compareTo(selectedTrackScore) > 0) {
...@@ -2409,7 +2409,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2409,7 +2409,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
return selectedGroup == null return selectedGroup == null
? null ? null
: new TrackSelection.Definition(selectedGroup, selectedTrackIndex); : new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex);
} }
// Utility methods. // Utility methods.
...@@ -2430,7 +2430,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2430,7 +2430,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
@Capabilities int[][][] renderererFormatSupports, @Capabilities int[][][] renderererFormatSupports,
@NullableType RendererConfiguration[] rendererConfigurations, @NullableType RendererConfiguration[] rendererConfigurations,
@NullableType TrackSelection[] trackSelections) { @NullableType ExoTrackSelection[] trackSelections) {
// Check whether we can enable tunneling. To enable tunneling we require exactly one audio and // Check whether we can enable tunneling. To enable tunneling we require exactly one audio and
// one video renderer to support tunneling and have a selection. // one video renderer to support tunneling and have a selection.
int tunnelingAudioRendererIndex = -1; int tunnelingAudioRendererIndex = -1;
...@@ -2438,7 +2438,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2438,7 +2438,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
boolean enableTunneling = true; boolean enableTunneling = true;
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) { for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
int rendererType = mappedTrackInfo.getRendererType(i); int rendererType = mappedTrackInfo.getRendererType(i);
TrackSelection trackSelection = trackSelections[i]; ExoTrackSelection trackSelection = trackSelections[i];
if ((rendererType == C.TRACK_TYPE_AUDIO || rendererType == C.TRACK_TYPE_VIDEO) if ((rendererType == C.TRACK_TYPE_AUDIO || rendererType == C.TRACK_TYPE_VIDEO)
&& trackSelection != null) { && trackSelection != null) {
if (rendererSupportsTunneling( if (rendererSupportsTunneling(
...@@ -2471,16 +2471,18 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2471,16 +2471,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
} }
/** /**
* Returns whether a renderer supports tunneling for a {@link TrackSelection}. * Returns whether a renderer supports tunneling for a {@link ExoTrackSelection}.
* *
* @param formatSupport The {@link Capabilities} for each track, indexed by group index and track * @param formatSupport The {@link Capabilities} for each track, indexed by group index and track
* index (in that order). * index (in that order).
* @param trackGroups The {@link TrackGroupArray}s for the renderer. * @param trackGroups The {@link TrackGroupArray}s for the renderer.
* @param selection The track selection. * @param selection The track selection.
* @return Whether the renderer supports tunneling for the {@link TrackSelection}. * @return Whether the renderer supports tunneling for the {@link ExoTrackSelection}.
*/ */
private static boolean rendererSupportsTunneling( private static boolean rendererSupportsTunneling(
@Capabilities int[][] formatSupport, TrackGroupArray trackGroups, TrackSelection selection) { @Capabilities int[][] formatSupport,
TrackGroupArray trackGroups,
ExoTrackSelection selection) {
if (selection == null) { if (selection == null) {
return false; return false;
} }
...@@ -2565,8 +2567,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2565,8 +2567,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return 0; return 0;
} }
private static List<Integer> getViewportFilteredTrackIndices(TrackGroup group, int viewportWidth, private static List<Integer> getViewportFilteredTrackIndices(
int viewportHeight, boolean orientationMayChange) { TrackGroup group, int viewportWidth, int viewportHeight, boolean orientationMayChange) {
// Initially include all indices. // Initially include all indices.
ArrayList<Integer> selectedTrackIndices = new ArrayList<>(group.length); ArrayList<Integer> selectedTrackIndices = new ArrayList<>(group.length);
for (int i = 0; i < group.length; i++) { for (int i = 0; i < group.length; i++) {
...@@ -2585,8 +2587,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2585,8 +2587,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// smallest to exceed the maximum size at which it can be displayed within the viewport. // smallest to exceed the maximum size at which it can be displayed within the viewport.
// We'll discard formats of higher resolution. // We'll discard formats of higher resolution.
if (format.width > 0 && format.height > 0) { if (format.width > 0 && format.height > 0) {
Point maxVideoSizeInViewport = getMaxVideoSizeInViewport(orientationMayChange, Point maxVideoSizeInViewport =
viewportWidth, viewportHeight, format.width, format.height); getMaxVideoSizeInViewport(
orientationMayChange, viewportWidth, viewportHeight, format.width, format.height);
int videoPixels = format.width * format.height; int videoPixels = format.width * format.height;
if (format.width >= (int) (maxVideoSizeInViewport.x * FRACTION_TO_CONSIDER_FULLSCREEN) if (format.width >= (int) (maxVideoSizeInViewport.x * FRACTION_TO_CONSIDER_FULLSCREEN)
&& format.height >= (int) (maxVideoSizeInViewport.y * FRACTION_TO_CONSIDER_FULLSCREEN) && format.height >= (int) (maxVideoSizeInViewport.y * FRACTION_TO_CONSIDER_FULLSCREEN)
...@@ -2616,8 +2619,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2616,8 +2619,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* Given viewport dimensions and video dimensions, computes the maximum size of the video as it * Given viewport dimensions and video dimensions, computes the maximum size of the video as it
* will be rendered to fit inside of the viewport. * will be rendered to fit inside of the viewport.
*/ */
private static Point getMaxVideoSizeInViewport(boolean orientationMayChange, int viewportWidth, private static Point getMaxVideoSizeInViewport(
int viewportHeight, int videoWidth, int videoHeight) { boolean orientationMayChange,
int viewportWidth,
int viewportHeight,
int videoWidth,
int videoHeight) {
if (orientationMayChange && (videoWidth > videoHeight) != (viewportWidth > viewportHeight)) { if (orientationMayChange && (videoWidth > videoHeight) != (viewportWidth > viewportHeight)) {
// Rotation is allowed, and the video will be larger in the rotated viewport. // Rotation is allowed, and the video will be larger in the rotated viewport.
int tempViewportWidth = viewportWidth; int tempViewportWidth = viewportWidth;
......
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.trackselection;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.chunk.Chunk;
import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import java.util.List;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/**
* A {@link TrackSelection} that can change the individually selected track as a result of calling
* {@link #updateSelectedTrack(long, long, long, List, MediaChunkIterator[])} or {@link
* #evaluateQueueSize(long, List)}. This only happens between calls to {@link #enable()} and {@link
* #disable()}.
*/
public interface ExoTrackSelection extends TrackSelection {
/** Contains of a subset of selected tracks belonging to a {@link TrackGroup}. */
final class Definition {
/** The {@link TrackGroup} which tracks belong to. */
public final TrackGroup group;
/** The indices of the selected tracks in {@link #group}. */
public final int[] tracks;
/** The track selection reason. One of the {@link C} SELECTION_REASON_ constants. */
public final int reason;
/** Optional data associated with this selection of tracks. */
@Nullable public final Object data;
/**
* @param group The {@link TrackGroup}. Must not be null.
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
* null or empty. May be in any order.
*/
public Definition(TrackGroup group, int... tracks) {
this(group, tracks, C.SELECTION_REASON_UNKNOWN, /* data= */ null);
}
/**
* @param group The {@link TrackGroup}. Must not be null.
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
* @param reason The track selection reason. One of the {@link C} SELECTION_REASON_ constants.
* @param data Optional data associated with this selection of tracks.
*/
public Definition(TrackGroup group, int[] tracks, int reason, @Nullable Object data) {
this.group = group;
this.tracks = tracks;
this.reason = reason;
this.data = data;
}
}
/** Factory for {@link ExoTrackSelection} instances. */
interface Factory {
/**
* Creates track selections for the provided {@link Definition Definitions}.
*
* <p>Implementations that create at most one adaptive track selection may use {@link
* TrackSelectionUtil#createTrackSelectionsForDefinitions}.
*
* @param definitions A {@link Definition} array. May include null values.
* @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
* @param mediaPeriodId The {@link MediaPeriodId} of the period for which tracks are to be
* selected.
* @param timeline The {@link Timeline} holding the period for which tracks are to be selected.
* @return The created selections. Must have the same length as {@code definitions} and may
* include null values.
*/
@NullableType
ExoTrackSelection[] createTrackSelections(
@NullableType Definition[] definitions,
BandwidthMeter bandwidthMeter,
MediaPeriodId mediaPeriodId,
Timeline timeline);
}
/**
* Enables the track selection. Dynamic changes via {@link #updateSelectedTrack(long, long, long,
* List, MediaChunkIterator[])}, {@link #evaluateQueueSize(long, List)} or {@link
* #shouldCancelChunkLoad(long, Chunk, List)} will only happen after this call.
*
* <p>This method may not be called when the track selection is already enabled.
*/
void enable();
/**
* Disables this track selection. No further dynamic changes via {@link #updateSelectedTrack(long,
* long, long, List, MediaChunkIterator[])}, {@link #evaluateQueueSize(long, List)} or {@link
* #shouldCancelChunkLoad(long, Chunk, List)} will happen after this call.
*
* <p>This method may only be called when the track selection is already enabled.
*/
void disable();
// Individual selected track.
/** Returns the {@link Format} of the individual selected track. */
Format getSelectedFormat();
/** Returns the index in the track group of the individual selected track. */
int getSelectedIndexInTrackGroup();
/** Returns the index of the selected track. */
int getSelectedIndex();
/** Returns the reason for the current track selection. */
int getSelectionReason();
/** Returns optional data associated with the current track selection. */
@Nullable
Object getSelectionData();
// Adaptation.
/**
* Called to notify the selection of the current playback speed. The playback speed may affect
* adaptive track selection.
*
* @param speed The factor by which playback is sped up.
*/
void onPlaybackSpeed(float speed);
/**
* Called to notify the selection of a position discontinuity.
*
* <p>This happens when the playback position jumps, e.g., as a result of a seek being performed.
*/
default void onDiscontinuity() {}
/**
* Called to notify when a rebuffer occurred.
*
* <p>A rebuffer is defined to be caused by buffer depletion rather than a user action. Hence this
* method is not called during initial buffering or when buffering as a result of a seek
* operation.
*/
default void onRebuffer() {}
/**
* Called to notify when the playback is paused or resumed.
*
* @param playWhenReady Whether playback will proceed when ready.
*/
default void onPlayWhenReadyChanged(boolean playWhenReady) {}
/**
* Updates the selected track for sources that load media in discrete {@link MediaChunk}s.
*
* <p>This method will only be called when the selection is enabled.
*
* @param playbackPositionUs The current playback position in microseconds. If playback of the
* period to which this track selection belongs has not yet started, the value will be the
* starting position in the period minus the duration of any media in previous periods still
* to be played.
* @param bufferedDurationUs The duration of media currently buffered from the current playback
* position, in microseconds. Note that the next load position can be calculated as {@code
* (playbackPositionUs + bufferedDurationUs)}.
* @param availableDurationUs The duration of media available for buffering from the current
* playback position, in microseconds, or {@link C#TIME_UNSET} if media can be buffered to the
* end of the current period. Note that if not set to {@link C#TIME_UNSET}, the position up to
* which media is available for buffering can be calculated as {@code (playbackPositionUs +
* availableDurationUs)}.
* @param queue The queue of already buffered {@link MediaChunk}s. Must not be modified.
* @param mediaChunkIterators An array of {@link MediaChunkIterator}s providing information about
* the sequence of upcoming media chunks for each track in the selection. All iterators start
* from the media chunk which will be loaded next if the respective track is selected. Note
* that this information may not be available for all tracks, and so some iterators may be
* empty.
*/
void updateSelectedTrack(
long playbackPositionUs,
long bufferedDurationUs,
long availableDurationUs,
List<? extends MediaChunk> queue,
MediaChunkIterator[] mediaChunkIterators);
/**
* Returns the number of chunks that should be retained in the queue.
*
* <p>May be called by sources that load media in discrete {@link MediaChunk MediaChunks} and
* support discarding of buffered chunks.
*
* <p>To avoid excessive re-buffering, implementations should normally return the size of the
* queue. An example of a case where a smaller value may be returned is if network conditions have
* improved dramatically, allowing chunks to be discarded and re-buffered in a track of
* significantly higher quality. Discarding chunks may allow faster switching to a higher quality
* track in this case.
*
* <p>Note that even if the source supports discarding of buffered chunks, the actual number of
* discarded chunks is not guaranteed. The source will call {@link #updateSelectedTrack(long,
* long, long, List, MediaChunkIterator[])} with the updated queue of chunks before loading a new
* chunk to allow switching to another quality.
*
* <p>This method will only be called when the selection is enabled and none of the {@link
* MediaChunk MediaChunks} in the queue are currently loading.
*
* @param playbackPositionUs The current playback position in microseconds. If playback of the
* period to which this track selection belongs has not yet started, the value will be the
* starting position in the period minus the duration of any media in previous periods still
* to be played.
* @param queue The queue of buffered {@link MediaChunk MediaChunks}. Must not be modified.
* @return The number of chunks to retain in the queue.
*/
int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue);
/**
* Returns whether an ongoing load of a chunk should be canceled.
*
* <p>May be called by sources that load media in discrete {@link MediaChunk MediaChunks} and
* support canceling the ongoing chunk load. The ongoing chunk load is either the last {@link
* MediaChunk} in the queue or another type of {@link Chunk}, for example, if the source loads
* initialization or encryption data.
*
* <p>To avoid excessive re-buffering, implementations should normally return {@code false}. An
* example where {@code true} might be returned is if a load of a high quality chunk gets stuck
* and canceling this load in favor of a lower quality alternative may avoid a rebuffer.
*
* <p>The source will call {@link #evaluateQueueSize(long, List)} after the cancelation finishes
* to allow discarding of chunks, and {@link #updateSelectedTrack(long, long, long, List,
* MediaChunkIterator[])} before loading a new chunk to allow switching to another quality.
*
* <p>This method will only be called when the selection is enabled.
*
* @param playbackPositionUs The current playback position in microseconds. If playback of the
* period to which this track selection belongs has not yet started, the value will be the
* starting position in the period minus the duration of any media in previous periods still
* to be played.
* @param loadingChunk The currently loading {@link Chunk} that will be canceled if this method
* returns {@code true}.
* @param queue The queue of buffered {@link MediaChunk MediaChunks}, including the {@code
* loadingChunk} if it's a {@link MediaChunk}. Must not be modified.
* @return Whether the ongoing load of {@code loadingChunk} should be canceled.
*/
default boolean shouldCancelChunkLoad(
long playbackPositionUs, Chunk loadingChunk, List<? extends MediaChunk> queue) {
return false;
}
/**
* Attempts to exclude the track at the specified index in the selection, making it ineligible for
* selection by calls to {@link #updateSelectedTrack(long, long, long, List,
* MediaChunkIterator[])} for the specified period of time.
*
* <p>Exclusion will fail if all other tracks are currently excluded. If excluding the currently
* selected track, note that it will remain selected until the next call to {@link
* #updateSelectedTrack(long, long, long, List, MediaChunkIterator[])}.
*
* <p>This method will only be called when the selection is enabled.
*
* @param index The index of the track in the selection.
* @param exclusionDurationMs The duration of time for which the track should be excluded, in
* milliseconds.
* @return Whether exclusion was successful.
*/
boolean blacklist(int index, long exclusionDurationMs);
}
...@@ -43,14 +43,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -43,14 +43,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /**
* Base class for {@link TrackSelector}s that first establish a mapping between {@link TrackGroup}s * Base class for {@link TrackSelector}s that first establish a mapping between {@link TrackGroup}s
* and {@link Renderer}s, and then from that mapping create a {@link TrackSelection} for each * and {@link Renderer}s, and then from that mapping create a {@link ExoTrackSelection} for each
* renderer. * renderer.
*/ */
public abstract class MappingTrackSelector extends TrackSelector { public abstract class MappingTrackSelector extends TrackSelector {
/** /** Provides mapped track information for each renderer. */
* Provides mapped track information for each renderer.
*/
public static final class MappedTrackInfo { public static final class MappedTrackInfo {
/** /**
...@@ -401,7 +399,7 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -401,7 +399,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
rendererFormatSupports, rendererFormatSupports,
unmappedTrackGroupArray); unmappedTrackGroupArray);
Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> result = Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]> result =
selectTracks( selectTracks(
mappedTrackInfo, mappedTrackInfo,
rendererFormatSupports, rendererFormatSupports,
...@@ -428,7 +426,7 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -428,7 +426,7 @@ public abstract class MappingTrackSelector extends TrackSelector {
* RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}. * RendererCapabilities#getTrackType()} is {@link C#TRACK_TYPE_NONE}.
* @throws ExoPlaybackException If an error occurs while selecting the tracks. * @throws ExoPlaybackException If an error occurs while selecting the tracks.
*/ */
protected abstract Pair<@NullableType RendererConfiguration[], @NullableType TrackSelection[]> protected abstract Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]>
selectTracks( selectTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
@Capabilities int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
...@@ -538,5 +536,4 @@ public abstract class MappingTrackSelector extends TrackSelector { ...@@ -538,5 +536,4 @@ public abstract class MappingTrackSelector extends TrackSelector {
} }
return mixedMimeTypeAdaptationSupport; return mixedMimeTypeAdaptationSupport;
} }
} }
...@@ -28,15 +28,11 @@ import java.util.List; ...@@ -28,15 +28,11 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /** An {@link ExoTrackSelection} whose selected track is updated randomly. */
* A {@link TrackSelection} whose selected track is updated randomly.
*/
public final class RandomTrackSelection extends BaseTrackSelection { public final class RandomTrackSelection extends BaseTrackSelection {
/** /** Factory for {@link RandomTrackSelection} instances. */
* Factory for {@link RandomTrackSelection} instances. public static final class Factory implements ExoTrackSelection.Factory {
*/
public static final class Factory implements TrackSelection.Factory {
private final Random random; private final Random random;
...@@ -44,15 +40,13 @@ public final class RandomTrackSelection extends BaseTrackSelection { ...@@ -44,15 +40,13 @@ public final class RandomTrackSelection extends BaseTrackSelection {
random = new Random(); random = new Random();
} }
/** /** @param seed A seed for the {@link Random} instance used by the factory. */
* @param seed A seed for the {@link Random} instance used by the factory.
*/
public Factory(int seed) { public Factory(int seed) {
random = new Random(seed); random = new Random(seed);
} }
@Override @Override
public @NullableType TrackSelection[] createTrackSelections( public @NullableType ExoTrackSelection[] createTrackSelections(
@NullableType Definition[] definitions, @NullableType Definition[] definitions,
BandwidthMeter bandwidthMeter, BandwidthMeter bandwidthMeter,
MediaPeriodId mediaPeriodId, MediaPeriodId mediaPeriodId,
...@@ -144,5 +138,4 @@ public final class RandomTrackSelection extends BaseTrackSelection { ...@@ -144,5 +138,4 @@ public final class RandomTrackSelection extends BaseTrackSelection {
public Object getSelectionData() { public Object getSelectionData() {
return null; return null;
} }
} }
...@@ -15,107 +15,18 @@ ...@@ -15,107 +15,18 @@
*/ */
package com.google.android.exoplayer2.trackselection; package com.google.android.exoplayer2.trackselection;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.chunk.Chunk;
import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import java.util.List;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/** /**
* A track selection consisting of a static subset of selected tracks belonging to a {@link * A track selection consisting of a static subset of selected tracks belonging to a {@link
* TrackGroup}, and a possibly varying individual selected track from the subset. * TrackGroup}.
* *
* <p>Tracks belonging to the subset are exposed in decreasing bandwidth order. The individual * <p>Tracks belonging to the subset are exposed in decreasing bandwidth order.
* selected track may change dynamically as a result of calling {@link #updateSelectedTrack(long,
* long, long, List, MediaChunkIterator[])} or {@link #evaluateQueueSize(long, List)}. This only
* happens between calls to {@link #enable()} and {@link #disable()}.
*/ */
public interface TrackSelection { public interface TrackSelection {
/** Contains of a subset of selected tracks belonging to a {@link TrackGroup}. */
final class Definition {
/** The {@link TrackGroup} which tracks belong to. */
public final TrackGroup group;
/** The indices of the selected tracks in {@link #group}. */
public final int[] tracks;
/** The track selection reason. One of the {@link C} SELECTION_REASON_ constants. */
public final int reason;
/** Optional data associated with this selection of tracks. */
@Nullable public final Object data;
/**
* @param group The {@link TrackGroup}. Must not be null.
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
* null or empty. May be in any order.
*/
public Definition(TrackGroup group, int... tracks) {
this(group, tracks, C.SELECTION_REASON_UNKNOWN, /* data= */ null);
}
/**
* @param group The {@link TrackGroup}. Must not be null.
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
* @param reason The track selection reason. One of the {@link C} SELECTION_REASON_ constants.
* @param data Optional data associated with this selection of tracks.
*/
public Definition(TrackGroup group, int[] tracks, int reason, @Nullable Object data) {
this.group = group;
this.tracks = tracks;
this.reason = reason;
this.data = data;
}
}
/** Factory for {@link TrackSelection} instances. */
interface Factory {
/**
* Creates track selections for the provided {@link Definition Definitions}.
*
* <p>Implementations that create at most one adaptive track selection may use {@link
* TrackSelectionUtil#createTrackSelectionsForDefinitions}.
*
* @param definitions A {@link Definition} array. May include null values.
* @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
* @param mediaPeriodId The {@link MediaPeriodId} of the period for which tracks are to be
* selected.
* @param timeline The {@link Timeline} holding the period for which tracks are to be selected.
* @return The created selections. Must have the same length as {@code definitions} and may
* include null values.
*/
@NullableType
TrackSelection[] createTrackSelections(
@NullableType Definition[] definitions,
BandwidthMeter bandwidthMeter,
MediaPeriodId mediaPeriodId,
Timeline timeline);
}
/**
* Enables the track selection. Dynamic changes via {@link #updateSelectedTrack(long, long, long,
* List, MediaChunkIterator[])}, {@link #evaluateQueueSize(long, List)} or {@link
* #shouldCancelChunkLoad(long, Chunk, List)} will only happen after this call.
*
* <p>This method may not be called when the track selection is already enabled.
*/
void enable();
/**
* Disables this track selection. No further dynamic changes via {@link #updateSelectedTrack(long,
* long, long, List, MediaChunkIterator[])}, {@link #evaluateQueueSize(long, List)} or {@link
* #shouldCancelChunkLoad(long, Chunk, List)} will happen after this call.
*
* <p>This method may only be called when the track selection is already enabled.
*/
void disable();
/** Returns the {@link TrackGroup} to which the selected tracks belong. */ /** Returns the {@link TrackGroup} to which the selected tracks belong. */
TrackGroup getTrackGroup(); TrackGroup getTrackGroup();
...@@ -159,166 +70,4 @@ public interface TrackSelection { ...@@ -159,166 +70,4 @@ public interface TrackSelection {
* index is not part of the selection. * index is not part of the selection.
*/ */
int indexOf(int indexInTrackGroup); int indexOf(int indexInTrackGroup);
// Individual selected track.
/** Returns the {@link Format} of the individual selected track. */
Format getSelectedFormat();
/** Returns the index in the track group of the individual selected track. */
int getSelectedIndexInTrackGroup();
/** Returns the index of the selected track. */
int getSelectedIndex();
/** Returns the reason for the current track selection. */
int getSelectionReason();
/** Returns optional data associated with the current track selection. */
@Nullable
Object getSelectionData();
// Adaptation.
/**
* Called to notify the selection of the current playback speed. The playback speed may affect
* adaptive track selection.
*
* @param speed The factor by which playback is sped up.
*/
void onPlaybackSpeed(float speed);
/**
* Called to notify the selection of a position discontinuity.
*
* <p>This happens when the playback position jumps, e.g., as a result of a seek being performed.
*/
default void onDiscontinuity() {}
/**
* Called to notify when a rebuffer occurred.
*
* <p>A rebuffer is defined to be caused by buffer depletion rather than a user action. Hence this
* method is not called during initial buffering or when buffering as a result of a seek
* operation.
*/
default void onRebuffer() {}
/**
* Called to notify when the playback is paused or resumed.
*
* @param playWhenReady Whether playback will proceed when ready.
*/
default void onPlayWhenReadyChanged(boolean playWhenReady) {}
/**
* Updates the selected track for sources that load media in discrete {@link MediaChunk}s.
*
* <p>This method will only be called when the selection is enabled.
*
* @param playbackPositionUs The current playback position in microseconds. If playback of the
* period to which this track selection belongs has not yet started, the value will be the
* starting position in the period minus the duration of any media in previous periods still
* to be played.
* @param bufferedDurationUs The duration of media currently buffered from the current playback
* position, in microseconds. Note that the next load position can be calculated as {@code
* (playbackPositionUs + bufferedDurationUs)}.
* @param availableDurationUs The duration of media available for buffering from the current
* playback position, in microseconds, or {@link C#TIME_UNSET} if media can be buffered to the
* end of the current period. Note that if not set to {@link C#TIME_UNSET}, the position up to
* which media is available for buffering can be calculated as {@code (playbackPositionUs +
* availableDurationUs)}.
* @param queue The queue of already buffered {@link MediaChunk}s. Must not be modified.
* @param mediaChunkIterators An array of {@link MediaChunkIterator}s providing information about
* the sequence of upcoming media chunks for each track in the selection. All iterators start
* from the media chunk which will be loaded next if the respective track is selected. Note
* that this information may not be available for all tracks, and so some iterators may be
* empty.
*/
void updateSelectedTrack(
long playbackPositionUs,
long bufferedDurationUs,
long availableDurationUs,
List<? extends MediaChunk> queue,
MediaChunkIterator[] mediaChunkIterators);
/**
* Returns the number of chunks that should be retained in the queue.
*
* <p>May be called by sources that load media in discrete {@link MediaChunk MediaChunks} and
* support discarding of buffered chunks.
*
* <p>To avoid excessive re-buffering, implementations should normally return the size of the
* queue. An example of a case where a smaller value may be returned is if network conditions have
* improved dramatically, allowing chunks to be discarded and re-buffered in a track of
* significantly higher quality. Discarding chunks may allow faster switching to a higher quality
* track in this case.
*
* <p>Note that even if the source supports discarding of buffered chunks, the actual number of
* discarded chunks is not guaranteed. The source will call {@link #updateSelectedTrack(long,
* long, long, List, MediaChunkIterator[])} with the updated queue of chunks before loading a new
* chunk to allow switching to another quality.
*
* <p>This method will only be called when the selection is enabled and none of the {@link
* MediaChunk MediaChunks} in the queue are currently loading.
*
* @param playbackPositionUs The current playback position in microseconds. If playback of the
* period to which this track selection belongs has not yet started, the value will be the
* starting position in the period minus the duration of any media in previous periods still
* to be played.
* @param queue The queue of buffered {@link MediaChunk MediaChunks}. Must not be modified.
* @return The number of chunks to retain in the queue.
*/
int evaluateQueueSize(long playbackPositionUs, List<? extends MediaChunk> queue);
/**
* Returns whether an ongoing load of a chunk should be canceled.
*
* <p>May be called by sources that load media in discrete {@link MediaChunk MediaChunks} and
* support canceling the ongoing chunk load. The ongoing chunk load is either the last {@link
* MediaChunk} in the queue or another type of {@link Chunk}, for example, if the source loads
* initialization or encryption data.
*
* <p>To avoid excessive re-buffering, implementations should normally return {@code false}. An
* example where {@code true} might be returned is if a load of a high quality chunk gets stuck
* and canceling this load in favor of a lower quality alternative may avoid a rebuffer.
*
* <p>The source will call {@link #evaluateQueueSize(long, List)} after the cancelation finishes
* to allow discarding of chunks, and {@link #updateSelectedTrack(long, long, long, List,
* MediaChunkIterator[])} before loading a new chunk to allow switching to another quality.
*
* <p>This method will only be called when the selection is enabled.
*
* @param playbackPositionUs The current playback position in microseconds. If playback of the
* period to which this track selection belongs has not yet started, the value will be the
* starting position in the period minus the duration of any media in previous periods still
* to be played.
* @param loadingChunk The currently loading {@link Chunk} that will be canceled if this method
* returns {@code true}.
* @param queue The queue of buffered {@link MediaChunk MediaChunks}, including the {@code
* loadingChunk} if it's a {@link MediaChunk}. Must not be modified.
* @return Whether the ongoing load of {@code loadingChunk} should be canceled.
*/
default boolean shouldCancelChunkLoad(
long playbackPositionUs, Chunk loadingChunk, List<? extends MediaChunk> queue) {
return false;
}
/**
* Attempts to exclude the track at the specified index in the selection, making it ineligible for
* selection by calls to {@link #updateSelectedTrack(long, long, long, List,
* MediaChunkIterator[])} for the specified period of time.
*
* <p>Exclusion will fail if all other tracks are currently excluded. If excluding the currently
* selected track, note that it will remain selected until the next call to {@link
* #updateSelectedTrack(long, long, long, List, MediaChunkIterator[])}.
*
* <p>This method will only be called when the selection is enabled.
*
* @param index The index of the track in the selection.
* @param exclusionDurationMs The duration of time for which the track should be excluded, in
* milliseconds.
* @return Whether exclusion was successful.
*/
boolean blacklist(int index, long exclusionDurationMs);
} }
...@@ -18,7 +18,7 @@ package com.google.android.exoplayer2.trackselection; ...@@ -18,7 +18,7 @@ package com.google.android.exoplayer2.trackselection;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
import com.google.android.exoplayer2.trackselection.TrackSelection.Definition; import com.google.android.exoplayer2.trackselection.ExoTrackSelection.Definition;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
/** Track selection related utility methods. */ /** Track selection related utility methods. */
...@@ -35,7 +35,7 @@ public final class TrackSelectionUtil { ...@@ -35,7 +35,7 @@ public final class TrackSelectionUtil {
* @param trackSelectionDefinition A {@link Definition} for the track selection. * @param trackSelectionDefinition A {@link Definition} for the track selection.
* @return The created track selection. * @return The created track selection.
*/ */
TrackSelection createAdaptiveTrackSelection(Definition trackSelectionDefinition); ExoTrackSelection createAdaptiveTrackSelection(Definition trackSelectionDefinition);
} }
/** /**
...@@ -48,10 +48,10 @@ public final class TrackSelectionUtil { ...@@ -48,10 +48,10 @@ public final class TrackSelectionUtil {
* @return The array of created track selection. For null entries in {@code definitions} returns * @return The array of created track selection. For null entries in {@code definitions} returns
* null values. * null values.
*/ */
public static @NullableType TrackSelection[] createTrackSelectionsForDefinitions( public static @NullableType ExoTrackSelection[] createTrackSelectionsForDefinitions(
@NullableType Definition[] definitions, @NullableType Definition[] definitions,
AdaptiveTrackSelectionFactory adaptiveTrackSelectionFactory) { AdaptiveTrackSelectionFactory adaptiveTrackSelectionFactory) {
TrackSelection[] selections = new TrackSelection[definitions.length]; ExoTrackSelection[] selections = new ExoTrackSelection[definitions.length];
boolean createdAdaptiveTrackSelection = false; boolean createdAdaptiveTrackSelection = false;
for (int i = 0; i < definitions.length; i++) { for (int i = 0; i < definitions.length; i++) {
Definition definition = definitions[i]; Definition definition = definitions[i];
......
...@@ -30,8 +30,8 @@ public final class TrackSelectorResult { ...@@ -30,8 +30,8 @@ public final class TrackSelectorResult {
* renderer should be disabled. * renderer should be disabled.
*/ */
public final @NullableType RendererConfiguration[] rendererConfigurations; public final @NullableType RendererConfiguration[] rendererConfigurations;
/** A {@link TrackSelection} array containing the track selection for each renderer. */ /** A {@link ExoTrackSelection} array containing the track selection for each renderer. */
public final @NullableType TrackSelection[] selections; public final @NullableType ExoTrackSelection[] selections;
/** /**
* An opaque object that will be returned to {@link TrackSelector#onSelectionActivated(Object)} * An opaque object that will be returned to {@link TrackSelector#onSelectionActivated(Object)}
* should the selections be activated. * should the selections be activated.
...@@ -41,14 +41,14 @@ public final class TrackSelectorResult { ...@@ -41,14 +41,14 @@ public final class TrackSelectorResult {
/** /**
* @param rendererConfigurations A {@link RendererConfiguration} for each renderer. A null entry * @param rendererConfigurations A {@link RendererConfiguration} for each renderer. A null entry
* indicates the corresponding renderer should be disabled. * indicates the corresponding renderer should be disabled.
* @param selections A {@link TrackSelection} array containing the selection for each renderer. * @param selections A {@link ExoTrackSelection} array containing the selection for each renderer.
* @param info An opaque object that will be returned to {@link * @param info An opaque object that will be returned to {@link
* TrackSelector#onSelectionActivated(Object)} should the selection be activated. May be * TrackSelector#onSelectionActivated(Object)} should the selection be activated. May be
* {@code null}. * {@code null}.
*/ */
public TrackSelectorResult( public TrackSelectorResult(
@NullableType RendererConfiguration[] rendererConfigurations, @NullableType RendererConfiguration[] rendererConfigurations,
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
@Nullable Object info) { @Nullable Object info) {
this.rendererConfigurations = rendererConfigurations; this.rendererConfigurations = rendererConfigurations;
this.selections = selections.clone(); this.selections = selections.clone();
......
...@@ -20,7 +20,7 @@ import static com.google.common.truth.Truth.assertThat; ...@@ -20,7 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.DefaultLoadControl.Builder; import com.google.android.exoplayer2.DefaultLoadControl.Builder;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.DefaultAllocator; import com.google.android.exoplayer2.upstream.DefaultAllocator;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -177,7 +177,7 @@ public class DefaultLoadControlTest { ...@@ -177,7 +177,7 @@ public class DefaultLoadControlTest {
@Test @Test
public void shouldContinueLoading_withNoSelectedTracks_returnsTrue() { public void shouldContinueLoading_withNoSelectedTracks_returnsTrue() {
loadControl = builder.build(); loadControl = builder.build();
loadControl.onTracksSelected(new Renderer[0], TrackGroupArray.EMPTY, new TrackSelection[0]); loadControl.onTracksSelected(new Renderer[0], TrackGroupArray.EMPTY, new ExoTrackSelection[0]);
assertThat( assertThat(
loadControl.shouldContinueLoading( loadControl.shouldContinueLoading(
......
...@@ -31,7 +31,7 @@ import com.google.android.exoplayer2.testutil.FakeMediaSource; ...@@ -31,7 +31,7 @@ import com.google.android.exoplayer2.testutil.FakeMediaSource;
import com.google.android.exoplayer2.testutil.FakeShuffleOrder; import com.google.android.exoplayer2.testutil.FakeShuffleOrder;
import com.google.android.exoplayer2.testutil.FakeTimeline; import com.google.android.exoplayer2.testutil.FakeTimeline;
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectorResult; import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
...@@ -470,7 +470,7 @@ public final class MediaPeriodQueueTest { ...@@ -470,7 +470,7 @@ public final class MediaPeriodQueueTest {
mediaSourceList, mediaSourceList,
getNextMediaPeriodInfo(), getNextMediaPeriodInfo(),
new TrackSelectorResult( new TrackSelectorResult(
new RendererConfiguration[0], new TrackSelection[0], /* info= */ null)); new RendererConfiguration[0], new ExoTrackSelection[0], /* info= */ null));
} }
private MediaPeriodInfo getNextMediaPeriodInfo() { private MediaPeriodInfo getNextMediaPeriodInfo() {
......
...@@ -38,8 +38,8 @@ import com.google.android.exoplayer2.testutil.FakeRenderer; ...@@ -38,8 +38,8 @@ import com.google.android.exoplayer2.testutil.FakeRenderer;
import com.google.android.exoplayer2.testutil.FakeTimeline; import com.google.android.exoplayer2.testutil.FakeTimeline;
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition; import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo; import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import java.io.IOException; import java.io.IOException;
...@@ -99,8 +99,7 @@ public class DownloadHelperTest { ...@@ -99,8 +99,7 @@ public class DownloadHelperTest {
trackGroupTextZh); trackGroupTextZh);
TrackGroupArray trackGroupArraySingle = TrackGroupArray trackGroupArraySingle =
new TrackGroupArray(TRACK_GROUP_VIDEO_SINGLE, trackGroupAudioUs); new TrackGroupArray(TRACK_GROUP_VIDEO_SINGLE, trackGroupAudioUs);
trackGroupArrays = trackGroupArrays = new TrackGroupArray[] {trackGroupArrayAll, trackGroupArraySingle};
new TrackGroupArray[] {trackGroupArrayAll, trackGroupArraySingle};
testMediaItem = testMediaItem =
new MediaItem.Builder().setUri("http://test.uri").setCustomCacheKey("cacheKey").build(); new MediaItem.Builder().setUri("http://test.uri").setCustomCacheKey("cacheKey").build();
...@@ -194,17 +193,17 @@ public class DownloadHelperTest { ...@@ -194,17 +193,17 @@ public class DownloadHelperTest {
public void getTrackSelections_returnsInitialSelection() throws Exception { public void getTrackSelections_returnsInitialSelection() throws Exception {
prepareDownloadHelper(downloadHelper); prepareDownloadHelper(downloadHelper);
List<TrackSelection> selectedText0 = List<ExoTrackSelection> selectedText0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio0 = List<ExoTrackSelection> selectedAudio0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo0 = List<ExoTrackSelection> selectedVideo0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
List<TrackSelection> selectedText1 = List<ExoTrackSelection> selectedText1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio1 = List<ExoTrackSelection> selectedAudio1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo1 = List<ExoTrackSelection> selectedVideo1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
assertSingleTrackSelectionEquals(selectedText0, trackGroupTextUs, 0); assertSingleTrackSelectionEquals(selectedText0, trackGroupTextUs, 0);
...@@ -222,17 +221,17 @@ public class DownloadHelperTest { ...@@ -222,17 +221,17 @@ public class DownloadHelperTest {
// Clear only one period selection to verify second period selection is untouched. // Clear only one period selection to verify second period selection is untouched.
downloadHelper.clearTrackSelections(/* periodIndex= */ 0); downloadHelper.clearTrackSelections(/* periodIndex= */ 0);
List<TrackSelection> selectedText0 = List<ExoTrackSelection> selectedText0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio0 = List<ExoTrackSelection> selectedAudio0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo0 = List<ExoTrackSelection> selectedVideo0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
List<TrackSelection> selectedText1 = List<ExoTrackSelection> selectedText1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio1 = List<ExoTrackSelection> selectedAudio1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo1 = List<ExoTrackSelection> selectedVideo1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
assertThat(selectedText0).isEmpty(); assertThat(selectedText0).isEmpty();
...@@ -258,17 +257,17 @@ public class DownloadHelperTest { ...@@ -258,17 +257,17 @@ public class DownloadHelperTest {
// Replace only one period selection to verify second period selection is untouched. // Replace only one period selection to verify second period selection is untouched.
downloadHelper.replaceTrackSelections(/* periodIndex= */ 0, parameters); downloadHelper.replaceTrackSelections(/* periodIndex= */ 0, parameters);
List<TrackSelection> selectedText0 = List<ExoTrackSelection> selectedText0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio0 = List<ExoTrackSelection> selectedAudio0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo0 = List<ExoTrackSelection> selectedVideo0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
List<TrackSelection> selectedText1 = List<ExoTrackSelection> selectedText1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio1 = List<ExoTrackSelection> selectedAudio1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo1 = List<ExoTrackSelection> selectedVideo1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
assertSingleTrackSelectionEquals(selectedText0, trackGroupTextZh, 0); assertSingleTrackSelectionEquals(selectedText0, trackGroupTextZh, 0);
...@@ -294,17 +293,17 @@ public class DownloadHelperTest { ...@@ -294,17 +293,17 @@ public class DownloadHelperTest {
// Add only to one period selection to verify second period selection is untouched. // Add only to one period selection to verify second period selection is untouched.
downloadHelper.addTrackSelection(/* periodIndex= */ 0, parameters); downloadHelper.addTrackSelection(/* periodIndex= */ 0, parameters);
List<TrackSelection> selectedText0 = List<ExoTrackSelection> selectedText0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio0 = List<ExoTrackSelection> selectedAudio0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo0 = List<ExoTrackSelection> selectedVideo0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
List<TrackSelection> selectedText1 = List<ExoTrackSelection> selectedText1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio1 = List<ExoTrackSelection> selectedAudio1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo1 = List<ExoTrackSelection> selectedVideo1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
assertSingleTrackSelectionEquals(selectedText0, trackGroupTextUs, 0); assertSingleTrackSelectionEquals(selectedText0, trackGroupTextUs, 0);
...@@ -327,17 +326,17 @@ public class DownloadHelperTest { ...@@ -327,17 +326,17 @@ public class DownloadHelperTest {
// Add a non-default language, and a non-existing language (which will select the default). // Add a non-default language, and a non-existing language (which will select the default).
downloadHelper.addAudioLanguagesToSelection("ZH", "Klingonese"); downloadHelper.addAudioLanguagesToSelection("ZH", "Klingonese");
List<TrackSelection> selectedText0 = List<ExoTrackSelection> selectedText0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio0 = List<ExoTrackSelection> selectedAudio0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo0 = List<ExoTrackSelection> selectedVideo0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
List<TrackSelection> selectedText1 = List<ExoTrackSelection> selectedText1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio1 = List<ExoTrackSelection> selectedAudio1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo1 = List<ExoTrackSelection> selectedVideo1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
assertThat(selectedVideo0).isEmpty(); assertThat(selectedVideo0).isEmpty();
...@@ -361,17 +360,17 @@ public class DownloadHelperTest { ...@@ -361,17 +360,17 @@ public class DownloadHelperTest {
// Add a non-default language, and a non-existing language (which will select the default). // Add a non-default language, and a non-existing language (which will select the default).
downloadHelper.addTextLanguagesToSelection( downloadHelper.addTextLanguagesToSelection(
/* selectUndeterminedTextLanguage= */ true, "ZH", "Klingonese"); /* selectUndeterminedTextLanguage= */ true, "ZH", "Klingonese");
List<TrackSelection> selectedText0 = List<ExoTrackSelection> selectedText0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio0 = List<ExoTrackSelection> selectedAudio0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo0 = List<ExoTrackSelection> selectedVideo0 =
downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 0, /* rendererIndex= */ 2);
List<TrackSelection> selectedText1 = List<ExoTrackSelection> selectedText1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 0);
List<TrackSelection> selectedAudio1 = List<ExoTrackSelection> selectedAudio1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 1);
List<TrackSelection> selectedVideo1 = List<ExoTrackSelection> selectedVideo1 =
downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2); downloadHelper.getTrackSelections(/* periodIndex= */ 1, /* rendererIndex= */ 2);
assertThat(selectedVideo0).isEmpty(); assertThat(selectedVideo0).isEmpty();
...@@ -464,13 +463,13 @@ public class DownloadHelperTest { ...@@ -464,13 +463,13 @@ public class DownloadHelperTest {
} }
private static void assertSingleTrackSelectionEquals( private static void assertSingleTrackSelectionEquals(
List<TrackSelection> trackSelectionList, TrackGroup trackGroup, int... tracks) { List<ExoTrackSelection> trackSelectionList, TrackGroup trackGroup, int... tracks) {
assertThat(trackSelectionList).hasSize(1); assertThat(trackSelectionList).hasSize(1);
assertTrackSelectionEquals(trackSelectionList.get(0), trackGroup, tracks); assertTrackSelectionEquals(trackSelectionList.get(0), trackGroup, tracks);
} }
private static void assertTrackSelectionEquals( private static void assertTrackSelectionEquals(
TrackSelection trackSelection, TrackGroup trackGroup, int... tracks) { ExoTrackSelection trackSelection, TrackGroup trackGroup, int... tracks) {
assertThat(trackSelection.getTrackGroup()).isEqualTo(trackGroup); assertThat(trackSelection.getTrackGroup()).isEqualTo(trackGroup);
assertThat(trackSelection.length()).isEqualTo(tracks.length); assertThat(trackSelection.length()).isEqualTo(tracks.length);
int[] selectedTracksInGroup = new int[trackSelection.length()]; int[] selectedTracksInGroup = new int[trackSelection.length()];
...@@ -498,9 +497,9 @@ public class DownloadHelperTest { ...@@ -498,9 +497,9 @@ public class DownloadHelperTest {
new EventDispatcher() new EventDispatcher()
.withParameters(/* windowIndex= */ 0, id, /* mediaTimeOffsetMs= */ 0)) { .withParameters(/* windowIndex= */ 0, id, /* mediaTimeOffsetMs= */ 0)) {
@Override @Override
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) { public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
List<StreamKey> result = new ArrayList<>(); List<StreamKey> result = new ArrayList<>();
for (TrackSelection trackSelection : trackSelections) { for (ExoTrackSelection trackSelection : trackSelections) {
int groupIndex = trackGroupArrays[periodIndex].indexOf(trackSelection.getTrackGroup()); int groupIndex = trackGroupArrays[periodIndex].indexOf(trackSelection.getTrackGroup());
for (int i = 0; i < trackSelection.length(); i++) { for (int i = 0; i < trackSelection.length(); i++) {
result.add( result.add(
......
...@@ -29,8 +29,8 @@ import com.google.android.exoplayer2.drm.DrmSessionManager; ...@@ -29,8 +29,8 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.testutil.FakeMediaPeriod; import com.google.android.exoplayer2.testutil.FakeMediaPeriod;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.FixedTrackSelection; import com.google.android.exoplayer2.trackselection.FixedTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.DefaultAllocator; import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
...@@ -72,13 +72,15 @@ public final class MergingMediaPeriodTest { ...@@ -72,13 +72,15 @@ public final class MergingMediaPeriodTest {
new MergingPeriodDefinition( new MergingPeriodDefinition(
/* timeOffsetUs= */ 0, /* singleSampleTimeUs= */ 0, childFormat21, childFormat22)); /* timeOffsetUs= */ 0, /* singleSampleTimeUs= */ 0, childFormat21, childFormat22));
TrackSelection selectionForChild1 = ExoTrackSelection selectionForChild1 =
new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(1), /* track= */ 0); new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(1), /* track= */ 0);
TrackSelection selectionForChild2 = ExoTrackSelection selectionForChild2 =
new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(2), /* track= */ 0); new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(2), /* track= */ 0);
SampleStream[] streams = new SampleStream[4]; SampleStream[] streams = new SampleStream[4];
mergingMediaPeriod.selectTracks( mergingMediaPeriod.selectTracks(
/* selections= */ new TrackSelection[] {null, selectionForChild1, selectionForChild2, null}, /* selections= */ new ExoTrackSelection[] {
null, selectionForChild1, selectionForChild2, null
},
/* mayRetainStreamFlags= */ new boolean[] {false, false, false, false}, /* mayRetainStreamFlags= */ new boolean[] {false, false, false, false},
streams, streams,
/* streamResetFlags= */ new boolean[] {false, false, false, false}, /* streamResetFlags= */ new boolean[] {false, false, false, false},
...@@ -117,13 +119,13 @@ public final class MergingMediaPeriodTest { ...@@ -117,13 +119,13 @@ public final class MergingMediaPeriodTest {
childFormat21, childFormat21,
childFormat22)); childFormat22));
TrackSelection selectionForChild1 = ExoTrackSelection selectionForChild1 =
new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(0), /* track= */ 0); new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(0), /* track= */ 0);
TrackSelection selectionForChild2 = ExoTrackSelection selectionForChild2 =
new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(2), /* track= */ 0); new FixedTrackSelection(mergingMediaPeriod.getTrackGroups().get(2), /* track= */ 0);
SampleStream[] streams = new SampleStream[2]; SampleStream[] streams = new SampleStream[2];
mergingMediaPeriod.selectTracks( mergingMediaPeriod.selectTracks(
/* selections= */ new TrackSelection[] {selectionForChild1, selectionForChild2}, /* selections= */ new ExoTrackSelection[] {selectionForChild1, selectionForChild2},
/* mayRetainStreamFlags= */ new boolean[] {false, false}, /* mayRetainStreamFlags= */ new boolean[] {false, false},
streams, streams,
/* streamResetFlags= */ new boolean[] {false, false}, /* streamResetFlags= */ new boolean[] {false, false},
...@@ -218,7 +220,7 @@ public final class MergingMediaPeriodTest { ...@@ -218,7 +220,7 @@ public final class MergingMediaPeriodTest {
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
......
...@@ -30,7 +30,7 @@ import com.google.android.exoplayer2.testutil.FakeClock; ...@@ -30,7 +30,7 @@ import com.google.android.exoplayer2.testutil.FakeClock;
import com.google.android.exoplayer2.testutil.FakeMediaChunk; import com.google.android.exoplayer2.testutil.FakeMediaChunk;
import com.google.android.exoplayer2.testutil.FakeTimeline; import com.google.android.exoplayer2.testutil.FakeTimeline;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection.AdaptationCheckpoint; import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection.AdaptationCheckpoint;
import com.google.android.exoplayer2.trackselection.TrackSelection.Definition; import com.google.android.exoplayer2.trackselection.ExoTrackSelection.Definition;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
......
...@@ -138,7 +138,7 @@ public final class MappingTrackSelectorTest { ...@@ -138,7 +138,7 @@ public final class MappingTrackSelectorTest {
private MappedTrackInfo lastMappedTrackInfo; private MappedTrackInfo lastMappedTrackInfo;
@Override @Override
protected Pair<RendererConfiguration[], TrackSelection[]> selectTracks( protected Pair<RendererConfiguration[], ExoTrackSelection[]> selectTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
@Capabilities int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports, @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports,
...@@ -147,7 +147,7 @@ public final class MappingTrackSelectorTest { ...@@ -147,7 +147,7 @@ public final class MappingTrackSelectorTest {
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
lastMappedTrackInfo = mappedTrackInfo; lastMappedTrackInfo = mappedTrackInfo;
return Pair.create( return Pair.create(
new RendererConfiguration[rendererCount], new TrackSelection[rendererCount]); new RendererConfiguration[rendererCount], new ExoTrackSelection[rendererCount]);
} }
public void assertMappedTrackGroups(int rendererIndex, TrackGroup... expected) { public void assertMappedTrackGroups(int rendererIndex, TrackGroup... expected) {
......
...@@ -21,14 +21,12 @@ import com.google.android.exoplayer2.Format; ...@@ -21,14 +21,12 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.chunk.ChunkSource; import com.google.android.exoplayer2.source.chunk.ChunkSource;
import com.google.android.exoplayer2.source.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler; import com.google.android.exoplayer2.source.dash.PlayerEmsgHandler.PlayerTrackEmsgHandler;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
import java.util.List; import java.util.List;
/** /** A {@link ChunkSource} for DASH streams. */
* An {@link ChunkSource} for DASH streams.
*/
public interface DashChunkSource extends ChunkSource { public interface DashChunkSource extends ChunkSource {
/** Factory for {@link DashChunkSource}s. */ /** Factory for {@link DashChunkSource}s. */
...@@ -55,7 +53,7 @@ public interface DashChunkSource extends ChunkSource { ...@@ -55,7 +53,7 @@ public interface DashChunkSource extends ChunkSource {
DashManifest manifest, DashManifest manifest,
int periodIndex, int periodIndex,
int[] adaptationSetIndices, int[] adaptationSetIndices,
TrackSelection trackSelection, ExoTrackSelection trackSelection,
int type, int type,
long elapsedRealtimeOffsetMs, long elapsedRealtimeOffsetMs,
boolean enableEventMessageTrack, boolean enableEventMessageTrack,
...@@ -76,5 +74,5 @@ public interface DashChunkSource extends ChunkSource { ...@@ -76,5 +74,5 @@ public interface DashChunkSource extends ChunkSource {
* *
* @param trackSelection The new track selection instance. Must be equivalent to the previous one. * @param trackSelection The new track selection instance. Must be equivalent to the previous one.
*/ */
void updateTrackSelection(TrackSelection trackSelection); void updateTrackSelection(ExoTrackSelection trackSelection);
} }
...@@ -47,7 +47,7 @@ import com.google.android.exoplayer2.source.dash.manifest.Descriptor; ...@@ -47,7 +47,7 @@ import com.google.android.exoplayer2.source.dash.manifest.Descriptor;
import com.google.android.exoplayer2.source.dash.manifest.EventStream; import com.google.android.exoplayer2.source.dash.manifest.EventStream;
import com.google.android.exoplayer2.source.dash.manifest.Period; import com.google.android.exoplayer2.source.dash.manifest.Period;
import com.google.android.exoplayer2.source.dash.manifest.Representation; import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
...@@ -213,10 +213,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -213,10 +213,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
@Override @Override
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) { public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
List<AdaptationSet> manifestAdaptationSets = manifest.getPeriod(periodIndex).adaptationSets; List<AdaptationSet> manifestAdaptationSets = manifest.getPeriod(periodIndex).adaptationSets;
List<StreamKey> streamKeys = new ArrayList<>(); List<StreamKey> streamKeys = new ArrayList<>();
for (TrackSelection trackSelection : trackSelections) { for (ExoTrackSelection trackSelection : trackSelections) {
int trackGroupIndex = trackGroups.indexOf(trackSelection.getTrackGroup()); int trackGroupIndex = trackGroups.indexOf(trackSelection.getTrackGroup());
TrackGroupInfo trackGroupInfo = trackGroupInfos[trackGroupIndex]; TrackGroupInfo trackGroupInfo = trackGroupInfos[trackGroupIndex];
if (trackGroupInfo.trackGroupCategory != TrackGroupInfo.CATEGORY_PRIMARY) { if (trackGroupInfo.trackGroupCategory != TrackGroupInfo.CATEGORY_PRIMARY) {
...@@ -256,7 +256,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -256,7 +256,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -356,7 +356,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -356,7 +356,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
// Internal methods. // Internal methods.
private int[] getStreamIndexToTrackGroupIndex(TrackSelection[] selections) { private int[] getStreamIndexToTrackGroupIndex(ExoTrackSelection[] selections) {
int[] streamIndexToTrackGroupIndex = new int[selections.length]; int[] streamIndexToTrackGroupIndex = new int[selections.length];
for (int i = 0; i < selections.length; i++) { for (int i = 0; i < selections.length; i++) {
if (selections[i] != null) { if (selections[i] != null) {
...@@ -369,7 +369,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -369,7 +369,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
private void releaseDisabledStreams( private void releaseDisabledStreams(
TrackSelection[] selections, boolean[] mayRetainStreamFlags, SampleStream[] streams) { ExoTrackSelection[] selections, boolean[] mayRetainStreamFlags, SampleStream[] streams) {
for (int i = 0; i < selections.length; i++) { for (int i = 0; i < selections.length; i++) {
if (selections[i] == null || !mayRetainStreamFlags[i]) { if (selections[i] == null || !mayRetainStreamFlags[i]) {
if (streams[i] instanceof ChunkSampleStream) { if (streams[i] instanceof ChunkSampleStream) {
...@@ -386,7 +386,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -386,7 +386,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
private void releaseOrphanEmbeddedStreams( private void releaseOrphanEmbeddedStreams(
TrackSelection[] selections, SampleStream[] streams, int[] streamIndexToTrackGroupIndex) { ExoTrackSelection[] selections, SampleStream[] streams, int[] streamIndexToTrackGroupIndex) {
for (int i = 0; i < selections.length; i++) { for (int i = 0; i < selections.length; i++) {
if (streams[i] instanceof EmptySampleStream || streams[i] instanceof EmbeddedSampleStream) { if (streams[i] instanceof EmptySampleStream || streams[i] instanceof EmbeddedSampleStream) {
// We need to release an embedded stream if the corresponding primary stream is released. // We need to release an embedded stream if the corresponding primary stream is released.
...@@ -414,14 +414,14 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -414,14 +414,14 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
private void selectNewStreams( private void selectNewStreams(
TrackSelection[] selections, ExoTrackSelection[] selections,
SampleStream[] streams, SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
long positionUs, long positionUs,
int[] streamIndexToTrackGroupIndex) { int[] streamIndexToTrackGroupIndex) {
// Create newly selected primary and event streams. // Create newly selected primary and event streams.
for (int i = 0; i < selections.length; i++) { for (int i = 0; i < selections.length; i++) {
TrackSelection selection = selections[i]; ExoTrackSelection selection = selections[i];
if (selection == null) { if (selection == null) {
continue; continue;
} }
...@@ -703,8 +703,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -703,8 +703,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
return trackGroupCount; return trackGroupCount;
} }
private static void buildManifestEventTrackGroupInfos(List<EventStream> eventStreams, private static void buildManifestEventTrackGroupInfos(
TrackGroup[] trackGroups, TrackGroupInfo[] trackGroupInfos, int existingTrackGroupCount) { List<EventStream> eventStreams,
TrackGroup[] trackGroups,
TrackGroupInfo[] trackGroupInfos,
int existingTrackGroupCount) {
for (int i = 0; i < eventStreams.size(); i++) { for (int i = 0; i < eventStreams.size(); i++) {
EventStream eventStream = eventStreams.get(i); EventStream eventStream = eventStreams.get(i);
Format format = Format format =
...@@ -717,8 +720,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -717,8 +720,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
} }
private ChunkSampleStream<DashChunkSource> buildSampleStream(TrackGroupInfo trackGroupInfo, private ChunkSampleStream<DashChunkSource> buildSampleStream(
TrackSelection selection, long positionUs) { TrackGroupInfo trackGroupInfo, ExoTrackSelection selection, long positionUs) {
int embeddedTrackCount = 0; int embeddedTrackCount = 0;
boolean enableEventMessageTrack = boolean enableEventMessageTrack =
trackGroupInfo.embeddedEventMessageTrackGroupIndex != C.INDEX_UNSET; trackGroupInfo.embeddedEventMessageTrackGroupIndex != C.INDEX_UNSET;
...@@ -813,8 +816,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -813,8 +816,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
return null; return null;
} }
private static boolean hasEventMessageTrack(List<AdaptationSet> adaptationSets, private static boolean hasEventMessageTrack(
int[] adaptationSetIndices) { List<AdaptationSet> adaptationSets, int[] adaptationSetIndices) {
for (int i : adaptationSetIndices) { for (int i : adaptationSetIndices) {
List<Representation> representations = adaptationSets.get(i).representations; List<Representation> representations = adaptationSets.get(i).representations;
for (int j = 0; j < representations.size(); j++) { for (int j = 0; j < representations.size(); j++) {
...@@ -897,8 +900,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -897,8 +900,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
public @interface TrackGroupCategory {} public @interface TrackGroupCategory {}
/** /**
* A normal track group that has its samples drawn from the stream. * A normal track group that has its samples drawn from the stream. For example: a video Track
* For example: a video Track Group or an audio Track Group. * Group or an audio Track Group.
*/ */
private static final int CATEGORY_PRIMARY = 0; private static final int CATEGORY_PRIMARY = 0;
...@@ -909,9 +912,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -909,9 +912,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
private static final int CATEGORY_EMBEDDED = 1; private static final int CATEGORY_EMBEDDED = 1;
/** /**
* A track group that has its samples listed explicitly in the DASH manifest file. * A track group that has its samples listed explicitly in the DASH manifest file. For example:
* For example: an EventStream track has its sample (Events) included directly in the DASH * an EventStream track has its sample (Events) included directly in the DASH manifest file.
* manifest file.
*/ */
private static final int CATEGORY_MANIFEST_EVENTS = 2; private static final int CATEGORY_MANIFEST_EVENTS = 2;
...@@ -940,8 +942,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -940,8 +942,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
/* eventStreamGroupIndex= */ -1); /* eventStreamGroupIndex= */ -1);
} }
public static TrackGroupInfo embeddedEmsgTrack(int[] adaptationSetIndices, public static TrackGroupInfo embeddedEmsgTrack(
int primaryTrackGroupIndex) { int[] adaptationSetIndices, int primaryTrackGroupIndex) {
return new TrackGroupInfo( return new TrackGroupInfo(
C.TRACK_TYPE_METADATA, C.TRACK_TYPE_METADATA,
CATEGORY_EMBEDDED, CATEGORY_EMBEDDED,
...@@ -992,5 +994,4 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -992,5 +994,4 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
this.eventStreamGroupIndex = eventStreamGroupIndex; this.eventStreamGroupIndex = eventStreamGroupIndex;
} }
} }
} }
...@@ -47,7 +47,7 @@ import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet; ...@@ -47,7 +47,7 @@ import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.manifest.RangedUri; import com.google.android.exoplayer2.source.dash.manifest.RangedUri;
import com.google.android.exoplayer2.source.dash.manifest.Representation; import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException; import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException;
...@@ -84,7 +84,7 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -84,7 +84,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
DashManifest manifest, DashManifest manifest,
int periodIndex, int periodIndex,
int[] adaptationSetIndices, int[] adaptationSetIndices,
TrackSelection trackSelection, ExoTrackSelection trackSelection,
int trackType, int trackType,
long elapsedRealtimeOffsetMs, long elapsedRealtimeOffsetMs,
boolean enableEventMessageTrack, boolean enableEventMessageTrack,
...@@ -122,7 +122,7 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -122,7 +122,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
protected final RepresentationHolder[] representationHolders; protected final RepresentationHolder[] representationHolders;
private TrackSelection trackSelection; private ExoTrackSelection trackSelection;
private DashManifest manifest; private DashManifest manifest;
private int periodIndex; private int periodIndex;
@Nullable private IOException fatalError; @Nullable private IOException fatalError;
...@@ -152,7 +152,7 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -152,7 +152,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
DashManifest manifest, DashManifest manifest,
int periodIndex, int periodIndex,
int[] adaptationSetIndices, int[] adaptationSetIndices,
TrackSelection trackSelection, ExoTrackSelection trackSelection,
int trackType, int trackType,
DataSource dataSource, DataSource dataSource,
long elapsedRealtimeOffsetMs, long elapsedRealtimeOffsetMs,
...@@ -228,7 +228,7 @@ public class DefaultDashChunkSource implements DashChunkSource { ...@@ -228,7 +228,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
} }
@Override @Override
public void updateTrackSelection(TrackSelection trackSelection) { public void updateTrackSelection(ExoTrackSelection trackSelection) {
this.trackSelection = trackSelection; this.trackSelection = trackSelection;
} }
......
...@@ -37,7 +37,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist; ...@@ -37,7 +37,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment; import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
import com.google.android.exoplayer2.trackselection.BaseTrackSelection; import com.google.android.exoplayer2.trackselection.BaseTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
...@@ -137,8 +137,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -137,8 +137,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// Note: The track group in the selection is typically *not* equal to trackGroup. This is due to // Note: The track group in the selection is typically *not* equal to trackGroup. This is due to
// the way in which HlsSampleStreamWrapper generates track groups. Use only index based methods // the way in which HlsSampleStreamWrapper generates track groups. Use only index based methods
// in TrackSelection to avoid unexpected behavior. // in ExoTrackSelection to avoid unexpected behavior.
private TrackSelection trackSelection; private ExoTrackSelection trackSelection;
private long liveEdgeInPeriodTimeUs; private long liveEdgeInPeriodTimeUs;
private boolean seenExpectedPlaylistError; private boolean seenExpectedPlaylistError;
...@@ -219,14 +219,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -219,14 +219,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** /**
* Sets the current track selection. * Sets the current track selection.
* *
* @param trackSelection The {@link TrackSelection}. * @param trackSelection The {@link ExoTrackSelection}.
*/ */
public void setTrackSelection(TrackSelection trackSelection) { public void setTrackSelection(ExoTrackSelection trackSelection) {
this.trackSelection = trackSelection; this.trackSelection = trackSelection;
} }
/** Returns the current {@link TrackSelection}. */ /** Returns the current {@link ExoTrackSelection}. */
public TrackSelection getTrackSelection() { public ExoTrackSelection getTrackSelection() {
return trackSelection; return trackSelection;
} }
...@@ -810,9 +810,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -810,9 +810,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
// Private classes. // Private classes.
/** /** A {@link ExoTrackSelection} to use for initialization. */
* A {@link TrackSelection} to use for initialization.
*/
private static final class InitializationTrackSelection extends BaseTrackSelection { private static final class InitializationTrackSelection extends BaseTrackSelection {
private int selectedIndex; private int selectedIndex;
......
...@@ -39,7 +39,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist; ...@@ -39,7 +39,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Rendition; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Rendition;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
...@@ -177,7 +177,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -177,7 +177,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
// null URLs, this method must be updated to calculate stream keys that are compatible with those // null URLs, this method must be updated to calculate stream keys that are compatible with those
// that may already be persisted for offline. // that may already be persisted for offline.
@Override @Override
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) { public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
// See HlsMasterPlaylist.copy for interpretation of StreamKeys. // See HlsMasterPlaylist.copy for interpretation of StreamKeys.
HlsMasterPlaylist masterPlaylist = Assertions.checkNotNull(playlistTracker.getMasterPlaylist()); HlsMasterPlaylist masterPlaylist = Assertions.checkNotNull(playlistTracker.getMasterPlaylist());
boolean hasVariants = !masterPlaylist.variants.isEmpty(); boolean hasVariants = !masterPlaylist.variants.isEmpty();
...@@ -202,7 +202,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -202,7 +202,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
List<StreamKey> streamKeys = new ArrayList<>(); List<StreamKey> streamKeys = new ArrayList<>();
boolean needsPrimaryTrackGroupSelection = false; boolean needsPrimaryTrackGroupSelection = false;
boolean hasPrimaryTrackGroupSelection = false; boolean hasPrimaryTrackGroupSelection = false;
for (TrackSelection trackSelection : trackSelections) { for (ExoTrackSelection trackSelection : trackSelections) {
TrackGroup trackSelectionGroup = trackSelection.getTrackGroup(); TrackGroup trackSelectionGroup = trackSelection.getTrackGroup();
int mainWrapperTrackGroupIndex = mainWrapperTrackGroups.indexOf(trackSelectionGroup); int mainWrapperTrackGroupIndex = mainWrapperTrackGroups.indexOf(trackSelectionGroup);
if (mainWrapperTrackGroupIndex != C.INDEX_UNSET) { if (mainWrapperTrackGroupIndex != C.INDEX_UNSET) {
...@@ -258,7 +258,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -258,7 +258,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -286,7 +286,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper ...@@ -286,7 +286,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
// Select tracks for each child, copying the resulting streams back into a new streams array. // Select tracks for each child, copying the resulting streams back into a new streams array.
SampleStream[] newStreams = new SampleStream[selections.length]; SampleStream[] newStreams = new SampleStream[selections.length];
@NullableType SampleStream[] childStreams = new SampleStream[selections.length]; @NullableType SampleStream[] childStreams = new SampleStream[selections.length];
@NullableType TrackSelection[] childSelections = new TrackSelection[selections.length]; @NullableType ExoTrackSelection[] childSelections = new ExoTrackSelection[selections.length];
int newEnabledSampleStreamWrapperCount = 0; int newEnabledSampleStreamWrapperCount = 0;
HlsSampleStreamWrapper[] newEnabledSampleStreamWrappers = HlsSampleStreamWrapper[] newEnabledSampleStreamWrappers =
new HlsSampleStreamWrapper[sampleStreamWrappers.length]; new HlsSampleStreamWrapper[sampleStreamWrappers.length];
......
...@@ -53,7 +53,7 @@ import com.google.android.exoplayer2.source.TrackGroup; ...@@ -53,7 +53,7 @@ import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.Chunk; import com.google.android.exoplayer2.source.chunk.Chunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator; import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataReader; import com.google.android.exoplayer2.upstream.DataReader;
import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.HttpDataSource;
...@@ -331,7 +331,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -331,7 +331,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* part of the track selection. * part of the track selection.
*/ */
public boolean selectTracks( public boolean selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -358,11 +358,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; ...@@ -358,11 +358,11 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
: positionUs != lastSeekPositionUs); : positionUs != lastSeekPositionUs);
// Get the old (i.e. current before the loop below executes) primary track selection. The new // Get the old (i.e. current before the loop below executes) primary track selection. The new
// primary selection will equal the old one unless it's changed in the loop. // primary selection will equal the old one unless it's changed in the loop.
TrackSelection oldPrimaryTrackSelection = chunkSource.getTrackSelection(); ExoTrackSelection oldPrimaryTrackSelection = chunkSource.getTrackSelection();
TrackSelection primaryTrackSelection = oldPrimaryTrackSelection; ExoTrackSelection primaryTrackSelection = oldPrimaryTrackSelection;
// Select new tracks. // Select new tracks.
for (int i = 0; i < selections.length; i++) { for (int i = 0; i < selections.length; i++) {
TrackSelection selection = selections[i]; ExoTrackSelection selection = selections[i];
if (selection == null) { if (selection == null) {
continue; continue;
} }
......
...@@ -34,7 +34,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk; ...@@ -34,7 +34,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator; import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
...@@ -61,7 +61,7 @@ public class DefaultSsChunkSource implements SsChunkSource { ...@@ -61,7 +61,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
LoaderErrorThrower manifestLoaderErrorThrower, LoaderErrorThrower manifestLoaderErrorThrower,
SsManifest manifest, SsManifest manifest,
int elementIndex, int elementIndex,
TrackSelection trackSelection, ExoTrackSelection trackSelection,
@Nullable TransferListener transferListener) { @Nullable TransferListener transferListener) {
DataSource dataSource = dataSourceFactory.createDataSource(); DataSource dataSource = dataSourceFactory.createDataSource();
if (transferListener != null) { if (transferListener != null) {
...@@ -78,7 +78,7 @@ public class DefaultSsChunkSource implements SsChunkSource { ...@@ -78,7 +78,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
private final ChunkExtractor[] chunkExtractors; private final ChunkExtractor[] chunkExtractors;
private final DataSource dataSource; private final DataSource dataSource;
private TrackSelection trackSelection; private ExoTrackSelection trackSelection;
private SsManifest manifest; private SsManifest manifest;
private int currentManifestChunkOffset; private int currentManifestChunkOffset;
...@@ -95,7 +95,7 @@ public class DefaultSsChunkSource implements SsChunkSource { ...@@ -95,7 +95,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
LoaderErrorThrower manifestLoaderErrorThrower, LoaderErrorThrower manifestLoaderErrorThrower,
SsManifest manifest, SsManifest manifest,
int streamElementIndex, int streamElementIndex,
TrackSelection trackSelection, ExoTrackSelection trackSelection,
DataSource dataSource) { DataSource dataSource) {
this.manifestLoaderErrorThrower = manifestLoaderErrorThrower; this.manifestLoaderErrorThrower = manifestLoaderErrorThrower;
this.manifest = manifest; this.manifest = manifest;
...@@ -163,7 +163,7 @@ public class DefaultSsChunkSource implements SsChunkSource { ...@@ -163,7 +163,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
} }
@Override @Override
public void updateTrackSelection(TrackSelection trackSelection) { public void updateTrackSelection(ExoTrackSelection trackSelection) {
this.trackSelection = trackSelection; this.trackSelection = trackSelection;
} }
......
...@@ -18,13 +18,11 @@ package com.google.android.exoplayer2.source.smoothstreaming; ...@@ -18,13 +18,11 @@ package com.google.android.exoplayer2.source.smoothstreaming;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.source.chunk.ChunkSource; import com.google.android.exoplayer2.source.chunk.ChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
/** /** A {@link ChunkSource} for SmoothStreaming. */
* A {@link ChunkSource} for SmoothStreaming.
*/
public interface SsChunkSource extends ChunkSource { public interface SsChunkSource extends ChunkSource {
/** Factory for {@link SsChunkSource}s. */ /** Factory for {@link SsChunkSource}s. */
...@@ -45,7 +43,7 @@ public interface SsChunkSource extends ChunkSource { ...@@ -45,7 +43,7 @@ public interface SsChunkSource extends ChunkSource {
LoaderErrorThrower manifestLoaderErrorThrower, LoaderErrorThrower manifestLoaderErrorThrower,
SsManifest manifest, SsManifest manifest,
int streamElementIndex, int streamElementIndex,
TrackSelection trackSelection, ExoTrackSelection trackSelection,
@Nullable TransferListener transferListener); @Nullable TransferListener transferListener);
} }
...@@ -61,5 +59,5 @@ public interface SsChunkSource extends ChunkSource { ...@@ -61,5 +59,5 @@ public interface SsChunkSource extends ChunkSource {
* *
* @param trackSelection The new track selection instance. Must be equivalent to the previous one. * @param trackSelection The new track selection instance. Must be equivalent to the previous one.
*/ */
void updateTrackSelection(TrackSelection trackSelection); void updateTrackSelection(ExoTrackSelection trackSelection);
} }
...@@ -31,7 +31,7 @@ import com.google.android.exoplayer2.source.TrackGroup; ...@@ -31,7 +31,7 @@ import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream; import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoaderErrorThrower; import com.google.android.exoplayer2.upstream.LoaderErrorThrower;
...@@ -123,7 +123,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -123,7 +123,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -156,10 +156,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -156,10 +156,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
} }
@Override @Override
public List<StreamKey> getStreamKeys(List<TrackSelection> trackSelections) { public List<StreamKey> getStreamKeys(List<ExoTrackSelection> trackSelections) {
List<StreamKey> streamKeys = new ArrayList<>(); List<StreamKey> streamKeys = new ArrayList<>();
for (int selectionIndex = 0; selectionIndex < trackSelections.size(); selectionIndex++) { for (int selectionIndex = 0; selectionIndex < trackSelections.size(); selectionIndex++) {
TrackSelection trackSelection = trackSelections.get(selectionIndex); ExoTrackSelection trackSelection = trackSelections.get(selectionIndex);
int streamElementIndex = trackGroups.indexOf(trackSelection.getTrackGroup()); int streamElementIndex = trackGroups.indexOf(trackSelection.getTrackGroup());
for (int i = 0; i < trackSelection.length(); i++) { for (int i = 0; i < trackSelection.length(); i++) {
streamKeys.add(new StreamKey(streamElementIndex, trackSelection.getIndexInTrackGroup(i))); streamKeys.add(new StreamKey(streamElementIndex, trackSelection.getIndexInTrackGroup(i)));
...@@ -232,16 +232,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType; ...@@ -232,16 +232,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
// Private methods. // Private methods.
private ChunkSampleStream<SsChunkSource> buildSampleStream(TrackSelection selection, private ChunkSampleStream<SsChunkSource> buildSampleStream(
long positionUs) { ExoTrackSelection selection, long positionUs) {
int streamElementIndex = trackGroups.indexOf(selection.getTrackGroup()); int streamElementIndex = trackGroups.indexOf(selection.getTrackGroup());
SsChunkSource chunkSource = SsChunkSource chunkSource =
chunkSourceFactory.createChunkSource( chunkSourceFactory.createChunkSource(
manifestLoaderErrorThrower, manifestLoaderErrorThrower, manifest, streamElementIndex, selection, transferListener);
manifest,
streamElementIndex,
selection,
transferListener);
return new ChunkSampleStream<>( return new ChunkSampleStream<>(
manifest.streamElements[streamElementIndex].type, manifest.streamElements[streamElementIndex].type,
null, null,
......
...@@ -46,9 +46,9 @@ import com.google.android.exoplayer2.testutil.ExoHostedTest; ...@@ -46,9 +46,9 @@ import com.google.android.exoplayer2.testutil.ExoHostedTest;
import com.google.android.exoplayer2.testutil.HostActivity; import com.google.android.exoplayer2.testutil.HostActivity;
import com.google.android.exoplayer2.testutil.HostActivity.HostedTest; import com.google.android.exoplayer2.testutil.HostActivity.HostedTest;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.RandomTrackSelection; import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
...@@ -386,7 +386,7 @@ import java.util.List; ...@@ -386,7 +386,7 @@ import java.util.List;
} }
@Override @Override
protected TrackSelection.Definition[] selectAllTracks( protected ExoTrackSelection.Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
int[][][] rendererFormatSupports, int[][][] rendererFormatSupports,
int[] rendererMixedMimeTypeAdaptationSupports, int[] rendererMixedMimeTypeAdaptationSupports,
...@@ -399,10 +399,10 @@ import java.util.List; ...@@ -399,10 +399,10 @@ import java.util.List;
TrackGroupArray audioTrackGroups = mappedTrackInfo.getTrackGroups(AUDIO_RENDERER_INDEX); TrackGroupArray audioTrackGroups = mappedTrackInfo.getTrackGroups(AUDIO_RENDERER_INDEX);
Assertions.checkState(videoTrackGroups.length == 1); Assertions.checkState(videoTrackGroups.length == 1);
Assertions.checkState(audioTrackGroups.length == 1); Assertions.checkState(audioTrackGroups.length == 1);
TrackSelection.Definition[] definitions = ExoTrackSelection.Definition[] definitions =
new TrackSelection.Definition[mappedTrackInfo.getRendererCount()]; new ExoTrackSelection.Definition[mappedTrackInfo.getRendererCount()];
definitions[VIDEO_RENDERER_INDEX] = definitions[VIDEO_RENDERER_INDEX] =
new TrackSelection.Definition( new ExoTrackSelection.Definition(
videoTrackGroups.get(0), videoTrackGroups.get(0),
getVideoTrackIndices( getVideoTrackIndices(
videoTrackGroups.get(0), videoTrackGroups.get(0),
...@@ -410,7 +410,7 @@ import java.util.List; ...@@ -410,7 +410,7 @@ import java.util.List;
videoFormatIds, videoFormatIds,
canIncludeAdditionalVideoFormats)); canIncludeAdditionalVideoFormats));
definitions[AUDIO_RENDERER_INDEX] = definitions[AUDIO_RENDERER_INDEX] =
new TrackSelection.Definition( new ExoTrackSelection.Definition(
audioTrackGroups.get(0), getTrackIndex(audioTrackGroups.get(0), audioFormatId)); audioTrackGroups.get(0), getTrackIndex(audioTrackGroups.get(0), audioFormatId));
includedAdditionalVideoFormats = includedAdditionalVideoFormats =
definitions[VIDEO_RENDERER_INDEX].tracks.length > videoFormatIds.length; definitions[VIDEO_RENDERER_INDEX].tracks.length > videoFormatIds.length;
......
...@@ -33,7 +33,7 @@ import com.google.android.exoplayer2.source.SequenceableLoader; ...@@ -33,7 +33,7 @@ import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream; import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
...@@ -143,7 +143,7 @@ public class FakeAdaptiveMediaPeriod ...@@ -143,7 +143,7 @@ public class FakeAdaptiveMediaPeriod
@SuppressWarnings({"unchecked", "rawtypes"}) // Casting sample streams created by this class. @SuppressWarnings({"unchecked", "rawtypes"}) // Casting sample streams created by this class.
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -157,7 +157,7 @@ public class FakeAdaptiveMediaPeriod ...@@ -157,7 +157,7 @@ public class FakeAdaptiveMediaPeriod
streams[i] = null; streams[i] = null;
} }
if (streams[i] == null && selections[i] != null) { if (streams[i] == null && selections[i] != null) {
TrackSelection selection = selections[i]; ExoTrackSelection selection = selections[i];
assertThat(selection.length()).isAtLeast(1); assertThat(selection.length()).isAtLeast(1);
TrackGroup trackGroup = selection.getTrackGroup(); TrackGroup trackGroup = selection.getTrackGroup();
assertThat(trackGroupArray.indexOf(trackGroup)).isNotEqualTo(C.INDEX_UNSET); assertThat(trackGroupArray.indexOf(trackGroup)).isNotEqualTo(C.INDEX_UNSET);
......
...@@ -27,7 +27,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk; ...@@ -27,7 +27,7 @@ import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator; import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk; import com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk;
import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment; import com.google.android.exoplayer2.testutil.FakeDataSet.FakeData.Segment;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
...@@ -55,7 +55,7 @@ public final class FakeChunkSource implements ChunkSource { ...@@ -55,7 +55,7 @@ public final class FakeChunkSource implements ChunkSource {
} }
public FakeChunkSource createChunkSource( public FakeChunkSource createChunkSource(
TrackSelection trackSelection, ExoTrackSelection trackSelection,
long durationUs, long durationUs,
@Nullable TransferListener transferListener) { @Nullable TransferListener transferListener) {
FakeAdaptiveDataSet dataSet = FakeAdaptiveDataSet dataSet =
...@@ -70,12 +70,12 @@ public final class FakeChunkSource implements ChunkSource { ...@@ -70,12 +70,12 @@ public final class FakeChunkSource implements ChunkSource {
} }
private final TrackSelection trackSelection; private final ExoTrackSelection trackSelection;
private final DataSource dataSource; private final DataSource dataSource;
private final FakeAdaptiveDataSet dataSet; private final FakeAdaptiveDataSet dataSet;
public FakeChunkSource(TrackSelection trackSelection, DataSource dataSource, public FakeChunkSource(
FakeAdaptiveDataSet dataSet) { ExoTrackSelection trackSelection, DataSource dataSource, FakeAdaptiveDataSet dataSet) {
this.trackSelection = trackSelection; this.trackSelection = trackSelection;
this.dataSource = dataSource; this.dataSource = dataSource;
this.dataSet = dataSet; this.dataSet = dataSet;
......
...@@ -38,7 +38,7 @@ import com.google.android.exoplayer2.source.SampleStream; ...@@ -38,7 +38,7 @@ import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem; import com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
...@@ -187,8 +187,8 @@ public class FakeMediaPeriod implements MediaPeriod { ...@@ -187,8 +187,8 @@ public class FakeMediaPeriod implements MediaPeriod {
} }
/** /**
* Sets a discontinuity position to be returned from the next call to * Sets a discontinuity position to be returned from the next call to {@link
* {@link #readDiscontinuity()}. * #readDiscontinuity()}.
* *
* @param discontinuityPositionUs The position to be returned, in microseconds. * @param discontinuityPositionUs The position to be returned, in microseconds.
*/ */
...@@ -196,9 +196,7 @@ public class FakeMediaPeriod implements MediaPeriod { ...@@ -196,9 +196,7 @@ public class FakeMediaPeriod implements MediaPeriod {
this.discontinuityPositionUs = discontinuityPositionUs; this.discontinuityPositionUs = discontinuityPositionUs;
} }
/** /** Allows the fake media period to complete preparation. May be called on any thread. */
* Allows the fake media period to complete preparation. May be called on any thread.
*/
public synchronized void setPreparationComplete() { public synchronized void setPreparationComplete() {
deferOnPrepared = false; deferOnPrepared = false;
if (playerHandler != null && prepareCallback != null) { if (playerHandler != null && prepareCallback != null) {
...@@ -256,7 +254,7 @@ public class FakeMediaPeriod implements MediaPeriod { ...@@ -256,7 +254,7 @@ public class FakeMediaPeriod implements MediaPeriod {
@Override @Override
public long selectTracks( public long selectTracks(
@NullableType TrackSelection[] selections, @NullableType ExoTrackSelection[] selections,
boolean[] mayRetainStreamFlags, boolean[] mayRetainStreamFlags,
@NullableType SampleStream[] streams, @NullableType SampleStream[] streams,
boolean[] streamResetFlags, boolean[] streamResetFlags,
...@@ -270,7 +268,7 @@ public class FakeMediaPeriod implements MediaPeriod { ...@@ -270,7 +268,7 @@ public class FakeMediaPeriod implements MediaPeriod {
streams[i] = null; streams[i] = null;
} }
if (streams[i] == null && selections[i] != null) { if (streams[i] == null && selections[i] != null) {
TrackSelection selection = selections[i]; ExoTrackSelection selection = selections[i];
assertThat(selection.length()).isAtLeast(1); assertThat(selection.length()).isAtLeast(1);
TrackGroup trackGroup = selection.getTrackGroup(); TrackGroup trackGroup = selection.getTrackGroup();
assertThat(trackGroupArray.indexOf(trackGroup) != C.INDEX_UNSET).isTrue(); assertThat(trackGroupArray.indexOf(trackGroup) != C.INDEX_UNSET).isTrue();
......
...@@ -23,14 +23,14 @@ import com.google.android.exoplayer2.Format; ...@@ -23,14 +23,14 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator; import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import java.util.List; import java.util.List;
/** /**
* A fake {@link TrackSelection} that only returns 1 fixed track, and allows querying the number of * A fake {@link ExoTrackSelection} that only returns 1 fixed track, and allows querying the number
* calls to its methods. * of calls to its methods.
*/ */
public final class FakeTrackSelection implements TrackSelection { public final class FakeTrackSelection implements ExoTrackSelection {
private final TrackGroup rendererTrackGroup; private final TrackGroup rendererTrackGroup;
......
...@@ -23,8 +23,8 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; ...@@ -23,8 +23,8 @@ import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector; import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -41,8 +41,8 @@ public class FakeTrackSelector extends DefaultTrackSelector { ...@@ -41,8 +41,8 @@ public class FakeTrackSelector extends DefaultTrackSelector {
/** /**
* @param mayReuseTrackSelection Whether this {@link FakeTrackSelector} will reuse {@link * @param mayReuseTrackSelection Whether this {@link FakeTrackSelector} will reuse {@link
* TrackSelection}s during track selection, when it finds previously-selected track selection * ExoTrackSelection}s during track selection, when it finds previously-selected track
* using the same {@link TrackGroup}. * selection using the same {@link TrackGroup}.
*/ */
public FakeTrackSelector(boolean mayReuseTrackSelection) { public FakeTrackSelector(boolean mayReuseTrackSelection) {
this(new FakeTrackSelectionFactory(mayReuseTrackSelection)); this(new FakeTrackSelectionFactory(mayReuseTrackSelection));
...@@ -54,18 +54,18 @@ public class FakeTrackSelector extends DefaultTrackSelector { ...@@ -54,18 +54,18 @@ public class FakeTrackSelector extends DefaultTrackSelector {
} }
@Override @Override
protected TrackSelection.@NullableType Definition[] selectAllTracks( protected ExoTrackSelection.@NullableType Definition[] selectAllTracks(
MappedTrackInfo mappedTrackInfo, MappedTrackInfo mappedTrackInfo,
@Capabilities int[][][] rendererFormatSupports, @Capabilities int[][][] rendererFormatSupports,
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports, @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports,
Parameters params) { Parameters params) {
int rendererCount = mappedTrackInfo.getRendererCount(); int rendererCount = mappedTrackInfo.getRendererCount();
TrackSelection.@NullableType Definition[] definitions = ExoTrackSelection.@NullableType Definition[] definitions =
new TrackSelection.Definition[rendererCount]; new ExoTrackSelection.Definition[rendererCount];
for (int i = 0; i < rendererCount; i++) { for (int i = 0; i < rendererCount; i++) {
TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i); TrackGroupArray trackGroupArray = mappedTrackInfo.getTrackGroups(i);
boolean hasTracks = trackGroupArray.length > 0; boolean hasTracks = trackGroupArray.length > 0;
definitions[i] = hasTracks ? new TrackSelection.Definition(trackGroupArray.get(0)) : null; definitions[i] = hasTracks ? new ExoTrackSelection.Definition(trackGroupArray.get(0)) : null;
} }
return definitions; return definitions;
} }
...@@ -75,7 +75,7 @@ public class FakeTrackSelector extends DefaultTrackSelector { ...@@ -75,7 +75,7 @@ public class FakeTrackSelector extends DefaultTrackSelector {
return fakeTrackSelectionFactory.trackSelections; return fakeTrackSelectionFactory.trackSelections;
} }
private static class FakeTrackSelectionFactory implements TrackSelection.Factory { private static class FakeTrackSelectionFactory implements ExoTrackSelection.Factory {
private final List<FakeTrackSelection> trackSelections; private final List<FakeTrackSelection> trackSelections;
private final boolean mayReuseTrackSelection; private final boolean mayReuseTrackSelection;
...@@ -86,14 +86,14 @@ public class FakeTrackSelector extends DefaultTrackSelector { ...@@ -86,14 +86,14 @@ public class FakeTrackSelector extends DefaultTrackSelector {
} }
@Override @Override
public TrackSelection[] createTrackSelections( public ExoTrackSelection[] createTrackSelections(
TrackSelection.@NullableType Definition[] definitions, ExoTrackSelection.@NullableType Definition[] definitions,
BandwidthMeter bandwidthMeter, BandwidthMeter bandwidthMeter,
MediaPeriodId mediaPeriodId, MediaPeriodId mediaPeriodId,
Timeline timeline) { Timeline timeline) {
TrackSelection[] selections = new TrackSelection[definitions.length]; ExoTrackSelection[] selections = new ExoTrackSelection[definitions.length];
for (int i = 0; i < definitions.length; i++) { for (int i = 0; i < definitions.length; i++) {
TrackSelection.Definition definition = definitions[i]; ExoTrackSelection.Definition definition = definitions[i];
if (definition != null) { if (definition != null) {
selections[i] = createTrackSelection(definition.group); selections[i] = createTrackSelection(definition.group);
} }
...@@ -101,7 +101,7 @@ public class FakeTrackSelector extends DefaultTrackSelector { ...@@ -101,7 +101,7 @@ public class FakeTrackSelector extends DefaultTrackSelector {
return selections; return selections;
} }
private TrackSelection createTrackSelection(TrackGroup trackGroup) { private ExoTrackSelection createTrackSelection(TrackGroup trackGroup) {
if (mayReuseTrackSelection) { if (mayReuseTrackSelection) {
for (FakeTrackSelection trackSelection : trackSelections) { for (FakeTrackSelection trackSelection : trackSelections) {
if (trackSelection.getTrackGroup().equals(trackGroup)) { if (trackSelection.getTrackGroup().equals(trackGroup)) {
......
...@@ -29,7 +29,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray; ...@@ -29,7 +29,7 @@ import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator; import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.trackselection.BaseTrackSelection; import com.google.android.exoplayer2.trackselection.BaseTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.ExoTrackSelection;
import com.google.android.exoplayer2.util.ConditionVariable; import com.google.android.exoplayer2.util.ConditionVariable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
...@@ -102,7 +102,7 @@ public final class MediaPeriodAsserts { ...@@ -102,7 +102,7 @@ public final class MediaPeriodAsserts {
// - One selection with one track per group, two tracks or all tracks. // - One selection with one track per group, two tracks or all tracks.
// - Two selections with tracks from multiple groups, or tracks from a single group. // - Two selections with tracks from multiple groups, or tracks from a single group.
// - Multiple selections with tracks from all groups. // - Multiple selections with tracks from all groups.
List<List<TrackSelection>> testSelections = new ArrayList<>(); List<List<ExoTrackSelection>> testSelections = new ArrayList<>();
for (int i = 0; i < trackGroupArray.length; i++) { for (int i = 0; i < trackGroupArray.length; i++) {
TrackGroup trackGroup = trackGroupArray.get(i); TrackGroup trackGroup = trackGroupArray.get(i);
for (int j = 0; j < trackGroup.length; j++) { for (int j = 0; j < trackGroup.length; j++) {
...@@ -112,7 +112,7 @@ public final class MediaPeriodAsserts { ...@@ -112,7 +112,7 @@ public final class MediaPeriodAsserts {
testSelections.add(Collections.singletonList(new TestTrackSelection(trackGroup, 0, 1))); testSelections.add(Collections.singletonList(new TestTrackSelection(trackGroup, 0, 1)));
testSelections.add( testSelections.add(
Arrays.asList( Arrays.asList(
new TrackSelection[] { new ExoTrackSelection[] {
new TestTrackSelection(trackGroup, 0), new TestTrackSelection(trackGroup, 1) new TestTrackSelection(trackGroup, 0), new TestTrackSelection(trackGroup, 1)
})); }));
} }
...@@ -130,7 +130,7 @@ public final class MediaPeriodAsserts { ...@@ -130,7 +130,7 @@ public final class MediaPeriodAsserts {
for (int j = i + 1; j < trackGroupArray.length; j++) { for (int j = i + 1; j < trackGroupArray.length; j++) {
testSelections.add( testSelections.add(
Arrays.asList( Arrays.asList(
new TrackSelection[] { new ExoTrackSelection[] {
new TestTrackSelection(trackGroupArray.get(i), 0), new TestTrackSelection(trackGroupArray.get(i), 0),
new TestTrackSelection(trackGroupArray.get(j), 0) new TestTrackSelection(trackGroupArray.get(j), 0)
})); }));
...@@ -138,7 +138,7 @@ public final class MediaPeriodAsserts { ...@@ -138,7 +138,7 @@ public final class MediaPeriodAsserts {
} }
} }
if (trackGroupArray.length > 2) { if (trackGroupArray.length > 2) {
List<TrackSelection> selectionsFromAllGroups = new ArrayList<>(); List<ExoTrackSelection> selectionsFromAllGroups = new ArrayList<>();
for (int i = 0; i < trackGroupArray.length; i++) { for (int i = 0; i < trackGroupArray.length; i++) {
selectionsFromAllGroups.add(new TestTrackSelection(trackGroupArray.get(i), 0)); selectionsFromAllGroups.add(new TestTrackSelection(trackGroupArray.get(i), 0));
} }
...@@ -147,7 +147,7 @@ public final class MediaPeriodAsserts { ...@@ -147,7 +147,7 @@ public final class MediaPeriodAsserts {
// Verify for each case that stream keys can be used to create filtered tracks which still // Verify for each case that stream keys can be used to create filtered tracks which still
// contain at least all requested formats. // contain at least all requested formats.
for (List<TrackSelection> testSelection : testSelections) { for (List<ExoTrackSelection> testSelection : testSelections) {
List<StreamKey> streamKeys = mediaPeriod.getStreamKeys(testSelection); List<StreamKey> streamKeys = mediaPeriod.getStreamKeys(testSelection);
if (streamKeys.isEmpty()) { if (streamKeys.isEmpty()) {
// Manifests won't be filtered if stream key is empty. // Manifests won't be filtered if stream key is empty.
...@@ -158,7 +158,7 @@ public final class MediaPeriodAsserts { ...@@ -158,7 +158,7 @@ public final class MediaPeriodAsserts {
MediaPeriod filteredMediaPeriod = MediaPeriod filteredMediaPeriod =
mediaPeriodFactory.createMediaPeriod(filteredManifest, /* periodIndex= */ 0); mediaPeriodFactory.createMediaPeriod(filteredManifest, /* periodIndex= */ 0);
TrackGroupArray filteredTrackGroupArray = prepareAndGetTrackGroups(filteredMediaPeriod); TrackGroupArray filteredTrackGroupArray = prepareAndGetTrackGroups(filteredMediaPeriod);
for (TrackSelection trackSelection : testSelection) { for (ExoTrackSelection trackSelection : testSelection) {
if (ignoredMimeType != null if (ignoredMimeType != null
&& ignoredMimeType.equals(trackSelection.getFormat(0).sampleMimeType)) { && ignoredMimeType.equals(trackSelection.getFormat(0).sampleMimeType)) {
continue; continue;
......
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