🎬 第八章 音视频编解码技术与流程
📄 一句话概括

块是编码的最小处理单位,16×16 是经典宏块;块越小越贴合细节、但描述开销越大,所以现代标准把块大小做成可变的。

📝 本节和前面几节的关系

8.3.5 讲了帧内编码的流程,这一节把流程里的处理单位——块与宏块——单独说清楚。

一、为什么必须切块

编码器不逐像素处理,而是成块处理,原因有三个: 预测需要邻域——一块的邻居比一个像素的邻居更稳定,预测更准; 变换需要矩阵——DCT 本身就是二维块变换,块是它的天然输入; 并行与硬件——规则的小块便于流水线与 SIMD 加速。 所以【块】不是一个约定,而是由变换与预测的数学性质决定的。

二、16×16 这个经典尺寸

宏块(Macroblock)是 H.261 到 H.264 一路沿用下来的基本单位: 尺寸 16×16,一帧按行列整齐排布; 1080p 按 1920×1088 算,一帧 120×68 = 8160 个宏块; 宏块内部还可以再切:16×16、16×8、8×16、8×8,8×8 还能再分成 8×4、4×8、4×4。 宏块是【地址单位】,块是【处理单位】——两者不是一回事。

三、块越小的两面

块大小的取舍是一道很直白的题: 块越小——越能贴合细节与边缘,残差更小、压得更准; 但块数成倍增长,每块都要写模式、矢量、系数,描述开销也跟着涨; 数字很直观:同样的画面,4×4 的块数是 16×16 的 16 倍。 所以最优解不是【越细越好】,而是逐块试出最合适的尺寸。

四、可变块大小:现代标准的做法

既然一刀切都不对,现代标准就把它做成可选的: 平坦区域用大块——天空、墙面、失焦背景,大块最省; 纹理与边缘处用小块——细节多,小块才贴得住; 编码器逐块比较代价,选总代价最小的那种切法; H.265 更进一步,把固定 16×16 换成最大 64×64 的编码树单元(CTU)(第 7.4.3 节)。 代价也很直接:候选切法一多,搜索空间爆炸,编码就慢下来了。

五、块与它的邻居

最后记住一条和流程相关的要点——块的预测依赖邻居: 帧内预测要用左边和上边已经重建的像素; 所以块的处理顺序必须是从左到右、从上到下,不能打乱,否则邻居还没重建出来; 这一点决定了编码器内部的串行依赖,也是并行化的难点之一。 块不只是数据划分,还是一张有向的依赖图。

六、动手 Demo:块越小,数量越多

同一个画面,换一种块大小,处理单位的数量立刻变几倍。

total = 1920 * 1088
for size, px in ((16, 256), (8, 64), (4, 16)):
    print("%d×%d 一帧 %6d 个块,是 16×16 的 %2d 倍"
          % (size, size, total // px, 256 // px))

实跑输出:

--------------------------------------------------------------------
块越小,数量越多
--------------------------------------------------------------------

同一个画面,换一种块大小,处理单位的数量立刻变几倍。

  块大小     一帧块数     相对 16×16     适合
  --------------------------------------------------------
  16×16      8160         1 倍           细节少、平坦区域
  8×8        32640        4 倍           过渡区域
  4×4        130560       16 倍          纹理复杂、边缘多

  **块越小、数量越多、能贴合细节,但描述每个块的开销(模式、矢量)也越多。**
  所以现代标准把它做成**可变块大小**:平坦处用大块、复杂处用小块,
  由编码器逐块试出来最优组合——**这也是编码变慢的主要原因之一**。

块越小、数量越多、能贴合细节,但描述每个块的开销也越多。 所以现代标准把它做成可变块大小:平坦处用大块、复杂处用小块。

30 秒实验

  1. 算一下 720p(1280×720)的宏块总数,和 1080p 的 8160 比一比。
  2. 注意 720 ÷ 16 = 45 是整数——720p 恰好不需要补边。

常见误区

  1. 把【宏块】与【块】当成同义词。宏块是 16×16 的地址单位,块是可变的处理单位。
  2. 以为块越小越好。描述开销会跟着涨,平坦区域用小块是浪费。
  3. 以为块可以随便并行处理。帧内预测依赖左邻与上邻,顺序不能乱。
自测三问(点开对答案) 1. 经典宏块的尺寸是多少? —— 16×16,H.261 到 H.264 一路沿用。 2. 为什么现代标准要用可变块大小? —— 平坦区域用大块省开销,复杂区域用小块贴细节。 3. 块的处理顺序为什么必须是逐行逐列? —— 帧内预测要用左边和上边已重建的像素,顺序打乱就没有参考。

相关笔记