Search in sources :

Example 26 with CodecCapabilities

use of android.media.MediaCodecInfo.CodecCapabilities in project ExoPlayer by google.

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 : ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) CodecProfileLevel(android.media.MediaCodecInfo.CodecProfileLevel) MediaFormat(android.media.MediaFormat) RendererCapabilities(com.google.android.exoplayer2.RendererCapabilities) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Mock(org.mockito.Mock) RunWith(org.junit.runner.RunWith) SystemClock(android.os.SystemClock) AndroidJUnit4(androidx.test.ext.junit.runners.AndroidJUnit4) Shadows.shadowOf(org.robolectric.Shadows.shadowOf) ApplicationProvider(androidx.test.core.app.ApplicationProvider) Format(com.google.android.exoplayer2.Format) PlayerId(com.google.android.exoplayer2.analytics.PlayerId) MediaCodecInfo(com.google.android.exoplayer2.mediacodec.MediaCodecInfo) ArgumentCaptor(org.mockito.ArgumentCaptor) DrmSessionEventListener(com.google.android.exoplayer2.drm.DrmSessionEventListener) MimeTypes(com.google.android.exoplayer2.util.MimeTypes) ImmutableList(com.google.common.collect.ImmutableList) Handler(android.os.Handler) Looper(android.os.Looper) After(org.junit.After) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) MockitoJUnit(org.mockito.junit.MockitoJUnit) FakeSampleStream(com.google.android.exoplayer2.testutil.FakeSampleStream) DefaultAllocator(com.google.android.exoplayer2.upstream.DefaultAllocator) C(com.google.android.exoplayer2.C) Before(org.junit.Before) FakeSampleStreamItem.format(com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.format) SurfaceTexture(android.graphics.SurfaceTexture) Capabilities(com.google.android.exoplayer2.RendererCapabilities.Capabilities) ShadowLooper(org.robolectric.shadows.ShadowLooper) END_OF_STREAM_ITEM(com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.END_OF_STREAM_ITEM) Surface(android.view.Surface) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) Truth.assertThat(com.google.common.truth.Truth.assertThat) Collectors(java.util.stream.Collectors) Mockito.verify(org.mockito.Mockito.verify) FakeSampleStreamItem.oneByteSample(com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem.oneByteSample) Mockito.never(org.mockito.Mockito.never) Nullable(androidx.annotation.Nullable) Rule(org.junit.Rule) RendererConfiguration(com.google.android.exoplayer2.RendererConfiguration) MediaCodecSelector(com.google.android.exoplayer2.mediacodec.MediaCodecSelector) DrmSessionManager(com.google.android.exoplayer2.drm.DrmSessionManager) MockitoRule(org.mockito.junit.MockitoRule) Renderer(com.google.android.exoplayer2.Renderer) Collections(java.util.Collections) CodecProfileLevel(android.media.MediaCodecInfo.CodecProfileLevel) MediaCodecSelector(com.google.android.exoplayer2.mediacodec.MediaCodecSelector) MediaFormat(android.media.MediaFormat) Format(com.google.android.exoplayer2.Format) RendererCapabilities(com.google.android.exoplayer2.RendererCapabilities) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) Capabilities(com.google.android.exoplayer2.RendererCapabilities.Capabilities) Handler(android.os.Handler) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) Test(org.junit.Test)

Example 27 with CodecCapabilities

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

the class ShadowMediaCodecListTest method codecCapabilities_createFromProfileLevel.

@Test
public void codecCapabilities_createFromProfileLevel() {
    CodecCapabilities codecCapabilities = CodecCapabilities.createFromProfileLevel(MediaFormat.MIMETYPE_VIDEO_AVC, CodecProfileLevel.AVCProfileBaseline, CodecProfileLevel.AVCLevel2);
    CodecProfileLevel expected = new CodecProfileLevel();
    expected.profile = CodecProfileLevel.AVCProfileBaseline;
    expected.level = CodecProfileLevel.AVCLevel2;
    assertThat(codecCapabilities.getMimeType()).isEqualTo(MediaFormat.MIMETYPE_VIDEO_AVC);
    assertThat(codecCapabilities.profileLevels).hasLength(1);
    assertThat(codecCapabilities.profileLevels[0]).isEqualTo(expected);
}
Also used : CodecProfileLevel(android.media.MediaCodecInfo.CodecProfileLevel) CodecCapabilities(android.media.MediaCodecInfo.CodecCapabilities) Test(org.junit.Test)

Example 28 with CodecCapabilities

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

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, mimeType);
                boolean softwareOnly = isSoftwareOnly(codecInfo, mimeType);
                boolean vendor = isVendor(codecInfo);
                if ((secureDecodersExplicit && key.secure == secureSupported) || (!secureDecodersExplicit && !key.secure)) {
                    decoderInfos.add(MediaCodecInfo.newInstance(name, mimeType, codecMimeType, capabilities, hardwareAccelerated, softwareOnly, vendor, /* forceDisableAdaptive= */
                    false, /* forceSecure= */
                    false));
                } else if (!secureDecodersExplicit && secureSupported) {
                    decoderInfos.add(MediaCodecInfo.newInstance(name + ".secure", mimeType, codecMimeType, capabilities, hardwareAccelerated, softwareOnly, vendor, /* forceDisableAdaptive= */
                    false, /* 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)

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