每个 NAL 单元的第一个字节就是它的身份证:1 位禁用位、2 位优先级、5 位类型——类型 7 是 SPS、8 是 PPS、5 是 IDR 片。
9.3.2 讲了码流的排列顺序,这一节把单个单元拆到字节位。
一、NAL 头的三个字段
NAL 单元的第一个字节按位切成三段: 第 1 位:forbidden_zero_bit——禁用位,正常码流里必须是 0; 第 2~3 位:nal_ref_idc——优先级,越大越重要; 第 4~8 位:nal_unit_type——类型,决定这个单元装的是什么。 一个字节就把【合法性、重要性、用途】三件事说清楚了——这是很典型的一处紧凑设计。
二、类型值的含义
常用的 nal_unit_type 取值并不多:
1——非 IDR 片,普通的 P/B 片数据;
5——IDR 片,拖动的落脚点(第 6.5.1 节);
6——SEI,补充增强信息,装时间戳、HDR 元数据之类;
7——SPS,序列参数集;
8——PPS,图像参数集;
9——AUD,访问单元分隔符。
用码流分析工具看到 7 与 8 存在,就可以确认【码流结构是完整的】。
三、优先级字段的作用
nal_ref_idc 这个名字看着拗口,作用其实很直接:
它标记这个单元对后续解码有多重要;
参数集与被参考的片通常优先级高,不被参考的 B 片优先级可以低甚至为 0;
在网络拥塞或需要丢弃时,优先丢低优先级的单元;
所以它给传输层提供了一个可操作的降级旋钮——这也是 NAL 层【为网络而生】的一个具体体现(第 9.1.3 节)。
四、从字节回看整个第九章
到这里,H.264 的全貌可以从一个字节往上拼出来了: 一个字节的 NAL 头 → 决定了这个单元的类型与重要性; 一串 NAL 单元 → 组成码流:起始码、SPS、PPS、各类片; 片内部 → 五级结构:片级、宏块级、子块级; 宏块内部 → 预测(帧内九种方向/帧间七种分块)、变换、量化、熵编码; 整段视频 → 档次与级别把能力划成格子。 从字节到整段视频,这就是 H.264 的完整层级。
五、往下一章看
第九章到这里结束,下一章换到音频: 第十章 AAC 编解码基础——音频那边的【主力标准】; 结构上和 H.264 有相似之处:也有档次、也有帧结构、也讲码流组织; 所以学完 H.264 再看 AAC,很多概念可以直接对应过去; 第十章之后是 第十一章 H.265,把视频这条线补到最新。 视频—音频—下一代视频,剩下三章就是这个顺序。
六、动手 Demo:NAL 头一个字节怎么切
每个 NAL 单元的第一个字节就是它的【身份证】。
types = [(1, "非 IDR 片"), (5, "IDR 片"), (6, "SEI 补充信息"),
(7, "SPS 序列参数集"), (8, "PPS 图像参数集"), (9, "AUD 分隔符")]
for v, name in types:
print("nal_unit_type = %d %s" % (v, name))
print("NAL 头 1 字节 = 1 位禁用 + 2 位优先级 + 5 位类型")
实跑输出:
--------------------------------------------------------------------
NAL 头一个字节怎么切
--------------------------------------------------------------------
每个 NAL 单元的第一个字节就是它的【身份证】。
第 1 位 禁用位 forbidden_zero_bit
第 2~3 位 优先级 nal_ref_idc
第 4~8 位 类型 nal_unit_type
类型值 含义
------------------------------
1 非 IDR 片
5 IDR 片
6 SEI 补充增强信息
7 SPS 序列参数集
8 PPS 图像参数集
9 AUD 访问单元分隔符
**类型 7 与 8 就是 SPS 与 PPS**——用码流分析工具看到它们,就知道码流结构是完整的。
**类型 5 是 IDR 片,也就是拖动的落脚点**(第 6.5.1 节);
**优先级 nal_ref_idc 越大越重要**,网络丢包时会优先保它。
类型 7 与 8 就是 SPS 与 PPS——看到它们就知道码流结构完整; 类型 5 是 IDR 片,也就是拖动的落脚点(第 6.5.1 节)。 优先级 nal_ref_idc 越大越重要,网络丢包时会优先保它。
30 秒实验
- 用十六进制工具打开一段裸 H.264 码流,找 00 00 01 后面的那个字节。
- 如果看到 0x67(7 = SPS)与 0x68(8 = PPS),就找到了参数集。
常见误区
- 以为 NAL 头很长。它只有一个字节,字段排得很紧。
- 以为优先级字段没用。它给拥塞时的丢包策略提供了依据。
- 以为类型值可以随便扩展。它们是标准规定的枚举,不是自定义字段。
自测三问(点开对答案)
1. NAL 头一个字节的三个字段是什么? —— 1 位禁用位、2 位优先级 nal_ref_idc、5 位类型 nal_unit_type。 2. nal_unit_type 为 5 表示什么? —— IDR 片,即可独立解码的关键帧数据。 3. 优先级字段有什么用? —— 标记单元重要性,网络拥塞时作为丢弃依据。- ☐ 下一章(第十章 AAC编解码基础)
相关笔记
- H.264码流结构 — 单元的排列顺序
- VCL与NAL — NAL 层为什么存在
- I/P/B/IDR帧 — IDR 与 I 的区别
- 封装格式 — 这些单元装在什么容器里
- 🎬 FFmpeg入门详解 · 索引