RTP协议
在实时音视频通话中,我们通常使用 UDP 作为传输层协议,使用 RTP 协议包荷载音视频数据,RTP(Real-time Transport Protocol)是一种在 Internet 上传输多媒体数据的应用层协议,它通常建立在 UDP 之上(也可以建立在 TCP 上)。UDP 协议没有序号等信息,而 RTP 协议可以补充许多音视频传输必要的信息,让音视频数据到达对端后可以重新组合完整,RTP 本身只保证实时数据的传输,并不能提供可靠传输保证,也没有流量控制,拥塞控制机制,它通常与 RTCP 配合使用以提供这些服务。
协议解析
RTP 协议格式如下,红色部分为 RTP 协议可选字段,RTP 协议最小为 12 byte。
RTP固定头部字段介绍
- version (V): 2 bits RTP 协议版本号,固定为2即可
- padding §: 1 bit 填充标识位,如果该位为 1,说明该 RTP 包末尾包含了一个或多个填充字节,最后一个字节的值表示填充的字节数(包含最后一个字节本身),一般在一些需要固定块大小的加密算法中才需要填充
- extension (X): 1 bit 扩展标识位,如果该位为 1,说明有扩展头部信息(Extension header)
- CSRC count (CC): 4 bits 共享媒体源个数,一般用于混音和混屏中,例如某个音频流是混合了其它音频后的数据,那么其它音频源就是该音频源的 CSRC
- marker (M): 1 bit Mark 标记位,对于不同的负载类型有不同含义,例如使用 RTP 荷载 H264 码流时,如果某个帧分成多个包进行传输,可以使用该位标记是否为帧的最后一个包
- payload type (PT): 7 bits 负载包类型,接收端可以根据该信息查找相应的解码器进行解码,Payload Type 值对应的编解码类型请参考 https://www.rfc-editor.org/rfc/rfc3551.html#page-32
- sequence number: 16 bits 序列号,每个 RTP 包序号递增加一,接收端根据序列号可以判断传输是否丢包,序列号初始值是随机的
- timestamp: 32 bits 相对时间戳信息,反映 RTP 数据包数据采样时间,一个帧的数据可能被分成多个 RTP 包发送,同一个帧的时间戳是相同的,不同帧的时间戳是不相同的,该值初始值是随机的,单位的含义与数据采样频率有关
- SSRC: 32 bits 媒体源的标识,不同的 SSRC 标识不同的媒体源,例如不同用户的音频就属于不同的媒体源,具有不同的
- CSRC list: 0 to 15 items, 32 bits each 共享媒体源列表,表示对 RTP 包内载荷起作用的媒体源,参见 CC 解释,CSRC 最多 15 个
扩展头部介绍
现有的RTP数据包头格式可能支持大多数应用程序类所需的公共函数集的完整集,但是还需要满足其他一些需求,有些特定的场合,RTP固定包头的字段内容无法满足,这就需要额外附加信息表征特性,从而RTP定义了扩展头,位于固定头最后。在RFC3550中定义的扩展头格式如下:
If the X bit in the RTP header is one, a variable-length header extension MUST be appended to the RTP header, following the CSRC list if present. The header extension contains a 16-bit length field that counts the number of 32-bit words in the extension, excluding the four-octet extension header (therefore zero is a valid length). Only a single extension can be appended to the RTP data header. To allow multiple interoperating implementations to each experiment independently with different header extensions, or to allow a particular implementation to experiment with more than one type of header extension, the first 16 bits of the header extension are left open for distinguishing identifiers or parameters. The format of these 16 bits is to be defined by the profile specification under which the implementations are operating. This RTP specification does not define any header extensions itself.
从rfc3550这段话中,注意到两点点
- 头扩展包含一个16位的defined by profile字段和16位长度的字段表征扩展头长度,此处的长度是扩展头32位的个数,比如,扩展头长度是8字节,则length=2。
- 两个缺陷
- 首先在每个rtp包中最多只允许一个扩展头;
- 其次,该规范没有提供关于如何分配16位头扩展标识符defined by profile以避免冲突的方案。
在RFC5285中针对以上两个缺陷做出了修改,针对第一个,新协议在单个RTP包中可以有多个扩展头,通过定义URI命名的扩展元素;定义在IETF规范中定义的扩展元素的IANA注册表,以及用于在命名URI和RTP数据包中携带的标识符值之间映射的会话描述协议(SDP)方法,从而消除了第二个缺陷。数据包中的每个扩展元素都具有一个本地标识符(ID)和一个长度。流中存在的本地标识符必须在带外进行协商或定义,每个不同的扩展都必须有一个唯一的ID。值0保留用于填充,不能用作本地标识符。
这些主要是应用不做详细说明,请参考 RTP扩展头这篇博客
RTP应用实践
-
【TCP负载的RTP】
RFC4571 Framing Real-time Transport Protocol (RTP) and RTP Control Protocol (RTCP) Packets over Connection-Oriented Transport规定了基于面向连接传输协议的RTP/RTCP包的封装。
A 16-bit unsigned integer LENGTH field, coded in network byte order (big-endian), begins the frame. If LENGTH is non-zero, an RTP or RTCP packet follows the LENGTH field. The value coded in the LENGTH field MUST equal the number of octets in the RTP or RTCP packet. Zero is a valid value for LENGTH, and it codes the null packet.
GB28181中基于tcp的视频流传输就是根据RFC4571进行规范的 -
【RTSP interleaved frame】
- 背景 某些防火墙或者其他网络环境强制服务器使用同一个连接交替传输RTSP信令与视频流数据。这种交替传输方式应当避免除非有必要。因为它在复杂化客户端与服务端的通信的同时,带来额外的开销。Interleaved binary data SHOULD only be used if RTSP is carried over TCP.
- Stream data such as RTP packets is encapsulated by an ASCII dollar sign (24 hexadecimal), followed by a one-byte channel identifier, followed by the length of the encapsulated binary data as a binary, two-byte integer in network byte order. The stream data follows immediately afterwards, without a CRLF, but including the upper-layer protocol headers. Each $ block contains exactly one upper-layer protocol data unit, e.g., one RTP packet. 简单来说就在LENGTH字段前面又添加了两个字节,第一个字节固定为0x24,第二个字节表示信道id
-
【强制wireshark将UDP包负载解析为RTP】
- RTP/RTCP很少单独使用,一般结合RTSP或者SIP信令来使用,后者负责协商RTP的五元组,前者负责基于协商好的五元组进行音视频流的传输。可以看出RTP的端口并不是固定的,在wireshark解析包的时候,可以根据上下文信息,自动将相关包解析为RTP,但在没有上下文信息缺失的情况,这种自动解析就失效了。
- 选定要解析的包,右击-> Decode as …,在弹出的对话框中,字段与值是包过滤条件,这里是TCP Port为554的包,当前,双机可以选择RTP,选好后确定即可。
持续更新内容如下
- 多种保存RTP负载的方法
- RTP发送H264流
- 多种从RTP包中保存H264流的方式
参考文献
- rfc3550 RTP: A Transport Protocol for Real-Time Applications
- rtfc3551 RTP Profile for Audio and Video Conferences with Minimal Control
- rfc5285 A General Mechanism for RTP Header Extensions
- rfc4571 Framing Real-time Transport Protocol (RTP) and RTP Control Protocol (RTCP) Packets over Connection-Oriented Transport
- rfc2326 Real Time Streaming Protocol (RTSP)
-
- rtp协议解析实战参考 Live555 MultiFramedRTPSource.cpp:296