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;
}
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);
}
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);
}
}
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));
}
}
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);
}
Aggregations