H.265帧间预测
帧间预测整个流程可以理解为一个在巨大搜索空间中寻找最优率失真 (RDO) 解的过程。编码器会尝试多种模式,最终选择一个消耗比特最少且失真最小的组合。
第 1 步:CU 划分决策
编码器从最大的 CTU 尺寸开始,进行递归检查。它会计算:
- 不划分 (Split_flag = 0):将当前整个 CU 作为一个单元进行预测的 R-D cost。
- 划分为四个子 CU (Split_flag = 1):递归地对四个子 CU 进行最优预测,并将它们的 R-D cost 相加。
编码器会选择总 R-D cost 更小的选项,直到达到最小 CU 尺寸(如 8x8)为止。
第 2 步:PU 模式决策
对于一个决定不再划分的 CU,编码器进入 PU 模式决策阶段。它会尝试将这个 CU 按照多种几何形状划分为 PU。除了传统的对称划分(2Nx2N, 2NxN, Nx2N, NxN),HEVC 还引入了非对称运动划分 (Asymmetric Motion Partitions, AMP),能更好地拟合物体边缘。
- 对称模式 (Symmetric): 2Nx2N,2NxN,Nx2N,NxN(仅最小CU支持)
- 非对称模式 (Asymmetric): 2NxnU,2NxnD,nLx2N,nRx2N
编码器会为每种 PU 划分模式,执行接下来的运动估计和补偿,并计算 R-D cost,最终选择最优的一种。
第 3 步:运动矢量预测与运动估计 (ME)
对于每一个 PU,编码器需要为其寻找最佳的运动信息(运动矢量 MV + 参考图像索引 ref_idx)。
HEVC 设计了两种高效的模式来寻找和编码这些信息:Merge 模式 和 AMVP (Advanced Motion Vector Prediction) 模式。
预测候选位置
无论是AMVP还是Merge模式,它们都试图从当前PU的时空邻域寻找候选者,以减少需要编码的信息。
代码段
      +------+------+------+
      | B2   | B1   | B0   |  <-- 上方邻近块 (Above)
+-----+------+-------------+
| A1  |           |
+-----+  Current  |
| A0  |    PU     |
+-----+-----------+
                      +------+
                      | T0/T1|  <-- 时间维度上的共置块 (Temporal/Co-located)
                      +------+
                      (在参考帧中的对应位置)
- 空间候选(Spatial Candidates):
    - 左侧: A0, A1
- 上方: B0, B1, B2
 
- 时间候选(Temporal Candidate):
    - T0/T1: 位于参考帧中与当前PU相同位置的块(Co-located PU)。
 
1. AMVP (Advanced Motion Vector Prediction) - 高级运动矢量预测
AMVP是一种显式(Explicit)的运动矢量编码模式。它的核心思想是:不直接编码完整的MV,而是先从时空邻域构建一个MV候选列表,编码器选择一个最佳的运动矢量预测子(Motion Vector Predictor, MVP),然后只编码真实MV与MVP之间的差值(Motion Vector Difference, MVD)。
因为邻近块的运动趋势往往相似,所以MVD通常很小,可以用更少的比特来表示。
AMVP流程:
- 构建候选列表(Candidate List Generation):
    - 为当前PU构建一个包含2个MVP的候选列表。
- 第一步:检查左侧空间候选。按 A0 -> A1 的顺序检查,找到第一个可用的MV,加入列表。
- 第二步:检查上方空间候选。按 B0 -> B1 -> B2 的顺序检查,找到第一个可用的MV,加入列表。
- 第三步:列表去重。如果从左侧和上方找到了相同的MV,则只保留一个。
- 第四步:填充列表。如果列表未满(少于2个候选者),则按以下顺序填充:
        - 时间候选(Temporal Candidate): 使用T0/T1位置块的MV(需要进行时域缩放)。
- 零运动矢量(Zero MV): 如果列表仍未满,用(0,0)作为MV填充。
 
 
- 选择与信令(Selection and Signaling):
    - 编码器从这个包含2个候选者的列表中,为当前PU选择一个最优的MVP。
- 在比特流中,发送一个索引(mvp_l0_flag/mvp_l1_flag,1 bit)来告诉解码器选择了哪个MVP。
- 发送计算出的MVD。
 
- MV重建(MV Reconstruction):
    - 解码器端根据收到的索引选择同一个MVP,然后与收到的MVD相加,得到最终的MV。
 
MVfinal=MVP+MVD
LaTeX: MV_{final} = MVP + MVD
本质: AMVP的目标是预测运动矢量本身。它为PU独立编码了MV、ref_idx等信息,但通过预测来节省了MV的编码比特。
2. Merge模式
Merge模式是一种隐式(Implicit)的运动信息编码模式,它假设当前PU的运动信息(包括MV、参考帧索引ref_idx、预测方向L0/L1/Bi-prediction)与某个时空邻近块完全相同。
在这种模式下,编码器不需要发送任何MVD或ref_idx,只需要发送一个指向候选列表的索引。
Merge模式流程:
- 构建候选列表(Candidate List Generation):
    - 为当前PU构建一个最多包含5个候选者的列表。
- 第一步:空间候选。按 A1 -> B1 -> B0 -> A0 -> B2 的顺序检查,将有效的邻近块的完整运动信息(MV, ref_idx, 预测方向)加入列表。
- 第二步:时间候选。将时间候选位置T0/T1的运动信息加入列表。
- 第三步:列表去重。
- 第四步:填充列表。如果列表未满,会尝试生成一些组合的双向预测候选(Combined Bi-predictive candidates),即从已有的单向预测候选者中组合出新的双向预测候选。
- 第五步:零运动矢量候选。如果列表仍未满,用零运动矢量相关的候选填充。
 
- 选择与信令(Selection and Signaling):
    - 编码器从这个列表中选择一个最优的候选者。
- 在比特流中,只发送一个索引(merge_idx)来指明使用了哪个候选者的运动信息。
 
- 运动信息继承(Motion Information Inheritance):
    - 解码器构建完全相同的候选列表,根据接收到的merge_idx,直接拷贝对应候选者的所有运动信息(MV, ref_idx, 预测方向)作为当前PU的运动信息。
 
- 解码器构建完全相同的候选列表,根据接收到的
本质: Merge模式的目标是复用一整套运动信息。它不发送MVD和ref_idx,只发送一个很短的索引,比特消耗极低。它非常适用于大面积拥有相同运动趋势的区域(例如,摄像机平移时,背景中的多个块运动完全一致)。
3. Skip模式
Skip模式是Merge模式的一种终极简化,是HEVC中编码效率最高的一种模式。
当一个PU使用Skip模式时,它意味着:
- 运动信息: 与Merge模式完全一样,通过merge_idx从Merge候选列表中继承一套完整的运动信息。
- 残差信息: 没有残差数据(No Residual)。编码器会跳过对这个PU的残差计算、变换、量化和熵编码,解码器也同样跳过这些步骤。
也就是说,Skip模式的PU,其重建块完全等于根据继承的运动信息从参考帧中找到的预测块。
Skip模式的信令:
Skip模式的信令在编码单元(Coding Unit, CU)层面。编码器会为每个CU发送一个cu_skip_flag。
- 如果cu_skip_flag为真,则该CU下所有的PU都采用Skip模式。解码器只需要解析一个merge_idx来确定运动信息即可。
- 如果cu_skip_flag为假,则继续解析该CU下各个PU的具体预测模式(可能是Inter-AMVP, Inter-Merge, 或者Intra)。
本质: Skip模式是为那些运动补偿预测后,残差几乎为零的块设计的。最典型的场景是视频中静止不动的背景。它用极少的比特(一个skip标志和几比特的merge_idx)就完成了一个块的编码,是实现高压缩比的利器。
第 4 步:运动补偿 (MC)
确定了每个 PU 的 MV 和 ref_idx 后,就进入运动补偿阶段,即生成预测块 (Predicted Block)。
- 
    定位参考块:根据 MV,在参考帧列表中找到对应的参考图像,并定位到参考块的整数像素位置。 
- 
    亚像素插值:MV 通常不是整数,带有小数部分,这就需要进行亚像素插值。 - 亮度 (Luma):采用 1/4 像素精度。插值滤波器是基于 DCT 的 7-tap (奇数位) 或 8-tap (偶数位) 滤波器,比 H.264 的 6-tap 滤波器更精确。
- 色度 (Chroma):采用 1/8 像素精度。如你之前问题所述,这对应于 1/4 亮度像素的物理精度。插值滤波器是 4-tap 的。
 
- 
    加权平均 (Bi-prediction):对于 B-PU(双向预测),会从参考列表 L0 和 L1 中各产生一个预测块 P_0 和 P_1。最终的预测块 P 通过加权平均得到: P=shift(w0×P0+w1×P1+offset0+offset1) P=shift(w_0×P_0+w_1×P_1+offset_0+offset_1) 在标准预测中,权重 w_0,w_1 通常相等,即简单的平均。 
流程总结 ASCII 图
+------------------+
|      CTU         |
+------------------+
        |
        v
+------------------+       No
|   划分CU ?       |------------------>
| (Split Decision) |
+------------------+
        | Yes
        v
+------------------+
|   4个子CU        | (递归调用)
+------------------+
        |
        v
+------------------+
|  PU模式决策       |
| (2Nx2N, AMP...)  |
+------------------+
        |
        v
+------------------------------------+
|   为每个PU选择最优运动信息模式        |
|  (Merge vs. AMVP)                  |
|   - 构建候选列表                     |
|   - ME (仅AMVP)                    |
|   - 计算各模式R-D cost             |
+------------------------------------+
        |
        v
+------------------------------------+
|        运动补偿 (MC)               |
|   - 亚像素插值 (1/4 Y, 1/8 C)      |
|   - 双向预测加权平均                |
+------------------------------------+
        |
        v
+------------------+
|  生成预测块P      |
+------------------+
        |
        v
+------------------+      +------------------+
| 计算残差 R = O-P |----->|  变换、量化、熵编码 |
+------------------+      +------------------+