From 5b6891afddcef18ea699efcd457dfab80c22ac70 Mon Sep 17 00:00:00 2001 From: Alex Leung Date: Thu, 18 Jan 2018 10:01:14 -0800 Subject: [PATCH] Add MediaTek H264 and VP8 HW Codec Support with field trial MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:8761 Change-Id: I06cdff086b624afaf3533ced3e5e4eaf3a862720 Reviewed-on: https://webrtc-review.googlesource.com/39980 Commit-Queue: Alex Leung Reviewed-by: Sami Kalliomäki Reviewed-by: Alex Glaznev Cr-Commit-Position: refs/heads/master@{#21699} --- .../org/webrtc/MediaCodecVideoDecoder.java | 45 +++++++++++++++---- .../org/webrtc/MediaCodecVideoEncoder.java | 21 ++++++--- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/sdk/android/api/org/webrtc/MediaCodecVideoDecoder.java b/sdk/android/api/org/webrtc/MediaCodecVideoDecoder.java index 57682ab7f7..cc014fa988 100644 --- a/sdk/android/api/org/webrtc/MediaCodecVideoDecoder.java +++ b/sdk/android/api/org/webrtc/MediaCodecVideoDecoder.java @@ -20,6 +20,7 @@ import android.os.SystemClock; import android.view.Surface; import java.nio.ByteBuffer; import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -82,16 +83,37 @@ public class MediaCodecVideoDecoder { private static final String VP9_MIME_TYPE = "video/x-vnd.on2.vp9"; private static final String H264_MIME_TYPE = "video/avc"; // List of supported HW VP8 decoders. - private static final String[] supportedVp8HwCodecPrefixes = { - "OMX.qcom.", "OMX.Nvidia.", "OMX.Exynos.", "OMX.Intel."}; + private static final String[] supportedVp8HwCodecPrefixes() { + ArrayList supportedPrefixes = new ArrayList(); + supportedPrefixes.add("OMX.qcom."); + supportedPrefixes.add("OMX.Nvidia."); + supportedPrefixes.add("OMX.Exynos."); + supportedPrefixes.add("OMX.Intel."); + if (PeerConnectionFactory.fieldTrialsFindFullName("WebRTC-MediaTekVP8").equals("Enabled") + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + supportedPrefixes.add("OMX.MTK."); + } + return supportedPrefixes.toArray(new String[supportedPrefixes.size()]); + } // List of supported HW VP9 decoders. private static final String[] supportedVp9HwCodecPrefixes = {"OMX.qcom.", "OMX.Exynos."}; // List of supported HW H.264 decoders. - private static final String[] supportedH264HwCodecPrefixes = { - "OMX.qcom.", "OMX.Intel.", "OMX.Exynos."}; + private static final String[] supportedH264HwCodecPrefixes() { + ArrayList supportedPrefixes = new ArrayList(); + supportedPrefixes.add("OMX.qcom."); + supportedPrefixes.add("OMX.Intel."); + supportedPrefixes.add("OMX.Exynos."); + if (PeerConnectionFactory.fieldTrialsFindFullName("WebRTC-MediaTekH264").equals("Enabled") + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + supportedPrefixes.add("OMX.MTK."); + } + return supportedPrefixes.toArray(new String[supportedPrefixes.size()]); + } + // List of supported HW H.264 high profile decoders. private static final String supportedQcomH264HighProfileHwCodecPrefix = "OMX.qcom."; private static final String supportedExynosH264HighProfileHwCodecPrefix = "OMX.Exynos."; + private static final String supportedMediaTekH264HighProfileHwCodecPrefix = "OMX.MTK."; // NV12 color format supported by QCOM codec, but not declared in MediaCodec - // see /hardware/qcom/media/mm-core/inc/OMX_QCOMExtns.h @@ -156,7 +178,7 @@ public class MediaCodecVideoDecoder { @CalledByNativeUnchecked public static boolean isVp8HwSupported() { return !hwDecoderDisabledTypes.contains(VP8_MIME_TYPE) - && (findDecoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes) != null); + && (findDecoder(VP8_MIME_TYPE, supportedVp8HwCodecPrefixes()) != null); } @CalledByNativeUnchecked @@ -168,7 +190,7 @@ public class MediaCodecVideoDecoder { @CalledByNativeUnchecked public static boolean isH264HwSupported() { return !hwDecoderDisabledTypes.contains(H264_MIME_TYPE) - && (findDecoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes) != null); + && (findDecoder(H264_MIME_TYPE, supportedH264HwCodecPrefixes()) != null); } @CalledByNative @@ -188,6 +210,13 @@ public class MediaCodecVideoDecoder { != null) { return true; } + // Support H.264 HP decoding on MediaTek chips for Android O and above + if (PeerConnectionFactory.fieldTrialsFindFullName("WebRTC-MediaTekH264").equals("Enabled") + && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && findDecoder(H264_MIME_TYPE, new String[] {supportedMediaTekH264HighProfileHwCodecPrefix}) + != null) { + return true; + } return false; } @@ -301,13 +330,13 @@ public class MediaCodecVideoDecoder { String[] supportedCodecPrefixes = null; if (type == VideoCodecType.VIDEO_CODEC_VP8) { mime = VP8_MIME_TYPE; - supportedCodecPrefixes = supportedVp8HwCodecPrefixes; + supportedCodecPrefixes = supportedVp8HwCodecPrefixes(); } else if (type == VideoCodecType.VIDEO_CODEC_VP9) { mime = VP9_MIME_TYPE; supportedCodecPrefixes = supportedVp9HwCodecPrefixes; } else if (type == VideoCodecType.VIDEO_CODEC_H264) { mime = H264_MIME_TYPE; - supportedCodecPrefixes = supportedH264HwCodecPrefixes; + supportedCodecPrefixes = supportedH264HwCodecPrefixes(); } else { throw new RuntimeException("initDecode: Non-supported codec " + type); } diff --git a/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java b/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java index db82be96b7..2e8b802769 100644 --- a/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java +++ b/sdk/android/api/org/webrtc/MediaCodecVideoEncoder.java @@ -176,8 +176,17 @@ public class MediaCodecVideoEncoder { "OMX.qcom.", Build.VERSION_CODES.KITKAT, BitrateAdjustmentType.NO_ADJUSTMENT); private static final MediaCodecProperties exynosH264HwProperties = new MediaCodecProperties( "OMX.Exynos.", Build.VERSION_CODES.LOLLIPOP, BitrateAdjustmentType.FRAMERATE_ADJUSTMENT); - private static final MediaCodecProperties[] h264HwList = - new MediaCodecProperties[] {qcomH264HwProperties, exynosH264HwProperties}; + private static final MediaCodecProperties mediatekH264HwProperties = new MediaCodecProperties( + "OMX.MTK.", Build.VERSION_CODES.O, BitrateAdjustmentType.FRAMERATE_ADJUSTMENT); + private static final MediaCodecProperties[] h264HwList() { + final ArrayList supported_codecs = new ArrayList(); + supported_codecs.add(qcomH264HwProperties); + supported_codecs.add(exynosH264HwProperties); + if (PeerConnectionFactory.fieldTrialsFindFullName("WebRTC-MediaTekH264").equals("Enabled")) { + supported_codecs.add(mediatekH264HwProperties); + } + return supported_codecs.toArray(new MediaCodecProperties[supported_codecs.size()]); + } // List of supported HW H.264 high profile encoders. private static final MediaCodecProperties exynosH264HighProfileHwProperties = @@ -277,7 +286,7 @@ public class MediaCodecVideoEncoder { @CalledByNative public static boolean isH264HwSupported() { return !hwEncoderDisabledTypes.contains(H264_MIME_TYPE) - && (findHwEncoder(H264_MIME_TYPE, h264HwList, supportedColorList) != null); + && (findHwEncoder(H264_MIME_TYPE, h264HwList(), supportedColorList) != null); } public static boolean isH264HighProfileHwSupported() { @@ -297,7 +306,7 @@ public class MediaCodecVideoEncoder { public static boolean isH264HwSupportedUsingTextures() { return !hwEncoderDisabledTypes.contains(H264_MIME_TYPE) - && (findHwEncoder(H264_MIME_TYPE, h264HwList, supportedSurfaceColorList) != null); + && (findHwEncoder(H264_MIME_TYPE, h264HwList(), supportedSurfaceColorList) != null); } // Helper struct for findHwEncoder() below. @@ -464,8 +473,8 @@ public class MediaCodecVideoEncoder { keyFrameIntervalSec = 100; } else if (type == VideoCodecType.VIDEO_CODEC_H264) { mime = H264_MIME_TYPE; - properties = findHwEncoder( - H264_MIME_TYPE, h264HwList, useSurface ? supportedSurfaceColorList : supportedColorList); + properties = findHwEncoder(H264_MIME_TYPE, h264HwList(), + useSurface ? supportedSurfaceColorList : supportedColorList); if (profile == H264Profile.CONSTRAINED_HIGH.getValue()) { EncoderProperties h264HighProfileProperties = findHwEncoder(H264_MIME_TYPE, h264HighProfileHwList, useSurface ? supportedSurfaceColorList : supportedColorList);