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

Assuming there is no text language preference.

PiperOrigin-RevId: 244176667
This commit is contained in:
aquilescanta 2019-04-18 14:41:45 +01:00 committed by Andrew Lewis
parent fe65f002a5
commit 4ea2463856
3 changed files with 40 additions and 44 deletions

View file

@ -44,7 +44,7 @@
* MP3: Fix ID3 frame unsychronization
([#5673](https://github.com/google/ExoPlayer/issues/5673)).
* 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
(i.e. if the flag is not set), the 0x82 elementary stream type is now
treated as an SCTE subtitle track
@ -55,6 +55,8 @@
* Update `TrackSelection.Factory` interface to support creating all track
selections together.
* 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:
* Update `DefaultTimeBar` based on duration of media and add parameter to set
the minimum update interval to control the smoothness of the updates

View file

@ -2070,29 +2070,25 @@ public class DefaultTrackSelector extends MappingTrackSelector {
boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0;
int trackScore;
int languageScore = getFormatLanguageScore(format, params.preferredTextLanguage);
if (languageScore > 0
|| (params.selectUndeterminedTextLanguage && formatHasNoLanguage(format))) {
boolean trackHasNoLanguage = formatHasNoLanguage(format);
if (languageScore > 0 || (params.selectUndeterminedTextLanguage && trackHasNoLanguage)) {
if (isDefault) {
trackScore = 17;
trackScore = 11;
} else if (!isForced) {
// 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
// a subset.
trackScore = 13;
trackScore = 7;
} else {
trackScore = 9;
trackScore = 3;
}
trackScore += languageScore;
} else if (isDefault) {
trackScore = 8;
} else if (isForced) {
int preferredAudioLanguageScore =
getFormatLanguageScore(format, params.preferredAudioLanguage);
if (preferredAudioLanguageScore > 0) {
trackScore = 4 + preferredAudioLanguageScore;
} else {
trackScore = 1 + getFormatLanguageScore(format, selectedAudioLanguage);
}
trackScore = 2;
} else if (isForced
&& (getFormatLanguageScore(format, selectedAudioLanguage) > 0
|| (trackHasNoLanguage && stringDefinesNoLanguage(selectedAudioLanguage)))) {
trackScore = 1;
} else {
// Track should not be selected.
continue;
@ -2281,15 +2277,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
&& maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES);
}
/**
* Returns whether a {@link Format} does not define a language.
*
* @param format The {@link Format}.
* @return Whether the {@link Format} does not define a language.
*/
/** Equivalent to {@link #stringDefinesNoLanguage stringDefinesNoLanguage(format.language)}. */
protected static boolean formatHasNoLanguage(Format format) {
return TextUtils.isEmpty(format.language)
|| TextUtils.equals(format.language, C.LANGUAGE_UNDETERMINED);
return stringDefinesNoLanguage(format.language);
}
/**
* Returns whether the given string does not define a language.
*
* @param language The string.
* @return Whether the given string does not define a language.
*/
protected static boolean stringDefinesNoLanguage(@Nullable String language) {
return TextUtils.isEmpty(language) || TextUtils.equals(language, C.LANGUAGE_UNDETERMINED);
}
/**

View file

@ -910,13 +910,8 @@ public final class DefaultTrackSelectorTest {
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
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.
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);
trackSelector.setParameters(
Parameters.DEFAULT
@ -924,15 +919,7 @@ public final class DefaultTrackSelectorTest {
.setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_DEFAULT)
.build());
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections.get(0), trackGroups, forcedOnly);
// 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);
assertNoSelection(result.selections.get(0));
// All selection flags are disabled and there is no language preference, so nothing should be
// selected.
@ -977,6 +964,11 @@ public final class DefaultTrackSelectorTest {
buildTextFormat(/* id= */ "forcedEnglish", /* language= */ "eng", C.SELECTION_FLAG_FORCED);
Format forcedGerman =
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 germanAudio =
buildAudioFormat(
@ -994,16 +986,18 @@ public final class DefaultTrackSelectorTest {
ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES
};
// The audio declares no language. The first forced text track should be selected.
TrackGroupArray trackGroups = wrapFormats(audio, forcedEnglish, forcedGerman);
// Neither the audio nor the forced text track define a language. We select them both under the
// assumption that they have matching language.
TrackGroupArray trackGroups = wrapFormats(audio, forcedNoLanguage);
TrackSelectorResult result =
trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE);
assertFixedSelection(result.selections.get(1), trackGroups, forcedEnglish);
assertFixedSelection(result.selections.get(1), trackGroups, forcedNoLanguage);
// Ditto.
trackGroups = wrapFormats(audio, forcedGerman, forcedEnglish);
// No forced text track should be selected because none of the forced text tracks' languages
// matches the selected audio language.
trackGroups = wrapFormats(audio, forcedEnglish, forcedGerman);
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.
trackGroups = wrapFormats(germanAudio, forcedGerman, forcedEnglish);