基于H.264的RTP打包中的组合封包以及分片封包结构图简介及抓包分析

H.264视频流的RTP封装类型分析:

前言:

NULL Hearder简介(结构如下):
  +---------------+
  |0|1|2|3|4|5|6|7|
  +-+-+-+-+-+-+-+-+
  |F|NRI|  Type   |
  +---------------+
  1. F:forbidden_zero_bit, 占1位,在 H.264 规范中规定了这一位必须为 0;
  2. NRI:nal_ref_idc, 占2位,取值从0到3,指示这个 NALU 的重要性,取值越大约重要;
  3. Type:nalu是指包含在 NAL 单元中的 RBSP 数据结构的类型,其中0未指,1-19在264协议中有定义,20-23为264协议指定的保留位。24-29在RFC3984中进行了指定。其中STAP-A为24,FU-A为28

其中Type详细介绍前文以叙述:RFC3984: RTP Payload Format for H.264 Video(中英文版)官方文献,RTP协议头格式分析详解;RTP载荷H264码流;

其中我们看到1-11就是NALU的单个包类型,但是一个NALU的大小是不一样的,如果是非视频数据的SPS PPS才十几个字节,对于IDR帧,则有可能几十KB。这样把NALU打包到RTP方式就很多:分为一个RTP包承载一个NALU,多个NALU合并到一个RTP,一个大的NALU切分成多个RTP。同时由于时间戳的问题,就有了24-29几种类型。

但是对于发送端组RTP包的一方来说,尽可能找简单的打包方式。对于接受端则需要适配各种发送端的打包方式,因为无法决定输入源的打包方式。这里先分享下我们的打包方式,比较简单:

  1. 我们对于NALU的长度<1400的则采用的是单一NALU打包到单一的RTP包中;
  2. 我们对于NALU的长度>=1400的则采用了FU-A的方式进行了打包,这种就是把一个大的NALU进行了切分,最后接收方则进行了合并,把多个RTP包合并成一个完整的NALU即可;
  3. 至于为什么NALU的长度大于1400字节就要进行FU-A切片,是因为底层MTU大小值固定为1500,从传输效率讲,这里用1400作为切分条件。

一、单一NALU模式分析:

1.单一NALU模式结构如下:
   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        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2.抓包对照分析

二、分片包模式分析

1.FU-A和FU-B的结构如下:
// 5.8. Fragmentation Units (FUs) (p29)
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   |              DON              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
|                                                               |
|                          FU payload                           |
|                                                               |
|                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               :   ...OPTIONAL RTP padding     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

注意:STAP-A和FU-A的RTP荷载结构不包含DON(解码顺序号). STAP-B,FU-B结构包含DON。

与单一封包不一样的是,|F|NRI|type|变成了|FU indicator|FU header|。其实,|FU indicator|就是|F|NRI|type|,但是额外增加了|FU header|用于标识当前分片的状态,如下所示:

  // FU header 结构如下:
  +---------------+
  |0|1|2|3|4|5|6|7|
  +-+-+-+-+-+-+-+-+
  |S|E|R|  Type   |
  +---------------+
  1. S: 1 bit 当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0;
  2. E: 1 bit 当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的FU荷载不是分片NAL单元的最后分片,结束位设置为0;
  3. R: 1 bit 保留位必须设置为0,接收者必须忽略该位;
  4. Type: 5 bits NAL单元荷载类型定义在[1]的表7-1(与前文中的type一致,不做展开)。
2.抓包对照分析,以FU-A为例

三、组合包封装模式分析

1.STAP-A结构如下(type 24):

当NALU的长度特别小时,可以把几个NALU封在一个RTP包中。                                                      下面的是STAP-A模式,如果是STAP-B的话会多加入一个DON域。

       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         
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+        
      |                          RTP Header                           |        
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+        
      |STAP-A NAL HDR |         NALU 1 Size           | NALU 1 HDR    |        
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                         NALU 1 Data                           |        
      :                                                               :
      +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |               | NALU 2 Size                   | NALU 2 HDR    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                         NALU 2 Data                           |
      :                                                               :
      |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                               :...OPTIONAL RTP padding        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            图 STAP-A RTP包包含一个STAP-A. STAP包含两个单时刻聚合单元
 2.STAP-B结构如下(type 25):
       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
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                          RTP Header                           |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |STAP-B NAL HDR | DON                           | NALU 1 Size   |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      | NALU 1 Size   | NALU 1 HDR    | NALU 1 Data                   |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
      :                                                               :
      +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |               | NALU 2 Size                   | NALU 2 HDR    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                       NALU 2 Data                             |
      :                                                               :
      |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                               :...OPTIONAL RTP padding        |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

         图STAP-B 一个RTP包包含一个STAP-B. STAP包含两个单时刻聚合单元例子
  1. RTP Header(1 byte):RTP协议头,前文有叙述,不做展开;
  2. STAP-(A/B) NAL HDR():STAP-(A/B)帧头,与前文的|F|NRI|type|结构一致;
  3. DON:解码顺序号,STAP-A帧不包含DON,STAP-B帧的话则会多加入一个DON域;

例:如有一个 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 ... ]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python数据分析大作业(ARIMA 自回归积分滑动平均模型) 4000+字 图文分析文档 销售价格库存分析+完整python代码

资源地址&#xff1a;Python数据分析大作业 4000字 图文分析文档 销售分析 完整python代码 完整代码分析 ​ 同时销售量后1000的sku品类占比中&#xff08;不畅销产品&#xff09;如上&#xff0c;精品类产品占比第一&#xff0c;达到66.7%&#xff0c;其次是香化类产品&#x…

【架构】后端项目如何分层及分层领域模型简化

文章目录 一. 如何分层1. 阿里规范2. 具体案例分析 二. 分层领域模型的转换1. 阿里规范2. 模型种类简化分析 三. 小结 本文描述后端项目中如何进行分层&#xff0c;以及分层领域模型简化 一. 如何分层 1. 阿里规范 阿里的编码规范中约束分层逻辑如下: 开放接口层&#xff1a…

Apache Seata基于改良版雪花算法的分布式UUID生成器分析1

title: Seata基于改良版雪花算法的分布式UUID生成器分析 author: selfishlover keywords: [Seata, snowflake, UUID] date: 2021/05/08 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Seata基于改良版雪花算法的分布式UUID生成器分析…

NLP(10)--TFIDF优劣势及其应用Demo

前言 仅记录学习过程&#xff0c;有问题欢迎讨论 TF*IDF&#xff1a; 优势&#xff1a; 可解释性好 可以清晰地看到关键词 即使预测结果出错&#xff0c;也很容易找到原因 计算速度快 分词本身占耗时最多&#xff0c;其余为简单统计计算 对标注数据依赖小 可以使用无标注语…

请编写函数fun,该函数的功能是:将放在字符串数组中的M个字符串(每串的长度不超过N),按顺序合并组成一个新的字符串。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 请编…

React Router 路由配置数组配组持久化

在一些特定场景下,你可能需要将路由配置数组进行持久化,例如从后端动态加载路由配置或根据用户权限动态生成路由配置。这时,持久化路由配置数组就很有用,可以避免每次应用启动时重新获取或计算路由配置。 持久化路由配置数组的步骤如下: 定义路由配置数组 首先,你需要定义一…

[华为OD]C卷 找座位,在一个大型体育场内举办了一场大型活动,由于疫情防控的需要 100

题目&#xff1a; 在一个大型体育场内举办了一场大型活动&#xff0c;由于疫情防控的需要&#xff0c;要求每位观众的必须间隔至 少一个空位才允许落座。现在给出一排观众座位分布图Q,座位中存在已落座的观众&#xff0c;请计 算出&#xff0c;在不移动现有观众座位的情况…

从不同性别、年龄入手,发过的主题还能发!| NHANES数据库周报(4.24)

零基础NHANES挖掘培训班,欢迎咨询&#xff01; 课程 | 零基础两天掌握NHANES公共数据库挖掘技巧&#xff0c;发表SCI论文 美国国家健康和营养检查调查&#xff08;NHANES&#xff09;是一项旨在评估美国成人和儿童健康和营养状况的研究计划。该调查的独特之处在于它结合了访谈和…

Spring6 当中 获取 Bean 的四种方式

1. Spring6 当中 获取 Bean 的四种方式 文章目录 1. Spring6 当中 获取 Bean 的四种方式每博一文案1.1 第一种方式&#xff1a;通过构造方法获取 Bean1.2 第二种方式&#xff1a;通过简单工厂模式获取 Bean1.3 第三种方式&#xff1a;通过 factory-bean 属性获取 Bean1.4 第四种…

LT6911C HDMI 1.4 至 2 端口 MIPI DSI/CSI 龙迅方案

1. 描述LT6911C 是一款高性能 HDMI1.4 至 MIPIDSI/CSI/LVDS 芯片&#xff0c;适用于 VR/智能手机 / 显示应用。对于 MIPIDSI / CSI 输出&#xff0c;LT6911C 具有可配置的单端口或双端口 MIPIDSI/CSI&#xff0c;具有 1 个高速时钟通道和 1~4 个高速数据通道&#xff0c;工作速…

NFTScan | 04.22~04.28 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期&#xff1a;2024.04.22~ 2024.04.28 NFT Hot News 01/ ApeCoin DAO 发起「由 APE 代币支持的 NFT Launchpad」提案投票 4 月 22 日&#xff0c;ApeCoin DAO 社区发起「由 APE 代币支持的 NFT Launch…

JAVA基础——集合框架(List与Set)

数据结构 什么是数据结构 数据结构就是用来装数据以及数据与之间关系的一种集合。如何把相关联的数据存储到计算机&#xff0c;为后续的分析提供有效的数据源&#xff0c;是数据结构产生的由来。数据结构就是计算机存储、组织数据的方式。好的数据结构&#xff0c;让我们做起事…

Deckset for Mac激活版:MD文档转幻灯片软件

Deckset for Mac是一款专为Mac用户打造的Markdown文档转幻灯片软件。它凭借简洁直观的界面和强大的功能&#xff0c;成为许多用户的心头好。 Deckset for Mac激活版下载 Deckset支持Markdown语法&#xff0c;让用户在编辑文档时无需分心于复杂的格式设置&#xff0c;只需专注于…

分布式与一致性协议之Raft算法(二)

Raft算法 什么是任期 我们知道&#xff0c;议会选举中的领导者是有任期的&#xff0c;当领导者任命到期后&#xff0c;需要重新再次选举。Raft算法中的领导者也是有任期&#xff0c;每个任期由单调递增的数字(任期编号)标识。比如&#xff0c;节点A的任期编号是1。任期编号会…

Spark-机器学习(8)分类学习之随机森林

在之前的文章中&#xff0c;我们学习了分类学习之支持向量机决策树支持向量机&#xff0c;并带来简单案例&#xff0c;学习用法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&a…

【全开源】Java上门老人护理老人上门服务类型系统小程序APP源码

功能&#xff1a; 服务分类与选择&#xff1a;系统提供详细的老人护理服务分类&#xff0c;包括日常照护、康复训练、医疗护理等&#xff0c;用户可以根据老人的需求选择合适的服务项目。预约与订单管理&#xff1a;用户可以通过系统预约护理服务&#xff0c;并查看订单详情&a…

mybatis工程需要的pom.xml,以及@Data 、@BeforeEach、@AfterEach 的使用,简化mybatis

对 “mybatis - XxxMapper.java接口中方法的参数 和 返回值类型&#xff0c;怎样在 XxxMapper.xml 中配置的问题” 这篇文章做一下优化 这个pom.xml文件&#xff0c;就是上面说的这篇文章的父工程的pom.xml&#xff0c;即&#xff1a;下面这个pom.xml 是可以拿来就用的 <?…

Python爬虫(入门版)

1、爬虫是什么 简单的来说&#xff1a;就是用程序获取网络上数据。 2、爬虫的原理 如果要获取网络上数据&#xff0c;我们要给爬虫一个网址&#xff08;程序中通常叫URL&#xff09;&#xff0c;爬虫发送一个HTTP请求给目标网页的服务器&#xff0c;服务器返回数据给客户端&am…

帕累托森林李朝政博士受聘「天工开物开源基金会」专家顾问

导语&#xff1a; 开源铸造了当前最前沿的科技引擎。开源驱动了软件生态&#xff0c;也以指数级速度驱动硬件生态。 3月中旬&#xff0c;天工开物开源基金会授予李朝政博士专家顾问&#xff0c;表彰他积极推动参与中国智能软件生态的建设&#xff0c;期待一起共筑未来新生态。…

稳扎稳打 部署丝滑 开源即时通讯(IM)项目OpenIM源码部署流程(linux windows mac)

背景 OpenIM包含多个关键组件&#xff0c;每个都是系统功能必不可少的一部分。具体来说&#xff0c;MongoDB 用于持久化存储&#xff1b;Redis 用作缓存&#xff1b;Kafka 用于消息队列&#xff1b;Zookeeper 用于服务发现&#xff1b;Minio 用于对象存储。这些组件的众多可能会…