写点什么

音视频学习 --VLC 优化

作者:Fenngton
  • 2021 年 12 月 04 日
  • 本文字数:5038 字

    阅读完需:约 17 分钟

音视频学习--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 失败了

[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: 0main debug: rebuilding array of current - root 播放列表main debug: rebuild done - 2 items, index 1main debug: starting playback of new itemmain debug: resyncing on rtsp://12X.7X.14X.18X:554/0C1105079740main debug: rtsp://12X.7X.14X.18X:554/0C11050DD646 is at 1main debug: creating new input threadmain debug: Creating an input for 'rtsp://12X.7X.14X.18X:554/0C1105079740'main debug: requesting art for new input threadmain debug: looking for meta fetcher module matching "any": 1 candidatesmain debug: using timeshift granularity of 50 MiBmain debug: using timeshift path: D:\AppData\Tempmain 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 candidateslive555 debug: version 2016.11.28lua debug: Trying Lua scripts in C:\Users\Administrator\AppData\Roaming\vlc\lua\meta\fetcher main warning: Password in a URI is DEPRECATEDlua debug: Trying Lua scripts in D:\Program Files\VideoLAN\VLC\lua\meta\fetchermain debug: no meta fetcher modules matchedmain debug: looking for art finder module matching "any": 2 candidatesmain debug: no art finder modules matchedmain debug: looking for meta fetcher module matching "any": 1 candidatesmain debug: no meta fetcher modules matchedmain debug: looking for art finder module matching "any": 2 candidatesmain debug: no art finder modules matchedqt debug: IM: Setting an inputlive555 debug: connection timeoutlive555 error: Failed to connect with rtsp://12X.7X.14X.18X554/0C1105079740main debug: no access_demux modules matchedmain debug: creating access: rtsp://user:u1Px6E1908997046@12X.7X.14X.18X:554/0C1105079740main debug: (path: \\user:u1Px6E1908997046@12X.7X.14X.18X:554\0C1105079740)main debug: looking for access module matching "rtsp": 27 candidatessatip 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 554main debug: incoming request - stopping current inputsatip error: Failed to connect to RTSP server 12X.7X.14X.18X:554main debug: net: connecting to 12X.7X.14X.18X port 554access_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 优化结果





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


发布于: 1 小时前阅读数: 7
用户头像

Fenngton

关注

明天取得的所有成就, 都源于今天的不将就 2019.06.18 加入

Android音视频开发者; 致力于交流和学习音视频相关内容。 知乎专栏:《音视频学习》

评论

发布
暂无评论
音视频学习--VLC优化