音视频学习 --VLC 优化
1 vlc 截图异常
修复需求 bug 时,发现 vlc 没有开启硬件编解码器时,截图就会失败,如下 log:
经过一步步排查,发现是无法构建 video converter,应该是构建相关组件时构建失败了。
失败时 log 并不足以显示,只能一步一步排查代码。后来对比发现 8x V2.6 的库推进去竟然可以截图,之后对比一下代码,构建 options 时候,开启了 MediaCodec 的硬件编解码。但是 4X 没有用到,所以暂时关闭就可以了。
猜测原因可能:
(1)优先用了硬解编解码,但是视频用的 iomx 的 codec,导致无法进行转换,;
(2)可能 4x 的 MediaCodec 库和 40X 的不一样,需要进行调试;
root cause 目前没有时间继续跟进,暂时没有周到,临时方案移除 MediaCodec 的 codec 选项,有时间再进行跟踪。
2 vlc 监控概率失败问题
Android 平台的话机和室内机统一用的 vlc 进行 rtsp 监控的,深圳某客户项目部署时出现一个问题,所以投入两周时间进行排查和优化,相关内容总结如下:
2.1 问题背景
深圳客户项目部署多台 4X 作为管理机,每个门口 2X 作为门口机的一整套智能云监控系统,在部署过程中碰到一个问题:
(1)客户现场用 4X 作为管理机,但是 4X 通过 wifi 接入网络;这时视频通话和监控都非常卡顿;同时视频质量有下降趋势;
(2)由于门口机和管理机在不同的网段,所有的通话和监控都需要经过云端服务器进行转发通信;这时如果进行视频监控,则加载时会概率等待很久黑屏的现象(有时候超过 10s);
(3)4X 之前的设计规划并没有增加主动尝试的动作,一旦加载失败,就直接黑屏或者关闭当前会话;使用体验不佳。
出现问题后,第一时间销售端提供一个临时方案:将所有 2X 增加为本地监控的方式,绕过云端进行监控;该方案可以一定程度上减少和云端的交互,缩短加载时间,但是并非最终解决方案;毕竟部署项目设计的楼层和楼栋还是蛮多的,这种修改需要增加客户的维护成本,同时不利于大面积部署。
第二种临时方案:销售端建议客户将 4X 通过有线的方式接入网络,毕竟有线比无线速率、带宽、通信质量等有很大的提升,这样也可以最大程度减少加载失败的概率;然而客户环境限制,同时为了后续大面积部署就要每台都重新布线,增加客户成本。
尝试多个方案仍然被客户投诉,前端反馈给研发中心,之后和 Y 神一起承担问题修复的工作。
2.2 问题复现
由于问题时链接云系统才可以复现的,不过客户还比较好说话,协商后客户也允许链接测试机到实际环境下,因此增加三台设备到客户实际环境中验证和调试。
由于当时掌握的资料比较少,采用盲猜和测试验证的方法快速定位问题发生在哪个阶段:门口机到云阶段;云到话机阶段;话机本身问题;
之后采用测试验证逐步排查方法。经过第一轮公司内部测试和结合客户反馈的现场情况,所以笼统的做了一下对比实验,得出如下测试结果:
当时看到这样结果,第一时间怀疑肯定是 VLC 源码的问题,毕竟 PC 端也是异常的,而 iOS 和 Android APP 的 RTSP 监控方案是公司内部开发。之后开始了漫长的 vlc 代码跟踪之旅。
2.3 问题分析
2.3.1 VLC 端问题排查
话机端 VLC 异常 log 如下,connect 失败了
pc VLC 异常 log 如下:connect 失败了。
这么看应该就是 VLC connect 的异常问题了,当时还在想,这么快就找到原因了。来,安排,盘它。
2.3.2 VLC 代码框架
但是 vlc 的代码跟踪了一圈,一直跟踪到 live555,增加了很多 log,尝试了多个办法,仍然有概率 connect 失败,vlc 的代码跟踪流程部分关键节点:
//input.c -> InitPrograms -> es_out_SetMode
//es_out.c -> EsOutControlLocked -> EsOutSelect -> EsCreateDecoder
//decoder.c -> input_DecoderNew -> decoder_New -> CreateDecoder -> vlc_custom_create -> LoadDecoder
//modules.c 这里设计到 VLC 模块加载的很多细节,
//大概原理就是根据 cap(视频解码 cap: video decoder) 去找对应模块(mediacodec(系统支持), avcodec(ffmpeg)。。。)列表,
//然后匹配 name 值(在解码模块这里可以理解成具体的解码器), 如果有多个模块被匹配到这个 name, 则根据模块的 score 来决定加载哪个模块。 -> module_need -> vlc_module_load -> module_match_name -> module_load -> module_Map
把 live555log 打印出来之后,显示如下,sendOptionsCommand 阶段就异常了:
2.3.3 问题总结
经过分析、测试、以及和云端的调试,目前定位到的问题点如下:
(1)有概率出现 4X 通过 VLC 新启动一次监控时,链接不上上服务的问题。该问题点是话机 connect 失败的;
(2)有概率出现 live555 链接失败,用 real-rtsp 进行尝试
(3)有概率出现 4X 和云交互式,4X 发送 TCP 握手,但是握手不成功的问题;
发送了三次 SYN TCP,但是在云端抓包,云并没有收到;
(4)有概率出现 4X 发送的穿透包无法到达云端;
发送两个穿透包,但是云端有概率没有收到;
(5)在 4X 链接失败只有弹框提醒,之后一直显示黑屏;
因为建立不起来 RTSP 链接,导致一直黑屏,之后显示加载失败。
2.4 解决方案
和 Y 神一起通过抓包确认了一些问题,并协商对应的解决方案:
(1)话机 connect 失败的,分析后应该是公司网络异常导致;
通过 4G 手机热点测试,是正常的;一旦工作时段在公司测试就有概率异常(正好这段时间公司装修,网络线路有出现波动,网络变慢了,也容易丢包)
(2)有概率出现 4X 和云交互式,4X 发送 TCP 握手不成功的问题,应该也和公司网络有关系,同时移除 real-rtsp 发包请求的处理机制;
同时将 live555 超时从 5s 缩减到 2s,减弱超时对于建立链接的影响,修改内容:
移除 real-rtsp 配置项:
直接删除,或者设置成 disable
(3)4X 发送的穿透包无法到达云端:增加穿透包为 4 个。
对应的修改位置如下:
(4)为了提升体验,在 4X 黑屏时,增加动画效果显示正在加载或者其他字样,防止黑屏的现象:这部分和需求以及 UI 沟通,完成界面优化。
(5)增加 5 次监控建立失败后的重试优化,防止无法加载现象出现。
第四点和第五点一起修改,对应的修改如下:
2.5 优化结果
3 vlc 编译相关
参考之前文章:音视频应用--VLC-Android 截图和录制 - 知乎 (zhihu.com)
3.1 live555 编译
vlc 工程中, 会发现默认只有一个 \src\emb_android\vlc\src\vlc-android\vlc\contrib\src\live555 的目录:
该路径下,并没有真实的代码,而是一些 patch 路径,通过 patch 编译时候获取对应节点,在重新拉去,然后再编译。
通过查看 rules.mak 可以得知,需要从官网上 down 一个固定节点的内容,然后再单独编译各个模块
编译的方法,进入需要编译的子模块中,make, 然后再 make install,
拉去的文件存放在\vlc\src\vlc-android\vlc\contrib\contrib-android-arm-linux-androideabi\live555。路径下
要编译该路径的内容,直接编译,make;make install 即可
之后再通过./compile-libvlc.sh \-a arm \-\-no\-ml,完成 vlc 的编译。
3.2 vlc log 放开
3.2.1 log 等级放开
在 Android.c 中将 verbosity 的值分别加上 info、warn、dbg 就可以把 log 等级放开,方便不熟悉的人进行流程跟踪
3.2.2 live555 log 打印
在 live555 中通过 p_sys->env->getResultMsg()将 live555 模块中的 log 输出到 console 端进行查看:
在 RTSPClient 中通过 envir()输出 log,并将 log 传输到 env 中,通过 getresultMsg 输出。
以上是这周时间做的一次问题排查和优化内容,当然这些都是为了特殊场景下解决一些问题,不一定是最优结果,周末会进行压测,通过自动化脚本的方式进行不断重连,到时候看看压测效果。
参考文献:
官方下载:VLC media player,最棒的开源播放器 - VideoLAN
版权声明: 本文为 InfoQ 作者【Fenngton】的原创文章。
原文链接:【http://xie.infoq.cn/article/10b4eaf98e21640546341d1d8】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论