Add static TrackSelection type

This type is different to the selection reason, which is
dynamic (i.e., corresponds to the individual selected track,
which can change during playback). The static type is
exposed via TrackSelection, where-as the selection reason
will be internal to the core (i.e., player) module.

PiperOrigin-RevId: 357578201
This commit is contained in:
olly 2021-02-15 16:27:10 +00:00 committed by kim-vde
parent f74918a674
commit 7f5b5c9b6d
11 changed files with 145 additions and 60 deletions

View File

@ -36,6 +36,11 @@ import com.google.android.exoplayer2.util.Assertions;
this.trackGroup = trackGroup;
}
@Override
public int getType() {
return TYPE_UNSET;
}
@Override
public TrackGroup getTrackGroup() {
return trackGroup;

View File

@ -27,6 +27,21 @@ import com.google.android.exoplayer2.source.TrackGroup;
*/
public interface TrackSelection {
/** An unspecified track selection type. */
int TYPE_UNSET = 0;
/** The first value that can be used for application specific track selection types. */
int TYPE_CUSTOM_BASE = 10000;
/**
* Returns an integer specifying the type of the selection, or {@link #TYPE_UNSET} if not
* specified.
*
* <p>Track selection types are specific to individual applications, but should be defined
* starting from {@link #TYPE_CUSTOM_BASE} to ensure they don't conflict with any types that may
* be added to the library in the future.
*/
int getType();
/** Returns the {@link TrackGroup} to which the selected tracks belong. */
TrackGroup getTrackGroup();

View File

@ -148,11 +148,16 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
selections[i] =
definition.tracks.length == 1
? new FixedTrackSelection(
definition.group, definition.tracks[0], definition.reason, definition.data)
definition.group,
/* track= */ definition.tracks[0],
/* type= */ definition.type,
/* reason= */ definition.reason,
definition.data)
: createAdaptiveTrackSelection(
definition.group,
bandwidthMeter,
definition.tracks,
definition.type,
bandwidthMeter,
adaptationCheckpoints.get(i));
}
return selections;
@ -162,20 +167,23 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
* Creates a single adaptive selection for the given group, bandwidth meter and tracks.
*
* @param group The {@link TrackGroup}.
* @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
* @param tracks The indices of the selected tracks in the track group.
* @param type The type that will be returned from {@link TrackSelection#getType()}.
* @param bandwidthMeter A {@link BandwidthMeter} which can be used to select tracks.
* @param adaptationCheckpoints The {@link AdaptationCheckpoint checkpoints} that can be used to
* calculate available bandwidth for this selection.
* @return An {@link AdaptiveTrackSelection} for the specified tracks.
*/
protected AdaptiveTrackSelection createAdaptiveTrackSelection(
TrackGroup group,
BandwidthMeter bandwidthMeter,
int[] tracks,
int type,
BandwidthMeter bandwidthMeter,
ImmutableList<AdaptationCheckpoint> adaptationCheckpoints) {
return new AdaptiveTrackSelection(
group,
tracks,
type,
bandwidthMeter,
minDurationForQualityIncreaseMs,
maxDurationForQualityDecreaseMs,
@ -220,6 +228,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
this(
group,
tracks,
TrackSelection.TYPE_UNSET,
bandwidthMeter,
DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
@ -234,6 +243,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
* @param group The {@link TrackGroup}.
* @param tracks The indices of the selected tracks within the {@link TrackGroup}. Must not be
* empty. May be in any order.
* @param type The type that will be returned from {@link TrackSelection#getType()}.
* @param bandwidthMeter Provides an estimate of the currently available bandwidth.
* @param minDurationForQualityIncreaseMs The minimum duration of buffered data required for the
* selected track to switch to one of higher quality.
@ -259,6 +269,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
protected AdaptiveTrackSelection(
TrackGroup group,
int[] tracks,
int type,
BandwidthMeter bandwidthMeter,
long minDurationForQualityIncreaseMs,
long maxDurationForQualityDecreaseMs,
@ -267,7 +278,7 @@ public class AdaptiveTrackSelection extends BaseTrackSelection {
float bufferedFractionToLiveEdgeForQualityIncrease,
List<AdaptationCheckpoint> adaptationCheckpoints,
Clock clock) {
super(group, tracks);
super(group, tracks, type);
this.bandwidthMeter = bandwidthMeter;
this.minDurationForQualityIncreaseUs = minDurationForQualityIncreaseMs * 1000L;
this.maxDurationForQualityDecreaseUs = maxDurationForQualityDecreaseMs * 1000L;

View File

@ -38,6 +38,8 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
/** The indices of the selected tracks in {@link #group}, in order of decreasing bandwidth. */
protected final int[] tracks;
/** The type of the selection. */
private final int type;
/** The {@link Format}s of the selected tracks, in order of decreasing bandwidth. */
private final Format[] formats;
/** Selected track exclusion timestamps, in order of decreasing bandwidth. */
@ -52,7 +54,18 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
* null or empty. May be in any order.
*/
public BaseTrackSelection(TrackGroup group, int... tracks) {
this(group, tracks, TrackSelection.TYPE_UNSET);
}
/**
* @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.
* @param type The type that will be returned from {@link TrackSelection#getType()}.
*/
public BaseTrackSelection(TrackGroup group, int[] tracks, int type) {
Assertions.checkState(tracks.length > 0);
this.type = type;
this.group = Assertions.checkNotNull(group);
this.length = tracks.length;
// Set the formats, sorted in order of decreasing bandwidth.
@ -70,14 +83,11 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
excludeUntilTimes = new long[length];
}
@Override
public void enable() {
// Do nothing.
}
// TrackSelection implementation.
@Override
public void disable() {
// Do nothing.
public final int getType() {
return type;
}
@Override
@ -121,6 +131,8 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
return C.INDEX_UNSET;
}
// ExoTrackSelection specific methods.
@Override
public final Format getSelectedFormat() {
return formats[getSelectedIndex()];
@ -131,6 +143,16 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
return tracks[getSelectedIndex()];
}
@Override
public void enable() {
// Do nothing.
}
@Override
public void disable() {
// Do nothing.
}
@Override
public void onPlaybackSpeed(float playbackSpeed) {
// Do nothing.
@ -158,6 +180,8 @@ public abstract class BaseTrackSelection implements ExoTrackSelection {
return true;
}
// Internal methods.
/**
* Returns whether the track at the specified index in the selection is excluded.
*

View File

@ -1507,15 +1507,26 @@ public class DefaultTrackSelector extends MappingTrackSelector {
public final int groupIndex;
public final int[] tracks;
public final int length;
public final int type;
/**
* @param groupIndex The overriding track group index.
* @param tracks The overriding track indices within the track group.
*/
public SelectionOverride(int groupIndex, int... tracks) {
this(groupIndex, tracks, TrackSelection.TYPE_UNSET);
}
/**
* @param groupIndex The overriding track group index.
* @param tracks The overriding track indices within the track group.
* @param type The type that will be returned from {@link TrackSelection#getType()}.
*/
public SelectionOverride(int groupIndex, int[] tracks, int type) {
this.groupIndex = groupIndex;
this.tracks = Arrays.copyOf(tracks, tracks.length);
this.length = tracks.length;
this.type = type;
Arrays.sort(this.tracks);
}
@ -1524,6 +1535,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
length = in.readByte();
tracks = new int[length];
in.readIntArray(tracks);
type = in.readInt();
}
/** Returns whether this override contains the specified track index. */
@ -1538,7 +1550,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@Override
public int hashCode() {
return 31 * groupIndex + Arrays.hashCode(tracks);
int hash = 31 * groupIndex + Arrays.hashCode(tracks);
return 31 * hash + type;
}
@Override
@ -1550,7 +1563,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return false;
}
SelectionOverride other = (SelectionOverride) obj;
return groupIndex == other.groupIndex && Arrays.equals(tracks, other.tracks);
return groupIndex == other.groupIndex
&& Arrays.equals(tracks, other.tracks)
&& type == other.type;
}
// Parcelable implementation.
@ -1565,6 +1580,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
dest.writeInt(groupIndex);
dest.writeInt(tracks.length);
dest.writeIntArray(tracks);
dest.writeInt(type);
}
public static final Parcelable.Creator<SelectionOverride> CREATOR =
@ -1708,6 +1724,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
: new ExoTrackSelection.Definition(
rendererTrackGroups.get(override.groupIndex),
override.tracks,
override.type,
C.SELECTION_REASON_MANUAL,
/* data= */ null);
}

View File

@ -42,6 +42,8 @@ public interface ExoTrackSelection extends TrackSelection {
public final TrackGroup group;
/** The indices of the selected tracks in {@link #group}. */
public final int[] tracks;
/** The type that will be returned from {@link TrackSelection#getType()}. */
public final int type;
/** The track selection reason. One of the {@link C} SELECTION_REASON_ constants. */
public final int reason;
/** Optional data associated with this selection of tracks. */
@ -53,18 +55,21 @@ public interface ExoTrackSelection extends TrackSelection {
* null or empty. May be in any order.
*/
public Definition(TrackGroup group, int... tracks) {
this(group, tracks, C.SELECTION_REASON_UNKNOWN, /* data= */ null);
this(group, tracks, TrackSelection.TYPE_UNSET, 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
* null or empty. May be in any order.
* @param type The type that will be returned from {@link TrackSelection#getType()}.
* @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) {
public Definition(TrackGroup group, int[] tracks, int type, int reason, @Nullable Object data) {
this.group = group;
this.tracks = tracks;
this.type = type;
this.reason = reason;
this.data = data;
}

View File

@ -35,17 +35,24 @@ public final class FixedTrackSelection extends BaseTrackSelection {
* @param track The index of the selected track within the {@link TrackGroup}.
*/
public FixedTrackSelection(TrackGroup group, int track) {
this(group, track, C.SELECTION_REASON_UNKNOWN, null);
this(
group,
/* track= */ track,
/* type= */ TrackSelection.TYPE_UNSET,
/* reason= */ C.SELECTION_REASON_UNKNOWN,
null);
}
/**
* @param group The {@link TrackGroup}. Must not be null.
* @param track The index of the selected track within the {@link TrackGroup}.
* @param type The type that will be returned from {@link TrackSelection#getType()}.
* @param reason A reason for the track selection.
* @param data Optional data associated with the track selection.
*/
public FixedTrackSelection(TrackGroup group, int track, int reason, @Nullable Object data) {
super(group, track);
public FixedTrackSelection(
TrackGroup group, int track, int type, int reason, @Nullable Object data) {
super(group, /* tracks= */ new int[] {track}, /* type= */ type);
this.reason = reason;
this.data = data;
}

View File

@ -53,7 +53,9 @@ public final class RandomTrackSelection extends BaseTrackSelection {
Timeline timeline) {
return TrackSelectionUtil.createTrackSelectionsForDefinitions(
definitions,
definition -> new RandomTrackSelection(definition.group, definition.tracks, random));
definition ->
new RandomTrackSelection(
definition.group, definition.tracks, definition.type, random));
}
}
@ -61,35 +63,14 @@ public final class RandomTrackSelection extends BaseTrackSelection {
private int selectedIndex;
/**
* @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 RandomTrackSelection(TrackGroup group, int... tracks) {
super(group, tracks);
random = new Random();
selectedIndex = random.nextInt(length);
}
/**
* @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.
* @param seed A seed for the {@link Random} instance used to update the selected track.
*/
public RandomTrackSelection(TrackGroup group, int[] tracks, long seed) {
this(group, tracks, new Random(seed));
}
/**
* @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.
* @param random A source of random numbers.
*/
public RandomTrackSelection(TrackGroup group, int[] tracks, Random random) {
super(group, tracks);
public RandomTrackSelection(TrackGroup group, int[] tracks, int type, Random random) {
super(group, tracks, type);
this.random = random;
selectedIndex = random.nextInt(length);
}

View File

@ -64,7 +64,11 @@ public final class TrackSelectionUtil {
} else {
selections[i] =
new FixedTrackSelection(
definition.group, definition.tracks[0], definition.reason, definition.data);
definition.group,
definition.tracks[0],
/* type= */ definition.type,
/* reason= */ definition.reason,
definition.data);
}
}
return selections;

View File

@ -315,8 +315,9 @@ public final class AdaptiveTrackSelectionTest {
/* bandwidthFraction= */ 1f)
.createAdaptiveTrackSelection(
trackGroup,
mockBandwidthMeter,
/* tracks= */ new int[] {0, 1},
/* type= */ TrackSelection.TYPE_UNSET,
mockBandwidthMeter,
/* adaptationCheckpoints= */ ImmutableList.of());
// Make initial selection.
@ -491,12 +492,13 @@ public final class AdaptiveTrackSelectionTest {
@Override
protected AdaptiveTrackSelection createAdaptiveTrackSelection(
TrackGroup group,
BandwidthMeter bandwidthMeter,
int[] tracks,
int type,
BandwidthMeter bandwidthMeter,
ImmutableList<AdaptationCheckpoint> adaptationCheckpoints) {
checkPoints.add(adaptationCheckpoints);
return super.createAdaptiveTrackSelection(
group, bandwidthMeter, tracks, adaptationCheckpoints);
group, tracks, TrackSelection.TYPE_UNSET, bandwidthMeter, adaptationCheckpoints);
}
};
@ -541,12 +543,13 @@ public final class AdaptiveTrackSelectionTest {
@Override
protected AdaptiveTrackSelection createAdaptiveTrackSelection(
TrackGroup group,
BandwidthMeter bandwidthMeter,
int[] tracks,
int type,
BandwidthMeter bandwidthMeter,
ImmutableList<AdaptationCheckpoint> adaptationCheckpoints) {
checkPoints.add(adaptationCheckpoints);
return super.createAdaptiveTrackSelection(
group, bandwidthMeter, tracks, adaptationCheckpoints);
group, tracks, TrackSelection.TYPE_UNSET, bandwidthMeter, adaptationCheckpoints);
}
};
@ -589,6 +592,7 @@ public final class AdaptiveTrackSelectionTest {
new AdaptiveTrackSelection(
trackGroup,
selectedAllTracksInGroup(trackGroup),
TrackSelection.TYPE_UNSET,
mockBandwidthMeter,
minDurationForQualityIncreaseMs,
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
@ -605,6 +609,7 @@ public final class AdaptiveTrackSelectionTest {
new AdaptiveTrackSelection(
trackGroup,
selectedAllTracksInGroup(trackGroup),
TrackSelection.TYPE_UNSET,
mockBandwidthMeter,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
maxDurationForQualityDecreaseMs,
@ -621,6 +626,7 @@ public final class AdaptiveTrackSelectionTest {
new AdaptiveTrackSelection(
trackGroup,
selectedAllTracksInGroup(trackGroup),
TrackSelection.TYPE_UNSET,
mockBandwidthMeter,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,
@ -637,6 +643,7 @@ public final class AdaptiveTrackSelectionTest {
new AdaptiveTrackSelection(
trackGroup,
selectedAllTracksInGroup(trackGroup),
TrackSelection.TYPE_UNSET,
mockBandwidthMeter,
AdaptiveTrackSelection.DEFAULT_MIN_DURATION_FOR_QUALITY_INCREASE_MS,
AdaptiveTrackSelection.DEFAULT_MAX_DURATION_FOR_QUALITY_DECREASE_MS,

View File

@ -42,20 +42,11 @@ public final class FakeTrackSelection implements ExoTrackSelection {
this.rendererTrackGroup = rendererTrackGroup;
}
@Override
public void enable() {
// assert that track selection is in disabled state before this call.
assertThat(isEnabled).isFalse();
enableCount++;
isEnabled = true;
}
// TrackSelection implementation.
@Override
public void disable() {
// assert that track selection is in enabled state before this call.
assertThat(isEnabled).isTrue();
releaseCount++;
isEnabled = false;
public int getType() {
return TYPE_UNSET;
}
@Override
@ -89,6 +80,24 @@ public final class FakeTrackSelection implements ExoTrackSelection {
return 0;
}
// ExoTrackSelection specific methods.
@Override
public void enable() {
// assert that track selection is in disabled state before this call.
assertThat(isEnabled).isFalse();
enableCount++;
isEnabled = true;
}
@Override
public void disable() {
// assert that track selection is in enabled state before this call.
assertThat(isEnabled).isTrue();
releaseCount++;
isEnabled = false;
}
@Override
public Format getSelectedFormat() {
return rendererTrackGroup.getFormat(0);