VvsipMediaCodecFinder.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. vvphone is a SIP app for android.
  3. vvsip is a SIP library for softphone (SIP -rfc3261-)
  4. Copyright (C) 2003-2010 Bluegoby - <bluegoby@163.com>
  5. */
  6. package com.vvsip.ansip;
  7. import java.util.ArrayList;
  8. import android.annotation.TargetApi;
  9. import android.media.MediaCodecInfo;
  10. import android.media.MediaCodecInfo.CodecCapabilities;
  11. import android.media.MediaCodecList;
  12. import android.media.MediaCodecInfo.CodecProfileLevel;
  13. import android.os.Build;
  14. import android.util.Log;
  15. //Information on encoder, decoder, phone tested...
  16. /*
  17. HW-INFO:Galaxy Nexus
  18. HW-INFO:4.3
  19. HW-INFO:maguro
  20. HW-INFO:google
  21. Encoder: OMX.TI.DUCATI1.VIDEO.H264E Mimetype:video/avc supported with NV12 (COLOR_TI_FormatYUV420PackedSemiPlanar)
  22. Decoder: OMX.TI.DUCATI1.VIDEO.DECODER Mimetype:video/avc supported with NV12 (COLOR_TI_FormatYUV420PackedSemiPlanar)
  23. sidenote: was working with 4.2
  24. sidenote: MS_NV12 for both decoder/encoder
  25. sidenote: the decoded data(second plane) is shift by 16 octets?? (end of plane 1 + 16)
  26. src_pic.planes[1]=d->data_nv12->b_rptr+d->stride*slice_height+(ysize)/2+16;
  27. TODO: verify other received size
  28. sidenote: decoder tested with CIF and QCIF
  29. sidenote: encoder tested with 320x240 (and I think CIF and most probably other too...)
  30. HW-INFO:GT-I9305
  31. HW-INFO:4.1.2
  32. HW-INFO:m3
  33. HW-INFO:samsung
  34. Encoder: OMX.SEC.avc.enc Mimetype:video/avc supported with NV21 (COLOR_FormatYUV420SemiPlanar)
  35. Decoder: OMX.SEC.avc.dec Mimetype:video/avc supported with NV12 (COLOR_FormatYUV420SemiPlanar)
  36. sidenote: ENCODER ********MS_NV21*******
  37. DECODER ********MS_NV12*******
  38. -> WHY ARE THEY DIFFERENT???
  39. sidenote: example decoder:
  40. INFO_OUTPUT_FORMAT_CHANGED: codec name: OMX.SEC.avc.dec
  41. INFO_OUTPUT_FORMAT_CHANGED: width: 352
  42. INFO_OUTPUT_FORMAT_CHANGED: height: 288
  43. INFO_OUTPUT_FORMAT_CHANGED: stride: 352
  44. INFO_OUTPUT_FORMAT_CHANGED: slice-height: 288
  45. INFO_OUTPUT_FORMAT_CHANGED: color-format: 21
  46. INFO_OUTPUT_FORMAT_CHANGED: crop-left: 0
  47. INFO_OUTPUT_FORMAT_CHANGED: crop-top: 0
  48. INFO_OUTPUT_FORMAT_CHANGED: crop-right: 351
  49. INFO_OUTPUT_FORMAT_CHANGED: crop-bottom: 287
  50. sidenote: decoder tested with CIF and QCIF
  51. nexus7:
  52. 09-04 14:35:32.218: D/VvsipMediaCodecFinder(4104): Encoder: OMX.Nvidia.h264.encoder Mimetype:video/avc supported with YUV420P (COLOR_FormatYUV420Planar)
  53. 09-04 14:35:32.248: D/VvsipMediaCodecFinder(4104): Decoder: OMX.Nvidia.h264.decode Mimetype:video/avc supported with YUV420P (COLOR_FormatYUV420Planar)
  54. 09-04 14:36:15.688: I/VvsipService(4104): HW-INFO:Nexus 7
  55. 09-04 14:36:15.688: I/VvsipService(4104): HW-INFO:4.2.2
  56. 09-04 14:36:15.688: I/VvsipService(4104): HW-INFO:tilapia
  57. 09-04 14:36:15.688: I/VvsipService(4104): HW-INFO:google
  58. 09-04 14:40:39.238: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: codec name: OMX.Nvidia.h264.decode
  59. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: width: 352
  60. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: height: 288
  61. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: stride: 352
  62. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: slice-height: 0
  63. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: color-format: 19
  64. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: crop-left: 0
  65. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: crop-top: 0
  66. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: crop-right: 351
  67. 09-04 14:40:39.988: E/H264MediaCodecDecoder(4104): INFO_OUTPUT_FORMAT_CHANGED: crop-bottom: 287
  68. sidenote: decoder CIF and QCIF tested
  69. HW-INFO:POV_TAB-PROTAB25XXL8
  70. HW-INFO:4.1.1
  71. HW-INFO:POV_TAB-PROTAB25XXL
  72. HW-INFO:POV
  73. Decoder: OMX.google.h264.decoder Mimetype:video/avc supported with YUV420P (COLOR_FormatYUV420Planar)
  74. No usable Encoder
  75. sidenote: receiving QCIF -> crash
  76. sidenote: second decoder receiving QCIF -> crash (same as OMX.google.h264.decoder?)
  77. it reports: Decoder: video/avc supported with YUV420P (COLOR_FormatYUV420Planar)
  78. GT-N7000 and GT-I9100
  79. Encoder: NV12 with COLOR_FormatYUV420SemiPlanar
  80. */
  81. /*
  82. * 枚举硬编解码器
  83. */
  84. @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  85. public class VvsipMediaCodecFinder {
  86. static final String mTag = "VvsipMediaCodecFinder";
  87. static public ArrayList<VvsipMediaCodecInfo> AvcEncoders = new ArrayList<VvsipMediaCodecInfo>();
  88. static public ArrayList<VvsipMediaCodecInfo> AvcDecoders = new ArrayList<VvsipMediaCodecInfo>();
  89. static public boolean codec_loaded = false;
  90. static public int codecCount = 0;
  91. static public int totalSize = 0;
  92. /*
  93. * Find whether the given codec is supported
  94. */
  95. private static boolean isFormatSupported(MediaCodecInfo info, CodecCapabilities cap, int colorFormat) {
  96. try {
  97. for (int k = 0; k < cap.colorFormats.length; ++k) {
  98. if (cap.colorFormats[k] == colorFormat) {
  99. //Log.d(mTag, "isFormatSupported: Found " + info.getName() + " // format: " + cap.colorFormats[k]);
  100. return true;
  101. }
  102. }
  103. }catch (Exception e) {
  104. Log.d(mTag, "Codec: Skipping codec " + info.getName());
  105. e.printStackTrace();
  106. }
  107. return false;
  108. }
  109. public static int ListAllMediaCodec(String mMimeType, int profile, boolean checkEncoder, boolean checkDecoder) {
  110. if (android.os.Build.VERSION.SDK_INT<16) {
  111. return totalSize;
  112. }
  113. if (AvcEncoders.size()>0)
  114. checkEncoder=false;
  115. if (AvcDecoders.size()>0)
  116. checkDecoder=false;
  117. /* already done or not required */
  118. if (checkEncoder==false && checkDecoder==false) {
  119. codec_loaded=true;
  120. return totalSize;
  121. }
  122. totalSize=0;
  123. codecCount = MediaCodecList.getCodecCount();
  124. for (int i = 0; i < codecCount; ++i) {
  125. MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
  126. String[] types = info.getSupportedTypes();
  127. if (info.isEncoder()==true && types.length>0)
  128. Log.d(mTag, "Codec: Found " + info.getName() + " // + " + types[0] + " // encoder");
  129. else if (info.isEncoder()==true)
  130. Log.d(mTag, "Codec: Found " + info.getName() + " // decoder");
  131. else if (types.length>0)
  132. Log.d(mTag, "Codec: Found " + info.getName() + " // + " + types[0] + " // decoder");
  133. else
  134. Log.d(mTag, "Codec: Found " + info.getName() + " // decoder");
  135. totalSize += 1;
  136. if (checkEncoder==false && info.isEncoder())
  137. continue;
  138. if (checkDecoder==false && info.isEncoder()==false)
  139. continue;
  140. try {
  141. for (int j = 0; j < types.length; ++j) {
  142. int profile_found=0;
  143. if (types[j].compareTo(mMimeType) != 0)
  144. continue;
  145. CodecCapabilities cap = info.getCapabilitiesForType(types[j]);
  146. CodecProfileLevel[] profileLevels = cap.profileLevels;
  147. for (int k = 0; k < profileLevels.length; ++k) {
  148. //Log.d(mTag, "Codec: Found " + info.getName() + " // " + types[j] + " // profile: " + profileLevels[k].profile + " level:" + profileLevels[k].level);
  149. if (profile==profileLevels[k].profile) {
  150. profile_found=1;
  151. }
  152. }
  153. if (profile_found!=0) {
  154. if (isFormatSupported(info, cap, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar)==true) {
  155. Log.d(mTag, "Codec: Found " + info.getName() + " // " + types[j] + " // COLOR_FormatYUV420SemiPlanar");
  156. VvsipMediaCodecInfo apci;
  157. if (info.getName().equalsIgnoreCase("OMX.Intel.VideoDecoder.AVC"))
  158. continue; //can't find the correct format...
  159. else if (info.getName().equalsIgnoreCase("OMX.SEC.avc.enc") && android.os.Build.VERSION.SDK_INT<17)
  160. apci = new VvsipMediaCodecInfo(info, mMimeType, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar, 8); // NV21
  161. else
  162. apci = new VvsipMediaCodecInfo(info, mMimeType, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar, 9); // NV12
  163. if (info.isEncoder()==true) AvcEncoders.add(apci);
  164. else AvcDecoders.add(apci);
  165. }
  166. if (isFormatSupported(info, cap, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar)==true) {
  167. Log.d(mTag, "Codec: Found " + info.getName() + " // " + types[j] + " // COLOR_FormatYUV420Planar");
  168. VvsipMediaCodecInfo apci = new VvsipMediaCodecInfo(info, mMimeType, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar, 0); // YUV420P
  169. if (info.isEncoder()==true) AvcEncoders.add(apci);
  170. else AvcDecoders.add(apci);
  171. }
  172. if (isFormatSupported(info, cap, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar)==true) {
  173. Log.d(mTag, "Codec: Found " + info.getName() + " // " + types[j] + " // COLOR_FormatYUV420PackedPlanar");
  174. VvsipMediaCodecInfo apci = new VvsipMediaCodecInfo(info, mMimeType, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar, 0); // YUV420P
  175. if (info.isEncoder()==true) AvcEncoders.add(apci);
  176. else AvcDecoders.add(apci);
  177. }
  178. if (isFormatSupported(info, cap, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar)==true) {
  179. Log.d(mTag, "Codec: Found " + info.getName() + " // " + types[j] + " // COLOR_FormatYUV420PackedSemiPlanar");
  180. VvsipMediaCodecInfo apci = new VvsipMediaCodecInfo(info, mMimeType, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar, 9); // NV12
  181. if (info.isEncoder()==true) AvcEncoders.add(apci);
  182. else AvcDecoders.add(apci);
  183. }
  184. if (isFormatSupported(info, cap, MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar)==true) {
  185. Log.d(mTag, "Codec: Found " + info.getName() + " // " + types[j] + " // COLOR_TI_FormatYUV420PackedSemiPlanar");
  186. VvsipMediaCodecInfo apci = new VvsipMediaCodecInfo(info, mMimeType, MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar, 9); // NV12
  187. if (info.isEncoder()==true) AvcEncoders.add(apci);
  188. else AvcDecoders.add(apci);
  189. }
  190. if (isFormatSupported(info, cap, 0x7f000001)==true) {
  191. Log.d(mTag, "Codec: Found " + info.getName() + " // " + types[j] + " // COLOR_TI_FormatYUV420PackedSemiPlanarInterlaced");
  192. VvsipMediaCodecInfo apci = new VvsipMediaCodecInfo(info, mMimeType, 0x7f000001, 9); // NV12
  193. if (info.isEncoder()==true) AvcEncoders.add(apci);
  194. else AvcDecoders.add(apci);
  195. }
  196. if (isFormatSupported(info, cap, MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar)==true) {
  197. Log.d(mTag, "Codec: Found " + info.getName() + " // " + types[j] + " // COLOR_QCOM_FormatYUV420SemiPlanar");
  198. VvsipMediaCodecInfo apci = new VvsipMediaCodecInfo(info, mMimeType, MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar, 9); // NV12
  199. if (info.isEncoder()==true) AvcEncoders.add(apci);
  200. else AvcDecoders.add(apci);
  201. }
  202. }
  203. }
  204. }catch (Exception e) {
  205. Log.d(mTag, "Codec: Skipping codec " + info.getName());
  206. e.printStackTrace();
  207. }
  208. }
  209. codec_loaded=true;
  210. return totalSize;
  211. }
  212. }