From 560c8c8760cd6f5b085e51030442bce8a4d75ea8 Mon Sep 17 00:00:00 2001 From: tonihei Date: Wed, 24 Jul 2019 11:05:27 +0100 Subject: [PATCH] Simplify and improve text selection logic. This changes the logic in the following ways: - If no preferred language is matched, prefer better scores for the selected audio language. - If a preferred language is matched, always prefer the better match irrespective of default or forced flags. - If a preferred language score and the isForced flag is the same, prefer tracks with a better selected audio language match. PiperOrigin-RevId: 259707430 --- RELEASENOTES.md | 2 ++ .../trackselection/DefaultTrackSelector.java | 35 ++++++++----------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 602480d9f8..b490e3a314 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -16,6 +16,8 @@ provided ([#6325](https://github.com/google/ExoPlayer/issues/6325)). * Add `HttpDataSource.getResponseCode` to provide the status code associated with the most recent HTTP response. +* Improve text selection logic to always prefer the better language matches + over other selection parameters. * OkHttp extension: Upgrade OkHttp to fix HTTP2 socket timeout issue ([#4078](https://github.com/google/ExoPlayer/issues/4078)). * RTMP extension: Upgrade LibRtmp-Client-for-Android to fix RTMP playback issues diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java index 5e5ad3b4bc..0d35fcd65a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java @@ -2638,9 +2638,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { private final boolean isWithinRendererCapabilities; private final boolean isDefault; - private final boolean isForced; + private final boolean hasPreferredIsForcedFlag; private final int preferredLanguageScore; - private final boolean isForcedAndSelectedAudioLanguage; + private final int selectedAudioLanguageScore; public TextTrackScore( Format format, @@ -2652,17 +2652,21 @@ public class DefaultTrackSelector extends MappingTrackSelector { int maskedSelectionFlags = format.selectionFlags & ~parameters.disabledTextTrackSelectionFlags; isDefault = (maskedSelectionFlags & C.SELECTION_FLAG_DEFAULT) != 0; - isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0; + boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0; preferredLanguageScore = getFormatLanguageScore( format, parameters.preferredTextLanguage, parameters.selectUndeterminedTextLanguage); + // Prefer non-forced to forced if a preferred text language has been matched. Where both are + // provided the non-forced track will usually contain the forced subtitles as a subset. + // Otherwise, prefer a forced track. + hasPreferredIsForcedFlag = + (preferredLanguageScore > 0 && !isForced) || (preferredLanguageScore == 0 && isForced); boolean selectedAudioLanguageUndetermined = normalizeUndeterminedLanguageToNull(selectedAudioLanguage) == null; - int selectedAudioLanguageScore = + selectedAudioLanguageScore = getFormatLanguageScore(format, selectedAudioLanguage, selectedAudioLanguageUndetermined); - isForcedAndSelectedAudioLanguage = isForced && selectedAudioLanguageScore > 0; isWithinConstraints = - preferredLanguageScore > 0 || isDefault || isForcedAndSelectedAudioLanguage; + preferredLanguageScore > 0 || isDefault || (isForced && selectedAudioLanguageScore > 0); } /** @@ -2677,25 +2681,16 @@ public class DefaultTrackSelector extends MappingTrackSelector { if (this.isWithinRendererCapabilities != other.isWithinRendererCapabilities) { return this.isWithinRendererCapabilities ? 1 : -1; } - if ((this.preferredLanguageScore > 0) != (other.preferredLanguageScore > 0)) { - return this.preferredLanguageScore > 0 ? 1 : -1; + if (this.preferredLanguageScore != other.preferredLanguageScore) { + return compareInts(this.preferredLanguageScore, other.preferredLanguageScore); } if (this.isDefault != other.isDefault) { return this.isDefault ? 1 : -1; } - if (this.preferredLanguageScore > 0) { - if (this.isForced != other.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. - return !this.isForced ? 1 : -1; - } - return compareInts(this.preferredLanguageScore, other.preferredLanguageScore); + if (this.hasPreferredIsForcedFlag != other.hasPreferredIsForcedFlag) { + return this.hasPreferredIsForcedFlag ? 1 : -1; } - if (this.isForcedAndSelectedAudioLanguage != other.isForcedAndSelectedAudioLanguage) { - return this.isForcedAndSelectedAudioLanguage ? 1 : -1; - } - return 0; + return compareInts(this.selectedAudioLanguageScore, other.selectedAudioLanguageScore); } } }