H.264数据结构分析

一、H.264 码流层次结构

H.264 标准将视频数据分为两大层:

  1. VCL(Video Coding Layer):负责视频内容的压缩编码(如帧、宏块、预测、变换等)。
  2. NAL(Network Abstraction Layer):负责将 VCL 数据封装成适合网络传输的单元(NAL 单元)。

二、NAL 单元结构

1. NAL 单元定义

每个 H.264 码流由一系列 NAL 单元组成。每个 NAL 单元包括:

  • 起始码前缀0x000001 或 0x00000001
  • NAL Header:1 字节
  • Payload:具体数据(如 SPS、PPS、Slice 等)

2. NAL Header 结构

Bit名称说明
1forbidden_zero_bit必须为 0
2nal_ref_idc参考优先级(0~3)
5nal_unit_type单元类型(如 SPS=7, PPS=8, IDR=5, 非IDR=1等)

示例:NAL Header 字节结构

+----------------+----------------+----------------+
| 1bit           | 2bit           | 5bit           |
| forbidden_zero | nal_ref_idc    | nal_unit_type  |
+----------------+----------------+----------------+

3. NAL 单元类型(常见)

类型名称说明
1非IDR片段普通编码帧(P/B帧)
5IDR片段关键帧(I帧)
6SEI辅助增强信息
7SPS序列参数集
8PPS图像参数集
9分隔符分隔NAL单元

三、SPS/PPS 数据结构

1. SPS(Sequence Parameter Set)

  • 描述一组视频序列的全局参数(如分辨率、帧率、色彩格式、参考帧数等)
  • 只需解析一次,后续帧均可复用

SPS 结构常见字段:

  • profile_idc(编码配置文件)
  • level_idc(编码等级)
  • seq_parameter_set_id
  • log2_max_frame_num_minus4
  • pic_order_cnt_type
  • frame_mbs_only_flag
  • pic_width_in_mbs_minus1
  • pic_height_in_map_units_minus1
  • vui_parameters_present_flag(可选,包含宽高比、帧率等)

SPS示例解析:

profile_idc: 100
level_idc: 40
pic_width_in_mbs_minus1: 79  // 宽度 = (79+1)*16 = 1280
pic_height_in_map_units_minus1: 44 // 高度 = (44+1)*16 = 720

2. PPS(Picture Parameter Set)

  • 描述一组图像的参数(如熵编码方式、量化参数等)
  • 可为不同Slice指定不同PPS

PPS结构常见字段:

  • pic_parameter_set_id
  • seq_parameter_set_id
  • entropy_coding_mode_flag(0:CAVLC, 1:CABAC)
  • num_slice_groups_minus1
  • num_ref_idx_l0_active_minus1
  • weighted_pred_flag
  • deblocking_filter_control_present_flag

四、Slice 结构

1. Slice Header

每个 Slice(片)包含一个头部,描述当前片的信息:

  • first_mb_in_slice:本片第一个宏块编号
  • slice_type:I/P/B/…
  • pic_parameter_set_id:PPS编号
  • frame_num:帧号
  • idr_pic_id:IDR帧编号
  • slice_qp_delta:量化参数调整
  • direct_spatial_mv_pred_flag:空间预测标志

2. Slice 数据

  • 由一系列宏块(Macroblock)组成
  • 每个宏块包含类型、运动矢量、预测模式、残差数据等

五、宏块(Macroblock)结构

1. 宏块类型

  • I宏块:帧内预测
  • P宏块:帧间预测
  • B宏块:双向预测

2. 宏块字段

  • mb_type:宏块类型
  • mb_pred:预测模式(帧内/帧间,块划分方式)
  • mb_qp_delta:本宏块的量化参数调整
  • mb_mv:运动矢量(帧间宏块)
  • mb_residual:变换残差数据

3. 分块结构

  • 宏块可进一步分为 16x16, 8x8, 4x4 等大小的子块
  • 每个子块有单独的预测、变换、量化参数

六、码流分析举例

以原始 H.264 码流为例,常见结构如下:

00 00 00 01 [NAL Header] [SPS 数据]
00 00 00 01 [NAL Header] [PPS 数据]
00 00 00 01 [NAL Header] [IDR Slice 数据]
00 00 00 01 [NAL Header] [Non-IDR Slice 数据]
...

可用工具(如 H264Visa、Elecard StreamEye)解析,得到:

  • NAL 单元类型分布
  • SPS/PPS内容
  • 每帧的Slice结构和宏块信息

七、码流分析工具操作

1. 用 H264Visa 分析

  • 打开 .264 文件
  • 查看 NAL 单元列表,识别 SPS、PPS、IDR、P/B帧
  • 点击帧,可见 Slice Header、宏块分布、运动矢量等详细数据

2. 用 FFmpeg 查看结构

ffprobe -show_packets -select_streams v input.h264

可输出每个 NAL 单元的类型和偏移。


八、进阶:NAL 单元与容器格式

  • 原始 H.264 码流是 NAL 单元拼接
  • MP4、TS 等封装格式会对 NAL 单元做打包(去掉起始码,加入长度前缀)

九、SPS(Sequence Parameter Set)详细字段解析

1. SPS 字段顺序(简化版)

字段名说明
profile_idc配置文件(如66=baseline, 77=main, 100=high)
constraint_set_flags配置约束标志
level_idc等级(如30, 31, 40, 41, 50等)
seq_parameter_set_idSPS编号
log2_max_frame_num_minus4最大帧号
pic_order_cnt_typePOC类型
pic_width_in_mbs_minus1宽度(以16像素为单位)
pic_height_in_map_units_minus1高度(以16像素为单位)
frame_mbs_only_flag仅帧编码标志
direct_8x8_inference_flag8x8预测推断标志
frame_cropping_flag裁剪标志
vui_parameters_present_flagVUI参数存在标志

2. SPS 二进制举例

假设有一段 SPS 数据(16进制):

67 42 00 1e 95 a8 14 01 6e 9b 80 80 80 a0 01 00 04 68 ce 3c 80
  • 67:NAL Header(type=7,SPS)
  • 42:profile_idc = 66(baseline)
  • 00:constraint_set_flags = 0
  • 1e:level_idc = 30
  • …(后续为sps字段,需Exp-Golomb解码)

真实解析通常需要用 bitstream 工具或代码逐比特分析。

3. SPS 字段解析工具


十、PPS(Picture Parameter Set)字段详细解析

字段名说明
pic_parameter_set_idPPS编号
seq_parameter_set_id所属SPS编号
entropy_coding_mode_flag0=CAVLC, 1=CABAC
num_slice_groups_minus1Slice组数-1
num_ref_idx_l0_active_minus1L0参考帧数-1
weighted_pred_flag加权预测标志
deblocking_filter_control_present_flag去块滤波控制标志

PPS 也需用 Exp-Golomb 解码,通常紧随 SPS 后出现。


十一、Slice Header 字段详细解析

每个 Slice(NAL type=1或5)都有头部,主要字段如下:

字段名说明
first_mb_in_slice当前Slice第一个宏块编号
slice_typeSlice类型(I/P/B/…)
pic_parameter_set_idPPS编号
frame_num帧号
idr_pic_idIDR帧编号(仅IDR帧)
pic_order_cnt_lsbPOC低位计数
slice_qp_delta量化参数偏移

Slice Header 之后紧跟着宏块数据。

Slice Header 解析举例

假设 Slice Header 二进制如下:

00 00 00 01 65 88 84 00 0a f2 ...
  • 65:NAL Header(type=5,IDR帧)
  • 88 84 00 0a f2 …:Slice Header及后续数据

用 H264Visa 打开后可看到 first_mb_in_slice=0, slice_type=I, frame_num=0 等。


十二、宏块(Macroblock)结构与数据

1. 宏块基本结构

字段名说明
mb_type宏块类型(Intra/Inter)
mb_pred预测信息(模式、参考帧等)
mb_qp_delta量化参数调整
mb_mv运动矢量(Inter宏块)
mb_residual残差(变换系数)

2. 宏块类型举例

  • I_16x16:帧内16x16预测
  • I_4x4:帧内4x4预测
  • P_L0_16x16:帧间16x16预测
  • P_L0_L0_8x8:帧间8x8预测

3. 宏块残差与运动矢量

  • 残差通过变换、量化后存储
  • 运动矢量为 Inter 宏块指定参考帧及偏移

4. 宏块数据解析工具

  • H264Visa:可显示每个宏块的类型、预测模式、运动矢量、残差等
  • StreamEye:可可视化宏块划分和运动矢量分布

十三、实际码流结构举例

00 00 00 01 67 ...      // SPS
00 00 00 01 68 ...      // PPS
00 00 00 01 65 ...      // IDR Slice(I帧)
00 00 00 01 41 ...      // 非IDR Slice(P/B帧)
...

每个 NAL 单元可被工具逐项解析,SPS/PPS 只需解一次,Slice/宏块每帧解码。


十四、码流分析实操建议

  1. 用 H264Visa 打开 .264 文件

    • 查看 NAL 单元分布,定位 SPS/PPS/Slice
    • 选中 Slice,浏览 Header 和宏块详细信息
    • 可导出宏块分布和运动矢量图
  2. 用 FFprobe 查看 NAL 单元类型

    ffprobe -show_packets -select_streams v input.h264
    
  3. 用在线 SPS/PPS 解析器粘贴 NAL 数据,查看参数含义


十五、H.264 码流二进制解析流程概览

  1. 找到起始码(0x000001 或 0x00000001)
  2. 读取 NAL Header,判断类型
  3. 若为 SPS/PPS,按 Exp-Golomb 编码解析参数
  4. 若为 Slice,先解析 Slice Header,再逐宏块解码
  5. 宏块数据需结合预测、运动矢量、残差等信息联合解码

十六、进阶推荐

  • 阅读 H.264 标准附录A(码流语法)和附录B(NAL单元封装)
  • 用 x264 编码一段视频,导出 .264 文件,逐字节分析 SPS/PPS/Slice
  • 结合码流分析工具与标准文档,对照理解每个字段和实际数据
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猩火燎猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值