WebRTC android h264 编解码适配(二)
最近一段时间接到不少android客户反馈,看到对方的视频是绿屏,还有一些反馈对方看不到自己的视频,由于我们使用的是h264硬编解码,首先想到的是编解码这块出现了问题。
先看绿屏的问题,收集了下反馈机型,主要集中在cpu为联发科MT6735至MT6755的机器上,使用的硬件编解码器是OMX.MTK.**,随便在云真机测试平台找了台机器-华为畅享5(TIT-AL00)测试,果然是绿屏。打开webrtc全日志
Logging.enableTracing( "logcat:", EnumSet.of(Logging.TraceLevel.TRACE_ALL)) Logging.enableLogToDebugOutput(Logging.Severity.LS_SENSITIVE)
再编译个版本在华为畅享5上跑,日志下载下来,逐条分析,有一段日志很奇怪:
04-12 15:58:45.440 W/hwcomposer( 260): [BLT] Not support color range(0), use default BT60104-12 15:58:45.440 W/hwcomposer( 260): [BLT] Not support color range(0), use default BT601
hwcomposer是android4.0后推出的新特性,它定义了一套HAL接口,然后各大厂商需要根据自己硬件特性去实现,其实就是一些图层处理功能,这里报了color不支持。下面我们追踪一下源码,看看webrtc 解码中使用了哪些color
private static @Nullable DecoderProperties findDecoder( String mime, String[] supportedCodecPrefixes) { ... // Check if codec supports either yuv420 or nv12. CodecCapabilities capabilities; try { capabilities = info.getCapabilitiesForType(mime); } catch (IllegalArgumentException e) { Logging.e(TAG, "Cannot retrieve decoder capabilities", e); continue; } for (int colorFormat : capabilities.colorFormats) { Logging.v(TAG, " Color: 0x" + Integer.toHexString(colorFormat)); } for (int supportedColorFormat : supportedColorList) { for (int codecColorFormat : capabilities.colorFormats) { if (codecColorFormat == supportedColorFormat) { // Found supported HW decoder. Logging.d(TAG, "Found target decoder " + name + ". Color: 0x" + Integer.toHexString(codecColorFormat)); return new DecoderProperties(name, codecColorFormat); } } } } ...}
这里会遍历解码器支持的所有colorFormat,然后看支持的格式是否在supportedColorList列表中,直到匹配上,supportedColorList是以白名单的形式存在的,如下:
private static final List supportedColorList = Arrays.asList( CodecCapabilities.COLOR_FormatYUV420Planar, CodecCapabilities.COLOR_FormatYUV420SemiPlanar, CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar, COLOR_QCOM_FORMATYVU420PackedSemiPlanar32m4ka, COLOR_QCOM_FORMATYVU420PackedSemiPlanar16m4ka, COLOR_QCOM_FORMATYVU420PackedSemiPlanar64x32Tile2m8ka, COLOR_QCOM_FORMATYUV420PackedSemiPlanar32m);
遍历的是硬件支持的colorFormat,看上去没有任何问题。再回头看看运行日志,看看使用了哪个colorFormat
04-12 15:58:27.286 I/MediaCodecVideoDecoder( 2452): MediaCodecVideoDecoder: Java initDecode: VIDEO_CODEC_H264 : 320 x 240. Color: 0x13. Use Surface: true
日志显示使用了0x13的Color,对应supportedColorList里面的CodecCapabilities.COLOR_FormatYUV420Planar,也就是第一个,先把这个colorFormate屏蔽掉试试
private static @Nullable DecoderProperties findDecoder( String mime, String[] supportedCodecPrefixes) { ... // Check if codec supports either yuv420 or nv12. CodecCapabilities capabilities; try { capabilities = info.getCapabilitiesForType(mime); } catch (IllegalArgumentException e) { Logging.e(TAG, "Cannot retrieve decoder capabilities", e); continue; } for (int colorFormat : capabilities.colorFormats) { Logging.v(TAG, " Color: 0x" + Integer.toHexString(colorFormat)); } for (int supportedColorFormat : supportedColorList) { for (int codecColorFormat : capabilities.colorFormats) { //屏蔽掉解码器为OMX.MTK并且颜色格式为CodecCapabilities.COLOR_FormatYUV420Planar if (codecColorFormat == supportedColorFormat && (!name.startsWith("OMX.MTK") || supportedColorFormat != CodecCapabilities.COLOR_FormatYUV420Planar)) { // Found supported HW decoder. Logging.d(TAG, "Found target decoder " + name + ". Color: 0x" + Integer.toHexString(codecColorFormat)); return new DecoderProperties(name, codecColorFormat); } } } } ...}
编译好再在华为畅享5(TIT-AL00)测试,一切正常了,可以看到对方图像了。
受到启发,再来看看对方看不到我的情况,会不会也是跟绿屏的情况一样,是编码颜色格式的问题呢,先收集一下出问题的机型,主要集中在cpu为:华为kirin930 华为kirin935,对应编码器为OMX.IMG.TOPAZ,测试机器:华为p8,通过查看运行日志使用的colorFormate也是0x13,也就是supportedColorList里面的CodecCapabilities.COLOR_FormatYUV420Planar,对编码部分做同样的处理,即:屏蔽掉编码器为OMX.IMG.TOPAZ并且颜色格式为CodecCapabilities.COLOR_FormatYUV420Planar的情况,代码跟绿屏完全类似,这里就不贴出来了,编译好,再在p8上跑,正常了,对方能看到我的视频了。
至此,两种问题都解决了,但是原因呢,明明api支持这种颜色格式啊,实际确不支持,这不坑爹吗,也许只有手机厂商自己能解释清楚了。
欢迎关注公众号:
或者微信搜索公众号:webrtc home
更多相关文章
- Android(安卓)判断是否有刘海屏
- android修改TextView中部分文字的颜色来实现高亮效果
- Android(安卓)UI实战之基于Toolbar与Navigation Drawer的Materia
- android colormatrix
- 刘海屏适配总结
- Android(安卓)手机厂商推送服务调研
- Android(安卓)BLE MTU调整
- Android项目实践系列(二) - 深度定制Logger
- Android不规则点击区域详解