Add track selection override to the player API
This moves `SelectionOverride` from `DefaultTrackSelector` to `TrackSelectionParameters`. It is then use to allow track selection override per track selection array. Note that contrary to `DefaultTrackSelector.Parameters.selectionOverride`, the renderer concept is not exposed. This cl is a part of the bigger track selection change, splitted for ease of review. Find all cls with the tag: #player-track-selection PiperOrigin-RevId: 399933612
This commit is contained in:
parent
ece0cfc9f2
commit
d5ef11aaf3
@ -16,6 +16,8 @@
|
||||
package com.google.android.exoplayer2.trackselection;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||
import static com.google.android.exoplayer2.util.BundleableUtil.fromBundleNullableList;
|
||||
import static com.google.android.exoplayer2.util.BundleableUtil.toBundleArrayList;
|
||||
import static com.google.common.base.MoreObjects.firstNonNull;
|
||||
|
||||
import android.content.Context;
|
||||
@ -23,23 +25,27 @@ import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.view.accessibility.CaptioningManager;
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.primitives.Ints;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
||||
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* Constraint parameters for track selection.
|
||||
@ -93,6 +99,7 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
// General
|
||||
private boolean forceLowestBitrate;
|
||||
private boolean forceHighestSupportedBitrate;
|
||||
private ImmutableMap<TrackGroup, TrackSelectionOverride> trackSelectionOverrides;
|
||||
private ImmutableSet<@C.TrackType Integer> disabledTrackTypes;
|
||||
|
||||
/**
|
||||
@ -123,6 +130,7 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
// General
|
||||
forceLowestBitrate = false;
|
||||
forceHighestSupportedBitrate = false;
|
||||
trackSelectionOverrides = ImmutableMap.of();
|
||||
disabledTrackTypes = ImmutableSet.of();
|
||||
}
|
||||
|
||||
@ -224,7 +232,17 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
bundle.getBoolean(
|
||||
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE),
|
||||
DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate);
|
||||
|
||||
List<TrackGroup> keys =
|
||||
fromBundleNullableList(
|
||||
TrackGroup.CREATOR,
|
||||
bundle.getParcelableArrayList(keyForField(FIELD_SELECTION_OVERRIDE_KEYS)),
|
||||
ImmutableList.of());
|
||||
List<TrackSelectionOverride> values =
|
||||
fromBundleNullableList(
|
||||
TrackSelectionOverride.CREATOR,
|
||||
bundle.getParcelableArrayList(keyForField(FIELD_SELECTION_OVERRIDE_VALUES)),
|
||||
ImmutableList.of());
|
||||
trackSelectionOverrides = zipToMap(keys, values);
|
||||
disabledTrackTypes =
|
||||
ImmutableSet.copyOf(
|
||||
Ints.asList(
|
||||
@ -238,6 +256,7 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
"preferredAudioLanguages",
|
||||
"preferredAudioMimeTypes",
|
||||
"preferredTextLanguages",
|
||||
"trackSelectionOverrides",
|
||||
"disabledTrackTypes",
|
||||
})
|
||||
private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) {
|
||||
@ -267,6 +286,7 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
// General
|
||||
forceLowestBitrate = parameters.forceLowestBitrate;
|
||||
forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate;
|
||||
trackSelectionOverrides = parameters.trackSelectionOverrides;
|
||||
disabledTrackTypes = parameters.disabledTrackTypes;
|
||||
}
|
||||
|
||||
@ -615,6 +635,18 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selection overrides.
|
||||
*
|
||||
* @param trackSelectionOverrides The track selection overrides.
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setTrackSelectionOverrides(
|
||||
Map<TrackGroup, TrackSelectionOverride> trackSelectionOverrides) {
|
||||
this.trackSelectionOverrides = ImmutableMap.copyOf(trackSelectionOverrides);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the disabled track types, preventing all tracks of those types from being selected for
|
||||
* playback.
|
||||
@ -659,6 +691,83 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
}
|
||||
return listBuilder.build();
|
||||
}
|
||||
|
||||
private static <K, V> ImmutableMap<@NonNull K, @NonNull V> zipToMap(
|
||||
List<@NonNull K> keys, List<@NonNull V> values) {
|
||||
ImmutableMap.Builder<@NonNull K, @NonNull V> builder = new ImmutableMap.Builder<>();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
builder.put(keys.get(i), values.get(i));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the selection of {@link #tracks} for a {@link TrackGroup}.
|
||||
*
|
||||
* @see #trackSelectionOverrides
|
||||
*/
|
||||
public static final class TrackSelectionOverride implements Bundleable {
|
||||
/** Force the selection of the associated {@link TrackGroup}, but no track will be played. */
|
||||
public static final TrackSelectionOverride DISABLE =
|
||||
new TrackSelectionOverride(ImmutableSet.of());
|
||||
|
||||
/** The index of tracks in a {@link TrackGroup} to be selected. */
|
||||
public final ImmutableSet<Integer> tracks;
|
||||
|
||||
/** Constructs an instance to force {@code tracks} to be selected. */
|
||||
public TrackSelectionOverride(ImmutableSet<Integer> tracks) {
|
||||
this.tracks = tracks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
TrackSelectionOverride that = (TrackSelectionOverride) obj;
|
||||
return tracks.equals(that.tracks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return tracks.hashCode();
|
||||
}
|
||||
|
||||
// Bundleable implementation
|
||||
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
FIELD_TRACKS,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
private static final int FIELD_TRACKS = 0;
|
||||
|
||||
@Override
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putIntArray(keyForField(FIELD_TRACKS), Ints.toArray(tracks));
|
||||
return bundle;
|
||||
}
|
||||
|
||||
/** Object that can restore {@code TrackSelectionOverride} from a {@link Bundle}. */
|
||||
public static final Creator<TrackSelectionOverride> CREATOR =
|
||||
bundle -> {
|
||||
@Nullable int[] tracks = bundle.getIntArray(keyForField(FIELD_TRACKS));
|
||||
if (tracks == null) {
|
||||
return DISABLE;
|
||||
}
|
||||
return new TrackSelectionOverride(ImmutableSet.copyOf(Ints.asList(tracks)));
|
||||
};
|
||||
|
||||
private static String keyForField(@FieldNumber int field) {
|
||||
return Integer.toString(field, Character.MAX_RADIX);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -810,6 +919,30 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
* other constraints. The default value is {@code false}.
|
||||
*/
|
||||
public final boolean forceHighestSupportedBitrate;
|
||||
|
||||
/**
|
||||
* For each {@link TrackGroup} in the map, forces the tracks associated with it to be selected for
|
||||
* playback.
|
||||
*
|
||||
* <p>For example if {@code trackSelectionOverrides.equals(ImmutableMap.of(trackGroup,
|
||||
* ImmutableSet.of(1, 2, 3)))}, the tracks 1, 2 and 3 of {@code trackGroup} will be selected.
|
||||
*
|
||||
* <p>If multiple of the current {@link TrackGroup}s of the same {@link C.TrackType} are
|
||||
* overridden, it is undetermined which one(s) will be selected. For example if a {@link
|
||||
* MediaItem} has 2 video track groups (for example 2 different angles), and both are overriden,
|
||||
* it is undetermined which one will be selected.
|
||||
*
|
||||
* <p>If multiple tracks of the {@link TrackGroup} are overriden, all supported (see {@link
|
||||
* C.FormatSupport}) will be selected.
|
||||
*
|
||||
* <p>If a {@link TrackGroup} is associated with an empty set of tracks, no tracks will be played.
|
||||
* This is similar to {@link #disabledTrackTypes}, except it will only affect the playback of the
|
||||
* associated {@link TrackGroup}. For example, if the {@link C#TRACK_TYPE_VIDEO} {@link
|
||||
* TrackGroup} is associated with no tracks, no video will play until the next video starts.
|
||||
*
|
||||
* <p>The default value is that no {@link TrackGroup} selections are overridden (empty map).
|
||||
*/
|
||||
public final ImmutableMap<TrackGroup, TrackSelectionOverride> trackSelectionOverrides;
|
||||
/**
|
||||
* The track types that are disabled. No track of a disabled type will be selected, thus no track
|
||||
* type contained in the set will be played. The default value is that no track type is disabled
|
||||
@ -844,6 +977,7 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
// General
|
||||
this.forceLowestBitrate = builder.forceLowestBitrate;
|
||||
this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate;
|
||||
this.trackSelectionOverrides = builder.trackSelectionOverrides;
|
||||
this.disabledTrackTypes = builder.disabledTrackTypes;
|
||||
}
|
||||
|
||||
@ -887,6 +1021,7 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
// General
|
||||
&& forceLowestBitrate == other.forceLowestBitrate
|
||||
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
|
||||
&& trackSelectionOverrides.equals(other.trackSelectionOverrides)
|
||||
&& disabledTrackTypes.equals(other.disabledTrackTypes);
|
||||
}
|
||||
|
||||
@ -919,6 +1054,7 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
// General
|
||||
result = 31 * result + (forceLowestBitrate ? 1 : 0);
|
||||
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
|
||||
result = 31 * result + trackSelectionOverrides.hashCode();
|
||||
result = 31 * result + disabledTrackTypes.hashCode();
|
||||
return result;
|
||||
}
|
||||
@ -950,6 +1086,8 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
FIELD_PREFERRED_AUDIO_MIME_TYPES,
|
||||
FIELD_FORCE_LOWEST_BITRATE,
|
||||
FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE,
|
||||
FIELD_SELECTION_OVERRIDE_KEYS,
|
||||
FIELD_SELECTION_OVERRIDE_VALUES,
|
||||
FIELD_DISABLED_TRACK_TYPE,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
@ -976,10 +1114,11 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
private static final int FIELD_PREFERRED_AUDIO_MIME_TYPES = 20;
|
||||
private static final int FIELD_FORCE_LOWEST_BITRATE = 21;
|
||||
private static final int FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE = 22;
|
||||
private static final int FIELD_DISABLED_TRACK_TYPE = 23;
|
||||
private static final int FIELD_SELECTION_OVERRIDE_KEYS = 23;
|
||||
private static final int FIELD_SELECTION_OVERRIDE_VALUES = 24;
|
||||
private static final int FIELD_DISABLED_TRACK_TYPE = 25;
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
public Bundle toBundle() {
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
@ -1019,6 +1158,12 @@ public class TrackSelectionParameters implements Bundleable {
|
||||
bundle.putBoolean(keyForField(FIELD_FORCE_LOWEST_BITRATE), forceLowestBitrate);
|
||||
bundle.putBoolean(
|
||||
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate);
|
||||
bundle.putParcelableArrayList(
|
||||
keyForField(FIELD_SELECTION_OVERRIDE_KEYS),
|
||||
toBundleArrayList(trackSelectionOverrides.keySet()));
|
||||
bundle.putParcelableArrayList(
|
||||
keyForField(FIELD_SELECTION_OVERRIDE_VALUES),
|
||||
toBundleArrayList(trackSelectionOverrides.values()));
|
||||
bundle.putIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE), Ints.toArray(disabledTrackTypes));
|
||||
|
||||
return bundle;
|
||||
|
@ -24,6 +24,7 @@ import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/** Utilities for {@link Bundleable}. */
|
||||
@ -108,14 +109,15 @@ public final class BundleableUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a list of {@link Bundleable} to an {@link ArrayList} of {@link Bundle} so that the
|
||||
* returned list can be put to {@link Bundle} using {@link Bundle#putParcelableArrayList}
|
||||
* Converts a collection of {@link Bundleable} to an {@link ArrayList} of {@link Bundle} so that
|
||||
* the returned list can be put to {@link Bundle} using {@link Bundle#putParcelableArrayList}
|
||||
* conveniently.
|
||||
*/
|
||||
public static <T extends Bundleable> ArrayList<Bundle> toBundleArrayList(List<T> bundleableList) {
|
||||
ArrayList<Bundle> arrayList = new ArrayList<>(bundleableList.size());
|
||||
for (int i = 0; i < bundleableList.size(); i++) {
|
||||
arrayList.add(bundleableList.get(i).toBundle());
|
||||
public static <T extends Bundleable> ArrayList<Bundle> toBundleArrayList(
|
||||
Collection<T> bundleables) {
|
||||
ArrayList<Bundle> arrayList = new ArrayList<>(bundleables.size());
|
||||
for (T element : bundleables) {
|
||||
arrayList.add(element.toBundle());
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
|
@ -19,8 +19,14 @@ import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.Bundleable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters.TrackSelectionOverride;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@ -58,10 +64,16 @@ public class TrackSelectionParametersTest {
|
||||
// General
|
||||
assertThat(parameters.forceLowestBitrate).isFalse();
|
||||
assertThat(parameters.forceHighestSupportedBitrate).isFalse();
|
||||
assertThat(parameters.trackSelectionOverrides).isEmpty();
|
||||
assertThat(parameters.disabledTrackTypes).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parametersSet_fromDefault_isAsExpected() {
|
||||
ImmutableMap<TrackGroup, TrackSelectionOverride> trackSelectionOverrides =
|
||||
ImmutableMap.of(
|
||||
new TrackGroup(new Format.Builder().build()),
|
||||
new TrackSelectionOverride(/* tracks= */ ImmutableSet.of(2, 3)));
|
||||
TrackSelectionParameters parameters =
|
||||
TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT
|
||||
.buildUpon()
|
||||
@ -90,6 +102,8 @@ public class TrackSelectionParametersTest {
|
||||
// General
|
||||
.setForceLowestBitrate(false)
|
||||
.setForceHighestSupportedBitrate(true)
|
||||
.setTrackSelectionOverrides(trackSelectionOverrides)
|
||||
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT))
|
||||
.build();
|
||||
|
||||
// Video
|
||||
@ -122,6 +136,9 @@ public class TrackSelectionParametersTest {
|
||||
// General
|
||||
assertThat(parameters.forceLowestBitrate).isFalse();
|
||||
assertThat(parameters.forceHighestSupportedBitrate).isTrue();
|
||||
assertThat(parameters.trackSelectionOverrides).isEqualTo(trackSelectionOverrides);
|
||||
assertThat(parameters.disabledTrackTypes)
|
||||
.containsExactly(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_TEXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -160,4 +177,17 @@ public class TrackSelectionParametersTest {
|
||||
assertThat(parameters.viewportHeight).isEqualTo(Integer.MAX_VALUE);
|
||||
assertThat(parameters.viewportOrientationMayChange).isTrue();
|
||||
}
|
||||
|
||||
/** Tests {@link SelectionOverride}'s {@link Bundleable} implementation. */
|
||||
@Test
|
||||
public void roundTripViaBundle_ofSelectionOverride_yieldsEqualInstance() {
|
||||
SelectionOverride selectionOverrideToBundle =
|
||||
new SelectionOverride(/* groupIndex= */ 1, /* tracks...= */ 2, 3);
|
||||
|
||||
SelectionOverride selectionOverrideFromBundle =
|
||||
DefaultTrackSelector.SelectionOverride.CREATOR.fromBundle(
|
||||
selectionOverrideToBundle.toBundle());
|
||||
|
||||
assertThat(selectionOverrideFromBundle).isEqualTo(selectionOverrideToBundle);
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ 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.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters.TrackSelectionOverride;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.BundleableUtil;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
@ -608,6 +609,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParametersBuilder setTrackSelectionOverrides(
|
||||
Map<TrackGroup, TrackSelectionOverride> trackSelectionOverrides) {
|
||||
super.setTrackSelectionOverrides(trackSelectionOverrides);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParametersBuilder setDisabledTrackTypes(Set<@C.TrackType Integer> disabledTrackTypes) {
|
||||
super.setDisabledTrackTypes(disabledTrackTypes);
|
||||
@ -1490,19 +1498,33 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
|
||||
// Apply track disabling and overriding.
|
||||
for (int i = 0; i < rendererCount; i++) {
|
||||
// Per renderer and per track type disabling
|
||||
@C.TrackType int rendererType = mappedTrackInfo.getRendererType(i);
|
||||
if (params.getRendererDisabled(i) || params.disabledTrackTypes.contains(rendererType)) {
|
||||
definitions[i] = null;
|
||||
continue;
|
||||
}
|
||||
// Per TrackGroupArray override
|
||||
TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(i);
|
||||
if (params.hasSelectionOverride(i, rendererTrackGroups)) {
|
||||
SelectionOverride override = params.getSelectionOverride(i, rendererTrackGroups);
|
||||
@Nullable SelectionOverride override = params.getSelectionOverride(i, rendererTrackGroups);
|
||||
definitions[i] =
|
||||
override == null
|
||||
? null
|
||||
: new ExoTrackSelection.Definition(
|
||||
rendererTrackGroups.get(override.groupIndex), override.tracks, override.type);
|
||||
continue;
|
||||
}
|
||||
// Per TrackGroup override
|
||||
for (int j = 0; j < rendererTrackGroups.length; j++) {
|
||||
TrackGroup trackGroup = rendererTrackGroups.get(j);
|
||||
@Nullable
|
||||
TrackSelectionOverride overrideTracks = params.trackSelectionOverrides.get(trackGroup);
|
||||
if (overrideTracks != null) {
|
||||
definitions[i] =
|
||||
new ExoTrackSelection.Definition(trackGroup, Ints.toArray(overrideTracks.tracks));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,10 +45,12 @@ import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.Parameters;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.ParametersBuilder;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector.SelectionOverride;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters.TrackSelectionOverride;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationListener;
|
||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -152,16 +154,21 @@ public final class DefaultTrackSelectorTest {
|
||||
assertThat(parametersFromBundle).isEqualTo(parametersToBundle);
|
||||
}
|
||||
|
||||
/** Tests {@link SelectionOverride}'s {@link Bundleable} implementation. */
|
||||
/** Tests that an empty override clears a track selection. */
|
||||
@Test
|
||||
public void roundTripViaBundle_ofSelectionOverride_yieldsEqualInstance() {
|
||||
SelectionOverride selectionOverrideToBundle =
|
||||
new SelectionOverride(/* groupIndex= */ 1, /* tracks...= */ 2, 3);
|
||||
public void selectTracks_withNullOverride_clearsTrackSelection() throws ExoPlaybackException {
|
||||
trackSelector.setParameters(
|
||||
trackSelector
|
||||
.buildUponParameters()
|
||||
.setTrackSelectionOverrides(
|
||||
ImmutableMap.of(VIDEO_TRACK_GROUP, new TrackSelectionOverride(ImmutableSet.of()))));
|
||||
|
||||
SelectionOverride selectionOverrideFromBundle =
|
||||
SelectionOverride.CREATOR.fromBundle(selectionOverrideToBundle.toBundle());
|
||||
TrackSelectorResult result =
|
||||
trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS, periodId, TIMELINE);
|
||||
|
||||
assertThat(selectionOverrideFromBundle).isEqualTo(selectionOverrideToBundle);
|
||||
assertSelections(result, new TrackSelection[] {null, TRACK_SELECTIONS[1]});
|
||||
assertThat(result.rendererConfigurations)
|
||||
.isEqualTo(new RendererConfiguration[] {null, DEFAULT});
|
||||
}
|
||||
|
||||
/** Tests that a null override clears a track selection. */
|
||||
@ -193,6 +200,29 @@ public final class DefaultTrackSelectorTest {
|
||||
.isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT});
|
||||
}
|
||||
|
||||
/** Tests that an empty override is not applied for a different set of available track groups. */
|
||||
@Test
|
||||
public void selectTracks_withEmptyTrackOverrideForDifferentTracks_hasNoEffect()
|
||||
throws ExoPlaybackException {
|
||||
trackSelector.setParameters(
|
||||
trackSelector
|
||||
.buildUponParameters()
|
||||
.setTrackSelectionOverrides(
|
||||
ImmutableMap.of(
|
||||
new TrackGroup(VIDEO_FORMAT, VIDEO_FORMAT), TrackSelectionOverride.DISABLE)));
|
||||
|
||||
TrackSelectorResult result =
|
||||
trackSelector.selectTracks(
|
||||
RENDERER_CAPABILITIES,
|
||||
new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP, VIDEO_TRACK_GROUP),
|
||||
periodId,
|
||||
TIMELINE);
|
||||
|
||||
assertThat(result.selections).asList().containsExactlyElementsIn(TRACK_SELECTIONS).inOrder();
|
||||
assertThat(result.rendererConfigurations)
|
||||
.isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT});
|
||||
}
|
||||
|
||||
/** Tests that an override is not applied for a different set of available track groups. */
|
||||
@Test
|
||||
public void selectTracksWithNullOverrideForDifferentTracks() throws ExoPlaybackException {
|
||||
@ -1815,6 +1845,10 @@ public final class DefaultTrackSelectorTest {
|
||||
.setRendererDisabled(1, true)
|
||||
.setRendererDisabled(3, true)
|
||||
.setRendererDisabled(5, false)
|
||||
.setTrackSelectionOverrides(
|
||||
ImmutableMap.of(
|
||||
AUDIO_TRACK_GROUP,
|
||||
new TrackSelectionOverride(/* tracks= */ ImmutableSet.of(3, 4, 5))))
|
||||
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))
|
||||
.build();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user