H.264 CBP 语义深入分析

参考:
https://www.cnblogs.com/TaigaCon/p/5229392.html
ITU-T H.264 标准文档
新一代视频压缩标准-H.264_AVC 毕厚杰

1. CBP 语义的作用

1.1 DCT 变换与 AC & DC 语义

我们知道 h.264 码流在经过模式选择后,接着需要再经过 计算残差 ---> DCT 变换 ---> 量化 ---> 熵编码 这 4 步,然后才得到最终的码流。其中 AC/DC 是 DCT 变换阶段的概念。
一个 4x4 的残差数据矩阵,在经过 DCT 变换后,得到一个 4x4 的系数矩阵,其中左上角被称为 DC (DC Coefficient,直流系数),其余 15 个被称为 AC (AC Coefficient,交流系数):

1.2 CBP 的作用

上述 DCT 变换后的 4x4 系数矩阵,接着会经历量化步骤。经过量化后,理论上大部分 AC 系数会被量化为 0,这样为最后的熵编码带来更好的压缩率。
考虑一种情况,经过量化后,4x4 系数矩阵都为 0。这种情况下有两个可优化的点可以考虑:

  • 是否需要熵编码一个全 0 系数矩阵,以及是否需要一个 bit 位来对其进行编码?
  • 解码端是否可以直接跳过全 0 系数矩阵的反熵编码?

针对此,cbp 概念被提出来来对全 0 系数矩阵的情况进行优化:

  • 在编码端,被 cbp 标识的系数矩阵无需再进行熵编码,节约了编码时间和码流大小
  • 在解码端,被 cbp 标识的系数矩阵无需再进行反熵编码,节约了解码时间

1.3 CBP 语义用法

CBP 通常用 1 个 bit 位,来表示一个 8x8 的系数矩阵是否是全 0。(非绝对,下面会详细说明)
例如如下一个 16x16 的宏块,就会被编码为二进制 0b1000 (只有左上角一个 8x8 的系数矩阵存在非 0 值):

我们经常能在 H.264 相关编解码代码中,看到 cbp&0x1; cbp&0x2 等语句,就是利用了 1 个 bit 位来表示 8x8 系数矩阵是否全 0 的特性

  • 在 H.264 标准中,cbp 通常由 coded_block_pattern 字段来表示。其是一个 6 bit 的字段,前 2 个 bit 用于 chroma 色度的 cbp 表示,后 4 个 bit 用于 luma 亮度的 cbp 表示。(不绝对,下面会详细分析)
  • 其中前 2 个 bit 又可以称为 CodedBlockPatternChroma 语法元素;后 4 个 bit 又可以称为 CodedBlockPatternLuma 语法元素,分别用于表示 两个 chroma(色度) 和 luma(亮度)的系数矩阵为全 0 情况。

1.4 易混淆点

H.264 标准中,对 cbp 的最终表示是比较复杂的,其受到如下因数影响:

  • 4x4 还是 8x8 的 DCT 变换
  • 当前是 luma(亮度)编码还是 chroma(色度)编码
  • 当前 16x16 宏块的分割方式
  • DC、AC 系数的分开存储特性

所以下面对这些易混淆点进行详细分析,帮助理清 cbp 在语法中的语义。

2 DCT 变换大小和宏块分割方式对 CBP 表示的影响

这个时候会有一些疑问,那就是 8x8 为一个单位来进行全 0 系数表示,如何处理宏块非 16x16 分割,以及 4x4/8x8 DCT 变换的?实际上是按照如下规则处理的:

  • 不管 16x16 的宏块,最终分割大小是多少,都可以看作是在整个宏块量化完毕后,通过检查整个 16x16 的系数矩阵,来确定以 8x8 为单位的 cbp 值 (当然实际上不是这么做的,理解上可以这么认为)
  • 如果是 8x8 DCT 变换,那么变换后的 8x8 系数矩阵天然就切合 cbp 的表示;如果是 4x4 DCT 变换,那么一个 8x8 cbp 表示,内部有 4 个 4x4 系数矩阵,如果这 4 个系数矩阵全都是 0,那么 cbp 就为 0,否则非 0

3 DCT 变换与量化

H.264 标准对 AC/DC 的特殊处理增加了对 cbp 理解的难度,所以首先需要理清不同情况下,DCT 变换 --> AC/DC 系数矩阵 ---> 量化 这 3 者的关系
总体关系如下图:

4 luma(亮度)编码时 CBP 表示

一个 16x16 宏块的亮度也是 16x16 大小的,本节主要讨论亮度系数矩阵的 cbp 表示。为便于理解,如下以 4x4 DCT 变换为例

4.1 Intra_16x16 模式下 luma CBP 表示

对于 intra_16x16 的模式,标准规定在 4x4 DCT 变换后,再对 16 个 DC 系数组成的 4x4 DC 系数矩阵做一次 Hadamard 变换,以进一步提高压缩率:
(如下 00 到 33 组成新的 4x4 DC 系数矩阵,毕厚节书-5.7.2节)

这里会导致 DC 和 AC 系数矩阵分开进行后续的量化和熵编码。H.264 标准中,针对这种情况,cbp 的表示有如下结果:

  • DC 系数矩阵没有 cbp 进行表示;只对 AC 系数矩阵进行 cbp 表示
  • AC 系数矩阵的 cbp 在 macroblock_layer::mb_type 语法字段中的 CodedBlockPatternLuma 字段进行表示
  • CodedBlockPatternLuma 字段取值只有 0 和 15 两种值。0 表示 16 个 4x4 AC 系数矩阵全为 0,15 表示至少有一个 4x4 AC 系数矩阵不为 0
  • 4x4 的 AC 系数矩阵由于左上角 DC 系数被单独抽出去了,所以还剩下 15 个 AC 系数

4.2 其它情况 luma CBP 表示

对于其它帧内帧间模式,或其它分割大小,无需将 DC 系数提出来单独再做一次 Hadamard 变换,所以 AC 和 DC 系数一起进行后续熵编码。
H.264 标准中,此时 cbp 的表示有如下结果:

  • cbp 统一表示 16 个 4x4 系数矩阵(包括 AC 和 DC)的全 0 情况
  • cbp 在 macroblock_layer::coded_block_pattern 语法字段中给出 (注意不再是 mb_type 字段)

5 chroma(色度)编码时 CBP 表示

一个 16x16 宏块的色度是两个 8x8 大小的 cr 和 cb。另外对于色度,需要注意以下特性:

  • intra chroma 总是 8x8 分割大小,但是可以有不同于 luma 的像素预测方式
  • inter chroma 也总是 8x8 分割大小,其运动矢量由 luma 的运动矢量推导而来

本节主要讨论色度系数矩阵的 cbp 表示。为便于理解,如下以 4x4 DCT 变换为例
对于色度编码,无论是帧内帧间模式,标准规定在 4x4 DCT 变换后,都需要再对 4 个 DC 系数组成的 2x2 DC 系数矩阵做一次 Hadamard 变换,以进一步提高压缩率:
(如下 00 到 11 组成新的 2x2 DC 系数矩阵,毕厚节书-5.7.2节)

另外,无论是帧内帧间模式,chroma cbp 都有如下语义

CodedBlockPatternChroma Description
0 All chroma transform coefficient levels are equal to 0.
1 One or more chroma DC transform coefficient levels shall be non-zero valued.
All chroma AC transform coefficient levels are equal to 0.
2 Zero or more chroma DC transform coefficient levels are non-zero valued.
One or more chroma AC transform coefficient levels shall be non-zero valued.

5.1 Intra_16x16 luma 模式下 chroma CBP 表示

H.264 标准中,此时色度 cbp 的表示有如下结果:

  • cbp 在 macroblock_layer::mb_type 语法字段中的 CodedBlockPatternChroma 字段进行表示
  • 注意,这里 chroma 的 cbp 在这里表示是因为 macroblock_layer::mb_type 字段在 Intra_16x16 luma 模式分割下,能够顺带的将 chroma cbp 也添加进来。不用再单独用一个 coded_block_pattern 字段来表示 cbp,以节省码率

5.2 其它情况 chroma CBP 表示

H.264 标准中,此时色度 cbp 的表示有如下结果:

  • cbp 在 macroblock_layer::coded_block_pattern 语法字段中给出 (注意不再是 mb_type 字段)
posted @ 2025-03-27 17:37  重返科韵路  阅读(117)  评论(0)    收藏  举报