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

2024-04-30 11:28

本文主要是介绍基于H.264的RTP打包中的组合封包以及分片封包结构图简介及抓包分析;FU-A FU-B STAP-A STAP-B简介;,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

前言:

1.RTP打包原则:

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

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作为切分条件。
2.RTP打包模式: 

主要分为三种模式:单一NALU模式、分片模式、组合模式,实际中前两种用的比较多。

一、单一NALU模式分析:

1.单一NALU模式结构如下:
   0                   1                   2                   30 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                   30 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 ... ]

这篇关于基于H.264的RTP打包中的组合封包以及分片封包结构图简介及抓包分析;FU-A FU-B STAP-A STAP-B简介;的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Qt QCustomPlot库简介(最新推荐)

《QtQCustomPlot库简介(最新推荐)》QCustomPlot是一款基于Qt的高性能C++绘图库,专为二维数据可视化设计,它具有轻量级、实时处理百万级数据和多图层支持等特点,适用于科学计算、... 目录核心特性概览核心组件解析1.绘图核心 (QCustomPlot类)2.数据容器 (QCPDataC

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

SpringBoot中4种数据水平分片策略

《SpringBoot中4种数据水平分片策略》数据水平分片作为一种水平扩展策略,通过将数据分散到多个物理节点上,有效解决了存储容量和性能瓶颈问题,下面小编就来和大家分享4种数据分片策略吧... 目录一、前言二、哈希分片2.1 原理2.2 SpringBoot实现2.3 优缺点分析2.4 适用场景三、范围分片

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

Redis分片集群、数据读写规则问题小结

《Redis分片集群、数据读写规则问题小结》本文介绍了Redis分片集群的原理,通过数据分片和哈希槽机制解决单机内存限制与写瓶颈问题,实现分布式存储和高并发处理,但存在通信开销大、维护复杂及对事务支持... 目录一、分片集群解android决的问题二、分片集群图解 分片集群特征如何解决的上述问题?(与哨兵模

关于MyISAM和InnoDB对比分析

《关于MyISAM和InnoDB对比分析》:本文主要介绍关于MyISAM和InnoDB对比分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录开篇:从交通规则看存储引擎选择理解存储引擎的基本概念技术原理对比1. 事务支持:ACID的守护者2. 锁机制:并发控制的艺

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛