Java Code Examples for android.media.MediaCodecInfo#getSupportedTypes()

The following examples show how to use android.media.MediaCodecInfo#getSupportedTypes() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: H264EncodeConsumer.java    From AndroidUSBCamera with Apache License 2.0 6 votes vote down vote up
/**
 * select the first codec that match a specific MIME type
 *
 * @param mimeType
 * @return null if no codec matched
 */
@SuppressWarnings("deprecation")
protected final MediaCodecInfo selectVideoCodec(final String mimeType) {

    // get the list of available codecs
    final int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
        final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);

        if (!codecInfo.isEncoder()) {    // skipp decoder
            continue;
        }
        // select first codec that match a specific MIME type and color format
        final String[] types = codecInfo.getSupportedTypes();
        for (int j = 0; j < types.length; j++) {
            if (types[j].equalsIgnoreCase(mimeType)) {
                final int format = selectColorFormat(codecInfo, mimeType);
                if (format > 0) {
                    mColorFormat = format;
                    return codecInfo;
                }
            }
        }
    }
    return null;
}
 
Example 2
Source File: MediaCodecUtil.java    From 365browser with Apache License 2.0 6 votes vote down vote up
/**
  * Return an array of supported codecs and profiles.
  */
@CalledByNative
private static Object[] getSupportedCodecProfileLevels() {
    CodecProfileLevelList profileLevels = new CodecProfileLevelList();
    MediaCodecListHelper codecListHelper = new MediaCodecListHelper();
    for (MediaCodecInfo info : codecListHelper) {
        for (String mime : info.getSupportedTypes()) {
            // On versions L and M, VP9 codecCapabilities do not advertise profile level
            // support. In this case, estimate the level from MediaCodecInfo.VideoCapabilities
            // instead. Assume VP9 is not supported before L. For more information, consult
            // https://developer.android.com/reference/android/media/MediaCodecInfo.CodecProfileLevel.html
            CodecCapabilities codecCapabilities = info.getCapabilitiesForType(mime);
            if (mime.endsWith("vp9") && Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT
                    && Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
                addVp9CodecProfileLevels(profileLevels, codecCapabilities);
                continue;
            }
            for (CodecProfileLevel profileLevel : codecCapabilities.profileLevels) {
                profileLevels.addCodecProfileLevel(mime, profileLevel);
            }
        }
    }
    return profileLevels.toArray();
}
 
Example 3
Source File: SettingsActivity.java    From echo with GNU General Public License v3.0 6 votes vote down vote up
private void debugPrintCodecs() {
    final int codecCount = MediaCodecList.getCodecCount();
    for(int i = 0; i < codecCount; ++i) {
        final MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
        if(!info.isEncoder()) continue;
        boolean audioFound = false;
        String types = "";
        final String[] supportedTypes = info.getSupportedTypes();
        for(int j = 0; j < supportedTypes.length; ++j) {
            if(j > 0)
                types += ", ";
            types += supportedTypes[j];
            if(supportedTypes[j].startsWith("audio")) audioFound = true;
        }
        if(!audioFound) continue;
        Log.d(TAG, "Codec " + i + ": " + info.getName() + " (" + types + ") encoder: " + info.isEncoder());
    }
}
 
Example 4
Source File: MediaVideoEncoder.java    From MegviiFacepp-Android-SDK with Apache License 2.0 6 votes vote down vote up
/**
 * select the first codec that match a specific MIME type
 * @param mimeType
 * @return null if no codec matched
 */
protected static final MediaCodecInfo selectVideoCodec(final String mimeType) {
	if (DEBUG) Log.v(TAG, "selectVideoCodec:");

	// get the list of available codecs
    final int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
    	final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);

        if (!codecInfo.isEncoder()) {	// skipp decoder
            continue;
        }
        // select first codec that match a specific MIME type and color format
        final String[] types = codecInfo.getSupportedTypes();
        for (int j = 0; j < types.length; j++) {
            if (types[j].equalsIgnoreCase(mimeType)) {
            	if (DEBUG) Log.i(TAG, "codec:" + codecInfo.getName() + ",MIME=" + types[j]);
        		final int format = selectColorFormat(codecInfo, mimeType);
            	if (format > 0) {
            		return codecInfo;
            	}
            }
        }
    }
    return null;
}
 
Example 5
Source File: DecodeEditEncodeTest.java    From Android-MediaCodec-Examples with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the first codec capable of encoding the specified MIME type, or null if no
 * match was found.
 */
private static MediaCodecInfo selectCodec(String mimeType) {
    int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
        MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
        if (!codecInfo.isEncoder()) {
            continue;
        }
        String[] types = codecInfo.getSupportedTypes();
        for (int j = 0; j < types.length; j++) {
            if (types[j].equalsIgnoreCase(mimeType)) {
                return codecInfo;
            }
        }
    }
    return null;
}
 
Example 6
Source File: CameraUtil.java    From ssj with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Returns the first codec capable of encoding the specified MIME type, or null if no
 * match was found.
 *
 * @param mimeType String
 * @return MediaCodecInfo
 */
public static MediaCodecInfo selectCodec(String mimeType)
{
    int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++)
    {
        MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
        if (!codecInfo.isEncoder())
        {
            continue;
        }
        String[] types = codecInfo.getSupportedTypes();
        for (String type : types)
        {
            if (type.equalsIgnoreCase(mimeType))
            {
                return codecInfo;
            }
        }
    }
    return null;
}
 
Example 7
Source File: MediaAudioEncoder.java    From UVCCameraZxing with Apache License 2.0 6 votes vote down vote up
/**
     * select the first codec that match a specific MIME type
     * @param mimeType
     * @return
     */
    private static final MediaCodecInfo selectAudioCodec(final String mimeType) {
    	if (DEBUG) Log.v(TAG, "selectAudioCodec:");

    	MediaCodecInfo result = null;
    	// get the list of available codecs
        final int numCodecs = MediaCodecList.getCodecCount();
LOOP:	for (int i = 0; i < numCodecs; i++) {
        	final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
            if (!codecInfo.isEncoder()) {	// skipp decoder
                continue;
            }
            final String[] types = codecInfo.getSupportedTypes();
            for (int j = 0; j < types.length; j++) {
            	if (DEBUG) Log.i(TAG, "supportedType:" + codecInfo.getName() + ",MIME=" + types[j]);
                if (types[j].equalsIgnoreCase(mimeType)) {
                	if (result == null) {
                		result = codecInfo;
               			break LOOP;
                	}
                }
            }
        }
   		return result;
    }
 
Example 8
Source File: MediaCodecUtil.java    From 365browser with Apache License 2.0 6 votes vote down vote up
/**
 * Get a name of default android codec.
 * @param mime MIME type of the media.
 * @param direction Whether this is encoder or decoder.
 * @param requireSoftwareCodec Whether we require a software codec.
 * @return name of the codec.
 */
@CalledByNative
private static String getDefaultCodecName(
        String mime, int direction, boolean requireSoftwareCodec) {
    MediaCodecListHelper codecListHelper = new MediaCodecListHelper();
    for (MediaCodecInfo info : codecListHelper) {
        int codecDirection =
                info.isEncoder() ? MediaCodecDirection.ENCODER : MediaCodecDirection.DECODER;
        if (codecDirection != direction) continue;

        if (requireSoftwareCodec && !isSoftwareCodec(info.getName())) continue;

        for (String supportedType : info.getSupportedTypes()) {
            if (supportedType.equalsIgnoreCase(mime)) return info.getName();
        }
    }

    Log.e(TAG, "Decoder for type %s is not supported on this device", mime);
    return "";
}
 
Example 9
Source File: MediaAudioEncoder.java    From MegviiFacepp-Android-SDK with Apache License 2.0 6 votes vote down vote up
/**
     * select the first codec that match a specific MIME type
     * @param mimeType
     * @return
     */
    private static final MediaCodecInfo selectAudioCodec(final String mimeType) {
    	if (DEBUG) Log.v(TAG, "selectAudioCodec:");

    	MediaCodecInfo result = null;
    	// get the list of available codecs
        final int numCodecs = MediaCodecList.getCodecCount();
LOOP:	for (int i = 0; i < numCodecs; i++) {
        	final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
            if (!codecInfo.isEncoder()) {	// skipp decoder
                continue;
            }
            final String[] types = codecInfo.getSupportedTypes();
            for (int j = 0; j < types.length; j++) {
            	if (DEBUG) Log.i(TAG, "supportedType:" + codecInfo.getName() + ",MIME=" + types[j]);
                if (types[j].equalsIgnoreCase(mimeType)) {
                	if (result == null) {
                		result = codecInfo;
               			break LOOP;
                	}
                }
            }
        }
   		return result;
    }
 
Example 10
Source File: MediaVideoEncoder.java    From AudioVideoRecordingSample with Apache License 2.0 6 votes vote down vote up
/**
 * select the first codec that match a specific MIME type
 * @param mimeType
 * @return null if no codec matched
 */
protected static final MediaCodecInfo selectVideoCodec(final String mimeType) {
	if (DEBUG) Log.v(TAG, "selectVideoCodec:");

	// get the list of available codecs
    final int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
    	final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);

        if (!codecInfo.isEncoder()) {	// skipp decoder
            continue;
        }
        // select first codec that match a specific MIME type and color format
        final String[] types = codecInfo.getSupportedTypes();
        for (int j = 0; j < types.length; j++) {
            if (types[j].equalsIgnoreCase(mimeType)) {
            	if (DEBUG) Log.i(TAG, "codec:" + codecInfo.getName() + ",MIME=" + types[j]);
        		final int format = selectColorFormat(codecInfo, mimeType);
            	if (format > 0) {
            		return codecInfo;
            	}
            }
        }
    }
    return null;
}
 
Example 11
Source File: MediaUtils.java    From jellyfin-androidtv with GNU General Public License v2.0 5 votes vote down vote up
private static boolean hasCodecForMime(boolean encoder, String mime) {
    for (MediaCodecInfo info : sMCL.getCodecInfos()) {
        if (encoder != info.isEncoder()) {
            continue;
        }
        for (String type : info.getSupportedTypes()) {
            if (type.equalsIgnoreCase(mime)) {
                Timber.i("found codec %s for mime %s", info.getName(), mime);
                return true;
            }
        }
    }
    return false;
}
 
Example 12
Source File: AudioEncoder.java    From DeviceConnect-Android with MIT License 5 votes vote down vote up
/**
 * 指定された MediaCodecInfo のマイムタイプとカラーフォーマットが一致するか確認します.
 *
 * @param codecInfo 確認する MediaCodecInfo
 * @param mimeType マイムタイプ
 * @return 一致する場合はtrue、それ以外はfalse
 */
private boolean isMediaCodecInfo(MediaCodecInfo codecInfo, String mimeType) {
    if (!codecInfo.isEncoder()) {
        return false;
    }

    String[] types = codecInfo.getSupportedTypes();
    for (String type : types) {
        if (type.equalsIgnoreCase(mimeType)) {
            return true;
        }
    }

    return false;
}
 
Example 13
Source File: MediaCodecUtil.java    From 365browser with Apache License 2.0 5 votes vote down vote up
/**
 * Find HW encoder with given MIME type.
 * @param mime MIME type of the media.
 * @return HWEncoderProperties object.
 */
private static HWEncoderProperties findHWEncoder(String mime) {
    MediaCodecListHelper codecListHelper = new MediaCodecListHelper();
    for (MediaCodecInfo info : codecListHelper) {
        if (!info.isEncoder() || isSoftwareCodec(info.getName())) continue;

        String encoderName = null;
        for (String mimeType : info.getSupportedTypes()) {
            if (mimeType.equalsIgnoreCase(mime)) {
                encoderName = info.getName();
                break;
            }
        }

        if (encoderName == null) {
            continue; // No HW support in this codec; try the next one.
        }

        // Check if this is supported HW encoder.
        for (HWEncoderProperties codecProperties : HWEncoderProperties.values()) {
            if (!mime.equalsIgnoreCase(codecProperties.getMime())) continue;

            if (encoderName.startsWith(codecProperties.getPrefix())) {
                if (Build.VERSION.SDK_INT < codecProperties.getMinSDK()) {
                    Log.w(TAG, "Codec " + encoderName + " is disabled due to SDK version "
                                    + Build.VERSION.SDK_INT);
                    continue;
                }
                Log.d(TAG, "Found target encoder for mime " + mime + " : " + encoderName);
                return codecProperties;
            }
        }
    }

    Log.w(TAG, "HW encoder for " + mime + " is not available on this device.");
    return null;
}
 
Example 14
Source File: VideoEncoder.java    From TikTok with Apache License 2.0 5 votes vote down vote up
static public int getSupportColorFormat() {

        int numCodecs = MediaCodecList.getCodecCount();
        MediaCodecInfo codecInfo = null;
        for (int i = 0; i < numCodecs && codecInfo == null; i++) {
            MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
            if (!info.isEncoder()) {
                continue;
            }
            String[] types = info.getSupportedTypes();
            boolean found = false;
            for (int j = 0; j < types.length && !found; j++) {
                if (types[j].equals("video/avc")) {
                    found = true;
                }
            }
            if (!found)
                continue;
            codecInfo = info;
        }

        // Find a color profile that the codec supports
        MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType("video/avc");

        for (int i = 0; i < capabilities.colorFormats.length; i++) {
            Log.e(TAG,"format="+capabilities.colorFormats[i]);
            switch (capabilities.colorFormats[i]) {
                case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
                case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
                    Log.e(TAG, "supported color format " + capabilities.colorFormats[i]);
                    return capabilities.colorFormats[i];
                default:
                    Log.e(TAG, "unsupported color format " + capabilities.colorFormats[i]);
                    break;
            }
        }

        return -1;
    }
 
Example 15
Source File: MediaCodecHelper.java    From libcommon with Apache License 2.0 5 votes vote down vote up
/**
	 * 指定したMIMEに一致する最初の音声エンコード用コーデックを選択する
	 * 対応するものがなければnullを返す
	 * @param mimeType
	 * @return
	 */
	@Deprecated
	@Nullable
	public static final MediaCodecInfo selectAudioEncoder(final String mimeType) {
//    	if (DEBUG) Log.v(TAG, "selectAudioCodec:");

 		MediaCodecInfo result = null;
 		// コーデックの一覧を取得
		//noinspection deprecation
		final int numCodecs = getCodecCount();
LOOP:	for (int i = 0; i < numCodecs; i++) {
			//noinspection deprecation
	     	final MediaCodecInfo codecInfo = getCodecInfoAt(i);
			if (!codecInfo.isEncoder()) {	// エンコーダーでない(=デコーダー)はスキップする
				continue;
			}
			final String[] types = codecInfo.getSupportedTypes();
			for (int j = 0; j < types.length; j++) {
//				if (DEBUG) Log.i(TAG, "supportedType:" + codecInfo.getName() + ",MIME=" + types[j]);
				if (types[j].equalsIgnoreCase(mimeType)) {
					result = codecInfo;
					break LOOP;
				}
			}
		}
		return result;
	}
 
Example 16
Source File: MediaAudioEncoder.java    From VideoRecorder with Apache License 2.0 5 votes vote down vote up
/**
 * select the first codec that match a specific MIME type
 *
 * @param mimeType
 * @return
 */
private static final MediaCodecInfo selectAudioCodec(final String mimeType) {
    if (DEBUG) Log.v(TAG, "selectAudioCodec:");

    MediaCodecInfo result = null;
    // get the list of available codecs
    final int numCodecs = MediaCodecList.getCodecCount();
    LOOP:
    for (int i = 0; i < numCodecs; i++) {
        final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
        if (!codecInfo.isEncoder()) {    // skipp decoder
            continue;
        }
        final String[] types = codecInfo.getSupportedTypes();
        for (int j = 0; j < types.length; j++) {
            if (DEBUG)
                LogUtil.loge(TAG, "supportedType:" + codecInfo.getName() + ",MIME=" + types[j]);
            if (types[j].equalsIgnoreCase(mimeType)) {
                if (result == null) {
                    result = codecInfo;
                    break LOOP;
                }
            }
        }
    }
    return result;
}
 
Example 17
Source File: HeifReader.java    From heifreader with MIT License 5 votes vote down vote up
/**
 * Initialize HeifReader module.
 *
 * @param context Context.
 */
public static void initialize(Context context) {
    mRenderScript = RenderScript.create(context);
    mCacheDir = context.getCacheDir();

    // find best HEVC decoder
    mDecoderName = null;
    mDecoderSupportedSize = new Size(0, 0);
    int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
        MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
        if (codecInfo.isEncoder()) {
            continue;
        }
        for (String type : codecInfo.getSupportedTypes()) {
            if (type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
                MediaCodecInfo.CodecCapabilities cap = codecInfo.getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_HEVC);
                MediaCodecInfo.VideoCapabilities vcap = cap.getVideoCapabilities();
                Size supportedSize = new Size(vcap.getSupportedWidths().getUpper(), vcap.getSupportedHeights().getUpper());
                Log.d(TAG, "HEVC decoder=\"" + codecInfo.getName() + "\""
                        + " supported-size=" + supportedSize
                        + " color-formats=" + Arrays.toString(cap.colorFormats)
                );
                if (mDecoderSupportedSize.getWidth() * mDecoderSupportedSize.getHeight() < supportedSize.getWidth() * supportedSize.getHeight()) {
                    mDecoderName = codecInfo.getName();
                    mDecoderSupportedSize = supportedSize;
                }
            }
        }
    }
    if (mDecoderName == null) {
        throw new RuntimeException("no HEVC decoding support");
    }
    Log.i(TAG, "HEVC decoder=\"" + mDecoderName + "\" supported-size=" + mDecoderSupportedSize);
}
 
Example 18
Source File: MediaCodecVideoEncoder.java    From droidkit-webrtc with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
private static EncoderProperties findVp8HwEncoder() {
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
    return null; // MediaCodec.setParameters is missing.

  for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
    MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
    if (!info.isEncoder()) {
      continue;
    }
    String name = null;
    for (String mimeType : info.getSupportedTypes()) {
      if (mimeType.equals(VP8_MIME_TYPE)) {
        name = info.getName();
        break;
      }
    }
    if (name == null) {
      continue;  // No VP8 support in this codec; try the next one.
    }
    Log.d(TAG, "Found candidate encoder " + name);
    CodecCapabilities capabilities =
        info.getCapabilitiesForType(VP8_MIME_TYPE);
    for (int colorFormat : capabilities.colorFormats) {
      Log.d(TAG, "   Color: 0x" + Integer.toHexString(colorFormat));
    }

    // Check if this is supported HW encoder
    for (String hwCodecPrefix : supportedHwCodecPrefixes) {
      if (!name.startsWith(hwCodecPrefix)) {
        continue;
      }
      // Check if codec supports either yuv420 or nv12
      for (int supportedColorFormat : supportedColorList) {
        for (int codecColorFormat : capabilities.colorFormats) {
          if (codecColorFormat == supportedColorFormat) {
            // Found supported HW VP8 encoder
            Log.d(TAG, "Found target encoder " + name +
                ". Color: 0x" + Integer.toHexString(codecColorFormat));
            return new EncoderProperties(name, codecColorFormat);
          }
        }
      }
    }
  }
  return null;  // No HW VP8 encoder.
}
 
Example 19
Source File: IjkMediaPlayer.java    From DanDanPlayForAndroid with MIT License 4 votes vote down vote up
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public String onMediaCodecSelect(IMediaPlayer mp, String mimeType, int profile, int level) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
        return null;

    if (TextUtils.isEmpty(mimeType))
        return null;

    Log.i(TAG, String.format(Locale.US, "onSelectCodec: mime=%s, profile=%d, level=%d", mimeType, profile, level));
    ArrayList<IjkMediaCodecInfo> candidateCodecList = new ArrayList<IjkMediaCodecInfo>();
    int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
        MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
        Log.d(TAG, String.format(Locale.US, "  found codec: %s", codecInfo.getName()));
        if (codecInfo.isEncoder())
            continue;

        String[] types = codecInfo.getSupportedTypes();
        if (types == null)
            continue;

        for(String type: types) {
            if (TextUtils.isEmpty(type))
                continue;

            Log.d(TAG, String.format(Locale.US, "    mime: %s", type));
            if (!type.equalsIgnoreCase(mimeType))
                continue;

            IjkMediaCodecInfo candidate = IjkMediaCodecInfo.setupCandidate(codecInfo, mimeType);
            if (candidate == null)
                continue;

            candidateCodecList.add(candidate);
            Log.i(TAG, String.format(Locale.US, "candidate codec: %s rank=%d", codecInfo.getName(), candidate.mRank));
            candidate.dumpProfileLevels(mimeType);
        }
    }

    if (candidateCodecList.isEmpty()) {
        return null;
    }

    IjkMediaCodecInfo bestCodec = candidateCodecList.get(0);

    for (IjkMediaCodecInfo codec : candidateCodecList) {
        if (codec.mRank > bestCodec.mRank) {
            bestCodec = codec;
        }
    }

    if (bestCodec.mRank < IjkMediaCodecInfo.RANK_LAST_CHANCE) {
        Log.w(TAG, String.format(Locale.US, "unaccetable codec: %s", bestCodec.mCodecInfo.getName()));
        return null;
    }

    Log.i(TAG, String.format(Locale.US, "selected codec: %s rank=%d", bestCodec.mCodecInfo.getName(), bestCodec.mRank));
    return bestCodec.mCodecInfo.getName();
}
 
Example 20
Source File: IjkMediaPlayer.java    From MKVideoPlayer with MIT License 4 votes vote down vote up
@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public String onMediaCodecSelect(IMediaPlayer mp, String mimeType, int profile, int level) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
        return null;

    if (TextUtils.isEmpty(mimeType))
        return null;

    Log.i(TAG, String.format(Locale.US, "onSelectCodec: mime=%s, profile=%d, level=%d", mimeType, profile, level));
    ArrayList<IjkMediaCodecInfo> candidateCodecList = new ArrayList<IjkMediaCodecInfo>();
    int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
        MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
        Log.d(TAG, String.format(Locale.US, "  found codec: %s", codecInfo.getName()));
        if (codecInfo.isEncoder())
            continue;

        String[] types = codecInfo.getSupportedTypes();
        if (types == null)
            continue;

        for(String type: types) {
            if (TextUtils.isEmpty(type))
                continue;

            Log.d(TAG, String.format(Locale.US, "    mime: %s", type));
            if (!type.equalsIgnoreCase(mimeType))
                continue;

            IjkMediaCodecInfo candidate = IjkMediaCodecInfo.setupCandidate(codecInfo, mimeType);
            if (candidate == null)
                continue;

            candidateCodecList.add(candidate);
            Log.i(TAG, String.format(Locale.US, "candidate codec: %s rank=%d", codecInfo.getName(), candidate.mRank));
            candidate.dumpProfileLevels(mimeType);
        }
    }

    if (candidateCodecList.isEmpty()) {
        return null;
    }

    IjkMediaCodecInfo bestCodec = candidateCodecList.get(0);

    for (IjkMediaCodecInfo codec : candidateCodecList) {
        if (codec.mRank > bestCodec.mRank) {
            bestCodec = codec;
        }
    }

    if (bestCodec.mRank < IjkMediaCodecInfo.RANK_LAST_CHANCE) {
        Log.w(TAG, String.format(Locale.US, "unaccetable codec: %s", bestCodec.mCodecInfo.getName()));
        return null;
    }

    Log.i(TAG, String.format(Locale.US, "selected codec: %s rank=%d", bestCodec.mCodecInfo.getName(), bestCodec.mRank));
    return bestCodec.mCodecInfo.getName();
}