🎬 第九章 H.264编解码基础
📄 一句话概括

每个 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 秒实验

  1. 用十六进制工具打开一段裸 H.264 码流,找 00 00 01 后面的那个字节。
  2. 如果看到 0x67(7 = SPS)与 0x68(8 = PPS),就找到了参数集。

常见误区

  1. 以为 NAL 头很长。它只有一个字节,字段排得很紧。
  2. 以为优先级字段没用。它给拥塞时的丢包策略提供了依据。
  3. 以为类型值可以随便扩展。它们是标准规定的枚举,不是自定义字段。
自测三问(点开对答案) 1. NAL 头一个字节的三个字段是什么? —— 1 位禁用位、2 位优先级 nal_ref_idc、5 位类型 nal_unit_type。 2. nal_unit_type 为 5 表示什么? —— IDR 片,即可独立解码的关键帧数据。 3. 优先级字段有什么用? —— 标记单元重要性,网络拥塞时作为丢弃依据。

相关笔记