(MediaCodecVideoDecoder.java)findDecoder

 

@mime:对h264,对应值是video/avc。
@supportedCodecPrefixes。查找四条件之三的名称前缀。找到的解码器name必须以该数组之一为前缀。

private static DecoderProperties findDecoder(String mime, String[] supportedCodecPrefixes) {
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
    return null; // MediaCodec.setParameters is missing.
  }
  Logging.d(TAG, "Trying to find HW decoder for mime " + mime);
  for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
    MediaCodecInfo info = null;
    try {
      info = MediaCodecList.getCodecInfoAt(i);
    } catch (IllegalArgumentException e) {
      Logging.e(TAG, "Cannot retrieve decoder codec info", e);
    }
    // 查找四条件之二:info的isEncoder必须是false。
    if (info == null || info.isEncoder()) {
      continue;
    }
    String name = null;
    // 查找四条件之一:mime必须一致。
    for (String mimeType : info.getSupportedTypes()) {
      if (mimeType.equals(mime)) {
        name = info.getName();
        break;
      }
    }
    if (name == null) {
      continue; // No HW support in this codec; try the next one.
    }
    Logging.d(TAG, "Found candidate decoder " + name);
    // 查找四条件之三:name必须以supportedCodecPrefixes数组之一为前缀。
    // Check if this is supported decoder.
    boolean supportedCodec = false;
    for (String codecPrefix : supportedCodecPrefixes) {
      if (name.startsWith(codecPrefix)) {
        supportedCodec = true;
        break;
      }
    }
    if (!supportedCodec) {
      continue;
    }
    // Check if codec supports either yuv420 or nv12.
    CodecCapabilities capabilities;
    try {
      capabilities = info.getCapabilitiesForType(mime);
    } catch (IllegalArgumentException e) {
      Logging.e(TAG, "Cannot retrieve decoder capabilities", e);
      continue;
    }
    for (int colorFormat : capabilities.colorFormats) {
      Logging.v(TAG, "   Color: 0x" + Integer.toHexString(colorFormat));
    }
    // 查找四条件之四:支持的颜色格式和supportedColorList必须有交集。
    for (int supportedColorFormat : supportedColorList) {
      for (int codecColorFormat : capabilities.colorFormats) {
        if (codecColorFormat == supportedColorFormat) {
          // Found supported HW decoder.
          Logging.d(TAG, "Found target decoder " + name + ". Color: 0x"
                  + Integer.toHexString(codecColorFormat));
          return new DecoderProperties(name, codecColorFormat);
        }
      }
    }
  }
  Logging.d(TAG, "No HW decoder found for mime " + mime);
  return null; // No HW decoder.
}

要理解此函数,像参数mime有什么值,以及接下的MediaCodecList.getCodecCount/getCodecInfoAt、MediaCodecInfo,强烈建议先去看“kOS(6):MediaCodec”中的“1.1 MediaCodec”。

findDecoder用于查找系统中能解码mime格式的HW解码器。Andorid用一个MediaCodecInfo结构表示一个编/解码器,该MediaCodecInfo除mime要满足一致外,还有其它三个条件。

  1. mime。该MediaCodecInfo.mime必须等于参数mime。
  2. isEncoder。必须是false,表示这是一个解码器。true表示该MediaCodecInfo是个编码器。
  3. name。name字符串必须以supportedCodecPrefixes(一个数组)中的某个字符串开始。每种mime有不一样的supportedCodecPrefixes,因而它作为参数传给findDecoder。
  4. colorFormats。支持的颜色格式和supportedColorList(一个数组)有交集。所有mime有着一样的supportedColorList。

要注解这个函数,一个很重要原因是为支持更多Android设备,你需要修改一处webrtc源码,具体是:supportedCodecPrefixes。对h264,对应的是supportedH264HwCodecPrefixes。

private static final String[] supportedH264HwCodecPrefixes = {
      "OMX.qcom.", "OMX.Intel.", "OMX.Exynos."};

以上是官方webrtc给出的值。但是,市面上一些Android设备不在当中,以下是个人认为至少要加上两种后的版本。

private static final String[] supportedH264HwCodecPrefixes = {
      "OMX.qcom.", "OMX.Intel.", "OMX.Exynos.", "OMX.rk.", "OMX.hisi."};
  • OMX.rk.:rk3288/rk3399主板,像Firefly的RK系列。
  • OMX.hisi.:华为手机、PAD。

类似原因,要支持市面更多android设备,需修改MediaCodecVideoEecoder.java中的MediaCodecProperties。

private static final MediaCodecProperties rkH264HwProperties = new MediaCodecProperties(
        "OMX.rk.", Build.VERSION_CODES.LOLLIPOP, BitrateAdjustmentType.FRAMERATE_ADJUSTMENT);
private static final MediaCodecProperties hisiH264HwProperties = new MediaCodecProperties(
        "OMX.hisi.", Build.VERSION_CODES.LOLLIPOP, BitrateAdjustmentType.FRAMERATE_ADJUSTMENT);
private static final MediaCodecProperties[] h264HwList =
    new MediaCodecProperties[] {qcomH264HwProperties, exynosH264HwProperties, rkH264HwProperties, hisiH264HwProperties};

全部评论: 0

    写评论: