use of androidx.media3.exoplayer.RendererConfiguration in project media by androidx.
the class DefaultTrackSelector method maybeConfigureRenderersForTunneling.
// Utility methods.
/**
* Determines whether tunneling can be enabled, replacing {@link RendererConfiguration}s in {@code
* rendererConfigurations} with configurations that enable tunneling on the appropriate renderers
* if so.
*
* @param mappedTrackInfo Mapped track information.
* @param renderererFormatSupports The {@link Capabilities} for each mapped track, indexed by
* renderer, track group and track (in that order).
* @param rendererConfigurations The renderer configurations. Configurations may be replaced with
* ones that enable tunneling as a result of this call.
* @param trackSelections The renderer track selections.
*/
private static void maybeConfigureRenderersForTunneling(MappedTrackInfo mappedTrackInfo, @Capabilities int[][][] renderererFormatSupports, @NullableType RendererConfiguration[] rendererConfigurations, @NullableType ExoTrackSelection[] trackSelections) {
// Check whether we can enable tunneling. To enable tunneling we require exactly one audio and
// one video renderer to support tunneling and have a selection.
int tunnelingAudioRendererIndex = -1;
int tunnelingVideoRendererIndex = -1;
boolean enableTunneling = true;
for (int i = 0; i < mappedTrackInfo.getRendererCount(); i++) {
int rendererType = mappedTrackInfo.getRendererType(i);
ExoTrackSelection trackSelection = trackSelections[i];
if ((rendererType == C.TRACK_TYPE_AUDIO || rendererType == C.TRACK_TYPE_VIDEO) && trackSelection != null) {
if (rendererSupportsTunneling(renderererFormatSupports[i], mappedTrackInfo.getTrackGroups(i), trackSelection)) {
if (rendererType == C.TRACK_TYPE_AUDIO) {
if (tunnelingAudioRendererIndex != -1) {
enableTunneling = false;
break;
} else {
tunnelingAudioRendererIndex = i;
}
} else {
if (tunnelingVideoRendererIndex != -1) {
enableTunneling = false;
break;
} else {
tunnelingVideoRendererIndex = i;
}
}
}
}
}
enableTunneling &= tunnelingAudioRendererIndex != -1 && tunnelingVideoRendererIndex != -1;
if (enableTunneling) {
RendererConfiguration tunnelingRendererConfiguration = new RendererConfiguration(/* tunneling= */
true);
rendererConfigurations[tunnelingAudioRendererIndex] = tunnelingRendererConfiguration;
rendererConfigurations[tunnelingVideoRendererIndex] = tunnelingRendererConfiguration;
}
}
use of androidx.media3.exoplayer.RendererConfiguration in project media by androidx.
the class DefaultTrackSelector method selectTracks.
// MappingTrackSelector implementation.
@Override
protected final Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]> selectTracks(MappedTrackInfo mappedTrackInfo, @Capabilities int[][][] rendererFormatSupports, @AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports, MediaPeriodId mediaPeriodId, Timeline timeline) throws ExoPlaybackException {
Parameters params = parametersReference.get();
int rendererCount = mappedTrackInfo.getRendererCount();
ExoTrackSelection.@NullableType Definition[] definitions = selectAllTracks(mappedTrackInfo, rendererFormatSupports, rendererMixedMimeTypeAdaptationSupports, params);
// Apply per track type overrides.
SparseArray<Pair<TrackSelectionOverride, Integer>> applicableOverridesByTrackType = getApplicableOverrides(mappedTrackInfo, params);
for (int i = 0; i < applicableOverridesByTrackType.size(); i++) {
Pair<TrackSelectionOverride, Integer> overrideAndRendererIndex = applicableOverridesByTrackType.valueAt(i);
applyTrackTypeOverride(mappedTrackInfo, definitions, /* trackType= */
applicableOverridesByTrackType.keyAt(i), /* override= */
overrideAndRendererIndex.first, /* overrideRendererIndex= */
overrideAndRendererIndex.second);
}
// Apply legacy per renderer overrides.
for (int i = 0; i < rendererCount; i++) {
if (hasLegacyRendererOverride(mappedTrackInfo, params, /* rendererIndex= */
i)) {
definitions[i] = getLegacyRendererOverride(mappedTrackInfo, params, /* rendererIndex= */
i);
}
}
// Disable renderers if needed.
for (int i = 0; i < rendererCount; i++) {
if (isRendererDisabled(mappedTrackInfo, params, /* rendererIndex= */
i)) {
definitions[i] = null;
}
}
@NullableType ExoTrackSelection[] rendererTrackSelections = trackSelectionFactory.createTrackSelections(definitions, getBandwidthMeter(), mediaPeriodId, timeline);
// Initialize the renderer configurations to the default configuration for all renderers with
// selections, and null otherwise.
@NullableType RendererConfiguration[] rendererConfigurations = new RendererConfiguration[rendererCount];
for (int i = 0; i < rendererCount; i++) {
@C.TrackType int rendererType = mappedTrackInfo.getRendererType(i);
boolean forceRendererDisabled = params.getRendererDisabled(i) || params.disabledTrackTypes.contains(rendererType);
boolean rendererEnabled = !forceRendererDisabled && (mappedTrackInfo.getRendererType(i) == C.TRACK_TYPE_NONE || rendererTrackSelections[i] != null);
rendererConfigurations[i] = rendererEnabled ? RendererConfiguration.DEFAULT : null;
}
// Configure audio and video renderers to use tunneling if appropriate.
if (params.tunnelingEnabled) {
maybeConfigureRenderersForTunneling(mappedTrackInfo, rendererFormatSupports, rendererConfigurations, rendererTrackSelections);
}
return Pair.create(rendererConfigurations, rendererTrackSelections);
}
use of androidx.media3.exoplayer.RendererConfiguration in project media by androidx.
the class MappingTrackSelector method selectTracks.
@Override
public final TrackSelectorResult selectTracks(RendererCapabilities[] rendererCapabilities, TrackGroupArray trackGroups, MediaPeriodId periodId, Timeline timeline) throws ExoPlaybackException {
// Structures into which data will be written during the selection. The extra item at the end
// of each array is to store data associated with track groups that cannot be associated with
// any renderer.
int[] rendererTrackGroupCounts = new int[rendererCapabilities.length + 1];
TrackGroup[][] rendererTrackGroups = new TrackGroup[rendererCapabilities.length + 1][];
@Capabilities int[][][] rendererFormatSupports = new int[rendererCapabilities.length + 1][][];
for (int i = 0; i < rendererTrackGroups.length; i++) {
rendererTrackGroups[i] = new TrackGroup[trackGroups.length];
rendererFormatSupports[i] = new int[trackGroups.length][];
}
// Determine the extent to which each renderer supports mixed mimeType adaptation.
@AdaptiveSupport int[] rendererMixedMimeTypeAdaptationSupports = getMixedMimeTypeAdaptationSupports(rendererCapabilities);
// renderer provides for each track in the group.
for (int groupIndex = 0; groupIndex < trackGroups.length; groupIndex++) {
TrackGroup group = trackGroups.get(groupIndex);
// Associate the group to a preferred renderer.
boolean preferUnassociatedRenderer = MimeTypes.getTrackType(group.getFormat(0).sampleMimeType) == C.TRACK_TYPE_METADATA;
int rendererIndex = findRenderer(rendererCapabilities, group, rendererTrackGroupCounts, preferUnassociatedRenderer);
// Evaluate the support that the renderer provides for each track in the group.
@Capabilities int[] rendererFormatSupport = rendererIndex == rendererCapabilities.length ? new int[group.length] : getFormatSupport(rendererCapabilities[rendererIndex], group);
// Stash the results.
int rendererTrackGroupCount = rendererTrackGroupCounts[rendererIndex];
rendererTrackGroups[rendererIndex][rendererTrackGroupCount] = group;
rendererFormatSupports[rendererIndex][rendererTrackGroupCount] = rendererFormatSupport;
rendererTrackGroupCounts[rendererIndex]++;
}
// Create a track group array for each renderer, and trim each rendererFormatSupports entry.
TrackGroupArray[] rendererTrackGroupArrays = new TrackGroupArray[rendererCapabilities.length];
String[] rendererNames = new String[rendererCapabilities.length];
int[] rendererTrackTypes = new int[rendererCapabilities.length];
for (int i = 0; i < rendererCapabilities.length; i++) {
int rendererTrackGroupCount = rendererTrackGroupCounts[i];
rendererTrackGroupArrays[i] = new TrackGroupArray(Util.nullSafeArrayCopy(rendererTrackGroups[i], rendererTrackGroupCount));
rendererFormatSupports[i] = Util.nullSafeArrayCopy(rendererFormatSupports[i], rendererTrackGroupCount);
rendererNames[i] = rendererCapabilities[i].getName();
rendererTrackTypes[i] = rendererCapabilities[i].getTrackType();
}
// Create a track group array for track groups not mapped to a renderer.
int unmappedTrackGroupCount = rendererTrackGroupCounts[rendererCapabilities.length];
TrackGroupArray unmappedTrackGroupArray = new TrackGroupArray(Util.nullSafeArrayCopy(rendererTrackGroups[rendererCapabilities.length], unmappedTrackGroupCount));
// Package up the track information and selections.
MappedTrackInfo mappedTrackInfo = new MappedTrackInfo(rendererNames, rendererTrackTypes, rendererTrackGroupArrays, rendererMixedMimeTypeAdaptationSupports, rendererFormatSupports, unmappedTrackGroupArray);
Pair<@NullableType RendererConfiguration[], @NullableType ExoTrackSelection[]> result = selectTracks(mappedTrackInfo, rendererFormatSupports, rendererMixedMimeTypeAdaptationSupports, periodId, timeline);
TracksInfo tracksInfo = buildTracksInfo(result.second, mappedTrackInfo);
return new TrackSelectorResult(result.first, result.second, tracksInfo, mappedTrackInfo);
}
use of androidx.media3.exoplayer.RendererConfiguration in project media by androidx.
the class DefaultTrackSelectorTest method selectTracksWithClearedNullOverride.
/**
* Tests that a null override can be cleared.
*/
@Test
public void selectTracksWithClearedNullOverride() throws ExoPlaybackException {
trackSelector.setParameters(trackSelector.buildUponParameters().setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP), null).clearSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP)));
TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, TRACK_GROUPS, periodId, TIMELINE);
assertSelections(result, TRACK_SELECTIONS);
assertThat(result.rendererConfigurations).isEqualTo(new RendererConfiguration[] { DEFAULT, DEFAULT });
}
use of androidx.media3.exoplayer.RendererConfiguration in project media by androidx.
the class DefaultTrackSelectorTest method selectTracksWithNullOverrideForDifferentTracks.
/**
* Tests that an override is not applied for a different set of available track groups.
*/
@Test
public void selectTracksWithNullOverrideForDifferentTracks() throws ExoPlaybackException {
TrackGroup videoGroup0 = VIDEO_TRACK_GROUP.copyWithId("0");
TrackGroup videoGroup1 = VIDEO_TRACK_GROUP.copyWithId("1");
trackSelector.setParameters(trackSelector.buildUponParameters().setSelectionOverride(0, new TrackGroupArray(VIDEO_TRACK_GROUP.copyWithId("2")), null));
TrackSelectorResult result = trackSelector.selectTracks(RENDERER_CAPABILITIES, new TrackGroupArray(videoGroup0, AUDIO_TRACK_GROUP, videoGroup1), periodId, TIMELINE);
assertThat(result.selections).asList().containsExactly(new FixedTrackSelection(videoGroup0, /* track= */
0), new FixedTrackSelection(AUDIO_TRACK_GROUP, /* track= */
0)).inOrder();
assertThat(result.rendererConfigurations).isEqualTo(new RendererConfiguration[] { DEFAULT, DEFAULT });
}
Aggregations