From 99eb35179dbf3e6b39bdc752bf9464dfd2c2190f Mon Sep 17 00:00:00 2001 From: tonihei Date: Mon, 29 Nov 2021 10:57:51 +0000 Subject: [PATCH] Update track selection to prefer content over technical preferences. Currently we prefer technical preferences set in the Parameters over content preferences implied by the media. It proably makes more sense in the opposite order to avoid the situation where a non-default track (e.g. commentary) is selected just because it better matches some technical criteria. Also add comments explaining the track selection logic stages. PiperOrigin-RevId: 412840962 --- RELEASENOTES.md | 4 ++++ .../trackselection/DefaultTrackSelector.java | 22 ++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index b317217030..2dcd8eebf5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -5,6 +5,10 @@ * Core library: * Support preferred video role flags in track selection ((#9402)[https://github.com/google/ExoPlayer/issues/9402]). + * Prefer audio content preferences (for example, "default" audio track or + track matching system Locale language) over technical track selection + constraints (for example, preferred MIME type, or maximum channel + count). * Extractors: * Fix inconsistency with spec in H.265 SPS nal units parsing ((#9719)[https://github.com/google/ExoPlayer/issues/9719]). 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 24ff480b5e..21e05f33bb 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 @@ -2558,14 +2558,18 @@ public class DefaultTrackSelector extends MappingTrackSelector { : FORMAT_VALUE_ORDERING.reverse(); return ComparisonChain.start() .compareFalseFirst(this.isWithinRendererCapabilities, other.isWithinRendererCapabilities) + // 1. Compare match with specific content preferences set by the parameters. .compare(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore) + // 2. Compare match with implicit content preferences set by the media. .compareFalseFirst(this.hasMainOrNoRoleFlag, other.hasMainOrNoRoleFlag) + // 3. Compare match with technical preferences set by the parameters. .compareFalseFirst(this.isWithinMaxConstraints, other.isWithinMaxConstraints) .compareFalseFirst(this.isWithinMinConstraints, other.isWithinMinConstraints) .compare( this.preferredMimeTypeMatchIndex, other.preferredMimeTypeMatchIndex, Ordering.natural().reverse()) + // 4. Compare technical quality. .compare( this.bitrate, other.bitrate, @@ -2675,13 +2679,22 @@ public class DefaultTrackSelector extends MappingTrackSelector { : FORMAT_VALUE_ORDERING.reverse(); return ComparisonChain.start() .compareFalseFirst(this.isWithinRendererCapabilities, other.isWithinRendererCapabilities) + // 1. Compare match with specific content preferences set by the parameters. .compare( this.preferredLanguageIndex, other.preferredLanguageIndex, Ordering.natural().reverse()) .compare(this.preferredLanguageScore, other.preferredLanguageScore) .compare(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore) + // 2. Compare match with implicit content preferences set by the media or the system. + .compareFalseFirst(this.isDefaultSelectionFlag, other.isDefaultSelectionFlag) .compareFalseFirst(this.hasMainOrNoRoleFlag, other.hasMainOrNoRoleFlag) + .compare( + this.localeLanguageMatchIndex, + other.localeLanguageMatchIndex, + Ordering.natural().reverse()) + .compare(this.localeLanguageScore, other.localeLanguageScore) + // 3. Compare match with technical preferences set by the parameters. .compareFalseFirst(this.isWithinConstraints, other.isWithinConstraints) .compare( this.preferredMimeTypeMatchIndex, @@ -2691,12 +2704,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { this.bitrate, other.bitrate, parameters.forceLowestBitrate ? FORMAT_VALUE_ORDERING.reverse() : NO_ORDER) - .compareFalseFirst(this.isDefaultSelectionFlag, other.isDefaultSelectionFlag) - .compare( - this.localeLanguageMatchIndex, - other.localeLanguageMatchIndex, - Ordering.natural().reverse()) - .compare(this.localeLanguageScore, other.localeLanguageScore) + // 4. Compare technical quality. .compare(this.channelCount, other.channelCount, qualityOrdering) .compare(this.sampleRate, other.sampleRate, qualityOrdering) .compare( @@ -2785,12 +2793,14 @@ public class DefaultTrackSelector extends MappingTrackSelector { ComparisonChain.start() .compareFalseFirst( this.isWithinRendererCapabilities, other.isWithinRendererCapabilities) + // 1. Compare match with specific content preferences set by the parameters. .compare( this.preferredLanguageIndex, other.preferredLanguageIndex, Ordering.natural().reverse()) .compare(this.preferredLanguageScore, other.preferredLanguageScore) .compare(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore) + // 2. Compare match with implicit content preferences set by the media. .compareFalseFirst(this.isDefault, other.isDefault) .compare( this.isForced,