From 5f4887173143bc53d069f7e61165141b7d206ea2 Mon Sep 17 00:00:00 2001 From: Yannick RUI Date: Thu, 5 Sep 2019 17:31:24 +0200 Subject: [PATCH] Count the number of matches for role flags. Select a track with matching role flags even if someone specifies a preferred role flgs without providing a preferred language Prefer track without captions or describing music and sound flag when no role flag preference is provided. --- .../trackselection/DefaultTrackSelector.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) 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 0c96309fdc..f0b6f7e69b 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 @@ -2695,6 +2695,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { private final boolean isWithinRendererCapabilities; private final boolean isDefault; private final boolean hasPreferredIsForcedFlag; + private final boolean hasPreferredRoleFlags; + private final int hasCaptionRoleFlags; private final int preferredLanguageScore; private final int preferredRoleFlagsScore; private final int selectedAudioLanguageScore; @@ -2713,18 +2715,21 @@ public class DefaultTrackSelector extends MappingTrackSelector { preferredLanguageScore = getFormatLanguageScore( format, parameters.preferredTextLanguage, parameters.selectUndeterminedTextLanguage); - preferredRoleFlagsScore = format.roleFlags & parameters.preferredRoleFlags; + preferredRoleFlagsScore = Integer.bitCount(format.roleFlags & parameters.preferredRoleFlags); // 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); + hasPreferredRoleFlags = parameters.preferredRoleFlags > 0; + hasCaptionRoleFlags = Integer.bitCount(format.roleFlags + & (C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND)); boolean selectedAudioLanguageUndetermined = normalizeUndeterminedLanguageToNull(selectedAudioLanguage) == null; selectedAudioLanguageScore = getFormatLanguageScore(format, selectedAudioLanguage, selectedAudioLanguageUndetermined); isWithinConstraints = - (preferredLanguageScore > 0 || (parameters.preferredTextLanguage == null && selectedAudioLanguageScore > 0 && preferredRoleFlagsScore > 0)) || isDefault || (isForced && selectedAudioLanguageScore > 0); + (preferredLanguageScore > 0 || (parameters.preferredTextLanguage == null && preferredRoleFlagsScore > 0)) || isDefault || (isForced && selectedAudioLanguageScore > 0); } /** @@ -2742,16 +2747,23 @@ public class DefaultTrackSelector extends MappingTrackSelector { if (this.preferredLanguageScore != other.preferredLanguageScore) { return compareInts(this.preferredLanguageScore, other.preferredLanguageScore); } - if (this.preferredRoleFlagsScore != other.preferredRoleFlagsScore) { - return compareInts(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore); - } if (this.isDefault != other.isDefault) { return this.isDefault ? 1 : -1; } if (this.hasPreferredIsForcedFlag != other.hasPreferredIsForcedFlag) { return this.hasPreferredIsForcedFlag ? 1 : -1; } - return compareInts(this.selectedAudioLanguageScore, other.selectedAudioLanguageScore); + if (this.selectedAudioLanguageScore != other.selectedAudioLanguageScore) { + return compareInts(this.selectedAudioLanguageScore, other.selectedAudioLanguageScore); + } + + // If no role flag preference is provided in the parameters, prefer tracks + // without C.ROLE_FLAG_CAPTION or C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND + // No specification means that non-captioning text tracks are preferred. + if (!this.hasPreferredRoleFlags) { + return compareInts(other.hasCaptionRoleFlags, this.hasCaptionRoleFlags); + } + return compareInts(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore); } } }