😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍RTP协议🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
⏰发布时间⏰: 2025-06-19 18:41:25
本文未经允许,不得转发!!!
目录
🎄一、概述
RTP
协议,全称是Real-time Transport Protocol
(实时传输协议)。RTP协议地主要作用时,为实时音视频流(如视频会议、直播、VoIP)提供端到端的传输服务,解决传统TCP/UDP
在实时性、丢包容忍性上的不足。
设计原则:
- 低延迟:优先传输最新数据,允许丢包。
- 时序同步:通过时间戳和序列号重建时序。
- 可扩展性:支持头部扩展和负载格式自定义。
- 控制与反馈:依赖
RTCP
(RTP Control Protocol)监控网络状态。
根据传输层协议区分,可分为两种方式:①RTP_OVER_UDP
(通过UDP协议传输RTP包);②RTP_OVER_TCP
(通过TCP协议传输RTP包)。
🎄二、RTP协议相关的官方文档
✨2.1、核心协议
RFC 3550
“RTP: A Transport Protocol for Real-Time Applications”
定义了 RTP 和 RTCP(RTP 控制协议)的核心规范,包括数据包格式、时间戳、序列号、负载类型标识和拥塞控制基础。RFC 3551
“RTP Profile for Audio and Video Conferences with Minimal Control”
定义了音视频会议场景下的 RTP 标准配置(Profile),如默认的编解码类型(如 PCMU、GSM)和 RTCP 报告间隔。
✨2.2、RTP 控制协议(RTCP)扩展
RFC 4585
“Extended RTP Profile for RTCP-Based Feedback”
扩展了 RTCP 的反馈机制,支持重传请求(NACK)和拥塞控制反馈(如 PLI、FIR)。RFC 5104
“Codec Control Messages in RTCP”
定义了编解码器控制反馈(如 TMMBR/TMMBN),用于动态调整媒体流的带宽和分辨率。RFC 5760
“RTCP Extensions for Single-Source Multicast Sessions”
支持单源组播(SSM)场景下的 RTCP 扩展。
✨2.3、负载格式(Payload Formats)
H.264 视频:RFC 6184
H.265 视频:RFC7798:RTP Payload Format for High Efficiency Video Coding (HEVC)
AAC 音频:RFC3640:RTP Payload Format for Transport of MPEG-4 Elementary Streams
VP8/VP9 视频:RFC 7741
Opus 音频:RFC 7587
G.711 音频:RFC 3551
MPEG Audio:RFC 2250
文本(如字幕):RFC 4103
✨2.4、安全扩展
RFC 3711
“Secure Real-Time Transport Protocol (SRTP)”
定义 SRTP,提供 RTP 流的加密、认证和防重放攻击保护。RFC 7741
“RTP Header Extension for Client-to-Mixer Audio Level”
扩展头部字段,支持安全传输音频电平信息。
✨2.5、配置与扩展头
RFC 5285
“A General Mechanism for RTP Header Extensions”
允许在 RTP 头部添加自定义扩展字段(如视频旋转、网络状态标识)。RFC 6051
“RTP Timestamp Frequency for Variable Rate Audio”
定义动态调整时间戳频率的机制,适应可变比特率编解码器。
✨2.6、传输与拥塞控制
RFC 5506
“Support for Reduced-Size RTCP”
允许更小的 RTCP 数据包,适用于低带宽场景。RFC 8083
“RTP Congestion Control: Guidelines”
提供 RTP 流拥塞控制的最佳实践。
✨2.7、多路复用与 WebRTC
RFC 8834
“Media Transport and Use of RTP in WebRTC”
规范 WebRTC 中 RTP/RTCP 的使用,包括多路复用和 ICE 集成。RFC 8850
“SDP: Grouping for Media Streams”
定义 SDP 中媒体流的多路复用规则。
🎄三、RTP 封包机制
RTP封包机制主要在 RFC 3550 文档介绍,整个RTP数据包分为RTP固定头(RTP Fixed Header
)、RTP拓展头(RTP Header Extension
)、RTP负载(RTP Payload
)。
✨3.1、RTP固定头(RTP Fixed Header)
下面是 RFC 3550
文档中关于RTP数据包的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 |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
整个RTP固定头总共是12
个字节,其中CSRC列表
是可选的,各个字段解析如下:
字段名称 | 长度(bit) | 描述 |
---|---|---|
V (Version) |
2 | 版本号,当前版本为2。 |
P (Padding) |
1 | 填充标志,为1则在该RTP尾部填充一个或多个额外的8bit数据。 |
X (Extension) |
1 | 扩展标志,为1则表示在该RTP Header后面跟随一个扩展头。 |
CC (CSRC count) |
4 | CSRC计数器,表示CSRC的个数。 |
M (Marker) |
1 | 标识,视频与音频包中该值具有不同的含义。 为视频包时,该值为1则表示视频一帧的结束(该包是当前帧的最后一个RTP包); 为音频包时,该值为1则表示音频会话的开始; |
PT (Payload Type) |
7 | 负载类型,表示RTP包中的媒体文件类型,该值的定义在RFC3551 中。由于H264、H265、AAC编码标准出现的较晚,没有出现在 RFC3551 的详细定义中,通常使用96-127(动态序号),如H264的PT使用96,PT值通常在RTSP信令SDP中指定。 |
sequence number |
16 | 当前包的序列号,每次封装(发送)一个RTP包该值加一; 可以被接收方用来检测数据包丢失和恢复数据包顺序; |
timestamp |
32 | 时间戳,表示当前数据的采样时刻;同一个帧,不同RTP包的时间戳应该相同.。 RTP包为视频时候时间戳的基准则为 90KH (90000)。RTP包为音频则通常按照 音频采样率 为时间基准。时间基准通常在RTSP信令SDP中指定; 当传输的音视频帧是按照固定周期生成(固定帧率),则时间戳 采用累加的时间 ,而不是获取系统时间,如视频固定帧率25帧,则时间戳的增量为90000/25=3600,第一帧时间戳采用系统时间或者随机时间,第二帧时间戳则在第一帧的基础上加3600。 |
SSRC |
32 | 同步信源标识符,标识RTP数据流的唯一来源;在同一个RTP会话中不会出现两个相同SSRC标识符的信源; |
CSRC列表 |
32/个 | 提供信源标识符列表,一共可以包含最大16(0~15)个提供信源标识符; 每个CSRC标识了包含在当前RTP报文有效载荷中的所有提供信源; 例如音频(混音器)RTP混合了不同的同步信源RTP包后,经过混合后产生一个新的组合RTP包, 并产生新的混合RTP包的SSRC,将原来所有的SSRC都作为CSRC传送给接收者, 让接受者知道组成组合RTP包的所有SSRC; |
✨3.2、RTP拓展头(RTP Header Extension)
下面是 RFC 3550
文档中关于RTP数据包的 RTP拓展头 结构的介绍:
当 RTP固定头 中的X
字段为1时,则需要在 RTP固定头 后添加 RTP扩展头 ;RTP扩展头定义如下;至少包含32bit。
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 |
| .... |
字段名称 | 长度(bit) | 描述 |
---|---|---|
defined by profile |
16 | 表示扩展数据类型,通常自定义。 |
length |
16 | 扩展数据长度,不包含defined by profile和length所占用大小。占用16bit大小; |
header extension |
≥ 0 | 扩展数据内容,可以为空,即大小最小可以为0。 |
✨3.3、RTP负载(RTP Payload)
RTP包的负载一般都是音视频流数据,包括但不限于H264、H265、AAC等格式的数据。而不同类型的负载数据在RTP封包时也存在不同的处理方式,下面是常见的几个音视频格式的RTP负载格式封包相关的文档,可以了解一下,我们将在下个小节简单介绍:
- H.264 视频:RFC 6184:RTP Payload Format for H.264 Video
- H.265 视频:RFC7798:RTP Payload Format for High Efficiency Video Coding (HEVC)
- AAC 音频:RFC3640:RTP Payload Format for Transport of MPEG-4 Elementary Streams
🎄四、常见的RTP负载封包格式
这个小节主要介绍 常见的RTP负载封包格式,常见的有 H.264、AAC,目前先介绍这两个,其他的后续用到再添加。
✨4.1、RTP封包 H.264 格式
下面会涉及到一些H264的知识,不清楚的可以参考这篇文章:H.264视频编码及NALU详解 。
H.264 视频码流一般有开始码(00 00 01
或 00 00 00 01
)将每个NAL单元(NAL Unit)分割开,进行RTP封包时,需要将这个开始码去掉,只保留NALU。
H.264 视频的RTP封包相关文档可以看这个:RFC 6184:RTP Payload Format for H.264 Video 。主要分为三类封包:
- ①单个NAL单元封包(
Single NAL Unit Packet
):仅包含一个NAL单元在有效载荷中。NAL头类型字段等于原始NAL单元类型,即在1到23的范围内(包括1和23)。
注意: 每个H.264的NAL Unit 都有一个字节大小的NAL头(NAL Header),如下:
如果RTP包使用 单个NAL单元封包(Single NAL Unit Packet
) 的方式,这个NAL头可以直接作为RTP负载数据的第一个字节,下面是 单个NAL单元封包的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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |F|NRI| Type | | +-+-+-+-+-+-+-+-+ | | | | Bytes 2..n of a single NAL unit | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | :...OPTIONAL RTP padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ②聚合封包(
Aggregation Packet
):用于将多个NAL单元聚合到单个RTP有效载荷中的数据包类型。此数据包存在四种版本,即单一时间聚合数据包类型A(STAP-A)、单一时间聚合数据包类型B(STAP-B)、多个时间聚合数据包(MTAP)带16位偏移量(MTAP16),以及 多个时间聚合数据包(MTAP)带24位偏移量(MTAP24)。为STAP-A、STAP-B、MTAP16和MTAP24分配的NAL单元类型编号分别为24、25、26和27。
聚合封包(Aggregation Packet
)比较少用,感兴趣的同学可以看看RFC6184
的5.7. Aggregation Packets
。 - ③分片单元(
Fragmentation Unit
);用于将单个NAL单元分割成多个RTP数据包。存在两个版本,FU-A和FU-B,分别用NAL单元类型编号28和29标识。常用的是FU-A,下面也只介绍FU-A格式的封包,第一个字节是FU indicator
,第二个字节是FU header
,第三个字节开始就是NAL单元去掉NAL头之后的数据: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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | FU indicator | FU header | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | FU payload | | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | :...OPTIONAL RTP padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
FU indicator
:FU indicator
的大小是一个字节,格式如下,跟NAL头的格式一样,但作为 分片RTP封包 ,并不能直接将H264的NAL头直接填上去。
F
:一般为0。为0表示此NAL单元不应包含bit错误或语法违规;为1表示此NAL单元可能包含bit错误或语法违规;
NRI
:直接将H264NAL头的NRI值填入即可;
Type
:FU-A格式的封包填28
,FU-B格式的封包填29。+---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |F|NRI| Type | +---------------+
FU header
:FU header
的大小也是一个字节,格式如下:
S
:start,NALU拆分多个分包后,第一个发送的分包,此bit位置1,其他分包为0;
E
:end,NALU拆分多个分包后,最后一个发送的分包,此bit位置1,其他分包为0;
R
:保留位,必须等于0;
Type
:将H264的NAL头的负载类型Type直接填入。+---------------+ |0|1|2|3|4|5|6|7| +-+-+-+-+-+-+-+-+ |S|E|R| Type | +---------------+
关于H264的RTP封包格式就先介绍上面这些了,后续按需添加。
✨4.2、RTP封包 AAC 格式
RTP封装AAC的协议采用MPEG-4格式的封装协议,AAC封装成RTP的官方文档可以参考这个:RFC 3640:RTP Payload Format for Transport of MPEG-4 Elementary Streams 。
AAC的RTP封包结构如下图,RTP Header
就是前面第3节介绍的RTP头,负载(RTP Packet Payload)分为三部分:
1、AU Header Section
是AU(访问单元,Access Unit)头部部分,包含一个或多个AU头部,也可以没有AU头部的部分;
2、Auxiliary Section
是一些辅助信息,这个部分也可以配置为空,实际上基本不用;
3、Access Unit Data Section
是访问单元数据部分,包含一个访问单元的单个片段或一个或多个完整的访问单元。访问单元数据部分不得为空。:
因为 Auxiliary Section
基本用不到,本文就不介绍了,而Access Unit Data Section
部分对于AAC来说就是ADTS帧去掉ADTS头部之后的数据,也无须过多介绍。对于AAC格式不熟的可以看这篇文章:AAC格式音频文件解析 。下面主要介绍 AU Header Section
。
如果一个RTP负载有AU头部部分(AU Header Section
),那么AU头部部分由AU-header-length
字段组成,后面跟着若干个AU-header
,如下图:
AU-headers-length
:是一个2字节字段,它指定紧接其后的所有AU-header
总共占用多少个比特位(bit)。
AU Header
:AU Header
的个数和大小在不同的负载会有所不同,本文介绍的是 High Bit-rate AAC 类型的 AAC 负载,详细介绍可点击链接去看原文。High Bit-rate AAC
的AAC负载的AU Header
是一个2字节的字段,其中13bit
用来表示其后的AAC帧总大小,3bit
表示AU-Index(-delta) field
。
所以,AAC的常见的RTP封包如下所示:
①12个字节的RTP头;
②2个字节的AU头长度(AU-headers-length);
③13bit的AU size
;
④3bit的AU-Index(-delta) field
0 1 2 3
7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| AU-headers-length | AU-size |AU-I |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: AAC Frame (Access Unit) :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
AAC的RTP负载封装代码,可以参考这个:
rtpPacket->payload[0] = 0x00;
rtpPacket->payload[1] = 0x10;
rtpPacket->payload[2] = (frameSize & 0x1FE0) >> 5; // 高8位
rtpPacket->payload[3] = (frameSize & 0x1F) << 3; // 低5位
memcpy(rtpPacket->payload + 4, frame, frameSize);
🎄五、总结
本文介绍了RTP协议的相关协议,RTP数据包格式,H264的RTP封包、AAC的RTP封包格式 等
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁