123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- package tv.danmaku.ijk.media.player;
- import android.annotation.TargetApi;
- import android.media.MediaCodecInfo;
- import android.media.MediaCodecInfo.CodecCapabilities;
- import android.media.MediaCodecInfo.CodecProfileLevel;
- import android.os.Build;
- import android.text.TextUtils;
- import android.util.Log;
- import java.util.Locale;
- import java.util.Map;
- import java.util.TreeMap;
- public class IjkMediaCodecInfo {
- private final static String TAG = "IjkMediaCodecInfo";
- public static final int RANK_MAX = 1000;
- public static final int RANK_TESTED = 800;
- public static final int RANK_ACCEPTABLE = 700;
- public static final int RANK_LAST_CHANCE = 600;
- public static final int RANK_SECURE = 300;
- public static final int RANK_SOFTWARE = 200;
- public static final int RANK_NON_STANDARD = 100;
- public static final int RANK_NO_SENSE = 0;
- public MediaCodecInfo mCodecInfo;
- public int mRank = 0;
- public String mMimeType;
- private static Map<String, Integer> sKnownCodecList;
- private static synchronized Map<String, Integer> getKnownCodecList() {
- if (sKnownCodecList != null)
- return sKnownCodecList;
- sKnownCodecList = new TreeMap<String, Integer>(
- String.CASE_INSENSITIVE_ORDER);
- // ----- Nvidia -----
- // Tegra3
- // Nexus 7 (2012)
- // Tegra K1
- // Nexus 9
- sKnownCodecList.put("OMX.Nvidia.h264.decode", RANK_TESTED);
- sKnownCodecList.put("OMX.Nvidia.h264.decode.secure", RANK_SECURE);
- // ----- Intel -----
- // Atom Z3735
- // Teclast X98 Air
- sKnownCodecList.put("OMX.Intel.hw_vd.h264", RANK_TESTED + 1);
- // Atom Z2560
- // Dell Venue 7 3730
- sKnownCodecList.put("OMX.Intel.VideoDecoder.AVC", RANK_TESTED);
- // ----- Qualcomm -----
- // MSM8260
- // Xiaomi MI 1S
- sKnownCodecList.put("OMX.qcom.video.decoder.avc", RANK_TESTED);
- sKnownCodecList.put("OMX.ittiam.video.decoder.avc", RANK_NO_SENSE);
- // ----- Samsung -----
- // Exynos 3110
- // Nexus S
- sKnownCodecList.put("OMX.SEC.avc.dec", RANK_TESTED);
- sKnownCodecList.put("OMX.SEC.AVC.Decoder", RANK_TESTED - 1);
- // OMX.SEC.avcdec doesn't reorder output pictures on GT-9100
- sKnownCodecList.put("OMX.SEC.avcdec", RANK_TESTED - 2);
- sKnownCodecList.put("OMX.SEC.avc.sw.dec", RANK_SOFTWARE);
- // Exynos 5 ?
- sKnownCodecList.put("OMX.Exynos.avc.dec", RANK_TESTED);
- sKnownCodecList.put("OMX.Exynos.AVC.Decoder", RANK_TESTED - 1);
- // ------ Huawei hisilicon ------
- // Kirin 910, Mali 450 MP
- // Huawei HONOR 3C (H30-L01)
- sKnownCodecList.put("OMX.k3.video.decoder.avc", RANK_TESTED);
- // Kirin 920, Mali T624
- // Huawei HONOR 6
- sKnownCodecList.put("OMX.IMG.MSVDX.Decoder.AVC", RANK_TESTED);
- // ----- TI -----
- // TI OMAP4460
- // Galaxy Nexus
- sKnownCodecList.put("OMX.TI.DUCATI1.VIDEO.DECODER", RANK_TESTED);
- // ------ RockChip ------
- // Youku TVBox
- sKnownCodecList.put("OMX.rk.video_decoder.avc", RANK_TESTED);
- // ------ AMLogic -----
- // MiBox1, 1s, 2
- sKnownCodecList.put("OMX.amlogic.avc.decoder.awesome", RANK_TESTED);
- // ------ Marvell ------
- // Lenovo A788t
- sKnownCodecList.put("OMX.MARVELL.VIDEO.HW.CODA7542DECODER", RANK_TESTED);
- sKnownCodecList.put("OMX.MARVELL.VIDEO.H264DECODER", RANK_SOFTWARE);
- // ----- TODO: need test -----
- sKnownCodecList.remove("OMX.Action.Video.Decoder");
- sKnownCodecList.remove("OMX.allwinner.video.decoder.avc");
- sKnownCodecList.remove("OMX.BRCM.vc4.decoder.avc");
- sKnownCodecList.remove("OMX.brcm.video.h264.hw.decoder");
- sKnownCodecList.remove("OMX.brcm.video.h264.decoder");
- sKnownCodecList.remove("OMX.cosmo.video.decoder.avc");
- sKnownCodecList.remove("OMX.duos.h264.decoder");
- sKnownCodecList.remove("OMX.hantro.81x0.video.decoder");
- sKnownCodecList.remove("OMX.hantro.G1.video.decoder");
- sKnownCodecList.remove("OMX.hisi.video.decoder");
- sKnownCodecList.remove("OMX.LG.decoder.video.avc");
- sKnownCodecList.remove("OMX.MS.AVC.Decoder");
- sKnownCodecList.remove("OMX.RENESAS.VIDEO.DECODER.H264");
- sKnownCodecList.remove("OMX.RTK.video.decoder");
- sKnownCodecList.remove("OMX.sprd.h264.decoder");
- sKnownCodecList.remove("OMX.ST.VFM.H264Dec");
- sKnownCodecList.remove("OMX.vpu.video_decoder.avc");
- sKnownCodecList.remove("OMX.WMT.decoder.avc");
- // Really ?
- sKnownCodecList.remove("OMX.bluestacks.hw.decoder");
- // ---------------
- // Useless codec
- // ----- google -----
- sKnownCodecList.put("OMX.google.h264.decoder", RANK_SOFTWARE);
- sKnownCodecList.put("OMX.google.h264.lc.decoder", RANK_SOFTWARE);
- // ----- huawei k920 -----
- sKnownCodecList.put("OMX.k3.ffmpeg.decoder", RANK_SOFTWARE);
- sKnownCodecList.put("OMX.ffmpeg.video.decoder", RANK_SOFTWARE);
- // ----- unknown -----
- sKnownCodecList.put("OMX.sprd.soft.h264.decoder", RANK_SOFTWARE);
- return sKnownCodecList;
- }
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- public static IjkMediaCodecInfo setupCandidate(MediaCodecInfo codecInfo,
- String mimeType) {
- if (codecInfo == null
- || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
- return null;
- String name = codecInfo.getName();
- if (TextUtils.isEmpty(name))
- return null;
- name = name.toLowerCase(Locale.US);
- int rank = RANK_NO_SENSE;
- if (!name.startsWith("omx.")) {
- rank = RANK_NON_STANDARD;
- } else if (name.startsWith("omx.pv")) {
- rank = RANK_SOFTWARE;
- } else if (name.startsWith("omx.google.")) {
- rank = RANK_SOFTWARE;
- } else if (name.startsWith("omx.ffmpeg.")) {
- rank = RANK_SOFTWARE;
- } else if (name.startsWith("omx.k3.ffmpeg.")) {
- rank = RANK_SOFTWARE;
- } else if (name.startsWith("omx.avcodec.")) {
- rank = RANK_SOFTWARE;
- } else if (name.startsWith("omx.ittiam.")) {
- // unknown codec in qualcomm SoC
- rank = RANK_NO_SENSE;
- } else if (name.startsWith("omx.mtk.")) {
- // 1. MTK only works on 4.3 and above
- // 2. MTK works on MIUI 6 (4.2.1)
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2)
- rank = RANK_NO_SENSE;
- else
- rank = RANK_TESTED;
- } else {
- Integer knownRank = getKnownCodecList().get(name);
- if (knownRank != null) {
- rank = knownRank;
- } else {
- try {
- CodecCapabilities cap = codecInfo
- .getCapabilitiesForType(mimeType);
- if (cap != null)
- rank = RANK_ACCEPTABLE;
- else
- rank = RANK_LAST_CHANCE;
- } catch (Throwable e) {
- rank = RANK_LAST_CHANCE;
- }
- }
- }
- IjkMediaCodecInfo candidate = new IjkMediaCodecInfo();
- candidate.mCodecInfo = codecInfo;
- candidate.mRank = rank;
- candidate.mMimeType = mimeType;
- return candidate;
- }
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- public void dumpProfileLevels(String mimeType) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
- return;
- try {
- CodecCapabilities caps = mCodecInfo
- .getCapabilitiesForType(mimeType);
- int maxProfile = 0;
- int maxLevel = 0;
- if (caps != null) {
- if (caps.profileLevels != null) {
- for (CodecProfileLevel profileLevel : caps.profileLevels) {
- if (profileLevel == null)
- continue;
- maxProfile = Math.max(maxProfile, profileLevel.profile);
- maxLevel = Math.max(maxLevel, profileLevel.level);
- }
- }
- }
- Log.i(TAG,
- String.format(Locale.US, "%s",
- getProfileLevelName(maxProfile, maxLevel)));
- } catch (Throwable e) {
- Log.i(TAG, "profile-level: exception");
- }
- }
- public static String getProfileLevelName(int profile, int level) {
- return String.format(Locale.US, " %s Profile Level %s (%d,%d)",
- getProfileName(profile), getLevelName(level), profile, level);
- }
- public static String getProfileName(int profile) {
- switch (profile) {
- case CodecProfileLevel.AVCProfileBaseline:
- return "Baseline";
- case CodecProfileLevel.AVCProfileMain:
- return "Main";
- case CodecProfileLevel.AVCProfileExtended:
- return "Extends";
- case CodecProfileLevel.AVCProfileHigh:
- return "High";
- case CodecProfileLevel.AVCProfileHigh10:
- return "High10";
- case CodecProfileLevel.AVCProfileHigh422:
- return "High422";
- case CodecProfileLevel.AVCProfileHigh444:
- return "High444";
- default:
- return "Unknown";
- }
- }
- public static String getLevelName(int level) {
- switch (level) {
- case CodecProfileLevel.AVCLevel1:
- return "1";
- case CodecProfileLevel.AVCLevel1b:
- return "1b";
- case CodecProfileLevel.AVCLevel11:
- return "11";
- case CodecProfileLevel.AVCLevel12:
- return "12";
- case CodecProfileLevel.AVCLevel13:
- return "13";
- case CodecProfileLevel.AVCLevel2:
- return "2";
- case CodecProfileLevel.AVCLevel21:
- return "21";
- case CodecProfileLevel.AVCLevel22:
- return "22";
- case CodecProfileLevel.AVCLevel3:
- return "3";
- case CodecProfileLevel.AVCLevel31:
- return "31";
- case CodecProfileLevel.AVCLevel32:
- return "32";
- case CodecProfileLevel.AVCLevel4:
- return "4";
- case CodecProfileLevel.AVCLevel41:
- return "41";
- case CodecProfileLevel.AVCLevel42:
- return "42";
- case CodecProfileLevel.AVCLevel5:
- return "5";
- case CodecProfileLevel.AVCLevel51:
- return "51";
- case 65536: // CodecProfileLevel.AVCLevel52:
- return "52";
- default:
- return "0";
- }
- }
- }
|