public static CodecInfo getCodecInfo(MediaCodecInfo codecInfo) {
   String[] types = codecInfo.getSupportedTypes();
   for (String type : types) {
     try {
       if (type.equals(MEDIA_CODEC_TYPE_H263)) return new H263CodecInfo(codecInfo);
       else if (type.equals(MEDIA_CODEC_TYPE_H264)) return new H264CodecInfo(codecInfo);
       else if (type.equals(MEDIA_CODEC_TYPE_VP8)) return new VP8CodecInfo(codecInfo);
     } catch (IllegalArgumentException e) {
       logger.error(
           "Error initializing codec info: " + codecInfo.getName() + ", type: " + type, e);
     }
   }
   return null;
 }
  /**
   * Creates new instance of <tt>CodecInfo</tt> that will encapsulate given <tt>codecInfo</tt>.
   *
   * @param codecInfo the codec info object to encapsulate.
   * @param mediaType media type of the codec
   */
  public CodecInfo(MediaCodecInfo codecInfo, String mediaType) {
    this.codecInfo = codecInfo;
    this.mediaType = mediaType;
    this.caps = codecInfo.getCapabilitiesForType(mediaType);

    this.colors = new ArrayList<CodecColorFormat>();
    int[] colorFormats = caps.colorFormats;
    for (int colorFormat : colorFormats) {
      colors.add(CodecColorFormat.fromInt(colorFormat));
    }
  }
  static {
    bannedYuvCodecs = new ArrayList<String>();

    // Banned H264 encoders/decoders
    // Crashes
    bannedYuvCodecs.add("OMX.SEC.avc.enc");
    bannedYuvCodecs.add("OMX.SEC.h263.enc");
    // Don't support 3.1 profile used by Jitsi
    bannedYuvCodecs.add("OMX.Nvidia.h264.decode");
    // bannedYuvCodecs.add("OMX.SEC.avc.dec");

    // Banned VP8 encoders/decoders
    bannedYuvCodecs.add("OMX.SEC.vp8.dec");
    // This one works only for res 176x144
    bannedYuvCodecs.add("OMX.google.vpx.encoder");

    for (int codecIndex = 0, codecCount = MediaCodecList.getCodecCount();
        codecIndex < codecCount;
        codecIndex++) {
      MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(codecIndex);
      logger.info(
          "Discovered codec: "
              + codecInfo.getName()
              + "/"
              + Arrays.toString(codecInfo.getSupportedTypes()));
      CodecInfo ci = CodecInfo.getCodecInfo(codecInfo);
      if (ci != null) {
        codecs.add(ci);
        ci.setBanned(bannedYuvCodecs.contains(ci.getName()));
      }
    }
    logger.info("Selected H264 encoder: " + getCodecForType(MEDIA_CODEC_TYPE_H264, true));
    logger.info("Selected H264 decoder: " + getCodecForType(MEDIA_CODEC_TYPE_H264, false));
    logger.info("Selected H263 encoder: " + getCodecForType(MEDIA_CODEC_TYPE_H263, true));
    logger.info("Selected H263 decoder: " + getCodecForType(MEDIA_CODEC_TYPE_H263, false));
    logger.info("Selected VP8 encoder: " + getCodecForType(MEDIA_CODEC_TYPE_VP8, true));
    logger.info("Selected VP8 decoder: " + getCodecForType(MEDIA_CODEC_TYPE_VP8, false));
  }
  @Override
  public String toString() {
    StringBuilder colorStr = new StringBuilder("\ncolors:\n");
    for (int i = 0; i < colors.size(); i++) {
      colorStr.append(colors.get(i));
      if (i != colors.size() - 1) colorStr.append(", \n");
    }

    StringBuilder plStr = new StringBuilder("\nprofiles:\n");
    ProfileLevel[] profiles = getProfileLevels();
    for (int i = 0; i < profiles.length; i++) {
      plStr.append(profiles[i].toString());
      if (i != profiles.length - 1) plStr.append(", \n");
    }

    return codecInfo.getName() + "(" + getLibjitsiEncoding() + ")" + colorStr + plStr;
  }
 public boolean isEncoder() {
   return codecInfo.isEncoder();
 }
 /**
  * Returns codec name that can be used to obtain <tt>MediaCodec</tt>.
  *
  * @return codec name that can be used to obtain <tt>MediaCodec</tt>.
  */
 public String getName() {
   return codecInfo.getName();
 }