From 7f5b5c9b6dbeddb9efcc2212f4d1ec8184c961f5 Mon Sep 17 00:00:00 2001 From: olly Date: Mon, 15 Feb 2021 16:27:10 +0000 Subject: [PATCH] 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 --- .../ext/cast/CastTrackSelection.java | 5 +++ .../trackselection/TrackSelection.java | 15 ++++++++ .../AdaptiveTrackSelection.java | 21 ++++++++--- .../trackselection/BaseTrackSelection.java | 36 +++++++++++++++---- .../trackselection/DefaultTrackSelector.java | 21 +++++++++-- .../trackselection/ExoTrackSelection.java | 9 +++-- .../trackselection/FixedTrackSelection.java | 13 +++++-- .../trackselection/RandomTrackSelection.java | 29 +++------------ .../trackselection/TrackSelectionUtil.java | 6 +++- .../AdaptiveTrackSelectionTest.java | 17 ++++++--- .../testutil/FakeTrackSelection.java | 33 ++++++++++------- 11 files changed, 145 insertions(+), 60 deletions(-) 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);