mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add options for controlling audio track selection
Issue: #3314 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=219158729
This commit is contained in:
parent
069e3cbf7d
commit
7eeeb40d24
@ -6,6 +6,8 @@
|
|||||||
here ([#2826](https://github.com/google/ExoPlayer/issues/2826)).
|
here ([#2826](https://github.com/google/ExoPlayer/issues/2826)).
|
||||||
* Improve initial bandwidth meter estimates using the current country and
|
* Improve initial bandwidth meter estimates using the current country and
|
||||||
network type.
|
network type.
|
||||||
|
* Add options for controlling audio track selections to `DefaultTrackSelector`
|
||||||
|
([#3314](https://github.com/google/ExoPlayer/issues/3314)).
|
||||||
* Do not retry failed loads whose error is `FileNotFoundException`.
|
* Do not retry failed loads whose error is `FileNotFoundException`.
|
||||||
* Add convenience methods `Player.next`, `Player.previous`, `Player.hasNext`
|
* Add convenience methods `Player.next`, `Player.previous`, `Player.hasNext`
|
||||||
and `Player.hasPrevious`
|
and `Player.hasPrevious`
|
||||||
|
@ -170,11 +170,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
private int maxVideoFrameRate;
|
private int maxVideoFrameRate;
|
||||||
private int maxVideoBitrate;
|
private int maxVideoBitrate;
|
||||||
private boolean exceedVideoConstraintsIfNecessary;
|
private boolean exceedVideoConstraintsIfNecessary;
|
||||||
|
private boolean allowVideoMixedMimeTypeAdaptiveness;
|
||||||
|
private boolean allowVideoNonSeamlessAdaptiveness;
|
||||||
private int viewportWidth;
|
private int viewportWidth;
|
||||||
private int viewportHeight;
|
private int viewportHeight;
|
||||||
private boolean viewportOrientationMayChange;
|
private boolean viewportOrientationMayChange;
|
||||||
// Audio
|
// Audio
|
||||||
@Nullable private String preferredAudioLanguage;
|
@Nullable private String preferredAudioLanguage;
|
||||||
|
private int maxAudioChannelCount;
|
||||||
|
private int maxAudioBitrate;
|
||||||
|
private boolean exceedAudioConstraintsIfNecessary;
|
||||||
|
private boolean allowAudioMixedMimeTypeAdaptiveness;
|
||||||
|
private boolean allowAudioMixedSampleRateAdaptiveness;
|
||||||
// Text
|
// Text
|
||||||
@Nullable private String preferredTextLanguage;
|
@Nullable private String preferredTextLanguage;
|
||||||
private boolean selectUndeterminedTextLanguage;
|
private boolean selectUndeterminedTextLanguage;
|
||||||
@ -182,8 +189,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
private boolean forceLowestBitrate;
|
private boolean forceLowestBitrate;
|
||||||
private boolean forceHighestSupportedBitrate;
|
private boolean forceHighestSupportedBitrate;
|
||||||
private boolean allowMixedMimeAdaptiveness;
|
|
||||||
private boolean allowNonSeamlessAdaptiveness;
|
|
||||||
private boolean exceedRendererCapabilitiesIfNecessary;
|
private boolean exceedRendererCapabilitiesIfNecessary;
|
||||||
private int tunnelingAudioSessionId;
|
private int tunnelingAudioSessionId;
|
||||||
|
|
||||||
@ -203,11 +208,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
maxVideoFrameRate = initialValues.maxVideoFrameRate;
|
maxVideoFrameRate = initialValues.maxVideoFrameRate;
|
||||||
maxVideoBitrate = initialValues.maxVideoBitrate;
|
maxVideoBitrate = initialValues.maxVideoBitrate;
|
||||||
exceedVideoConstraintsIfNecessary = initialValues.exceedVideoConstraintsIfNecessary;
|
exceedVideoConstraintsIfNecessary = initialValues.exceedVideoConstraintsIfNecessary;
|
||||||
|
allowVideoMixedMimeTypeAdaptiveness = initialValues.allowVideoMixedMimeTypeAdaptiveness;
|
||||||
|
allowVideoNonSeamlessAdaptiveness = initialValues.allowVideoNonSeamlessAdaptiveness;
|
||||||
viewportWidth = initialValues.viewportWidth;
|
viewportWidth = initialValues.viewportWidth;
|
||||||
viewportHeight = initialValues.viewportHeight;
|
viewportHeight = initialValues.viewportHeight;
|
||||||
viewportOrientationMayChange = initialValues.viewportOrientationMayChange;
|
viewportOrientationMayChange = initialValues.viewportOrientationMayChange;
|
||||||
// Audio
|
// Audio
|
||||||
preferredAudioLanguage = initialValues.preferredAudioLanguage;
|
preferredAudioLanguage = initialValues.preferredAudioLanguage;
|
||||||
|
maxAudioChannelCount = initialValues.maxAudioChannelCount;
|
||||||
|
maxAudioBitrate = initialValues.maxAudioBitrate;
|
||||||
|
exceedAudioConstraintsIfNecessary = initialValues.exceedAudioConstraintsIfNecessary;
|
||||||
|
allowAudioMixedMimeTypeAdaptiveness = initialValues.allowAudioMixedMimeTypeAdaptiveness;
|
||||||
|
allowAudioMixedSampleRateAdaptiveness = initialValues.allowAudioMixedSampleRateAdaptiveness;
|
||||||
// Text
|
// Text
|
||||||
preferredTextLanguage = initialValues.preferredTextLanguage;
|
preferredTextLanguage = initialValues.preferredTextLanguage;
|
||||||
selectUndeterminedTextLanguage = initialValues.selectUndeterminedTextLanguage;
|
selectUndeterminedTextLanguage = initialValues.selectUndeterminedTextLanguage;
|
||||||
@ -215,8 +227,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
forceLowestBitrate = initialValues.forceLowestBitrate;
|
forceLowestBitrate = initialValues.forceLowestBitrate;
|
||||||
forceHighestSupportedBitrate = initialValues.forceHighestSupportedBitrate;
|
forceHighestSupportedBitrate = initialValues.forceHighestSupportedBitrate;
|
||||||
allowMixedMimeAdaptiveness = initialValues.allowMixedMimeAdaptiveness;
|
|
||||||
allowNonSeamlessAdaptiveness = initialValues.allowNonSeamlessAdaptiveness;
|
|
||||||
exceedRendererCapabilitiesIfNecessary = initialValues.exceedRendererCapabilitiesIfNecessary;
|
exceedRendererCapabilitiesIfNecessary = initialValues.exceedRendererCapabilitiesIfNecessary;
|
||||||
tunnelingAudioSessionId = initialValues.tunnelingAudioSessionId;
|
tunnelingAudioSessionId = initialValues.tunnelingAudioSessionId;
|
||||||
// Overrides
|
// Overrides
|
||||||
@ -286,6 +296,28 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link Parameters#allowVideoMixedMimeTypeAdaptiveness}.
|
||||||
|
*
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public ParametersBuilder setAllowVideoMixedMimeTypeAdaptiveness(
|
||||||
|
boolean allowVideoMixedMimeTypeAdaptiveness) {
|
||||||
|
this.allowVideoMixedMimeTypeAdaptiveness = allowVideoMixedMimeTypeAdaptiveness;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link Parameters#allowVideoNonSeamlessAdaptiveness}.
|
||||||
|
*
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public ParametersBuilder setAllowVideoNonSeamlessAdaptiveness(
|
||||||
|
boolean allowVideoNonSeamlessAdaptiveness) {
|
||||||
|
this.allowVideoNonSeamlessAdaptiveness = allowVideoNonSeamlessAdaptiveness;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Equivalent to calling {@link #setViewportSize(int, int, boolean)} with the viewport size
|
* Equivalent to calling {@link #setViewportSize(int, int, boolean)} with the viewport size
|
||||||
* obtained from {@link Util#getPhysicalDisplaySize(Context)}.
|
* obtained from {@link Util#getPhysicalDisplaySize(Context)}.
|
||||||
@ -340,6 +372,59 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link Parameters#maxAudioChannelCount}.
|
||||||
|
*
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public ParametersBuilder setMaxAudioChannelCount(int maxAudioChannelCount) {
|
||||||
|
this.maxAudioChannelCount = maxAudioChannelCount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link Parameters#maxAudioBitrate}.
|
||||||
|
*
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public ParametersBuilder setMaxAudioBitrate(int maxAudioBitrate) {
|
||||||
|
this.maxAudioBitrate = maxAudioBitrate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link Parameters#exceedAudioConstraintsIfNecessary}.
|
||||||
|
*
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public ParametersBuilder setExceedAudioConstraintsIfNecessary(
|
||||||
|
boolean exceedAudioConstraintsIfNecessary) {
|
||||||
|
this.exceedAudioConstraintsIfNecessary = exceedAudioConstraintsIfNecessary;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link Parameters#allowAudioMixedMimeTypeAdaptiveness}.
|
||||||
|
*
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public ParametersBuilder setAllowAudioMixedMimeTypeAdaptiveness(
|
||||||
|
boolean allowAudioMixedMimeTypeAdaptiveness) {
|
||||||
|
this.allowAudioMixedMimeTypeAdaptiveness = allowAudioMixedMimeTypeAdaptiveness;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See {@link Parameters#allowAudioMixedSampleRateAdaptiveness}.
|
||||||
|
*
|
||||||
|
* @return This builder.
|
||||||
|
*/
|
||||||
|
public ParametersBuilder setAllowAudioMixedSampleRateAdaptiveness(
|
||||||
|
boolean allowAudioMixedSampleRateAdaptiveness) {
|
||||||
|
this.allowAudioMixedSampleRateAdaptiveness = allowAudioMixedSampleRateAdaptiveness;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -397,23 +482,20 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See {@link Parameters#allowMixedMimeAdaptiveness}.
|
* @deprecated Use {@link #setAllowVideoMixedMimeTypeAdaptiveness(boolean)} and {@link
|
||||||
*
|
* #setAllowAudioMixedMimeTypeAdaptiveness(boolean)}.
|
||||||
* @return This builder.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public ParametersBuilder setAllowMixedMimeAdaptiveness(boolean allowMixedMimeAdaptiveness) {
|
public ParametersBuilder setAllowMixedMimeAdaptiveness(boolean allowMixedMimeAdaptiveness) {
|
||||||
this.allowMixedMimeAdaptiveness = allowMixedMimeAdaptiveness;
|
setAllowAudioMixedMimeTypeAdaptiveness(allowMixedMimeAdaptiveness);
|
||||||
|
setAllowVideoMixedMimeTypeAdaptiveness(allowMixedMimeAdaptiveness);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @deprecated Use {@link #setAllowVideoNonSeamlessAdaptiveness(boolean)} */
|
||||||
* See {@link Parameters#allowNonSeamlessAdaptiveness}.
|
@Deprecated
|
||||||
*
|
|
||||||
* @return This builder.
|
|
||||||
*/
|
|
||||||
public ParametersBuilder setAllowNonSeamlessAdaptiveness(boolean allowNonSeamlessAdaptiveness) {
|
public ParametersBuilder setAllowNonSeamlessAdaptiveness(boolean allowNonSeamlessAdaptiveness) {
|
||||||
this.allowNonSeamlessAdaptiveness = allowNonSeamlessAdaptiveness;
|
return setAllowVideoNonSeamlessAdaptiveness(allowNonSeamlessAdaptiveness);
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -563,11 +645,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
maxVideoFrameRate,
|
maxVideoFrameRate,
|
||||||
maxVideoBitrate,
|
maxVideoBitrate,
|
||||||
exceedVideoConstraintsIfNecessary,
|
exceedVideoConstraintsIfNecessary,
|
||||||
|
allowVideoMixedMimeTypeAdaptiveness,
|
||||||
|
allowVideoNonSeamlessAdaptiveness,
|
||||||
viewportWidth,
|
viewportWidth,
|
||||||
viewportHeight,
|
viewportHeight,
|
||||||
viewportOrientationMayChange,
|
viewportOrientationMayChange,
|
||||||
// Audio
|
// Audio
|
||||||
preferredAudioLanguage,
|
preferredAudioLanguage,
|
||||||
|
maxAudioChannelCount,
|
||||||
|
maxAudioBitrate,
|
||||||
|
exceedAudioConstraintsIfNecessary,
|
||||||
|
allowAudioMixedMimeTypeAdaptiveness,
|
||||||
|
allowAudioMixedSampleRateAdaptiveness,
|
||||||
// Text
|
// Text
|
||||||
preferredTextLanguage,
|
preferredTextLanguage,
|
||||||
selectUndeterminedTextLanguage,
|
selectUndeterminedTextLanguage,
|
||||||
@ -575,8 +664,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
forceLowestBitrate,
|
forceLowestBitrate,
|
||||||
forceHighestSupportedBitrate,
|
forceHighestSupportedBitrate,
|
||||||
allowMixedMimeAdaptiveness,
|
|
||||||
allowNonSeamlessAdaptiveness,
|
|
||||||
exceedRendererCapabilitiesIfNecessary,
|
exceedRendererCapabilitiesIfNecessary,
|
||||||
tunnelingAudioSessionId,
|
tunnelingAudioSessionId,
|
||||||
// Overrides
|
// Overrides
|
||||||
@ -638,6 +725,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
* {@code true}.
|
* {@code true}.
|
||||||
*/
|
*/
|
||||||
public final boolean exceedVideoConstraintsIfNecessary;
|
public final boolean exceedVideoConstraintsIfNecessary;
|
||||||
|
/**
|
||||||
|
* Whether to allow adaptive video selections containing mixed mime types. Adaptations between
|
||||||
|
* different mime types may not be completely seamless, in which case {@link
|
||||||
|
* #allowVideoNonSeamlessAdaptiveness} also needs to be {@code true} for mixed mime type
|
||||||
|
* selections to be made. The default value is {@code false}.
|
||||||
|
*/
|
||||||
|
public final boolean allowVideoMixedMimeTypeAdaptiveness;
|
||||||
|
/**
|
||||||
|
* Whether to allow adaptive video selections where adaptation may not be completely seamless.
|
||||||
|
* The default value is {@code true}.
|
||||||
|
*/
|
||||||
|
public final boolean allowVideoNonSeamlessAdaptiveness;
|
||||||
/**
|
/**
|
||||||
* Viewport width in pixels. Constrains video track selections for adaptive content so that only
|
* 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 {@link Integer#MAX_VALUE}
|
* tracks suitable for the viewport are selected. The default value is {@link Integer#MAX_VALUE}
|
||||||
@ -664,6 +763,30 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
* {@code null}.
|
* {@code null}.
|
||||||
*/
|
*/
|
||||||
@Nullable public final String preferredAudioLanguage;
|
@Nullable public final String preferredAudioLanguage;
|
||||||
|
/**
|
||||||
|
* Maximum allowed audio channel count. The default value is {@link Integer#MAX_VALUE} (i.e. no
|
||||||
|
* constraint).
|
||||||
|
*/
|
||||||
|
public final int maxAudioChannelCount;
|
||||||
|
/**
|
||||||
|
* Maximum audio bitrate. 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}.
|
||||||
|
*/
|
||||||
|
public final boolean exceedAudioConstraintsIfNecessary;
|
||||||
|
/**
|
||||||
|
* Whether to allow adaptive audio selections containing mixed mime types. Adaptations between
|
||||||
|
* different mime types may not be completely seamless. The default value is {@code false}.
|
||||||
|
*/
|
||||||
|
public final boolean allowAudioMixedMimeTypeAdaptiveness;
|
||||||
|
/**
|
||||||
|
* Whether to allow adaptive audio selections containing mixed sample rates. Adaptations between
|
||||||
|
* different sample rates may not be completely seamless. The default value is {@code false}.
|
||||||
|
*/
|
||||||
|
public final boolean allowAudioMixedSampleRateAdaptiveness;
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
/**
|
/**
|
||||||
@ -695,15 +818,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
*/
|
*/
|
||||||
public final boolean forceHighestSupportedBitrate;
|
public final boolean forceHighestSupportedBitrate;
|
||||||
/**
|
/**
|
||||||
* Whether to allow adaptive selections containing mixed mime types. The default value is {@code
|
* @deprecated Use {@link #allowVideoMixedMimeTypeAdaptiveness} and {@link
|
||||||
* false}.
|
* #allowAudioMixedMimeTypeAdaptiveness}.
|
||||||
*/
|
*/
|
||||||
public final boolean allowMixedMimeAdaptiveness;
|
@Deprecated public final boolean allowMixedMimeAdaptiveness;
|
||||||
/**
|
/** @deprecated Use {@link #allowVideoNonSeamlessAdaptiveness}. */
|
||||||
* Whether to allow adaptive selections where adaptation may not be completely seamless. The
|
@Deprecated public final boolean allowNonSeamlessAdaptiveness;
|
||||||
* default value is {@code true}.
|
|
||||||
*/
|
|
||||||
public final boolean allowNonSeamlessAdaptiveness;
|
|
||||||
/**
|
/**
|
||||||
* Whether to exceed renderer capabilities when no selection can be made otherwise.
|
* Whether to exceed renderer capabilities when no selection can be made otherwise.
|
||||||
*
|
*
|
||||||
@ -729,11 +849,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
/* maxVideoFrameRate= */ Integer.MAX_VALUE,
|
/* maxVideoFrameRate= */ Integer.MAX_VALUE,
|
||||||
/* maxVideoBitrate= */ Integer.MAX_VALUE,
|
/* maxVideoBitrate= */ Integer.MAX_VALUE,
|
||||||
/* exceedVideoConstraintsIfNecessary= */ true,
|
/* exceedVideoConstraintsIfNecessary= */ true,
|
||||||
|
/* allowVideoMixedMimeTypeAdaptiveness= */ false,
|
||||||
|
/* allowVideoNonSeamlessAdaptiveness= */ true,
|
||||||
/* viewportWidth= */ Integer.MAX_VALUE,
|
/* viewportWidth= */ Integer.MAX_VALUE,
|
||||||
/* viewportHeight= */ Integer.MAX_VALUE,
|
/* viewportHeight= */ Integer.MAX_VALUE,
|
||||||
/* viewportOrientationMayChange= */ true,
|
/* viewportOrientationMayChange= */ true,
|
||||||
// Audio
|
// Audio
|
||||||
/* preferredAudioLanguage= */ null,
|
/* preferredAudioLanguage= */ null,
|
||||||
|
/* maxAudioChannelCount= */ Integer.MAX_VALUE,
|
||||||
|
/* maxAudioBitrate= */ Integer.MAX_VALUE,
|
||||||
|
/* exceedAudioConstraintsIfNecessary= */ true,
|
||||||
|
/* allowAudioMixedMimeTypeAdaptiveness= */ false,
|
||||||
|
/* allowAudioMixedSampleRateAdaptiveness= */ false,
|
||||||
// Text
|
// Text
|
||||||
/* preferredTextLanguage= */ null,
|
/* preferredTextLanguage= */ null,
|
||||||
/* selectUndeterminedTextLanguage= */ false,
|
/* selectUndeterminedTextLanguage= */ false,
|
||||||
@ -741,8 +868,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
/* forceLowestBitrate= */ false,
|
/* forceLowestBitrate= */ false,
|
||||||
/* forceHighestSupportedBitrate= */ false,
|
/* forceHighestSupportedBitrate= */ false,
|
||||||
/* allowMixedMimeAdaptiveness= */ false,
|
|
||||||
/* allowNonSeamlessAdaptiveness= */ true,
|
|
||||||
/* exceedRendererCapabilitiesIfNecessary= */ true,
|
/* exceedRendererCapabilitiesIfNecessary= */ true,
|
||||||
/* tunnelingAudioSessionId= */ C.AUDIO_SESSION_ID_UNSET,
|
/* tunnelingAudioSessionId= */ C.AUDIO_SESSION_ID_UNSET,
|
||||||
// Overrides
|
// Overrides
|
||||||
@ -757,11 +882,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
int maxVideoFrameRate,
|
int maxVideoFrameRate,
|
||||||
int maxVideoBitrate,
|
int maxVideoBitrate,
|
||||||
boolean exceedVideoConstraintsIfNecessary,
|
boolean exceedVideoConstraintsIfNecessary,
|
||||||
|
boolean allowVideoMixedMimeTypeAdaptiveness,
|
||||||
|
boolean allowVideoNonSeamlessAdaptiveness,
|
||||||
int viewportWidth,
|
int viewportWidth,
|
||||||
int viewportHeight,
|
int viewportHeight,
|
||||||
boolean viewportOrientationMayChange,
|
boolean viewportOrientationMayChange,
|
||||||
// Audio
|
// Audio
|
||||||
@Nullable String preferredAudioLanguage,
|
@Nullable String preferredAudioLanguage,
|
||||||
|
int maxAudioChannelCount,
|
||||||
|
int maxAudioBitrate,
|
||||||
|
boolean exceedAudioConstraintsIfNecessary,
|
||||||
|
boolean allowAudioMixedMimeTypeAdaptiveness,
|
||||||
|
boolean allowAudioMixedSampleRateAdaptiveness,
|
||||||
// Text
|
// Text
|
||||||
@Nullable String preferredTextLanguage,
|
@Nullable String preferredTextLanguage,
|
||||||
boolean selectUndeterminedTextLanguage,
|
boolean selectUndeterminedTextLanguage,
|
||||||
@ -769,8 +901,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
boolean forceLowestBitrate,
|
boolean forceLowestBitrate,
|
||||||
boolean forceHighestSupportedBitrate,
|
boolean forceHighestSupportedBitrate,
|
||||||
boolean allowMixedMimeAdaptiveness,
|
|
||||||
boolean allowNonSeamlessAdaptiveness,
|
|
||||||
boolean exceedRendererCapabilitiesIfNecessary,
|
boolean exceedRendererCapabilitiesIfNecessary,
|
||||||
int tunnelingAudioSessionId,
|
int tunnelingAudioSessionId,
|
||||||
// Overrides
|
// Overrides
|
||||||
@ -782,11 +912,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
this.maxVideoFrameRate = maxVideoFrameRate;
|
this.maxVideoFrameRate = maxVideoFrameRate;
|
||||||
this.maxVideoBitrate = maxVideoBitrate;
|
this.maxVideoBitrate = maxVideoBitrate;
|
||||||
this.exceedVideoConstraintsIfNecessary = exceedVideoConstraintsIfNecessary;
|
this.exceedVideoConstraintsIfNecessary = exceedVideoConstraintsIfNecessary;
|
||||||
|
this.allowVideoMixedMimeTypeAdaptiveness = allowVideoMixedMimeTypeAdaptiveness;
|
||||||
|
this.allowVideoNonSeamlessAdaptiveness = allowVideoNonSeamlessAdaptiveness;
|
||||||
this.viewportWidth = viewportWidth;
|
this.viewportWidth = viewportWidth;
|
||||||
this.viewportHeight = viewportHeight;
|
this.viewportHeight = viewportHeight;
|
||||||
this.viewportOrientationMayChange = viewportOrientationMayChange;
|
this.viewportOrientationMayChange = viewportOrientationMayChange;
|
||||||
// Audio
|
// Audio
|
||||||
this.preferredAudioLanguage = Util.normalizeLanguageCode(preferredAudioLanguage);
|
this.preferredAudioLanguage = Util.normalizeLanguageCode(preferredAudioLanguage);
|
||||||
|
this.maxAudioChannelCount = maxAudioChannelCount;
|
||||||
|
this.maxAudioBitrate = maxAudioBitrate;
|
||||||
|
this.exceedAudioConstraintsIfNecessary = exceedAudioConstraintsIfNecessary;
|
||||||
|
this.allowAudioMixedMimeTypeAdaptiveness = allowAudioMixedMimeTypeAdaptiveness;
|
||||||
|
this.allowAudioMixedSampleRateAdaptiveness = allowAudioMixedSampleRateAdaptiveness;
|
||||||
// Text
|
// Text
|
||||||
this.preferredTextLanguage = Util.normalizeLanguageCode(preferredTextLanguage);
|
this.preferredTextLanguage = Util.normalizeLanguageCode(preferredTextLanguage);
|
||||||
this.selectUndeterminedTextLanguage = selectUndeterminedTextLanguage;
|
this.selectUndeterminedTextLanguage = selectUndeterminedTextLanguage;
|
||||||
@ -794,13 +931,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
this.forceLowestBitrate = forceLowestBitrate;
|
this.forceLowestBitrate = forceLowestBitrate;
|
||||||
this.forceHighestSupportedBitrate = forceHighestSupportedBitrate;
|
this.forceHighestSupportedBitrate = forceHighestSupportedBitrate;
|
||||||
this.allowMixedMimeAdaptiveness = allowMixedMimeAdaptiveness;
|
|
||||||
this.allowNonSeamlessAdaptiveness = allowNonSeamlessAdaptiveness;
|
|
||||||
this.exceedRendererCapabilitiesIfNecessary = exceedRendererCapabilitiesIfNecessary;
|
this.exceedRendererCapabilitiesIfNecessary = exceedRendererCapabilitiesIfNecessary;
|
||||||
this.tunnelingAudioSessionId = tunnelingAudioSessionId;
|
this.tunnelingAudioSessionId = tunnelingAudioSessionId;
|
||||||
// Overrides
|
// Overrides
|
||||||
this.selectionOverrides = selectionOverrides;
|
this.selectionOverrides = selectionOverrides;
|
||||||
this.rendererDisabledFlags = rendererDisabledFlags;
|
this.rendererDisabledFlags = rendererDisabledFlags;
|
||||||
|
// Deprecated fields.
|
||||||
|
this.allowMixedMimeAdaptiveness = allowVideoMixedMimeTypeAdaptiveness;
|
||||||
|
this.allowNonSeamlessAdaptiveness = allowVideoNonSeamlessAdaptiveness;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ Parameters(Parcel in) {
|
/* package */ Parameters(Parcel in) {
|
||||||
@ -810,11 +948,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
this.maxVideoFrameRate = in.readInt();
|
this.maxVideoFrameRate = in.readInt();
|
||||||
this.maxVideoBitrate = in.readInt();
|
this.maxVideoBitrate = in.readInt();
|
||||||
this.exceedVideoConstraintsIfNecessary = Util.readBoolean(in);
|
this.exceedVideoConstraintsIfNecessary = Util.readBoolean(in);
|
||||||
|
this.allowVideoMixedMimeTypeAdaptiveness = Util.readBoolean(in);
|
||||||
|
this.allowVideoNonSeamlessAdaptiveness = Util.readBoolean(in);
|
||||||
this.viewportWidth = in.readInt();
|
this.viewportWidth = in.readInt();
|
||||||
this.viewportHeight = in.readInt();
|
this.viewportHeight = in.readInt();
|
||||||
this.viewportOrientationMayChange = Util.readBoolean(in);
|
this.viewportOrientationMayChange = Util.readBoolean(in);
|
||||||
// Audio
|
// Audio
|
||||||
this.preferredAudioLanguage = in.readString();
|
this.preferredAudioLanguage = in.readString();
|
||||||
|
this.maxAudioChannelCount = in.readInt();
|
||||||
|
this.maxAudioBitrate = in.readInt();
|
||||||
|
this.exceedAudioConstraintsIfNecessary = Util.readBoolean(in);
|
||||||
|
this.allowAudioMixedMimeTypeAdaptiveness = Util.readBoolean(in);
|
||||||
|
this.allowAudioMixedSampleRateAdaptiveness = Util.readBoolean(in);
|
||||||
// Text
|
// Text
|
||||||
this.preferredTextLanguage = in.readString();
|
this.preferredTextLanguage = in.readString();
|
||||||
this.selectUndeterminedTextLanguage = Util.readBoolean(in);
|
this.selectUndeterminedTextLanguage = Util.readBoolean(in);
|
||||||
@ -822,13 +967,14 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
this.forceLowestBitrate = Util.readBoolean(in);
|
this.forceLowestBitrate = Util.readBoolean(in);
|
||||||
this.forceHighestSupportedBitrate = Util.readBoolean(in);
|
this.forceHighestSupportedBitrate = Util.readBoolean(in);
|
||||||
this.allowMixedMimeAdaptiveness = Util.readBoolean(in);
|
|
||||||
this.allowNonSeamlessAdaptiveness = Util.readBoolean(in);
|
|
||||||
this.exceedRendererCapabilitiesIfNecessary = Util.readBoolean(in);
|
this.exceedRendererCapabilitiesIfNecessary = Util.readBoolean(in);
|
||||||
this.tunnelingAudioSessionId = in.readInt();
|
this.tunnelingAudioSessionId = in.readInt();
|
||||||
// Overrides
|
// Overrides
|
||||||
this.selectionOverrides = readSelectionOverrides(in);
|
this.selectionOverrides = readSelectionOverrides(in);
|
||||||
this.rendererDisabledFlags = in.readSparseBooleanArray();
|
this.rendererDisabledFlags = in.readSparseBooleanArray();
|
||||||
|
// Deprecated fields.
|
||||||
|
this.allowMixedMimeAdaptiveness = allowVideoMixedMimeTypeAdaptiveness;
|
||||||
|
this.allowNonSeamlessAdaptiveness = allowVideoNonSeamlessAdaptiveness;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -887,11 +1033,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
&& maxVideoFrameRate == other.maxVideoFrameRate
|
&& maxVideoFrameRate == other.maxVideoFrameRate
|
||||||
&& maxVideoBitrate == other.maxVideoBitrate
|
&& maxVideoBitrate == other.maxVideoBitrate
|
||||||
&& exceedVideoConstraintsIfNecessary == other.exceedVideoConstraintsIfNecessary
|
&& exceedVideoConstraintsIfNecessary == other.exceedVideoConstraintsIfNecessary
|
||||||
|
&& allowVideoMixedMimeTypeAdaptiveness == other.allowVideoMixedMimeTypeAdaptiveness
|
||||||
|
&& allowVideoNonSeamlessAdaptiveness == other.allowVideoNonSeamlessAdaptiveness
|
||||||
&& viewportOrientationMayChange == other.viewportOrientationMayChange
|
&& viewportOrientationMayChange == other.viewportOrientationMayChange
|
||||||
&& viewportWidth == other.viewportWidth
|
&& viewportWidth == other.viewportWidth
|
||||||
&& viewportHeight == other.viewportHeight
|
&& viewportHeight == other.viewportHeight
|
||||||
// Audio
|
// Audio
|
||||||
&& TextUtils.equals(preferredAudioLanguage, other.preferredAudioLanguage)
|
&& TextUtils.equals(preferredAudioLanguage, other.preferredAudioLanguage)
|
||||||
|
&& maxAudioChannelCount == other.maxAudioChannelCount
|
||||||
|
&& maxAudioBitrate == other.maxAudioBitrate
|
||||||
|
&& exceedAudioConstraintsIfNecessary == other.exceedAudioConstraintsIfNecessary
|
||||||
|
&& allowAudioMixedMimeTypeAdaptiveness == other.allowAudioMixedMimeTypeAdaptiveness
|
||||||
|
&& allowAudioMixedSampleRateAdaptiveness == other.allowAudioMixedSampleRateAdaptiveness
|
||||||
// Text
|
// Text
|
||||||
&& TextUtils.equals(preferredTextLanguage, other.preferredTextLanguage)
|
&& TextUtils.equals(preferredTextLanguage, other.preferredTextLanguage)
|
||||||
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
|
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
|
||||||
@ -899,8 +1052,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
&& forceLowestBitrate == other.forceLowestBitrate
|
&& forceLowestBitrate == other.forceLowestBitrate
|
||||||
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
|
&& forceHighestSupportedBitrate == other.forceHighestSupportedBitrate
|
||||||
&& allowMixedMimeAdaptiveness == other.allowMixedMimeAdaptiveness
|
|
||||||
&& allowNonSeamlessAdaptiveness == other.allowNonSeamlessAdaptiveness
|
|
||||||
&& exceedRendererCapabilitiesIfNecessary == other.exceedRendererCapabilitiesIfNecessary
|
&& exceedRendererCapabilitiesIfNecessary == other.exceedRendererCapabilitiesIfNecessary
|
||||||
&& tunnelingAudioSessionId == other.tunnelingAudioSessionId
|
&& tunnelingAudioSessionId == other.tunnelingAudioSessionId
|
||||||
// Overrides
|
// Overrides
|
||||||
@ -917,12 +1068,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
result = 31 * result + maxVideoFrameRate;
|
result = 31 * result + maxVideoFrameRate;
|
||||||
result = 31 * result + maxVideoBitrate;
|
result = 31 * result + maxVideoBitrate;
|
||||||
result = 31 * result + (exceedVideoConstraintsIfNecessary ? 1 : 0);
|
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 + (viewportOrientationMayChange ? 1 : 0);
|
||||||
result = 31 * result + viewportWidth;
|
result = 31 * result + viewportWidth;
|
||||||
result = 31 * result + viewportHeight;
|
result = 31 * result + viewportHeight;
|
||||||
// Audio
|
// Audio
|
||||||
result =
|
result =
|
||||||
31 * result + (preferredAudioLanguage == null ? 0 : preferredAudioLanguage.hashCode());
|
31 * result + (preferredAudioLanguage == null ? 0 : preferredAudioLanguage.hashCode());
|
||||||
|
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);
|
||||||
// Text
|
// Text
|
||||||
result = 31 * result + (preferredTextLanguage == null ? 0 : preferredTextLanguage.hashCode());
|
result = 31 * result + (preferredTextLanguage == null ? 0 : preferredTextLanguage.hashCode());
|
||||||
result = 31 * result + (selectUndeterminedTextLanguage ? 1 : 0);
|
result = 31 * result + (selectUndeterminedTextLanguage ? 1 : 0);
|
||||||
@ -930,8 +1088,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
result = 31 * result + (forceLowestBitrate ? 1 : 0);
|
result = 31 * result + (forceLowestBitrate ? 1 : 0);
|
||||||
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
|
result = 31 * result + (forceHighestSupportedBitrate ? 1 : 0);
|
||||||
result = 31 * result + (allowMixedMimeAdaptiveness ? 1 : 0);
|
|
||||||
result = 31 * result + (allowNonSeamlessAdaptiveness ? 1 : 0);
|
|
||||||
result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0);
|
result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0);
|
||||||
result = 31 * result + tunnelingAudioSessionId;
|
result = 31 * result + tunnelingAudioSessionId;
|
||||||
// Overrides (omitted from hashCode).
|
// Overrides (omitted from hashCode).
|
||||||
@ -953,11 +1109,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
dest.writeInt(maxVideoFrameRate);
|
dest.writeInt(maxVideoFrameRate);
|
||||||
dest.writeInt(maxVideoBitrate);
|
dest.writeInt(maxVideoBitrate);
|
||||||
Util.writeBoolean(dest, exceedVideoConstraintsIfNecessary);
|
Util.writeBoolean(dest, exceedVideoConstraintsIfNecessary);
|
||||||
|
Util.writeBoolean(dest, allowVideoMixedMimeTypeAdaptiveness);
|
||||||
|
Util.writeBoolean(dest, allowVideoNonSeamlessAdaptiveness);
|
||||||
dest.writeInt(viewportWidth);
|
dest.writeInt(viewportWidth);
|
||||||
dest.writeInt(viewportHeight);
|
dest.writeInt(viewportHeight);
|
||||||
Util.writeBoolean(dest, viewportOrientationMayChange);
|
Util.writeBoolean(dest, viewportOrientationMayChange);
|
||||||
// Audio
|
// Audio
|
||||||
dest.writeString(preferredAudioLanguage);
|
dest.writeString(preferredAudioLanguage);
|
||||||
|
dest.writeInt(maxAudioChannelCount);
|
||||||
|
dest.writeInt(maxAudioBitrate);
|
||||||
|
Util.writeBoolean(dest, exceedAudioConstraintsIfNecessary);
|
||||||
|
Util.writeBoolean(dest, allowAudioMixedMimeTypeAdaptiveness);
|
||||||
|
Util.writeBoolean(dest, allowAudioMixedSampleRateAdaptiveness);
|
||||||
// Text
|
// Text
|
||||||
dest.writeString(preferredTextLanguage);
|
dest.writeString(preferredTextLanguage);
|
||||||
Util.writeBoolean(dest, selectUndeterminedTextLanguage);
|
Util.writeBoolean(dest, selectUndeterminedTextLanguage);
|
||||||
@ -965,8 +1128,6 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// General
|
// General
|
||||||
Util.writeBoolean(dest, forceLowestBitrate);
|
Util.writeBoolean(dest, forceLowestBitrate);
|
||||||
Util.writeBoolean(dest, forceHighestSupportedBitrate);
|
Util.writeBoolean(dest, forceHighestSupportedBitrate);
|
||||||
Util.writeBoolean(dest, allowMixedMimeAdaptiveness);
|
|
||||||
Util.writeBoolean(dest, allowNonSeamlessAdaptiveness);
|
|
||||||
Util.writeBoolean(dest, exceedRendererCapabilitiesIfNecessary);
|
Util.writeBoolean(dest, exceedRendererCapabilitiesIfNecessary);
|
||||||
dest.writeInt(tunnelingAudioSessionId);
|
dest.writeInt(tunnelingAudioSessionId);
|
||||||
// Overrides
|
// Overrides
|
||||||
@ -1322,11 +1483,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
rendererTrackGroups.get(override.groupIndex), override.tracks[0]);
|
rendererTrackGroups.get(override.groupIndex), override.tracks[0]);
|
||||||
} else {
|
} else {
|
||||||
rendererTrackSelections[i] =
|
rendererTrackSelections[i] =
|
||||||
Assertions.checkNotNull(adaptiveTrackSelectionFactory)
|
adaptiveTrackSelectionFactory.createTrackSelection(
|
||||||
.createTrackSelection(
|
rendererTrackGroups.get(override.groupIndex),
|
||||||
rendererTrackGroups.get(override.groupIndex),
|
getBandwidthMeter(),
|
||||||
getBandwidthMeter(),
|
override.tracks);
|
||||||
override.tracks);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1508,11 +1668,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
TrackSelection.Factory adaptiveTrackSelectionFactory,
|
TrackSelection.Factory adaptiveTrackSelectionFactory,
|
||||||
BandwidthMeter bandwidthMeter)
|
BandwidthMeter bandwidthMeter)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
int requiredAdaptiveSupport = params.allowNonSeamlessAdaptiveness
|
int requiredAdaptiveSupport =
|
||||||
? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS | RendererCapabilities.ADAPTIVE_SEAMLESS)
|
params.allowVideoNonSeamlessAdaptiveness
|
||||||
: RendererCapabilities.ADAPTIVE_SEAMLESS;
|
? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS | RendererCapabilities.ADAPTIVE_SEAMLESS)
|
||||||
|
: RendererCapabilities.ADAPTIVE_SEAMLESS;
|
||||||
boolean allowMixedMimeTypes =
|
boolean allowMixedMimeTypes =
|
||||||
params.allowMixedMimeAdaptiveness
|
params.allowVideoMixedMimeTypeAdaptiveness
|
||||||
&& (mixedMimeTypeAdaptationSupports & requiredAdaptiveSupport) != 0;
|
&& (mixedMimeTypeAdaptationSupports & requiredAdaptiveSupport) != 0;
|
||||||
for (int i = 0; i < groups.length; i++) {
|
for (int i = 0; i < groups.length; i++) {
|
||||||
TrackGroup group = groups.get(i);
|
TrackGroup group = groups.get(i);
|
||||||
@ -1530,8 +1691,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
params.viewportHeight,
|
params.viewportHeight,
|
||||||
params.viewportOrientationMayChange);
|
params.viewportOrientationMayChange);
|
||||||
if (adaptiveTracks.length > 0) {
|
if (adaptiveTracks.length > 0) {
|
||||||
return Assertions.checkNotNull(adaptiveTrackSelectionFactory)
|
return adaptiveTrackSelectionFactory.createTrackSelection(
|
||||||
.createTrackSelection(group, bandwidthMeter, adaptiveTracks);
|
group, bandwidthMeter, adaptiveTracks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -1758,6 +1919,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
* selection was made.
|
* selection was made.
|
||||||
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
|
* @throws ExoPlaybackException If an error occurs while selecting the tracks.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
protected @Nullable Pair<TrackSelection, AudioTrackScore> selectAudioTrack(
|
protected @Nullable Pair<TrackSelection, AudioTrackScore> selectAudioTrack(
|
||||||
TrackGroupArray groups,
|
TrackGroupArray groups,
|
||||||
int[][] formatSupports,
|
int[][] formatSupports,
|
||||||
@ -1777,6 +1939,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
Format format = trackGroup.getFormat(trackIndex);
|
Format format = trackGroup.getFormat(trackIndex);
|
||||||
AudioTrackScore trackScore =
|
AudioTrackScore trackScore =
|
||||||
new AudioTrackScore(format, params, trackFormatSupport[trackIndex]);
|
new AudioTrackScore(format, params, trackFormatSupport[trackIndex]);
|
||||||
|
if (!trackScore.isWithinConstraints && !params.exceedAudioConstraintsIfNecessary) {
|
||||||
|
// Track should not be selected.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (selectedTrackScore == null || trackScore.compareTo(selectedTrackScore) > 0) {
|
if (selectedTrackScore == null || trackScore.compareTo(selectedTrackScore) > 0) {
|
||||||
selectedGroupIndex = groupIndex;
|
selectedGroupIndex = groupIndex;
|
||||||
selectedTrackIndex = trackIndex;
|
selectedTrackIndex = trackIndex;
|
||||||
@ -1799,7 +1965,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
// If the group of the track with the highest score allows it, try to enable adaptation.
|
// If the group of the track with the highest score allows it, try to enable adaptation.
|
||||||
int[] adaptiveTracks =
|
int[] adaptiveTracks =
|
||||||
getAdaptiveAudioTracks(
|
getAdaptiveAudioTracks(
|
||||||
selectedGroup, formatSupports[selectedGroupIndex], params.allowMixedMimeAdaptiveness);
|
selectedGroup,
|
||||||
|
formatSupports[selectedGroupIndex],
|
||||||
|
params.allowAudioMixedMimeTypeAdaptiveness,
|
||||||
|
params.allowAudioMixedSampleRateAdaptiveness);
|
||||||
if (adaptiveTracks.length > 0) {
|
if (adaptiveTracks.length > 0) {
|
||||||
selection =
|
selection =
|
||||||
adaptiveTrackSelectionFactory.createTrackSelection(
|
adaptiveTrackSelectionFactory.createTrackSelection(
|
||||||
@ -1814,18 +1983,27 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
return Pair.create(selection, Assertions.checkNotNull(selectedTrackScore));
|
return Pair.create(selection, Assertions.checkNotNull(selectedTrackScore));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[] getAdaptiveAudioTracks(TrackGroup group, int[] formatSupport,
|
private static int[] getAdaptiveAudioTracks(
|
||||||
boolean allowMixedMimeTypes) {
|
TrackGroup group,
|
||||||
|
int[] formatSupport,
|
||||||
|
boolean allowMixedMimeTypeAdaptiveness,
|
||||||
|
boolean allowMixedSampleRateAdaptiveness) {
|
||||||
int selectedConfigurationTrackCount = 0;
|
int selectedConfigurationTrackCount = 0;
|
||||||
AudioConfigurationTuple selectedConfiguration = null;
|
AudioConfigurationTuple selectedConfiguration = null;
|
||||||
HashSet<AudioConfigurationTuple> seenConfigurationTuples = new HashSet<>();
|
HashSet<AudioConfigurationTuple> seenConfigurationTuples = new HashSet<>();
|
||||||
for (int i = 0; i < group.length; i++) {
|
for (int i = 0; i < group.length; i++) {
|
||||||
Format format = group.getFormat(i);
|
Format format = group.getFormat(i);
|
||||||
AudioConfigurationTuple configuration = new AudioConfigurationTuple(
|
AudioConfigurationTuple configuration =
|
||||||
format.channelCount, format.sampleRate,
|
new AudioConfigurationTuple(
|
||||||
allowMixedMimeTypes ? null : format.sampleMimeType);
|
format.channelCount, format.sampleRate, format.sampleMimeType);
|
||||||
if (seenConfigurationTuples.add(configuration)) {
|
if (seenConfigurationTuples.add(configuration)) {
|
||||||
int configurationCount = getAdaptiveAudioTrackCount(group, formatSupport, configuration);
|
int configurationCount =
|
||||||
|
getAdaptiveAudioTrackCount(
|
||||||
|
group,
|
||||||
|
formatSupport,
|
||||||
|
configuration,
|
||||||
|
allowMixedMimeTypeAdaptiveness,
|
||||||
|
allowMixedSampleRateAdaptiveness);
|
||||||
if (configurationCount > selectedConfigurationTrackCount) {
|
if (configurationCount > selectedConfigurationTrackCount) {
|
||||||
selectedConfiguration = configuration;
|
selectedConfiguration = configuration;
|
||||||
selectedConfigurationTrackCount = configurationCount;
|
selectedConfigurationTrackCount = configurationCount;
|
||||||
@ -1838,7 +2016,11 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < group.length; i++) {
|
for (int i = 0; i < group.length; i++) {
|
||||||
if (isSupportedAdaptiveAudioTrack(
|
if (isSupportedAdaptiveAudioTrack(
|
||||||
group.getFormat(i), formatSupport[i], Assertions.checkNotNull(selectedConfiguration))) {
|
group.getFormat(i),
|
||||||
|
formatSupport[i],
|
||||||
|
Assertions.checkNotNull(selectedConfiguration),
|
||||||
|
allowMixedMimeTypeAdaptiveness,
|
||||||
|
allowMixedSampleRateAdaptiveness)) {
|
||||||
adaptiveIndices[index++] = i;
|
adaptiveIndices[index++] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1847,23 +2029,41 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
return NO_TRACKS;
|
return NO_TRACKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getAdaptiveAudioTrackCount(TrackGroup group, int[] formatSupport,
|
private static int getAdaptiveAudioTrackCount(
|
||||||
AudioConfigurationTuple configuration) {
|
TrackGroup group,
|
||||||
|
int[] formatSupport,
|
||||||
|
AudioConfigurationTuple configuration,
|
||||||
|
boolean allowMixedMimeTypeAdaptiveness,
|
||||||
|
boolean allowMixedSampleRateAdaptiveness) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < group.length; i++) {
|
for (int i = 0; i < group.length; i++) {
|
||||||
if (isSupportedAdaptiveAudioTrack(group.getFormat(i), formatSupport[i], configuration)) {
|
if (isSupportedAdaptiveAudioTrack(
|
||||||
|
group.getFormat(i),
|
||||||
|
formatSupport[i],
|
||||||
|
configuration,
|
||||||
|
allowMixedMimeTypeAdaptiveness,
|
||||||
|
allowMixedSampleRateAdaptiveness)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSupportedAdaptiveAudioTrack(Format format, int formatSupport,
|
private static boolean isSupportedAdaptiveAudioTrack(
|
||||||
AudioConfigurationTuple configuration) {
|
Format format,
|
||||||
return isSupported(formatSupport, false) && format.channelCount == configuration.channelCount
|
int formatSupport,
|
||||||
&& format.sampleRate == configuration.sampleRate
|
AudioConfigurationTuple configuration,
|
||||||
&& (configuration.mimeType == null
|
boolean allowMixedMimeTypeAdaptiveness,
|
||||||
|| TextUtils.equals(configuration.mimeType, format.sampleMimeType));
|
boolean allowMixedSampleRateAdaptiveness) {
|
||||||
|
return isSupported(formatSupport, false)
|
||||||
|
&& (format.channelCount != Format.NO_VALUE
|
||||||
|
&& format.channelCount == configuration.channelCount)
|
||||||
|
&& (allowMixedMimeTypeAdaptiveness
|
||||||
|
|| (format.sampleMimeType != null
|
||||||
|
&& TextUtils.equals(format.sampleMimeType, configuration.mimeType)))
|
||||||
|
&& (allowMixedSampleRateAdaptiveness
|
||||||
|
|| (format.sampleRate != Format.NO_VALUE
|
||||||
|
&& format.sampleRate == configuration.sampleRate));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text track selection implementation.
|
// Text track selection implementation.
|
||||||
@ -2202,6 +2402,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
/** Represents how well an audio track matches the selection {@link Parameters}. */
|
/** Represents how well an audio track matches the selection {@link Parameters}. */
|
||||||
protected static final class AudioTrackScore implements Comparable<AudioTrackScore> {
|
protected static final class AudioTrackScore implements Comparable<AudioTrackScore> {
|
||||||
|
|
||||||
|
public final boolean isWithinConstraints;
|
||||||
|
|
||||||
private final Parameters parameters;
|
private final Parameters parameters;
|
||||||
private final int withinRendererCapabilitiesScore;
|
private final int withinRendererCapabilitiesScore;
|
||||||
private final int matchLanguageScore;
|
private final int matchLanguageScore;
|
||||||
@ -2218,6 +2420,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
channelCount = format.channelCount;
|
channelCount = format.channelCount;
|
||||||
sampleRate = format.sampleRate;
|
sampleRate = format.sampleRate;
|
||||||
bitrate = format.bitrate;
|
bitrate = format.bitrate;
|
||||||
|
isWithinConstraints =
|
||||||
|
(format.bitrate == Format.NO_VALUE || format.bitrate <= parameters.maxAudioBitrate)
|
||||||
|
&& (format.channelCount == Format.NO_VALUE
|
||||||
|
|| format.channelCount <= parameters.maxAudioChannelCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2236,6 +2442,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
if (this.matchLanguageScore != other.matchLanguageScore) {
|
if (this.matchLanguageScore != other.matchLanguageScore) {
|
||||||
return compareInts(this.matchLanguageScore, other.matchLanguageScore);
|
return compareInts(this.matchLanguageScore, other.matchLanguageScore);
|
||||||
}
|
}
|
||||||
|
if (this.isWithinConstraints != other.isWithinConstraints) {
|
||||||
|
return this.isWithinConstraints ? 1 : -1;
|
||||||
|
}
|
||||||
if (parameters.forceLowestBitrate) {
|
if (parameters.forceLowestBitrate) {
|
||||||
int bitrateComparison = compareFormatValues(bitrate, other.bitrate);
|
int bitrateComparison = compareFormatValues(bitrate, other.bitrate);
|
||||||
if (bitrateComparison != 0) {
|
if (bitrateComparison != 0) {
|
||||||
@ -2245,9 +2454,9 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||||||
if (this.defaultSelectionFlagScore != other.defaultSelectionFlagScore) {
|
if (this.defaultSelectionFlagScore != other.defaultSelectionFlagScore) {
|
||||||
return compareInts(this.defaultSelectionFlagScore, other.defaultSelectionFlagScore);
|
return compareInts(this.defaultSelectionFlagScore, other.defaultSelectionFlagScore);
|
||||||
}
|
}
|
||||||
// If the formats are within renderer capabilities then prefer higher values of channel count,
|
// If the formats are within constraints and renderer capabilities then prefer higher values
|
||||||
// sample rate and bit rate in that order. Otherwise, prefer lower values.
|
// of channel count, sample rate and bit rate in that order. Otherwise, prefer lower values.
|
||||||
int resultSign = withinRendererCapabilitiesScore == 1 ? 1 : -1;
|
int resultSign = isWithinConstraints && withinRendererCapabilitiesScore == 1 ? 1 : -1;
|
||||||
if (this.channelCount != other.channelCount) {
|
if (this.channelCount != other.channelCount) {
|
||||||
return resultSign * compareInts(this.channelCount, other.channelCount);
|
return resultSign * compareInts(this.channelCount, other.channelCount);
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.trackselection;
|
package com.google.android.exoplayer2.trackselection;
|
||||||
|
|
||||||
|
import static com.google.android.exoplayer2.RendererCapabilities.ADAPTIVE_NOT_SEAMLESS;
|
||||||
import static com.google.android.exoplayer2.RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES;
|
import static com.google.android.exoplayer2.RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES;
|
||||||
import static com.google.android.exoplayer2.RendererCapabilities.FORMAT_HANDLED;
|
import static com.google.android.exoplayer2.RendererCapabilities.FORMAT_HANDLED;
|
||||||
import static com.google.android.exoplayer2.RendererCapabilities.FORMAT_UNSUPPORTED_SUBTYPE;
|
import static com.google.android.exoplayer2.RendererCapabilities.FORMAT_UNSUPPORTED_SUBTYPE;
|
||||||
@ -132,21 +133,26 @@ public final class DefaultTrackSelectorTest {
|
|||||||
/* maxVideoFrameRate= */ 2,
|
/* maxVideoFrameRate= */ 2,
|
||||||
/* maxVideoBitrate= */ 3,
|
/* maxVideoBitrate= */ 3,
|
||||||
/* exceedVideoConstraintsIfNecessary= */ false,
|
/* exceedVideoConstraintsIfNecessary= */ false,
|
||||||
|
/* allowVideoMixedMimeTypeAdaptiveness= */ true,
|
||||||
|
/* allowVideoNonSeamlessAdaptiveness= */ false,
|
||||||
/* viewportWidth= */ 4,
|
/* viewportWidth= */ 4,
|
||||||
/* viewportHeight= */ 5,
|
/* viewportHeight= */ 5,
|
||||||
/* viewportOrientationMayChange= */ true,
|
/* viewportOrientationMayChange= */ true,
|
||||||
// Audio
|
// Audio
|
||||||
/* preferredAudioLanguage= */ "en",
|
/* preferredAudioLanguage= */ "en",
|
||||||
|
/* maxAudioChannelCount= */ 6,
|
||||||
|
/* maxAudioBitrate= */ 7,
|
||||||
|
/* exceedAudioConstraintsIfNecessary= */ false,
|
||||||
|
/* allowAudioMixedMimeTypeAdaptiveness= */ true,
|
||||||
|
/* allowAudioMixedSampleRateAdaptiveness= */ false,
|
||||||
// Text
|
// Text
|
||||||
/* preferredTextLanguage= */ "de",
|
/* preferredTextLanguage= */ "de",
|
||||||
/* selectUndeterminedTextLanguage= */ false,
|
/* selectUndeterminedTextLanguage= */ true,
|
||||||
/* disabledTextTrackSelectionFlags= */ 6,
|
/* disabledTextTrackSelectionFlags= */ 8,
|
||||||
// General
|
// General
|
||||||
/* forceLowestBitrate= */ true,
|
/* forceLowestBitrate= */ false,
|
||||||
/* forceHighestSupportedBitrate= */ false,
|
/* forceHighestSupportedBitrate= */ true,
|
||||||
/* allowMixedMimeAdaptiveness= */ true,
|
/* exceedRendererCapabilitiesIfNecessary= */ false,
|
||||||
/* allowNonSeamlessAdaptiveness= */ false,
|
|
||||||
/* exceedRendererCapabilitiesIfNecessary= */ true,
|
|
||||||
/* tunnelingAudioSessionId= */ C.AUDIO_SESSION_ID_UNSET,
|
/* tunnelingAudioSessionId= */ C.AUDIO_SESSION_ID_UNSET,
|
||||||
// Overrides
|
// Overrides
|
||||||
selectionOverrides,
|
selectionOverrides,
|
||||||
@ -1090,6 +1096,137 @@ public final class DefaultTrackSelectorTest {
|
|||||||
assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1);
|
assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelectTracksWithMultipleAudioTracksWithMixedSampleRates() throws Exception {
|
||||||
|
Format highSampleRateAudioFormat =
|
||||||
|
buildAudioFormatWithSampleRate("44100", /* sampleRate= */ 44100);
|
||||||
|
Format lowSampleRateAudioFormat =
|
||||||
|
buildAudioFormatWithSampleRate("22050", /* sampleRate= */ 22050);
|
||||||
|
|
||||||
|
// Should not adapt between mixed sample rates by default, so we expect a fixed selection
|
||||||
|
// containing the higher sample rate stream.
|
||||||
|
TrackGroupArray trackGroups =
|
||||||
|
singleTrackGroup(highSampleRateAudioFormat, lowSampleRateAudioFormat);
|
||||||
|
TrackSelectorResult result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, highSampleRateAudioFormat);
|
||||||
|
|
||||||
|
// The same applies if the tracks are provided in the opposite order.
|
||||||
|
trackGroups = singleTrackGroup(lowSampleRateAudioFormat, highSampleRateAudioFormat);
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, highSampleRateAudioFormat);
|
||||||
|
|
||||||
|
// If we explicitly enable mixed sample rate adaptiveness, expect an adaptive selection.
|
||||||
|
trackSelector.setParameters(
|
||||||
|
Parameters.DEFAULT.buildUpon().setAllowAudioMixedSampleRateAdaptiveness(true));
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelectTracksWithMultipleAudioTracksWithMixedMimeTypes() throws Exception {
|
||||||
|
Format aacAudioFormat = buildAudioFormatWithMimeType("aac", MimeTypes.AUDIO_AAC);
|
||||||
|
Format opusAudioFormat = buildAudioFormatWithMimeType("opus", MimeTypes.AUDIO_OPUS);
|
||||||
|
|
||||||
|
// Should not adapt between mixed mime types by default, so we expect a fixed selection
|
||||||
|
// containing the first stream.
|
||||||
|
TrackGroupArray trackGroups = singleTrackGroup(aacAudioFormat, opusAudioFormat);
|
||||||
|
TrackSelectorResult result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, aacAudioFormat);
|
||||||
|
|
||||||
|
// The same applies if the tracks are provided in the opposite order.
|
||||||
|
trackGroups = singleTrackGroup(opusAudioFormat, aacAudioFormat);
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, opusAudioFormat);
|
||||||
|
|
||||||
|
// If we explicitly enable mixed mime type adaptiveness, expect an adaptive selection.
|
||||||
|
trackSelector.setParameters(
|
||||||
|
Parameters.DEFAULT.buildUpon().setAllowAudioMixedMimeTypeAdaptiveness(true));
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelectTracksWithMultipleAudioTracksWithMixedChannelCounts() throws Exception {
|
||||||
|
Format stereoAudioFormat =
|
||||||
|
buildAudioFormatWithChannelCount("2-channels", /* channelCount= */ 2);
|
||||||
|
Format surroundAudioFormat =
|
||||||
|
buildAudioFormatWithChannelCount("5-channels", /* channelCount= */ 5);
|
||||||
|
|
||||||
|
// Should not adapt between different channel counts, so we expect a fixed selection containing
|
||||||
|
// the track with more channels.
|
||||||
|
TrackGroupArray trackGroups = singleTrackGroup(stereoAudioFormat, surroundAudioFormat);
|
||||||
|
TrackSelectorResult result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, surroundAudioFormat);
|
||||||
|
|
||||||
|
// The same applies if the tracks are provided in the opposite order.
|
||||||
|
trackGroups = singleTrackGroup(surroundAudioFormat, stereoAudioFormat);
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, surroundAudioFormat);
|
||||||
|
|
||||||
|
// If we constrain the channel count to 4 we expect a fixed selection containing the track with
|
||||||
|
// fewer channels.
|
||||||
|
trackSelector.setParameters(Parameters.DEFAULT.buildUpon().setMaxAudioChannelCount(4));
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, stereoAudioFormat);
|
||||||
|
|
||||||
|
// If we constrain the channel count to 2 we expect a fixed selection containing the track with
|
||||||
|
// fewer channels.
|
||||||
|
trackSelector.setParameters(Parameters.DEFAULT.buildUpon().setMaxAudioChannelCount(2));
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, stereoAudioFormat);
|
||||||
|
|
||||||
|
// If we constrain the channel count to 1 we expect a fixed selection containing the track with
|
||||||
|
// fewer channels.
|
||||||
|
trackSelector.setParameters(Parameters.DEFAULT.buildUpon().setMaxAudioChannelCount(1));
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, stereoAudioFormat);
|
||||||
|
|
||||||
|
// If we disable exceeding of constraints we expect no selection.
|
||||||
|
trackSelector.setParameters(
|
||||||
|
Parameters.DEFAULT
|
||||||
|
.buildUpon()
|
||||||
|
.setMaxAudioChannelCount(1)
|
||||||
|
.setExceedAudioConstraintsIfNecessary(false));
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertNoSelection(result.selections.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelectTracksWithMultipleAudioTracksOverrideReturnsAdaptiveTrackSelection()
|
public void testSelectTracksWithMultipleAudioTracksOverrideReturnsAdaptiveTrackSelection()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@ -1164,6 +1301,70 @@ public final class DefaultTrackSelectorTest {
|
|||||||
assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1);
|
assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelectTracksWithMultipleVideoTracksWithNonSeamlessAdaptiveness()
|
||||||
|
throws Exception {
|
||||||
|
FakeRendererCapabilities nonSeamlessVideoCapabilities =
|
||||||
|
new FakeRendererCapabilities(C.TRACK_TYPE_VIDEO, FORMAT_HANDLED | ADAPTIVE_NOT_SEAMLESS);
|
||||||
|
|
||||||
|
// Should do non-seamless adaptiveness by default, so expect an adaptive selection.
|
||||||
|
TrackGroupArray trackGroups = singleTrackGroup(buildVideoFormat("0"), buildVideoFormat("1"));
|
||||||
|
trackSelector.setParameters(
|
||||||
|
Parameters.DEFAULT.buildUpon().setAllowVideoNonSeamlessAdaptiveness(true));
|
||||||
|
TrackSelectorResult result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {nonSeamlessVideoCapabilities},
|
||||||
|
trackGroups,
|
||||||
|
periodId,
|
||||||
|
TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1);
|
||||||
|
|
||||||
|
// If we explicitly disable non-seamless adaptiveness, expect a fixed selection.
|
||||||
|
trackSelector.setParameters(
|
||||||
|
Parameters.DEFAULT.buildUpon().setAllowVideoNonSeamlessAdaptiveness(false));
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {nonSeamlessVideoCapabilities},
|
||||||
|
trackGroups,
|
||||||
|
periodId,
|
||||||
|
TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups.get(0), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelectTracksWithMultipleVideoTracksWithMixedMimeTypes() throws Exception {
|
||||||
|
Format h264VideoFormat = buildVideoFormatWithMimeType("h264", MimeTypes.VIDEO_H264);
|
||||||
|
Format h265VideoFormat = buildVideoFormatWithMimeType("h265", MimeTypes.VIDEO_H265);
|
||||||
|
|
||||||
|
// Should not adapt between mixed mime types by default, so we expect a fixed selection
|
||||||
|
// containing the first stream.
|
||||||
|
TrackGroupArray trackGroups = singleTrackGroup(h264VideoFormat, h265VideoFormat);
|
||||||
|
TrackSelectorResult result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, h264VideoFormat);
|
||||||
|
|
||||||
|
// The same applies if the tracks are provided in the opposite order.
|
||||||
|
trackGroups = singleTrackGroup(h265VideoFormat, h264VideoFormat);
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertFixedSelection(result.selections.get(0), trackGroups, h265VideoFormat);
|
||||||
|
|
||||||
|
// If we explicitly enable mixed mime type adaptiveness, expect an adaptive selection.
|
||||||
|
trackSelector.setParameters(
|
||||||
|
Parameters.DEFAULT.buildUpon().setAllowVideoMixedMimeTypeAdaptiveness(true));
|
||||||
|
result =
|
||||||
|
trackSelector.selectTracks(
|
||||||
|
new RendererCapabilities[] {VIDEO_CAPABILITIES}, trackGroups, periodId, TIMELINE);
|
||||||
|
assertThat(result.length).isEqualTo(1);
|
||||||
|
assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelectTracksWithMultipleVideoTracksOverrideReturnsAdaptiveTrackSelection()
|
public void testSelectTracksWithMultipleVideoTracksOverrideReturnsAdaptiveTrackSelection()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@ -1277,6 +1478,36 @@ public final class DefaultTrackSelectorTest {
|
|||||||
/* sampleRate= */ 44100);
|
/* sampleRate= */ 44100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Format buildAudioFormatWithSampleRate(String id, int sampleRate) {
|
||||||
|
return buildAudioFormat(
|
||||||
|
id,
|
||||||
|
MimeTypes.AUDIO_AAC,
|
||||||
|
/* language= */ null,
|
||||||
|
/* selectionFlags= */ 0,
|
||||||
|
/* channelCount= */ 2,
|
||||||
|
sampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Format buildAudioFormatWithChannelCount(String id, int channelCount) {
|
||||||
|
return buildAudioFormat(
|
||||||
|
id,
|
||||||
|
MimeTypes.AUDIO_AAC,
|
||||||
|
/* language= */ null,
|
||||||
|
/* selectionFlags= */ 0,
|
||||||
|
channelCount,
|
||||||
|
/* sampleRate= */ 44100);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Format buildAudioFormatWithMimeType(String id, String mimeType) {
|
||||||
|
return buildAudioFormat(
|
||||||
|
id,
|
||||||
|
mimeType,
|
||||||
|
/* language= */ null,
|
||||||
|
/* selectionFlags= */ 0,
|
||||||
|
/* channelCount= */ 2,
|
||||||
|
/* sampleRate= */ 44100);
|
||||||
|
}
|
||||||
|
|
||||||
private static Format buildAudioFormat(String id) {
|
private static Format buildAudioFormat(String id) {
|
||||||
return buildAudioFormat(
|
return buildAudioFormat(
|
||||||
id,
|
id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user