RTP音频流分析以及乱序问题的解决方法(一)

来源:互联网 发布:arrayslice php 编辑:程序博客网 时间:2024/06/03 03:38

一、背景描述:

近日,项目现场传来消息,终端音频解码声音不正常,有爆破音。

我们的项目的视音频使用RTP协议封装,视频使用H.264格式,音频使用G.711格式,使用UDP发送接收。

音频流传输是这样的:

终端A -> 流媒体服务器 -> 终端B

在现场的同事,在流媒体服务器上面进行了抓包,流媒体服务器收到的音频流、发出去的音频流,解出来的声音都没有问题。


二、如何从RTP包中提取音频数据

1、拿到.pcap文件后,使用wireshark打开

2、解码为RTP:此时还是现实UDP包,点击任意一个UDP包,鼠标右键,Decode As,窗口右侧列表总选择RTP

3、查看流信息:菜单 Telephony->rtp->stream analysis

4、保存.AU文件:在弹出窗口中,可以看到这个流的统计信息,包括丢包、乱序等,点击左下角按钮save payload as,选择.au

5、收听.AU文件:可以使用VLC直接打开,也可以使用audacity打开并且查看波形


三、分析PCM数据

既然服务器发出去的流没有问题,那么只能从终端上面找原因了。

终端设备是嵌入式设备,使用嵌入式linux系统,音频采集、播放使用ALSA接口,编解码使用软件模块。

由于设备不在身边,不能操作串口,所以我先选择了修改代码,在ALSA播放线程,保存音频解码后的PCM数据。

保存方法就是直接将收到的数据写入一个文件中。

1、保存文件代码

FILE *fp = NULL;if (!fp)    fp = fopen("./audio_dec.pcm", "wb");fwrite(str_buf, strlen(str_buf), 1, fp);fflush(fp);

2、使用audacity打开

打开audacity

文件->导入->原始数据->选择文件

窗口选择 16bitpcm、小端、8K


四、分析G.711数据

发现PCM数据与线程播放效果一致,有问题。

那么再往上追查,在G.711解码线程中保存rtp解包后的G.711数据

使用audacity打开的方法与打开PCM差不多,唯一的区别是原来选择16bitPCM那里,选择U-law

通过分析,这个G711数据也有问题,那么问题基本可以定位在设备收流和rtp解包这两块儿了。


五、设备上面抓包

需要在嵌入式设备上面抓包,需要下载并交叉编译tcpdump

可以将tcpdump命令在程序中传递给shell执行

1、传递shell命令

char temp[128];FILE* cmdFile;memset(temp, 0, sizeof(temp));sprintf(temp, "linux shell cmd &");cmdFile = popen(temp, "r");pclose(cmdFile);

2、开始抓包

./tcpdump -i eth0 -w port_10006_recv.pcap -n -s0 udp port 10006 -C 10 &

3、停止抓包

killall tcpdump


将抓到的pcap文件使用wireshark打开,解包、流分析(参照‘二、从RTP中提取音频数据’)

查看 Sequence errors(乱序) 和 Lost RTP packets(丢包) 这两项。

发现,设备中收到的流,乱序率达到了40%,没有丢包。

而在终端rtp解包代码中,是不处理乱序的,直接解包后进行G.711解码,所以乱序的音频解码后,声音就不正常了。

后续文章描述如何处理乱序问题。


原创粉丝点击