流媒体传输 - RTP 荷载 H264

news2025/7/13 7:57:45

H264 码流结构

H264 码流是由很多 NAL Unit 组成,所有 NAL Unit 均存在一个八位数据的 NAL Unit Header ,这八位数据也充当此 RTP 有效负载格式的有效负载头。一个 NAL Unit Header 的语法如下:

    +---------------+
    |0|1|2|3|4|5|6|7|
    +-+-+-+-+-+-+-+-+
    |F|NRI|  Type   |
    +---------------+
  • F: 1bit forbidden_zero_bit,在 H.264 规范中规定了这一位必须为 0。

  • NRI: 2bit nal_ref_idc,取 00 ~ 11, 似乎指示这个 NALU 的重要性,如 00 的 NALU 解码器可以丢弃它而不影响图像的回放。不过一般情况下不太关心这个属性。

  • Type: 5bit 等于 nal_unit_type,标识着这个 NAL Unit 的 Type,其类型如下:

      Table 1.  Summary of NAL unit types and the corresponding packet types
    
          NAL Unit  Packet    Packet Type Name               Section
          Type      Type
          -------------------------------------------------------------
          0        reserved                                     -
          1-23     NAL unit  Single NAL unit packet             5.6
          24       STAP-A    Single-time aggregation packet     5.7.1
          25       STAP-B    Single-time aggregation packet     5.7.1
          26       MTAP16    Multi-time aggregation packet      5.7.2
          27       MTAP24    Multi-time aggregation packet      5.7.2
          28       FU-A      Fragmentation unit                 5.8
          29       FU-B      Fragmentation unit                 5.8
          30-31    reserved

H264 码流打包

RFC 6184 Section 5.2 中指定了 3 种打包方式:

  • 单 NAL 单元模式(Single NAL Unit Packet): 仅包含单个 NAL 单元的有效载荷。
  • 组合封包模式(Aggregation Packet):用于聚合多个 NAL 单元的分组类型成为单个 RTP 有效负载。
  • 分片封包模式(Fragmentation Unit):用于将单个 NAL 单元分段成多个 RTP 数据包。

单 NAL 单元模式

一个 RTP 包仅由一个完整的 NALU 组成。这种情况下 RTP 的 NAL 头类型字段和原始的 H.264 的 NALU 头类型字段是一样的。

对于 NALU 的长度小于 MTU 大小的包,一般采用单一 NAL 单元模式。一个原始的 H.264 NALU 单元常由 [Start Code] [NALU Header] [NALU Payload] 三部分组成,其中 Start Code 用于标示这是一个 NALU 单元的开始,必须是 "00 00 00 01" 或 "00 00 01", NALU 头仅一个字节,其后都是 NALU 单元内容,打包时去除 "00 00 01" 或 "00 00 00 01" 的开始码,把其他数据封包为 RTP 包即可。

 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        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    Figure 2.  RTP payload format for single NAL unit packet

组合封包模式

可能是由多个 NAL 单元组成一个 RTP 包。分别有 4 种组合方式: STAP-A, STAP-B, MTAP16, MTAP24,类型值分别是 24, 25, 26 以及 27。

 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   |                                               |
+-+-+-+-+-+-+-+-+                                               |
|                                                               |
|             one or more aggregation units                     |
|                                                               |
|                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                               :...OPTIONAL RTP padding        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    Figure 3.  RTP payload format for aggregation packets

MTAP 和 STAP 共享以下打包规则:

  • RTP 时间戳必须设置为所有要组合的 NAL 单元中 NALU-times 的最早时间。

  • 必须将 NAL 单元类型八位字节的类型字段设置为适当的值,如表 4 所示。

  • 如果聚合的 NAL 的所有 F 位均为零,则必须置零 F 位;否则,必须设置它。

  • NRI 的值必须是所有在聚合数据包中 NAL 单元的最大值。

           Table 4.  Type field for STAPs and MTAPs
    
      Type   Packet    Timestamp offset   DON-related fields
                      field length       (DON, DONB, DOND)
                      (in bits)          present
      --------------------------------------------------------
      24     STAP-A       0                 no
      25     STAP-B       0                 yes
      26     MTAP16      16                 yes
      27     MTAP24      24                 yes

分片封包模式

【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~

  

用于把一个 NALU 单元封装成多个 RTP 包。存在两种类型 FU-A 和 FU-B. 类型值分别是 28 和 29。 这种载荷类型允许将 NAL 单元分为多个 RTP 包。该封包模式具有以下优点:

  • 有效负载格式能够在 IPv4 网络传输大于 64 KB 的 NAL 单元,特别是在高清晰度格式中(每张图片的切片数量有限,导致每张图片的 NAL 单位数上限,可能会导致 NAL 单位数变大)
  • 分段机制允许分段单个 NAL 单元并应用通用前向纠错。

FU-A

下图给出了 FU-As 的 RTP 有效载荷格式:

    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   |                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               |
    |                                                               |
    |                         FU payload                            |
    |                                                               |
    |                               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                               :...OPTIONAL RTP padding        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            Figure 14.  RTP payload format for FU-A
  • FU indicator 格式与 NAL Header 一致:

      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+

Type 字段的值等于 28 和 29 分别标识该 RTP 包的封包模式为 FU-A 和 FU-B。

  • FU header 格式如下:

      +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |S|E|R|  Type   |
      +---------------+
    • S: 1 bit 开始位
      • 当设置成 1 时,指示跟随的 FU 荷载是分片 NAL 单元的开始。
      • 当设置成 0 时,指示跟随的 FU 荷载不是分片 NAL 单元荷载的开始。
    • E: 1 bit 结束位
      • 当设置成 1 时,指示跟随的 FU 荷载是分片 NAL 单元的结束。
      • 当设置成 1 时,指示跟随的 FU 荷载不是分片 NAL 单元的结束。
    • R: 1 bit 保留位
      • 保留位必须设置为 0。
    • Type: 5 bits
      • NAL 单元荷载类型定义见下表:

以两段 Wirshark 抓包的码流为例:

  1. FU - Start

     0000   7c 85 b8 00 00 1d dc 40 00 02 ff ea 14 34 0c ab   |......@.....4..
     0010   5a 02 6f 1a 0f d5 5c f3 a9 df 6f d6 6b a8 25 1f   Z.o...\...o.k.%.
    
     ===================== 转化 第一个字节 7c 第二个字节 85 =====================
     0111 1100  F=0 NRI=11 Type=28 说明是 FU-A
     1000 0101  S=1 E=0 R=0 Type=5 非参考帧
    
     ============================= Wirshark 解析 =============================
     FU header:
       1... .... = Start bit: the first packet of FU-A picture
       .0.. .... = End bit: Not the last packet of FU-A picture
       ..0. .... = Forbidden bit: 0
       ...0 0101 = Nal_unit_type: Coded slice of an IDR picture (5)
  2. FU - End

     0000   7c 45 c0                                          |E.
    
     ============== 转化 第一个字节 7c 第二个字节 45 ================

    0111 1100 F=0 NRI=11 Type=28 0100 0101 S=0 E=1 R=0 Type=5

     ======================= Wirshark 解析 =======================
     FU header:
       0... .... = Start bit: Not the first packet of FU-A picture
       .1.. .... = End bit: the last packet of FU-A picture
       ..0. .... = Forbidden bit: 0
       ...0 0101 = Nal_unit_type: Coded slice of an IDR picture (5)

FU-B

FU-B 的封包格式仅仅是在 FU header 后面多了 2 个字节的 DON 解码顺序号,它允许 NAL 单元的传输顺序和 NAL 单元的解码顺序不同 ,用来 指示 NAL 单元的解码顺序。

    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        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

             Figure 15.  RTP payload format for FU-B

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

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

相关文章

深分页Scroll

ES对from size是有限制的,from和size二者之和不能超过1W 原理: fromsize在ES查询数据的方式: 第一步现将用户指定的关键进行分词。 第二步将词汇去分词库中进行检索,得到多个文档的id。 第三步去各个分片中去拉取指定的数据。耗…

JUC总结-基础篇

juc是什么? JUC是java.util.concurrent包的简称,在Java5.0添加,目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题! juc脑图 juc总结 juc多数工具都是依赖volatile关键字保持可见性和禁止指…

ovs vxlan 时延和吞吐

设计云时到底要不要用vxlan,如果用vxlan到底要不要购买比较贵的smart nic做offload,采用软件vxlan还是硬件交换机vxlan,很难决策,这儿简单测试一下,给个参考,资源终究是有限的,成本还是有考虑的…

Flutter splash 屏幕

Flutter splash 屏幕 原文 https://medium.com/bedirhanssaglam/flutter-splash-screen-a8cafec52c8e 前言 启动画面通常被特别大的应用程序用来通知用户程序正在加载过程中。它们提供的反馈表明,一个漫长的过程正在进行中。有时,启动画面中的进度条会指…

【MYSQL】在线恢复主从复制方案

一、恢复前提 因复杂情况,从库无法从binlog中恢复主从复制关系,需要从备份文件中恢复。恢复过程的几个关键点为: 1、从库现有数据的清理。本方案采用覆盖的方式,导出时添加add-drop参数即可。还有一个方案是手动删除数据文件&…

1990-2021年全国各省外商直接投资水平

1990-2021年全国各省外商直接投资水平 1、包括全国30省,不含西藏 2、指标包括: 行政区划代码、长江经济带、年份、地区、经度、纬度、GDP(亿元)、外商直接投资(美元)(万美元)、人民币对美元汇率(美元1)(元)、外商直接投资(万元)、外商直接投资水平 3、…

第三章:CompletableFuture

Future接口复习FutureTask 实现类Future 编码的优缺点优点缺点get() 方法导致阻塞isDone() 轮询总结CompletableFutureCompletableFuture 为什么会出现?CompletableFuture 架构图CompletionStageCompletableFuture 四个静态方法CompletableFuture 减少阻塞和轮询注意…

Elasticsearch 8.4.1 配置自签名证书和启用Https

一、背景 某次安全扫描过程中,发现环境存在【SSL证书不可信】和【SSL自签名证书】漏洞;漏洞描述: 此服务的X.509证书链未由认可的证书颁发机构签名。如果远程主机是生产中的公共主机,这将取消SSL的使用,因为任何人都可…

干货分享:超级浏览器使用感受

在亚马逊做工艺品时间挺长的了,来说说我这几年使用超级浏览的感受。 现在做跨境的就跟做国内的电商平台一样卷了,不仅产品要新奇独特、要包邮价格还要有优势,可以说以前跨境电商是卖方市场,现在已经妥妥变成买方市场了。但这是国际…

python基础之模块与列表

文章目录一、模块模块名也是一个标识符二、列表高级变量类型:在python中,所有非数字型变量都支持以下特点:列表的定义:列表函数使用:关键字、函数和方法科普:列表的迭代 遍历:一、模块 模块是p…

一文了解 Go 中的指针和结构体

一文了解 Go 中的指针和结构体前言指针指针的定义获取和修改指针所指向变量的值结构体结构体定义结构体的创建方式小结耐心和持久胜过激烈和狂热。 前言 前面的两篇文章对 Go 语言的基础语法和基本数据类型以及几个复合数据类型进行介绍,本文将对 Go 里面的指针和结…

机器学习-(手推)线性回归-最小二乘法(矩阵表达)、几何意义

一、最小二乘法(矩阵表达)误差平均分散每个样本 如下数学推到过程(手推!!!): 数据介绍: D{(x1,y1),(x2,y2),......(xn,yn), Xi(P维列向量&…

行列向量的维数和个数的关系【三秩相等作为桥梁】

前置知识 1.列向量组维数增加时,向量组的极大无关组增加(或不变)。 2. 三秩相等 向量组证明 直观证明 这两个列向量显然是相关的。 这两个列向量当a和b取k和2k的时候相关(k为任意常数),当不是k和2k的时…

【2-Docker安装部署ElasticSearch和Kibanan详细步骤】

一.知识回顾 【0.ElasticSearch专栏在这里哟,想要学习的可自行进入专栏学习】 【1-ElasticSearch的基本介绍与用途、ElasticSearch中一些基本的概念、倒排索引的基本概念】 二.Docker安装部署ElasticSearch 2.1 docker pull 从镜像仓库中拉拉取ElasticSearch的镜像…

【零基础入门SpringMVC】第三期——请求域添加数据与视图

一、域对象共享数据 SpringMVC 中有哪些域对象? Request请求域,代表一次请求,从浏览器开启到关闭Session请求域,代表一次会话,从服务器开启到关闭【一次getSession获得了cookie,这个会话没关闭,…

Romantics三大浪漫(编译原理+操作系统+计算机图形学)

Romantics三大浪漫 一、编译原理1.1 研究翻译的科学1.2 编译器和解释器1.3 编译的流程(JIT为例)1.4 词法分析器1.5 多有限状态机提取Token- 实现词法分析器lexer1.6 实现流的peek和putBack操作一、编译原理 本章目标: 提升编程能力 区别于面向研究人员、学者的编译原理教学&a…

CSS学习笔记(三)

her~~llo,我是你们的好朋友Lyle,是名梦想成为计算机大佬的男人! 博客是为了记录自我的学习历程,加强记忆方便复习,如有不足之处还望多多包涵!非常欢迎大家的批评指正。 目录 一、CSS 的三大特性 1.1 层叠…

mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)

mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存)MyBatis的缓存机制MyBatis的一级缓存MyBatis的二级缓存二级缓存的相关配置MyBatis缓存查询的顺序整合第三方缓存EHCacheEHCache配置文件说明:MyBatis的缓存机制 MyBatis作为持久化框架&…

社区故事|SmartX 用户社区技术发烧友独家专访

小伙伴们,SmartX 用户社区已经陪伴我们走过近两年的时光,这期间有一千多位小伙伴加入我们,共同讨论问题、分享经验。今天,SmartX 用户社区的一线记者小乐为我们带来了独家采访,揭秘社区中两位技术发烧友的幕后故事&…

葡萄糖-聚乙二醇-转铁蛋白|Transferrin-PEG-Glucose|转铁蛋白-PEG-葡萄糖

转铁蛋白又名运铁蛋白 transferrin,TRF,siderophilin)还可以提供PEG接枝修饰葡萄糖,葡萄糖-聚乙二醇-转铁蛋白,Transferrin-PEG-Glucose,转铁蛋白-PEG-葡萄糖 中文名称:葡萄糖-转铁蛋白 英文名称:Glucose…