Search in sources :

Example 6 with CodecCapabilities

use of android.media.MediaCodecInfo.CodecCapabilities in project edx-app-android by edx.

the class MediaCodecUtil method maxH264DecodableFrameSize.

/**
 * @return the maximum frame size for an H264 stream that can be decoded on the device.
 */
public static int maxH264DecodableFrameSize() {
    Pair<MediaCodecInfo, CodecCapabilities> info = getMediaCodecInfo(MimeTypes.VIDEO_H264);
    if (info == null) {
        return 0;
    }
    int maxH264DecodableFrameSize = 0;
    CodecCapabilities capabilities = info.second;
    for (int i = 0; i < capabilities.profileLevels.length; i++) {
        CodecProfileLevel profileLevel = capabilities.profileLevels[i];
        maxH264DecodableFrameSize = Math.max(avcLevelToMaxFrameSize(profileLevel.level), maxH264DecodableFrameSize);
    }
    return maxH264DecodableFrameSize;
}
Also used : CodecProfileLevel(android.media.MediaCodecInfo.CodecProfileLevel) MediaCodecInfo(android.media.MediaCodecInfo) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities)

Example 7 with CodecCapabilities

use of android.media.MediaCodecInfo.CodecCapabilities in project Telegram-FOSS by Telegram-FOSS-Team.

the class MediaCodecVideoDecoderFactory method createDecoder.

@Nullable
@Override
public VideoDecoder createDecoder(VideoCodecInfo codecType) {
    VideoCodecMimeType type = VideoCodecMimeType.valueOf(codecType.getName());
    MediaCodecInfo info = findCodecForType(type);
    if (info == null) {
        return null;
    }
    CodecCapabilities capabilities = info.getCapabilitiesForType(type.mimeType());
    return new AndroidVideoDecoder(new MediaCodecWrapperFactoryImpl(), info.getName(), type, MediaCodecUtils.selectColorFormat(MediaCodecUtils.DECODER_COLOR_FORMATS, capabilities), sharedContext);
}
Also used : MediaCodecInfo(android.media.MediaCodecInfo) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) Nullable(androidx.annotation.Nullable)

Example 8 with CodecCapabilities

use of android.media.MediaCodecInfo.CodecCapabilities in project Telegram-FOSS by Telegram-FOSS-Team.

the class MediaCodecUtil method getDecoderInfosInternal.

// Internal methods.
/**
 * Returns {@link MediaCodecInfo}s for the given codec {@link CodecKey} in the order given by
 * {@code mediaCodecList}.
 *
 * @param key The codec key.
 * @param mediaCodecList The codec list.
 * @return The codec information for usable codecs matching the specified key.
 * @throws DecoderQueryException If there was an error querying the available decoders.
 */
private static ArrayList<MediaCodecInfo> getDecoderInfosInternal(CodecKey key, MediaCodecListCompat mediaCodecList) throws DecoderQueryException {
    try {
        ArrayList<MediaCodecInfo> decoderInfos = new ArrayList<>();
        String mimeType = key.mimeType;
        int numberOfCodecs = mediaCodecList.getCodecCount();
        boolean secureDecodersExplicit = mediaCodecList.secureDecodersExplicit();
        // Note: MediaCodecList is sorted by the framework such that the best decoders come first.
        for (int i = 0; i < numberOfCodecs; i++) {
            android.media.MediaCodecInfo codecInfo = mediaCodecList.getCodecInfoAt(i);
            if (isAlias(codecInfo)) {
                // names.
                continue;
            }
            String name = codecInfo.getName();
            if (!isCodecUsableDecoder(codecInfo, name, secureDecodersExplicit, mimeType)) {
                continue;
            }
            @Nullable String codecMimeType = getCodecMimeType(codecInfo, name, mimeType);
            if (codecMimeType == null) {
                continue;
            }
            try {
                CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(codecMimeType);
                boolean tunnelingSupported = mediaCodecList.isFeatureSupported(CodecCapabilities.FEATURE_TunneledPlayback, codecMimeType, capabilities);
                boolean tunnelingRequired = mediaCodecList.isFeatureRequired(CodecCapabilities.FEATURE_TunneledPlayback, codecMimeType, capabilities);
                if ((!key.tunneling && tunnelingRequired) || (key.tunneling && !tunnelingSupported)) {
                    continue;
                }
                boolean secureSupported = mediaCodecList.isFeatureSupported(CodecCapabilities.FEATURE_SecurePlayback, codecMimeType, capabilities);
                boolean secureRequired = mediaCodecList.isFeatureRequired(CodecCapabilities.FEATURE_SecurePlayback, codecMimeType, capabilities);
                if ((!key.secure && secureRequired) || (key.secure && !secureSupported)) {
                    continue;
                }
                boolean hardwareAccelerated = isHardwareAccelerated(codecInfo);
                boolean softwareOnly = isSoftwareOnly(codecInfo);
                boolean vendor = isVendor(codecInfo);
                boolean forceDisableAdaptive = codecNeedsDisableAdaptationWorkaround(name);
                if ((secureDecodersExplicit && key.secure == secureSupported) || (!secureDecodersExplicit && !key.secure)) {
                    decoderInfos.add(MediaCodecInfo.newInstance(name, mimeType, codecMimeType, capabilities, hardwareAccelerated, softwareOnly, vendor, forceDisableAdaptive, /* forceSecure= */
                    false));
                } else if (!secureDecodersExplicit && secureSupported) {
                    decoderInfos.add(MediaCodecInfo.newInstance(name + ".secure", mimeType, codecMimeType, capabilities, hardwareAccelerated, softwareOnly, vendor, forceDisableAdaptive, /* forceSecure= */
                    true));
                    // It only makes sense to have one synthesized secure decoder, return immediately.
                    return decoderInfos;
                }
            } catch (Exception e) {
                if (Util.SDK_INT <= 23 && !decoderInfos.isEmpty()) {
                    // Suppress error querying secondary codec capabilities up to API level 23.
                    Log.e(TAG, "Skipping codec " + name + " (failed to query capabilities)");
                } else {
                    // Rethrow error querying primary codec capabilities, or secondary codec
                    // capabilities if API level is greater than 23.
                    Log.e(TAG, "Failed to query codec " + name + " (" + codecMimeType + ")");
                    throw e;
                }
            }
        }
        return decoderInfos;
    } catch (Exception e) {
        // or an IllegalArgumentException here.
        throw new DecoderQueryException(e);
    }
}
Also used : ArrayList(java.util.ArrayList) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) SuppressLint(android.annotation.SuppressLint) Nullable(androidx.annotation.Nullable)

Example 9 with CodecCapabilities

use of android.media.MediaCodecInfo.CodecCapabilities 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 10 with CodecCapabilities

use of android.media.MediaCodecInfo.CodecCapabilities in project media by androidx.

the class MediaCodecVideoRendererTest method supportsFormat_withDolbyVisionMedia_returnsTrueWhenFallbackToH265orH264Allowed.

@Test
public void supportsFormat_withDolbyVisionMedia_returnsTrueWhenFallbackToH265orH264Allowed() throws Exception {
    // Create Dolby media formats that could fall back to H265 or H264.
    Format formatDvheDtrFallbackToH265 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_DOLBY_VISION).setCodecs("dvhe.04.01").build();
    Format formatDvheStFallbackToH265 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_DOLBY_VISION).setCodecs("dvhe.08.01").build();
    Format formatDvavSeFallbackToH264 = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_DOLBY_VISION).setCodecs("dvav.09.01").build();
    Format formatNoFallbackPossible = new Format.Builder().setSampleMimeType(MimeTypes.VIDEO_DOLBY_VISION).setCodecs("dvav.01.01").build();
    // Only provide H264 and H265 decoders with codec profiles needed for fallback.
    MediaCodecSelector mediaCodecSelector = (mimeType, requiresSecureDecoder, requiresTunnelingDecoder) -> {
        switch(mimeType) {
            case MimeTypes.VIDEO_H264:
                CodecCapabilities capabilitiesH264 = new CodecCapabilities();
                capabilitiesH264.profileLevels = new CodecProfileLevel[] { new CodecProfileLevel(), new CodecProfileLevel() };
                capabilitiesH264.profileLevels[0].profile = CodecProfileLevel.AVCProfileBaseline;
                capabilitiesH264.profileLevels[0].level = CodecProfileLevel.AVCLevel42;
                capabilitiesH264.profileLevels[1].profile = CodecProfileLevel.AVCProfileHigh;
                capabilitiesH264.profileLevels[1].level = CodecProfileLevel.AVCLevel42;
                return ImmutableList.of(MediaCodecInfo.newInstance(/* name= */
                "h264-codec", /* mimeType= */
                mimeType, /* codecMimeType= */
                mimeType, /* capabilities= */
                capabilitiesH264, /* hardwareAccelerated= */
                false, /* softwareOnly= */
                true, /* vendor= */
                false, /* forceDisableAdaptive= */
                false, /* forceSecure= */
                false));
            case MimeTypes.VIDEO_H265:
                CodecCapabilities capabilitiesH265 = new CodecCapabilities();
                capabilitiesH265.profileLevels = new CodecProfileLevel[] { new CodecProfileLevel(), new CodecProfileLevel() };
                capabilitiesH265.profileLevels[0].profile = CodecProfileLevel.HEVCProfileMain;
                capabilitiesH265.profileLevels[0].level = CodecProfileLevel.HEVCMainTierLevel41;
                capabilitiesH265.profileLevels[1].profile = CodecProfileLevel.HEVCProfileMain10;
                capabilitiesH265.profileLevels[1].level = CodecProfileLevel.HEVCHighTierLevel51;
                return ImmutableList.of(MediaCodecInfo.newInstance(/* name= */
                "h265-codec", /* mimeType= */
                mimeType, /* codecMimeType= */
                mimeType, /* capabilities= */
                capabilitiesH265, /* hardwareAccelerated= */
                false, /* softwareOnly= */
                true, /* vendor= */
                false, /* forceDisableAdaptive= */
                false, /* forceSecure= */
                false));
            default:
                return ImmutableList.of();
        }
    };
    MediaCodecVideoRenderer renderer = new MediaCodecVideoRenderer(ApplicationProvider.getApplicationContext(), mediaCodecSelector, /* allowedJoiningTimeMs= */
    0, /* eventHandler= */
    new Handler(testMainLooper), /* eventListener= */
    eventListener, /* maxDroppedFramesToNotify= */
    1);
    renderer.init(/* index= */
    0, PlayerId.UNSET);
    @Capabilities int capabilitiesDvheDtrFallbackToH265 = renderer.supportsFormat(formatDvheDtrFallbackToH265);
    @Capabilities int capabilitiesDvheStFallbackToH265 = renderer.supportsFormat(formatDvheStFallbackToH265);
    @Capabilities int capabilitiesDvavSeFallbackToH264 = renderer.supportsFormat(formatDvavSeFallbackToH264);
    @Capabilities int capabilitiesNoFallbackPossible = renderer.supportsFormat(formatNoFallbackPossible);
    assertThat(RendererCapabilities.getFormatSupport(capabilitiesDvheDtrFallbackToH265)).isEqualTo(C.FORMAT_HANDLED);
    assertThat(RendererCapabilities.getFormatSupport(capabilitiesDvheStFallbackToH265)).isEqualTo(C.FORMAT_HANDLED);
    assertThat(RendererCapabilities.getFormatSupport(capabilitiesDvavSeFallbackToH264)).isEqualTo(C.FORMAT_HANDLED);
    assertThat(RendererCapabilities.getFormatSupport(capabilitiesNoFallbackPossible)).isEqualTo(C.FORMAT_UNSUPPORTED_SUBTYPE);
}
Also used : CodecProfileLevel(android.media.MediaCodecInfo.CodecProfileLevel) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) AndroidJUnit4(androidx.test.ext.junit.runners.AndroidJUnit4) ApplicationProvider(androidx.test.core.app.ApplicationProvider) DrmSessionManager(androidx.media3.exoplayer.drm.DrmSessionManager) MediaCodecInfo(androidx.media3.exoplayer.mediacodec.MediaCodecInfo) END_OF_STREAM_ITEM(androidx.media3.test.utils.FakeSampleStream.FakeSampleStreamItem.END_OF_STREAM_ITEM) Renderer(androidx.media3.exoplayer.Renderer) Handler(android.os.Handler) Looper(android.os.Looper) After(org.junit.After) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) RendererConfiguration(androidx.media3.exoplayer.RendererConfiguration) Surface(android.view.Surface) VideoSize(androidx.media3.common.VideoSize) FakeSampleStream(androidx.media3.test.utils.FakeSampleStream) Collectors(java.util.stream.Collectors) Format(androidx.media3.common.Format) MediaCodecSelector(androidx.media3.exoplayer.mediacodec.MediaCodecSelector) Nullable(androidx.annotation.Nullable) FakeSampleStreamItem.format(androidx.media3.test.utils.FakeSampleStream.FakeSampleStreamItem.format) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) MediaFormat(android.media.MediaFormat) Mock(org.mockito.Mock) RunWith(org.junit.runner.RunWith) SystemClock(android.os.SystemClock) Shadows.shadowOf(org.robolectric.Shadows.shadowOf) RendererCapabilities(androidx.media3.exoplayer.RendererCapabilities) Capabilities(androidx.media3.exoplayer.RendererCapabilities.Capabilities) ArgumentCaptor(org.mockito.ArgumentCaptor) ImmutableList(com.google.common.collect.ImmutableList) DrmSessionEventListener(androidx.media3.exoplayer.drm.DrmSessionEventListener) MockitoJUnit(org.mockito.junit.MockitoJUnit) Before(org.junit.Before) SurfaceTexture(android.graphics.SurfaceTexture) ShadowLooper(org.robolectric.shadows.ShadowLooper) MimeTypes(androidx.media3.common.MimeTypes) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) DefaultAllocator(androidx.media3.exoplayer.upstream.DefaultAllocator) C(androidx.media3.common.C) Mockito.never(org.mockito.Mockito.never) Rule(org.junit.Rule) FakeSampleStreamItem.oneByteSample(androidx.media3.test.utils.FakeSampleStream.FakeSampleStreamItem.oneByteSample) PlayerId(androidx.media3.exoplayer.analytics.PlayerId) MockitoRule(org.mockito.junit.MockitoRule) Collections(java.util.Collections) CodecProfileLevel(android.media.MediaCodecInfo.CodecProfileLevel) MediaCodecSelector(androidx.media3.exoplayer.mediacodec.MediaCodecSelector) Format(androidx.media3.common.Format) MediaFormat(android.media.MediaFormat) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) RendererCapabilities(androidx.media3.exoplayer.RendererCapabilities) Capabilities(androidx.media3.exoplayer.RendererCapabilities.Capabilities) Handler(android.os.Handler) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) Test(org.junit.Test)

Aggregations

CodecCapabilities (android.media.MediaCodecInfo.CodecCapabilities)28 MediaCodecInfo (android.media.MediaCodecInfo)15 Test (org.junit.Test)11 Config (org.robolectric.annotation.Config)8 CodecProfileLevel (android.media.MediaCodecInfo.CodecProfileLevel)7 Nullable (androidx.annotation.Nullable)6 ArrayList (java.util.ArrayList)5 SparseIntArray (android.util.SparseIntArray)4 IOException (java.io.IOException)4 HashSet (java.util.HashSet)4 SuppressLint (android.annotation.SuppressLint)3 Point (android.graphics.Point)3 VideoCapabilities (android.media.MediaCodecInfo.VideoCapabilities)3 MediaCodecList (android.media.MediaCodecList)3 TreeMap (java.util.TreeMap)3 SurfaceTexture (android.graphics.SurfaceTexture)2 MediaFormat (android.media.MediaFormat)2 Handler (android.os.Handler)2 Looper (android.os.Looper)2 SystemClock (android.os.SystemClock)2