在基于RTP的实时码流传输过程中,经常会遇到音视频卡顿、花屏的现象。对于这类问题,如何定位? 下面这个工具可以帮助分析类似问题:
https://github.com/sigusr1/rtp_parse_from_pcap
从传输的角度看,造成卡顿、花屏的常见原因如下:
定位这类问题,最快捷的方式是通过wireshark或者tcpdump抓包,然后进行分析。这样可以看出到底是发送端的问题还是接收端的问题,缩小排查范围。 由于我实际工作中使用的都是rtp over rtsp(也就是TCP传输方式),下面的讨论仅针对rtp over rtsp进行,该工具也是针对这种场景开发的。
总体思路就是对抓包文件进行回放,回放过程中解析报文,分析RTP信息和帧间隔。 处理过程中需要考虑以下问题:
基于以上思路,可以用下面的数据处理流程来实现:
src[源IP[源端口]]--dst[目的IP[目的端口]].txt
的形式命名的。 如果抓包文件中包含多条流,每条流都会生成一个独立的解析文件。本帧帧尾时间 减去 上一帧帧尾时间
。
下图最后一行的Frm_Interval计算过程为:1514774319.466358s - 1514774318.891198s = 575160us
pyhton analyse.py src[192.168.43.252[554]]--dst[192.168.43.1[39535]].txt
可得到下图所示分析结果。图中横坐标代表帧,纵坐标代表帧间隔,单位是us。如下图所示,有一个帧间隔达到了500多ms,肯定会导致卡顿现象。
同时命令行会有如下输出,提示帧间隔过大。最后一行对应的就是图中的波峰:
从上面的txt解析文件中可以看出,问题应该出在RTP序号18492 ~ 18500之间。 分析抓包文件,可以看到RTP序号18492和18493之间有个500多ms的间隔(18492和18491在同一个TCP报文中,wireshark并未显示出18492),而这期间接收端的窗口都是OK的,也就是说发送端导致了这个间隔。排查发送端代码,果然有个分支会sleep 500ms,某些情况会走到该分支。
该工具依赖开源库libpcap(本工程中的源码版本为1.8.1,未做任何修改)和libnids(本工程中的源码基于1.24做了相关修改)。 正常情况下,如无特殊需要,不需执行第1步和第2步。
./configure --with-libpcap=../libpcap --enable-tcpreasm --disable-libglib --disable-libnet
其中--enable-tcpreasm选项是允许跟踪不完整的tcp连接,使能了这个选项,即使抓包文件中没有tcp连接的三次握手过程,也跟踪这条tcp数据流。
b. 执行make,生成libnids.a.
c. 将libnids.a拷到rtp_parser/lib目录。
./rtp_parser rtsp.pcap
(rtsp.pcap为抓包文件)即可生成解析文件
目前rtp_parser的实现比较简单,可根据需要自行修改,然后执行上面第3步的编译即可。