mirror of
https://github.com/samsonjs/media.git
synced 2026-04-04 11:05:47 +00:00
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
This commit is contained in:
parent
0eb0267131
commit
66aa35f581
2 changed files with 64 additions and 106 deletions
|
|
@ -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<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) {
|
||||
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<TextTrackScore> {
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue