Commit a75f902c by krocard Committed by Oliver Woodman

Add track type disabling to Track selection parameters

This will allow to disable video/audio... through the player
interface.

PiperOrigin-RevId: 397183548
parent 4ff4263a
...@@ -31,10 +31,13 @@ import com.google.android.exoplayer2.Bundleable; ...@@ -31,10 +31,13 @@ import com.google.android.exoplayer2.Bundleable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Locale; import java.util.Locale;
import java.util.Set;
import org.checkerframework.checker.initialization.qual.UnknownInitialization; import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull; import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
...@@ -90,6 +93,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -90,6 +93,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
private boolean forceLowestBitrate; private boolean forceLowestBitrate;
private boolean forceHighestSupportedBitrate; private boolean forceHighestSupportedBitrate;
private ImmutableSet<@C.TrackType Integer> disabledTrackTypes;
/** /**
* @deprecated {@link Context} constraints will not be set using this constructor. Use {@link * @deprecated {@link Context} constraints will not be set using this constructor. Use {@link
...@@ -119,6 +123,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -119,6 +123,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
forceLowestBitrate = false; forceLowestBitrate = false;
forceHighestSupportedBitrate = false; forceHighestSupportedBitrate = false;
disabledTrackTypes = ImmutableSet.of();
} }
/** /**
...@@ -219,6 +224,12 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -219,6 +224,12 @@ public class TrackSelectionParameters implements Bundleable {
bundle.getBoolean( bundle.getBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE),
DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate); DEFAULT_WITHOUT_CONTEXT.forceHighestSupportedBitrate);
disabledTrackTypes =
ImmutableSet.copyOf(
Ints.asList(
firstNonNull(
bundle.getIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE)), new int[0])));
} }
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */ /** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
...@@ -226,7 +237,8 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -226,7 +237,8 @@ public class TrackSelectionParameters implements Bundleable {
"preferredVideoMimeTypes", "preferredVideoMimeTypes",
"preferredAudioLanguages", "preferredAudioLanguages",
"preferredAudioMimeTypes", "preferredAudioMimeTypes",
"preferredTextLanguages" "preferredTextLanguages",
"disabledTrackTypes",
}) })
private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) { private void init(@UnknownInitialization Builder this, TrackSelectionParameters parameters) {
// Video // Video
...@@ -255,6 +267,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -255,6 +267,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
forceLowestBitrate = parameters.forceLowestBitrate; forceLowestBitrate = parameters.forceLowestBitrate;
forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate; forceHighestSupportedBitrate = parameters.forceHighestSupportedBitrate;
disabledTrackTypes = parameters.disabledTrackTypes;
} }
/** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */ /** Overrides the value of the builder with the value of {@link TrackSelectionParameters}. */
...@@ -602,6 +615,18 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -602,6 +615,18 @@ public class TrackSelectionParameters implements Bundleable {
return this; return this;
} }
/**
* Sets the disabled track types, preventing all tracks of those types from being selected for
* playback.
*
* @param disabledTrackTypes The track types to disable.
* @return This builder.
*/
public Builder setDisabledTrackTypes(Set<@C.TrackType Integer> disabledTrackTypes) {
this.disabledTrackTypes = ImmutableSet.copyOf(disabledTrackTypes);
return this;
}
/** Builds a {@link TrackSelectionParameters} instance with the selected values. */ /** Builds a {@link TrackSelectionParameters} instance with the selected values. */
public TrackSelectionParameters build() { public TrackSelectionParameters build() {
return new TrackSelectionParameters(this); return new TrackSelectionParameters(this);
...@@ -785,6 +810,12 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -785,6 +810,12 @@ public class TrackSelectionParameters implements Bundleable {
* other constraints. The default value is {@code false}. * other constraints. The default value is {@code false}.
*/ */
public final boolean forceHighestSupportedBitrate; public final boolean forceHighestSupportedBitrate;
/**
* 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
* (empty set).
*/
public final ImmutableSet<@C.TrackType Integer> disabledTrackTypes;
protected TrackSelectionParameters(Builder builder) { protected TrackSelectionParameters(Builder builder) {
// Video // Video
...@@ -813,6 +844,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -813,6 +844,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
this.forceLowestBitrate = builder.forceLowestBitrate; this.forceLowestBitrate = builder.forceLowestBitrate;
this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate; this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate;
this.disabledTrackTypes = builder.disabledTrackTypes;
} }
/** Creates a new {@link Builder}, copying the initial values from this instance. */ /** Creates a new {@link Builder}, copying the initial values from this instance. */
...@@ -854,7 +886,8 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -854,7 +886,8 @@ public class TrackSelectionParameters implements Bundleable {
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage && selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
// General // General
&& forceLowestBitrate == other.forceLowestBitrate && forceLowestBitrate == other.forceLowestBitrate
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate; && forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
&& disabledTrackTypes.equals(other.disabledTrackTypes);
} }
@Override @Override
...@@ -886,6 +919,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -886,6 +919,7 @@ public class TrackSelectionParameters implements Bundleable {
// General // General
result = 31 * result + (forceLowestBitrate ? 1 : 0); result = 31 * result + (forceLowestBitrate ? 1 : 0);
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0); result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
result = 31 * result + disabledTrackTypes.hashCode();
return result; return result;
} }
...@@ -916,6 +950,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -916,6 +950,7 @@ public class TrackSelectionParameters implements Bundleable {
FIELD_PREFERRED_AUDIO_MIME_TYPES, FIELD_PREFERRED_AUDIO_MIME_TYPES,
FIELD_FORCE_LOWEST_BITRATE, FIELD_FORCE_LOWEST_BITRATE,
FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE, FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE,
FIELD_DISABLED_TRACK_TYPE,
}) })
private @interface FieldNumber {} private @interface FieldNumber {}
...@@ -941,6 +976,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -941,6 +976,7 @@ public class TrackSelectionParameters implements Bundleable {
private static final int FIELD_PREFERRED_AUDIO_MIME_TYPES = 20; 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_LOWEST_BITRATE = 21;
private static final int FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE = 22; private static final int FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE = 22;
private static final int FIELD_DISABLED_TRACK_TYPE = 23;
@Override @Override
@CallSuper @CallSuper
...@@ -983,6 +1019,7 @@ public class TrackSelectionParameters implements Bundleable { ...@@ -983,6 +1019,7 @@ public class TrackSelectionParameters implements Bundleable {
bundle.putBoolean(keyForField(FIELD_FORCE_LOWEST_BITRATE), forceLowestBitrate); bundle.putBoolean(keyForField(FIELD_FORCE_LOWEST_BITRATE), forceLowestBitrate);
bundle.putBoolean( bundle.putBoolean(
keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate); keyForField(FIELD_FORCE_HIGHEST_SUPPORTED_BITRATE), forceHighestSupportedBitrate);
bundle.putIntArray(keyForField(FIELD_DISABLED_TRACK_TYPE), Ints.toArray(disabledTrackTypes));
return bundle; return bundle;
} }
......
...@@ -55,6 +55,7 @@ import java.util.HashMap; ...@@ -55,6 +55,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.checkerframework.checker.nullness.compatqual.NullableType; import org.checkerframework.checker.nullness.compatqual.NullableType;
...@@ -607,6 +608,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -607,6 +608,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this; return this;
} }
@Override
public ParametersBuilder setDisabledTrackTypes(Set<@C.TrackType Integer> trackTypes) {
super.setDisabledTrackTypes(trackTypes);
return this;
}
/** /**
* Sets whether to exceed renderer capabilities when no selection can be made otherwise. * Sets whether to exceed renderer capabilities when no selection can be made otherwise.
* *
...@@ -1484,7 +1491,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1484,7 +1491,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Apply track disabling and overriding. // Apply track disabling and overriding.
for (int i = 0; i < rendererCount; i++) { for (int i = 0; i < rendererCount; i++) {
if (params.getRendererDisabled(i)) { @C.TrackType int rendererType = mappedTrackInfo.getRendererType(i);
if (params.getRendererDisabled(i) || params.disabledTrackTypes.contains(rendererType)) {
definitions[i] = null; definitions[i] = null;
continue; continue;
} }
...@@ -1509,7 +1517,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -1509,7 +1517,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@NullableType @NullableType
RendererConfiguration[] rendererConfigurations = 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); @C.TrackType int rendererType = mappedTrackInfo.getRendererType(i);
boolean forceRendererDisabled =
params.getRendererDisabled(i) || params.disabledTrackTypes.contains(rendererType);
boolean rendererEnabled = boolean rendererEnabled =
!forceRendererDisabled !forceRendererDisabled
&& (mappedTrackInfo.getRendererType(i) == C.TRACK_TYPE_NONE && (mappedTrackInfo.getRendererType(i) == C.TRACK_TYPE_NONE
......
...@@ -49,6 +49,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationLi ...@@ -49,6 +49,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationLi
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.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.junit.Before; import org.junit.Before;
...@@ -101,12 +102,14 @@ public final class DefaultTrackSelectorTest { ...@@ -101,12 +102,14 @@ public final class DefaultTrackSelectorTest {
private static final TrackGroup AUDIO_TRACK_GROUP = new TrackGroup(AUDIO_FORMAT); private static final TrackGroup AUDIO_TRACK_GROUP = new TrackGroup(AUDIO_FORMAT);
private static final TrackGroupArray TRACK_GROUPS = private static final TrackGroupArray TRACK_GROUPS =
new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP); new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP);
private static final TrackSelection VIDEO_TRACK_SELECTION =
new FixedTrackSelection(VIDEO_TRACK_GROUP, 0);
private static final TrackSelection AUDIO_TRACK_SELECTION =
new FixedTrackSelection(AUDIO_TRACK_GROUP, 0);
private static final TrackSelection[] TRACK_SELECTIONS = private static final TrackSelection[] TRACK_SELECTIONS =
new TrackSelection[] { new TrackSelection[] {VIDEO_TRACK_SELECTION, AUDIO_TRACK_SELECTION};
new FixedTrackSelection(VIDEO_TRACK_GROUP, 0), new FixedTrackSelection(AUDIO_TRACK_GROUP, 0)
};
private static final TrackSelection[] TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER = private static final TrackSelection[] TRACK_SELECTIONS_WITH_NO_SAMPLE_RENDERER =
new TrackSelection[] {new FixedTrackSelection(VIDEO_TRACK_GROUP, 0), null}; new TrackSelection[] {VIDEO_TRACK_SELECTION, null};
private static final Timeline TIMELINE = new FakeTimeline(); private static final Timeline TIMELINE = new FakeTimeline();
...@@ -208,6 +211,58 @@ public final class DefaultTrackSelectorTest { ...@@ -208,6 +211,58 @@ public final class DefaultTrackSelectorTest {
.isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT}); .isEqualTo(new RendererConfiguration[] {DEFAULT, DEFAULT});
} }
/** Tests disabling a track type. */
@Test
public void selectVideoAudioTracks_withDisabledAudioType_onlyVideoIsSelected()
throws ExoPlaybackException {
trackSelector.setParameters(
defaultParameters.buildUpon().setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO)));
TrackSelectorResult result =
trackSelector.selectTracks(
RENDERER_CAPABILITIES,
new TrackGroupArray(VIDEO_TRACK_GROUP, AUDIO_TRACK_GROUP),
periodId,
TIMELINE);
assertThat(result.selections).asList().containsExactly(VIDEO_TRACK_SELECTION, null).inOrder();
assertThat(result.rendererConfigurations).asList().containsExactly(DEFAULT, null);
}
/** Tests that a disabled track type can be enabled again. */
@Test
public void selectTracks_withClearedDisabledTrackType_selectsAll() throws ExoPlaybackException {
trackSelector.setParameters(
trackSelector
.buildUponParameters()
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))
.setDisabledTrackTypes(ImmutableSet.of()));
TrackSelectorResult result =
trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS, periodId, TIMELINE);
assertThat(result.selections).asList().containsExactlyElementsIn(TRACK_SELECTIONS).inOrder();
assertThat(result.rendererConfigurations).asList().containsExactly(DEFAULT, DEFAULT).inOrder();
}
/** Tests disabling NONE track type rendering. */
@Test
public void selectTracks_withDisabledNoneTracksAndNoSampleRenderer_disablesNoSampleRenderer()
throws ExoPlaybackException {
trackSelector.setParameters(
defaultParameters.buildUpon().setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_NONE)));
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {VIDEO_CAPABILITIES, NO_SAMPLE_CAPABILITIES},
TRACK_GROUPS,
periodId,
TIMELINE);
assertThat(result.selections).asList().containsExactly(VIDEO_TRACK_SELECTION, null).inOrder();
assertThat(result.rendererConfigurations).asList().containsExactly(DEFAULT, null).inOrder();
}
/** Tests disabling a renderer. */ /** Tests disabling a renderer. */
@Test @Test
public void selectTracksWithDisabledRenderer() throws ExoPlaybackException { public void selectTracksWithDisabledRenderer() throws ExoPlaybackException {
...@@ -1760,6 +1815,7 @@ public final class DefaultTrackSelectorTest { ...@@ -1760,6 +1815,7 @@ public final class DefaultTrackSelectorTest {
.setRendererDisabled(1, true) .setRendererDisabled(1, true)
.setRendererDisabled(3, true) .setRendererDisabled(3, true)
.setRendererDisabled(5, false) .setRendererDisabled(5, false)
.setDisabledTrackTypes(ImmutableSet.of(C.TRACK_TYPE_AUDIO))
.build(); .build();
} }
......
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