H264码流的RTP封装

一、RTP协议头:

1.RTP头定义:

RTP协议头一般固定为12个字段,在每一个RTP数据包中都存在。各字段的含义如下:

version(V):2bits:标识RTP的版本,当前协议版本固定为2.

padding(P):1bits:填充位。默认0,如果为1,则在该报文的末尾填充一个或多个额外的八位组,它们不是有效载荷的一部分。某些具有固定块大小的加密算法可能会使用到填充

extension(X):1bits:扩展位。默认0,如果为1,设置了扩展位,固定头部必须紧跟一个头部扩展。

CSRC count(CC):4bits:CSRC计数器。默认为0,指示CSRC标识符的个数。

marker(M):1bits:不同的载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。

payload type(PT):7bits:载荷类型。常见的H264视频为96,AAC音频为97

sequence number(SEQ):16bits:序列号。用于标识发送者发送RTP报文的序列号,每次加1,初始值应该是随机的。接收方可以用于检测丢包,或者重排。音频包和视频包是分别计数的。

timestamp:32bits:时间戳。反映RTP数据包中第一个八位字节的采样瞬间,接收者可以用来计算延迟和延迟抖动,结合RTCP包的NTP时间基等概念,接受端可以进行音视频同步控制(以后再深入学习)

ssrc:32bits:同步信源标识。该标识符应当是随机选择的,且同一RTP会话中不同同步源需要有不同的ssrc标识符。

csrc list:0~15个32bits:特约信源。标识符的个数由CC字段给出,一般在混音器插入时才出现,默认不需要。

2.ZLM中关于H264流RTP的构造:

 二、RTP封包类型:

H264可以由三种RTP打包方式:1)单NALU打包,一个RTP包包含一个完整的NALU;2)聚合打包,对于较小的NALU,一个RTP包可以包含多个完整的NALU;3)分片打包:对于较大的NALU,一个NALU可以分为多个RTP包发送。比较常见的是单NALU打包和分片打包。

 单NALU打包简单,将整个NALU的数据放入到RTP包的载荷中即可。

 分片打包。在RTP载荷开始之前有两个字节的信息,然后是NALU的内容。

 第一个字节是FU Indicator。标识封包类型。格式如下:F禁止位,NRI两个bite,Type为封包类型。解析方法:futype = fu_indicator & 0x1f;

 第二个字节是FU header。用于判断包的位置,和包的类型。FU-A打包中的第一个包时,S设为1;FU-A打包的最后一个包时,E设为1;R为保留位。Type为原来NALU的Type的低位,0x01,0x05,0x07,0x08这些

 H264帧的NALU TYPE类型:nal_fu = (fu_indicator & 0xe0) | (fu_header & 0x1f)

在ZLM中使用到的RTP分别类型有3种:Single包、STAP-A包、FU-A包。

 三。STAP-A包

1.STAP-A包的完整格式:

 2.SPS帧抓包:

 

其中:80 60 31 4a 00 57 40 e0 00 00 00 02为RTP HEAD,对照RTP HEAD定义可以进行解析。可以得出PT为96,SEQ为12618,Timestamp为5718240,SSRC为000002

剩余部分:78 00 18 67 64 ......

78 -->0111 1000。0x78 & 0x1f = 0x18 。后5位type为24。表示为STAP-A类型包

00 18 载荷长度:24

67 -->NALU TYPE表示为SPS包

之后的内容是SPS包的具体内容,不再分析。

3.PPS帧抓包:

 其中:80 60 31 4b 00 57 40 e0 00 00 00 02为RTPHEAD, 可以得出PT为96,SEQ为12619,Timestamp为5718240,SSRC为000002。对比SPS包可以看出,SEQ加1,同一时刻构造的包,SSRC一致。

剩余部分:78 00 05 68 ee 31 b2 1b

78 -->0111 1000。0x78 & 0x1f = 0x18 。后5位type为24。表示为STAP-A类型包

00 15 载荷长度:5

68 -->NALU TYPE表示为PPS包。

之后的内容是PPS包的具体内容,不再分析

四、FU-A包

1、FU-A包完整格式:

 2、I帧(起始帧)抓包

 

其中:80 60 31 4c 00 57 40 e0 00 00 00 02为RTPHEAD, 可以得出PT为96,SEQ为12620,Timestamp为5718240,SSRC为000002。对比SPS包可以看出,SEQ加1,同一时刻构造的包,SSRC一致。

剩余部分:7c 85 b8 ...

7c --> 0111 1100。0x7c & 0x1f = 0x1c。后5位type为28表示为FU-A类型包

85 -->1000 0101。对比FU Head解析,S为1,说明是起始包。后5位为5,说明是I帧。更加完整的NAL TYPE为:(0x7c &  0xe0) | (0x85 & 0x1f) = 0x65

之后的内容是NALU负载,不再分析

3、I帧(中间帧)抓包

 

其中:80 60 31 4d 00 57 40 e0 00 00 00 02为RTPHEAD, 可以得出PT为96,SEQ为12621,Timestamp为5718240,SSRC为000002。对比SPS包可以看出,SEQ加1,同一时刻构造的包,SSRC一致

剩余部分:7c 05 ad ...

7c --> 0111 1100。0x7c & 0x1f = 0x1c。后5位type为28表示为FU-A类型包

05 -->0000 0101。对比FU Head解析,S为0,E为0,说明是中间包。后5位为5,说明是I帧。更加完整的NAL TYPE为:(0x7c &  0xe0) | (0x05 & 0x1f) = 0x65

之后的内容是NALU负载,不再分析

4、I帧(结尾帧)抓包:

 

其中:80 e0 31 db 00 57 40 e0 00 00 00 02为RTPHEAD, 可以得出PT为96,SEQ为12763,Timestamp为5718240,SSRC为000002。对比SPS包可以看出,SEQ加了很多,同一时刻构造的包,SSRC一致

剩余部分:7c 05 ad ...

7c --> 0111 1100。0x7c & 0x1f = 0x1c。后5位type为28表示为FU-A类型包

45 -->0100 0101。对比FU Head解析,S为0,E为1,说明是结尾包。后5位为5,说明是I帧。更加完整的NAL TYPE为:(0x7c &  0xe0) | (0x45 & 0x1f) = 0x65

之后的内容是NALU负载,不再分析

至此一个完整的I帧结束

5、P帧(分包)抓包

 

其中:80 60 31 f2 00 58 83 9c 00 00 00 02为RTPHEAD, 可以得出PT为96,SEQ为12786,Timestamp为5800860,SSRC为000002。对比SPS包可以看出,SEQ加了很多, 时间戳增加,SSRC一致

剩余部分:7c 81 e2 ...

7c --> 0111 1100。0x7c & 0x1f = 0x1c。后5位type为28表示为FU-A类型包

81 -->1000 0001。对比FU Head解析,S为1,E为0,说明是起始包。后5位为1,说明是P帧。更加完整的NAL TYPE为:(0x7c &  0xe0) | (0x81 & 0x1f) = 0x61

五、ZLM对RTP的封装实现:

1、根据H264帧的长度,决定单包还是分包:

 2、对于单包,zlm根据配置分别采用单nalu和stap-a两种方式:

 3、singlenalu打包:直接将NALU内容放在RTP头后面

 4、stap-a打包:作者注释是为了兼容性webrtc。第一个字节为0x24,第二和第三字节为负载长度,后面为NALU内容

5、fu-a打包:设置第一个字节为28,第二个字节有NALU的TYPE和起始结束标识进行构造。在while循环中进行分包处理。

 六、ZLM对RTP的解封装实现

1、根据RTP头部之后的第一个字节判读包类型:nal = frame[0] & 0x1f。其中小于24为单包,24为stap-a,28为su-a,其它不支持

 2、解封装单包:在负载内容frame之前添加帧分隔符00 00 00 01,组装成H264裸帧

 3、解封装stap-a包:stap-a包和单包类似,只不过多了两个字节表示载荷长度,可用于包长度校验。取出nalu载荷之后通上述单包逻辑,组成成H264裸帧。

 

4、解封装fu-a包:根据RTP头后面的第二个字段,可以判断出是起始/中间/结尾包。根据第一个和第二个字段可以计算出H264帧的类型。如果是起始包,添加00 00 00 01帧头,添加帧类型,缓存后续包;如果是中间包,缓存第二个字节之后的后续包;如果是结尾包,缓存第二个字节之后的后续包之后,至此组装出一个完整的H264裸帧。在分包缓存的过程中根据SEQ序号还就行了帧连续性判断

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

批量计算遥感影像NDVI:Python代码

本文介绍基于Python中的gdal模块,批量基于大量多波段遥感影像文件,计算其每1景图像各自的NDVI数值,并将多景结果依次保存为栅格文件的方法~本文介绍基于Python中的gdal模块,批量基于大量多波段遥感影像文件,计算其每1景图像各自的NDVI数值,并将多景结果依次保存为栅格文件…

线程池创建方式

线程池创建方式一、方式一:通过ThreadPoolExecutor构造函数来创建(推荐) 方式二:通过 Executor 框架的工具类 Executors 来创建。Executors工具类提供的创建线程池的方法如下图所示: 可以看出,通过Executors工具类可以创建多种类型的线程池,包括:1. FixedThreadPo…

HTML基础练习

注意:全卷满分140+45分,时间40分钟。 全开卷,并允许联网查询。 凡是标注“不定项”的,每个选项均分总分,每错选或漏选一个均仅扣除该项得分。例如8分4选项题,答案为AD,选ABD得6分,A得6分,AB得4分。 所有题目均为人工阅卷,不需要特别遵守格式规范,均按照答案酌情给分…

将URDF模型文件导入Issac_Gym系列【1】

1 在solidworks中导出URDF文件 1 这里按照古月居老师的要求进行基本的配置 https://www.bilibili.com/video/BV1Tx411o7rH/?vd_source=fcddcf87e97b17fd530dc88db643aab3 关于catkin_ws这种ROS的工作环境的配置,具体可以参考我的这篇博客 https://www.cnblogs.com/myleaf/p/1…

SpringMVC 学习笔记

概述 SpringMVC 中的 MVC 即模型-视图-控制器,该框架围绕一个 DispatcherServlet 改计而成,DispatcherServlet 会把请求分发给各个处理器,并支持可配置的处理器映射和视图渲染等功能 SpringMVC 的工作流程如下所示:客户端发起 HTTP 请求:客户端将请求提交到 DispatcherSer…

VMware vSphere 6.7 Update 3w 下载

VMware vSphere 6.7 Update 3w 下载VMware vSphere 6.7 Update 3w 下载 ESXi 6.7 U3 & vCenter Server 6.7 U3, Dell, HPE, LENOVO, Inspur Custom Image 请访问原文链接:https://sysin.org/blog/vmware-vsphere-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sys…

HER304-ASEMI轴向高效恢复二极管HER304

HER304-ASEMI轴向高效恢复二极管HER304编辑:ll HER304-ASEMI轴向高效恢复二极管HER304 型号:HER304 品牌:ASEMI 封装:DO-27 特性:轴向高效恢复二极管 正向电流:3A 反向耐压:300V 恢复时间:35ns 引脚数量:2 芯片个数:2 芯片尺寸:MIL 浪涌电流:125A 漏电流:10ua 工作…

Blender 常用修改器

修改器的好处是,它是一个非破坏性的建模方式,方便修改和撤销表面细分修改器 将网格的面分割成更小的面,使其看起来更光滑,但它的顶点并不会受到影响实体修改器 获取任意网格的表面,然后为之添加深度,使其变厚,偏移量可以决定它朝哪边偏移倒角修改器 宽度是坡口形成的两条…

LIN总线

LIN总线 参考链接:https://www.renesas.cn/zh/document/apn/904591?language=zh LIN 是 Local Interconnect Network 的缩写,是基于 UART/SCI(Universal Asynchronous Receiver-Transmitter / Serial Communication Interface,通用异步收发器/串行通信接口)的低成本串行通信…

Nuxt.js 应用中的 listen 事件钩子详解

title: Nuxt.js 应用中的 listen 事件钩子详解 date: 2024/11/9 updated: 2024/11/9 author: cmdragon excerpt: 它为开发者提供了一个自由的空间可以在开发服务器启动时插入自定义逻辑。通过合理利用这个钩子,开发者能够提升代码的可维护性和调试能力。注意处理性能、错误和…

vmware虚拟机更改名字

vmware 虚拟机更改名字,vmware虚拟机安装目录最少文件我安装的时候起名字为 debian1260,后来想改为 debian12gui,我把虚拟机安装目录中的其他文件全都删除,只保留这三个文件。然后把名字改一下,vmx 文本文件中的名字替换一下,双击虚拟机 vmx 文件打开即可。有了计划记得推…

Vanity Intermediate 统配符提权

nmap扫描 ┌──(root㉿kali)-[~] └─# nmap -p- -A 192.168.167.234 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-09 03:59 UTC Stats: 0:01:22 elapsed; 0 hosts completed (1 up), 1 undergoing Traceroute Traceroute Timing: About 32.26% done; ETC: 04:00 …