зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1822932
- Add utility functions to distinguish between SW/HW codec support on Android r=geckoview-reviewers,owlish
Differential Revision: https://phabricator.services.mozilla.com/D166239
This commit is contained in:
Родитель
0ff58c4d40
Коммит
02a8ca6f31
|
@ -1,7 +1,8 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* * This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.util;
|
||||
|
||||
|
@ -12,6 +13,7 @@ import android.media.MediaCodecInfo.CodecCapabilities;
|
|||
import android.media.MediaCodecList;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
|
@ -58,6 +60,7 @@ public final class HardwareCodecCapabilityUtils {
|
|||
CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
|
||||
COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m
|
||||
};
|
||||
private static final int COLOR_FORMAT_NOT_SUPPORTED = -1;
|
||||
private static final String[] adaptivePlaybackBlacklist = {
|
||||
"GT-I9300", // S3 (I9300 / I9300I)
|
||||
"SCH-I535", // S3
|
||||
|
@ -94,30 +97,84 @@ public final class HardwareCodecCapabilityUtils {
|
|||
return codecList;
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public static String[] getDecoderSupportedMimeTypes() {
|
||||
// Return list of all codecs (decode + encode).
|
||||
private static MediaCodecInfo[] getCodecList() {
|
||||
final MediaCodecInfo[] codecList;
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
codecList = getCodecListWithOldAPI();
|
||||
} else {
|
||||
final MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
|
||||
codecList = list.getCodecInfos();
|
||||
}
|
||||
|
||||
final Set<String> supportedTypes = new HashSet<>();
|
||||
|
||||
for (final MediaCodecInfo codec : codecList) {
|
||||
if (codec.isEncoder()) {
|
||||
continue;
|
||||
}
|
||||
supportedTypes.addAll(Arrays.asList(codec.getSupportedTypes()));
|
||||
}
|
||||
|
||||
return supportedTypes.toArray(new String[0]);
|
||||
return codecList;
|
||||
}
|
||||
|
||||
// Return list of all decoders.
|
||||
private static MediaCodecInfo[] getDecoderInfos() {
|
||||
final ArrayList<MediaCodecInfo> decoderList = new ArrayList<MediaCodecInfo>();
|
||||
for (final MediaCodecInfo info : getCodecList()) {
|
||||
if (!info.isEncoder()) {
|
||||
decoderList.add(info);
|
||||
}
|
||||
}
|
||||
return decoderList.toArray(new MediaCodecInfo[0]);
|
||||
}
|
||||
|
||||
// Return list of all encoders.
|
||||
private static MediaCodecInfo[] getEncoderInfos() {
|
||||
final ArrayList<MediaCodecInfo> encoderList = new ArrayList<MediaCodecInfo>();
|
||||
for (final MediaCodecInfo info : getCodecList()) {
|
||||
if (info.isEncoder()) {
|
||||
encoderList.add(info);
|
||||
}
|
||||
}
|
||||
return encoderList.toArray(new MediaCodecInfo[0]);
|
||||
}
|
||||
|
||||
// Return list of all decoder-supported MIME types without distinguishing
|
||||
// between SW/HW support.
|
||||
@WrapForJNI
|
||||
public static String[] getDecoderSupportedMimeTypes() {
|
||||
final Set<String> mimeTypes = new HashSet<>();
|
||||
for (final MediaCodecInfo info : getDecoderInfos()) {
|
||||
mimeTypes.addAll(Arrays.asList(info.getSupportedTypes()));
|
||||
}
|
||||
return mimeTypes.toArray(new String[0]);
|
||||
}
|
||||
|
||||
// Return list of all decoder-supported MIME types, each prefixed with
|
||||
// either SW or HW indicating software or hardware support.
|
||||
@WrapForJNI
|
||||
public static String[] getDecoderSupportedMimeTypesWithAccelInfo() {
|
||||
final Set<String> mimeTypes = new HashSet<>();
|
||||
final String[] hwPrefixes = getAllSupportedHWCodecPrefixes(false);
|
||||
|
||||
for (final MediaCodecInfo info : getDecoderInfos()) {
|
||||
final String[] supportedTypes = info.getSupportedTypes();
|
||||
for (final String mimeType : info.getSupportedTypes()) {
|
||||
boolean isHwPrefix = false;
|
||||
for (final String prefix : hwPrefixes) {
|
||||
if (info.getName().startsWith(prefix)) {
|
||||
isHwPrefix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isHwPrefix) {
|
||||
mimeTypes.add("SW " + mimeType);
|
||||
continue;
|
||||
}
|
||||
final CodecCapabilities caps = info.getCapabilitiesForType(mimeType);
|
||||
if (getSupportsYUV420orNV12(caps) != COLOR_FORMAT_NOT_SUPPORTED) {
|
||||
mimeTypes.add("HW " + mimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final String typeit : mimeTypes) {
|
||||
Log.d(LOGTAG, "MIME support: " + typeit);
|
||||
}
|
||||
return mimeTypes.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static boolean checkSupportsAdaptivePlayback(
|
||||
final MediaCodec aCodec, final String aMimeType) {
|
||||
// isFeatureSupported supported on API level >= 19.
|
||||
|
@ -158,6 +215,7 @@ public final class HardwareCodecCapabilityUtils {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check if a given MIME Type has HW decode or encode support.
|
||||
public static boolean getHWCodecCapability(final String aMimeType, final boolean aIsEncoder) {
|
||||
if (Build.VERSION.SDK_INT >= 20) {
|
||||
for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
|
||||
|
@ -208,20 +266,16 @@ public final class HardwareCodecCapabilityUtils {
|
|||
+ Integer.toHexString(pl.level));
|
||||
}
|
||||
}
|
||||
for (final int supportedColorFormat : supportedColorList) {
|
||||
for (final int codecColorFormat : capabilities.colorFormats) {
|
||||
if (codecColorFormat == supportedColorFormat) {
|
||||
// Found supported HW Codec.
|
||||
Log.d(
|
||||
LOGTAG,
|
||||
"Found target"
|
||||
+ (aIsEncoder ? " encoder " : " decoder ")
|
||||
+ name
|
||||
+ ". Color: 0x"
|
||||
+ Integer.toHexString(codecColorFormat));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final int codecColorFormat = getSupportsYUV420orNV12(capabilities);
|
||||
if (codecColorFormat != COLOR_FORMAT_NOT_SUPPORTED) {
|
||||
Log.d(
|
||||
LOGTAG,
|
||||
"Found target"
|
||||
+ (aIsEncoder ? " encoder " : " decoder ")
|
||||
+ name
|
||||
+ ". Color: 0x"
|
||||
+ Integer.toHexString(codecColorFormat));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,6 +283,19 @@ public final class HardwareCodecCapabilityUtils {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check if codec supports YUV420 or NV12
|
||||
private static int getSupportsYUV420orNV12(final CodecCapabilities aCodecCaps) {
|
||||
for (final int supportedColorFormat : supportedColorList) {
|
||||
for (final int codecColorFormat : aCodecCaps.colorFormats) {
|
||||
if (codecColorFormat == supportedColorFormat) {
|
||||
return codecColorFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
return COLOR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// Check if MIME type string has HW prefix (encode or decode, VP8, VP9, and H264)
|
||||
private static String[] getSupportedHWCodecPrefixes(
|
||||
final String aMimeType, final boolean aIsEncoder) {
|
||||
if (aMimeType.equals(H264_MIME_TYPE)) {
|
||||
|
@ -243,6 +310,16 @@ public final class HardwareCodecCapabilityUtils {
|
|||
return null;
|
||||
}
|
||||
|
||||
// Return list of HW codec prefixes (encode or decode, VP8, VP9, and H264)
|
||||
private static String[] getAllSupportedHWCodecPrefixes(final boolean aIsEncoder) {
|
||||
final Set<String> prefixes = new HashSet<>();
|
||||
final String[] mimeTypes = {H264_MIME_TYPE, VP8_MIME_TYPE, VP9_MIME_TYPE};
|
||||
for (final String mt : mimeTypes) {
|
||||
prefixes.addAll(Arrays.asList(getSupportedHWCodecPrefixes(mt, aIsEncoder)));
|
||||
}
|
||||
return prefixes.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public static boolean hasHWVP8(final boolean aIsEncoder) {
|
||||
return getHWCodecCapability(VP8_MIME_TYPE, aIsEncoder);
|
||||
|
|
Загрузка…
Ссылка в новой задаче