音视频问题汇总--vlc调试优化

Fenngtun

共 8464字,需浏览 17分钟

 · 2022-02-09

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+ 4G50次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没有画面
14X优化前9次3次8次
24X优化后11次4次5次
3iOS16次0次4次
431X5次6次9次
5Android app16次1次3次


白天时间段:有线,一共测试20次

5s以内加载10s以内加载无法加载或者大于30s没有画面
14X优化前9次5次6次
24X优化后14次3次3次
3iOS + 4G16次0次4次
431X5次6次9次


早上时间段:链接wifi, 一共测试20次

5s以内加载10s以内加载无法加载或者大于30s没有画面
14X优化前10次3次7次
24X优化后10次6次3次
3iOS app1次0次3次(没有重新尝试加载)
431X5次6次9次
5Android app17次0次3次(没有重新尝试加载)


早上时间段:4X链接有线网络,一共测试50次

5s以内加载10s以内加载无法加载或者大于30s没有画面
14X优化前50次0次0次
24X优化后50次0次0次
3iOS + 4G50次0次0次
431X 有线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 android的编译及截图,录制视频等功能

LIVE555.COM

官方下载:VLC media player,最棒的开源播放器 - VideoLAN


欢迎点赞、评论、关注、转发;随时探讨,持续输出。ZGNB

浏览 3
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报