多媒体服务的协议栈如下,RTP和RTCP属于传输层。
RTP(Real-time Transport Protocol,实时传输协议)只负责实时数据的传输,RTCP(Real-time Transport Control Protocol,即实时传输控制协议)负责对RTP的通讯和会话进行带外管理(如流量控制、拥塞控制、会话源管理等)。
协议格式RTP固定头部格式,来源字段:
V:RTP版本,目前为2。
P:代表当前RTP包中是否有填充数据。
X:该bit置1表示包含头部扩展,置0表示不包含。
CSRC count (CC):固定头部后CSRC标志符的个数。比如说多人音视频会议,接收到两个人的音频数据,RTP包中就包含两个人的音频的数据。
M:比如视频帧被分为多个包,最后一个包标识M位。
payload type (PT):流媒体中一般用来区分音频或者视频。
类型参考这里 https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml,https://chromium.googlesource.com/external/webrtc/+/master/pc/g3doc/rtp.md
一般音频在[35,63],视频 [96,127]。
Sequence Num:发送RTP报文的序列号,接收端用于检测丢包或者重新排序接收到的包。
timeStamp:该数据包中第一个字节的采样时间,比如说一帧视频拆分成的包时间戳是一样的。
SSRC:同步源标识,即RTP包的来源,比如视频来源可能来源于摄像头采集和屏幕录屏,因此有两个ssrc。
CSRC列表:最多15个,由CC决定。混合器将有贡献的SSRC标识插入表中。例如不同的SSRC的音频包混合在一起,混合器将所有有贡献的SSRC标识列出,以便接收端能正确指出交谈双方的身份。
modules tp_rtcpsource tp_packet.cc中实现。
RTP扩展如果固定头部的X置1,则CSRC列表之后存在可变长头部扩展信息。
defined by profile:表示使用一字节头部扩展(ID占4bit,最多表示16种)还是两字节扩展(ID占8bit,最多表示225中)。接收端通过这个字段决定如何解析扩展头。
length:表示头部扩展(header extension)的长度length*4字节;
header extension:扩展头要保持4字节对齐,需要使用padding补齐,并计入length。
例如下边使用的两字节头部扩展,length为3,后面跟着3*4字节长度扩展,对于第一个header extension:L=0,数据长度为0,对于第二个header extension:L=1,data长度为1,接着是填充数据,对于第三个header extension:L=4,后面跟着4字节长度数据。
webrtc中代码实现头部实现rtp_packet.h定义了RTP包,class RtpPacket;提供了解析RTP头部字段信息解析parser、头部字段信息设置set、开辟/释放内存buffer 等处理方法。
头部扩展添加rtp_rtcp_defines.h 中指定了rtp的扩展字段的扩展类型。如果需要根据自己应用场景添加字段的话,也是增加一个ID以及相应内容字段。
rtp_header_extension_map.h 管理所有的头部扩展字段;ids_[kRtpExtensionNumberOfExtensions],数组记录RTPExtensionType和id的映射关系。提供注册RTPExtensionType的方法。
rtp_header_extensions.h 定义所有的头部扩展字段;例如 class TransportSequenceNumber;包含RTPExtensionType、kValueSizeBytes、uri等。
比如在发送音频包的时候,添加TransportSequenceNumber头部扩展字段,在RTP包分配一段内存给TransportSequenceNumber字段。
在发送PacketRouter::SendPacket包的时候设置具体的seq值给该扩展字段。