Search in sources :

Example 1 with Capabilities

use of androidx.media3.exoplayer.RendererCapabilities.Capabilities 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 Capabilities

use of androidx.media3.exoplayer.RendererCapabilities.Capabilities 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;
    }
}
Also used : RendererConfiguration(androidx.media3.exoplayer.RendererConfiguration) SuppressLint(android.annotation.SuppressLint) Point(android.graphics.Point)

Example 3 with Capabilities

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

the class DefaultTrackSelector method selectOtherTrack.

// Generic track selection methods.
/**
 * Called by {@link #selectAllTracks(MappedTrackInfo, int[][][], int[], Parameters)} to create a
 * {@link ExoTrackSelection} for a renderer whose type is neither video, audio or text.
 *
 * @param trackType The type of the renderer.
 * @param groups The {@link TrackGroupArray} mapped to the renderer.
 * @param formatSupport The {@link Capabilities} for each mapped track, indexed by track group and
 *     track (in that order).
 * @param params The selector's current constraint parameters.
 * @return The {@link ExoTrackSelection} for the renderer, or null if no selection was made.
 * @throws ExoPlaybackException If an error occurs while selecting the tracks.
 */
@Nullable
protected ExoTrackSelection.Definition selectOtherTrack(int trackType, TrackGroupArray groups, @Capabilities int[][] formatSupport, Parameters params) throws ExoPlaybackException {
    @Nullable TrackGroup selectedGroup = null;
    int selectedTrackIndex = 0;
    @Nullable OtherTrackScore selectedTrackScore = null;
    for (int groupIndex = 0; groupIndex < groups.length; groupIndex++) {
        TrackGroup trackGroup = groups.get(groupIndex);
        @Capabilities int[] trackFormatSupport = formatSupport[groupIndex];
        for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) {
            if (isSupported(trackFormatSupport[trackIndex], params.exceedRendererCapabilitiesIfNecessary)) {
                Format format = trackGroup.getFormat(trackIndex);
                OtherTrackScore trackScore = new OtherTrackScore(format, trackFormatSupport[trackIndex]);
                if (selectedTrackScore == null || trackScore.compareTo(selectedTrackScore) > 0) {
                    selectedGroup = trackGroup;
                    selectedTrackIndex = trackIndex;
                    selectedTrackScore = trackScore;
                }
            }
        }
    }
    return selectedGroup == null ? null : new ExoTrackSelection.Definition(selectedGroup, selectedTrackIndex);
}
Also used : Format(androidx.media3.common.Format) TrackGroup(androidx.media3.common.TrackGroup) RendererCapabilities(androidx.media3.exoplayer.RendererCapabilities) Capabilities(androidx.media3.exoplayer.RendererCapabilities.Capabilities) Nullable(androidx.annotation.Nullable) SuppressLint(android.annotation.SuppressLint) Point(android.graphics.Point) Nullable(androidx.annotation.Nullable)

Example 4 with Capabilities

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

the class EnumerateDecodersTest method logDecoderInfos.

private void logDecoderInfos(String mimeType, boolean secure, boolean tunneling) throws DecoderQueryException {
    List<MediaCodecInfo> mediaCodecInfos = MediaCodecUtil.getDecoderInfos(mimeType, secure, tunneling);
    for (MediaCodecInfo mediaCodecInfo : mediaCodecInfos) {
        CodecCapabilities capabilities = mediaCodecInfo.capabilities;
        metricsLogger.logMetric("capabilities_" + mediaCodecInfo.name, codecCapabilitiesToString(mimeType, capabilities));
    }
}
Also used : MediaCodecInfo(androidx.media3.exoplayer.mediacodec.MediaCodecInfo) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities)

Example 5 with Capabilities

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

the class MediaCodecAudioRenderer method supportsFormat.

@Override
@Capabilities
protected int supportsFormat(MediaCodecSelector mediaCodecSelector, Format format) throws DecoderQueryException {
    if (!MimeTypes.isAudio(format.sampleMimeType)) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE);
    }
    @TunnelingSupport int tunnelingSupport = Util.SDK_INT >= 21 ? TUNNELING_SUPPORTED : TUNNELING_NOT_SUPPORTED;
    boolean formatHasDrm = format.cryptoType != C.CRYPTO_TYPE_NONE;
    boolean supportsFormatDrm = supportsFormatDrm(format);
    // Else we don't don't need a decoder at all.
    if (supportsFormatDrm && audioSink.supportsFormat(format) && (!formatHasDrm || MediaCodecUtil.getDecryptOnlyDecoderInfo() != null)) {
        return RendererCapabilities.create(C.FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport);
    }
    // the input format directly.
    if (MimeTypes.AUDIO_RAW.equals(format.sampleMimeType) && !audioSink.supportsFormat(format)) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
    }
    // For all other input formats, we expect the decoder to output 16-bit PCM.
    if (!audioSink.supportsFormat(Util.getPcmFormat(C.ENCODING_PCM_16BIT, format.channelCount, format.sampleRate))) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
    }
    List<MediaCodecInfo> decoderInfos = getDecoderInfos(mediaCodecSelector, format, /* requiresSecureDecoder= */
    false, audioSink);
    if (decoderInfos.isEmpty()) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
    }
    if (!supportsFormatDrm) {
        return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_DRM);
    }
    // Check whether the first decoder supports the format. This is the preferred decoder for the
    // format's MIME type, according to the MediaCodecSelector.
    MediaCodecInfo decoderInfo = decoderInfos.get(0);
    boolean isFormatSupported = decoderInfo.isFormatSupported(format);
    boolean isPreferredDecoder = true;
    if (!isFormatSupported) {
        // Check whether any of the other decoders support the format.
        for (int i = 1; i < decoderInfos.size(); i++) {
            MediaCodecInfo otherDecoderInfo = decoderInfos.get(i);
            if (otherDecoderInfo.isFormatSupported(format)) {
                decoderInfo = otherDecoderInfo;
                isFormatSupported = true;
                isPreferredDecoder = false;
                break;
            }
        }
    }
    @C.FormatSupport int formatSupport = isFormatSupported ? C.FORMAT_HANDLED : C.FORMAT_EXCEEDS_CAPABILITIES;
    @AdaptiveSupport int adaptiveSupport = isFormatSupported && decoderInfo.isSeamlessAdaptationSupported(format) ? ADAPTIVE_SEAMLESS : ADAPTIVE_NOT_SEAMLESS;
    @HardwareAccelerationSupport int hardwareAccelerationSupport = decoderInfo.hardwareAccelerated ? HARDWARE_ACCELERATION_SUPPORTED : HARDWARE_ACCELERATION_NOT_SUPPORTED;
    @DecoderSupport int decoderSupport = isPreferredDecoder ? DECODER_SUPPORT_PRIMARY : DECODER_SUPPORT_FALLBACK;
    return RendererCapabilities.create(formatSupport, adaptiveSupport, tunnelingSupport, hardwareAccelerationSupport, decoderSupport);
}
Also used : MediaCodecInfo(androidx.media3.exoplayer.mediacodec.MediaCodecInfo) SuppressLint(android.annotation.SuppressLint) RendererCapabilities(androidx.media3.exoplayer.RendererCapabilities)

Aggregations

Format (androidx.media3.common.Format)23 TrackGroupArray (androidx.media3.common.TrackGroupArray)23 Test (org.junit.Test)22 RendererCapabilities (androidx.media3.exoplayer.RendererCapabilities)17 Capabilities (androidx.media3.exoplayer.RendererCapabilities.Capabilities)9 Nullable (androidx.annotation.Nullable)7 SuppressLint (android.annotation.SuppressLint)6 MediaCodecInfo (androidx.media3.exoplayer.mediacodec.MediaCodecInfo)6 Point (android.graphics.Point)5 Handler (android.os.Handler)5 RendererConfiguration (androidx.media3.exoplayer.RendererConfiguration)5 Before (org.junit.Before)5 CodecCapabilities (android.media.MediaCodecInfo.CodecCapabilities)4 MediaFormat (android.media.MediaFormat)4 TrackGroup (androidx.media3.common.TrackGroup)4 ImmutableList (com.google.common.collect.ImmutableList)4 HashMap (java.util.HashMap)4 SurfaceTexture (android.graphics.SurfaceTexture)3 Looper (android.os.Looper)3 SystemClock (android.os.SystemClock)3