Align audio adaptive support checks with video

In particular:
 - Add allowAudioNonSeamlessAdaptiveness parameter (default true, same
   as video and as already implemented by default)
 - Forward mixedMimeTypeAdaptation support to AudioTrackScore
   (as for VideoTrackScore) and adapt mixed MIME type adaptive
   support accordingly
 - Check adaptive support when deciding whether a track is allowed for
   adaptation (also same check as for video). This takes the new
   parameter into account.

#minor-release

PiperOrigin-RevId: 572191308
This commit is contained in:
tonihei 2023-10-10 03:15:55 -07:00 committed by Copybara-Service
parent d60596cfca
commit f20d18e6ca
3 changed files with 166 additions and 13 deletions

View file

@ -6,6 +6,9 @@
* ExoPlayer: * ExoPlayer:
* Transformer: * Transformer:
* Track Selection: * Track Selection:
* Add `DefaultTrackSelector.Parameters.allowAudioNonSeamlessAdaptiveness`
to explicitly allow or disallow non-seamless adaptation. The default
stays at its current behavior of `true`.
* Extractors: * Extractors:
* Audio: * Audio:
* Video: * Video:

View file

@ -386,7 +386,9 @@ public class DefaultTrackSelector extends MappingTrackSelector
/** /**
* Sets whether to allow adaptive audio selections containing mixed MIME types. * Sets whether to allow adaptive audio selections containing mixed MIME types.
* *
* <p>Adaptations between different MIME types may not be completely seamless. * <p>Adaptations between different MIME types may not be completely seamless, in which case
* {@link Parameters.Builder#setAllowAudioNonSeamlessAdaptiveness(boolean)} also needs to be
* {@code true} for mixed MIME type selections to be made.
* *
* @param allowAudioMixedMimeTypeAdaptiveness Whether to allow adaptive audio selections * @param allowAudioMixedMimeTypeAdaptiveness Whether to allow adaptive audio selections
* containing mixed MIME types. * containing mixed MIME types.
@ -769,6 +771,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
private boolean allowAudioMixedSampleRateAdaptiveness; private boolean allowAudioMixedSampleRateAdaptiveness;
private boolean allowAudioMixedChannelCountAdaptiveness; private boolean allowAudioMixedChannelCountAdaptiveness;
private boolean allowAudioMixedDecoderSupportAdaptiveness; private boolean allowAudioMixedDecoderSupportAdaptiveness;
private boolean allowAudioNonSeamlessAdaptiveness;
private boolean constrainAudioChannelCountToDeviceCapabilities; private boolean constrainAudioChannelCountToDeviceCapabilities;
// General // General
private boolean exceedRendererCapabilitiesIfNecessary; private boolean exceedRendererCapabilitiesIfNecessary;
@ -825,6 +828,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
initialValues.allowAudioMixedChannelCountAdaptiveness; initialValues.allowAudioMixedChannelCountAdaptiveness;
allowAudioMixedDecoderSupportAdaptiveness = allowAudioMixedDecoderSupportAdaptiveness =
initialValues.allowAudioMixedDecoderSupportAdaptiveness; initialValues.allowAudioMixedDecoderSupportAdaptiveness;
allowAudioNonSeamlessAdaptiveness = initialValues.allowAudioNonSeamlessAdaptiveness;
constrainAudioChannelCountToDeviceCapabilities = constrainAudioChannelCountToDeviceCapabilities =
initialValues.constrainAudioChannelCountToDeviceCapabilities; initialValues.constrainAudioChannelCountToDeviceCapabilities;
// General // General
@ -881,6 +885,10 @@ public class DefaultTrackSelector extends MappingTrackSelector
bundle.getBoolean( bundle.getBoolean(
Parameters.FIELD_ALLOW_AUDIO_MIXED_DECODER_SUPPORT_ADAPTIVENESS, Parameters.FIELD_ALLOW_AUDIO_MIXED_DECODER_SUPPORT_ADAPTIVENESS,
defaultValue.allowAudioMixedDecoderSupportAdaptiveness)); defaultValue.allowAudioMixedDecoderSupportAdaptiveness));
setAllowAudioNonSeamlessAdaptiveness(
bundle.getBoolean(
Parameters.FIELD_ALLOW_AUDIO_NON_SEAMLESS_ADAPTIVENESS,
defaultValue.allowAudioNonSeamlessAdaptiveness));
setConstrainAudioChannelCountToDeviceCapabilities( setConstrainAudioChannelCountToDeviceCapabilities(
bundle.getBoolean( bundle.getBoolean(
Parameters.FIELD_CONSTRAIN_AUDIO_CHANNEL_COUNT_TO_DEVICE_CAPABILITIES, Parameters.FIELD_CONSTRAIN_AUDIO_CHANNEL_COUNT_TO_DEVICE_CAPABILITIES,
@ -1136,7 +1144,9 @@ public class DefaultTrackSelector extends MappingTrackSelector
/** /**
* Sets whether to allow adaptive audio selections containing mixed MIME types. * Sets whether to allow adaptive audio selections containing mixed MIME types.
* *
* <p>Adaptations between different MIME types may not be completely seamless. * <p>Adaptations between different MIME types may not be completely seamless, in which case
* {@link #setAllowAudioNonSeamlessAdaptiveness(boolean)} also needs to be {@code true} for
* mixed MIME type selections to be made.
* *
* @param allowAudioMixedMimeTypeAdaptiveness Whether to allow adaptive audio selections * @param allowAudioMixedMimeTypeAdaptiveness Whether to allow adaptive audio selections
* containing mixed MIME types. * containing mixed MIME types.
@ -1211,6 +1221,21 @@ public class DefaultTrackSelector extends MappingTrackSelector
return this; return this;
} }
/**
* Sets whether to allow adaptive audio selections where adaptation may not be completely
* seamless.
*
* @param allowAudioNonSeamlessAdaptiveness Whether to allow adaptive audio selections where
* adaptation may not be completely seamless.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setAllowAudioNonSeamlessAdaptiveness(
boolean allowAudioNonSeamlessAdaptiveness) {
this.allowAudioNonSeamlessAdaptiveness = allowAudioNonSeamlessAdaptiveness;
return this;
}
/** /**
* Whether to only select audio tracks with channel counts that don't exceed the device's * Whether to only select audio tracks with channel counts that don't exceed the device's
* output capabilities. The default value is {@code true}. * output capabilities. The default value is {@code true}.
@ -1580,6 +1605,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
allowAudioMixedSampleRateAdaptiveness = false; allowAudioMixedSampleRateAdaptiveness = false;
allowAudioMixedChannelCountAdaptiveness = false; allowAudioMixedChannelCountAdaptiveness = false;
allowAudioMixedDecoderSupportAdaptiveness = false; allowAudioMixedDecoderSupportAdaptiveness = false;
allowAudioNonSeamlessAdaptiveness = true;
constrainAudioChannelCountToDeviceCapabilities = true; constrainAudioChannelCountToDeviceCapabilities = true;
// General // General
exceedRendererCapabilitiesIfNecessary = true; exceedRendererCapabilitiesIfNecessary = true;
@ -1713,7 +1739,9 @@ public class DefaultTrackSelector extends MappingTrackSelector
/** /**
* Whether to allow adaptive audio selections containing mixed MIME types. Adaptations between * Whether to allow adaptive audio selections containing mixed MIME types. Adaptations between
* different MIME types may not be completely seamless. The default value is {@code false}. * different MIME types may not be completely seamless, in which case {@link
* #allowAudioNonSeamlessAdaptiveness} also needs to be {@code true} for mixed MIME type
* selections to be made. The default value is {@code false}.
*/ */
public final boolean allowAudioMixedMimeTypeAdaptiveness; public final boolean allowAudioMixedMimeTypeAdaptiveness;
@ -1737,6 +1765,12 @@ public class DefaultTrackSelector extends MappingTrackSelector
*/ */
public final boolean allowAudioMixedDecoderSupportAdaptiveness; public final boolean allowAudioMixedDecoderSupportAdaptiveness;
/**
* Whether to allow adaptive audio selections where adaptation may not be completely seamless.
* The default value is {@code true}.
*/
public final boolean allowAudioNonSeamlessAdaptiveness;
/** /**
* Whether to constrain audio track selection so that the selected track's channel count does * Whether to constrain audio track selection so that the selected track's channel count does
* not exceed the device's output capabilities. The default value is {@code true}. * not exceed the device's output capabilities. The default value is {@code true}.
@ -1793,6 +1827,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
allowAudioMixedSampleRateAdaptiveness = builder.allowAudioMixedSampleRateAdaptiveness; allowAudioMixedSampleRateAdaptiveness = builder.allowAudioMixedSampleRateAdaptiveness;
allowAudioMixedChannelCountAdaptiveness = builder.allowAudioMixedChannelCountAdaptiveness; allowAudioMixedChannelCountAdaptiveness = builder.allowAudioMixedChannelCountAdaptiveness;
allowAudioMixedDecoderSupportAdaptiveness = builder.allowAudioMixedDecoderSupportAdaptiveness; allowAudioMixedDecoderSupportAdaptiveness = builder.allowAudioMixedDecoderSupportAdaptiveness;
allowAudioNonSeamlessAdaptiveness = builder.allowAudioNonSeamlessAdaptiveness;
constrainAudioChannelCountToDeviceCapabilities = constrainAudioChannelCountToDeviceCapabilities =
builder.constrainAudioChannelCountToDeviceCapabilities; builder.constrainAudioChannelCountToDeviceCapabilities;
// General // General
@ -1885,6 +1920,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
== other.allowAudioMixedChannelCountAdaptiveness == other.allowAudioMixedChannelCountAdaptiveness
&& allowAudioMixedDecoderSupportAdaptiveness && allowAudioMixedDecoderSupportAdaptiveness
== other.allowAudioMixedDecoderSupportAdaptiveness == other.allowAudioMixedDecoderSupportAdaptiveness
&& allowAudioNonSeamlessAdaptiveness == other.allowAudioNonSeamlessAdaptiveness
&& constrainAudioChannelCountToDeviceCapabilities && constrainAudioChannelCountToDeviceCapabilities
== other.constrainAudioChannelCountToDeviceCapabilities == other.constrainAudioChannelCountToDeviceCapabilities
// General // General
@ -1913,6 +1949,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
result = 31 * result + (allowAudioMixedSampleRateAdaptiveness ? 1 : 0); result = 31 * result + (allowAudioMixedSampleRateAdaptiveness ? 1 : 0);
result = 31 * result + (allowAudioMixedChannelCountAdaptiveness ? 1 : 0); result = 31 * result + (allowAudioMixedChannelCountAdaptiveness ? 1 : 0);
result = 31 * result + (allowAudioMixedDecoderSupportAdaptiveness ? 1 : 0); result = 31 * result + (allowAudioMixedDecoderSupportAdaptiveness ? 1 : 0);
result = 31 * result + (allowAudioNonSeamlessAdaptiveness ? 1 : 0);
result = 31 * result + (constrainAudioChannelCountToDeviceCapabilities ? 1 : 0); result = 31 * result + (constrainAudioChannelCountToDeviceCapabilities ? 1 : 0);
// General // General
result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0); result = 31 * result + (exceedRendererCapabilitiesIfNecessary ? 1 : 0);
@ -1961,6 +1998,8 @@ public class DefaultTrackSelector extends MappingTrackSelector
Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 16); Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 16);
private static final String FIELD_ALLOW_INVALIDATE_SELECTIONS_ON_RENDERER_CAPABILITIES_CHANGE = private static final String FIELD_ALLOW_INVALIDATE_SELECTIONS_ON_RENDERER_CAPABILITIES_CHANGE =
Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 17); Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 17);
private static final String FIELD_ALLOW_AUDIO_NON_SEAMLESS_ADAPTIVENESS =
Util.intToStringMaxRadix(FIELD_CUSTOM_ID_BASE + 18);
@Override @Override
public Bundle toBundle() { public Bundle toBundle() {
@ -1989,6 +2028,8 @@ public class DefaultTrackSelector extends MappingTrackSelector
bundle.putBoolean( bundle.putBoolean(
FIELD_ALLOW_AUDIO_MIXED_DECODER_SUPPORT_ADAPTIVENESS, FIELD_ALLOW_AUDIO_MIXED_DECODER_SUPPORT_ADAPTIVENESS,
allowAudioMixedDecoderSupportAdaptiveness); allowAudioMixedDecoderSupportAdaptiveness);
bundle.putBoolean(
FIELD_ALLOW_AUDIO_NON_SEAMLESS_ADAPTIVENESS, allowAudioNonSeamlessAdaptiveness);
bundle.putBoolean( bundle.putBoolean(
FIELD_CONSTRAIN_AUDIO_CHANNEL_COUNT_TO_DEVICE_CAPABILITIES, FIELD_CONSTRAIN_AUDIO_CHANNEL_COUNT_TO_DEVICE_CAPABILITIES,
constrainAudioChannelCountToDeviceCapabilities); constrainAudioChannelCountToDeviceCapabilities);
@ -2678,7 +2719,8 @@ public class DefaultTrackSelector extends MappingTrackSelector
params, params,
support, support,
hasVideoRendererWithMappedTracksFinal, hasVideoRendererWithMappedTracksFinal,
this::isAudioFormatWithinAudioChannelCountConstraints), this::isAudioFormatWithinAudioChannelCountConstraints,
rendererMixedMimeTypeAdaptationSupports[rendererIndex]),
AudioTrackInfo::compareSelections); AudioTrackInfo::compareSelections);
} }
@ -3348,7 +3390,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
TrackGroup trackGroup, TrackGroup trackGroup,
Parameters params, Parameters params,
@Capabilities int[] formatSupport, @Capabilities int[] formatSupport,
@AdaptiveSupport int mixedMimeTypeAdaptionSupport) { @AdaptiveSupport int mixedMimeTypeAdaptationSupport) {
int maxPixelsToRetainForViewport = int maxPixelsToRetainForViewport =
getMaxVideoPixelsToRetainForViewport( getMaxVideoPixelsToRetainForViewport(
trackGroup, trackGroup,
@ -3368,7 +3410,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
/* trackIndex= */ i, /* trackIndex= */ i,
params, params,
formatSupport[i], formatSupport[i],
mixedMimeTypeAdaptionSupport, mixedMimeTypeAdaptationSupport,
isSuitableForViewport)); isSuitableForViewport));
} }
return listBuilder.build(); return listBuilder.build();
@ -3482,7 +3524,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
&& format.bitrate != Format.NO_VALUE && format.bitrate != Format.NO_VALUE
&& !parameters.forceHighestSupportedBitrate && !parameters.forceHighestSupportedBitrate
&& !parameters.forceLowestBitrate && !parameters.forceLowestBitrate
&& ((rendererSupport & requiredAdaptiveSupport) != 0) && (rendererSupport & requiredAdaptiveSupport) != 0
? SELECTION_ELIGIBILITY_ADAPTIVE ? SELECTION_ELIGIBILITY_ADAPTIVE
: SELECTION_ELIGIBILITY_FIXED; : SELECTION_ELIGIBILITY_FIXED;
} }
@ -3562,7 +3604,8 @@ public class DefaultTrackSelector extends MappingTrackSelector
Parameters params, Parameters params,
@Capabilities int[] formatSupport, @Capabilities int[] formatSupport,
boolean hasMappedVideoTracks, boolean hasMappedVideoTracks,
Predicate<Format> withinAudioChannelCountConstraints) { Predicate<Format> withinAudioChannelCountConstraints,
@AdaptiveSupport int mixedMimeTypeAdaptationSupport) {
ImmutableList.Builder<AudioTrackInfo> listBuilder = ImmutableList.builder(); ImmutableList.Builder<AudioTrackInfo> listBuilder = ImmutableList.builder();
for (int i = 0; i < trackGroup.length; i++) { for (int i = 0; i < trackGroup.length; i++) {
listBuilder.add( listBuilder.add(
@ -3573,7 +3616,8 @@ public class DefaultTrackSelector extends MappingTrackSelector
params, params,
formatSupport[i], formatSupport[i],
hasMappedVideoTracks, hasMappedVideoTracks,
withinAudioChannelCountConstraints)); withinAudioChannelCountConstraints,
mixedMimeTypeAdaptationSupport));
} }
return listBuilder.build(); return listBuilder.build();
} }
@ -3586,6 +3630,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
private final int preferredLanguageScore; private final int preferredLanguageScore;
private final int preferredLanguageIndex; private final int preferredLanguageIndex;
private final int preferredRoleFlagsScore; private final int preferredRoleFlagsScore;
private final boolean allowMixedMimeTypes;
private final boolean hasMainOrNoRoleFlag; private final boolean hasMainOrNoRoleFlag;
private final int localeLanguageMatchIndex; private final int localeLanguageMatchIndex;
private final int localeLanguageScore; private final int localeLanguageScore;
@ -3604,9 +3649,19 @@ public class DefaultTrackSelector extends MappingTrackSelector
Parameters parameters, Parameters parameters,
@Capabilities int formatSupport, @Capabilities int formatSupport,
boolean hasMappedVideoTracks, boolean hasMappedVideoTracks,
Predicate<Format> withinAudioChannelCountConstraints) { Predicate<Format> withinAudioChannelCountConstraints,
@AdaptiveSupport int mixedMimeTypeAdaptationSupport) {
super(rendererIndex, trackGroup, trackIndex); super(rendererIndex, trackGroup, trackIndex);
this.parameters = parameters; this.parameters = parameters;
@SuppressLint("WrongConstant")
int requiredAdaptiveSupport =
parameters.allowAudioNonSeamlessAdaptiveness
? (RendererCapabilities.ADAPTIVE_NOT_SEAMLESS
| RendererCapabilities.ADAPTIVE_SEAMLESS)
: RendererCapabilities.ADAPTIVE_SEAMLESS;
allowMixedMimeTypes =
parameters.allowAudioMixedMimeTypeAdaptiveness
&& (mixedMimeTypeAdaptationSupport & requiredAdaptiveSupport) != 0;
this.language = normalizeUndeterminedLanguageToNull(format.language); this.language = normalizeUndeterminedLanguageToNull(format.language);
isWithinRendererCapabilities = isWithinRendererCapabilities =
isSupported(formatSupport, /* allowExceedsCapabilities= */ false); isSupported(formatSupport, /* allowExceedsCapabilities= */ false);
@ -3669,7 +3724,8 @@ public class DefaultTrackSelector extends MappingTrackSelector
RendererCapabilities.getHardwareAccelerationSupport(formatSupport) RendererCapabilities.getHardwareAccelerationSupport(formatSupport)
== RendererCapabilities.HARDWARE_ACCELERATION_SUPPORTED; == RendererCapabilities.HARDWARE_ACCELERATION_SUPPORTED;
selectionEligibility = selectionEligibility =
evaluateSelectionEligibility(parameters, formatSupport, hasMappedVideoTracks); evaluateSelectionEligibility(
parameters, formatSupport, hasMappedVideoTracks, requiredAdaptiveSupport);
} }
@Override @Override
@ -3682,7 +3738,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
return (parameters.allowAudioMixedChannelCountAdaptiveness return (parameters.allowAudioMixedChannelCountAdaptiveness
|| (format.channelCount != Format.NO_VALUE || (format.channelCount != Format.NO_VALUE
&& format.channelCount == otherTrack.format.channelCount)) && format.channelCount == otherTrack.format.channelCount))
&& (parameters.allowAudioMixedMimeTypeAdaptiveness && (allowMixedMimeTypes
|| (format.sampleMimeType != null || (format.sampleMimeType != null
&& TextUtils.equals(format.sampleMimeType, otherTrack.format.sampleMimeType))) && TextUtils.equals(format.sampleMimeType, otherTrack.format.sampleMimeType)))
&& (parameters.allowAudioMixedSampleRateAdaptiveness && (parameters.allowAudioMixedSampleRateAdaptiveness
@ -3743,7 +3799,10 @@ public class DefaultTrackSelector extends MappingTrackSelector
} }
private @SelectionEligibility int evaluateSelectionEligibility( private @SelectionEligibility int evaluateSelectionEligibility(
Parameters params, @Capabilities int rendererSupport, boolean hasMappedVideoTracks) { Parameters params,
@Capabilities int rendererSupport,
boolean hasMappedVideoTracks,
@AdaptiveSupport int requiredAdaptiveSupport) {
if (!isSupported(rendererSupport, parameters.exceedRendererCapabilitiesIfNecessary)) { if (!isSupported(rendererSupport, parameters.exceedRendererCapabilitiesIfNecessary)) {
return SELECTION_ELIGIBILITY_NO; return SELECTION_ELIGIBILITY_NO;
} }
@ -3761,6 +3820,7 @@ public class DefaultTrackSelector extends MappingTrackSelector
&& !parameters.forceLowestBitrate && !parameters.forceLowestBitrate
&& (parameters.allowMultipleAdaptiveSelections || !hasMappedVideoTracks) && (parameters.allowMultipleAdaptiveSelections || !hasMappedVideoTracks)
&& params.audioOffloadPreferences.audioOffloadMode != AUDIO_OFFLOAD_MODE_REQUIRED && params.audioOffloadPreferences.audioOffloadMode != AUDIO_OFFLOAD_MODE_REQUIRED
&& (rendererSupport & requiredAdaptiveSupport) != 0
? SELECTION_ELIGIBILITY_ADAPTIVE ? SELECTION_ELIGIBILITY_ADAPTIVE
: SELECTION_ELIGIBILITY_FIXED; : SELECTION_ELIGIBILITY_FIXED;
} }

View file

@ -22,6 +22,8 @@ import static androidx.media3.common.C.FORMAT_UNSUPPORTED_TYPE;
import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED; import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED;
import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_REQUIRED; import static androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_REQUIRED;
import static androidx.media3.exoplayer.RendererCapabilities.ADAPTIVE_NOT_SEAMLESS; import static androidx.media3.exoplayer.RendererCapabilities.ADAPTIVE_NOT_SEAMLESS;
import static androidx.media3.exoplayer.RendererCapabilities.ADAPTIVE_NOT_SUPPORTED;
import static androidx.media3.exoplayer.RendererCapabilities.ADAPTIVE_SEAMLESS;
import static androidx.media3.exoplayer.RendererCapabilities.AUDIO_OFFLOAD_GAPLESS_SUPPORTED; import static androidx.media3.exoplayer.RendererCapabilities.AUDIO_OFFLOAD_GAPLESS_SUPPORTED;
import static androidx.media3.exoplayer.RendererCapabilities.AUDIO_OFFLOAD_SUPPORTED; import static androidx.media3.exoplayer.RendererCapabilities.AUDIO_OFFLOAD_SUPPORTED;
import static androidx.media3.exoplayer.RendererCapabilities.DECODER_SUPPORT_FALLBACK; import static androidx.media3.exoplayer.RendererCapabilities.DECODER_SUPPORT_FALLBACK;
@ -1860,6 +1862,94 @@ public final class DefaultTrackSelectorTest {
assertAdaptiveSelection(result.selections[0], trackGroups.get(0), 3, 2, 0); assertAdaptiveSelection(result.selections[0], trackGroups.get(0), 3, 2, 0);
} }
@Test
public void selectTracks_withMultipleAudioTracksWithoutAdaptationSupport_selectsFixed()
throws Exception {
FakeRendererCapabilities seamlessAudioCapabilities =
new FakeRendererCapabilities(
C.TRACK_TYPE_AUDIO,
RendererCapabilities.create(
FORMAT_HANDLED, ADAPTIVE_NOT_SUPPORTED, TUNNELING_NOT_SUPPORTED));
Format.Builder formatBuilder = AUDIO_FORMAT.buildUpon();
TrackGroupArray trackGroups =
singleTrackGroup(formatBuilder.setId("0").build(), formatBuilder.setId("1").build());
// Explicitly allow non-seamless adaptation to ensure it's not used.
trackSelector.setParameters(
defaultParameters.buildUpon().setAllowAudioNonSeamlessAdaptiveness(true));
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {seamlessAudioCapabilities},
trackGroups,
periodId,
TIMELINE);
assertThat(result.length).isEqualTo(1);
assertFixedSelection(result.selections[0], trackGroups.get(0), /* expectedTrack= */ 0);
}
@Test
public void
selectTracks_withMultipleAudioTracksWithNonSeamlessAdaptiveness_selectsAdaptiveOnlyIfAllowed()
throws Exception {
FakeRendererCapabilities nonSeamlessAudioCapabilities =
new FakeRendererCapabilities(
C.TRACK_TYPE_AUDIO,
RendererCapabilities.create(
FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, TUNNELING_NOT_SUPPORTED));
Format.Builder formatBuilder = AUDIO_FORMAT.buildUpon();
TrackGroupArray trackGroups =
singleTrackGroup(formatBuilder.setId("0").build(), formatBuilder.setId("1").build());
trackSelector.setParameters(
defaultParameters.buildUpon().setAllowAudioNonSeamlessAdaptiveness(true));
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {nonSeamlessAudioCapabilities},
trackGroups,
periodId,
TIMELINE);
assertThat(result.length).isEqualTo(1);
assertAdaptiveSelection(
result.selections[0], trackGroups.get(0), /* expectedTracks...= */ 0, 1);
trackSelector.setParameters(
defaultParameters.buildUpon().setAllowAudioNonSeamlessAdaptiveness(false));
result =
trackSelector.selectTracks(
new RendererCapabilities[] {nonSeamlessAudioCapabilities},
trackGroups,
periodId,
TIMELINE);
assertThat(result.length).isEqualTo(1);
assertFixedSelection(result.selections[0], trackGroups.get(0), /* expectedTrack= */ 0);
}
@Test
public void selectTracks_withMultipleAudioTracksWithSeamlessAdaptiveness_selectsAdaptive()
throws Exception {
FakeRendererCapabilities seamlessAudioCapabilities =
new FakeRendererCapabilities(
C.TRACK_TYPE_AUDIO,
RendererCapabilities.create(
FORMAT_HANDLED, ADAPTIVE_SEAMLESS, TUNNELING_NOT_SUPPORTED));
Format.Builder formatBuilder = AUDIO_FORMAT.buildUpon();
TrackGroupArray trackGroups =
singleTrackGroup(formatBuilder.setId("0").build(), formatBuilder.setId("1").build());
// Explicitly disallow non-seamless adaptation to ensure it's not used.
trackSelector.setParameters(
defaultParameters.buildUpon().setAllowAudioNonSeamlessAdaptiveness(false));
TrackSelectorResult result =
trackSelector.selectTracks(
new RendererCapabilities[] {seamlessAudioCapabilities},
trackGroups,
periodId,
TIMELINE);
assertThat(result.length).isEqualTo(1);
assertAdaptiveSelection(
result.selections[0], trackGroups.get(0), /* expectedTracks...= */ 0, 1);
}
@Test @Test
public void selectTracksWithMultipleAudioTracksOverrideReturnsAdaptiveTrackSelection() public void selectTracksWithMultipleAudioTracksOverrideReturnsAdaptiveTrackSelection()
throws Exception { throws Exception {