系统化学习 H264视频编码(05)码流数据及相关概念解读

news2024/10/2 10:37:56

说明:我们参考黄金圈学习法(什么是黄金圈法则?->模型 黄金圈法则,本文使用:why-what)来学习音H264视频编码。本系列文章侧重于理解视频编码的知识体系和实践方法,理论方面会更多地讲清楚 音视频中概念的起源以及各个概念的联系。知其然,知其所以然。同时更强调知识系统的建立。

针对本文,我们主要研究 H.264码流数据结构及相关概念。包括VCL层(Video Coding Layer,视频数据编码层)及其相关概念宏块、片等,NAL层(Network Abstraction Layer,视频数据网络抽象层)及其相关概念SODB、RBSP、EBSP和NALU等;NALU详细信息解读以及Annex格式和RTP格式解读。

1 H264码流数据解读

H.264码流按照功能分为两层:视频编码层和网络提取层。即VCL层(Video Coding Layer,视频数据编码层)和NAL层(Network Abstraction Layer,视频数据网络抽象层)。

那么为什么要这样分层呢?这样的分层设计主要是为了满足不同的需求和优化视频数据的存储与传输。下面是分层设计的几个主要原因:

  • 模块化设计:分层允许将视频编码的复杂性与网络传输的需求分离开来,使得每个层次可以独立优化和更新,而不影响另一层。
  • 灵活性和扩展性:视频编码层专注于视频数据的有效压缩,而网络提取层则处理数据的封装、同步、错误恢复等问题,以适应不同的网络环境。
  • 适应不同的网络条件:网络提取层可以根据网络带宽、延迟和丢包率等条件,对视频数据进行适当的处理,如数据分割、打包、传输和重组。
  • 支持多种传输协议:通过分层,H.264码流可以更容易地适配多种网络传输协议,如RTP、MPEG-TS、HLS等,而无需修改编码层的实现。
  • 提高错误恢复能力:网络提取层可以实现如FEC(前向纠错)等机制,增强视频流在不可靠网络中的传输鲁棒性。
  • 支持随机访问和快速启动:通过在网络提取层插入关键帧和参数集的重复,可以支持视频流的快速启动和随机访问点的快速定位。
  • 降低复杂性:将视频编码的复杂性限制在编码层,可以使得编码器设计更加集中和高效,而网络提取层则专注于数据的传输和提取。
  • 便于实现和标准化:分层使得H.264标准更容易实现和标准化,因为每个层次可以有明确的规范和接口。
  • 支持多种应用场景:不同的应用场景可能对视频数据的存储和传输有不同的需求,分层设计可以更好地满足这些需求。
  • 提高兼容性:分层设计允许旧的系统和设备通过升级网络提取层来兼容新的编码技术和标准。

总的来说,视频编码层和网络提取层的分层设计是为了实现一个更加灵活、高效、可靠的视频编码和传输系统,以适应不断发展的技术和多样化的应用需求。

1.1 VCL层解读

VCL层 对视频原始数据进行压缩。H264视频序列可以理解为一系列的帧图像数据,将宏块有组织,有结构,有顺序的形成一系列的码流。这种码流可以通过InputStream网络流的数据进行传输,也可以封装成一个文件进行保存 。其中一帧图像从大到小依次拆解为:一帧图像->slice片组->slice片->宏块->像素。VCL结构关系如下图所示:

VCL层的关系结构

这里着重说明下涉及到的2个概念:片和宏块。具体如下:

  • 宏块(Macroblock): 宏块是视频编码中的基本处理单元,通常由16x16像素的亮度数据和两个8x8像素的色度数据块组成(相对于4:2:0色度抽样)。宏块是预测、变换和量化操作的最小单位。

    • 子块子块是宏块的子单位,可以有不同的尺寸,例如8x8、8x4、4x8或4x4像素。在宏块内,亮度数据可以被进一步划分为子块进行处理,尤其是在变换(如DCT)和量化阶段。色度数据通常也按照亮度宏块的划分方式被划分为相应的子块。

    • 宏块和子块之间的关系:宏块是由多个子块组成的。例如,在4:2:0色度抽样中,一个亮度宏块可以被划分为4个8x8像素的子块。宏块内的每个子块可以独立进行变换和量化处理,这有助于提高编码效率和适应不同的图像内容。在帧内编码中,宏块的每个子块通常会使用相同的变换和量化参数;而在帧间编码中,宏块可以包含不同类型的子块,例如,某些子块可能使用运动补偿预测,而其他子块可能不使用。
    • 宏块和子块在编码过程中的应用:在编码过程中,宏块是进行预测、运动估计和残差编码的基本单元。子块的使用允许编码器对图像的不同区域应用不同的处理策略,以适应图像的局部特性,如边缘、纹理等。

    • 宏块和子块在编码效率中的意义通过合理地划分宏块和子块,编码器可以更有效地利用变换和量化技术来减少数据量,同时保持图像质量。两者的结合使用,使得视频编码算法能够灵活地适应不同的图像内容和编码需求。

  • 片(Slice): 片是视频帧中的一个逻辑分段,可以包含一个或多个宏块。编码器可以根据内容的复杂性或编码策略将帧分割成多个片。每个片可以独立解码,有助于错误恢复和并行处理。片的分类如下:

    • I片(Intra-coded Slice): I片,或称为内码片,完全由帧内编码的宏块组成。帧内编码意味着每个宏块仅使用其自身的像素数据进行编码,不依赖于其他帧的数据。I片通常用于关键帧,即在视频序列中用于参考的帧。
    • P片(Predictive-coded Slice): P片,或称为预测编码片,由P宏块组成,这些宏块使用前向时间预测来编码。P片可包含P和I宏块,P宏块可以引用前面的I片或P片中的宏块来减少冗余,从而提高压缩效率。
    • B片(Bidirectional-coded Slice): B片,或称为双向预测编码片,由B宏块组成,这些宏块使用双向时间预测来编码。B片可包含B和I宏块,B宏块可以引用前后两个方向的帧(包括同一帧内的其他片)来进一步减少时间上的冗余。
    • 其他类型的片: 除了I、P、B片之外,还可能有其他类型的片,例如SP-Slice(Switching P-Slice)和SI-Slice(Switching I-Slice),这些片类型用于特定的编码场景,如场景切换或帧内/帧间编码的切换。

这些概念在视频编码中非常重要,因为它们决定了编码的复杂性、压缩效率和解码性能。通过合理地使用不同类型的宏块和片,编码器可以适应不同的视频内容和编码需求。

1.2 NAL层解读

NAL层: 它的作用是H264码流需要在网络上传输,在传输的过程每个包以太网是1500字节,而H264的帧往往会大于1500字节,所以要进行拆包,将一个帧拆成多个包进行传输,所有的拆包或者组包都是通过NAL层去处理的。NAL的目的可以理解为将VCL的数据封装后进行传输。NALU解读如下图所:

NAL层的关系结构

码流中 SODB、RBSP、EBSP和NALU 的概念及关系

SODB、RBSP、EBSP和NALU是一些专业术语,它们与编码的比特流和网络抽象层有关。接下来用一张图表示它们之间的关系。如下所示:

SODB、RBSP、EBSP和NALU 的概念及关系

下面是这些术语的描述和它们之间的关系:

  1. SODB(Sequence of Data Bits):SODB是数据比特的序列,长度不一定是8的倍数.它是由VCL层产生的.因为非8的倍数所以处理比较麻烦。这就导致码流数据写完后,最后写入的数据量不满一个字节。所以编码时要在未加工过的码流后,添加一个值等于1的尾部来表示码流的结束,该位称为停止位(rbsp_stop_one_bit)。然后为了字节对齐,在停止位(值为1)之后添加0位使得8位对齐,如上图所示。

  2. RBSP(Raw Byte Sequence Payload):RBSP是EBSP去掉所有的填充字节(如H.264编码中的零字节填充)后的数据。RBSP是EBSP的一个子集,用于在解码过程中去除填充字节,以便正确解码原始数据。

  3. EBSP(Encapsulate Byte Sequence Payload):EBSP是编码后的比特流有效载荷,它包含了实际的编码数据,但不包括任何头部信息或填充数据。EBSP是编码过程中生成的原始数据,包含了视频或音频帧的编码信息。

  4. NALU(Network Abstraction Layer Unit ):本质上就是NAL Header+EBSP,即在EBSP的基础上加网络头。NALU是视频编码数据的封装单元,用于将编码后的数据分割成独立的、适合网络传输的包。每个NALU包含一个头部和有效载荷(Payload)。头部信息包括NALU类型、序列参数集(SPS)或图像参数集(PPS)的引用等。NALU类型定义了其内容的性质,例如视频帧的编码数据、序列参数集、图像参数集或其他控制信息。NALU设计为可以独立解码,这有助于错误恢复和并行处理。它的数据结构。

2 NALU 码流信息详细解读

接下来更详细地解读 NALU码流。NALU包含header(头信息)和数据信息。和前面了解到 NALU 数据实际上就是EBSP,EBSP去掉所有的填充字节,处理一下得到RBSP。因此NALU数据部分我们着重分析和关注RBSP的具体内容。

2.1 NALU Header(头部信息)解读

NALU Header整体只占据一个字节。分别为:

H264编码的官方文档截图

其中:

  • forbidden_zero_bit:占1个Bit,当它为0时,解码器对这个NALU正常进行解码;当它不为 0 时,表示网络传输过程中,当前NALU中可能存在错误,解码器可以不解码这个NALU。
  • nal_ref_idc:占2个Bit,取值范围为0~3,代表当前这个NALU的重要性,取值越大,代表当前NALU越重要,就需要优先被保护。
  • nal_unit_type:占5个Bit,代表NALU Header后面的EBSP数据结构的类型,这里可以理解为NALU的数据类型。EBSP的数据类型共2^5=32种。32种类型解读如下图所示:
  • H264中 32种NALU数据的类型

2.2 NALU Data(数据信息)解读

这里着重分析RBSP码流数据信息。RBSP数据信息主要分为2大类:

  • 编码后的视频帧数据:编码后的视频帧数据指的是经过H.264编码器处理后,用于表示视频帧的压缩数据。这些数据以一种高效的格式存储,以便减少所需的存储空间和传输带宽。编码后的视频帧数据主要包括:I帧、P帧、B帧,它们是属于哥伦布编码的。
  • 一些关键的元数据:解码和显示视频帧所需的额外信息。比如 序列参数集SPS, Sequence Parameter Set,包含了整个视频序列的全局参数,如图像尺寸、帧率、色彩空间等。SPS是解码器配置视频序列解码参数的关键信息) 图像参数集PPS, Picture Parameter Set,包含了单个图像或一组图像的参数,如编码模式的选择、去块滤波器的使用、量化参数等。PPS为解码器提供了图像级别的配置信息。​​​​​​)

这些数据被封装在NAL单元中,并通过添加特定的字节对齐比特和防止竞争字节,以适应网络传输和存储的需求。

有了对NALU数据的了解,在此基础上,我们再继续了解2种常见的数据封装格式。

3 Annex格式和RTP格式解读

Annex格式和RTP(Real-time Transport Protocol)是两种不同的数据封装格式,它们在H.264视频流的组织和传输中扮演不同的角色。

3.1 Annex格式

Annex格式,也称为Annex B格式,是H.264标准中推荐的一种码流组织方式,主要用于存储介质或实时播放。它的特点包括:

  • 使用特定的开始码(Start Code)来标识每个NAL单元(NALU)的开始,这些开始码可以是3字节的0x000001或4字节的0x00000001
  • 通常在关键帧前周期性地重复序列参数集(SPS)和图像参数集(PPS),以支持视频流的随机访问。
  • 适用于连续的数据传输,如视频文件或实时流媒体,因为它允许解码器从视频流的随机点开始解码 68。

3.2 RTP格式

RTP格式是为网络传输设计的,特别是适用于IP网络。RTP格式的特点包括:

  • 将NALU封装在RTP包中,每个RTP包包含一个或多个NALU。
  • RTP包头包含了用于实时传输的关键信息,如时间戳、序列号等。
  • 支持NALU的分割和组装,以适应不同的网络环境和传输效率。
  • 根据RFC 3984,RTP封装的H.264视频流可以有效地在IP网络上进行传输和控制 12。

3.3 Annex格式和RTP格式之间关系与差异

  • 关系:Annex格式和RTP格式都可以包含H.264的NALU,但是它们的封装方式和应用场景不同。Annex格式更适合存储和实时播放,而RTP格式更适合网络传输。
  • 差异
    • 开始码:Annex格式使用固定的开始码来标识NALU的边界,而RTP格式使用RTP包头和可能的NALU长度前缀。
    • 实时性:RTP格式提供了更好的实时传输支持,包括时间戳和序列号等信息。
    • 应用场景:Annex格式常用于视频文件和实时流,RTP格式用于基于IP的网络传输。

总的来说,Annex格式和RTP格式都是H.264视频流的有效封装方式,选择哪一种取决于具体的应用需求和传输环境。

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

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

相关文章

Nginx进阶-常见配置(二)

一、nginx 日志配置 nginx 日志介绍 nginx 有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志, 所需日志模块 ngx_http_log_module 的支持,日志格式通过 log_format 命令来定义,日志对于统计和排错是非常有利的,下面总…

【TwinCAT3教程】TwinCAT3 PLC 简单程序编写与调试

一、PLC 简单程序编写 1.1 新建TwinCAT3项目 (1)打开 TwinCAT 3,点击 New TwinCAT Project 新建 TC3 项目。 (2)选择 TwinCAT Project,输入项目名称和项目保存路径,然后点击确定。 1.2 添加PLC项目 1.2.1 步骤 (1)在树形资源管理器右键点击 PLC,选择 添加新项 新…

STM32F28335实验:继电器

继电器控制电机&#xff1a; 5s启动 5s停止 循环 管脚图&#xff1a; 管脚用的是GPIO15 驱动&#xff1a; beep.c /** leds.c** Created on: 2024年8月2日* Author: Administrator*/#include<relay.h>/***************************************************…

【算法设计题】查找给定结点的双亲结点(二叉树),第3题(C/C++)

目录 第3题 查找给定结点的双亲结点&#xff08;二叉树&#xff09; 得分点&#xff08;必背&#xff09; 题解 定义函数和初始化变量&#xff1a; 处理特殊情况&#xff1a; 遍历树&#xff1a; 中序遍历左子树&#xff1a; 处理右子树&#xff1a; 返回结果&#x…

LSTM实战之预测股票

&#x1f4c8; 用PyTorch搭建LSTM模型&#xff0c;轻松预测股票价格&#xff01;&#x1f680; Hey小伙伴们&#xff0c;今天给大家带来一个超级实用的项目教程——如何用PyTorch和LSTM模型来预测股票价格&#xff01;&#x1f31f; &#x1f50d; 项目背景 我们都知道股市是…

《Unity3D网络游戏实战》学习与实践--制作一款大乱斗游戏

角色类 基类Base Human是基础的角色类&#xff0c;它处理“操控角色”和“同步角色”的一些共有功能&#xff1b;CtrlHuman类代表“操控角色”​&#xff0c;它在BaseHuman类的基础上处理鼠标操控功能&#xff1b;SyncHuman类是“同步角色”类&#xff0c;它也继承自BaseHuman&…

MySQL的数据结构B+tree以及SQL优化

首先呢&#xff0c;我们知道MySQL的数据结构为Btree,那么其结构究竟是什么样的&#xff0c;为什么选择Btree&#xff0c;而不选择Btree。下面我们从其结构分析 1.Btree平衡多路查找树 B-tree结构的数据可以让系统高效的找到数据所在的磁盘块。为了描述B-Tree,首先定义一条记录…

入门mem0.NET

入门mem0.NET 安装包 如果你的项目使用了EntityFrameworkCore,那么你可以跟随这个教程走 <ItemGroup><PackageReference Include"mem0.NET" Version"0.1.7" /><PackageReference Include"mem0.NET.Qdrant" Version"0.1.7…

云动态摘要 2024-08-04

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 数据库上云优选 阿里云 2024-07-04 RDS、PolarDB、Redis、MongoDB 全系产品新用户低至首年6折起&#xff01; [免费体验]智能助手ChatBI上线 腾讯云 2024-07-02 基于混元大模型打造&…

java之IO篇——File、字节流、字符流

前言 IO流是用于读写文件中的数据&#xff0c;要读写文件之前可以创建文件获取文件对象再创建IO流&#xff0c;正文会先介绍File类&#xff0c;通过File类的构造方法获取文件的对象&#xff0c;创建文件或目录以及File类的一些方法获取文件对象的属性。后面还介绍了相关的IO流体…

Radxa ROCK 3C开发板编译Opencv,支持调用树莓派摄像头模块V2

目录 1、ROCK 3C和树莓派摄像头模块V2介绍2、ROCK 3C在rsetup开启支持3、测试指令4、编译Opencv4.1 增加swap&#xff0c;确保内存够用4.2 安装依赖和下载opencv4.3 编译参考链接 5、使用opencv调用树莓派摄像头模块V2 1、ROCK 3C和树莓派摄像头模块V2介绍 ROCK 3C 是一款基于…

刷题篇 - 01

目录 题目一&#xff1a; 题目二&#xff1a; 题目三&#xff1a; 题目四&#xff1a; 题目五&#xff1a; 题目六&#xff1a; 题目七&#xff1a; 题目一&#xff1a; 387. 字符串中的第一个唯一字符 - 力扣&#xff08;LeetCode&#xff09; public int firstUniqC…

订单定时状态处理业务(SpringTask)

文章目录 概要整体架构流程技术细节小结 概要 订单定时状态处理通常涉及到对订单状态进行定期检查&#xff0c;并根据订单的状态自动执行某些操作&#xff0c;比如关闭未支付的订单、自动确认收货等. 需求分析以及接口设计 需求分析 用户下单后可能存在的情况&#xff1a; …

鸿蒙(API 12 Beta2版)NDK开发【内存管理purgeable内存开发指导】

场景介绍 HarmonyOS提供Purgeable Memory内存管理机制&#xff0c;开发者可以使用相关接口创建PurgeableMemory对象&#xff0c;从而管理purgeable内存。 开发者可以通过本指导了解在HarmonyOS应用中&#xff0c;如何使用Native层相关接口操作purgeable内存。功能包括purgeab…

Jupyter-Notebook常用操作看这一篇就够啦

来源&#xff1a; “码农不会写诗”公众号 链接&#xff1a;Jupyter-Notebook常用操作看这一篇就够啦 文章目录 01 概括02 快捷键总结03 运行外部python文件04 魔法命令4.1 运行计时4.2 查看变量与函数4.3 其它常用指令 书接上文 Jupyter-Notebook是一个基于 Web 的交互式开发环…

第十四节、受伤、死亡的逻辑和动画

一、受伤的动画效果 1齿轮控制当前动画图层的权重 2、层级 当前动画层为add&#xff0c;所以不会覆盖之前的动画层&#xff0c;而是添加一个动画层 3、受伤闪烁 调用颜色的值&#xff0c;实现受伤闪烁 4、录制动画 点击时间轴&#xff0c;插入关键帧 伤害图层选择add&…

2024华数杯C题解题思路、参考论文已出(无偿分享)~

C题&#xff1a;老外游中国 “数模加油站”团队出品~ 问题1&#xff1a; 解题思路&#xff1a; 1、数据准备&#xff1a; 导入352个城市的csv文件&#xff0c;提取每个城市中的100个景点的信息。 将每个景点的评分数据提取出来&#xff0c;形成一个包含35200个景点评分的列…

centos虚拟机restart网络后隔一会断联

1. 前言 不知道各位有没有遇到过虚拟机网络设置的坑&#xff0c;往往前一段时间用的好好的&#xff0c;突然网络又不行了无法连接外部网络&#xff0c;而且使用 service network restart 一瞬间可以&#xff0c;但是过一会就断连了… 2. 解决方案 根据对虚拟机网络的学习了解…

五、一个quad同时支持pcie和sfp两种高速接口的ref时钟配置

项目描述 上位机将截图数据通过 XDMA 写入到 FPGA 侧的 DDR 内存区域 1 中通过 axi_lite 接口给 axi_read_start 信号&#xff0c;通知 AXI_read 模块启动读取数据&#xff0c;然后通过 GTP TX 模块发送出去。经过光纤回环&#xff0c;GTP RX 端接收到数据&#xff0c;送给 AX…

今天的一件小事,亲身感受:付费是提高效率的重要途径

今天需要修改一个单页网站源码&#xff0c;有一个小问题困住我3个小时了。 毕竟我也不是专业的&#xff0c;没有系统学习过这些&#xff0c;搜答案都不知道怎么搜哈哈 吃过午饭&#xff0c;想着不能这么耗下去了&#xff0c;于是及时去了某宝&#xff0c;找到一个修改代码的 …