Search in sources :

Example 1 with RendererCapabilities

use of androidx.media3.exoplayer.RendererCapabilities in project media by androidx.

the class DownloadHelper method getRendererCapabilities.

/**
 * Extracts renderer capabilities for the renderers created by the provided renderers factory.
 *
 * @param renderersFactory A {@link RenderersFactory}.
 * @return The {@link RendererCapabilities} for each renderer created by the {@code
 *     renderersFactory}.
 */
public static RendererCapabilities[] getRendererCapabilities(RenderersFactory renderersFactory) {
    Renderer[] renderers = renderersFactory.createRenderers(Util.createHandlerForCurrentOrMainLooper(), new VideoRendererEventListener() {
    }, new AudioRendererEventListener() {
    }, (cues) -> {
    }, (metadata) -> {
    });
    RendererCapabilities[] capabilities = new RendererCapabilities[renderers.length];
    for (int i = 0; i < renderers.length; i++) {
        capabilities[i] = renderers[i].getCapabilities();
    }
    return capabilities;
}
Also used : Renderer(androidx.media3.exoplayer.Renderer) VideoRendererEventListener(androidx.media3.exoplayer.video.VideoRendererEventListener) AudioRendererEventListener(androidx.media3.exoplayer.audio.AudioRendererEventListener) RendererCapabilities(androidx.media3.exoplayer.RendererCapabilities)

Example 2 with RendererCapabilities

use of androidx.media3.exoplayer.RendererCapabilities in project media by androidx.

the class MediaPeriodQueueTest method setUp.

@Before
public void setUp() {
    AnalyticsCollector analyticsCollector = new DefaultAnalyticsCollector(Clock.DEFAULT);
    analyticsCollector.setPlayer(new ExoPlayer.Builder(ApplicationProvider.getApplicationContext()).build(), Looper.getMainLooper());
    mediaPeriodQueue = new MediaPeriodQueue(analyticsCollector, new Handler(Looper.getMainLooper()));
    mediaSourceList = new MediaSourceList(mock(MediaSourceList.MediaSourceListInfoRefreshListener.class), analyticsCollector, new Handler(Looper.getMainLooper()), PlayerId.UNSET);
    rendererCapabilities = new RendererCapabilities[0];
    trackSelector = mock(TrackSelector.class);
    allocator = mock(Allocator.class);
}
Also used : Allocator(androidx.media3.exoplayer.upstream.Allocator) DefaultAnalyticsCollector(androidx.media3.exoplayer.analytics.DefaultAnalyticsCollector) AnalyticsCollector(androidx.media3.exoplayer.analytics.AnalyticsCollector) TrackSelector(androidx.media3.exoplayer.trackselection.TrackSelector) Handler(android.os.Handler) DefaultAnalyticsCollector(androidx.media3.exoplayer.analytics.DefaultAnalyticsCollector) Before(org.junit.Before)

Example 3 with RendererCapabilities

use of androidx.media3.exoplayer.RendererCapabilities 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);
}
Also used : TrackGroupArray(androidx.media3.common.TrackGroupArray) NullableType(org.checkerframework.checker.nullness.compatqual.NullableType) TracksInfo(androidx.media3.common.TracksInfo) TrackGroup(androidx.media3.common.TrackGroup) RendererCapabilities(androidx.media3.exoplayer.RendererCapabilities) Capabilities(androidx.media3.exoplayer.RendererCapabilities.Capabilities) AdaptiveSupport(androidx.media3.exoplayer.RendererCapabilities.AdaptiveSupport)

Example 4 with RendererCapabilities

use of androidx.media3.exoplayer.RendererCapabilities in project media by androidx.

the class MappingTrackSelector method findRenderer.

/**
 * Finds the renderer to which the provided {@link TrackGroup} should be mapped.
 *
 * <p>A {@link TrackGroup} is mapped to the renderer that reports the highest of (listed in
 * decreasing order of support) {@link C#FORMAT_HANDLED}, {@link C#FORMAT_EXCEEDS_CAPABILITIES},
 * {@link C#FORMAT_UNSUPPORTED_DRM} and {@link C#FORMAT_UNSUPPORTED_SUBTYPE}.
 *
 * <p>In the case that two or more renderers report the same level of support, the assignment
 * depends on {@code preferUnassociatedRenderer}.
 *
 * <ul>
 *   <li>If {@code preferUnassociatedRenderer} is false, the renderer with the lowest index is
 *       chosen regardless of how many other track groups are already mapped to this renderer.
 *   <li>If {@code preferUnassociatedRenderer} is true, the renderer with the lowest index and no
 *       other mapped track group is chosen, or the renderer with the lowest index if all
 *       available renderers have already mapped track groups.
 * </ul>
 *
 * <p>If all renderers report {@link C#FORMAT_UNSUPPORTED_TYPE} for all of the tracks in the
 * group, then {@code renderers.length} is returned to indicate that the group was not mapped to
 * any renderer.
 *
 * @param rendererCapabilities The {@link RendererCapabilities} of the renderers.
 * @param group The track group to map to a renderer.
 * @param rendererTrackGroupCounts The number of already mapped track groups for each renderer.
 * @param preferUnassociatedRenderer Whether renderers unassociated to any track group should be
 *     preferred.
 * @return The index of the renderer to which the track group was mapped, or {@code
 *     renderers.length} if it was not mapped to any renderer.
 * @throws ExoPlaybackException If an error occurs finding a renderer.
 */
private static int findRenderer(RendererCapabilities[] rendererCapabilities, TrackGroup group, int[] rendererTrackGroupCounts, boolean preferUnassociatedRenderer) throws ExoPlaybackException {
    int bestRendererIndex = rendererCapabilities.length;
    @FormatSupport int bestFormatSupportLevel = C.FORMAT_UNSUPPORTED_TYPE;
    boolean bestRendererIsUnassociated = true;
    for (int rendererIndex = 0; rendererIndex < rendererCapabilities.length; rendererIndex++) {
        RendererCapabilities rendererCapability = rendererCapabilities[rendererIndex];
        @FormatSupport int formatSupportLevel = C.FORMAT_UNSUPPORTED_TYPE;
        for (int trackIndex = 0; trackIndex < group.length; trackIndex++) {
            @FormatSupport int trackFormatSupportLevel = RendererCapabilities.getFormatSupport(rendererCapability.supportsFormat(group.getFormat(trackIndex)));
            formatSupportLevel = max(formatSupportLevel, trackFormatSupportLevel);
        }
        boolean rendererIsUnassociated = rendererTrackGroupCounts[rendererIndex] == 0;
        if (formatSupportLevel > bestFormatSupportLevel || (formatSupportLevel == bestFormatSupportLevel && preferUnassociatedRenderer && !bestRendererIsUnassociated && rendererIsUnassociated)) {
            bestRendererIndex = rendererIndex;
            bestFormatSupportLevel = formatSupportLevel;
            bestRendererIsUnassociated = rendererIsUnassociated;
        }
    }
    return bestRendererIndex;
}
Also used : FormatSupport(androidx.media3.common.C.FormatSupport) RendererCapabilities(androidx.media3.exoplayer.RendererCapabilities)

Example 5 with RendererCapabilities

use of androidx.media3.exoplayer.RendererCapabilities in project media by androidx.

the class DefaultTrackSelectorTest method selectTracksPreferHigherNumChannelBeforeSampleRate.

/**
 * Tests that track selector will prefer audio tracks with higher channel count over tracks with
 * higher sample rate when other factors are the same, and tracks are within renderer's
 * capabilities.
 */
@Test
public void selectTracksPreferHigherNumChannelBeforeSampleRate() throws Exception {
    Format.Builder formatBuilder = AUDIO_FORMAT.buildUpon();
    Format higherChannelLowerSampleRateFormat = formatBuilder.setChannelCount(6).setSampleRate(22050).build();
    Format lowerChannelHigherSampleRateFormat = formatBuilder.setChannelCount(2).setSampleRate(44100).build();
    TrackGroupArray trackGroups = wrapFormats(higherChannelLowerSampleRateFormat, lowerChannelHigherSampleRateFormat);
    TrackSelectorResult result = trackSelector.selectTracks(new RendererCapabilities[] { ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES }, trackGroups, periodId, TIMELINE);
    assertFixedSelection(result.selections[0], trackGroups, higherChannelLowerSampleRateFormat);
}
Also used : Format(androidx.media3.common.Format) TrackGroupArray(androidx.media3.common.TrackGroupArray) Test(org.junit.Test)

Aggregations

TrackGroupArray (androidx.media3.common.TrackGroupArray)58 Test (org.junit.Test)57 Format (androidx.media3.common.Format)47 RendererCapabilities (androidx.media3.exoplayer.RendererCapabilities)35 TrackGroup (androidx.media3.common.TrackGroup)9 HashMap (java.util.HashMap)8 ParametersBuilder (androidx.media3.exoplayer.trackselection.DefaultTrackSelector.ParametersBuilder)5 TrackSelectionOverride (androidx.media3.common.TrackSelectionOverrides.TrackSelectionOverride)4 Capabilities (androidx.media3.exoplayer.RendererCapabilities.Capabilities)3 Nullable (androidx.annotation.Nullable)2 SelectionOverride (androidx.media3.exoplayer.trackselection.DefaultTrackSelector.SelectionOverride)2 TrackSelectorResult (androidx.media3.exoplayer.trackselection.TrackSelectorResult)2 Handler (android.os.Handler)1 FormatSupport (androidx.media3.common.C.FormatSupport)1 TracksInfo (androidx.media3.common.TracksInfo)1 ExoPlaybackException (androidx.media3.exoplayer.ExoPlaybackException)1 Renderer (androidx.media3.exoplayer.Renderer)1 AdaptiveSupport (androidx.media3.exoplayer.RendererCapabilities.AdaptiveSupport)1 AnalyticsCollector (androidx.media3.exoplayer.analytics.AnalyticsCollector)1 DefaultAnalyticsCollector (androidx.media3.exoplayer.analytics.DefaultAnalyticsCollector)1