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

HEVC 沿用 H.264 的 VCL/NAL 两层结构,但参数集从两级变成三级:VPS/SPS/PPS——多的那个 VPS 是为多层与可伸缩编码留的口子。

📝 本节和前面几节的关系

11.2.1 讲了能力描述,这一节看码流内部是怎么组织的——结构与 H.264 高度相似,差别在细节。

一、两层结构没变

先确认一件事:HEVC 的整体分层与 H.264 完全一致(第 9.1.3 节)。 VCL——装编码数据(片、CTU); NAL——加头、切片,适配网络传输; 这个设计经受住了十年检验,H.265 没有理由改; 所以从 H.264 学过来的这套理解,可以原样搬到 H.265 上。

二、参数集从两级变三级

真正多出来的是参数集的层数: VPS(视频参数集,类型 32)——描述整条码流的层与可伸缩信息; SPS(序列参数集,类型 33)——与 H.264 对应,管分辨率、档次、级别; PPS(图像参数集,类型 34)——与 H.264 对应; 所以出现了 VPS → SPS → PPS 这样的三级引用链。 VPS 在单层应用里常被忽略,但它必须存在——因为解码器要先读它才知道码流分了几层。

三、单元类型重新编号

这一条最容易踩坑:HEVC 的 NAL 类型值是重新定的,不能拿 H.264 的表去查。 32 VPS、33 SPS、34 PPS、35 AUD——参数集与分隔符; 19 IDR_W_RADL、20 IDR_N_LP——两类 IDR; 21 CRA_NUT——清理随机访问点; 还有 BLA、TRAIL 等一系列前缀类型。 类型 5 在 H.264 里是 IDR 片,在 H.265 里不是——自己写解析器时,这个坑一定会遇到。

四、片与图像层的变化

与 H.264 的五级结构对应,HEVC 的内部层级也做了调整: 序列级 / 图像级 / 片级——与 H.264 基本对应; CTU 级 / CU 级 / PU 级 / TU 级——取代了原来的【宏块级 / 子块级】; 原因是块结构变了:不再有固定大小的宏块,切成四叉树的编码单元、预测单元、变换单元; 所以层级不是【更多】,而是换了一套与四叉树匹配的命名。

五、为什么这么设计

VPS 与新的层级设计,指向同一个目标——为未来留口子: 多层视频(如 3D、可伸缩编码)——VPS 描述层间关系; 可伸缩编码——同一码流里有基础层与增强层; 这些特性在普通单层应用里用不上,但结构上先把位置留好,以后扩展不必推翻标准; 这是一条很典型的标准设计思路:宁可先留空位,也不要事后打补丁。

六、动手 Demo:HEVC 多出来的那个 VPS

HEVC 的参数集与 H.264 很像,但多了一层。

rows = [("VPS 视频参数集", "32", "H.264 没有,HEVC 新增"),
        ("SPS 序列参数集", "33", "与 H.264 对应"),
        ("PPS 图像参数集", "34", "与 H.264 对应"),
        ("AUD 访问单元分隔", "35", "与 H.264 对应"),
        ("CRA_NUT", "21", "随机访问点,可清理前导")]
for a, b, c in rows:
    print("%-18s %-4s %s" % (a, b, c))

实跑输出:

--------------------------------------------------------------------
HEVC 多出来的那个 VPS
--------------------------------------------------------------------

HEVC 的参数集与 H.264 很像,但多了一层。

  单元类型             类型值     说明
  -------------------------------------------------------
  VPS 视频参数集       32         H.264 没有,HEVC 新增
  SPS 序列参数集       33         与 H.264 对应
  PPS 图像参数集       34         与 H.264 对应
  AUD 访问单元分隔     35         与 H.264 对应
  IDR_W_RADL           19         可独立解码的关键帧
  IDR_N_LP             20         不带前置图像的关键帧
  CRA_NUT              21         随机访问点,可清理前导

  **参数集从 SPS/PPS 两级变成了 VPS/SPS/PPS 三级。**
  VPS 描述【整条码流】的层与可伸缩信息——
  它是为**多层视频与可伸缩编码**铺的路,**单层应用里常被忽略**。
  类型值的变化也说明:**HEVC 重新编了号**,不能拿 H.264 的表去查(第 9.3.3 节)。

参数集从 SPS/PPS 两级变成 VPS/SPS/PPS 三级。 VPS 描述整条码流的层与可伸缩信息,单层应用里常被忽略。 类型值也变了:HEVC 重新编了号,不能拿 H.264 的表去查。

30 秒实验

  1. 用 FFmpeg 把视频导出成裸 HEVC 流:-c:v copy -f hevc out.h265。
  2. 用十六进制工具看起始码后面的字节,找 0x40(VPS,32 左移 1 位)。

常见误区

  1. 拿 H.264 的 NAL 类型表去查 HEVC 码流。类型值全部重编过。
  2. 以为 VPS 是可有可无的。解码器要先读它才知道码流的层结构。
  3. 以为 HEVC 的层级变多了。是换成与四叉树匹配的 CTU/CU/PU/TU。
自测三问(点开对答案) 1. HEVC 的参数集有哪三级? —— VPS(32)、SPS(33)、PPS(34)。 2. VPS 在单层应用里有什么用? —— 描述整条码流的层信息,必须存在,但内容通常简单。 3. HEVC 的层级为什么改用 CTU/CU/PU/TU? —— 因为块结构变成四叉树,不再有固定大小的宏块。

相关笔记