• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2017 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 package org.webrtc;
12 
13 import android.annotation.TargetApi;
14 import android.media.MediaCodecInfo;
15 import android.media.MediaCodecInfo.CodecCapabilities;
16 import android.os.Build;
17 import androidx.annotation.Nullable;
18 import java.util.HashMap;
19 import java.util.Map;
20 
21 /** Container class for static constants and helpers used with MediaCodec. */
22 // We are forced to use the old API because we want to support API level < 21.
23 @SuppressWarnings("deprecation")
24 class MediaCodecUtils {
25   private static final String TAG = "MediaCodecUtils";
26 
27   // Prefixes for supported hardware encoder/decoder component names.
28   static final String EXYNOS_PREFIX = "OMX.Exynos.";
29   static final String INTEL_PREFIX = "OMX.Intel.";
30   static final String NVIDIA_PREFIX = "OMX.Nvidia.";
31   static final String QCOM_PREFIX = "OMX.qcom.";
32   static final String[] SOFTWARE_IMPLEMENTATION_PREFIXES = {
33       "OMX.google.", "OMX.SEC.", "c2.android"};
34 
35   // NV12 color format supported by QCOM codec, but not declared in MediaCodec -
36   // see /hardware/qcom/media/mm-core/inc/OMX_QCOMExtns.h
37   static final int COLOR_QCOM_FORMATYVU420PackedSemiPlanar32m4ka = 0x7FA30C01;
38   static final int COLOR_QCOM_FORMATYVU420PackedSemiPlanar16m4ka = 0x7FA30C02;
39   static final int COLOR_QCOM_FORMATYVU420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03;
40   static final int COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m = 0x7FA30C04;
41 
42   // Color formats supported by hardware decoder - in order of preference.
43   static final int[] DECODER_COLOR_FORMATS = new int[] {CodecCapabilities.COLOR_FormatYUV420Planar,
44       CodecCapabilities.COLOR_FormatYUV420SemiPlanar,
45       CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
46       MediaCodecUtils.COLOR_QCOM_FORMATYVU420PackedSemiPlanar32m4ka,
47       MediaCodecUtils.COLOR_QCOM_FORMATYVU420PackedSemiPlanar16m4ka,
48       MediaCodecUtils.COLOR_QCOM_FORMATYVU420PackedSemiPlanar64x32Tile2m8ka,
49       MediaCodecUtils.COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m};
50 
51   // Color formats supported by hardware encoder - in order of preference.
52   static final int[] ENCODER_COLOR_FORMATS = {
53       MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar,
54       MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar,
55       MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar,
56       MediaCodecUtils.COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m};
57 
58   // Color formats supported by texture mode encoding - in order of preference.
59   static final int[] TEXTURE_COLOR_FORMATS =
60       new int[] {MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface};
61 
selectColorFormat( int[] supportedColorFormats, CodecCapabilities capabilities)62   static @Nullable Integer selectColorFormat(
63       int[] supportedColorFormats, CodecCapabilities capabilities) {
64     for (int supportedColorFormat : supportedColorFormats) {
65       for (int codecColorFormat : capabilities.colorFormats) {
66         if (codecColorFormat == supportedColorFormat) {
67           return codecColorFormat;
68         }
69       }
70     }
71     return null;
72   }
73 
codecSupportsType(MediaCodecInfo info, VideoCodecMimeType type)74   static boolean codecSupportsType(MediaCodecInfo info, VideoCodecMimeType type) {
75     for (String mimeType : info.getSupportedTypes()) {
76       if (type.mimeType().equals(mimeType)) {
77         return true;
78       }
79     }
80     return false;
81   }
82 
getCodecProperties(VideoCodecMimeType type, boolean highProfile)83   static Map<String, String> getCodecProperties(VideoCodecMimeType type, boolean highProfile) {
84     switch (type) {
85       case VP8:
86       case VP9:
87       case AV1:
88         return new HashMap<String, String>();
89       case H264:
90         return H264Utils.getDefaultH264Params(highProfile);
91       default:
92         throw new IllegalArgumentException("Unsupported codec: " + type);
93     }
94   }
95 
isHardwareAccelerated(MediaCodecInfo info)96   static boolean isHardwareAccelerated(MediaCodecInfo info) {
97     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
98       return isHardwareAcceleratedQOrHigher(info);
99     }
100     return !isSoftwareOnly(info);
101   }
102 
103   @TargetApi(29)
isHardwareAcceleratedQOrHigher(android.media.MediaCodecInfo codecInfo)104   private static boolean isHardwareAcceleratedQOrHigher(android.media.MediaCodecInfo codecInfo) {
105     return codecInfo.isHardwareAccelerated();
106   }
107 
isSoftwareOnly(android.media.MediaCodecInfo codecInfo)108   static boolean isSoftwareOnly(android.media.MediaCodecInfo codecInfo) {
109     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
110       return isSoftwareOnlyQOrHigher(codecInfo);
111     }
112     String name = codecInfo.getName();
113     for (String prefix : SOFTWARE_IMPLEMENTATION_PREFIXES) {
114       if (name.startsWith(prefix)) {
115         return true;
116       }
117     }
118     return false;
119   }
120 
121   @TargetApi(29)
isSoftwareOnlyQOrHigher(android.media.MediaCodecInfo codecInfo)122   private static boolean isSoftwareOnlyQOrHigher(android.media.MediaCodecInfo codecInfo) {
123     return codecInfo.isSoftwareOnly();
124   }
125 
MediaCodecUtils()126   private MediaCodecUtils() {
127     // This class should not be instantiated.
128   }
129 }
130