diff --git a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastTrackSelection.java b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastTrackSelection.java index 22fe86d9e4..9d5ea06b17 100644 --- a/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastTrackSelection.java +++ b/extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/CastTrackSelection.java @@ -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; diff --git a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelection.java b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelection.java index dca840790d..e439b5d00e 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelection.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelection.java @@ -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. + * + *

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(); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java index bd2e18ad92..57b0962b79 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelection.java @@ -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 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 adaptationCheckpoints, Clock clock) { - super(group, tracks); + super(group, tracks, type); this.bandwidthMeter = bandwidthMeter; this.minDurationForQualityIncreaseUs = minDurationForQualityIncreaseMs * 1000L; this.maxDurationForQualityDecreaseUs = maxDurationForQualityDecreaseMs * 1000L; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/BaseTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/BaseTrackSelection.java index 17c486b45a..fe08b02a1c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/BaseTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/BaseTrackSelection.java @@ -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. * diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java index 81b054b36b..cb4f409391 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java @@ -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 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); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/ExoTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/ExoTrackSelection.java index e6816ec884..62e2f3b550 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/ExoTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/ExoTrackSelection.java @@ -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; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/FixedTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/FixedTrackSelection.java index 62e9a3dc71..2ad673ee72 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/FixedTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/FixedTrackSelection.java @@ -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; } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/RandomTrackSelection.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/RandomTrackSelection.java index 3dcb73de21..49416f6556 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/RandomTrackSelection.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/RandomTrackSelection.java @@ -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); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionUtil.java index 0dac7259a3..fc91aa38be 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionUtil.java @@ -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; diff --git a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelectionTest.java b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelectionTest.java index aa6f420c3e..98d0f36ff7 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelectionTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/AdaptiveTrackSelectionTest.java @@ -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 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 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, diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTrackSelection.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTrackSelection.java index 38408efff7..15e1327bdf 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTrackSelection.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeTrackSelection.java @@ -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);