WebRTC RTP 解析
2020-05-12 本文已影响0人
满衣兄
RTP 报文定义
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| Contributing source (CSRC) identifiers |
| .... |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| header eXtension profile id | length in 32bits |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Extensions |
| .... |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| Payload |
| .... : padding... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| padding | Padding size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
可将RTP报文分为以下几个部分:
序号 | 名称 | 比特位 | 必选 | 说明 |
---|---|---|---|---|
1 | 固定报头 | 12*8 | 是 | 包括标志位:V、P、X、CC、M、PT、 sequence number、timestamp、SSRC。 |
2 | 特约信源 | CC*32 | 否 | 每个CSRC占32位,可以有0~15个。 |
3 | 扩展报头 | len*32 | 否 | 其中 len >= 0。 |
4 | 负载数据 | len*8 | 否 | 其中 len >= 0,例如H264编码后的视频 数据,或OPUS编码后的音频数据。 |
5 | 填充数据 | len*8 | 否 | 其中 len >= 0,自定义数据。 |
固定报头
序号 | 标记 | 比特位 | 名称 | 说明 |
---|---|---|---|---|
1 | V | 2 | 版本号 | 目前版本值固定为2 。 |
2 | P | 1 | 填充标志 | 若值为1,则在报文尾部填充 若干大于零的额外字节。 |
3 | X | 1 | 扩展标志 | 若值为1,则在报文头后跟一个扩展报头。 |
4 | CC | 4 | 特约信源(CSRC)计数器 | 指示 CSRC 标识符的个数。 |
5 | M | 1 | 标记位 | 对于视频,标记一帧的结束;对于音频, 标记负载类型改变。 |
6 | PT | 7 | 负载类型 | 取值范围小于128,可自定义取值含义, 例如H264定义为96。 |
7 | SEQ | 16 | 序列号 | 标记数据报文序列号。 |
8 | TS | 32 | 时间戳(Timestamp) | 标记媒体数据的采样时间。 |
9 | SSRC | 32 | 同步信源(SSRC)标识符 | 随机生成的字符串,标记一路数据来源。 |
- 固定报头大小为12字节,所以一帧合法的RTP报文最少包含12个字节的数据。
- 序列号:标识发送的RTP报文的序列号,每发送一个报文,序列号增1。UDP发送数据时,可用来检测丢包、乱序等问题。序列号的初始值随机,且音频包和视频包分别记数。
- 时间戳:视频时间戳单位为 90kHz 时钟频率,例如视频采样时间为MS=1589341659000毫秒,则时间戳为TS=MS*90。对于8kHz采样的音频信号,若每隔20ms发送一个数据包,则一个数据包中包含有160个样本(0.02×8000=160),因此每发送一个RTP包,时间戳的值就增加160。
特约信源(CSRC)
- 场景描述:在一个4人音视频会议中,每个发送端发送一路数据,则此时有SSRC1、SSRC2、SSRC3、SSRC4作为数据源;若媒体服务器对音频进行混音后转发,则媒体服务器将SSRC1、SSRC2、SSRC3、SSRC4填入CSRC字段,标识该路混音数据由四个来源贡献;同时媒体服务器新生成一个随机字符串作为该路流的SSRC。
- 通过上述场景描述可发现,特约信源往土里说其实就是标记流来源的标识(可简单理解为用户ID),最终来源为发送端生成的随机字符串,和SSRC本质上是同一个东西。
扩展报头(Extensions)
RTP header extension, RFC 3550.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| defined by profile | length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| header extension |
| .... |
序号 | 名称 | 比特位 | 说明 |
---|---|---|---|
1 | Profile | 16 | 扩展报文类型,值固定为 0xBEDE或0x1000。 |
2 | Length | 16 | 扩展报文长度,值为Extensions/4 (例如Extensions=12,则Length=3)。 |
3 | Extensions | Length * 16 | 扩展报文定义内容,4字节对齐, 若不足4字节则在Extensions末尾填充零值补齐, 解析时根据对齐原则自动减掉补齐的零值。 |
- 当扩展标志(X)值为1时,在RTP固定报头后跟有一个扩展报头。
- 若报文中包含CSRC,则扩展报头跟在CSRC之后。
单字节模式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0xBE | 0xDE | length=3 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ID | L=0 | data | ID | L=1 | data...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...data | 0 (pad) | 0 (pad) | ID | L=3 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
序号 | 名称 | 比特位 | 说明 |
---|---|---|---|
1 | ID | 4 | 最大有效值为14,若ID为15则忽略并终止解析。 |
2 | L | 4 | Data长度减一(即: L=len(Data) - 1, 例如0表示Data长度为1)。取值范围 [0,15]。 |
3 | Data | (L+1)*8 | 扩展消息内容。 |
- 单字节模式起始值固定为0xBEDE
- 因为第一版的 rfc5285 定义时间是圣比德节,所以用了BEDE的名字作为标记(the first version of this specification was written on the day of the Venerable Bede)。
- 例如,WebRTC中的AbsoluteSendTime定义如下(一个包的绝对发送时间):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ID | len=2 | absolute send time |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
双字节模式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x10 | 0x00 | length=3 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ID | L=0 | ID | L=1 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data | 0 (pad) | ID | L=4 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
序号 | 名称 | 比特位 | 说明 |
---|---|---|---|
1 | ID | 8 | |
2 | L | 8 | Data长度 L >= 0,0表示后面没有数据 。 |
3 | Data | L*8 | 扩展消息内容。 |
- 双字节模式起始值固定为0x1000
负载数据(Payload)
- 用来承载音视频编码后的媒体数据。
- 负载数据大小通常小于1400,以避免整个RTP报文超过UDP最大MTU(1500)导致网络丢包的问题。
- 负载数据大小:Payload = Size - CSRC - Extensions - Padding(即:负载数据大小 = RTP报文总大小 - CSRC大小 - 扩展报文大小 - 填充数据大小)。
填充数据(Padding)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| padding | Padding size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
序号 | 名称 | 比特位 | 说明 |
---|---|---|---|
1 | Padding(PD) | len*8 | padding,填充的自定义数据,len为自定义的长度 |
2 | Padding Size (PZ) | 8 | padding size,填充的自定义数据大小, 当P设置为1后,PZ值必须大于0。 |
- 填充数据由PD和PZ两部分构成,PZ = PD字节数 + PZ字节数(即:PZ = len(PD) + 1)。
- 填充的数据内容自定义,例如在WebRTC中每隔500毫秒发送一帧PZ为1的空帧作为心跳包。