diff --git a/dom/media/mediasource/MediaSource.cpp b/dom/media/mediasource/MediaSource.cpp index 10dc8d6cd987..3a751adf2a55 100644 --- a/dom/media/mediasource/MediaSource.cpp +++ b/dom/media/mediasource/MediaSource.cpp @@ -79,7 +79,7 @@ static bool IsWebMForced(DecoderDoctorDiagnostics* aDiagnostics) { bool hwsupported = gfx::gfxVars::CanUseHardwareVideoDecoding(); #ifdef MOZ_WIDGET_ANDROID return !mp4supported || !hwsupported || VP9Benchmark::IsVP9DecodeFast() || - java::HardwareCodecCapabilityUtils::HasHWVP9(); + java::HardwareCodecCapabilityUtils::HasHWVP9(false /* aIsEncoder */); #else return !mp4supported || !hwsupported || VP9Benchmark::IsVP9DecodeFast(); #endif diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java index b0f9ffb59d27..5efef1c31f21 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java @@ -874,12 +874,12 @@ public class GeckoAppShell { @WrapForJNI(calledFrom = "gecko") private static boolean getHWEncoderCapability() { - return HardwareCodecCapabilityUtils.getHWEncoderCapability(); + return HardwareCodecCapabilityUtils.hasHWVP8(true /* aIsEncoder */); } @WrapForJNI(calledFrom = "gecko") private static boolean getHWDecoderCapability() { - return HardwareCodecCapabilityUtils.getHWDecoderCapability(); + return HardwareCodecCapabilityUtils.hasHWVP8(false /* aIsEncoder */); } static List queryIntentActivities(final Intent intent) { diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java index 7c51a32d3716..4aeb816f85e6 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java @@ -29,7 +29,17 @@ public final class HardwareCodecCapabilityUtils { "OMX.qcom.", "OMX.Nvidia.", "OMX.Exynos.", "OMX.Intel." }; private static final String VP8_MIME_TYPE = "video/x-vnd.on2.vp8"; + // List of supported HW VP9 codecs. + private static final String[] supportedVp9HwCodecPrefixes = { + "OMX.qcom.", "OMX.Exynos." + }; private static final String VP9_MIME_TYPE = "video/x-vnd.on2.vp9"; + // List of supported HW H.264 codecs. + private static final String[] supportedH264HwCodecPrefixes = { + "OMX.qcom.", "OMX.Intel.", "OMX.Exynos.", "OMX.Nvidia", "OMX.SEC.", + "OMX.IMG.", "OMX.k3.", "OMX.hisi.", "OMX.TI.", "OMX.MTK." + }; + private static final String H264_MIME_TYPE = "video/avc"; // NV12 color format supported by QCOM codec, but not declared in MediaCodec - // see /hardware/qcom/media/mm-core/inc/OMX_QCOMExtns.h private static final int @@ -123,73 +133,11 @@ public final class HardwareCodecCapabilityUtils { return false; } - public static boolean getHWEncoderCapability() { + public static boolean getHWCodecCapability(final String aMimeType, final boolean aIsEncoder) { if (Build.VERSION.SDK_INT >= 20) { for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) { - MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); - if (!info.isEncoder()) { - continue; - } - String name = null; - for (String mimeType : info.getSupportedTypes()) { - if (mimeType.equals(VP8_MIME_TYPE)) { - name = info.getName(); - break; - } - } - if (name == null) { - continue; // No HW support in this codec; try the next one. - } - Log.e(LOGTAG, "Found candidate encoder " + name); - - // Check if this is supported encoder. - boolean supportedCodec = false; - for (String codecPrefix : supportedVp8HwEncCodecPrefixes) { - if (name.startsWith(codecPrefix)) { - supportedCodec = true; - break; - } - } - if (!supportedCodec) { - continue; - } - - // Check if codec supports either yuv420 or nv12. - CodecCapabilities capabilities = - info.getCapabilitiesForType(VP8_MIME_TYPE); - for (int colorFormat : capabilities.colorFormats) { - Log.v(LOGTAG, " Color: 0x" + Integer.toHexString(colorFormat)); - } - for (int supportedColorFormat : supportedColorList) { - for (int codecColorFormat : capabilities.colorFormats) { - if (codecColorFormat == supportedColorFormat) { - // Found supported HW Encoder. - Log.e(LOGTAG, "Found target encoder " + name + - ". Color: 0x" + Integer.toHexString(codecColorFormat)); - return true; - } - } - } - } - } - // No HW encoder. - return false; - } - - public static boolean getHWDecoderCapability() { - return getHWDecoderCapability(VP8_MIME_TYPE); - } - - @WrapForJNI - public static boolean HasHWVP9() { - return getHWDecoderCapability(VP9_MIME_TYPE); - } - - public static boolean getHWDecoderCapability(final String aMimeType) { - if (Build.VERSION.SDK_INT >= 20) { - for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) { - MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); - if (info.isEncoder()) { + final MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); + if (info.isEncoder() != aIsEncoder) { continue; } String name = null; @@ -202,11 +150,15 @@ public final class HardwareCodecCapabilityUtils { if (name == null) { continue; // No HW support in this codec; try the next one. } - Log.e(LOGTAG, "Found candidate decoder " + name); + Log.d(LOGTAG, "Found candidate" + (aIsEncoder ? " encoder " : " decoder ") + name); - // Check if this is supported decoder. + // Check if this is supported codec. + final String[] hwList = getSupportedHWCodecPrefixes(aMimeType, aIsEncoder); + if (hwList == null) { + continue; + } boolean supportedCodec = false; - for (String codecPrefix : supportedVp8HwDecCodecPrefixes) { + for (final String codecPrefix : hwList) { if (name.startsWith(codecPrefix)) { supportedCodec = true; break; @@ -217,7 +169,7 @@ public final class HardwareCodecCapabilityUtils { } // Check if codec supports either yuv420 or nv12. - CodecCapabilities capabilities = + final CodecCapabilities capabilities = info.getCapabilitiesForType(aMimeType); for (int colorFormat : capabilities.colorFormats) { Log.v(LOGTAG, " Color: 0x" + Integer.toHexString(colorFormat)); @@ -225,8 +177,9 @@ public final class HardwareCodecCapabilityUtils { for (int supportedColorFormat : supportedColorList) { for (int codecColorFormat : capabilities.colorFormats) { if (codecColorFormat == supportedColorFormat) { - // Found supported HW decoder. - Log.e(LOGTAG, "Found target decoder " + name + + // Found supported HW Codec. + Log.d(LOGTAG, "Found target" + + (aIsEncoder ? " encoder " : " decoder ") + name + ". Color: 0x" + Integer.toHexString(codecColorFormat)); return true; } @@ -234,6 +187,35 @@ public final class HardwareCodecCapabilityUtils { } } } - return false; // No HW decoder. + // No HW codec. + return false; + } + + private static String[] getSupportedHWCodecPrefixes(final String aMimeType, final boolean aIsEncoder) { + if (aMimeType.equals(H264_MIME_TYPE)) { + return supportedH264HwCodecPrefixes; + } + if (aMimeType.equals(VP9_MIME_TYPE)) { + return supportedVp9HwCodecPrefixes; + } + if (aMimeType.equals(VP8_MIME_TYPE)) { + return aIsEncoder ? supportedVp8HwEncCodecPrefixes : supportedVp8HwDecCodecPrefixes; + } + return null; + } + + public static boolean hasHWVP8(final boolean aIsEncoder) { + return getHWCodecCapability(VP8_MIME_TYPE, aIsEncoder); + } + + @WrapForJNI + public static boolean hasHWVP9(final boolean aIsEncoder) { + return getHWCodecCapability(VP9_MIME_TYPE, aIsEncoder); + } + + @WrapForJNI(calledFrom = "gecko") + public static boolean hasHWH264() { + return getHWCodecCapability(H264_MIME_TYPE, true) && + getHWCodecCapability(H264_MIME_TYPE, false); } }