Commit 66aa35f5 by tonihei Committed by kim-vde

Select adaptive audio tracks based on the best track in the group.

Currently, the subset of audio tracks for adaptation is selected
purely based on the size of the subset in the track group, completely
ignoring the previously selected best individual track.

This change ignores all tracks with a different configuration than the
previously selected best track.

PiperOrigin-RevId: 294231806
parent 0eb02671
...@@ -2133,11 +2133,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2133,11 +2133,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
getAdaptiveAudioTracks( getAdaptiveAudioTracks(
selectedGroup, selectedGroup,
formatSupports[selectedGroupIndex], formatSupports[selectedGroupIndex],
selectedTrackIndex,
params.maxAudioBitrate, params.maxAudioBitrate,
params.allowAudioMixedMimeTypeAdaptiveness, params.allowAudioMixedMimeTypeAdaptiveness,
params.allowAudioMixedSampleRateAdaptiveness, params.allowAudioMixedSampleRateAdaptiveness,
params.allowAudioMixedChannelCountAdaptiveness); params.allowAudioMixedChannelCountAdaptiveness);
if (adaptiveTracks.length > 0) { if (adaptiveTracks.length > 1) {
definition = new TrackSelection.Definition(selectedGroup, adaptiveTracks); definition = new TrackSelection.Definition(selectedGroup, adaptiveTracks);
} }
} }
...@@ -2152,100 +2153,49 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -2152,100 +2153,49 @@ public class DefaultTrackSelector extends MappingTrackSelector {
private static int[] getAdaptiveAudioTracks( private static int[] getAdaptiveAudioTracks(
TrackGroup group, TrackGroup group,
@Capabilities int[] formatSupport, @Capabilities int[] formatSupport,
int primaryTrackIndex,
int maxAudioBitrate, int maxAudioBitrate,
boolean allowMixedMimeTypeAdaptiveness, boolean allowMixedMimeTypeAdaptiveness,
boolean allowMixedSampleRateAdaptiveness, boolean allowMixedSampleRateAdaptiveness,
boolean allowAudioMixedChannelCountAdaptiveness) { boolean allowAudioMixedChannelCountAdaptiveness) {
int selectedConfigurationTrackCount = 0; Format primaryFormat = group.getFormat(primaryTrackIndex);
AudioConfigurationTuple selectedConfiguration = null; int[] adaptiveIndices = new int[group.length];
HashSet<AudioConfigurationTuple> 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) {
int count = 0; int count = 0;
for (int i = 0; i < group.length; i++) { for (int i = 0; i < group.length; i++) {
if (isSupportedAdaptiveAudioTrack( if (i == primaryTrackIndex
|| isSupportedAdaptiveAudioTrack(
group.getFormat(i), group.getFormat(i),
formatSupport[i], formatSupport[i],
configuration, primaryFormat,
maxAudioBitrate, maxAudioBitrate,
allowMixedMimeTypeAdaptiveness, allowMixedMimeTypeAdaptiveness,
allowMixedSampleRateAdaptiveness, allowMixedSampleRateAdaptiveness,
allowAudioMixedChannelCountAdaptiveness)) { allowAudioMixedChannelCountAdaptiveness)) {
count++; adaptiveIndices[count++] = i;
} }
} }
return count; return Arrays.copyOf(adaptiveIndices, count);
} }
private static boolean isSupportedAdaptiveAudioTrack( private static boolean isSupportedAdaptiveAudioTrack(
Format format, Format format,
@Capabilities int formatSupport, @Capabilities int formatSupport,
AudioConfigurationTuple configuration, Format primaryFormat,
int maxAudioBitrate, int maxAudioBitrate,
boolean allowMixedMimeTypeAdaptiveness, boolean allowMixedMimeTypeAdaptiveness,
boolean allowMixedSampleRateAdaptiveness, boolean allowMixedSampleRateAdaptiveness,
boolean allowAudioMixedChannelCountAdaptiveness) { boolean allowAudioMixedChannelCountAdaptiveness) {
return isSupported(formatSupport, false) return isSupported(formatSupport, /* allowExceedsCapabilities= */ false)
&& (format.bitrate == Format.NO_VALUE || format.bitrate <= maxAudioBitrate) && (format.bitrate == Format.NO_VALUE || format.bitrate <= maxAudioBitrate)
&& (allowAudioMixedChannelCountAdaptiveness && (allowAudioMixedChannelCountAdaptiveness
|| (format.channelCount != Format.NO_VALUE || (format.channelCount != Format.NO_VALUE
&& format.channelCount == configuration.channelCount)) && format.channelCount == primaryFormat.channelCount))
&& (allowMixedMimeTypeAdaptiveness && (allowMixedMimeTypeAdaptiveness
|| (format.sampleMimeType != null || (format.sampleMimeType != null
&& TextUtils.equals(format.sampleMimeType, configuration.mimeType))) && TextUtils.equals(format.sampleMimeType, primaryFormat.sampleMimeType)))
&& (allowMixedSampleRateAdaptiveness && (allowMixedSampleRateAdaptiveness
|| (format.sampleRate != Format.NO_VALUE || (format.sampleRate != Format.NO_VALUE
&& format.sampleRate == configuration.sampleRate)); && format.sampleRate == primaryFormat.sampleRate));
} }
// Text track selection implementation. // Text track selection implementation.
...@@ -2705,41 +2655,6 @@ public class DefaultTrackSelector extends MappingTrackSelector { ...@@ -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}. */ /** Represents how well a text track matches the selection {@link Parameters}. */
protected static final class TextTrackScore implements Comparable<TextTrackScore> { protected static final class TextTrackScore implements Comparable<TextTrackScore> {
......
...@@ -1283,6 +1283,37 @@ public final class DefaultTrackSelectorTest { ...@@ -1283,6 +1283,37 @@ public final class DefaultTrackSelectorTest {
} }
@Test @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 { public void testSelectTracksWithMultipleAudioTracksWithMixedSampleRates() throws Exception {
Format highSampleRateAudioFormat = Format highSampleRateAudioFormat =
buildAudioFormatWithSampleRate("44100", /* sampleRate= */ 44100); buildAudioFormatWithSampleRate("44100", /* sampleRate= */ 44100);
...@@ -1709,6 +1740,18 @@ public final class DefaultTrackSelectorTest { ...@@ -1709,6 +1740,18 @@ public final class DefaultTrackSelectorTest {
/* sampleRate= */ 44100); /* 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) { private static Format buildAudioFormat(String id) {
return buildAudioFormat( return buildAudioFormat(
id, id,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment