Move most of DefaultTrackSelector params to TrackSelectionParameters

The parameters staying in DefaultTrackSelector are considered
too ExoPlayer specific to be part of the `Player` interface.
Those are:
 - exceedVideoConstraintsIfNecessary;
 - allowVideoMixedMimeTypeAdaptiveness;
 - allowVideoNonSeamlessAdaptiveness;
 - exceedAudioConstraintsIfNecessary;
 - allowAudioMixedMimeTypeAdaptiveness;
 - allowAudioMixedSampleRateAdaptiveness;
 - allowAudioMixedChannelCountAdaptiveness;
 - disabledTextTrackSelectionFlags;
 - exceedRendererCapabilitiesIfNecessary;
 - tunnelingEnabled;
 - allowMultipleAdaptiveSelections;
 - rendererDisabledFlags

Track selection override will be migrated in a follow up cl.

To avoid breaking backward compatibility,
`DefaultTrackSelector.Parameters` extends
`TrackSelectionParameters` and
`DefaultTrackSelector.ParametersBuilder` extends `TrackSelectionParameters.Builder`.
The change are thus transparent for clients.

Test are incomplete for now, as this is a relatively big cl, I though
the reviewer could give a first pass will the tests are completed.

PiperOrigin-RevId: 383767021
This commit is contained in:
krocard 2021-07-09 04:29:12 +01:00 committed by kim-vde
parent 1309b26ebe
commit 298af78b4e
5 changed files with 1197 additions and 982 deletions

View file

@ -0,0 +1,855 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.trackselection;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.content.Context;
import android.graphics.Point;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.accessibility.CaptioningManager;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Locale;
/** Constraint parameters for track selection. */
public class TrackSelectionParameters implements Parcelable {
/**
* A builder for {@link TrackSelectionParameters}. See the {@link TrackSelectionParameters}
* documentation for explanations of the parameters that can be configured using this builder.
*/
public static class Builder {
// Video
private int maxVideoWidth;
private int maxVideoHeight;
private int maxVideoFrameRate;
private int maxVideoBitrate;
private int minVideoWidth;
private int minVideoHeight;
private int minVideoFrameRate;
private int minVideoBitrate;
private int viewportWidth;
private int viewportHeight;
private boolean viewportOrientationMayChange;
private ImmutableList<String> preferredVideoMimeTypes;
// Audio
private ImmutableList<String> preferredAudioLanguages;
@C.RoleFlags private int preferredAudioRoleFlags;
private int maxAudioChannelCount;
private int maxAudioBitrate;
private ImmutableList<String> preferredAudioMimeTypes;
// Text
private ImmutableList<String> preferredTextLanguages;
@C.RoleFlags private int preferredTextRoleFlags;
private boolean selectUndeterminedTextLanguage;
// General
private boolean forceLowestBitrate;
private boolean forceHighestSupportedBitrate;
/**
* @deprecated {@link Context} constraints will not be set using this constructor. Use {@link
* #Builder(Context)} instead.
*/
@Deprecated
public Builder() {
// Video
maxVideoWidth = Integer.MAX_VALUE;
maxVideoHeight = Integer.MAX_VALUE;
maxVideoFrameRate = Integer.MAX_VALUE;
maxVideoBitrate = Integer.MAX_VALUE;
viewportWidth = Integer.MAX_VALUE;
viewportHeight = Integer.MAX_VALUE;
viewportOrientationMayChange = true;
preferredVideoMimeTypes = ImmutableList.of();
// Audio
preferredAudioLanguages = ImmutableList.of();
preferredAudioRoleFlags = 0;
maxAudioChannelCount = Integer.MAX_VALUE;
maxAudioBitrate = Integer.MAX_VALUE;
preferredAudioMimeTypes = ImmutableList.of();
// Text
preferredTextLanguages = ImmutableList.of();
preferredTextRoleFlags = 0;
selectUndeterminedTextLanguage = false;
// General
forceLowestBitrate = false;
forceHighestSupportedBitrate = false;
}
/**
* Creates a builder with default initial values.
*
* @param context Any context.
*/
@SuppressWarnings({"deprecation", "method.invocation"}) // Methods invoked are setter only.
public Builder(Context context) {
this();
setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(context);
setViewportSizeToPhysicalDisplaySize(context, /* viewportOrientationMayChange= */ true);
}
/**
* @param initialValues The {@link TrackSelectionParameters} from which the initial values of
* the builder are obtained.
*/
protected Builder(TrackSelectionParameters initialValues) {
// Video
maxVideoWidth = initialValues.maxVideoWidth;
maxVideoHeight = initialValues.maxVideoHeight;
maxVideoFrameRate = initialValues.maxVideoFrameRate;
maxVideoBitrate = initialValues.maxVideoBitrate;
minVideoWidth = initialValues.minVideoWidth;
minVideoHeight = initialValues.minVideoHeight;
minVideoFrameRate = initialValues.minVideoFrameRate;
minVideoBitrate = initialValues.minVideoBitrate;
viewportWidth = initialValues.viewportWidth;
viewportHeight = initialValues.viewportHeight;
viewportOrientationMayChange = initialValues.viewportOrientationMayChange;
preferredVideoMimeTypes = initialValues.preferredVideoMimeTypes;
// Audio
preferredAudioLanguages = initialValues.preferredAudioLanguages;
preferredAudioRoleFlags = initialValues.preferredAudioRoleFlags;
maxAudioChannelCount = initialValues.maxAudioChannelCount;
maxAudioBitrate = initialValues.maxAudioBitrate;
preferredAudioMimeTypes = initialValues.preferredAudioMimeTypes;
// Text
preferredTextLanguages = initialValues.preferredTextLanguages;
preferredTextRoleFlags = initialValues.preferredTextRoleFlags;
selectUndeterminedTextLanguage = initialValues.selectUndeterminedTextLanguage;
// General
forceLowestBitrate = initialValues.forceLowestBitrate;
forceHighestSupportedBitrate = initialValues.forceHighestSupportedBitrate;
}
// Video
/**
* Equivalent to {@link #setMaxVideoSize setMaxVideoSize(1279, 719)}.
*
* @return This builder.
*/
public Builder setMaxVideoSizeSd() {
return setMaxVideoSize(1279, 719);
}
/**
* Equivalent to {@link #setMaxVideoSize setMaxVideoSize(Integer.MAX_VALUE, Integer.MAX_VALUE)}.
*
* @return This builder.
*/
public Builder clearVideoSizeConstraints() {
return setMaxVideoSize(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
* Sets the maximum allowed video width and height.
*
* @param maxVideoWidth Maximum allowed video width in pixels.
* @param maxVideoHeight Maximum allowed video height in pixels.
* @return This builder.
*/
public Builder setMaxVideoSize(int maxVideoWidth, int maxVideoHeight) {
this.maxVideoWidth = maxVideoWidth;
this.maxVideoHeight = maxVideoHeight;
return this;
}
/**
* Sets the maximum allowed video frame rate.
*
* @param maxVideoFrameRate Maximum allowed video frame rate in hertz.
* @return This builder.
*/
public Builder setMaxVideoFrameRate(int maxVideoFrameRate) {
this.maxVideoFrameRate = maxVideoFrameRate;
return this;
}
/**
* Sets the maximum allowed video bitrate.
*
* @param maxVideoBitrate Maximum allowed video bitrate in bits per second.
* @return This builder.
*/
public Builder setMaxVideoBitrate(int maxVideoBitrate) {
this.maxVideoBitrate = maxVideoBitrate;
return this;
}
/**
* Sets the minimum allowed video width and height.
*
* @param minVideoWidth Minimum allowed video width in pixels.
* @param minVideoHeight Minimum allowed video height in pixels.
* @return This builder.
*/
public Builder setMinVideoSize(int minVideoWidth, int minVideoHeight) {
this.minVideoWidth = minVideoWidth;
this.minVideoHeight = minVideoHeight;
return this;
}
/**
* Sets the minimum allowed video frame rate.
*
* @param minVideoFrameRate Minimum allowed video frame rate in hertz.
* @return This builder.
*/
public Builder setMinVideoFrameRate(int minVideoFrameRate) {
this.minVideoFrameRate = minVideoFrameRate;
return this;
}
/**
* Sets the minimum allowed video bitrate.
*
* @param minVideoBitrate Minimum allowed video bitrate in bits per second.
* @return This builder.
*/
public Builder setMinVideoBitrate(int minVideoBitrate) {
this.minVideoBitrate = minVideoBitrate;
return this;
}
/**
* Equivalent to calling {@link #setViewportSize(int, int, boolean)} with the viewport size
* obtained from {@link Util#getCurrentDisplayModeSize(Context)}.
*
* @param context Any context.
* @param viewportOrientationMayChange Whether the viewport orientation may change during
* playback.
* @return This builder.
*/
public Builder setViewportSizeToPhysicalDisplaySize(
Context context, boolean viewportOrientationMayChange) {
// Assume the viewport is fullscreen.
Point viewportSize = Util.getCurrentDisplayModeSize(context);
return setViewportSize(viewportSize.x, viewportSize.y, viewportOrientationMayChange);
}
/**
* Equivalent to {@link #setViewportSize setViewportSize(Integer.MAX_VALUE, Integer.MAX_VALUE,
* true)}.
*
* @return This builder.
*/
public Builder clearViewportSizeConstraints() {
return setViewportSize(Integer.MAX_VALUE, Integer.MAX_VALUE, true);
}
/**
* Sets the viewport size to constrain adaptive video selections so that only tracks suitable
* for the viewport are selected.
*
* @param viewportWidth Viewport width in pixels.
* @param viewportHeight Viewport height in pixels.
* @param viewportOrientationMayChange Whether the viewport orientation may change during
* playback.
* @return This builder.
*/
public Builder setViewportSize(
int viewportWidth, int viewportHeight, boolean viewportOrientationMayChange) {
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
this.viewportOrientationMayChange = viewportOrientationMayChange;
return this;
}
/**
* Sets the preferred sample MIME type for video tracks.
*
* @param mimeType The preferred MIME type for video tracks, or {@code null} to clear a
* previously set preference.
* @return This builder.
*/
public Builder setPreferredVideoMimeType(@Nullable String mimeType) {
return mimeType == null ? setPreferredVideoMimeTypes() : setPreferredVideoMimeTypes(mimeType);
}
/**
* Sets the preferred sample MIME types for video tracks.
*
* @param mimeTypes The preferred MIME types for video tracks in order of preference, or an
* empty list for no preference.
* @return This builder.
*/
public Builder setPreferredVideoMimeTypes(String... mimeTypes) {
preferredVideoMimeTypes = ImmutableList.copyOf(mimeTypes);
return this;
}
// Audio
/**
* Sets the preferred language for audio and forced text tracks.
*
* @param preferredAudioLanguage Preferred audio language as an IETF BCP 47 conformant tag, or
* {@code null} to select the default track, or the first track if there's no default.
* @return This builder.
*/
public Builder setPreferredAudioLanguage(@Nullable String preferredAudioLanguage) {
return preferredAudioLanguage == null
? setPreferredAudioLanguages()
: setPreferredAudioLanguages(preferredAudioLanguage);
}
/**
* Sets the preferred languages for audio and forced text tracks.
*
* @param preferredAudioLanguages Preferred audio languages as IETF BCP 47 conformant tags in
* order of preference, or an empty array to select the default track, or the first track if
* there's no default.
* @return This builder.
*/
public Builder setPreferredAudioLanguages(String... preferredAudioLanguages) {
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
for (String language : checkNotNull(preferredAudioLanguages)) {
listBuilder.add(Util.normalizeLanguageCode(checkNotNull(language)));
}
this.preferredAudioLanguages = listBuilder.build();
return this;
}
/**
* Sets the preferred {@link C.RoleFlags} for audio tracks.
*
* @param preferredAudioRoleFlags Preferred audio role flags.
* @return This builder.
*/
public Builder setPreferredAudioRoleFlags(@C.RoleFlags int preferredAudioRoleFlags) {
this.preferredAudioRoleFlags = preferredAudioRoleFlags;
return this;
}
/**
* Sets the maximum allowed audio channel count.
*
* @param maxAudioChannelCount Maximum allowed audio channel count.
* @return This builder.
*/
public Builder setMaxAudioChannelCount(int maxAudioChannelCount) {
this.maxAudioChannelCount = maxAudioChannelCount;
return this;
}
/**
* Sets the maximum allowed audio bitrate.
*
* @param maxAudioBitrate Maximum allowed audio bitrate in bits per second.
* @return This builder.
*/
public Builder setMaxAudioBitrate(int maxAudioBitrate) {
this.maxAudioBitrate = maxAudioBitrate;
return this;
}
/**
* Sets the preferred sample MIME type for audio tracks.
*
* @param mimeType The preferred MIME type for audio tracks, or {@code null} to clear a
* previously set preference.
* @return This builder.
*/
public Builder setPreferredAudioMimeType(@Nullable String mimeType) {
return mimeType == null ? setPreferredAudioMimeTypes() : setPreferredAudioMimeTypes(mimeType);
}
/**
* Sets the preferred sample MIME types for audio tracks.
*
* @param mimeTypes The preferred MIME types for audio tracks in order of preference, or an
* empty list for no preference.
* @return This builder.
*/
public Builder setPreferredAudioMimeTypes(String... mimeTypes) {
preferredAudioMimeTypes = ImmutableList.copyOf(mimeTypes);
return this;
}
// Text
/**
* Sets the preferred language and role flags for text tracks based on the accessibility
* settings of {@link CaptioningManager}.
*
* <p>Does nothing for API levels &lt; 19 or when the {@link CaptioningManager} is disabled.
*
* @param context A {@link Context}.
* @return This builder.
*/
public Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(
Context context) {
if (Util.SDK_INT >= 19) {
setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(context);
}
return this;
}
/**
* Sets the preferred language for text tracks.
*
* @param preferredTextLanguage Preferred text language as an IETF BCP 47 conformant tag, or
* {@code null} to select the default track if there is one, or no track otherwise.
* @return This builder.
*/
public Builder setPreferredTextLanguage(@Nullable String preferredTextLanguage) {
return preferredTextLanguage == null
? setPreferredTextLanguages()
: setPreferredTextLanguages(preferredTextLanguage);
}
/**
* Sets the preferred languages for text tracks.
*
* @param preferredTextLanguages Preferred text languages as IETF BCP 47 conformant tags in
* order of preference, or an empty array to select the default track if there is one, or no
* track otherwise.
* @return This builder.
*/
public Builder setPreferredTextLanguages(String... preferredTextLanguages) {
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
for (String language : checkNotNull(preferredTextLanguages)) {
listBuilder.add(Util.normalizeLanguageCode(checkNotNull(language)));
}
this.preferredTextLanguages = listBuilder.build();
return this;
}
/**
* Sets the preferred {@link C.RoleFlags} for text tracks.
*
* @param preferredTextRoleFlags Preferred text role flags.
* @return This builder.
*/
public Builder setPreferredTextRoleFlags(@C.RoleFlags int preferredTextRoleFlags) {
this.preferredTextRoleFlags = preferredTextRoleFlags;
return this;
}
/**
* Sets whether a text track with undetermined language should be selected if no track with
* {@link #setPreferredTextLanguages(String...) a preferred language} is available, or if the
* preferred language is unset.
*
* @param selectUndeterminedTextLanguage Whether a text track with undetermined language should
* be selected if no preferred language track is available.
* @return This builder.
*/
public Builder setSelectUndeterminedTextLanguage(boolean selectUndeterminedTextLanguage) {
this.selectUndeterminedTextLanguage = selectUndeterminedTextLanguage;
return this;
}
// General
/**
* Sets whether to force selection of the single lowest bitrate audio and video tracks that
* comply with all other constraints.
*
* @param forceLowestBitrate Whether to force selection of the single lowest bitrate audio and
* video tracks.
* @return This builder.
*/
public Builder setForceLowestBitrate(boolean forceLowestBitrate) {
this.forceLowestBitrate = forceLowestBitrate;
return this;
}
/**
* Sets whether to force selection of the highest bitrate audio and video tracks that comply
* with all other constraints.
*
* @param forceHighestSupportedBitrate Whether to force selection of the highest bitrate audio
* and video tracks.
* @return This builder.
*/
public Builder setForceHighestSupportedBitrate(boolean forceHighestSupportedBitrate) {
this.forceHighestSupportedBitrate = forceHighestSupportedBitrate;
return this;
}
/** Builds a {@link TrackSelectionParameters} instance with the selected values. */
public TrackSelectionParameters build() {
return new TrackSelectionParameters(this);
}
@RequiresApi(19)
private void setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(
Context context) {
if (Util.SDK_INT < 23 && Looper.myLooper() == null) {
// Android platform bug (pre-Marshmallow) that causes RuntimeExceptions when
// CaptioningService is instantiated from a non-Looper thread. See [internal: b/143779904].
return;
}
CaptioningManager captioningManager =
(CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
if (captioningManager == null || !captioningManager.isEnabled()) {
return;
}
preferredTextRoleFlags = C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND;
Locale preferredLocale = captioningManager.getLocale();
if (preferredLocale != null) {
preferredTextLanguages = ImmutableList.of(Util.getLocaleLanguageTag(preferredLocale));
}
}
}
/**
* An instance with default values, except those obtained from the {@link Context}.
*
* <p>If possible, use {@link #getDefaults(Context)} instead.
*
* <p>This instance will not have the following settings:
*
* <ul>
* <li>{@link Builder#setViewportSizeToPhysicalDisplaySize(Context, boolean) Viewport
* constraints} configured for the primary display.
* <li>{@link Builder#setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(Context)
* Preferred text language and role flags} configured to the accessibility settings of
* {@link CaptioningManager}.
* </ul>
*/
@SuppressWarnings("deprecation")
public static final TrackSelectionParameters DEFAULT_WITHOUT_CONTEXT = new Builder().build();
/**
* @deprecated This instance is not configured using {@link Context} constraints. Use {@link
* #getDefaults(Context)} instead.
*/
@Deprecated public static final TrackSelectionParameters DEFAULT = DEFAULT_WITHOUT_CONTEXT;
public static final Creator<TrackSelectionParameters> CREATOR =
new Creator<TrackSelectionParameters>() {
@Override
public TrackSelectionParameters createFromParcel(Parcel in) {
return new TrackSelectionParameters(in);
}
@Override
public TrackSelectionParameters[] newArray(int size) {
return new TrackSelectionParameters[size];
}
};
/** Returns an instance configured with default values. */
public static TrackSelectionParameters getDefaults(Context context) {
return new Builder(context).build();
}
// Video
/**
* Maximum allowed video width in pixels. The default value is {@link Integer#MAX_VALUE} (i.e. no
* constraint).
*
* <p>To constrain adaptive video track selections to be suitable for a given viewport (the region
* of the display within which video will be played), use ({@link #viewportWidth}, {@link
* #viewportHeight} and {@link #viewportOrientationMayChange}) instead.
*/
public final int maxVideoWidth;
/**
* Maximum allowed video height in pixels. The default value is {@link Integer#MAX_VALUE} (i.e. no
* constraint).
*
* <p>To constrain adaptive video track selections to be suitable for a given viewport (the region
* of the display within which video will be played), use ({@link #viewportWidth}, {@link
* #viewportHeight} and {@link #viewportOrientationMayChange}) instead.
*/
public final int maxVideoHeight;
/**
* Maximum allowed video frame rate in hertz. The default value is {@link Integer#MAX_VALUE} (i.e.
* no constraint).
*/
public final int maxVideoFrameRate;
/**
* Maximum allowed video bitrate in bits per second. The default value is {@link
* Integer#MAX_VALUE} (i.e. no constraint).
*/
public final int maxVideoBitrate;
/** Minimum allowed video width in pixels. The default value is 0 (i.e. no constraint). */
public final int minVideoWidth;
/** Minimum allowed video height in pixels. The default value is 0 (i.e. no constraint). */
public final int minVideoHeight;
/** Minimum allowed video frame rate in hertz. The default value is 0 (i.e. no constraint). */
public final int minVideoFrameRate;
/**
* Minimum allowed video bitrate in bits per second. The default value is 0 (i.e. no constraint).
*/
public final int minVideoBitrate;
/**
* Viewport width in pixels. Constrains video track selections for adaptive content so that only
* tracks suitable for the viewport are selected. The default value is the physical width of the
* primary display, in pixels.
*/
public final int viewportWidth;
/**
* Viewport height in pixels. Constrains video track selections for adaptive content so that only
* tracks suitable for the viewport are selected. The default value is the physical height of the
* primary display, in pixels.
*/
public final int viewportHeight;
/**
* Whether the viewport orientation may change during playback. Constrains video track selections
* for adaptive content so that only tracks suitable for the viewport are selected. The default
* value is {@code true}.
*/
public final boolean viewportOrientationMayChange;
/**
* The preferred sample MIME types for video tracks in order of preference, or an empty list for
* no preference. The default is an empty list.
*/
public final ImmutableList<String> preferredVideoMimeTypes;
// Audio
/**
* The preferred languages for audio and forced text tracks as IETF BCP 47 conformant tags in
* order of preference. An empty list selects the default track, or the first track if there's no
* default. The default value is an empty list.
*/
public final ImmutableList<String> preferredAudioLanguages;
/**
* The preferred {@link C.RoleFlags} for audio tracks. {@code 0} selects the default track if
* there is one, or the first track if there's no default. The default value is {@code 0}.
*/
@C.RoleFlags public final int preferredAudioRoleFlags;
/**
* Maximum allowed audio channel count. The default value is {@link Integer#MAX_VALUE} (i.e. no
* constraint).
*/
public final int maxAudioChannelCount;
/**
* Maximum allowed audio bitrate in bits per second. The default value is {@link
* Integer#MAX_VALUE} (i.e. no constraint).
*/
public final int maxAudioBitrate;
/**
* The preferred sample MIME types for audio tracks in order of preference, or an empty list for
* no preference. The default is an empty list.
*/
public final ImmutableList<String> preferredAudioMimeTypes;
// Text
/**
* The preferred languages for text tracks as IETF BCP 47 conformant tags in order of preference.
* An empty list selects the default track if there is one, or no track otherwise. The default
* value is an empty list, or the language of the accessibility {@link CaptioningManager} if
* enabled.
*/
public final ImmutableList<String> preferredTextLanguages;
/**
* The preferred {@link C.RoleFlags} for text tracks. {@code 0} selects the default track if there
* is one, or no track otherwise. The default value is {@code 0}, or {@link C#ROLE_FLAG_SUBTITLE}
* | {@link C#ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND} if the accessibility {@link CaptioningManager}
* is enabled.
*/
@C.RoleFlags public final int preferredTextRoleFlags;
/**
* Whether a text track with undetermined language should be selected if no track with {@link
* #preferredTextLanguages} is available, or if {@link #preferredTextLanguages} is unset. The
* default value is {@code false}.
*/
public final boolean selectUndeterminedTextLanguage;
// General
/**
* Whether to force selection of the single lowest bitrate audio and video tracks that comply with
* all other constraints. The default value is {@code false}.
*/
public final boolean forceLowestBitrate;
/**
* Whether to force selection of the highest bitrate audio and video tracks that comply with all
* other constraints. The default value is {@code false}.
*/
public final boolean forceHighestSupportedBitrate;
protected TrackSelectionParameters(Builder builder) {
// Video
this.maxVideoWidth = builder.maxVideoWidth;
this.maxVideoHeight = builder.maxVideoHeight;
this.maxVideoFrameRate = builder.maxVideoFrameRate;
this.maxVideoBitrate = builder.maxVideoBitrate;
this.minVideoWidth = builder.minVideoWidth;
this.minVideoHeight = builder.minVideoHeight;
this.minVideoFrameRate = builder.minVideoFrameRate;
this.minVideoBitrate = builder.minVideoBitrate;
this.viewportWidth = builder.viewportWidth;
this.viewportHeight = builder.viewportHeight;
this.viewportOrientationMayChange = builder.viewportOrientationMayChange;
this.preferredVideoMimeTypes = builder.preferredVideoMimeTypes;
// Audio
this.preferredAudioLanguages = builder.preferredAudioLanguages;
this.preferredAudioRoleFlags = builder.preferredAudioRoleFlags;
this.maxAudioChannelCount = builder.maxAudioChannelCount;
this.maxAudioBitrate = builder.maxAudioBitrate;
this.preferredAudioMimeTypes = builder.preferredAudioMimeTypes;
// Text
this.preferredTextLanguages = builder.preferredTextLanguages;
this.preferredTextRoleFlags = builder.preferredTextRoleFlags;
this.selectUndeterminedTextLanguage = builder.selectUndeterminedTextLanguage;
// General
this.forceLowestBitrate = builder.forceLowestBitrate;
this.forceHighestSupportedBitrate = builder.forceHighestSupportedBitrate;
}
/* package */ TrackSelectionParameters(Parcel in) {
ArrayList<String> preferredAudioLanguages = new ArrayList<>();
in.readList(preferredAudioLanguages, /* loader= */ null);
this.preferredAudioLanguages = ImmutableList.copyOf(preferredAudioLanguages);
this.preferredAudioRoleFlags = in.readInt();
ArrayList<String> preferredTextLanguages1 = new ArrayList<>();
in.readList(preferredTextLanguages1, /* loader= */ null);
this.preferredTextLanguages = ImmutableList.copyOf(preferredTextLanguages1);
this.preferredTextRoleFlags = in.readInt();
this.selectUndeterminedTextLanguage = Util.readBoolean(in);
// Video
this.maxVideoWidth = in.readInt();
this.maxVideoHeight = in.readInt();
this.maxVideoFrameRate = in.readInt();
this.maxVideoBitrate = in.readInt();
this.minVideoWidth = in.readInt();
this.minVideoHeight = in.readInt();
this.minVideoFrameRate = in.readInt();
this.minVideoBitrate = in.readInt();
this.viewportWidth = in.readInt();
this.viewportHeight = in.readInt();
this.viewportOrientationMayChange = Util.readBoolean(in);
ArrayList<String> preferredVideoMimeTypes = new ArrayList<>();
in.readList(preferredVideoMimeTypes, /* loader= */ null);
this.preferredVideoMimeTypes = ImmutableList.copyOf(preferredVideoMimeTypes);
// Audio
this.maxAudioChannelCount = in.readInt();
this.maxAudioBitrate = in.readInt();
ArrayList<String> preferredAudioMimeTypes = new ArrayList<>();
in.readList(preferredAudioMimeTypes, /* loader= */ null);
this.preferredAudioMimeTypes = ImmutableList.copyOf(preferredAudioMimeTypes);
// General
this.forceLowestBitrate = Util.readBoolean(in);
this.forceHighestSupportedBitrate = Util.readBoolean(in);
}
/** Creates a new {@link Builder}, copying the initial values from this instance. */
public Builder buildUpon() {
return new Builder(this);
}
@Override
@SuppressWarnings("EqualsGetClass")
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
TrackSelectionParameters other = (TrackSelectionParameters) obj;
// Video
return maxVideoWidth == other.maxVideoWidth
&& maxVideoHeight == other.maxVideoHeight
&& maxVideoFrameRate == other.maxVideoFrameRate
&& maxVideoBitrate == other.maxVideoBitrate
&& minVideoWidth == other.minVideoWidth
&& minVideoHeight == other.minVideoHeight
&& minVideoFrameRate == other.minVideoFrameRate
&& minVideoBitrate == other.minVideoBitrate
&& viewportOrientationMayChange == other.viewportOrientationMayChange
&& viewportWidth == other.viewportWidth
&& viewportHeight == other.viewportHeight
&& preferredVideoMimeTypes.equals(other.preferredVideoMimeTypes)
// Audio
&& preferredAudioLanguages.equals(other.preferredAudioLanguages)
&& preferredAudioRoleFlags == other.preferredAudioRoleFlags
&& maxAudioChannelCount == other.maxAudioChannelCount
&& maxAudioBitrate == other.maxAudioBitrate
&& preferredAudioMimeTypes.equals(other.preferredAudioMimeTypes)
&& preferredTextLanguages.equals(other.preferredTextLanguages)
&& preferredTextRoleFlags == other.preferredTextRoleFlags
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
// General
&& forceLowestBitrate == other.forceLowestBitrate
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate;
}
@Override
public int hashCode() {
int result = 1;
// Video
result = 31 * result + maxVideoWidth;
result = 31 * result + maxVideoHeight;
result = 31 * result + maxVideoFrameRate;
result = 31 * result + maxVideoBitrate;
result = 31 * result + minVideoWidth;
result = 31 * result + minVideoHeight;
result = 31 * result + minVideoFrameRate;
result = 31 * result + minVideoBitrate;
result = 31 * result + (viewportOrientationMayChange ? 1 : 0);
result = 31 * result + viewportWidth;
result = 31 * result + viewportHeight;
result = 31 * result + preferredVideoMimeTypes.hashCode();
// Audio
result = 31 * result + preferredAudioLanguages.hashCode();
result = 31 * result + preferredAudioRoleFlags;
result = 31 * result + maxAudioChannelCount;
result = 31 * result + maxAudioBitrate;
result = 31 * result + preferredAudioMimeTypes.hashCode();
// Text
result = 31 * result + preferredTextLanguages.hashCode();
result = 31 * result + preferredTextRoleFlags;
result = 31 * result + (selectUndeterminedTextLanguage ? 1 : 0);
// General
result = 31 * result + (forceLowestBitrate ? 1 : 0);
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
return result;
}
// Parcelable implementation.
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(preferredAudioLanguages);
dest.writeInt(preferredAudioRoleFlags);
dest.writeList(preferredTextLanguages);
dest.writeInt(preferredTextRoleFlags);
Util.writeBoolean(dest, selectUndeterminedTextLanguage);
// Video
dest.writeInt(maxVideoWidth);
dest.writeInt(maxVideoHeight);
dest.writeInt(maxVideoFrameRate);
dest.writeInt(maxVideoBitrate);
dest.writeInt(minVideoWidth);
dest.writeInt(minVideoHeight);
dest.writeInt(minVideoFrameRate);
dest.writeInt(minVideoBitrate);
dest.writeInt(viewportWidth);
dest.writeInt(viewportHeight);
Util.writeBoolean(dest, viewportOrientationMayChange);
dest.writeList(preferredVideoMimeTypes);
// Audio
dest.writeInt(maxAudioChannelCount);
dest.writeInt(maxAudioBitrate);
dest.writeList(preferredAudioMimeTypes);
// General
Util.writeBoolean(dest, forceLowestBitrate);
Util.writeBoolean(dest, forceHighestSupportedBitrate);
}
}

View file

@ -0,0 +1,163 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.trackselection;
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.C;
import com.google.android.exoplayer2.util.MimeTypes;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Tests for {@link TrackSelectionParameters}. */
@RunWith(AndroidJUnit4.class)
public class TrackSelectionParametersTest {
@Test
public void defaultValue_withoutChange_isAsExpected() {
TrackSelectionParameters parameters = TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT;
// Video
assertThat(parameters.maxVideoWidth).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.maxVideoHeight).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.maxVideoFrameRate).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.maxVideoBitrate).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.minVideoWidth).isEqualTo(0);
assertThat(parameters.minVideoHeight).isEqualTo(0);
assertThat(parameters.minVideoFrameRate).isEqualTo(0);
assertThat(parameters.minVideoBitrate).isEqualTo(0);
assertThat(parameters.viewportWidth).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.viewportHeight).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.viewportOrientationMayChange).isTrue();
assertThat(parameters.preferredVideoMimeTypes).isEmpty();
// Audio
assertThat(parameters.preferredAudioLanguages).isEmpty();
assertThat(parameters.preferredAudioRoleFlags).isEqualTo(0);
assertThat(parameters.maxAudioChannelCount).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.maxAudioBitrate).isEqualTo(Integer.MAX_VALUE);
// Text
assertThat(parameters.preferredAudioMimeTypes).isEmpty();
assertThat(parameters.preferredTextLanguages).isEmpty();
assertThat(parameters.preferredTextRoleFlags).isEqualTo(0);
assertThat(parameters.selectUndeterminedTextLanguage).isFalse();
// General
assertThat(parameters.forceLowestBitrate).isFalse();
assertThat(parameters.forceHighestSupportedBitrate).isFalse();
}
@Test
public void parametersSet_fromDefault_isAsExpected() {
TrackSelectionParameters parameters =
TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT
.buildUpon()
// Video
.setMaxVideoSize(/* maxVideoWidth= */ 0, /* maxVideoHeight= */ 1)
.setMaxVideoFrameRate(2)
.setMaxVideoBitrate(3)
.setMinVideoSize(/* minVideoWidth= */ 4, /* minVideoHeight= */ 5)
.setMinVideoFrameRate(6)
.setMinVideoBitrate(7)
.setViewportSize(
/* viewportWidth= */ 8,
/* viewportHeight= */ 9,
/* viewportOrientationMayChange= */ true)
.setPreferredVideoMimeTypes(MimeTypes.VIDEO_AV1, MimeTypes.VIDEO_H264)
// Audio
.setPreferredAudioLanguages("zh", "jp")
.setPreferredAudioRoleFlags(C.ROLE_FLAG_COMMENTARY)
.setMaxAudioChannelCount(10)
.setMaxAudioBitrate(11)
.setPreferredAudioMimeTypes(MimeTypes.AUDIO_AC3, MimeTypes.AUDIO_E_AC3)
// Text
.setPreferredTextLanguages("de", "en")
.setPreferredTextRoleFlags(C.ROLE_FLAG_CAPTION)
.setSelectUndeterminedTextLanguage(true)
// General
.setForceLowestBitrate(false)
.setForceHighestSupportedBitrate(true)
.build();
// Video
assertThat(parameters.maxVideoWidth).isEqualTo(0);
assertThat(parameters.maxVideoHeight).isEqualTo(1);
assertThat(parameters.maxVideoFrameRate).isEqualTo(2);
assertThat(parameters.maxVideoBitrate).isEqualTo(3);
assertThat(parameters.minVideoWidth).isEqualTo(4);
assertThat(parameters.minVideoHeight).isEqualTo(5);
assertThat(parameters.minVideoFrameRate).isEqualTo(6);
assertThat(parameters.minVideoBitrate).isEqualTo(7);
assertThat(parameters.viewportWidth).isEqualTo(8);
assertThat(parameters.viewportHeight).isEqualTo(9);
assertThat(parameters.viewportOrientationMayChange).isTrue();
assertThat(parameters.preferredVideoMimeTypes)
.containsExactly(MimeTypes.VIDEO_AV1, MimeTypes.VIDEO_H264)
.inOrder();
// Audio
assertThat(parameters.preferredAudioLanguages).containsExactly("zh", "jp").inOrder();
assertThat(parameters.preferredAudioRoleFlags).isEqualTo(C.ROLE_FLAG_COMMENTARY);
assertThat(parameters.maxAudioChannelCount).isEqualTo(10);
assertThat(parameters.maxAudioBitrate).isEqualTo(11);
assertThat(parameters.preferredAudioMimeTypes)
.containsExactly(MimeTypes.AUDIO_AC3, MimeTypes.AUDIO_E_AC3)
.inOrder();
// Text
assertThat(parameters.preferredTextLanguages).containsExactly("de", "en").inOrder();
assertThat(parameters.preferredTextRoleFlags).isEqualTo(C.ROLE_FLAG_CAPTION);
assertThat(parameters.selectUndeterminedTextLanguage).isTrue();
// General
assertThat(parameters.forceLowestBitrate).isFalse();
assertThat(parameters.forceHighestSupportedBitrate).isTrue();
}
@Test
public void setMaxVideoSizeSd_defaultBuilder_parametersVideoSizeAreSd() {
TrackSelectionParameters parameters =
new TrackSelectionParameters.Builder(getApplicationContext()).setMaxVideoSizeSd().build();
assertThat(parameters.maxVideoWidth).isEqualTo(1279);
assertThat(parameters.maxVideoHeight).isEqualTo(719);
}
@Test
public void clearVideoSizeConstraints_withSdConstrains_clearConstrains() {
TrackSelectionParameters parameters =
new TrackSelectionParameters.Builder(getApplicationContext())
.setMaxVideoSizeSd()
.clearVideoSizeConstraints()
.build();
assertThat(parameters.maxVideoWidth).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.maxVideoHeight).isEqualTo(Integer.MAX_VALUE);
}
@Test
public void clearViewPortConstraints_withConstrains_clearConstrains() {
TrackSelectionParameters parameters =
new TrackSelectionParameters.Builder(getApplicationContext())
.setViewportSize(
/*viewportWidth=*/ 1,
/*viewportHeight=*/ 2,
/*viewportOrientationMayChange=*/ false)
.clearViewportSizeConstraints()
.build();
assertThat(parameters.viewportWidth).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.viewportHeight).isEqualTo(Integer.MAX_VALUE);
assertThat(parameters.viewportOrientationMayChange).isTrue();
}
}

View file

@ -51,9 +51,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.checkerframework.checker.initialization.qual.UnderInitialization;
import org.checkerframework.checker.nullness.compatqual.NullableType;
import org.checkerframework.checker.nullness.qual.EnsuresNonNull;
/**
* A default {@link TrackSelector} suitable for most use cases. Track selections are made according
@ -170,32 +168,17 @@ public class DefaultTrackSelector extends MappingTrackSelector {
public static final class ParametersBuilder extends TrackSelectionParameters.Builder {
// Video
private int maxVideoWidth;
private int maxVideoHeight;
private int maxVideoFrameRate;
private int maxVideoBitrate;
private int minVideoWidth;
private int minVideoHeight;
private int minVideoFrameRate;
private int minVideoBitrate;
private boolean exceedVideoConstraintsIfNecessary;
private boolean allowVideoMixedMimeTypeAdaptiveness;
private boolean allowVideoNonSeamlessAdaptiveness;
private int viewportWidth;
private int viewportHeight;
private boolean viewportOrientationMayChange;
private ImmutableList<String> preferredVideoMimeTypes;
// Audio
private int maxAudioChannelCount;
private int maxAudioBitrate;
private boolean exceedAudioConstraintsIfNecessary;
private boolean allowAudioMixedMimeTypeAdaptiveness;
private boolean allowAudioMixedSampleRateAdaptiveness;
private boolean allowAudioMixedChannelCountAdaptiveness;
private ImmutableList<String> preferredAudioMimeTypes;
// Text
@C.SelectionFlags private int disabledTextTrackSelectionFlags;
// General
private boolean forceLowestBitrate;
private boolean forceHighestSupportedBitrate;
private boolean exceedRendererCapabilitiesIfNecessary;
private boolean tunnelingEnabled;
private boolean allowMultipleAdaptiveSelections;
@ -212,9 +195,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@SuppressWarnings({"deprecation"})
public ParametersBuilder() {
super();
setInitialValuesWithoutContext();
selectionOverrides = new SparseArray<>();
rendererDisabledFlags = new SparseBooleanArray();
init();
}
/**
@ -224,10 +207,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*/
public ParametersBuilder(Context context) {
super(context);
setInitialValuesWithoutContext();
selectionOverrides = new SparseArray<>();
rendererDisabledFlags = new SparseBooleanArray();
setViewportSizeToPhysicalDisplaySize(context, /* viewportOrientationMayChange= */ true);
init();
}
/**
@ -236,34 +218,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*/
private ParametersBuilder(Parameters initialValues) {
super(initialValues);
// Text
disabledTextTrackSelectionFlags = initialValues.disabledTextTrackSelectionFlags;
// Video
maxVideoWidth = initialValues.maxVideoWidth;
maxVideoHeight = initialValues.maxVideoHeight;
maxVideoFrameRate = initialValues.maxVideoFrameRate;
maxVideoBitrate = initialValues.maxVideoBitrate;
minVideoWidth = initialValues.minVideoWidth;
minVideoHeight = initialValues.minVideoHeight;
minVideoFrameRate = initialValues.minVideoFrameRate;
minVideoBitrate = initialValues.minVideoBitrate;
exceedVideoConstraintsIfNecessary = initialValues.exceedVideoConstraintsIfNecessary;
allowVideoMixedMimeTypeAdaptiveness = initialValues.allowVideoMixedMimeTypeAdaptiveness;
allowVideoNonSeamlessAdaptiveness = initialValues.allowVideoNonSeamlessAdaptiveness;
viewportWidth = initialValues.viewportWidth;
viewportHeight = initialValues.viewportHeight;
viewportOrientationMayChange = initialValues.viewportOrientationMayChange;
preferredVideoMimeTypes = initialValues.preferredVideoMimeTypes;
// Audio
maxAudioChannelCount = initialValues.maxAudioChannelCount;
maxAudioBitrate = initialValues.maxAudioBitrate;
exceedAudioConstraintsIfNecessary = initialValues.exceedAudioConstraintsIfNecessary;
allowAudioMixedMimeTypeAdaptiveness = initialValues.allowAudioMixedMimeTypeAdaptiveness;
allowAudioMixedSampleRateAdaptiveness = initialValues.allowAudioMixedSampleRateAdaptiveness;
allowAudioMixedChannelCountAdaptiveness =
initialValues.allowAudioMixedChannelCountAdaptiveness;
preferredAudioMimeTypes = initialValues.preferredAudioMimeTypes;
// General
forceLowestBitrate = initialValues.forceLowestBitrate;
forceHighestSupportedBitrate = initialValues.forceHighestSupportedBitrate;
exceedRendererCapabilitiesIfNecessary = initialValues.exceedRendererCapabilitiesIfNecessary;
tunnelingEnabled = initialValues.tunnelingEnabled;
allowMultipleAdaptiveSelections = initialValues.allowMultipleAdaptiveSelections;
@ -274,91 +241,53 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Video
/**
* Equivalent to {@link #setMaxVideoSize setMaxVideoSize(1279, 719)}.
*
* @return This builder.
*/
public ParametersBuilder setMaxVideoSizeSd() {
return setMaxVideoSize(1279, 719);
}
/**
* Equivalent to {@link #setMaxVideoSize setMaxVideoSize(Integer.MAX_VALUE, Integer.MAX_VALUE)}.
*
* @return This builder.
*/
public ParametersBuilder clearVideoSizeConstraints() {
return setMaxVideoSize(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
* Sets the maximum allowed video width and height.
*
* @param maxVideoWidth Maximum allowed video width in pixels.
* @param maxVideoHeight Maximum allowed video height in pixels.
* @return This builder.
*/
public ParametersBuilder setMaxVideoSize(int maxVideoWidth, int maxVideoHeight) {
this.maxVideoWidth = maxVideoWidth;
this.maxVideoHeight = maxVideoHeight;
@Override
public DefaultTrackSelector.ParametersBuilder setMaxVideoSizeSd() {
super.setMaxVideoSizeSd();
return this;
}
/**
* Sets the maximum allowed video frame rate.
*
* @param maxVideoFrameRate Maximum allowed video frame rate in hertz.
* @return This builder.
*/
public ParametersBuilder setMaxVideoFrameRate(int maxVideoFrameRate) {
this.maxVideoFrameRate = maxVideoFrameRate;
@Override
public DefaultTrackSelector.ParametersBuilder clearVideoSizeConstraints() {
super.clearVideoSizeConstraints();
return this;
}
/**
* Sets the maximum allowed video bitrate.
*
* @param maxVideoBitrate Maximum allowed video bitrate in bits per second.
* @return This builder.
*/
public ParametersBuilder setMaxVideoBitrate(int maxVideoBitrate) {
this.maxVideoBitrate = maxVideoBitrate;
@Override
public DefaultTrackSelector.ParametersBuilder setMaxVideoSize(
int maxVideoWidth, int maxVideoHeight) {
super.setMaxVideoSize(maxVideoWidth, maxVideoHeight);
return this;
}
/**
* Sets the minimum allowed video width and height.
*
* @param minVideoWidth Minimum allowed video width in pixels.
* @param minVideoHeight Minimum allowed video height in pixels.
* @return This builder.
*/
public ParametersBuilder setMinVideoSize(int minVideoWidth, int minVideoHeight) {
this.minVideoWidth = minVideoWidth;
this.minVideoHeight = minVideoHeight;
@Override
public DefaultTrackSelector.ParametersBuilder setMaxVideoFrameRate(int maxVideoFrameRate) {
super.setMaxVideoFrameRate(maxVideoFrameRate);
return this;
}
/**
* Sets the minimum allowed video frame rate.
*
* @param minVideoFrameRate Minimum allowed video frame rate in hertz.
* @return This builder.
*/
public ParametersBuilder setMinVideoFrameRate(int minVideoFrameRate) {
this.minVideoFrameRate = minVideoFrameRate;
@Override
public DefaultTrackSelector.ParametersBuilder setMaxVideoBitrate(int maxVideoBitrate) {
super.setMaxVideoBitrate(maxVideoBitrate);
return this;
}
/**
* Sets the minimum allowed video bitrate.
*
* @param minVideoBitrate Minimum allowed video bitrate in bits per second.
* @return This builder.
*/
public ParametersBuilder setMinVideoBitrate(int minVideoBitrate) {
this.minVideoBitrate = minVideoBitrate;
@Override
public DefaultTrackSelector.ParametersBuilder setMinVideoSize(
int minVideoWidth, int minVideoHeight) {
super.setMinVideoSize(minVideoWidth, minVideoHeight);
return this;
}
@Override
public DefaultTrackSelector.ParametersBuilder setMinVideoFrameRate(int minVideoFrameRate) {
super.setMinVideoFrameRate(minVideoFrameRate);
return this;
}
@Override
public DefaultTrackSelector.ParametersBuilder setMinVideoBitrate(int minVideoBitrate) {
super.setMinVideoBitrate(minVideoBitrate);
return this;
}
@ -407,70 +336,35 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
/**
* Equivalent to calling {@link #setViewportSize(int, int, boolean)} with the viewport size
* obtained from {@link Util#getCurrentDisplayModeSize(Context)}.
*
* @param context Any context.
* @param viewportOrientationMayChange Whether the viewport orientation may change during
* playback.
* @return This builder.
*/
@Override
public ParametersBuilder setViewportSizeToPhysicalDisplaySize(
Context context, boolean viewportOrientationMayChange) {
// Assume the viewport is fullscreen.
Point viewportSize = Util.getCurrentDisplayModeSize(context);
return setViewportSize(viewportSize.x, viewportSize.y, viewportOrientationMayChange);
}
/**
* Equivalent to {@link #setViewportSize setViewportSize(Integer.MAX_VALUE, Integer.MAX_VALUE,
* true)}.
*
* @return This builder.
*/
public ParametersBuilder clearViewportSizeConstraints() {
return setViewportSize(Integer.MAX_VALUE, Integer.MAX_VALUE, true);
}
/**
* Sets the viewport size to constrain adaptive video selections so that only tracks suitable
* for the viewport are selected.
*
* @param viewportWidth Viewport width in pixels.
* @param viewportHeight Viewport height in pixels.
* @param viewportOrientationMayChange Whether the viewport orientation may change during
* playback.
* @return This builder.
*/
public ParametersBuilder setViewportSize(
int viewportWidth, int viewportHeight, boolean viewportOrientationMayChange) {
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
this.viewportOrientationMayChange = viewportOrientationMayChange;
super.setViewportSizeToPhysicalDisplaySize(context, viewportOrientationMayChange);
return this;
}
/**
* Sets the preferred sample MIME type for video tracks.
*
* @param mimeType The preferred MIME type for video tracks, or {@code null} to clear a
* previously set preference.
* @return This builder.
*/
public ParametersBuilder setPreferredVideoMimeType(@Nullable String mimeType) {
return mimeType == null ? setPreferredVideoMimeTypes() : setPreferredVideoMimeTypes(mimeType);
@Override
public ParametersBuilder clearViewportSizeConstraints() {
super.clearViewportSizeConstraints();
return this;
}
/**
* Sets the preferred sample MIME types for video tracks.
*
* @param mimeTypes The preferred MIME types for video tracks in order of preference, or an
* empty list for no preference.
* @return This builder.
*/
@Override
public ParametersBuilder setViewportSize(
int viewportWidth, int viewportHeight, boolean viewportOrientationMayChange) {
super.setViewportSize(viewportWidth, viewportHeight, viewportOrientationMayChange);
return this;
}
@Override
public ParametersBuilder setPreferredVideoMimeType(@Nullable String mimeType) {
super.setPreferredVideoMimeType(mimeType);
return this;
}
@Override
public ParametersBuilder setPreferredVideoMimeTypes(String... mimeTypes) {
preferredVideoMimeTypes = ImmutableList.copyOf(mimeTypes);
super.setPreferredVideoMimeTypes(mimeTypes);
return this;
}
@ -494,25 +388,15 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
/**
* Sets the maximum allowed audio channel count.
*
* @param maxAudioChannelCount Maximum allowed audio channel count.
* @return This builder.
*/
@Override
public ParametersBuilder setMaxAudioChannelCount(int maxAudioChannelCount) {
this.maxAudioChannelCount = maxAudioChannelCount;
super.setMaxAudioChannelCount(maxAudioChannelCount);
return this;
}
/**
* Sets the maximum allowed audio bitrate.
*
* @param maxAudioBitrate Maximum allowed audio bitrate in bits per second.
* @return This builder.
*/
@Override
public ParametersBuilder setMaxAudioBitrate(int maxAudioBitrate) {
this.maxAudioBitrate = maxAudioBitrate;
super.setMaxAudioBitrate(maxAudioBitrate);
return this;
}
@ -575,26 +459,15 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
/**
* Sets the preferred sample MIME type for audio tracks.
*
* @param mimeType The preferred MIME type for audio tracks, or {@code null} to clear a
* previously set preference.
* @return This builder.
*/
@Override
public ParametersBuilder setPreferredAudioMimeType(@Nullable String mimeType) {
return mimeType == null ? setPreferredAudioMimeTypes() : setPreferredAudioMimeTypes(mimeType);
super.setPreferredAudioMimeType(mimeType);
return this;
}
/**
* Sets the preferred sample MIME types for audio tracks.
*
* @param mimeTypes The preferred MIME types for audio tracks in order of preference, or an
* empty list for no preference.
* @return This builder.
*/
@Override
public ParametersBuilder setPreferredAudioMimeTypes(String... mimeTypes) {
preferredAudioMimeTypes = ImmutableList.copyOf(mimeTypes);
super.setPreferredAudioMimeTypes(mimeTypes);
return this;
}
@ -632,38 +505,30 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return this;
}
@Override
/**
* Sets a bitmask of selection flags that are disabled for text track selections.
*
* @param disabledTextTrackSelectionFlags A bitmask of {@link C.SelectionFlags} that are
* disabled for text track selections.
* @return This builder.
*/
public ParametersBuilder setDisabledTextTrackSelectionFlags(
@C.SelectionFlags int disabledTextTrackSelectionFlags) {
super.setDisabledTextTrackSelectionFlags(disabledTextTrackSelectionFlags);
this.disabledTextTrackSelectionFlags = disabledTextTrackSelectionFlags;
return this;
}
// General
/**
* Sets whether to force selection of the single lowest bitrate audio and video tracks that
* comply with all other constraints.
*
* @param forceLowestBitrate Whether to force selection of the single lowest bitrate audio and
* video tracks.
* @return This builder.
*/
@Override
public ParametersBuilder setForceLowestBitrate(boolean forceLowestBitrate) {
this.forceLowestBitrate = forceLowestBitrate;
super.setForceLowestBitrate(forceLowestBitrate);
return this;
}
/**
* Sets whether to force selection of the highest bitrate audio and video tracks that comply
* with all other constraints.
*
* @param forceHighestSupportedBitrate Whether to force selection of the highest bitrate audio
* and video tracks.
* @return This builder.
*/
@Override
public ParametersBuilder setForceHighestSupportedBitrate(boolean forceHighestSupportedBitrate) {
this.forceHighestSupportedBitrate = forceHighestSupportedBitrate;
super.setForceHighestSupportedBitrate(forceHighestSupportedBitrate);
return this;
}
@ -826,74 +691,24 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
/** Builds a {@link Parameters} instance with the selected values. */
@Override
public Parameters build() {
return new Parameters(
// Video
maxVideoWidth,
maxVideoHeight,
maxVideoFrameRate,
maxVideoBitrate,
minVideoWidth,
minVideoHeight,
minVideoFrameRate,
minVideoBitrate,
exceedVideoConstraintsIfNecessary,
allowVideoMixedMimeTypeAdaptiveness,
allowVideoNonSeamlessAdaptiveness,
viewportWidth,
viewportHeight,
viewportOrientationMayChange,
preferredVideoMimeTypes,
// Audio
preferredAudioLanguages,
preferredAudioRoleFlags,
maxAudioChannelCount,
maxAudioBitrate,
exceedAudioConstraintsIfNecessary,
allowAudioMixedMimeTypeAdaptiveness,
allowAudioMixedSampleRateAdaptiveness,
allowAudioMixedChannelCountAdaptiveness,
preferredAudioMimeTypes,
// Text
preferredTextLanguages,
preferredTextRoleFlags,
selectUndeterminedTextLanguage,
disabledTextTrackSelectionFlags,
// General
forceLowestBitrate,
forceHighestSupportedBitrate,
exceedRendererCapabilitiesIfNecessary,
tunnelingEnabled,
allowMultipleAdaptiveSelections,
selectionOverrides,
rendererDisabledFlags);
return new Parameters(this);
}
@EnsuresNonNull({"preferredVideoMimeTypes", "preferredAudioMimeTypes"})
private void setInitialValuesWithoutContext(@UnderInitialization ParametersBuilder this) {
private void init(ParametersBuilder this) {
// Video
maxVideoWidth = Integer.MAX_VALUE;
maxVideoHeight = Integer.MAX_VALUE;
maxVideoFrameRate = Integer.MAX_VALUE;
maxVideoBitrate = Integer.MAX_VALUE;
exceedVideoConstraintsIfNecessary = true;
allowVideoMixedMimeTypeAdaptiveness = false;
allowVideoNonSeamlessAdaptiveness = true;
viewportWidth = Integer.MAX_VALUE;
viewportHeight = Integer.MAX_VALUE;
viewportOrientationMayChange = true;
preferredVideoMimeTypes = ImmutableList.of();
// Audio
maxAudioChannelCount = Integer.MAX_VALUE;
maxAudioBitrate = Integer.MAX_VALUE;
exceedAudioConstraintsIfNecessary = true;
allowAudioMixedMimeTypeAdaptiveness = false;
allowAudioMixedSampleRateAdaptiveness = false;
allowAudioMixedChannelCountAdaptiveness = false;
preferredAudioMimeTypes = ImmutableList.of();
// Text
disabledTextTrackSelectionFlags = 0;
// General
forceLowestBitrate = false;
forceHighestSupportedBitrate = false;
exceedRendererCapabilitiesIfNecessary = true;
tunnelingEnabled = false;
allowMultipleAdaptiveSelections = true;
@ -912,10 +727,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
/**
* Extends {@link TrackSelectionParameters} by adding fields that are specific to {@link
* DefaultTrackSelector}.
* Extends {@link Parameters} by adding fields that are specific to {@link DefaultTrackSelector}.
*/
public static final class Parameters extends TrackSelectionParameters {
public static final class Parameters extends TrackSelectionParameters implements Parcelable {
/**
* An instance with default values, except those obtained from the {@link Context}.
@ -935,6 +749,30 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*/
@SuppressWarnings("deprecation")
public static final Parameters DEFAULT_WITHOUT_CONTEXT = new ParametersBuilder().build();
/**
* @deprecated This instance is not configured using {@link Context} constraints. Use {@link
* #getDefaults(Context)} instead.
*/
@Deprecated public static final Parameters DEFAULT = DEFAULT_WITHOUT_CONTEXT;
public static final Creator<Parameters> CREATOR =
new Creator<Parameters>() {
@Override
public Parameters createFromParcel(Parcel in) {
return new Parameters(in);
}
@Override
public Parameters[] newArray(int size) {
return new Parameters[size];
}
};
/**
* Bitmask of selection flags that are disabled for text track selections. See {@link
* C.SelectionFlags}. The default value is {@code 0} (i.e. no flags).
*/
@C.SelectionFlags public final int disabledTextTrackSelectionFlags;
/** Returns an instance configured with default values. */
public static Parameters getDefaults(Context context) {
@ -942,45 +780,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
// Video
/**
* Maximum allowed video width in pixels. The default value is {@link Integer#MAX_VALUE} (i.e.
* no constraint).
*
* <p>To constrain adaptive video track selections to be suitable for a given viewport (the
* region of the display within which video will be played), use ({@link #viewportWidth}, {@link
* #viewportHeight} and {@link #viewportOrientationMayChange}) instead.
*/
public final int maxVideoWidth;
/**
* Maximum allowed video height in pixels. The default value is {@link Integer#MAX_VALUE} (i.e.
* no constraint).
*
* <p>To constrain adaptive video track selections to be suitable for a given viewport (the
* region of the display within which video will be played), use ({@link #viewportWidth}, {@link
* #viewportHeight} and {@link #viewportOrientationMayChange}) instead.
*/
public final int maxVideoHeight;
/**
* Maximum allowed video frame rate in hertz. The default value is {@link Integer#MAX_VALUE}
* (i.e. no constraint).
*/
public final int maxVideoFrameRate;
/**
* Maximum allowed video bitrate in bits per second. The default value is {@link
* Integer#MAX_VALUE} (i.e. no constraint).
*/
public final int maxVideoBitrate;
/** Minimum allowed video width in pixels. The default value is 0 (i.e. no constraint). */
public final int minVideoWidth;
/** Minimum allowed video height in pixels. The default value is 0 (i.e. no constraint). */
public final int minVideoHeight;
/** Minimum allowed video frame rate in hertz. The default value is 0 (i.e. no constraint). */
public final int minVideoFrameRate;
/**
* Minimum allowed video bitrate in bits per second. The default value is 0 (i.e. no
* constraint).
*/
public final int minVideoBitrate;
/**
* Whether to exceed the {@link #maxVideoWidth}, {@link #maxVideoHeight} and {@link
* #maxVideoBitrate} constraints when no selection can be made otherwise. The default value is
@ -999,40 +798,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* The default value is {@code true}.
*/
public final boolean allowVideoNonSeamlessAdaptiveness;
/**
* Viewport width in pixels. Constrains video track selections for adaptive content so that only
* tracks suitable for the viewport are selected. The default value is the physical width of the
* primary display, in pixels.
*/
public final int viewportWidth;
/**
* Viewport height in pixels. Constrains video track selections for adaptive content so that
* only tracks suitable for the viewport are selected. The default value is the physical height
* of the primary display, in pixels.
*/
public final int viewportHeight;
/**
* Whether the viewport orientation may change during playback. Constrains video track
* selections for adaptive content so that only tracks suitable for the viewport are selected.
* The default value is {@code true}.
*/
public final boolean viewportOrientationMayChange;
/**
* The preferred sample MIME types for video tracks in order of preference, or an empty list for
* no preference. The default is an empty list.
*/
public final ImmutableList<String> preferredVideoMimeTypes;
// Audio
/**
* Maximum allowed audio channel count. The default value is {@link Integer#MAX_VALUE} (i.e. no
* constraint).
*/
public final int maxAudioChannelCount;
/**
* Maximum allowed audio bitrate in bits per second. The default value is {@link
* Integer#MAX_VALUE} (i.e. no constraint).
*/
public final int maxAudioBitrate;
/**
* Whether to exceed the {@link #maxAudioChannelCount} and {@link #maxAudioBitrate} constraints
* when no selection can be made otherwise. The default value is {@code true}.
@ -1054,22 +819,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* false}.
*/
public final boolean allowAudioMixedChannelCountAdaptiveness;
/**
* The preferred sample MIME types for audio tracks in order of preference, or an empty list for
* no preference. The default is an empty list.
*/
public final ImmutableList<String> preferredAudioMimeTypes;
// General
/**
* Whether to force selection of the single lowest bitrate audio and video tracks that comply
* with all other constraints. The default value is {@code false}.
*/
public final boolean forceLowestBitrate;
/**
* Whether to force selection of the highest bitrate audio and video tracks that comply with all
* other constraints. The default value is {@code false}.
*/
public final boolean forceHighestSupportedBitrate;
/**
* Whether to exceed renderer capabilities when no selection can be made otherwise.
*
@ -1097,122 +846,42 @@ public class DefaultTrackSelector extends MappingTrackSelector {
selectionOverrides;
private final SparseBooleanArray rendererDisabledFlags;
/* package */ Parameters(
// Video
int maxVideoWidth,
int maxVideoHeight,
int maxVideoFrameRate,
int maxVideoBitrate,
int minVideoWidth,
int minVideoHeight,
int minVideoFrameRate,
int minVideoBitrate,
boolean exceedVideoConstraintsIfNecessary,
boolean allowVideoMixedMimeTypeAdaptiveness,
boolean allowVideoNonSeamlessAdaptiveness,
int viewportWidth,
int viewportHeight,
boolean viewportOrientationMayChange,
ImmutableList<String> preferredVideoMimeTypes,
// Audio
ImmutableList<String> preferredAudioLanguages,
@C.RoleFlags int preferredAudioRoleFlags,
int maxAudioChannelCount,
int maxAudioBitrate,
boolean exceedAudioConstraintsIfNecessary,
boolean allowAudioMixedMimeTypeAdaptiveness,
boolean allowAudioMixedSampleRateAdaptiveness,
boolean allowAudioMixedChannelCountAdaptiveness,
ImmutableList<String> preferredAudioMimeTypes,
// Text
ImmutableList<String> preferredTextLanguages,
@C.RoleFlags int preferredTextRoleFlags,
boolean selectUndeterminedTextLanguage,
@C.SelectionFlags int disabledTextTrackSelectionFlags,
// General
boolean forceLowestBitrate,
boolean forceHighestSupportedBitrate,
boolean exceedRendererCapabilitiesIfNecessary,
boolean tunnelingEnabled,
boolean allowMultipleAdaptiveSelections,
// Overrides
SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>> selectionOverrides,
SparseBooleanArray rendererDisabledFlags) {
super(
preferredAudioLanguages,
preferredAudioRoleFlags,
preferredTextLanguages,
preferredTextRoleFlags,
selectUndeterminedTextLanguage,
disabledTextTrackSelectionFlags);
private Parameters(ParametersBuilder builder) {
super(builder);
// Video
this.maxVideoWidth = maxVideoWidth;
this.maxVideoHeight = maxVideoHeight;
this.maxVideoFrameRate = maxVideoFrameRate;
this.maxVideoBitrate = maxVideoBitrate;
this.minVideoWidth = minVideoWidth;
this.minVideoHeight = minVideoHeight;
this.minVideoFrameRate = minVideoFrameRate;
this.minVideoBitrate = minVideoBitrate;
this.exceedVideoConstraintsIfNecessary = exceedVideoConstraintsIfNecessary;
this.allowVideoMixedMimeTypeAdaptiveness = allowVideoMixedMimeTypeAdaptiveness;
this.allowVideoNonSeamlessAdaptiveness = allowVideoNonSeamlessAdaptiveness;
this.viewportWidth = viewportWidth;
this.viewportHeight = viewportHeight;
this.viewportOrientationMayChange = viewportOrientationMayChange;
this.preferredVideoMimeTypes = preferredVideoMimeTypes;
exceedVideoConstraintsIfNecessary = builder.exceedVideoConstraintsIfNecessary;
allowVideoMixedMimeTypeAdaptiveness = builder.allowVideoMixedMimeTypeAdaptiveness;
allowVideoNonSeamlessAdaptiveness = builder.allowVideoNonSeamlessAdaptiveness;
// Audio
this.maxAudioChannelCount = maxAudioChannelCount;
this.maxAudioBitrate = maxAudioBitrate;
this.exceedAudioConstraintsIfNecessary = exceedAudioConstraintsIfNecessary;
this.allowAudioMixedMimeTypeAdaptiveness = allowAudioMixedMimeTypeAdaptiveness;
this.allowAudioMixedSampleRateAdaptiveness = allowAudioMixedSampleRateAdaptiveness;
this.allowAudioMixedChannelCountAdaptiveness = allowAudioMixedChannelCountAdaptiveness;
this.preferredAudioMimeTypes = preferredAudioMimeTypes;
exceedAudioConstraintsIfNecessary = builder.exceedAudioConstraintsIfNecessary;
allowAudioMixedMimeTypeAdaptiveness = builder.allowAudioMixedMimeTypeAdaptiveness;
allowAudioMixedSampleRateAdaptiveness = builder.allowAudioMixedSampleRateAdaptiveness;
allowAudioMixedChannelCountAdaptiveness = builder.allowAudioMixedChannelCountAdaptiveness;
// Text
disabledTextTrackSelectionFlags = builder.disabledTextTrackSelectionFlags;
// General
this.forceLowestBitrate = forceLowestBitrate;
this.forceHighestSupportedBitrate = forceHighestSupportedBitrate;
this.exceedRendererCapabilitiesIfNecessary = exceedRendererCapabilitiesIfNecessary;
this.tunnelingEnabled = tunnelingEnabled;
this.allowMultipleAdaptiveSelections = allowMultipleAdaptiveSelections;
exceedRendererCapabilitiesIfNecessary = builder.exceedRendererCapabilitiesIfNecessary;
tunnelingEnabled = builder.tunnelingEnabled;
allowMultipleAdaptiveSelections = builder.allowMultipleAdaptiveSelections;
// Overrides
this.selectionOverrides = selectionOverrides;
this.rendererDisabledFlags = rendererDisabledFlags;
selectionOverrides = builder.selectionOverrides;
rendererDisabledFlags = builder.rendererDisabledFlags;
}
/* package */ Parameters(Parcel in) {
super(in);
// Video
this.maxVideoWidth = in.readInt();
this.maxVideoHeight = in.readInt();
this.maxVideoFrameRate = in.readInt();
this.maxVideoBitrate = in.readInt();
this.minVideoWidth = in.readInt();
this.minVideoHeight = in.readInt();
this.minVideoFrameRate = in.readInt();
this.minVideoBitrate = in.readInt();
this.exceedVideoConstraintsIfNecessary = Util.readBoolean(in);
this.allowVideoMixedMimeTypeAdaptiveness = Util.readBoolean(in);
this.allowVideoNonSeamlessAdaptiveness = Util.readBoolean(in);
this.viewportWidth = in.readInt();
this.viewportHeight = in.readInt();
this.viewportOrientationMayChange = Util.readBoolean(in);
ArrayList<String> preferredVideoMimeTypes = new ArrayList<>();
in.readList(preferredVideoMimeTypes, /* loader= */ null);
this.preferredVideoMimeTypes = ImmutableList.copyOf(preferredVideoMimeTypes);
// Audio
this.maxAudioChannelCount = in.readInt();
this.maxAudioBitrate = in.readInt();
this.exceedAudioConstraintsIfNecessary = Util.readBoolean(in);
this.allowAudioMixedMimeTypeAdaptiveness = Util.readBoolean(in);
this.allowAudioMixedSampleRateAdaptiveness = Util.readBoolean(in);
this.allowAudioMixedChannelCountAdaptiveness = Util.readBoolean(in);
ArrayList<String> preferredAudioMimeTypes = new ArrayList<>();
in.readList(preferredAudioMimeTypes, /* loader= */ null);
this.preferredAudioMimeTypes = ImmutableList.copyOf(preferredAudioMimeTypes);
// Text
this.disabledTextTrackSelectionFlags = in.readInt();
// General
this.forceLowestBitrate = Util.readBoolean(in);
this.forceHighestSupportedBitrate = Util.readBoolean(in);
this.exceedRendererCapabilitiesIfNecessary = Util.readBoolean(in);
this.tunnelingEnabled = Util.readBoolean(in);
this.allowMultipleAdaptiveSelections = Util.readBoolean(in);
@ -1259,11 +928,11 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
/** Creates a new {@link ParametersBuilder}, copying the initial values from this instance. */
@Override
public ParametersBuilder buildUpon() {
return new ParametersBuilder(this);
}
@SuppressWarnings("EqualsGetClass") // Class is not final for backward-compatibility reason.
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
@ -1273,35 +942,20 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return false;
}
Parameters other = (Parameters) obj;
return super.equals(obj)
return super.equals(other)
// Video
&& maxVideoWidth == other.maxVideoWidth
&& maxVideoHeight == other.maxVideoHeight
&& maxVideoFrameRate == other.maxVideoFrameRate
&& maxVideoBitrate == other.maxVideoBitrate
&& minVideoWidth == other.minVideoWidth
&& minVideoHeight == other.minVideoHeight
&& minVideoFrameRate == other.minVideoFrameRate
&& minVideoBitrate == other.minVideoBitrate
&& exceedVideoConstraintsIfNecessary == other.exceedVideoConstraintsIfNecessary
&& allowVideoMixedMimeTypeAdaptiveness == other.allowVideoMixedMimeTypeAdaptiveness
&& allowVideoNonSeamlessAdaptiveness == other.allowVideoNonSeamlessAdaptiveness
&& viewportOrientationMayChange == other.viewportOrientationMayChange
&& viewportWidth == other.viewportWidth
&& viewportHeight == other.viewportHeight
&& preferredVideoMimeTypes.equals(other.preferredVideoMimeTypes)
// Audio
&& maxAudioChannelCount == other.maxAudioChannelCount
&& maxAudioBitrate == other.maxAudioBitrate
&& exceedAudioConstraintsIfNecessary == other.exceedAudioConstraintsIfNecessary
&& allowAudioMixedMimeTypeAdaptiveness == other.allowAudioMixedMimeTypeAdaptiveness
&& allowAudioMixedSampleRateAdaptiveness == other.allowAudioMixedSampleRateAdaptiveness
&& allowAudioMixedChannelCountAdaptiveness
== other.allowAudioMixedChannelCountAdaptiveness
&& preferredAudioMimeTypes.equals(other.preferredAudioMimeTypes)
// Text
&& disabledTextTrackSelectionFlags == other.disabledTextTrackSelectionFlags
// General
&& forceLowestBitrate == other.forceLowestBitrate
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
&& exceedRendererCapabilitiesIfNecessary == other.exceedRendererCapabilitiesIfNecessary
&& tunnelingEnabled == other.tunnelingEnabled
&& allowMultipleAdaptiveSelections == other.allowMultipleAdaptiveSelections
@ -1312,34 +966,20 @@ public class DefaultTrackSelector extends MappingTrackSelector {
@Override
public int hashCode() {
int result = super.hashCode();
int result = 1;
result = 31 * result + super.hashCode();
// Video
result = 31 * result + maxVideoWidth;
result = 31 * result + maxVideoHeight;
result = 31 * result + maxVideoFrameRate;
result = 31 * result + maxVideoBitrate;
result = 31 * result + minVideoWidth;
result = 31 * result + minVideoHeight;
result = 31 * result + minVideoFrameRate;
result = 31 * result + minVideoBitrate;
result = 31 * result + (exceedVideoConstraintsIfNecessary ? 1 : 0);
result = 31 * result + (allowVideoMixedMimeTypeAdaptiveness ? 1 : 0);
result = 31 * result + (allowVideoNonSeamlessAdaptiveness ? 1 : 0);
result = 31 * result + (viewportOrientationMayChange ? 1 : 0);
result = 31 * result + viewportWidth;
result = 31 * result + viewportHeight;
result = 31 * result + preferredVideoMimeTypes.hashCode();
// Audio
result = 31 * result + maxAudioChannelCount;
result = 31 * result + maxAudioBitrate;
result = 31 * result + (exceedAudioConstraintsIfNecessary ? 1 : 0);
result = 31 * result + (allowAudioMixedMimeTypeAdaptiveness ? 1 : 0);
result = 31 * result + (allowAudioMixedSampleRateAdaptiveness ? 1 : 0);
result = 31 * result + (allowAudioMixedChannelCountAdaptiveness ? 1 : 0);
result = 31 * result + preferredAudioMimeTypes.hashCode();
// Text
result = 31 * result + disabledTextTrackSelectionFlags;
// General
result = 31 * result + (forceLowestBitrate ? 1 : 0);
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0);
result = 31 * result + (tunnelingEnabled ? 1 : 0);
result = 31 * result + (allowMultipleAdaptiveSelections ? 1 : 0);
@ -1358,32 +998,17 @@ public class DefaultTrackSelector extends MappingTrackSelector {
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
// Video
dest.writeInt(maxVideoWidth);
dest.writeInt(maxVideoHeight);
dest.writeInt(maxVideoFrameRate);
dest.writeInt(maxVideoBitrate);
dest.writeInt(minVideoWidth);
dest.writeInt(minVideoHeight);
dest.writeInt(minVideoFrameRate);
dest.writeInt(minVideoBitrate);
Util.writeBoolean(dest, exceedVideoConstraintsIfNecessary);
Util.writeBoolean(dest, allowVideoMixedMimeTypeAdaptiveness);
Util.writeBoolean(dest, allowVideoNonSeamlessAdaptiveness);
dest.writeInt(viewportWidth);
dest.writeInt(viewportHeight);
Util.writeBoolean(dest, viewportOrientationMayChange);
dest.writeList(preferredVideoMimeTypes);
// Audio
dest.writeInt(maxAudioChannelCount);
dest.writeInt(maxAudioBitrate);
Util.writeBoolean(dest, exceedAudioConstraintsIfNecessary);
Util.writeBoolean(dest, allowAudioMixedMimeTypeAdaptiveness);
Util.writeBoolean(dest, allowAudioMixedSampleRateAdaptiveness);
Util.writeBoolean(dest, allowAudioMixedChannelCountAdaptiveness);
dest.writeList(preferredAudioMimeTypes);
// Text
dest.writeInt(disabledTextTrackSelectionFlags);
// General
Util.writeBoolean(dest, forceLowestBitrate);
Util.writeBoolean(dest, forceHighestSupportedBitrate);
Util.writeBoolean(dest, exceedRendererCapabilitiesIfNecessary);
Util.writeBoolean(dest, tunnelingEnabled);
Util.writeBoolean(dest, allowMultipleAdaptiveSelections);
@ -1392,20 +1017,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
dest.writeSparseBooleanArray(rendererDisabledFlags);
}
public static final Parcelable.Creator<Parameters> CREATOR =
new Parcelable.Creator<Parameters>() {
@Override
public Parameters createFromParcel(Parcel in) {
return new Parameters(in);
}
@Override
public Parameters[] newArray(int size) {
return new Parameters[size];
}
};
// Static utility methods.
private static SparseArray<Map<TrackGroupArray, @NullableType SelectionOverride>>

View file

@ -1,406 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.trackselection;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.content.Context;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.accessibility.CaptioningManager;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Util;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Locale;
/** Constraint parameters for track selection. */
public class TrackSelectionParameters implements Parcelable {
/**
* A builder for {@link TrackSelectionParameters}. See the {@link TrackSelectionParameters}
* documentation for explanations of the parameters that can be configured using this builder.
*/
public static class Builder {
/* package */ ImmutableList<String> preferredAudioLanguages;
@C.RoleFlags /* package */ int preferredAudioRoleFlags;
/* package */ ImmutableList<String> preferredTextLanguages;
@C.RoleFlags /* package */ int preferredTextRoleFlags;
/* package */ boolean selectUndeterminedTextLanguage;
@C.SelectionFlags /* package */ int disabledTextTrackSelectionFlags;
/**
* Creates a builder with default initial values.
*
* @param context Any context.
*/
@SuppressWarnings({"deprecation", "nullness:method.invocation"})
public Builder(Context context) {
this();
setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(context);
}
/**
* @deprecated {@link Context} constraints will not be set when using this constructor. Use
* {@link #Builder(Context)} instead.
*/
@Deprecated
public Builder() {
preferredAudioLanguages = ImmutableList.of();
preferredAudioRoleFlags = 0;
preferredTextLanguages = ImmutableList.of();
preferredTextRoleFlags = 0;
selectUndeterminedTextLanguage = false;
disabledTextTrackSelectionFlags = 0;
}
/**
* @param initialValues The {@link TrackSelectionParameters} from which the initial values of
* the builder are obtained.
*/
/* package */ Builder(TrackSelectionParameters initialValues) {
preferredAudioLanguages = initialValues.preferredAudioLanguages;
preferredAudioRoleFlags = initialValues.preferredAudioRoleFlags;
preferredTextLanguages = initialValues.preferredTextLanguages;
preferredTextRoleFlags = initialValues.preferredTextRoleFlags;
selectUndeterminedTextLanguage = initialValues.selectUndeterminedTextLanguage;
disabledTextTrackSelectionFlags = initialValues.disabledTextTrackSelectionFlags;
}
/**
* Sets the preferred language for audio and forced text tracks.
*
* @param preferredAudioLanguage Preferred audio language as an IETF BCP 47 conformant tag, or
* {@code null} to select the default track, or the first track if there's no default.
* @return This builder.
*/
public Builder setPreferredAudioLanguage(@Nullable String preferredAudioLanguage) {
return preferredAudioLanguage == null
? setPreferredAudioLanguages()
: setPreferredAudioLanguages(preferredAudioLanguage);
}
/**
* Sets the preferred languages for audio and forced text tracks.
*
* @param preferredAudioLanguages Preferred audio languages as IETF BCP 47 conformant tags in
* order of preference, or an empty array to select the default track, or the first track if
* there's no default.
* @return This builder.
*/
public Builder setPreferredAudioLanguages(String... preferredAudioLanguages) {
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
for (String language : checkNotNull(preferredAudioLanguages)) {
listBuilder.add(Util.normalizeLanguageCode(checkNotNull(language)));
}
this.preferredAudioLanguages = listBuilder.build();
return this;
}
/**
* Sets the preferred {@link C.RoleFlags} for audio tracks.
*
* @param preferredAudioRoleFlags Preferred audio role flags.
* @return This builder.
*/
public Builder setPreferredAudioRoleFlags(@C.RoleFlags int preferredAudioRoleFlags) {
this.preferredAudioRoleFlags = preferredAudioRoleFlags;
return this;
}
/**
* Sets the preferred language and role flags for text tracks based on the accessibility
* settings of {@link CaptioningManager}.
*
* <p>Does nothing for API levels &lt; 19 or when the {@link CaptioningManager} is disabled.
*
* @param context A {@link Context}.
* @return This builder.
*/
public Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(
Context context) {
if (Util.SDK_INT >= 19) {
setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(context);
}
return this;
}
/**
* Sets the preferred language for text tracks.
*
* @param preferredTextLanguage Preferred text language as an IETF BCP 47 conformant tag, or
* {@code null} to select the default track if there is one, or no track otherwise.
* @return This builder.
*/
public Builder setPreferredTextLanguage(@Nullable String preferredTextLanguage) {
return preferredTextLanguage == null
? setPreferredTextLanguages()
: setPreferredTextLanguages(preferredTextLanguage);
}
/**
* Sets the preferred languages for text tracks.
*
* @param preferredTextLanguages Preferred text languages as IETF BCP 47 conformant tags in
* order of preference, or an empty array to select the default track if there is one, or no
* track otherwise.
* @return This builder.
*/
public Builder setPreferredTextLanguages(String... preferredTextLanguages) {
ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
for (String language : checkNotNull(preferredTextLanguages)) {
listBuilder.add(Util.normalizeLanguageCode(checkNotNull(language)));
}
this.preferredTextLanguages = listBuilder.build();
return this;
}
/**
* Sets the preferred {@link C.RoleFlags} for text tracks.
*
* @param preferredTextRoleFlags Preferred text role flags.
* @return This builder.
*/
public Builder setPreferredTextRoleFlags(@C.RoleFlags int preferredTextRoleFlags) {
this.preferredTextRoleFlags = preferredTextRoleFlags;
return this;
}
/**
* Sets whether a text track with undetermined language should be selected if no track with
* {@link #setPreferredTextLanguages(String...) a preferred language} is available, or if the
* preferred language is unset.
*
* @param selectUndeterminedTextLanguage Whether a text track with undetermined language should
* be selected if no preferred language track is available.
* @return This builder.
*/
public Builder setSelectUndeterminedTextLanguage(boolean selectUndeterminedTextLanguage) {
this.selectUndeterminedTextLanguage = selectUndeterminedTextLanguage;
return this;
}
/**
* Sets a bitmask of selection flags that are disabled for text track selections.
*
* @param disabledTextTrackSelectionFlags A bitmask of {@link C.SelectionFlags} that are
* disabled for text track selections.
* @return This builder.
*/
public Builder setDisabledTextTrackSelectionFlags(
@C.SelectionFlags int disabledTextTrackSelectionFlags) {
this.disabledTextTrackSelectionFlags = disabledTextTrackSelectionFlags;
return this;
}
/** Builds a {@link TrackSelectionParameters} instance with the selected values. */
public TrackSelectionParameters build() {
return new TrackSelectionParameters(
// Audio
preferredAudioLanguages,
preferredAudioRoleFlags,
// Text
preferredTextLanguages,
preferredTextRoleFlags,
selectUndeterminedTextLanguage,
disabledTextTrackSelectionFlags);
}
@RequiresApi(19)
private void setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(
Context context) {
if (Util.SDK_INT < 23 && Looper.myLooper() == null) {
// Android platform bug (pre-Marshmallow) that causes RuntimeExceptions when
// CaptioningService is instantiated from a non-Looper thread. See [internal: b/143779904].
return;
}
CaptioningManager captioningManager =
(CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
if (captioningManager == null || !captioningManager.isEnabled()) {
return;
}
preferredTextRoleFlags = C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND;
Locale preferredLocale = captioningManager.getLocale();
if (preferredLocale != null) {
preferredTextLanguages = ImmutableList.of(Util.getLocaleLanguageTag(preferredLocale));
}
}
}
/**
* An instance with default values, except those obtained from the {@link Context}.
*
* <p>If possible, use {@link #getDefaults(Context)} instead.
*
* <p>This instance will not have the following settings:
*
* <ul>
* <li>{@link Builder#setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(Context)
* Preferred text language and role flags} configured to the accessibility settings of
* {@link CaptioningManager}.
* </ul>
*/
@SuppressWarnings("deprecation")
public static final TrackSelectionParameters DEFAULT_WITHOUT_CONTEXT = new Builder().build();
/**
* @deprecated This instance is not configured using {@link Context} constraints. Use {@link
* #getDefaults(Context)} instead.
*/
@Deprecated public static final TrackSelectionParameters DEFAULT = DEFAULT_WITHOUT_CONTEXT;
/** Returns an instance configured with default values. */
public static TrackSelectionParameters getDefaults(Context context) {
return new Builder(context).build();
}
/**
* The preferred languages for audio and forced text tracks as IETF BCP 47 conformant tags in
* order of preference. An empty list selects the default track, or the first track if there's no
* default. The default value is an empty list.
*/
public final ImmutableList<String> preferredAudioLanguages;
/**
* The preferred {@link C.RoleFlags} for audio tracks. {@code 0} selects the default track if
* there is one, or the first track if there's no default. The default value is {@code 0}.
*/
@C.RoleFlags public final int preferredAudioRoleFlags;
/**
* The preferred languages for text tracks as IETF BCP 47 conformant tags in order of preference.
* An empty list selects the default track if there is one, or no track otherwise. The default
* value is an empty list, or the language of the accessibility {@link CaptioningManager} if
* enabled.
*/
public final ImmutableList<String> preferredTextLanguages;
/**
* The preferred {@link C.RoleFlags} for text tracks. {@code 0} selects the default track if there
* is one, or no track otherwise. The default value is {@code 0}, or {@link C#ROLE_FLAG_SUBTITLE}
* | {@link C#ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND} if the accessibility {@link CaptioningManager}
* is enabled.
*/
@C.RoleFlags public final int preferredTextRoleFlags;
/**
* Whether a text track with undetermined language should be selected if no track with {@link
* #preferredTextLanguages} is available, or if {@link #preferredTextLanguages} is unset. The
* default value is {@code false}.
*/
public final boolean selectUndeterminedTextLanguage;
/**
* Bitmask of selection flags that are disabled for text track selections. See {@link
* C.SelectionFlags}. The default value is {@code 0} (i.e. no flags).
*/
@C.SelectionFlags public final int disabledTextTrackSelectionFlags;
/* package */ TrackSelectionParameters(
ImmutableList<String> preferredAudioLanguages,
@C.RoleFlags int preferredAudioRoleFlags,
ImmutableList<String> preferredTextLanguages,
@C.RoleFlags int preferredTextRoleFlags,
boolean selectUndeterminedTextLanguage,
@C.SelectionFlags int disabledTextTrackSelectionFlags) {
// Audio
this.preferredAudioLanguages = preferredAudioLanguages;
this.preferredAudioRoleFlags = preferredAudioRoleFlags;
// Text
this.preferredTextLanguages = preferredTextLanguages;
this.preferredTextRoleFlags = preferredTextRoleFlags;
this.selectUndeterminedTextLanguage = selectUndeterminedTextLanguage;
this.disabledTextTrackSelectionFlags = disabledTextTrackSelectionFlags;
}
/* package */ TrackSelectionParameters(Parcel in) {
ArrayList<String> preferredAudioLanguages = new ArrayList<>();
in.readList(preferredAudioLanguages, /* loader= */ null);
this.preferredAudioLanguages = ImmutableList.copyOf(preferredAudioLanguages);
this.preferredAudioRoleFlags = in.readInt();
ArrayList<String> preferredTextLanguages = new ArrayList<>();
in.readList(preferredTextLanguages, /* loader= */ null);
this.preferredTextLanguages = ImmutableList.copyOf(preferredTextLanguages);
this.preferredTextRoleFlags = in.readInt();
this.selectUndeterminedTextLanguage = Util.readBoolean(in);
this.disabledTextTrackSelectionFlags = in.readInt();
}
/** Creates a new {@link Builder}, copying the initial values from this instance. */
public Builder buildUpon() {
return new Builder(this);
}
@Override
@SuppressWarnings("EqualsGetClass")
public boolean equals(@Nullable Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
TrackSelectionParameters other = (TrackSelectionParameters) obj;
return preferredAudioLanguages.equals(other.preferredAudioLanguages)
&& preferredAudioRoleFlags == other.preferredAudioRoleFlags
&& preferredTextLanguages.equals(other.preferredTextLanguages)
&& preferredTextRoleFlags == other.preferredTextRoleFlags
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
&& disabledTextTrackSelectionFlags == other.disabledTextTrackSelectionFlags;
}
@Override
public int hashCode() {
int result = 1;
result = 31 * result + preferredAudioLanguages.hashCode();
result = 31 * result + preferredAudioRoleFlags;
result = 31 * result + preferredTextLanguages.hashCode();
result = 31 * result + preferredTextRoleFlags;
result = 31 * result + (selectUndeterminedTextLanguage ? 1 : 0);
result = 31 * result + disabledTextTrackSelectionFlags;
return result;
}
// Parcelable implementation.
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(preferredAudioLanguages);
dest.writeInt(preferredAudioRoleFlags);
dest.writeList(preferredTextLanguages);
dest.writeInt(preferredTextRoleFlags);
Util.writeBoolean(dest, selectUndeterminedTextLanguage);
dest.writeInt(disabledTextTrackSelectionFlags);
}
public static final Creator<TrackSelectionParameters> CREATOR =
new Creator<TrackSelectionParameters>() {
@Override
public TrackSelectionParameters createFromParcel(Parcel in) {
return new TrackSelectionParameters(in);
}
@Override
public TrackSelectionParameters[] newArray(int size) {
return new TrackSelectionParameters[size];
}
};
}

View file

@ -30,8 +30,6 @@ import static org.mockito.MockitoAnnotations.initMocks;
import android.content.Context;
import android.os.Parcel;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
@ -51,7 +49,6 @@ import com.google.android.exoplayer2.trackselection.TrackSelector.InvalidationLi
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.ImmutableList;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
@ -1725,55 +1722,50 @@ public final class DefaultTrackSelectorTest {
* variables.
*/
private static Parameters buildParametersForEqualsTest() {
SparseArray<Map<TrackGroupArray, SelectionOverride>> selectionOverrides = new SparseArray<>();
Map<TrackGroupArray, SelectionOverride> videoOverrides = new HashMap<>();
videoOverrides.put(new TrackGroupArray(VIDEO_TRACK_GROUP), new SelectionOverride(0, 1));
selectionOverrides.put(2, videoOverrides);
SparseBooleanArray rendererDisabledFlags = new SparseBooleanArray();
rendererDisabledFlags.put(3, true);
return new Parameters(
return Parameters.DEFAULT_WITHOUT_CONTEXT
.buildUpon()
// Video
/* maxVideoWidth= */ 0,
/* maxVideoHeight= */ 1,
/* maxVideoFrameRate= */ 2,
/* maxVideoBitrate= */ 3,
/* minVideoWidth= */ 4,
/* minVideoHeight= */ 5,
/* minVideoFrameRate= */ 6,
/* minVideoBitrate= */ 7,
/* exceedVideoConstraintsIfNecessary= */ false,
/* allowVideoMixedMimeTypeAdaptiveness= */ true,
/* allowVideoNonSeamlessAdaptiveness= */ false,
/* viewportWidth= */ 8,
/* viewportHeight= */ 9,
/* viewportOrientationMayChange= */ true,
/* preferredVideoMimeTypes= */ ImmutableList.of(MimeTypes.VIDEO_AV1, MimeTypes.VIDEO_H264),
.setMaxVideoSize(/* maxVideoWidth= */ 0, /* maxVideoHeight= */ 1)
.setMaxVideoFrameRate(2)
.setMaxVideoBitrate(3)
.setMinVideoSize(/* minVideoWidth= */ 4, /* minVideoHeight= */ 5)
.setMinVideoFrameRate(6)
.setMinVideoBitrate(7)
.setExceedVideoConstraintsIfNecessary(false)
.setAllowVideoMixedMimeTypeAdaptiveness(true)
.setAllowVideoNonSeamlessAdaptiveness(false)
.setViewportSize(
/* viewportWidth= */ 8,
/* viewportHeight= */ 9,
/* viewportOrientationMayChange= */ true)
.setPreferredVideoMimeTypes(MimeTypes.VIDEO_AV1, MimeTypes.VIDEO_H264)
// Audio
/* preferredAudioLanguages= */ ImmutableList.of("zh", "jp"),
/* preferredAudioRoleFlags= */ C.ROLE_FLAG_COMMENTARY,
/* maxAudioChannelCount= */ 10,
/* maxAudioBitrate= */ 11,
/* exceedAudioConstraintsIfNecessary= */ false,
/* allowAudioMixedMimeTypeAdaptiveness= */ true,
/* allowAudioMixedSampleRateAdaptiveness= */ false,
/* allowAudioMixedChannelCountAdaptiveness= */ true,
/* preferredAudioMimeTypes= */ ImmutableList.of(MimeTypes.AUDIO_AC3, MimeTypes.AUDIO_E_AC3),
.setPreferredAudioLanguages("zh", "jp")
.setPreferredAudioRoleFlags(C.ROLE_FLAG_COMMENTARY)
.setMaxAudioChannelCount(10)
.setMaxAudioBitrate(11)
.setExceedAudioConstraintsIfNecessary(false)
.setAllowAudioMixedMimeTypeAdaptiveness(true)
.setAllowAudioMixedSampleRateAdaptiveness(false)
.setAllowAudioMixedChannelCountAdaptiveness(true)
.setPreferredAudioMimeTypes(MimeTypes.AUDIO_AC3, MimeTypes.AUDIO_E_AC3)
// Text
/* preferredTextLanguages= */ ImmutableList.of("de", "en"),
/* preferredTextRoleFlags= */ C.ROLE_FLAG_CAPTION,
/* selectUndeterminedTextLanguage= */ true,
/* disabledTextTrackSelectionFlags= */ C.SELECTION_FLAG_AUTOSELECT,
.setPreferredTextLanguages("de", "en")
.setPreferredTextRoleFlags(C.ROLE_FLAG_CAPTION)
.setSelectUndeterminedTextLanguage(true)
.setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_AUTOSELECT)
// General
/* forceLowestBitrate= */ false,
/* forceHighestSupportedBitrate= */ true,
/* exceedRendererCapabilitiesIfNecessary= */ false,
/* tunnelingEnabled= */ true,
/* allowMultipleAdaptiveSelections= */ true,
// Overrides
selectionOverrides,
rendererDisabledFlags);
.setForceLowestBitrate(false)
.setForceHighestSupportedBitrate(true)
.setExceedRendererCapabilitiesIfNecessary(false)
.setTunnelingEnabled(true)
.setAllowMultipleAdaptiveSelections(true)
.setSelectionOverride(
/* rendererIndex= */ 2,
new TrackGroupArray(VIDEO_TRACK_GROUP),
new SelectionOverride(0, 1))
.setRendererDisabled(3, true)
.build();
}
/**