http://blog.youkuaiyun.com/ren911/archive/2010/05/04/5557682.aspx
最近在研究VOIP ,媒体网关底层使用ac490 进行语音信号IP 化( 驱动不由我写) ,碰见一些,总结如下。
一.ac490 介 绍:
ac490 是AudioCodes 公 司的VoIP 处理器,可以运行8/12 通道LBRC ,包括G.723/G.729/iLBC/AMR/GSM FR 。支持24 通道的G.711 算 法或12 通道的G.711/G.723 算法 的语音编码;G.168-2002 回波消除;T.38 传 真;支持RTP/RTCP 的打包/ 解包。
二.RTP 包格式
详细定义请见rfc3550 ( 对RTP 格式的描述) 和 rfc3551 ( 对RTP 携带的媒体信息格式的描述).
2.1RTP 头格式
前12 个字节在每一个RTP packet 中都存在,而一系列的CSRC 标记 只有存在Mixer 时才有。
version (V): 2 bits
标明RTP 版本号。协议初始版本为0 ,RFC3550 中规定的版本号为2 。
padding (P): 1 bit
如果该位被设置,则在该packet 末尾包含了额外的附加信息,附加信息的 最后一个字节表示额外附加信息的长度(包含该字节本身)。该字段之所以存在是因为一些加密机制需要固定长度的数据块,或者为了在一个底层协议数据单元中传 输多个RTP packets 。
extension (X): 1 bit
如果该位被设置,则在固定的头部后存在一个扩展头部,格式定义在RFC3550 5.3.1 节。
CSRC count (CC): 4 bits
在固定头部后存在多少个CSRC 标 记。
marker (M): 1 bit
该位的功能依赖于profile 的定义。profile 可以改变该位的 长度,但是要保持marker 和payload type 总 长度不变(一共是8 bit )。
payload type (PT): 7 bits
标记着RTP packet 所携带信息的类型,标准类型列出在RFC3551 中。如果接收方不能识 别该类型,必须忽略该packet 。
sequence number: 16 bits
序列号,每个RTP packet 发送后该序列号加1 ,接收方可以根据该序列号重新排列数据包顺序。
timestamp: 32 bits
时间戳。反映RTP packet 所携带信息包中第一个字节的采样时间。
SSRC: 32 bits
标识数据源。在一个RTP Session 其 间每个数据流都应该有一个不同的SSRC 。
CSRC list: 0 to 15 items, 32 bits each
标识贡献的数据源。只有存在Mixer 的时候才有效。如一个将多声道的语音流合并成一个单声道的语音流,在这里就列出原来每个声道的 SSRC 。
Payload :此部分的格式规定见RFC3551, 随携带的媒体流格式不同而不同。
2.2 RTP 中payload 格 式
2.2.1 G.729 格式
按照RFC3551 中4.5.6 规定,一个携带G729 格式的RTP 包的payload 可以由0 或多个G.729 或 G.729 Annex A 帧组成,后面再有0 或多个G.729 Annex B 帧组成。
G.729 或 G.729 Annex A 每帧长10 byte ,相互 间完全兼容,主要携带语音信息。G.729 Annex B 帧每帧长4 byte ,主要携带VAD(voice activity detector, 语音行为检测) 和CNG(comfort noise generator, 舒适噪音生成) 。
不过根据对sip 电话和软sip 电话的G729 的RTP 包抓包分析,其payload 一般是由4 个G.729 或 G.729 Annex A 组成。因为VAD 不是所有设 备都支持,例如asterisk 不支持。
2.2.2 G.711A 格式
按照RFC3551 中4.5.14 规定,一个携带G711 格式的RTP 包格式较简单,在G711 中每个声音采样被编码为8 bit 。56 kb/s 和48 kb/s 在RTP 中是不被支持的。
三. AC490 调试
本身希望用AC490 直接发送rtp 包,但是控制其直接发送的RTP 包却无法被sip 电话,asterisk 和wireshark 正确分析。
3.1 G .729 的问题
RTP 头部多了4 个bit ,一般来时G729 的RTP 包头2 个bite 是80 12 ,或者80 92(mark 被置为1 ,一般是在第一个RTP 包中) ,而
ac490 发送G729 的RTP 包中80 12 前面多个4bit , 修改ac490 的驱动使其去掉头4 个bit ,可以被wireshark 分析为G729 的RTP 包,
但仍然无法与sip 电话互通,继续分析发现sip 电话的G729 的RTP 包payload 长度为20 bit ,而ac490 的为12bit ,且在通过
asterisk 的时候,asterisk 报告检测有VAD 帧,查看asterisk 源码发现asterisk 的frame.c 不支持VAD 。
综上和前面对G729 格式的描述,猜测ac490 的默认G729 的RTP 包由2 个G.729 或 G.729 Annex A 帧和一个G.729 Annex B
帧组成。而sip 电话和软sip 电话的G729 的RTP 包一般由4 个G.729 或 G.729 Annex A 帧组成。
修改驱动,改变ac490 的G729 的RTP 包为4 个G.729 帧,与sip 电话和软sip 电话互通成功。
3.2 G .711A 的问题
在前面的调试过程,由于修改ac490 的G729 的RTP 包格式的方式需要些时间,尝试修改ac490 的RTP 格式为G.711A ,也就是pcma ,
因为其格式较为简单。但开始时仍然无法与sip 电话互通,表现为sip 电话可以听到声音但有很大的杂音,ac490 这面的普通电话静音。分析
为还是两端包格式不符,ac490
丢弃了所有发过来的包。
继续抓包,sip 电话的G.711A 的RTP 包payload 长度为160bit ,而ac490G.711A 的RTP 包payload 长度为162bit ,多次试验分析后,发
现主要在ac490RTP 包payload 最后两个bit 上,在一次通话中,这两个bit 要么是00 00 ,要么是固定的两个bit ,所有包后面都是这两种类型。
而不同通话中,00 00 外的另一种方式的两个bit 不同。而00 00 或两个固定bit 出现方式暂时为发现规律,在静音包和语音包尾部两种都会
出现。
建议修改ac490 驱动为在发送时去掉尾部两个bit ,接受时补上两个bit 00 00 。
再次试验互通成功。
四. 总结
1. 较为仔细的学习了RTP 有关RFC ,主要是rfc3550, rfc3551, 还有rfc 2198 和rfc2833 。
2. 基本掌握了sip 电话和软sip 电话的RTP 包结构,了解了常见的RTP 包格式( 即rfc 中建议的多种方式那种最常用) 。
3. 对asterisk 的sip.conf 配置进一步熟悉,尤其是canreinvite 这一段,怎样使其表现的近似于stateless 的sip 服务器。
4. 对用wireshark 抓包进一步掌握。