发布时间:2026-07-21阅读(1)
今天要说的RTP传输协议,有人也认为这是封装格式,因为协议中打包音视频要填写时间戳的相关信息,FFmpeg就把这个作为封装格式。我觉得都没啥问题,不过我更偏向认为是传输协议。
RTP协议即实时传输协议(Real-time Transport Protocol),从字面理解也是和实时传输有关系,协议的初衷是为了实时多人视频会议而设计的,现在应用很广泛。在视频监控、实时直播、语音电话、视频会议都能看到应用。特别是在目前大热的webRTC中将其作为传输协议,国内安防标准GB28181和国际标准ONVIF也是用这个传输音视频。所以在视频监控和实时视频传输还是统治级别的存在,没有啥协议能够进行短期取代,当然这都是由RTP特点决定的。
RTP协议背景:
RTP协议即Real-time Transport Protocol是一种网络传输协议,一般负责音视频数据的封包和传输。其中IETF多媒体小组在1996年的RFC1889就给出了该协议的规范和细节,其后在RFC3550中进行了更新,如果你要系统性学习,直接看RFC3550规范即可。
跟RTSP、RTCP的关系:
RTCP协议:实时传输控制协议即Real-time Transport Control Protocol,这个协议是RTP协议的姊妹协议,它是为了进行服务质量的监视与反馈、媒体间的同步,以及多播组中成员的标识,目前WecRTC用这个协议进行流量和拥塞控制。
RTSP协议:实时流协议即Real Time Streaming Protocol,这是一种会话管理和媒体控制的协议,用的最多地方就是视频监控。视频监控中摄像机、NVR、前后端之间都是用这个协议和RTP协议配合进行流媒体传输。
站在播放器实现角度,理解三者关系,看图:

编辑
添加图片注释,不超过 140 字(可选)
我用一个开源软件通过RTSP的URL拉取了一个大华摄像头的视频。其中大家看到这些开始播放,暂停、快播这些播放按钮背后的功能就需要靠RTSP来支持。看到这个图像视频数据,其实靠的是RTP协议传输过来的。RTCP呢?由于RTP协议大多数情况是不可靠协议,它只管传输音视频数据,但是并不保证这些数据丢了怎么处理,发快了怎么处理,这种数据的可靠性控制需要的RTCP协议来保障的。不过我们今天只讲RTP协议,通过这个讲解相信你能有个感官认识。
站在网络层次模型的角度,同样看图:

编辑
添加图片注释,不超过 140 字(可选)
其中RTSP协议就和HTTP协议一样,属于应用层协议,一般传输层靠的是TCP传输。其实本身的语法和HTTP协议都非常相似,后面文章会详细讲解。
RTP协议既可以理解为传输层也可以理解为应用层,这么说是因为RTP负载可以放到RTSP上进行传输,通过二元交织通道方式实现。也可以下层放到TCP进行承载,不过大多数情况RTP的负载协议是UDP,如果放到TCP上大大降低了RTP协议的实时性。之所以设计RTP协议,就是因为为了规避TCP协议的一些缺点,因为TCP协议在操作系统的协议栈上实现了流量和拥塞控制等机制,但是TCP并没有考虑传输视频的情况,它是针对传输任何数据更通用的做法,但是结合流媒体传输的特点,我们发现UDP更适合传输,所以我们把保证传输速度即快又正确这件事交给了上层的RTP和RTCP协议,这样我们开发者是可以来实现和控制这两种协议的,这样就为解决音视频低延时等场景提供了可能。
给个实例看下,上图:

编辑切换为居中
添加图片注释,不超过 140 字(可选)
RTP协议原理:
1.发送地址的确定:
上面说了RTP协议是发送端传输流媒体数据的,但是往那个IP和端口传输,如何将自己传输的音视频属性告诉给接收端就需要一种机制来实现,常见的做法就是用SDP进行描述,然后通过RTSP、SIP或者HTTP等协议和接收端协商。一般在协商过程中,会确定发送端RTP和RTCP的目的地址,目的地址由一个IP地址和端口对组成,偶数端口就是RTP媒体流的目的端口,偶数端口 1就是RTCP协议的目的端口,其中RTSP协议传输端口的确定就是通过SetUP方法,看下图:

2.RTP数据包的生成:
通过RTSP等协议的SDP信息协商好了RTP数据包的发送目的和传输方式,我们就需要把音视频数据打包成RTP包,用UDP发送给接收端了。RTP不仅可以用来传视频,也可以传音频,甚至可以传输图像和非音视频数据。传输视频不仅可以传输H264编码的数据,也可以传输H265,同样可以传输谷歌的VP8 VP9系列编码的视频裸数据。音频可以传输G7xx系列、AAC系列。那封装好的数据可以传输吗,也是可以的。其中安防中常说的国标流就是RTP PS形式,也可以传输RTP TS数据;
相关视频推荐
音视频开发基础知识到进阶剖析_哔哩哔哩_bilibili
音视频面试必问-RTSP/RTMP推流的各种坑分析_哔哩哔哩_bilibili
学习地址:【免费】FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发-学习视频教程-腾讯课堂
需要更多ffmpeg/webrtc..音视频流媒体开发学习资料加群812855908领取

3. RTP的灵活性:
之所以看到RTP协议应用场景广,传输的数据格式多,主要是因为RTP协议设计简单,有时少即是多。RTP协议把很多控制权交给了上层应用者,许多字段也是允许用户自己协商和确定,这样RTP协议的生命力和适应性就强很多。下面分析RTP格式和通过一个示例来看下RTP数据包格式。
RTP数据包格式:
RTP固定头:
RTP的数据包由RTP Header RTP Playload组成。其中RTP固定头如下图所示:

各个字段的解释:
1. V:当前的协议的版本号是2,其中0和1已经在草案规范中被占用,这里基本就是固定值了;
2. P:填充标记,包的末尾包含了一个或者多个填充字节,其中填充字节的第一字节包括了后面填充字节的长度,该长度字段包含自己,主要是为了一些对齐处理;
3. X位,如果为1则说明有扩展头,一般默认为0,很少有场景会用到;
4. CC位:是为了计算后面有多少个CSRC,四位说明则最大支持15个CSRC,一般默认为0。
5. M位:特别对于视频而言就是一帧的结束,视频帧比较大,需要通过多个NALU来传输,当看到M位为1时就认为是这个I帧的结束,由于音频帧比较小,一个RTP包就是一个音频帧,所以该位直接置1。
6. Sequence number序列号:16位,用于标识发送者发送的RTP报文序列号,每发送一个RTP包,则这里就增加1,当达到最大值后,则重新从0开始。刚才说了一般RTP协议是承载协议是UDP,UDP是不可靠传输协议。那我们如何保证接收端收的数据是正确的呢,就是通过这个字段进行重新排序,所以接收端一般收到RTP数据第一件事就是排序。
特别注意两点:
a. 这个序列号的初始值可以为0但是也可以为其它随机值,只要符合 1就行;
b. b.发送端的音频和视频都是通过RTP传输的,但是他们是分别计数的,所用的序列号是不同的。
7. timestamp时间戳:占32位四字节,这个单位要注意是采样率到倒数,不是真实的时间,一般要根据采样率进行换算。这里反应的RTP报文第一个八位组的采样时刻,目的是为了接收端计算延迟、抖动和音视频同步。需要说明的是,一个视频帧的时间戳是相同的,但是一个视频帧数据量很大可能需要多个RTP包传输,这样就存在多个RTP包时间戳相同的情况,音频帧数据小,不存在音频帧跨RTP的情况,所以不存在这个问题。
8. SSR同步信号源:占32位四字节,用于标识同步信号源,这个值只要保证在一路音视频会话里面值不相同即可。该标识符是随机选取的 RFC1889推荐了MD5随机算法。该值的作用就是在会话中标识RTP负载流的身份,给一个唯一标记值。
9. CSRC特约信号源CSRC:同样是32位,四字节。一个RTP头最多可以含有0-15个,如果是1对1的流媒体传输,这个字段就不用处理,直接忽略该字段。但是混流和混音时,则需要把各方的RTP同步信号源列出来,这样接收端就能正确指出交谈双方的身份。
RTP扩展头解析:
RTP提供了扩展机制以实现个性化:某些新的负载格式独立的功能要求的附加信息可以允许放到RTP数据包头的扩展部分进行传输,基本的RT并不定义任何扩展头本身。
我的理解就是为了给RTP传输协议增加一些扩展性,防止未来一些新功能的加入,同时允许用户增加一些私有信息和私有功能在里面,大部分音视频场景都没有启用RTP扩展部分,但是也有例外。在WebRTC中看到利用RTP扩展部分做了FEC(前向纠错,核心思想就是一些异或运算)的算法处理,这样当发生RTP丢包可以通过扩展快速恢复丢包,在网络不好的时候特别有用。如果你对这部分很了解,可以微信后台私信我一起探讨下。
扩展头格式:

字段说明:
扩展字段定义define by profile:16bit两字节,这个由上层的具体实现协议来决定;
扩展头长度length:表示扩展头的长度字段,16bit即2字节,最大扩展长度1024字节;
注意:
如果要启用扩展头,固定头的扩展标记X置1,负载类型playload需要按照规范定义,扩展头字段的长度可以为0,因为不包括头字段的4字节,最大1024.
H264打包RTP的方法:
上面已经交代了,RTP的特点不仅仅支持承载在UDP上,这样利于低延迟音视频数据的传输,另外一个特点是它允许通过其它协议接收端和发送端协商音视频数据的封装和编解码格式,这样固定头的playload type字段就比较灵活。截止目前为止,RTP是我见过传输音视频数据类型最多的,具体参考:https://en.wikipedia.org/wiki/RTP_payload_formats。
今天我以H264裸码流NALU为例,给大家讲述下如何进行H264的打包,这也是我上面几篇封装格式讲解的固定套路,其中H264打包的详细方法要参考RFC6184文档。

H.264标准协议定义了两种不同的类型:一种是VCL即Video Coding Layer,一种是NAL即Network Abstraction Layer。其中前者就是编码器吐出来的原始编码数据,没有考虑传输和存储问题。后面这种就是为了展现H.264的网络亲和性,对VCL输出的slice片数据进行了封装为NALUs(NAL Units),然后再封装为RTP包进行传输,这些都是H.264的基础。
NALU的基本格式是:NALU Header NALU Data,其中NALU的头由一个字节组成如下所示:
-----------------
|0|1|2 |3|4|5|6|7|
- - --- - - -
|F| NRI |Type|
-----------------
Copyright © 2024 有趣生活 All Rights Reserve吉ICP备19000289号-5 TXT地图HTML地图XML地图