RTSP系列三:RTP协议介绍

news2024/11/14 23:01:05

RTSP系列:

        RTSP系列一:RTSP协议介绍-CSDN博客

        RTSP系列二:RTSP协议鉴权-CSDN博客 

        RTSP系列三:RTP协议介绍-CSDN博客 

        RTSP系列四:RTSP Server/Client实战项目-CSDN博客 

目录

一、基本概念

二、RTP报文格式

三、RTP封装视频

3.1、RTP封装H264

3.1.1、单一封包模式

3.1.2、组合封包模式

3.1.3、​分片封包模式

3.1.4、RTP抓包分析

3.2、RTP封装H265

四、RTP封装音频

4.1、RTP封装AAC

4.2、RTP打包PCMA

五、RTP扩展头部


一、基本概念

        一种数据数据传输协议,RTP 协议实际上是由实时传输协议RTP(Real-time Transport Protocol)和实时传输控制协议RTCP(Real-time Transport Control Protocol)两部分组成。

        RTP 协议基于多播或单播网络为用户提供连续媒体数据的实时传输服务;RTCP 协议是RTP 协议的控制部分,用于实时监控数据传输质量,为系统提供拥塞控制和流控制。 由于TCP 需要较多的开销,故不太适合传输实时数据。在流式传输的实现方案中,一般采用RTSP/TCP 来传输控制信息,而用RTP/UDP 来传输实时声音数据(也可以用RTP/TCP)。RTP也属于应用层协议,与RTSP的关系如下图所示:

        RTP传输音视频过程如下:

二、RTP报文格式

        RTP报文格式如下:

*版本号(V):2比特,用来标志使用的RTP版本。

*填充位(P):1比特,如果该位置位,则该RTP包的尾部就包含附加的填充字节。

*扩展位(X):1比特,如果该位置位的话,RTP固定头部后面就跟有一个扩展头部。

*CSRC计数器(CC):4比特,含有固定头部后面跟着的CSRC的数目。

*标记位(M):1比特,该位的解释由配置文档(Profile)来承担.

*载荷类型(PT):7比特,标识了RTP载荷的类型。

*序列号(SN):16比特,发送方在每发送完一个RTP包后就将该域的值增加1,接收方可以由该域检测包的丢失及恢复包序列。序列号的初始值是随机的。

*时间戳:32比特,记录了该包中数据的第一个字节的采样时刻。在一次会话开始时,时间戳初始化成一个初始值。即使在没有信号发送时,时间戳的数值也要随时间而不断地增加(时间在流逝嘛)。时间戳是去除抖动和实现同步不可缺少的。

*同步源标识符(SSRC):32比特,同步源就是指RTP包流的来源。在同一个RTP会话中不能有两个相同的SSRC值。该标识符是随机选取的 RFC1889推荐了MD5随机算法。

*贡献源列表(CSRC List):0~15项,每项32比特,用来标志对一个RTP混合器产生的新包有贡献的所有RTP包的源。由混合器将这些有贡献的SSRC标识符插入表中。SSRC标识符都被列出来,以便接收端能正确指出交谈双方的身份。

符号位数定义数值
V2bit版本号2
P1bit填充位0
X1bit扩展位0
CC4bitCSRC数目0
M1bit标志位当RTP负载是一个完整的NALU时M 位置为 1;当前RTP 数据包为一个NALU 的最后的那个分片时(NALU 的分片在后面讲述),M位置 1。其余情况下M位保持为 0。
PT7bit载荷类型 负载类型(音视频负载,类型在SDP中描述)
SeqNum16bit序列号每发一个包加1
Timestamp32bit时间戳单一封包 +采样率,h264为3600; 分片封包第一个加采样率,后续不变
SSRC32bit同步源标识任意指定,标准是一个MD5算法值,未明
CSRC0bit贡献源列表CC为0,所以此项没有

一个RTP数据包定义如下:

三、RTP封装视频

3.1、RTP封装H264

        首先看一下H264 NALU头部定义:

  +---------------+
  |0|1|2|3|4|5|6|7|
  +-+-+-+-+-+-+-+-+
  |F|NRI|  Type   |
  +---------------+
F: 1 个比特. 一般为0 forbidden_zero_bit. 在 H.264 规范中规定了这一位必须为 0.
NRI: 2 个比特. nal_ref_idc. 取 00 ~ 11, 指示nalu单元的重要性,, 如 00 的 NALU 解码器可以丢弃而不影响图像的回放. 不过一般情况下不太关心这个属性.
Type: 5 个比特.nal_unit_type. 这个 NALU 单元的类型.

 

        RTP打包原则

        RTP的包长度必须要小于MTU(最大传输单元),IP协议中MTU的最大长度为1500字节。除去IP报头(20字节)、UDP报头(8字节)、RTP头(12字节),所有RTP有效载荷(即NALU内容)的长度不得超过1460字节。TCP(20字节)

        RTP有三种封包模式:单一封包模式,组合封包模式,分片封包模式

3.1.1、单一封包模式

        对于 NALU 的长度小于 MTU 大小的包, 一般采用单一 NAL 单元模式。对于一个原始的 H.264 NALU 单元打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码, 把其他数据封包的 RTP 包即可.

        如有一个 H.264 的 NALU 是这样的:

        [00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]

        这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是 NALU 内容.

        封装成 RTP 包将如下:

        [ RTP Header ] [ 67 42 A0 1E 23 56 0E 2F ]

        即只要去掉 4 个字节的开始码就可以了。

3.1.2、组合封包模式

         当 NALU 的长度特别小时, 可以把几个 NALU 单元封在一个 RTP 包中.这里只介绍STAP-A模式

        如有一个 H.264 的 NALU 是这样的:

        [00 00 00 01 67 42 A0 1E 23 56 0E 2F ... ]

        [00 00 00 01 68 42 B0 12 58 6A D4 FF ... ]

        封装成 RTP 包将如下:

        [ RTP Header ] [78 (STAP-A头,占用1个字节)] [第一个NALU长度 (占用两个字节)] [ 67 42 A0 1E 23 56 0E 2F ] [第二个NALU长度 (占用两个字节)] [68 42 B0 12 58 6A D4 FF ... ]

3.1.3、​分片封包模式

         当NALU的长度超过MTU时,就必须对NALU单元进行分片封包.也称为Fragmentation Units(FUs).

        高三位--F、NRI:与NALU第一个字节的高三位相同--F、NRI, Type:28

        S:标记该分片打包的第一个RTP包  E:该分片打包的最后一个RTP包Type:NALU的Type

        FU payload就是去掉起始码和头部的NALU。

3.1.4、RTP抓包分析

        RTP封包常用的就是单一封包模式和分片模式,组合封包模式几乎不用。

        RTP,序列号-每发送一个数据包就+1,时间戳--SPS/PPS时间戳不变、属于同一NALU的分片数据包时间戳不变,其余时间戳+90000/25

        SDP(会话协议)文件描述和视频封包的关联:

m=video 49170 RTP/AVP 98

a=rtpmap:98 H264/90000

a=fmtp:98;profile-level-id=42A01E;packetization-mode=1;sprop-parameter-sets=Z0IACpZTBYmI,aMljiA==

packetization-mode:  表示支持的封包模式.

当 packetization-mode 的值为 0 时或不存在时, 必须使用单一 NALU 单元模式.

当 packetization-mode 的值为 1 时必须使用非交错(non-interleaved)封包模式.

当 packetization-mode 的值为 2 时必须使用交错(interleaved)封包模式.

        回顾H264类型:

        0     没有定义

        1-23  NAL单元  单个 NAL 单元包

        24    STAP-A   单一时间的组合包

        25    STAP-B   单一时间的组合包

        26    MTAP16   多个时间的组合包

        27    MTAP24   多个时间的组合包

        28    FU-A     分片的单元

        29    FU-B     分片的单元

        30-31 没有定义

        h264仅用1-23,24以后的用在RTP H264负载类型头中

        如下表所示,每个打包方式允许的NAL单元类型总结(yes = 允许, no = 不允许, ig = 忽略)

TypePacketSingle NAL Unit ModeNon-Interleaved ModeInterleaved Mode
0undefinedigigig
1-23NAL unit yesyesno
24STAP-Anoyesno
25STAP-Bnono yes
26MTAP16nono yes
27MTAP24nono yes
28FU-Anoyesyes
29FU-Bnonoyes
30-31undefinedigigig

        用wireshark抓取的RTP数据包如下所示:

3.2、RTP封装H265

        首先看一下H265 NALU头部定义:

F: 1 bit. forbidden_zero_bit. 265要求是0,是1的话指示语法违规等.
Type: 6 bits. Nal类型. vps是32, sps是33, pps是34, 前缀sei是39. IDR是19和20.
LayerId: 6 bits. nuh_layer_id. 现在是0,将来可能扩展用.
TID: 3 bits. nuh_temporal_id_plus1. TemporalId 是TID-1.

        H265和H264打包模式类似,都是单一封包或分片封包。单一封包和H264完全一样,分片封包略有不同,如下图所示,为H265分片封包格式。

PayloadHdr还是拷贝NAL单元头,但是要把Type换成49。FU header 就一个字节,格式如下:

在这里插入图片描述

S:为1表示第一个分片。 E:为1表示表示最后一个分片。FuType就是实际的Nal type类型。

四、RTP封装音频

4.1、RTP封装AAC

         RTP封装AAC部分参考:RFC3640中对AAC进行RTP打包方式介绍-CSDN博客

        AU概念:在audio stream中就是一个audio frame。

        一个rtp包携带一个AU
        对应音频数据,就是携带一个audio frame

        一个rtp包中携带多个AU
        一个编码后的audio frame通常是比较小的(通常是100~300的字节),一个rtp(通常是1000个字节以上)通常是可以携带多个audio frame

        一个rtp包中可携带一个AU的片段
        多个rtp包携带一个AU,类似RTP打包的H264/265 FU-A模式,这种情况是针对视频等大数据量的码流。对音频来说,是不会出现这种情况的。

        RTP封装AAC格式如下:

        这里要注意的是,这些字段并不是固定出现的字段(按需携带,可有可无),所以码流结构图描述只是字段的名字,并没有给出字段的位数(位数也是可变的)。这个跟常见的码流结构定义不一样,比如rtp for h264/h265 rfc中,对字段名和位数都进行详细的规定。一个RTP包中可能包含多个AU,多个AU的头信息都被集中放在AU Header Section中。AU Header Section中有几个头信息则有几个AU。

        下面逐一对字段意思进行解释。

        AU Header Section
        下图是其结构图,其中包含的字段也是可变的(字段可有可无,长度可变)

        AU Header Section = AU-Headers-lengths + AU-header + Padding Bit

        AU-header 可以有0~n个,AU-Headers-lengths为0个时则整个AU Header Section都不会携带。一个AU-header对应一个AU,AU-header中包含对应AU解码所需的一些参数信息。

        AU-Headers-Lengths 固定的两个字节的长度,表示AU-Headers的总长度(单位是位),所以AU-Headers所占的字节数=AU-Headers-Lengths/8

        Padding Bits: 所有的Au-Header的总长度必须是整数个字节,如果不够则添加Padding Bit

        AU-header定义如下:

        如上图所示为AU-header的结构及字段意义,AU-Size,AU-Index,AU-Index-delta为固定字段,其余的几个字段都是码流的参数信息,这些字段都是按需出现的如果MIME format parameter中携带了对应的属性说明(SDP中),则就存在对应的字段

  • AU-size:就是整个数据帧的长度
  • AU-Index: Indicates the serial number of the associated Access Unit
  • AU-Index-delta:就是AU-Index

        关于AU-Index和AU-Index-delta,用在AU fragement(或interleaving模式)情况下,RTP payload携带的是AU的分片,那么AU-Index/AU-Index-delta就是标识分片的顺序(以加1递增)。那么除此之外,AU携带一个可解码的完整的audio frame时,AU-Index/AU-Index-delta填0即可)

SDP和AAC的关联

        打包AAC
        通过RTP打包AAC,需要结合一种协议携带Format Parameters。最常用的是sdp,rfc 3640定义了一些具体模式的约束。这里我们主要是关心携带AAC的情况。

        在 section 3.3.5和3.3.6分别描述了 Low Bit-rate AAC 和 High Bit-rate AAC sdp所应携带的信息

  • Low Bit-rate AAC

rfc中给出如下约束:

1.The maximum size of an AAC frame in this mode is 63 octets(AAC帧的最大长度是63个字节)
2.AAC frames MUST NOT be fragmented when using this mode(这种模式下不可携带AAC 帧片段)

        sdp携带参数信息的例子:

m=audio 49230 RTP/AVP 96
a=rtpmap:96 mpeg4-generic/22050/1
a=fmtp:96 streamtype=5; profile-level-id=14; mode=AAC-lbr; config=
1388; sizeLength=6; indexLength=2; indexDeltaLength=2;
constantDuration=1024; maxDisplacement=5
  • High Bit-rate AAC

        这种模式下AAC frame的长度有约束,最大长度为8191个字节(音频数据不会有这么大)

        sdp携带参数信息的例子

m=audio 49230 RTP/AVP 96
a=rtpmap:96 mpeg4-generic/48000/6
a=fmtp:96 streamtype=5; profile-level-id=16; mode=AAC-hbr;
config=11B0; sizeLength=13; indexLength=3;
indexDeltaLength=3; constantDuration=1024

        这两种模式的区别就是AAC Frame的大小限制。是用Low Bit-rate模式还是High Bit-rate模式,取决于AAC的编码格式。sizeLength,indexLength,indexDeltaLength,这3个属性值分别描述的是AU-header中AU-size,AU-index,AU-index-delta字段所占的字节数。是一定会携带的,
其它属性则是跟码流的参数相关的,比如config等。对于AAC config是一定要带的,这是有音频的采样率、通道数、编码级别按照一定格式编码而成的。

4.2、RTP打包PCMA

        RTP打包PCMA相对简单,RTP payload就是PCMA的一帧数据。

五、RTP扩展头部

        RTP扩展头参考:RTP包头扩展_rtp 扩展字段-CSDN博客

        如果RTP Header中X字段为1,说明后面跟着RTP Header Extension。RTP Header Extension结构如下:

  • defined by profile:决定使用哪种Header Extension:one-byte或者two-byte header
  • length:表示Header Extension的长度:length x 4字节

        如果不关心扩展头部,解析出length就可以把扩展头部跳过,解析RTP payload获取音视频了。

        One-Byte Header

        对于One-Byte Header,"defined by profile"字段为固定的0xBEDE。接着后面的结构如下:

  • ID:4-bit长度的ID表示本地标识符
  • len:表示extension data长度,范围:0~15,为0表示长度为1字节,15表示16字节

        RTP扩展头示例:

        首先是0xBEDE固定字段开头,接着length长度为3,说明后面跟着3x4字节长度的header extension 。对于第一个header extension:L=0,表示data长度为1字节。对于第二个header extension:L=1,表示data长度为2字节。由于按4字节对齐,所以接着是值为0的填充数据。最后一个header extension:L=3,表示data长度为4字节。

        Two-Byte Header 

        首先"defined by profile"字段为0x1000,length为3,后面跟着3x4字节长度扩展,对于第一个header extension:L=0,数据长度为0,对于第二个header extension:L=1,data长度为1,接着是填充数据,对于第三个header extension:L=4,后面跟着4字节长度数据。

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1981386.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码随想录训练营 Day21打卡 二叉树 part08 669. 修剪二叉搜索树 108. 将有序数组转换为二叉搜索树 538. 把二叉搜索树转换为累加树

代码随想录训练营 Day21打卡 二叉树 part08 一、 力扣669. 修剪二叉搜索树 给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 …

密码学基础:搞懂Hash函数SHA1、SHA-2、SHA3(2)

目录 1.引入 2. SHA512-224\256 3.SHA-3 4.MD5 5.SM3 1.引入 上篇密码学基础:搞懂Hash函数SHA1、SHA-2、SHA3(1)-CSDN博客,我们先就将基础的SHA1\2讲解了,接下来我们继续聊SHA-3、SHA2变体SHA512_224\256等 2. SHA512-224\256 SHA512…

[oeasy]python0028_女性程序员_Eniac_girls_bug_Grace

028_第一个bug是谁发现的_编译之母 回忆上次内容 py文件 是 按照顺序 一行行 挨排 解释执行的 可以用 pdb3 hello.py 来调试程序 顺序执行 程序 在文本中 从上到下 是 一行行写的 解释器 从上到下 是 一行行解释的 调试 也是 从上到下 一行行 调试的 bug这个东西 是什么时候才有…

Rsync未授权访问漏洞

Rsync未授权访问漏洞 Rsync是Liux/Unix下的一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件和目录,默认运行在873端口。由于配置不当,导致任何人可未授权访问Syc,上传本地文件,下载服务器文件。RSyc默认允许匿名访问…

Java—继承和多态 (๑╹◡╹)ノ“““

目录: 一、继承: 为什么面向对象中有继承的概念?那么继承又是什么,继承又有什么作用呢?在我们生活中啊,也存在继承的关系,比如:你父母的财产由你“继承”。那在面向对象中&#xff…

vxe-pulldown 设置了宽度,并不能100%的占满整个容器的解决

1、下拉容器的使用 2、然而,这个宽度的显示是个问题,只占了一小部分: 长度并没有充满整个容器。 vxe-input设置了100%,然后也是一样的效果。 3、解决: .vxe-pulldown {width: 100% !important;} 增加上面的样式&…

本地GitLab runner自动编译Airoha项目

0 Preface/Foreword 1 GitLab runner环境 具体情况如下: Gitlab-ruuner运行在wsl 1中的Ubuntu 18.04 distro上专门为GitLab-runner分配了一个用户,名为gitlab-runner 2 自动编译 2.1 Permission denied 编译过程中,有两个文件出现权限不允…

Java语言程序设计基础篇_编程练习题*16.4 (创建一个英里/公里的转换器)

目录 *16.4 (创建一个英里/公里的转换器) 代码示例 结果展示 *16.4 (创建一个英里/公里的转换器) 编写一个程序来转换英里和公里,如图16-37b所示。如果在英里文本域Mile中输入一个值之后按下回车键,就会在公里文本域公里值。同样的,在公里文…

Latex入门指南:从下载到安装的全面教程

本篇博客旨在为初学者提供一个全面的Latex入门指南,涵盖了从下载、安装到配置Texlive和TexStudio的详细步骤。通过本指南,您将了解到如何正确安装Latex环境并成功运行第一个Latex文档,为撰写高质量的科技论文或书籍打下坚实基础。 目录 一定…

因为不懂ESLint,我被公司开除了……

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​ gitee https://gitee.com/Qiuner 🌹 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 😄 (^ ~ ^) 想看更多 那就点个关注吧 我…

把握现货黄金价格走势与买入时机 这两点缺一不可

在现货黄金投资中,对黄金价格走势的分析和做交易(买入卖出),这些动作之间是相关联的,而且联系很大,比方说投资者如果没有对现货黄金价格走势做正确有效的分析,那他可能在一些交易中获得盈利&…

【附PDF】《大模型应用开发 动手做 AI Agent》,第一本给程序员看的AI Agent图书!

AI Agent火爆到什么程度? OpenAI创始人奥特曼预测,未来各行各业,每一个人都可以拥有一个AI Agent;比尔盖茨在2023年层预言:AI Agent将彻底改变人机交互方式,并颠覆整个软件行业;吴恩达教授在AI …

隧道通风网络节点图导出CAD文本时的三角形算法

在TESP软件中涉及到将带文本的节点图导出为CAD文件,其中文本的绘制需要根据Section的方向来确定,确保和绘图的习惯一致。具体包括: (1)垂直绘制的Section需确保文字字头向左。 (2)除了垂直的文…

Golang面试题三(map)

1.map底层实现 由图看出,其实map的底层结构体是hmap,同时hmap里面维护着若干个bucket数组(即桶数组)。bucket数组中每个元素都是bmap结构的,bmap中存储着8个key-value的键值对,如果是满了的话,当…

奥运会Ⅵ--LLM 是否狡猾到可以自行欺骗你?

这已经成为一句老生常谈,因为它是事实:人类开发的任何工具都可以用于行善或作恶。你可以用锤子敲钉子或砸某人的头。你可以用火取暖或烧毁房屋。等等。 因此,数字世界的最新工具既带来好处,也带来风险,这不足为奇。其…

文献解读-遗传病-第二十六期|《癫痫的临床特征、诊疗和KCNH5突变》

关键词:遗传病;基因测序;变异检测; 文献简介 标题(英文):Clinical Feature, Treatment, and KCNH5 Mutations in Epilepsy标题(中文):癫痫的临床特征、诊疗和…

文心一言 VS 讯飞星火 VS chatgpt (318)-- 算法导论22.3 10题

十、修改深度优先搜索的伪代码,让其打印出有向图G的每条边及其分类。并指出,如果图G是无向图,要进行何种修改才能达到相同的效果。如果要写代码,请用go语言。 文心一言: 首先,我们来定义深度优先搜索&…

leetcode:汇总区间

题目: 给定一个无重复元素的有序整数数组nums。返回恰好覆盖数组中所有数字的最小有序区间范围列表 。也就是说,nums的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于nums的数字X。列表中的每个区间范围[a,b]应该按…

简单的docker学习 第2章 docker引擎

第2章docker引擎 2.1Docker 引擎发展历程 2.1.1 首发版本架构 Docker 在首次发布时,其引擎由两个核心组件构成:LXC(Linux Container)与 Docker Daemon。不过,该架构依赖于 LXC,使得 Docker 存在严重的问…

人力资源杂志人力资源杂志社人力资源编辑部2024年第13期目录

看法_总编随笔 学会退步 齐向宇; 1 看法_热点聚焦 数说 7 司事 9 看法_热点聚焦_翻转 话题 “霸总”发言遭吐槽对职场年轻人多些体谅 8 看法_视界《人力资源》投稿:cn7kantougao163.com 养老保险改革及其对人事工作的启示 赵梓安; 12-13 做…