IjkMediaCodecInfo.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. package tv.danmaku.ijk.media.player;
  2. import android.annotation.TargetApi;
  3. import android.media.MediaCodecInfo;
  4. import android.media.MediaCodecInfo.CodecCapabilities;
  5. import android.media.MediaCodecInfo.CodecProfileLevel;
  6. import android.os.Build;
  7. import android.text.TextUtils;
  8. import android.util.Log;
  9. import java.util.Locale;
  10. import java.util.Map;
  11. import java.util.TreeMap;
  12. public class IjkMediaCodecInfo {
  13. private final static String TAG = "IjkMediaCodecInfo";
  14. public static final int RANK_MAX = 1000;
  15. public static final int RANK_TESTED = 800;
  16. public static final int RANK_ACCEPTABLE = 700;
  17. public static final int RANK_LAST_CHANCE = 600;
  18. public static final int RANK_SECURE = 300;
  19. public static final int RANK_SOFTWARE = 200;
  20. public static final int RANK_NON_STANDARD = 100;
  21. public static final int RANK_NO_SENSE = 0;
  22. public MediaCodecInfo mCodecInfo;
  23. public int mRank = 0;
  24. public String mMimeType;
  25. private static Map<String, Integer> sKnownCodecList;
  26. private static synchronized Map<String, Integer> getKnownCodecList() {
  27. if (sKnownCodecList != null)
  28. return sKnownCodecList;
  29. sKnownCodecList = new TreeMap<String, Integer>(
  30. String.CASE_INSENSITIVE_ORDER);
  31. // ----- Nvidia -----
  32. // Tegra3
  33. // Nexus 7 (2012)
  34. // Tegra K1
  35. // Nexus 9
  36. sKnownCodecList.put("OMX.Nvidia.h264.decode", RANK_TESTED);
  37. sKnownCodecList.put("OMX.Nvidia.h264.decode.secure", RANK_SECURE);
  38. // ----- Intel -----
  39. // Atom Z3735
  40. // Teclast X98 Air
  41. sKnownCodecList.put("OMX.Intel.hw_vd.h264", RANK_TESTED + 1);
  42. // Atom Z2560
  43. // Dell Venue 7 3730
  44. sKnownCodecList.put("OMX.Intel.VideoDecoder.AVC", RANK_TESTED);
  45. // ----- Qualcomm -----
  46. // MSM8260
  47. // Xiaomi MI 1S
  48. sKnownCodecList.put("OMX.qcom.video.decoder.avc", RANK_TESTED);
  49. sKnownCodecList.put("OMX.ittiam.video.decoder.avc", RANK_NO_SENSE);
  50. // ----- Samsung -----
  51. // Exynos 3110
  52. // Nexus S
  53. sKnownCodecList.put("OMX.SEC.avc.dec", RANK_TESTED);
  54. sKnownCodecList.put("OMX.SEC.AVC.Decoder", RANK_TESTED - 1);
  55. // OMX.SEC.avcdec doesn't reorder output pictures on GT-9100
  56. sKnownCodecList.put("OMX.SEC.avcdec", RANK_TESTED - 2);
  57. sKnownCodecList.put("OMX.SEC.avc.sw.dec", RANK_SOFTWARE);
  58. // Exynos 5 ?
  59. sKnownCodecList.put("OMX.Exynos.avc.dec", RANK_TESTED);
  60. sKnownCodecList.put("OMX.Exynos.AVC.Decoder", RANK_TESTED - 1);
  61. // ------ Huawei hisilicon ------
  62. // Kirin 910, Mali 450 MP
  63. // Huawei HONOR 3C (H30-L01)
  64. sKnownCodecList.put("OMX.k3.video.decoder.avc", RANK_TESTED);
  65. // Kirin 920, Mali T624
  66. // Huawei HONOR 6
  67. sKnownCodecList.put("OMX.IMG.MSVDX.Decoder.AVC", RANK_TESTED);
  68. // ----- TI -----
  69. // TI OMAP4460
  70. // Galaxy Nexus
  71. sKnownCodecList.put("OMX.TI.DUCATI1.VIDEO.DECODER", RANK_TESTED);
  72. // ------ RockChip ------
  73. // Youku TVBox
  74. sKnownCodecList.put("OMX.rk.video_decoder.avc", RANK_TESTED);
  75. // ------ AMLogic -----
  76. // MiBox1, 1s, 2
  77. sKnownCodecList.put("OMX.amlogic.avc.decoder.awesome", RANK_TESTED);
  78. // ------ Marvell ------
  79. // Lenovo A788t
  80. sKnownCodecList.put("OMX.MARVELL.VIDEO.HW.CODA7542DECODER", RANK_TESTED);
  81. sKnownCodecList.put("OMX.MARVELL.VIDEO.H264DECODER", RANK_SOFTWARE);
  82. // ----- TODO: need test -----
  83. sKnownCodecList.remove("OMX.Action.Video.Decoder");
  84. sKnownCodecList.remove("OMX.allwinner.video.decoder.avc");
  85. sKnownCodecList.remove("OMX.BRCM.vc4.decoder.avc");
  86. sKnownCodecList.remove("OMX.brcm.video.h264.hw.decoder");
  87. sKnownCodecList.remove("OMX.brcm.video.h264.decoder");
  88. sKnownCodecList.remove("OMX.cosmo.video.decoder.avc");
  89. sKnownCodecList.remove("OMX.duos.h264.decoder");
  90. sKnownCodecList.remove("OMX.hantro.81x0.video.decoder");
  91. sKnownCodecList.remove("OMX.hantro.G1.video.decoder");
  92. sKnownCodecList.remove("OMX.hisi.video.decoder");
  93. sKnownCodecList.remove("OMX.LG.decoder.video.avc");
  94. sKnownCodecList.remove("OMX.MS.AVC.Decoder");
  95. sKnownCodecList.remove("OMX.RENESAS.VIDEO.DECODER.H264");
  96. sKnownCodecList.remove("OMX.RTK.video.decoder");
  97. sKnownCodecList.remove("OMX.sprd.h264.decoder");
  98. sKnownCodecList.remove("OMX.ST.VFM.H264Dec");
  99. sKnownCodecList.remove("OMX.vpu.video_decoder.avc");
  100. sKnownCodecList.remove("OMX.WMT.decoder.avc");
  101. // Really ?
  102. sKnownCodecList.remove("OMX.bluestacks.hw.decoder");
  103. // ---------------
  104. // Useless codec
  105. // ----- google -----
  106. sKnownCodecList.put("OMX.google.h264.decoder", RANK_SOFTWARE);
  107. sKnownCodecList.put("OMX.google.h264.lc.decoder", RANK_SOFTWARE);
  108. // ----- huawei k920 -----
  109. sKnownCodecList.put("OMX.k3.ffmpeg.decoder", RANK_SOFTWARE);
  110. sKnownCodecList.put("OMX.ffmpeg.video.decoder", RANK_SOFTWARE);
  111. // ----- unknown -----
  112. sKnownCodecList.put("OMX.sprd.soft.h264.decoder", RANK_SOFTWARE);
  113. return sKnownCodecList;
  114. }
  115. @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  116. public static IjkMediaCodecInfo setupCandidate(MediaCodecInfo codecInfo,
  117. String mimeType) {
  118. if (codecInfo == null
  119. || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
  120. return null;
  121. String name = codecInfo.getName();
  122. if (TextUtils.isEmpty(name))
  123. return null;
  124. name = name.toLowerCase(Locale.US);
  125. int rank = RANK_NO_SENSE;
  126. if (!name.startsWith("omx.")) {
  127. rank = RANK_NON_STANDARD;
  128. } else if (name.startsWith("omx.pv")) {
  129. rank = RANK_SOFTWARE;
  130. } else if (name.startsWith("omx.google.")) {
  131. rank = RANK_SOFTWARE;
  132. } else if (name.startsWith("omx.ffmpeg.")) {
  133. rank = RANK_SOFTWARE;
  134. } else if (name.startsWith("omx.k3.ffmpeg.")) {
  135. rank = RANK_SOFTWARE;
  136. } else if (name.startsWith("omx.avcodec.")) {
  137. rank = RANK_SOFTWARE;
  138. } else if (name.startsWith("omx.ittiam.")) {
  139. // unknown codec in qualcomm SoC
  140. rank = RANK_NO_SENSE;
  141. } else if (name.startsWith("omx.mtk.")) {
  142. // 1. MTK only works on 4.3 and above
  143. // 2. MTK works on MIUI 6 (4.2.1)
  144. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2)
  145. rank = RANK_NO_SENSE;
  146. else
  147. rank = RANK_TESTED;
  148. } else {
  149. Integer knownRank = getKnownCodecList().get(name);
  150. if (knownRank != null) {
  151. rank = knownRank;
  152. } else {
  153. try {
  154. CodecCapabilities cap = codecInfo
  155. .getCapabilitiesForType(mimeType);
  156. if (cap != null)
  157. rank = RANK_ACCEPTABLE;
  158. else
  159. rank = RANK_LAST_CHANCE;
  160. } catch (Throwable e) {
  161. rank = RANK_LAST_CHANCE;
  162. }
  163. }
  164. }
  165. IjkMediaCodecInfo candidate = new IjkMediaCodecInfo();
  166. candidate.mCodecInfo = codecInfo;
  167. candidate.mRank = rank;
  168. candidate.mMimeType = mimeType;
  169. return candidate;
  170. }
  171. @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  172. public void dumpProfileLevels(String mimeType) {
  173. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN)
  174. return;
  175. try {
  176. CodecCapabilities caps = mCodecInfo
  177. .getCapabilitiesForType(mimeType);
  178. int maxProfile = 0;
  179. int maxLevel = 0;
  180. if (caps != null) {
  181. if (caps.profileLevels != null) {
  182. for (CodecProfileLevel profileLevel : caps.profileLevels) {
  183. if (profileLevel == null)
  184. continue;
  185. maxProfile = Math.max(maxProfile, profileLevel.profile);
  186. maxLevel = Math.max(maxLevel, profileLevel.level);
  187. }
  188. }
  189. }
  190. Log.i(TAG,
  191. String.format(Locale.US, "%s",
  192. getProfileLevelName(maxProfile, maxLevel)));
  193. } catch (Throwable e) {
  194. Log.i(TAG, "profile-level: exception");
  195. }
  196. }
  197. public static String getProfileLevelName(int profile, int level) {
  198. return String.format(Locale.US, " %s Profile Level %s (%d,%d)",
  199. getProfileName(profile), getLevelName(level), profile, level);
  200. }
  201. public static String getProfileName(int profile) {
  202. switch (profile) {
  203. case CodecProfileLevel.AVCProfileBaseline:
  204. return "Baseline";
  205. case CodecProfileLevel.AVCProfileMain:
  206. return "Main";
  207. case CodecProfileLevel.AVCProfileExtended:
  208. return "Extends";
  209. case CodecProfileLevel.AVCProfileHigh:
  210. return "High";
  211. case CodecProfileLevel.AVCProfileHigh10:
  212. return "High10";
  213. case CodecProfileLevel.AVCProfileHigh422:
  214. return "High422";
  215. case CodecProfileLevel.AVCProfileHigh444:
  216. return "High444";
  217. default:
  218. return "Unknown";
  219. }
  220. }
  221. public static String getLevelName(int level) {
  222. switch (level) {
  223. case CodecProfileLevel.AVCLevel1:
  224. return "1";
  225. case CodecProfileLevel.AVCLevel1b:
  226. return "1b";
  227. case CodecProfileLevel.AVCLevel11:
  228. return "11";
  229. case CodecProfileLevel.AVCLevel12:
  230. return "12";
  231. case CodecProfileLevel.AVCLevel13:
  232. return "13";
  233. case CodecProfileLevel.AVCLevel2:
  234. return "2";
  235. case CodecProfileLevel.AVCLevel21:
  236. return "21";
  237. case CodecProfileLevel.AVCLevel22:
  238. return "22";
  239. case CodecProfileLevel.AVCLevel3:
  240. return "3";
  241. case CodecProfileLevel.AVCLevel31:
  242. return "31";
  243. case CodecProfileLevel.AVCLevel32:
  244. return "32";
  245. case CodecProfileLevel.AVCLevel4:
  246. return "4";
  247. case CodecProfileLevel.AVCLevel41:
  248. return "41";
  249. case CodecProfileLevel.AVCLevel42:
  250. return "42";
  251. case CodecProfileLevel.AVCLevel5:
  252. return "5";
  253. case CodecProfileLevel.AVCLevel51:
  254. return "51";
  255. case 65536: // CodecProfileLevel.AVCLevel52:
  256. return "52";
  257. default:
  258. return "0";
  259. }
  260. }
  261. }