最近一段时间接到不少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

更多相关文章

  1. Android(安卓)判断是否有刘海屏
  2. android修改TextView中部分文字的颜色来实现高亮效果
  3. Android(安卓)UI实战之基于Toolbar与Navigation Drawer的Materia
  4. android colormatrix
  5. 刘海屏适配总结
  6. Android(安卓)手机厂商推送服务调研
  7. Android(安卓)BLE MTU调整
  8. Android项目实践系列(二) - 深度定制Logger
  9. Android不规则点击区域详解

随机推荐

  1. 什么是最好的Node.js mysql模块通过ssl连
  2. mysql utf8中文排序
  3. java系列-安装MySql(三)
  4. MySQL5.7以上版本root用户空密码修改(wind
  5. Auto-generated primary key in sql data
  6. 解决Linux主机上的 远程MySQL客户端无法
  7. 安装MySQL时出现黄色感叹号,提示3306已被
  8. java链接数据库--Mysql
  9. MySQL常用命令与常见问题解决
  10. profiles在mysql中的应用