Commit df862782 by Oliver Woodman

Merge pull request #7451 from szaboa:dev-v2-4511

PiperOrigin-RevId: 315995776
parents 5612ac50 a1ebffd2
......@@ -4,7 +4,6 @@
* Core library:
* Implement getTag for SilenceMediaSource.
* Add `Player.getTrackSelector` to access track selector from UI module.
* Added `TextComponent.getCurrentCues` because the current cues are no
longer forwarded to a new `TextOutput` in `SimpleExoPlayer`
automatically.
......@@ -76,7 +75,6 @@
`DecoderVideoRenderer` and `DecoderAudioRenderer` respectively, and
generalized to work with `Decoder` rather than `SimpleDecoder`.
* Add media item based playlist API to Player.
* Remove deprecated members in `DefaultTrackSelector`.
* Add `Player.DeviceComponent` and implement it for `SimpleExoPlayer` so
that the device volume can be controlled by player.
* Parse track titles from Matroska files
......@@ -92,6 +90,12 @@
ongoing load should be canceled. Only supported by HLS streams so far.
([#2848](https://github.com/google/ExoPlayer/issues/2848)).
* Video: Pass frame rate hint to `Surface.setFrameRate` on Android R devices.
* Track selection:
* Add `Player.getTrackSelector`.
* Remove deprecated members in `DefaultTrackSelector`.
* Add `DefaultTrackSelector` constraints for minimum video resolution,
bitrate and frame rate
([#4511](https://github.com/google/ExoPlayer/issues/4511)).
* Text:
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
later).
......
......@@ -169,6 +169,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
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;
......@@ -230,6 +234,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
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;
......@@ -310,8 +318,43 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
/**
* Sets whether to exceed the {@link #setMaxVideoSize(int, int)} and {@link
* #setMaxAudioBitrate(int)} constraints when no selection can be made otherwise.
* 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;
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;
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;
return this;
}
/**
* Sets whether to exceed the {@link #setMaxVideoBitrate}, {@link #setMaxVideoSize(int, int)}
* and {@link #setMaxVideoFrameRate} constraints when no selection can be made otherwise.
*
* @param exceedVideoConstraintsIfNecessary Whether to exceed video constraints when no
* selection can be made otherwise.
......@@ -712,6 +755,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
maxVideoHeight,
maxVideoFrameRate,
maxVideoBitrate,
minVideoWidth,
minVideoHeight,
minVideoFrameRate,
minVideoBitrate,
exceedVideoConstraintsIfNecessary,
allowVideoMixedMimeTypeAdaptiveness,
allowVideoNonSeamlessAdaptiveness,
......@@ -837,6 +884,17 @@ public class DefaultTrackSelector extends MappingTrackSelector {
* 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
......@@ -945,6 +1003,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
int maxVideoHeight,
int maxVideoFrameRate,
int maxVideoBitrate,
int minVideoWidth,
int minVideoHeight,
int minVideoFrameRate,
int minVideoBitrate,
boolean exceedVideoConstraintsIfNecessary,
boolean allowVideoMixedMimeTypeAdaptiveness,
boolean allowVideoNonSeamlessAdaptiveness,
......@@ -983,6 +1045,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
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;
......@@ -1014,6 +1080,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
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);
......@@ -1095,6 +1165,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
&& 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
......@@ -1127,6 +1201,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
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);
......@@ -1164,6 +1242,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
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);
......@@ -1407,7 +1489,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*/
private static final float FRACTION_TO_CONSIDER_FULLSCREEN = 0.98f;
private static final int[] NO_TRACKS = new int[0];
// Constants that are added to a track's score when certain conditions are met. Higher scoring
// tracks are selected over those with lower scores.
private static final int WITHIN_RENDERER_CAPABILITIES_BONUS = 1000;
private static final int SATISFIES_MIN_VIDEO_CONSTRAINTS_BONUS = 1;
private static final int SATISFIES_MAX_VIDEO_CONSTRAINTS_BONUS = 2;
private final TrackSelection.Factory trackSelectionFactory;
private final AtomicReference<Parameters> parametersReference;
......@@ -1751,6 +1838,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
params.maxVideoHeight,
params.maxVideoFrameRate,
params.maxVideoBitrate,
params.minVideoWidth,
params.minVideoHeight,
params.minVideoFrameRate,
params.minVideoBitrate,
params.viewportWidth,
params.viewportHeight,
params.viewportOrientationMayChange);
......@@ -1770,6 +1861,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
int maxVideoHeight,
int maxVideoFrameRate,
int maxVideoBitrate,
int minVideoWidth,
int minVideoHeight,
int minVideoFrameRate,
int minVideoBitrate,
int viewportWidth,
int viewportHeight,
boolean viewportOrientationMayChange) {
......@@ -1802,6 +1897,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
maxVideoHeight,
maxVideoFrameRate,
maxVideoBitrate,
minVideoWidth,
minVideoHeight,
minVideoFrameRate,
minVideoBitrate,
selectedTrackIndices);
if (countForMimeType > selectedMimeTypeTrackCount) {
selectedMimeType = sampleMimeType;
......@@ -1821,6 +1920,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
maxVideoHeight,
maxVideoFrameRate,
maxVideoBitrate,
minVideoWidth,
minVideoHeight,
minVideoFrameRate,
minVideoBitrate,
selectedTrackIndices);
return selectedTrackIndices.size() < 2 ? NO_TRACKS : Ints.toArray(selectedTrackIndices);
......@@ -1835,6 +1938,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
int maxVideoHeight,
int maxVideoFrameRate,
int maxVideoBitrate,
int minVideoWidth,
int minVideoHeight,
int minVideoFrameRate,
int minVideoBitrate,
List<Integer> selectedTrackIndices) {
int adaptiveTrackCount = 0;
for (int i = 0; i < selectedTrackIndices.size(); i++) {
......@@ -1847,7 +1954,11 @@ public class DefaultTrackSelector extends MappingTrackSelector {
maxVideoWidth,
maxVideoHeight,
maxVideoFrameRate,
maxVideoBitrate)) {
maxVideoBitrate,
minVideoWidth,
minVideoHeight,
minVideoFrameRate,
minVideoBitrate)) {
adaptiveTrackCount++;
}
}
......@@ -1863,6 +1974,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
int maxVideoHeight,
int maxVideoFrameRate,
int maxVideoBitrate,
int minVideoWidth,
int minVideoHeight,
int minVideoFrameRate,
int minVideoBitrate,
List<Integer> selectedTrackIndices) {
for (int i = selectedTrackIndices.size() - 1; i >= 0; i--) {
int trackIndex = selectedTrackIndices.get(i);
......@@ -1874,7 +1989,11 @@ public class DefaultTrackSelector extends MappingTrackSelector {
maxVideoWidth,
maxVideoHeight,
maxVideoFrameRate,
maxVideoBitrate)) {
maxVideoBitrate,
minVideoWidth,
minVideoHeight,
minVideoFrameRate,
minVideoBitrate)) {
selectedTrackIndices.remove(i);
}
}
......@@ -1888,24 +2007,32 @@ public class DefaultTrackSelector extends MappingTrackSelector {
int maxVideoWidth,
int maxVideoHeight,
int maxVideoFrameRate,
int maxVideoBitrate) {
int maxVideoBitrate,
int minVideoWidth,
int minVideoHeight,
int minVideoFrameRate,
int minVideoBitrate) {
if ((format.roleFlags & C.ROLE_FLAG_TRICK_PLAY) != 0) {
// Ignore trick-play tracks for now.
return false;
}
return isSupported(formatSupport, false)
return isSupported(formatSupport, /* allowExceedsCapabilities= */ false)
&& ((formatSupport & requiredAdaptiveSupport) != 0)
&& (mimeType == null || Util.areEqual(format.sampleMimeType, mimeType))
&& (format.width == Format.NO_VALUE || format.width <= maxVideoWidth)
&& (format.height == Format.NO_VALUE || format.height <= maxVideoHeight)
&& (format.frameRate == Format.NO_VALUE || format.frameRate <= maxVideoFrameRate)
&& (format.bitrate == Format.NO_VALUE || format.bitrate <= maxVideoBitrate);
&& (format.width == Format.NO_VALUE
|| (minVideoWidth <= format.width && format.width <= maxVideoWidth))
&& (format.height == Format.NO_VALUE
|| (minVideoHeight <= format.height && format.height <= maxVideoHeight))
&& (format.frameRate == Format.NO_VALUE
|| (minVideoFrameRate <= format.frameRate && format.frameRate <= maxVideoFrameRate))
&& (format.bitrate == Format.NO_VALUE
|| (minVideoBitrate <= format.bitrate && format.bitrate <= maxVideoBitrate));
}
@Nullable
private static TrackSelection.Definition selectFixedVideoTrack(
TrackGroupArray groups, @Capabilities int[][] formatSupports, Parameters params) {
TrackGroup selectedGroup = null;
@Nullable TrackGroup selectedGroup = null;
int selectedTrackIndex = 0;
int selectedTrackScore = 0;
int selectedBitrate = Format.NO_VALUE;
......@@ -1923,7 +2050,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
}
if (isSupported(trackFormatSupport[trackIndex],
params.exceedRendererCapabilitiesIfNecessary)) {
boolean isWithinConstraints =
boolean satisfiesMaxConstraints =
selectedTrackIndices.contains(trackIndex)
&& (format.width == Format.NO_VALUE || format.width <= params.maxVideoWidth)
&& (format.height == Format.NO_VALUE || format.height <= params.maxVideoHeight)
......@@ -1931,32 +2058,62 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|| format.frameRate <= params.maxVideoFrameRate)
&& (format.bitrate == Format.NO_VALUE
|| format.bitrate <= params.maxVideoBitrate);
if (!isWithinConstraints && !params.exceedVideoConstraintsIfNecessary) {
boolean satisfiesMinConstraints =
selectedTrackIndices.contains(trackIndex)
&& (format.width == Format.NO_VALUE || format.width >= params.minVideoWidth)
&& (format.height == Format.NO_VALUE || format.height >= params.minVideoHeight)
&& (format.frameRate == Format.NO_VALUE
|| format.frameRate >= params.minVideoFrameRate)
&& (format.bitrate == Format.NO_VALUE
|| format.bitrate >= params.minVideoBitrate);
if (!satisfiesMaxConstraints && !params.exceedVideoConstraintsIfNecessary) {
// Track should not be selected.
continue;
}
int trackScore = isWithinConstraints ? 2 : 1;
int trackScore = 1;
boolean isWithinCapabilities = isSupported(trackFormatSupport[trackIndex], false);
if (isWithinCapabilities) {
trackScore += WITHIN_RENDERER_CAPABILITIES_BONUS;
}
if (satisfiesMaxConstraints) {
trackScore += SATISFIES_MAX_VIDEO_CONSTRAINTS_BONUS;
}
if (satisfiesMinConstraints) {
trackScore += SATISFIES_MIN_VIDEO_CONSTRAINTS_BONUS;
}
boolean selectTrack = trackScore > selectedTrackScore;
if (trackScore == selectedTrackScore) {
// The current selection and the track being evaluated have the same score. Apply
// tiebreaking logic to choose between them.
int bitrateComparison = compareFormatValues(format.bitrate, selectedBitrate);
if (params.forceLowestBitrate && bitrateComparison != 0) {
// Use bitrate as a tie breaker, preferring the lower bitrate.
// Use bitrate as a tiebreaker, preferring the lower bitrate.
selectTrack = bitrateComparison < 0;
} else {
// Use the pixel count as a tie breaker (or bitrate if pixel counts are tied). If
// we're within constraints prefer a higher pixel count (or bitrate), else prefer a
// lower count (or bitrate). If still tied then prefer the first track (i.e. the one
// that's already selected).
// Use pixel count as a tiebreaker, followed by bitrate if pixel counts are equal.
int formatPixelCount = format.getPixelCount();
int comparisonResult = formatPixelCount != selectedPixelCount
? compareFormatValues(formatPixelCount, selectedPixelCount)
: compareFormatValues(format.bitrate, selectedBitrate);
selectTrack = isWithinCapabilities && isWithinConstraints
? comparisonResult > 0 : comparisonResult < 0;
if (!isWithinCapabilities) {
// We're not within capabilities, so pick the lower quality because it's more likely
// to play successfully.
selectTrack = comparisonResult < 0;
} else if (satisfiesMinConstraints && satisfiesMaxConstraints) {
// All constraints are satisfied, so pick the higher quality.
selectTrack = comparisonResult > 0;
} else if (!satisfiesMinConstraints && satisfiesMaxConstraints) {
// Pick the higher quality because it gets us closest to satisfying the violated min
// constraints.
selectTrack = comparisonResult > 0;
} else if (satisfiesMinConstraints) { // !satisfiesMaxConstraints
// Pick the lower quality because it gets us closest to satisfying the violated max
// constraints.
selectTrack = comparisonResult > 0;
} else { // !satisfiesMinConstraints && !satisfiesMaxConstraints
// Arbitrarily pick the lower quality.
selectTrack = comparisonResult < 0;
}
}
}
if (selectTrack) {
......
......@@ -131,51 +131,16 @@ public final class DefaultTrackSelectorTest {
trackSelector.init(invalidationListener, bandwidthMeter);
}
/** Tests {@link Parameters} {@link android.os.Parcelable} implementation. */
@Test
public void parametersParcelable() {
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);
public void parameters_buildUponThenBuild_isEqual() {
Parameters parameters = buildParametersForEqualsTest();
assertThat(parameters.buildUpon().build()).isEqualTo(parameters);
}
Parameters parametersToParcel =
new Parameters(
// Video
/* maxVideoWidth= */ 0,
/* maxVideoHeight= */ 1,
/* maxVideoFrameRate= */ 2,
/* maxVideoBitrate= */ 3,
/* exceedVideoConstraintsIfNecessary= */ false,
/* allowVideoMixedMimeTypeAdaptiveness= */ true,
/* allowVideoNonSeamlessAdaptiveness= */ false,
/* viewportWidth= */ 4,
/* viewportHeight= */ 5,
/* viewportOrientationMayChange= */ true,
// Audio
/* preferredAudioLanguage= */ "en",
/* maxAudioChannelCount= */ 6,
/* maxAudioBitrate= */ 7,
/* exceedAudioConstraintsIfNecessary= */ false,
/* allowAudioMixedMimeTypeAdaptiveness= */ true,
/* allowAudioMixedSampleRateAdaptiveness= */ false,
/* allowAudioMixedChannelCountAdaptiveness= */ true,
// Text
/* preferredTextLanguage= */ "de",
/* preferredTextRoleFlags= */ C.ROLE_FLAG_CAPTION,
/* selectUndeterminedTextLanguage= */ true,
/* disabledTextTrackSelectionFlags= */ 8,
// General
/* forceLowestBitrate= */ false,
/* forceHighestSupportedBitrate= */ true,
/* exceedRendererCapabilitiesIfNecessary= */ false,
/* tunnelingAudioSessionId= */ C.AUDIO_SESSION_ID_UNSET,
// Overrides
selectionOverrides,
rendererDisabledFlags);
/** Tests {@link Parameters} {@link android.os.Parcelable} implementation. */
@Test
public void parameters_parcelAndUnParcelable() {
Parameters parametersToParcel = buildParametersForEqualsTest();
Parcel parcel = Parcel.obtain();
parametersToParcel.writeToParcel(parcel, 0);
......@@ -1511,6 +1476,61 @@ public final class DefaultTrackSelectorTest {
}
/**
* Returns {@link Parameters} suitable for simple round trip equality tests.
*
* <p>Primitive variables are set to different values (to the extent that this is possible), to
* increase the probability of such tests failing if they accidentally compare mismatched
* 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(
// 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,
// Audio
/* preferredAudioLanguage= */ "en",
/* maxAudioChannelCount= */ 10,
/* maxAudioBitrate= */ 11,
/* exceedAudioConstraintsIfNecessary= */ false,
/* allowAudioMixedMimeTypeAdaptiveness= */ true,
/* allowAudioMixedSampleRateAdaptiveness= */ false,
/* allowAudioMixedChannelCountAdaptiveness= */ true,
// Text
/* preferredTextLanguage= */ "de",
/* preferredTextRoleFlags= */ C.ROLE_FLAG_CAPTION,
/* selectUndeterminedTextLanguage= */ true,
/* disabledTextTrackSelectionFlags= */ 12,
// General
/* forceLowestBitrate= */ false,
/* forceHighestSupportedBitrate= */ true,
/* exceedRendererCapabilitiesIfNecessary= */ false,
/* tunnelingAudioSessionId= */ 13,
// Overrides
selectionOverrides,
rendererDisabledFlags);
}
/**
* A {@link RendererCapabilities} that advertises support for all formats of a given type using
* a provided support value. For any format that does not have the given track type,
* {@link #supportsFormat(Format)} will return {@link #FORMAT_UNSUPPORTED_TYPE}.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment