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

H.264 把要写进码流的信息按作用范围分成五层:序列级、图像级、片级、宏块级、子块级——越往上写得越少,越往下越重复。

📝 本节和前面几节的关系

9.1.1 认清了六大技术,这一节看这些技术的结果怎么写进码流。

一、五层结构

按作用范围从小到大排,H.264 的句法元素分五层: 序列级(SPS)——整段视频的全局参数:分辨率、帧率、档次、级别; 图像级(PPS)——一帧级别的参数:熵编码方式、QP 初值; 片级(Slice header)——帧类型、参考帧列表、QP 偏移; 宏块级——分块方式、运动矢量差; 子块级——变换量化后的残差系数。

二、分层的本质是【复用】

为什么要把参数分层?因为它们的重复程度不同。 序列级的东西只写一次——分辨率不可能每帧都变; 图像级变化也少——熵编码方式通常整段一致; 越往下越具体、越重复——每个宏块都要写自己的分块方式; 所以把稳定的参数提取到上层,省下的是成千上万次的重复描述。 这是编码里非常通用的一招,和【把常量提到循环外面】是同一个道理。

三、参数集为什么单独立项

SPS 与 PPS 不只是【高层参数】,它们还是独立的单元、可以单独传输: 它们不属于任何一帧,可以被多次重复发送; 解码器只要拿到它们,后面任何一片都能解; 反过来,丢了它们,后面整段码流全部报废——因为解码器连【图像多大】都不知道。 所以流媒体传输里,SPS/PPS 往往随每个关键帧一起重发,为的就是让中途加入的客户端能立刻开始解码。

四、这些元素在实际工具里长什么样

用码流分析工具打开一个文件,会看到这些层级的具体身影: SPS/PPS——出现在最前面,通常在 IDR 之前; 片头——每一片都有一段 header,写着帧类型与 QP 偏移; 宏块数据——码流里占比最大的部分; 所以排查问题的顺序是自顶向下:先看 SPS/PPS 对不对,再看片头,最后才怀疑宏块。 这个顺序在 3.4 节介绍的码流分析器里看得最清楚。

五、和后面两节的关系

这一节给出的是【分了几层】,后面两节给出【为什么能这么分】: 9.1.3 VCL 与 NAL——解释这五层在传输上是怎么被拆成网络包的; 9.3.1 与 9.3.3——把分层结构与 NAL Unit 的字节格式讲到底。 先记住五层的名字与职责,后面都是在这张骨架上添细节。

六、动手 Demo:句法元素按五层组织

H.264 把所有要写进码流的信息,按作用范围分成五层。

rows = [("序列级", "SPS", "分辨率、帧率、档次、级别"),
        ("图像级", "PPS", "熵编码方式、QP 初值"),
        ("片级", "Slice header", "帧类型、参考帧、QP 偏移"),
        ("宏块级", "mb_type / mvd", "分块方式、运动矢量差")]
for lv, name, cont in rows:
    print("%-6s %-14s %s" % (lv, name, cont))

实跑输出:

--------------------------------------------------------------------
句法元素按五层组织
--------------------------------------------------------------------

H.264 把所有要写进码流的信息,按作用范围分成五层。

  层级       代表元素          管什么
  ------------------------------------------------------
  序列级     SPS               分辨率、帧率、档次、级别
  图像级     PPS               熵编码方式、QP 初值
  片级       Slice header      帧类型、参考帧、QP 偏移
  宏块级     mb_type / mvd     分块方式、运动矢量差
  子块级     残差系数          变换量化后的系数

  **分层的意义是复用**:SPS 与 PPS 只写一次,
  后面每一片、每个宏块都直接引用,**不必反复描述同一件事**。
  这就是为什么 SPS/PPS 一丢,后面整段码流都解不出来。

分层的意义是复用:SPS 与 PPS 只写一次, 后面每一片、每个宏块都直接引用,不必反复描述同一件事。 所以 SPS/PPS 一丢,后面整段码流都解不出来。

30 秒实验

  1. 用 ffprobe 或码流分析工具打开一个 MP4,找找 SPS 与 PPS 出现在哪里。
  2. 注意它们是不是只出现一次,还是随关键帧重复出现。

常见误区

  1. 以为句法元素只是【参数】。它们是码流的组成部分,有明确的位置与格式。
  2. 以为 SPS 属于第一帧。它不属于任何一帧,是独立的参数集单元。
  3. 以为丢一两个参数无所谓。SPS/PPS 一丢,后面的片全部无法解析。
自测三问(点开对答案) 1. H.264 的句法元素分哪五层? —— 序列级、图像级、片级、宏块级、子块级。 2. 分层的本质目的是什么? —— 复用——把稳定参数提到上层,避免重复描述。 3. 为什么 SPS/PPS 常常重复发送? —— 让中途加入的客户端能立刻开始解码。

相关笔记