H264原始码流格式分析
1.H264码流结构组成
H.264裸码流(Raw Bitstream)数据主要由一系列的NALU(网络抽象层单元)组成。每个NALU包含一个NAL头和一个RBSP(原始字节序列载荷)。
1.1 H.264码流层次
H.264码流的结构可以分为两个层次:VCL(视频编码层)和NAL(网络抽象层)。下图为H.264码流中的层次图:
VCL层:负责对视频的原始数据进行压缩。VCL数据编码器直接输出的原始数据比特串(SODB),表示图像被压缩后的编码比特流。
- SODB:生成压缩原始的图像编码数据比特串。
- 编码图像:宏块进行的帧内编码/帧间编码/熵编码等处理。
NAL层:负责将VCL数据封装成NAL单元(NALU),并在网络上传输或存储到磁盘上。每个NAL单元之前需要添加StartCodePrefix,形成H.264码流。NAL层还处理拆包和组包的工作,以适应网络传输的最大传输单元(通常为1500字节)。
1.2 NALU网络层组成
一个NALU由两个主要部分组成:
-
头部(Header):
NALU的头部包含了关于该单元的一些元数据信息,例如NAL单元类型(如序列参数集、图像参数集、帧数据单元等),NALU的优先级、参考帧标识、重要性指示等。头部的信息有助于解码器正确解析和处理每个NAL单元。
-
载荷(Payload):
NALU的载荷部分包含了实际的编码数据。这些数据可以是帧的视频数据、补充增强信息或其他特定于编码标准的数据。在视频解码过程中,解码器通过解析头部信息来识别NALU的类型,并且根据类型和载荷数据进行相应的解码和处理。
在H.264/AVC中,定义了多种NALU的类型,以适应不同的应用场景。常见的类型包括:
帧内预测(I)片:仅使用当前帧的信息进行编码。
预测(P)片:使用前一帧的信息进行编码。
双向预测(B)片:使用前一帧和后一帧的信息进行编码。
1.3 序列参数集SPS
序列参数集(Sequence Parameter Set,SPS)包含了描述视频序列全局参数的信息,这些参数对于解码器正确解码视频流至关重要。以下是SPS的一些主要内容和结构:
- profile_idc:标识H.264码流的profile,例如Baseline、Main、High等。
- level_idc:标识码流的Level,定义了最大分辨率、最大帧率等参数。
- seq_parameter_set_id:序列参数集的ID,用于标识不同的SPS。
- log2_max_frame_num_minus4:用于计算frame_num的最大值,frame_num标识图像的解码顺序。
- pic_order_cnt_type:指明图像播放顺序的编码方法。
- log2_max_pic_order_cnt_lsb_minus4:用于计算POC(Picture Order Count)的最大值。
- max_num_ref_frames:指定参考帧队列的最大长度。
- gaps_in_frame_num_value_allowed_flag:指示是否允许frame_num不连续。
- pic_width_in_mbs_minus1:图像宽度,以宏块为单位。
- pic_height_in_map_units_minus1:图像高度,以宏块为单位。
SPS中的信息对于解码器初始化和正确解码视频流至关重要。如果SPS数据丢失或损坏,解码器可能无法正确解码视频。
1.4 图像参数集PPS
图像参数集(Picture Parameter Set,PPS)包含了与单个图像编码相关的参数,这些参数用于控制图像的编码方式。以下是PPS的一些主要内容和结构:
- pic_parameter_set_id:当前PPS的唯一ID,取值范围为0-255。
- seq_parameter_set_id:指明该PPS对应的SPS(序列参数集)ID。
- entropy_coding_mode_flag:表示使用的熵编码类型,0为CAVLC,1为CABAC。
- num_slice_groups_minus1:表示slice group的数量,通常为0。
- num_ref_idx_l0_default_active_minus1和num_ref_idx_l1_default_active_minus1:表示P/B slice的前向和后向参考帧的最大个数减1。
- weighted_pred_flag:表示P slice的预测权重方式,0为默认预测权重,1为显式方式。
- weighted_bipred_flag:表示B slice的预测权重方式,0为默认预测权重,1为显式方式,2为隐式方式。
- pic_init_qp_minus26:用于计算Y分量的初始QP值。
- chroma_qp_index_offset:表示Cb分量QP相对于slice QP的偏移量。
- deblocking_filter_control_present_flag:表示是否存在去块效应滤波器的控制语法元素。
- constrained_intra_pred_flag:表示帧内预测方式是否存在限制条件。
- transform_8x8_mode_flag:表示是否使用8x8大小的DCT变换方式。
- pic_scaling_matrix_present_flag:表示量化参数矩阵是否存在。
- second_chroma_qp_index_offset:表示Cr分量QP相对于slice QP的偏移量。
PPS中的信息对于解码器正确解码视频流至关重要。PPS通常紧跟在SPS之后,并且可以有多个,因为不同的slice group可能有不同的参数设置。
2.常用的两种NALU格式
2.1 AnnexB
AnnexB是一种常见的NALU(网络抽象层单元)封装格式,主要用于H.264和H.265视频编码标准。AnnexB格式的基本结构如下:
[开始代码] [NALU单元] [开始代码] [NALU单元] ...
每个NALU单元由一个开始代码和随后的原始字节数据组成,通过分隔符0x00 00 00 01或者0x00 00 01区分不同的NALU单元。如果在RBSP(原始字节流载荷)中出现了0x000000、0x000001、0x000002或0x000003这样的序列,就需要插入一个0x03字节来避免这些序列被误识别。例如,将0x000001变成0x00000301,这样在解码时可以去除0x03字节,恢复原始数据。这种方法确保了数据的完整性和正确解码。例如:
-
原始数据:
0x000001
插入“模拟预防”字节后:0x00000301
解码时去除0x03字节,恢复为:0x000001
-
原始数据:
0x000000
插入“模拟预防”字节后:0x00000300
解码时去除0x03字节,恢复为:0x000000
-
原始数据:
0x000002
插入“模拟预防”字节后:0x00000302
解码时去除0x03字节,恢复为:0x000002
-
原始数据:
0x000003
插入“模拟预防”字节后:0x00000303
解码时去除0x03字节,恢复为:0x000003
如果插入的数据本身包含了“模拟预防”字节(例如0x00000301),编码器会将其转义为0x0000030301。
2.2 AVCC
AVCC(AVC Configuration)格式是一种用于存储和传输H.264视频流的格式,通常用于MP4、MKV等容器中。与Annex B格式不同,AVCC格式不使用起始码(start code)来分隔NALU(网络抽象层单元),而是使用NALU长度前缀。
AVCC格式结构:
- 头部信息(extradata):
- 包含SPS(序列参数集)和PPS(图像参数集)等参数信息。
- 头部信息的格式如下:
- 第1字节:版本号(通常为0x01)
- 第2字节:AVC Profile(与第一个SPS的第2字节相同)
- 第3字节:AVC Compatibility(与第一个SPS的第3字节相同)
- 第4字节:AVC Level(与第一个SPS的第4字节相同)
- 第5字节:保留位(前6位全1),后2位表示NALU长度字段的字节数减1(通常为3,即4字节)
- 第6字节:保留位(前3位全1),后5位表示SPS的个数(通常为1)
- 后续字节:SPS数据(包括16位SPS长度和SPS NALU数据)
- PPS数据(包括16位PPS长度和PPS NALU数据)
- NALU数据:
- 每个NALU前面都有一个长度前缀(通常为4字节),表示该NALU的长度。
- NALU数据不包含起始码。
假设有一个NALU数据为0x65 88 84 21
,其长度为4字节。在AVCC格式中,这个NALU会被存储为:
0x00 00 00 04 65 88 84 21
其中,0x00 00 00 04
表示NALU的长度为4字节,后面的65 88 84 21
是实际的NALU数据。
在解析AVCC格式时,需要先读取头部信息(extradata),然后根据NALU长度前缀来提取每个NALU的数据。
2.3 AnnexB和AVCC的优缺点
Annex B和AVCC是H.264视频编码中常见的两种NALU(网络抽象层单元)封装格式。它们各有优缺点,适用于不同的应用场景。以下是它们的优劣之处:
Annex B | |
---|---|
优点 | 简单直接:使用起始码(start code)0x000001 或0x00000001 来分隔NALU,便于解析和同步。广泛支持:许多硬件解码器和流媒体协议(如RTSP、RTP)默认支持Annex B格式。 实时流媒体:适合实时流媒体传输,因为起始码可以快速定位NALU的边界。 |
缺点 | 额外开销:起始码会增加一些额外的字节,导致数据冗余。 不适合文件存储:在文件存储中,起始码的存在可能会增加文件大小,不如AVCC格式高效。 |
AVCC | |
---|---|
优点 | 高效存储:使用NALU长度前缀(通常为4字节)来标识NALU的长度,减少了数据冗余,适合文件存储。 灵活性高:适用于多种容器格式(如MP4、MKV),便于在不同平台和设备之间传输和存储。 标准化:AVCC格式在许多多媒体框架和库(如FFmpeg、GStreamer)中得到广泛支持。 |
缺点 | 解析复杂:需要解析NALU长度前缀,增加了解码器的复杂性。 实时性较差:不如Annex B格式适合实时流媒体传输,因为需要额外的步骤来解析NALU长度。 |
选择建议
- 实时流媒体传输:推荐使用Annex B格式,因其简单直接,便于实时解析和同步。
- 文件存储和传输:推荐使用AVCC格式,因其高效存储和灵活性,适合在不同平台和设备之间传输和存储。
3.码流中的重要参数
3.1 量化参数(QP值)
QP(Quantization Parameter,量化参数)是H.264视频编码中用于控制视频压缩的质量和比特率。QP值直接影响视频的量化步长(Qstep),从而影响视频的压缩程度和图像质量。QP值的作用:
- 控制压缩质量:QP值越小,量化越精细,保留的图像细节越多,视频质量越高,但比特率也越高。相反,QP值越大,量化越粗糙,丢失的细节越多,视频质量下降,但比特率降低。
- 调节比特率:通过调整QP值,可以在视频质量和比特率之间找到一个平衡点,以满足不同的应用需求。
QP值的范围,在H.264标准中,QP值的取值范围为0到51:
- QP = 0:量化最精细,视频质量最高,比特率最大。
- QP = 51:量化最粗糙,视频质量最低,比特率最小。
假设你有一个视频片段,使用不同的QP值进行编码:
- QP = 20:视频质量较高,细节保留较多,但比特率较高。
- QP = 40:视频质量较低,细节丢失较多,但比特率较低。
QP值与量化步长(Qstep)之间存在一个对数关系。具体来说,QP每增加6,Qstep大约增加一倍。这个关系使得编码器可以在不同的QP值下灵活调整视频的压缩程度。
- 低QP值:适用于需要高质量视频的场景,如高清电影、专业视频制作。
- 高QP值:适用于对比特率要求较高的场景,如实时视频传输、低带宽环境。
3.2 码率
码率(Bitrate)是指单位时间内传输的数据量,通常以kbps(千比特每秒)或Mbps(兆比特每秒)为单位。码率在视频和音频编码中起着至关重要的作用,直接影响到文件的质量和大小。
- 视频质量:码率越高,视频质量越好,因为更多的数据可以用来表示图像细节。反之,码率越低,视频质量越差。
- 文件大小:码率越高,文件大小越大。对于同一段视频,较高的码率会导致更大的文件。
- 传输效率:在流媒体传输中,码率决定了视频流的带宽需求。较高的码率需要更高的网络带宽。
码率的基本计算公式为:
码率 (kbps)=\frac{文件大小 (KB)×8}{时间 (秒)}
码率控制模式:
- 恒定码率(CBR):码率在整个视频中保持恒定,适用于带宽稳定的环境。
- 可变码率(VBR):码率根据视频内容的复杂度动态调整,通常在保证质量的同时节省带宽。
- 平均码率(ABR):在指定的文件大小内,动态调整码率以平衡质量和文件大小。
假设一个视频文件大小为500MB,时长为10分钟(600秒),其码率计算如下:
码率 (kbps)=\frac{500×1024×8}{600}≈6826.67 kbps
如何选择合适的码率?
- 高质量需求:如高清电影、专业视频制作,建议使用较高的码率。
- 实时传输:如视频会议、直播,建议使用适中的码率以平衡质量和带宽需求。
- 低带宽环境:如移动网络,建议使用较低的码率以减少缓冲和卡顿。
相关文章:

H264原始码流格式分析
1.H264码流结构组成 H.264裸码流(Raw Bitstream)数据主要由一系列的NALU(网络抽象层单元)组成。每个NALU包含一个NAL头和一个RBSP(原始字节序列载荷)。 1.1 H.264码流层次 H.264码流的结构可以分为两个层…...

JAVA 接口、抽象类的关系和用处 详细解析
接口 - Java教程 - 廖雪峰的官方网站 一个 抽象类 如果实现了一个接口,可以只选择实现接口中的 部分方法(所有的方法都要有,可以一部分已经写具体,另一部分继续保留抽象),原因在于: 抽象类本身…...

反向代理模块b
1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求,然后将请求转发给内部网络上的服务器,将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说,反向代理就相当于…...
Nuitka打包python脚本
Python脚本打包 Python是解释执行语言,需要解释器才能运行代码,这就导致在开发机上编写的代码在别的电脑上无法直接运行,除非目标机器上也安装了Python解释器,有时候还需要额外安装Python第三方包,相当麻烦。 事实上P…...
pytorch线性回归模型预测房价例子
import torch import torch.nn as nn import torch.optim as optim import numpy as np# 1. 创建线性回归模型类 class LinearRegressionModel(nn.Module):def __init__(self):super(LinearRegressionModel, self).__init__()self.linear nn.Linear(1, 1) # 1个输入特征&…...
练习题 - DRF 3.x Caching 缓存使用示例和配置方法
在构建现代化的 Web 应用程序时,性能优化是一个非常重要的环节。尤其是在使用 Django Rest Framework (DRF) 开发 API 服务时,合理地利用缓存技术可以显著提高应用的响应速度和减轻数据库的负担。DRF 提供了多种缓存机制,包括基于内存、文件系统、数据库以及第三方缓存服务(…...

如何解压7z文件?8种方法(Win/Mac/手机/网页端)
7z 文件是一种高效的压缩文件格式,由 7 - Zip 软件开发者所采用。它运用独特的压缩算法,能显著缩小文件体积,便于存储与传输各类数据,像软件安装包、大型资料集等。但要使用其中内容,就必须解压,因为处于压…...

python学opencv|读取图像(五十)使用addWeighted()函数实现图像加权叠加效果
【1】引言 前序学习进程中,学习了图像互相叠加的不同操作方法,包括add()函数直接叠加BGR值和使用bitwise()函数对BGR值进行按位计算叠加等,相关文章链接包括且不限于: python学opencv|读取图像(四十二)使…...

window中80端口被占用问题
1,查看报错信息 可以看到在启动项目的时候,8081端口被占用了,导致项目无法启动。 2,查看被占用端口的pid #语法 netstat -aon|findstr :被占用端口#示例 netstat -aon|findstr :8080 3,杀死进程 #语法 taikkill /pid…...
06-机器学习-数据预处理
数据清洗 数据清洗是数据预处理的核心步骤,旨在修正或移除数据集中的错误、不完整、重复或不一致的部分,为后续分析和建模提供可靠基础。以下是数据清洗的详细流程、方法和实战示例: 一、数据清洗的核心任务 问题类型表现示例影响缺失值数值…...

电梯系统的UML文档12
5.2.1 DoorControl 的状态图 图 19: DoorControl 的状态图 5.2.2 DriveControl 的状态图 图 20: DriveControl 的状态图 5.2.3 LanternControl 的状态图 图 21: LanternControl 的状态图 5.2.4 HallButtonControl 的状态图 图 22: HallButtonControl 的状态图 5.2.5 CarB…...

萌新学 Python 之运算符
Python 中运算符包括:算术运算符、比较运算符、逻辑运算符、赋值运算符、位运算符、海象运算符 算术运算符:加 减 - 乘 * 除 / 取整 // 求余 % 求幂 ** 注意:取整时,一正一负整除,向下取整 比如 5 // …...

嵌入式知识点总结 Linux驱动 (五)-linux内核
针对于嵌入式软件杂乱的知识点总结起来,提供给读者学习复习对下述内容的强化。 目录 1.内核镜像格式有几种?分别有什么区别? 2.内核中申请内存有哪几个函数?有什么区别? 3.什么是内核空间,用户空间&…...

zabbix7 配置字体 解决中文乱码问题(随手记)
目录 问题网传的方法(无效)正确的修改方式步骤 问题 zabbix 最新数据 中,图标的中文显示不出。 网传的方法(无效) 网传有一个方法:上传字体文件到/usr/share/zabbix/assets/fonts;修改/usr/…...

预测不规则离散运动的下一个结构
有一个点在19*19的平面上运动,运动轨迹为 一共移动了90步,顺序为 y x y x y x 0 17 16 30 10 8 60 15 15 1 3 6 31 10 7 61 14 15 2 12 17 32 9 9 62 16 15 3 4 12 33 10 9 63 18 15 4 3 18 34 15 12 6…...

CTFSHOW-WEB入门-命令执行29-32
题目:web 29 题目:解题思路:分析代码: error_reporting(0); if(isset($_GET[c])){//get一个c的参数$c $_GET[c];//赋值给Cif(!preg_match("/flag/i", $c)){eval($c);//if C变量里面没有flag,那么就执行C…...

SQL Server 建立每日自动log备份的维护计划
SQLServer数据库可以使用维护计划完成数据库的自动备份,下面以在SQL Server 2012为例说明具体配置方法。 1.启动SQL Server Management Studio,在【对象资源管理器】窗格中选择数据库实例,然后依次选择【管理】→【维护计划】选项࿰…...
doris:HLL
HLL是用作模糊去重,在数据量大的情况性能优于 Count Distinct。HLL的导入需要结合hll_hash等函数来使用。更多文档参考HLL。 使用示例 第 1 步:准备数据 创建如下的 csv 文件:test_hll.csv 1001|koga 1002|nijg 1003|lojn 1004|lofn …...

双层Git管理项目,github托管显示正常
双层Git管理项目,github托管显示正常 背景 在写React项目时,使用Next.js,该项目默认由git托管。但是我有在项目代码外层记笔记的习惯,我就在外层使用了git托管。 目录如下 code 层内也有.git 文件,对其托管。 我没太在意&…...

准备知识——旋转机械的频率和振动基础
旋转频率,也称为转速或旋转速率(符号ν,小写希腊字母nu,也作n),是物体绕轴旋转的频率。其国际单位制单位是秒的倒数(s −1 );其他常见测量单位包括赫兹(Hz)、每秒周期数(cps) 和每分钟转数(rpm)…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...