Commit b6337adc by aquilescanta Committed by Oliver Woodman

Avoid selecting a forced text track that doesn't match the audio selection

Assuming there is no text language preference.

PiperOrigin-RevId: 244176667
parent a501f8c2
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
* MP3: Fix ID3 frame unsychronization * MP3: Fix ID3 frame unsychronization
([#5673](https://github.com/google/ExoPlayer/issues/5673)). ([#5673](https://github.com/google/ExoPlayer/issues/5673)).
* MP3: Fix playback of badly clipped files * MP3: Fix playback of badly clipped files
([#5772](https://github.com/google/ExoPlayer/issues/5772)). ([#5772](https://github.com/google/ExoPlayer/issues/5772)).
* MPEG-TS: Enable HDMV DTS stream detection only if a flag is set. By default * MPEG-TS: Enable HDMV DTS stream detection only if a flag is set. By default
(i.e. if the flag is not set), the 0x82 elementary stream type is now (i.e. if the flag is not set), the 0x82 elementary stream type is now
treated as an SCTE subtitle track treated as an SCTE subtitle track
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
* Update `TrackSelection.Factory` interface to support creating all track * Update `TrackSelection.Factory` interface to support creating all track
selections together. selections together.
* Allow to specify a selection reason for a `SelectionOverride`. * Allow to specify a selection reason for a `SelectionOverride`.
* When no text language preference matches, only select forced text tracks
whose language matches the selected audio language.
* UI: * UI:
* Update `DefaultTimeBar` based on duration of media and add parameter to set * Update `DefaultTimeBar` based on duration of media and add parameter to set
the minimum update interval to control the smoothness of the updates the minimum update interval to control the smoothness of the updates
......
...@@ -2070,29 +2070,25 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2070,29 +2070,25 @@ public class DefaultTrackSelector extends MappingTrackSelector {
boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0; boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0;
int trackScore; int trackScore;
int languageScore = getFormatLanguageScore(format, params.preferredTextLanguage); int languageScore = getFormatLanguageScore(format, params.preferredTextLanguage);
if (languageScore > 0 boolean trackHasNoLanguage = formatHasNoLanguage(format);
|| (params.selectUndeterminedTextLanguage && formatHasNoLanguage(format))) { if (languageScore > 0 || (params.selectUndeterminedTextLanguage && trackHasNoLanguage)) {
if (isDefault) { if (isDefault) {
trackScore = 17; trackScore = 11;
} else if (!isForced) { } else if (!isForced) {
// Prefer non-forced to forced if a preferred text language has been specified. Where // Prefer non-forced to forced if a preferred text language has been specified. Where
// both are provided the non-forced track will usually contain the forced subtitles as // both are provided the non-forced track will usually contain the forced subtitles as
// a subset. // a subset.
trackScore = 13; trackScore = 7;
} else { } else {
trackScore = 9; trackScore = 3;
} }
trackScore += languageScore; trackScore += languageScore;
} else if (isDefault) { } else if (isDefault) {
trackScore = 8; trackScore = 2;
} else if (isForced) { } else if (isForced
int preferredAudioLanguageScore = && (getFormatLanguageScore(format, selectedAudioLanguage) > 0
getFormatLanguageScore(format, params.preferredAudioLanguage); || (trackHasNoLanguage && stringDefinesNoLanguage(selectedAudioLanguage)))) {
if (preferredAudioLanguageScore > 0) { trackScore = 1;
trackScore = 4 + preferredAudioLanguageScore;
} else {
trackScore = 1 + getFormatLanguageScore(format, selectedAudioLanguage);
}
} else { } else {
// Track should not be selected. // Track should not be selected.
continue; continue;
...@@ -2281,15 +2277,19 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2281,15 +2277,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
&& maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES); && maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES);
} }
/** Equivalent to {@link #stringDefinesNoLanguage stringDefinesNoLanguage(format.language)}. */
protected static boolean formatHasNoLanguage(Format format) {
return stringDefinesNoLanguage(format.language);
}
/** /**
* Returns whether a {@link Format} does not define a language. * Returns whether the given string does not define a language.
* *
* @param format The {@link Format}. * @param language The string.
* @return Whether the {@link Format} does not define a language. * @return Whether the given string does not define a language.
*/ */
protected static boolean formatHasNoLanguage(Format format) { protected static boolean stringDefinesNoLanguage(@Nullable String language) {
return TextUtils.isEmpty(format.language) return TextUtils.isEmpty(language) || TextUtils.equals(language, C.LANGUAGE_UNDETERMINED);
|| TextUtils.equals(format.language, C.LANGUAGE_UNDETERMINED);
} }
/** /**
......
...@@ -910,13 +910,8 @@ public final class DefaultTrackSelectorTest { ...@@ -910,13 +910,8 @@ public final class DefaultTrackSelectorTest {
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE); result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections.get(0), trackGroups, defaultOnly); assertFixedSelection(result.selections.get(0), trackGroups, defaultOnly);
// With no language preference and no text track flagged as default, the first forced should be // Default flags are disabled and no language preference is provided, so no text track is
// selected. // selected.
trackGroups = wrapFormats(forcedOnly, noFlag);
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections.get(0), trackGroups, forcedOnly);
// Default flags are disabled, so the first track flagged as forced should be selected.
trackGroups = wrapFormats(defaultOnly, noFlag, forcedOnly, forcedDefault); trackGroups = wrapFormats(defaultOnly, noFlag, forcedOnly, forcedDefault);
trackSelector.setParameters( trackSelector.setParameters(
Parameters.DEFAULT Parameters.DEFAULT
...@@ -924,15 +919,7 @@ public final class DefaultTrackSelectorTest { ...@@ -924,15 +919,7 @@ public final class DefaultTrackSelectorTest {
.setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_DEFAULT) .setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_DEFAULT)
.build()); .build());
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE); result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections.get(0), trackGroups, forcedOnly); assertNoSelection(result.selections.get(0));
// Default flags are disabled, but there is a text track flagged as forced whose language
// matches the preferred audio language.
trackGroups = wrapFormats(forcedDefault, forcedOnly, defaultOnly, noFlag, forcedOnlySpanish);
trackSelector.setParameters(
trackSelector.getParameters().buildUpon().setPreferredTextLanguage("spa").build());
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections.get(0), trackGroups, forcedOnlySpanish);
// All selection flags are disabled and there is no language preference, so nothing should be // All selection flags are disabled and there is no language preference, so nothing should be
// selected. // selected.
...@@ -977,6 +964,11 @@ public final class DefaultTrackSelectorTest { ...@@ -977,6 +964,11 @@ public final class DefaultTrackSelectorTest {
buildTextFormat(/* id= */ "forcedEnglish", /* language= */ "eng", C.SELECTION_FLAG_FORCED); buildTextFormat(/* id= */ "forcedEnglish", /* language= */ "eng", C.SELECTION_FLAG_FORCED);
Format forcedGerman = Format forcedGerman =
buildTextFormat(/* id= */ "forcedGerman", /* language= */ "deu", C.SELECTION_FLAG_FORCED); buildTextFormat(/* id= */ "forcedGerman", /* language= */ "deu", C.SELECTION_FLAG_FORCED);
Format forcedNoLanguage =
buildTextFormat(
/* id= */ "forcedNoLanguage",
/* language= */ C.LANGUAGE_UNDETERMINED,
C.SELECTION_FLAG_FORCED);
Format audio = buildAudioFormat(/* id= */ "audio"); Format audio = buildAudioFormat(/* id= */ "audio");
Format germanAudio = Format germanAudio =
buildAudioFormat( buildAudioFormat(
...@@ -994,16 +986,18 @@ public final class DefaultTrackSelectorTest { ...@@ -994,16 +986,18 @@ public final class DefaultTrackSelectorTest {
ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES
}; };
// The audio declares no language. The first forced text track should be selected. // Neither the audio nor the forced text track define a language. We select them both under the
TrackGroupArray trackGroups = wrapFormats(audio, forcedEnglish, forcedGerman); // assumption that they have matching language.
TrackGroupArray trackGroups = wrapFormats(audio, forcedNoLanguage);
TrackSelectorResult result = TrackSelectorResult result =
trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE); trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections.get(1), trackGroups, forcedEnglish); assertFixedSelection(result.selections.get(1), trackGroups, forcedNoLanguage);
// Ditto. // No forced text track should be selected because none of the forced text tracks' languages
trackGroups = wrapFormats(audio, forcedGerman, forcedEnglish); // matches the selected audio language.
trackGroups = wrapFormats(audio, forcedEnglish, forcedGerman);
result = trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE); result = trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections.get(1), trackGroups, forcedGerman); assertNoSelection(result.selections.get(1));
// The audio declares german. The german forced track should be selected. // The audio declares german. The german forced track should be selected.
trackGroups = wrapFormats(germanAudio, forcedGerman, forcedEnglish); trackGroups = wrapFormats(germanAudio, forcedGerman, forcedEnglish);
......
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