mirror of
https://github.com/samsonjs/media.git
synced 2026-03-26 09:35:47 +00:00
Add a bitmask for text tracks' selection flags in DefaultTrackSelector
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=179039563
This commit is contained in:
parent
37a275f67e
commit
0ccf816a5c
3 changed files with 226 additions and 32 deletions
|
|
@ -29,6 +29,8 @@
|
|||
([#3149](https://github.com/google/ExoPlayer/issues/3149)).
|
||||
* DefaultTrackSelector: Replace `DefaultTrackSelector.Parameters` copy methods
|
||||
with a builder.
|
||||
* DefaultTrackSelector: Support disabling of individual text track selection
|
||||
flags.
|
||||
* New Cast extension: Simplifies toggling between local and Cast playbacks.
|
||||
|
||||
### 2.6.1 ###
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
private String preferredAudioLanguage;
|
||||
private String preferredTextLanguage;
|
||||
private boolean selectUndeterminedTextLanguage;
|
||||
private int disabledTextTrackSelectionFlags;
|
||||
private boolean forceLowestBitrate;
|
||||
private boolean allowMixedMimeAdaptiveness;
|
||||
private boolean allowNonSeamlessAdaptiveness;
|
||||
|
|
@ -109,6 +110,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
preferredAudioLanguage = initialValues.preferredAudioLanguage;
|
||||
preferredTextLanguage = initialValues.preferredTextLanguage;
|
||||
selectUndeterminedTextLanguage = initialValues.selectUndeterminedTextLanguage;
|
||||
disabledTextTrackSelectionFlags = initialValues.disabledTextTrackSelectionFlags;
|
||||
forceLowestBitrate = initialValues.forceLowestBitrate;
|
||||
allowMixedMimeAdaptiveness = initialValues.allowMixedMimeAdaptiveness;
|
||||
allowNonSeamlessAdaptiveness = initialValues.allowNonSeamlessAdaptiveness;
|
||||
|
|
@ -153,6 +155,17 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link Parameters#disabledTextTrackSelectionFlags}.
|
||||
*
|
||||
* @return This builder.
|
||||
*/
|
||||
public ParametersBuilder setDisabledTextTrackSelectionFlags(
|
||||
int disabledTextTrackSelectionFlags) {
|
||||
this.disabledTextTrackSelectionFlags = disabledTextTrackSelectionFlags;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link Parameters#forceLowestBitrate}.
|
||||
*
|
||||
|
|
@ -287,11 +300,22 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
* Builds a {@link Parameters} instance with the selected values.
|
||||
*/
|
||||
public Parameters build() {
|
||||
return new Parameters(preferredAudioLanguage, preferredTextLanguage,
|
||||
selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
|
||||
allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
|
||||
exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
|
||||
viewportHeight, viewportOrientationMayChange);
|
||||
return new Parameters(
|
||||
preferredAudioLanguage,
|
||||
preferredTextLanguage,
|
||||
selectUndeterminedTextLanguage,
|
||||
disabledTextTrackSelectionFlags,
|
||||
forceLowestBitrate,
|
||||
allowMixedMimeAdaptiveness,
|
||||
allowNonSeamlessAdaptiveness,
|
||||
maxVideoWidth,
|
||||
maxVideoHeight,
|
||||
maxVideoBitrate,
|
||||
exceedVideoConstraintsIfNecessary,
|
||||
exceedRendererCapabilitiesIfNecessary,
|
||||
viewportWidth,
|
||||
viewportHeight,
|
||||
viewportOrientationMayChange);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -303,19 +327,21 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
|
||||
/**
|
||||
* An instance with default values:
|
||||
*
|
||||
* <ul>
|
||||
* <li>No preferred audio language.</li>
|
||||
* <li>No preferred text language.</li>
|
||||
* <li>Text tracks with undetermined language are not selected if no track with
|
||||
* {@link #preferredTextLanguage} is available.</li>
|
||||
* <li>Lowest bitrate track selections are not forced.</li>
|
||||
* <li>Adaptation between different mime types is not allowed.</li>
|
||||
* <li>Non seamless adaptation is allowed.</li>
|
||||
* <li>No max limit for video width/height.</li>
|
||||
* <li>No max video bitrate.</li>
|
||||
* <li>Video constraints are exceeded if no supported selection can be made otherwise.</li>
|
||||
* <li>Renderer capabilities are exceeded if no supported selection can be made.</li>
|
||||
* <li>No viewport constraints.</li>
|
||||
* <li>No preferred audio language.
|
||||
* <li>No preferred text language.
|
||||
* <li>Text tracks with undetermined language are not selected if no track with {@link
|
||||
* #preferredTextLanguage} is available.
|
||||
* <li>All selection flags are considered for text track selections.
|
||||
* <li>Lowest bitrate track selections are not forced.
|
||||
* <li>Adaptation between different mime types is not allowed.
|
||||
* <li>Non seamless adaptation is allowed.
|
||||
* <li>No max limit for video width/height.
|
||||
* <li>No max video bitrate.
|
||||
* <li>Video constraints are exceeded if no supported selection can be made otherwise.
|
||||
* <li>Renderer capabilities are exceeded if no supported selection can be made.
|
||||
* <li>No viewport constraints.
|
||||
* </ul>
|
||||
*/
|
||||
public static final Parameters DEFAULT = new Parameters();
|
||||
|
|
@ -338,6 +364,11 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
* {@link #preferredTextLanguage} is available, or if {@link #preferredTextLanguage} is unset.
|
||||
*/
|
||||
public final boolean selectUndeterminedTextLanguage;
|
||||
/**
|
||||
* Bitmask of selection flags that are disabled for text track selections. See {@link
|
||||
* C.SelectionFlags}.
|
||||
*/
|
||||
public final int disabledTextTrackSelectionFlags;
|
||||
|
||||
// Video
|
||||
/**
|
||||
|
|
@ -392,19 +423,44 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
public final boolean exceedRendererCapabilitiesIfNecessary;
|
||||
|
||||
private Parameters() {
|
||||
this(null, null, false, false, false, true, Integer.MAX_VALUE, Integer.MAX_VALUE,
|
||||
Integer.MAX_VALUE, true, true, Integer.MAX_VALUE, Integer.MAX_VALUE, true);
|
||||
this(
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
Integer.MAX_VALUE,
|
||||
Integer.MAX_VALUE,
|
||||
Integer.MAX_VALUE,
|
||||
true,
|
||||
true,
|
||||
Integer.MAX_VALUE,
|
||||
Integer.MAX_VALUE,
|
||||
true);
|
||||
}
|
||||
|
||||
private Parameters(String preferredAudioLanguage, String preferredTextLanguage,
|
||||
boolean selectUndeterminedTextLanguage, boolean forceLowestBitrate,
|
||||
boolean allowMixedMimeAdaptiveness, boolean allowNonSeamlessAdaptiveness, int maxVideoWidth,
|
||||
int maxVideoHeight, int maxVideoBitrate, boolean exceedVideoConstraintsIfNecessary,
|
||||
boolean exceedRendererCapabilitiesIfNecessary, int viewportWidth, int viewportHeight,
|
||||
private Parameters(
|
||||
String preferredAudioLanguage,
|
||||
String preferredTextLanguage,
|
||||
boolean selectUndeterminedTextLanguage,
|
||||
int disabledTextTrackSelectionFlags,
|
||||
boolean forceLowestBitrate,
|
||||
boolean allowMixedMimeAdaptiveness,
|
||||
boolean allowNonSeamlessAdaptiveness,
|
||||
int maxVideoWidth,
|
||||
int maxVideoHeight,
|
||||
int maxVideoBitrate,
|
||||
boolean exceedVideoConstraintsIfNecessary,
|
||||
boolean exceedRendererCapabilitiesIfNecessary,
|
||||
int viewportWidth,
|
||||
int viewportHeight,
|
||||
boolean viewportOrientationMayChange) {
|
||||
this.preferredAudioLanguage = Util.normalizeLanguageCode(preferredAudioLanguage);
|
||||
this.preferredTextLanguage = Util.normalizeLanguageCode(preferredTextLanguage);
|
||||
this.selectUndeterminedTextLanguage = selectUndeterminedTextLanguage;
|
||||
this.disabledTextTrackSelectionFlags = disabledTextTrackSelectionFlags;
|
||||
this.forceLowestBitrate = forceLowestBitrate;
|
||||
this.allowMixedMimeAdaptiveness = allowMixedMimeAdaptiveness;
|
||||
this.allowNonSeamlessAdaptiveness = allowNonSeamlessAdaptiveness;
|
||||
|
|
@ -434,14 +490,18 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
return false;
|
||||
}
|
||||
Parameters other = (Parameters) obj;
|
||||
return forceLowestBitrate == other.forceLowestBitrate
|
||||
return selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
|
||||
&& disabledTextTrackSelectionFlags == other.disabledTextTrackSelectionFlags
|
||||
&& forceLowestBitrate == other.forceLowestBitrate
|
||||
&& allowMixedMimeAdaptiveness == other.allowMixedMimeAdaptiveness
|
||||
&& allowNonSeamlessAdaptiveness == other.allowNonSeamlessAdaptiveness
|
||||
&& maxVideoWidth == other.maxVideoWidth && maxVideoHeight == other.maxVideoHeight
|
||||
&& maxVideoWidth == other.maxVideoWidth
|
||||
&& maxVideoHeight == other.maxVideoHeight
|
||||
&& exceedVideoConstraintsIfNecessary == other.exceedVideoConstraintsIfNecessary
|
||||
&& exceedRendererCapabilitiesIfNecessary == other.exceedRendererCapabilitiesIfNecessary
|
||||
&& viewportOrientationMayChange == other.viewportOrientationMayChange
|
||||
&& viewportWidth == other.viewportWidth && viewportHeight == other.viewportHeight
|
||||
&& viewportWidth == other.viewportWidth
|
||||
&& viewportHeight == other.viewportHeight
|
||||
&& maxVideoBitrate == other.maxVideoBitrate
|
||||
&& TextUtils.equals(preferredAudioLanguage, other.preferredAudioLanguage)
|
||||
&& TextUtils.equals(preferredTextLanguage, other.preferredTextLanguage);
|
||||
|
|
@ -449,19 +509,21 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = preferredAudioLanguage.hashCode();
|
||||
result = 31 * result + preferredTextLanguage.hashCode();
|
||||
int result = selectUndeterminedTextLanguage ? 1 : 0;
|
||||
result = 31 * result + disabledTextTrackSelectionFlags;
|
||||
result = 31 * result + (forceLowestBitrate ? 1 : 0);
|
||||
result = 31 * result + (allowMixedMimeAdaptiveness ? 1 : 0);
|
||||
result = 31 * result + (allowNonSeamlessAdaptiveness ? 1 : 0);
|
||||
result = 31 * result + maxVideoWidth;
|
||||
result = 31 * result + maxVideoHeight;
|
||||
result = 31 * result + maxVideoBitrate;
|
||||
result = 31 * result + (exceedVideoConstraintsIfNecessary ? 1 : 0);
|
||||
result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0);
|
||||
result = 31 * result + (viewportOrientationMayChange ? 1 : 0);
|
||||
result = 31 * result + viewportWidth;
|
||||
result = 31 * result + viewportHeight;
|
||||
result = 31 * result + maxVideoBitrate;
|
||||
result = 31 * result + preferredAudioLanguage.hashCode();
|
||||
result = 31 * result + preferredTextLanguage.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -923,8 +985,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
|||
if (isSupported(trackFormatSupport[trackIndex],
|
||||
params.exceedRendererCapabilitiesIfNecessary)) {
|
||||
Format format = trackGroup.getFormat(trackIndex);
|
||||
boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
|
||||
boolean isForced = (format.selectionFlags & C.SELECTION_FLAG_FORCED) != 0;
|
||||
int maskedSelectionFlags =
|
||||
format.selectionFlags & ~params.disabledTextTrackSelectionFlags;
|
||||
boolean isDefault = (maskedSelectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
|
||||
boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0;
|
||||
int trackScore;
|
||||
boolean preferredLanguageFound = formatHasLanguage(format, params.preferredTextLanguage);
|
||||
if (preferredLanguageFound
|
||||
|
|
|
|||
|
|
@ -529,6 +529,134 @@ public final class DefaultTrackSelectorTest {
|
|||
.isEqualTo(lowerSampleRateHigherBitrateFormat);
|
||||
}
|
||||
|
||||
/** Tests text track selection flags. */
|
||||
@Test
|
||||
public void testsTextTrackSelectionFlags() throws ExoPlaybackException {
|
||||
Format forcedOnly =
|
||||
Format.createTextContainerFormat(
|
||||
"forcedOnly",
|
||||
null,
|
||||
MimeTypes.TEXT_VTT,
|
||||
null,
|
||||
Format.NO_VALUE,
|
||||
C.SELECTION_FLAG_FORCED,
|
||||
"eng");
|
||||
Format forcedDefault =
|
||||
Format.createTextContainerFormat(
|
||||
"forcedDefault",
|
||||
null,
|
||||
MimeTypes.TEXT_VTT,
|
||||
null,
|
||||
Format.NO_VALUE,
|
||||
C.SELECTION_FLAG_FORCED | C.SELECTION_FLAG_DEFAULT,
|
||||
"eng");
|
||||
Format defaultOnly =
|
||||
Format.createTextContainerFormat(
|
||||
"defaultOnly",
|
||||
null,
|
||||
MimeTypes.TEXT_VTT,
|
||||
null,
|
||||
Format.NO_VALUE,
|
||||
C.SELECTION_FLAG_DEFAULT,
|
||||
"eng");
|
||||
Format forcedOnlySpanish =
|
||||
Format.createTextContainerFormat(
|
||||
"forcedOnlySpanish",
|
||||
null,
|
||||
MimeTypes.TEXT_VTT,
|
||||
null,
|
||||
Format.NO_VALUE,
|
||||
C.SELECTION_FLAG_FORCED,
|
||||
"spa");
|
||||
Format noFlag =
|
||||
Format.createTextContainerFormat(
|
||||
"noFlag", null, MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "eng");
|
||||
|
||||
RendererCapabilities[] textRendererCapabilities =
|
||||
new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES};
|
||||
|
||||
TrackSelectorResult result;
|
||||
|
||||
// There is no text language preference, the first track flagged as default should be selected.
|
||||
result =
|
||||
trackSelector.selectTracks(
|
||||
textRendererCapabilities, wrapFormats(forcedOnly, forcedDefault, defaultOnly, noFlag));
|
||||
assertThat(result.selections.get(0).getFormat(0)).isSameAs(forcedDefault);
|
||||
|
||||
// Ditto.
|
||||
result =
|
||||
trackSelector.selectTracks(
|
||||
textRendererCapabilities, wrapFormats(forcedOnly, noFlag, defaultOnly));
|
||||
assertThat(result.selections.get(0).getFormat(0)).isSameAs(defaultOnly);
|
||||
|
||||
// With no language preference and no text track flagged as default, the first forced should be
|
||||
// selected.
|
||||
result = trackSelector.selectTracks(textRendererCapabilities, wrapFormats(forcedOnly, noFlag));
|
||||
assertThat(result.selections.get(0).getFormat(0)).isSameAs(forcedOnly);
|
||||
|
||||
trackSelector.setParameters(
|
||||
Parameters.DEFAULT
|
||||
.buildUpon()
|
||||
.setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
||||
.build());
|
||||
|
||||
// Default flags are disabled, so the first track flagged as forced should be selected.
|
||||
result =
|
||||
trackSelector.selectTracks(
|
||||
textRendererCapabilities, wrapFormats(defaultOnly, noFlag, forcedOnly, forcedDefault));
|
||||
assertThat(result.selections.get(0).getFormat(0)).isSameAs(forcedOnly);
|
||||
|
||||
trackSelector.setParameters(
|
||||
trackSelector.getParameters().buildUpon().setPreferredAudioLanguage("spa").build());
|
||||
|
||||
// Default flags are disabled, but there is a text track flagged as forced whose language
|
||||
// matches the preferred audio language.
|
||||
result =
|
||||
trackSelector.selectTracks(
|
||||
textRendererCapabilities,
|
||||
wrapFormats(forcedDefault, forcedOnly, defaultOnly, noFlag, forcedOnlySpanish));
|
||||
assertThat(result.selections.get(0).getFormat(0)).isSameAs(forcedOnlySpanish);
|
||||
|
||||
trackSelector.setParameters(
|
||||
trackSelector
|
||||
.getParameters()
|
||||
.buildUpon()
|
||||
.setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_DEFAULT | C.SELECTION_FLAG_FORCED)
|
||||
.build());
|
||||
|
||||
// All selection flags are disabled and there is no language preference, so nothing should be
|
||||
// selected.
|
||||
result =
|
||||
trackSelector.selectTracks(
|
||||
textRendererCapabilities, wrapFormats(forcedOnly, forcedDefault, defaultOnly, noFlag));
|
||||
assertThat(result.selections.get(0)).isNull();
|
||||
|
||||
trackSelector.setParameters(
|
||||
Parameters.DEFAULT.buildUpon().setPreferredTextLanguage("eng").build());
|
||||
|
||||
// There is a preferred language, so the first language-matching track flagged as default should
|
||||
// be selected.
|
||||
result =
|
||||
trackSelector.selectTracks(
|
||||
textRendererCapabilities, wrapFormats(forcedOnly, forcedDefault, defaultOnly, noFlag));
|
||||
assertThat(result.selections.get(0).getFormat(0)).isSameAs(forcedDefault);
|
||||
|
||||
trackSelector.setParameters(
|
||||
trackSelector
|
||||
.getParameters()
|
||||
.buildUpon()
|
||||
.setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
||||
.build());
|
||||
|
||||
// Same as above, but the default flag is disabled. If multiple tracks match the preferred
|
||||
// language, those not flagged as forced are preferred, as they likely include the contents of
|
||||
// forced subtitles.
|
||||
result =
|
||||
trackSelector.selectTracks(
|
||||
textRendererCapabilities, wrapFormats(noFlag, forcedOnly, forcedDefault, defaultOnly));
|
||||
assertThat(result.selections.get(0).getFormat(0)).isSameAs(noFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the default track selector will select a text track with undetermined language if no
|
||||
* text track with the preferred language is available but
|
||||
|
|
|
|||
Loading…
Reference in a new issue