• 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 android.support.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 = getTextureColorFormats();
60 
getTextureColorFormats()61   private static int[] getTextureColorFormats() {
62     if (Build.VERSION.SDK_INT >= 18) {
63       return new int[] {MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface};
64     } else {
65       return new int[] {};
66     }
67   }
68 
selectColorFormat( int[] supportedColorFormats, CodecCapabilities capabilities)69   static @Nullable Integer selectColorFormat(
70       int[] supportedColorFormats, CodecCapabilities capabilities) {
71     for (int supportedColorFormat : supportedColorFormats) {
72       for (int codecColorFormat : capabilities.colorFormats) {
73         if (codecColorFormat == supportedColorFormat) {
74           return codecColorFormat;
75         }
76       }
77     }
78     return null;
79   }
80 
codecSupportsType(MediaCodecInfo info, VideoCodecMimeType type)81   static boolean codecSupportsType(MediaCodecInfo info, VideoCodecMimeType type) {
82     for (String mimeType : info.getSupportedTypes()) {
83       if (type.mimeType().equals(mimeType)) {
84         return true;
85       }
86     }
87     return false;
88   }
89 
getCodecProperties(VideoCodecMimeType type, boolean highProfile)90   static Map<String, String> getCodecProperties(VideoCodecMimeType type, boolean highProfile) {
91     switch (type) {
92       case VP8:
93       case VP9:
94         return new HashMap<String, String>();
95       case H264:
96         return H264Utils.getDefaultH264Params(highProfile);
97       default:
98         throw new IllegalArgumentException("Unsupported codec: " + type);
99     }
100   }
101 
isHardwareAccelerated(MediaCodecInfo info)102   static boolean isHardwareAccelerated(MediaCodecInfo info) {
103     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
104       return isHardwareAcceleratedQOrHigher(info);
105     }
106     return !isSoftwareOnly(info);
107   }
108 
109   @TargetApi(29)
isHardwareAcceleratedQOrHigher(android.media.MediaCodecInfo codecInfo)110   private static boolean isHardwareAcceleratedQOrHigher(android.media.MediaCodecInfo codecInfo) {
111     return codecInfo.isHardwareAccelerated();
112   }
113 
isSoftwareOnly(android.media.MediaCodecInfo codecInfo)114   static boolean isSoftwareOnly(android.media.MediaCodecInfo codecInfo) {
115     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
116       return isSoftwareOnlyQOrHigher(codecInfo);
117     }
118     String name = codecInfo.getName();
119     for (String prefix : SOFTWARE_IMPLEMENTATION_PREFIXES) {
120       if (name.startsWith(prefix)) {
121         return true;
122       }
123     }
124     return false;
125   }
126 
127   @TargetApi(29)
isSoftwareOnlyQOrHigher(android.media.MediaCodecInfo codecInfo)128   private static boolean isSoftwareOnlyQOrHigher(android.media.MediaCodecInfo codecInfo) {
129     return codecInfo.isSoftwareOnly();
130   }
131 
MediaCodecUtils()132   private MediaCodecUtils() {
133     // This class should not be instantiated.
134   }
135 }
136