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 822fd03fdf..70c4ad14a5 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 @@ -2133,11 +2133,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { getAdaptiveAudioTracks( selectedGroup, formatSupports[selectedGroupIndex], + selectedTrackIndex, params.maxAudioBitrate, params.allowAudioMixedMimeTypeAdaptiveness, params.allowAudioMixedSampleRateAdaptiveness, params.allowAudioMixedChannelCountAdaptiveness); - if (adaptiveTracks.length > 0) { + if (adaptiveTracks.length > 1) { definition = new TrackSelection.Definition(selectedGroup, adaptiveTracks); } } @@ -2152,100 +2153,49 @@ public class DefaultTrackSelector extends MappingTrackSelector { private static int[] getAdaptiveAudioTracks( TrackGroup group, @Capabilities int[] formatSupport, + int primaryTrackIndex, int maxAudioBitrate, boolean allowMixedMimeTypeAdaptiveness, boolean allowMixedSampleRateAdaptiveness, boolean allowAudioMixedChannelCountAdaptiveness) { - int selectedConfigurationTrackCount = 0; - AudioConfigurationTuple selectedConfiguration = null; - HashSet seenConfigurationTuples = new HashSet<>(); - for (int i = 0; i < group.length; i++) { - Format format = group.getFormat(i); - AudioConfigurationTuple configuration = - new AudioConfigurationTuple( - format.channelCount, format.sampleRate, format.sampleMimeType); - if (seenConfigurationTuples.add(configuration)) { - int configurationCount = - getAdaptiveAudioTrackCount( - group, - formatSupport, - configuration, - maxAudioBitrate, - allowMixedMimeTypeAdaptiveness, - allowMixedSampleRateAdaptiveness, - allowAudioMixedChannelCountAdaptiveness); - if (configurationCount > selectedConfigurationTrackCount) { - selectedConfiguration = configuration; - selectedConfigurationTrackCount = configurationCount; - } - } - } - - if (selectedConfigurationTrackCount > 1) { - Assertions.checkNotNull(selectedConfiguration); - int[] adaptiveIndices = new int[selectedConfigurationTrackCount]; - int index = 0; - for (int i = 0; i < group.length; i++) { - Format format = group.getFormat(i); - if (isSupportedAdaptiveAudioTrack( - format, - formatSupport[i], - selectedConfiguration, - maxAudioBitrate, - allowMixedMimeTypeAdaptiveness, - allowMixedSampleRateAdaptiveness, - allowAudioMixedChannelCountAdaptiveness)) { - adaptiveIndices[index++] = i; - } - } - return adaptiveIndices; - } - return NO_TRACKS; - } - - private static int getAdaptiveAudioTrackCount( - TrackGroup group, - @Capabilities int[] formatSupport, - AudioConfigurationTuple configuration, - int maxAudioBitrate, - boolean allowMixedMimeTypeAdaptiveness, - boolean allowMixedSampleRateAdaptiveness, - boolean allowAudioMixedChannelCountAdaptiveness) { + Format primaryFormat = group.getFormat(primaryTrackIndex); + int[] adaptiveIndices = new int[group.length]; int count = 0; for (int i = 0; i < group.length; i++) { - if (isSupportedAdaptiveAudioTrack( - group.getFormat(i), - formatSupport[i], - configuration, - maxAudioBitrate, - allowMixedMimeTypeAdaptiveness, - allowMixedSampleRateAdaptiveness, - allowAudioMixedChannelCountAdaptiveness)) { - count++; + if (i == primaryTrackIndex + || isSupportedAdaptiveAudioTrack( + group.getFormat(i), + formatSupport[i], + primaryFormat, + maxAudioBitrate, + allowMixedMimeTypeAdaptiveness, + allowMixedSampleRateAdaptiveness, + allowAudioMixedChannelCountAdaptiveness)) { + adaptiveIndices[count++] = i; } } - return count; + return Arrays.copyOf(adaptiveIndices, count); } private static boolean isSupportedAdaptiveAudioTrack( Format format, @Capabilities int formatSupport, - AudioConfigurationTuple configuration, + Format primaryFormat, int maxAudioBitrate, boolean allowMixedMimeTypeAdaptiveness, boolean allowMixedSampleRateAdaptiveness, boolean allowAudioMixedChannelCountAdaptiveness) { - return isSupported(formatSupport, false) + return isSupported(formatSupport, /* allowExceedsCapabilities= */ false) && (format.bitrate == Format.NO_VALUE || format.bitrate <= maxAudioBitrate) && (allowAudioMixedChannelCountAdaptiveness || (format.channelCount != Format.NO_VALUE - && format.channelCount == configuration.channelCount)) + && format.channelCount == primaryFormat.channelCount)) && (allowMixedMimeTypeAdaptiveness || (format.sampleMimeType != null - && TextUtils.equals(format.sampleMimeType, configuration.mimeType))) + && TextUtils.equals(format.sampleMimeType, primaryFormat.sampleMimeType))) && (allowMixedSampleRateAdaptiveness || (format.sampleRate != Format.NO_VALUE - && format.sampleRate == configuration.sampleRate)); + && format.sampleRate == primaryFormat.sampleRate)); } // Text track selection implementation. @@ -2705,41 +2655,6 @@ public class DefaultTrackSelector extends MappingTrackSelector { } } - private static final class AudioConfigurationTuple { - - public final int channelCount; - public final int sampleRate; - @Nullable public final String mimeType; - - public AudioConfigurationTuple(int channelCount, int sampleRate, @Nullable String mimeType) { - this.channelCount = channelCount; - this.sampleRate = sampleRate; - this.mimeType = mimeType; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - AudioConfigurationTuple other = (AudioConfigurationTuple) obj; - return channelCount == other.channelCount && sampleRate == other.sampleRate - && TextUtils.equals(mimeType, other.mimeType); - } - - @Override - public int hashCode() { - int result = channelCount; - result = 31 * result + sampleRate; - result = 31 * result + (mimeType != null ? mimeType.hashCode() : 0); - return result; - } - - } - /** Represents how well a text track matches the selection {@link Parameters}. */ protected static final class TextTrackScore implements Comparable { diff --git a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java index 62d38187c4..6cd56924ef 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java @@ -1282,6 +1282,37 @@ public final class DefaultTrackSelectorTest { assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 1); } + @Test + public void selectTracks_multipleAudioTracks_selectsAllTracksInBestConfigurationOnly() + throws Exception { + TrackGroupArray trackGroups = + singleTrackGroup( + buildAudioFormatWithConfiguration( + /* id= */ "0", /* channelCount= */ 6, MimeTypes.AUDIO_AAC, /* sampleRate= */ 44100), + buildAudioFormatWithConfiguration( + /* id= */ "1", /* channelCount= */ 2, MimeTypes.AUDIO_AAC, /* sampleRate= */ 44100), + buildAudioFormatWithConfiguration( + /* id= */ "2", /* channelCount= */ 6, MimeTypes.AUDIO_AC3, /* sampleRate= */ 44100), + buildAudioFormatWithConfiguration( + /* id= */ "3", /* channelCount= */ 6, MimeTypes.AUDIO_AAC, /* sampleRate= */ 22050), + buildAudioFormatWithConfiguration( + /* id= */ "4", /* channelCount= */ 6, MimeTypes.AUDIO_AAC, /* sampleRate= */ 22050), + buildAudioFormatWithConfiguration( + /* id= */ "5", /* channelCount= */ 6, MimeTypes.AUDIO_AAC, /* sampleRate= */ 22050), + buildAudioFormatWithConfiguration( + /* id= */ "6", + /* channelCount= */ 6, + MimeTypes.AUDIO_AAC, + /* sampleRate= */ 44100)); + + TrackSelectorResult result = + trackSelector.selectTracks( + new RendererCapabilities[] {AUDIO_CAPABILITIES}, trackGroups, periodId, TIMELINE); + + assertThat(result.length).isEqualTo(1); + assertAdaptiveSelection(result.selections.get(0), trackGroups.get(0), 0, 6); + } + @Test public void testSelectTracksWithMultipleAudioTracksWithMixedSampleRates() throws Exception { Format highSampleRateAudioFormat = @@ -1709,6 +1740,18 @@ public final class DefaultTrackSelectorTest { /* sampleRate= */ 44100); } + private static Format buildAudioFormatWithConfiguration( + String id, int channelCount, String mimeType, int sampleRate) { + return buildAudioFormat( + id, + mimeType, + /* bitrate= */ Format.NO_VALUE, + /* language= */ null, + /* selectionFlags= */ 0, + channelCount, + sampleRate); + } + private static Format buildAudioFormat(String id) { return buildAudioFormat( id,