音视频问题汇总--vlc调试优化
共 8464字,需浏览 17分钟
·
2022-02-09 17:35
1 vlc截图异常
1.1 4x 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 问题复现
由于问题时链接云系统才可以复现的,不过客户还比较好说话,协商后客户也允许链接测试机到实际环境下,因此增加三台设备到客户实际环境中验证和调试。
由于当时掌握的资料比较少,采用盲猜和测试验证的方法快速定位问题发生在哪个阶段:门口机到云阶段;云到话机阶段;话机本身问题;
之后采用测试验证逐步排查方法。经过第一轮公司内部测试和结合客户反馈的现场情况,所以笼统的做了一下对比实验,得出如下测试结果:
客户端 | 是否有鉴权 | 结果 |
---|---|---|
4X话机 | 有 | 测试50次,概率加载10s+是后才可以加载,也有概率失败 |
VLC PC端 | 有 | 测试50次,概率加载10s+是后才可以加载,也有概率失败 |
4X话机 | 无 | 50次OK |
VLC PC端 | 无 | 50次OK |
iOS app+ 4G | 有 | 50次OK |
Android app | 有 | 测试50次,概率等待10s+后加载 |
31X | 有 | 测试10次,概率等待10s+后加载 |
30X | 有 | 测试10次,每次都是timeout,无法连接 |
当时看到这样结果,第一时间怀疑肯定是VLC源码的问题,毕竟PC端也是异常的,而iOS和Android APP的RTSP监控方案是公司内部开发。之后开始了漫长的vlc代码跟踪之旅。
2.3 问题分析
2.3.1 VLC端问题排查
话机端VLC 异常log如下,connect失败了
[17:16:12]I/( 1417): MonitorShowFragment.java: startVideo(136): start rtsp video rtsp://user:U16W19808c9G8544@12X.7X.14X.18X:554/0C1105079740
[17:16:12]D/( 1417): VLCVideoView.java: stop(310): start stop media
[17:16:12]E/adtest ( 1417): VLCVideoView.java: changeMediaPlayerLayout(207): setAspectRatio653*496
[17:16:17]E/VLC ( 1417): [b8652ec8/5539] libvlc demux: Failed to connect with rtsp://12X.7X.14X.18X:554/0C1105079740
[17:16:22]E/VLC ( 1417): [b88336a8/5539] libvlc stream: Failed to connect to RTSP server 12X.7X.14X.18X:554
[17:16:27]D/R47 ( 1417): PhoneWhole pid1417,tid1572,l3: open misc ioctl device failed.
[17:16:27]E/VLC ( 1417): [b88336a8/5539] libvlc stream: cannot connect to 12X.7X.14X.18X:554
[17:16:27]E/VLC ( 1417): [b88336a8/5539] libvlc stream: Connection failed
[17:16:27]E/VLC ( 1417): [b88336a8/5539] libvlc stream: VLC could not connect to "12X.7X.14X.18X:554".
[17:16:27]E/VLC ( 1417): [b85561a8/5539] libvlc input: Your input can't be opened
[17:16:27]E/VLC ( 1417): [b85561a8/5539] libvlc input: VLC is unable to open the MRL 'rtsp://user:U16W19808c9G8544@12X.7X.14X.18X:554/0C1105079740'. Check the log for details.
[17:16:27]W/art ( 1417): Native thread exiting without having called DetachCurrentThread (maybe it's going to use a pthread_key_create destructor?): Thread[53,tid=21817,Native,Thread*=0xb87b8870,peer=0x131e60a0,"VlcObject"]
[17:16:27]D/( 1417): VLCVideoView.java: stop(310): start stop media
[17:16:27]D/( 1417): VLCVideoView.java: stop(332): stop media successful
pc VLC 异常log如下:connect失败了。
main debug: processing request item: rtsp://12X.7X.14X.18X:554/0C1105079740, node: 播放列表, skip: 0
main debug: rebuilding array of current - root 播放列表
main debug: rebuild done - 2 items, index 1
main debug: starting playback of new item
main debug: resyncing on rtsp://12X.7X.14X.18X:554/0C1105079740
main debug: rtsp://12X.7X.14X.18X:554/0C11050DD646 is at 1
main debug: creating new input thread
main debug: Creating an input for 'rtsp://12X.7X.14X.18X:554/0C1105079740'
main debug: requesting art for new input thread
main debug: looking for meta fetcher module matching "any": 1 candidates
main debug: using timeshift granularity of 50 MiB
main debug: using timeshift path: D:\AppData\Temp
main debug: `rtsp://user:u1Px6E1908997046@12X.7X.14X.18X:554/0C1105079740' gives access `rtsp' demux `any' path `user:u1Px6E1908997046@12X.7X.14X.18X:554/0C1105079740'
main debug: creating demux: access='rtsp' demux='any' location='user:u1Px6E1908997046@12X.7X.14X.18X:554/0C1105079740' file='\\user:u1Px6E1908997046@12X.7X.14X.18X:554\0C1105079740'
main debug: looking for access_demux module matching "rtsp": 15 candidates
live555 debug: version 2016.11.28
lua debug: Trying Lua scripts in C:\Users\Administrator\AppData\Roaming\vlc\lua\meta\fetcher
main warning: Password in a URI is DEPRECATED
lua debug: Trying Lua scripts in D:\Program Files\VideoLAN\VLC\lua\meta\fetcher
main debug: no meta fetcher modules matched
main debug: looking for art finder module matching "any": 2 candidates
main debug: no art finder modules matched
main debug: looking for meta fetcher module matching "any": 1 candidates
main debug: no meta fetcher modules matched
main debug: looking for art finder module matching "any": 2 candidates
main debug: no art finder modules matched
qt debug: IM: Setting an input
live555 debug: connection timeout
live555 error: Failed to connect with rtsp://12X.7X.14X.18X554/0C1105079740
main debug: no access_demux modules matched
main debug: creating access: rtsp://user:u1Px6E1908997046@12X.7X.14X.18X:554/0C1105079740
main debug: (path: \\user:u1Px6E1908997046@12X.7X.14X.18X:554\0C1105079740)
main debug: looking for access module matching "rtsp": 27 candidates
satip debug: try to open 'rtsp://user:u1Px6E1908997046@12X.7X.14X.18X:554/0C1105079740'
satip debug: connect to host '12X.7X.14X.18X'
main debug: net: connecting to 12X.7X.14X.18X port 554
main debug: incoming request - stopping current input
satip error: Failed to connect to RTSP server 12X.7X.14X.18X:554
main debug: net: connecting to 12X.7X.14X.18X port 554
access_realrtsp error: cannot connect to 12X.7X.14X.18X:554
这么看应该就是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 优化结果
白天时间段:链接wifi,一共测试20次
5s以内加载 | 10s以内加载 | 无法加载或者大于30s没有画面 | ||
---|---|---|---|---|
1 | 4X优化前 | 9次 | 3次 | 8次 |
2 | 4X优化后 | 11次 | 4次 | 5次 |
3 | iOS | 16次 | 0次 | 4次 |
4 | 31X | 5次 | 6次 | 9次 |
5 | Android app | 16次 | 1次 | 3次 |
白天时间段:有线,一共测试20次
5s以内加载 | 10s以内加载 | 无法加载或者大于30s没有画面 | ||
---|---|---|---|---|
1 | 4X优化前 | 9次 | 5次 | 6次 |
2 | 4X优化后 | 14次 | 3次 | 3次 |
3 | iOS + 4G | 16次 | 0次 | 4次 |
4 | 31X | 5次 | 6次 | 9次 |
早上时间段:链接wifi, 一共测试20次
5s以内加载 | 10s以内加载 | 无法加载或者大于30s没有画面 | ||
---|---|---|---|---|
1 | 4X优化前 | 10次 | 3次 | 7次 |
2 | 4X优化后 | 10次 | 6次 | 3次 |
3 | iOS app | 1次 | 0次 | 3次(没有重新尝试加载) |
4 | 31X | 5次 | 6次 | 9次 |
5 | Android app | 17次 | 0次 | 3次(没有重新尝试加载) |
早上时间段:4X链接有线网络,一共测试50次
5s以内加载 | 10s以内加载 | 无法加载或者大于30s没有画面 | ||
---|---|---|---|---|
1 | 4X优化前 | 50次 | 0次 | 0次 |
2 | 4X优化后 | 50次 | 0次 | 0次 |
3 | iOS + 4G | 50次 | 0次 | 0次 |
4 | 31X 有线 | 50次 | 0次 | 0次 |
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
欢迎点赞、评论、关注、转发;随时探讨,持续输出。ZGNB