变换
一、基础内容
VVC中使用了DCT-2变换、DST-7变换和DCT-8变换作为主变换;同时为了进一步提高变换的性能,VVC针对帧内预测残差的低频分量引入了不可分变换作为二次变换(低频不可分二次变换)。
DCT-2变换、DST-7变换和DCT-8变换的基函数公式如下所示。
Transform Type | Basis function Ti(j), i, j = 0, 1,…, N−1 |
DCT-2 | where, |
DCT-8 | |
DST-7 |
在实现中,DCT-2/DST-7/DCT-8变换均采用了整数变换的实现.DCT变换原理参考:DCT变换
二、多核变换选择(Multiple Transform Selection,MTS)
MTS技术即通过率失真选择,从DCT2-DCT2变换以及DST-7/DCT-8变换的四种组合中选出最优的组合,MTS技术仅用在亮度分量上,且使用的最大块尺寸为32x32。MTS技术既可用在帧间预测残差,也可用在帧内预测残差。
在VVC中,包含两种MTS技术,即显性MTS和隐性MTS,显性MTS可以用于帧内和帧间的亮度块,显性MTS的DST-7/DCT-8变换核组合是由信号mts_idx显示表示的;隐性MTS的变换类型是根据变换块尺寸确定的,不需要信号传输。在SPS层中可以控制显性MTS和隐性MTS的开关。
显性MTS的变换类型由mts_idx语法元素控制,其值与含义对应如下:
mts_idx | 水平变换核 | 垂直变换核 |
0 | DCT-2 | DCT-2 |
1 | DST-7 | DST-7 |
2 | DCT-8 | DST-7 |
3 | DST-7 | DCT-8 |
4 | DCT-8 | DCT-8 |
在VTM代码中,为了实现方便,将TransformSkip也加入到了CU即的mts_idx变量中。使用显性MTS时,需要编码索引mts_idx,以指示变换类型。
当CU满足以下三种任一条件时,使用隐性MTS
- 当前CU块是ISP模式
- 当前cu_sbt_flag为1并且宽度和高度均小于等于32
- sps层关闭显性MTS且帧内模式且lfnst_idx等于0且mip_flag等于0
对于隐性MTS,变换核类型与尺寸相关:
- 当宽度大于等于4且小于等于16时,水平变换核使用DST-7变换,否则使用DCT-2变换
- 当高度大于等于4且小于等于16时,垂直变换核使用DST-7变换,否则使用DCT-2变换
为了降低复杂度,VVC在进行主变换时采用了高频系数归零技术,具体分为如下两种情况:
- 对于使用DCT-2变换的块,仅保留左上角32x32区域内的系数;
- 对于使用DST-7/DCT-8变换的块,仅保留左上角16x16区域内的系数
三、子块变换(Subblock Transforms,SBT)
VVC根据帧间预测残差的特性,引入了子块变换技术,即认为当前块的一部分残差非常小,可以将其看作0处理,因此在进行变换的时候可以仅对其具有残差的区域进行变换,可以提高变换性能。由于不知道当前块的哪部分区域残差较小,所以VVC采用了两种划分方式(水平划分和垂直划分)以及两种残差位置(position 0和position 1),如下图所示。除此之外,还有两种划分比例(1;3/3:1划分和2:2划分),总共有8种划分模式,如下图所示。,其中阴影部分区域即表示包含残差的区域(进行变换的区域)。
SBT的变换选择是一种隐式的选择,水平和垂直变换使用DCT-8或者DST-7,选择变换类型与位置SBT的划分方式及位置有关,具体如上图所示。
原理分析:
对于包含类似平移运动的视频,在进行帧间预测时候,预测块能够在参考帧中找到一个和当前块非常相似的块,这时预测块的残差就可能出现一部分存在残差而另一部分残差为零的情况,此时如果对整个块进行变换的话,变换性能并不会十分理想,因此如果只对有残差的那部分进行变换的话,则会大大提高变换性能且降低计算复杂度。
四、低频不可分变换(Low frequency non-separable transform,LFNST)
由于不可分变换比起可分离变换,有更好的去相关效果,VVC为了能够进一步提高变换部分的性能并考虑到复杂度的影响,VVC使用了一种二次变换和不可分变换相结合的技术,即仅将不可分变换用于主变换系数的低频系数,对于其余不做二次变换的系数全部归零,LFNST的应用如图所示。
LFNST根据块尺寸分为4x4 LFNST和8x8 LFNST:4x4 LFNST用于小块(min (width, height) < 8;8x8 LFNTS用于大块(min (width, height) > 4)。
LFNST仅用于帧内编码的块。LFNST的变换集的选择与帧内预测模式有关,如下表所示,其中IntraPredMode是将帧内预测模式映射为宽角度模式之后的模式。
IntraPredMode | Tr. set index |
IntraPredMode < 0 | 1 |
0 <= IntraPredMode <= 1 | 0 |
2 <= IntraPredMode <= 12 | 1 |
13 <= IntraPredMode <= 23 | 2 |
24 <= IntraPredMode <= 44 | 3 |
45 <= IntraPredMode <= 55 | 2 |
56 <= IntraPredMode<= 80 | 1 |
81 <= IntraPredMode<= 83 | 0 |
五、色度残差联合编码模式(joint coding of chroma residual,JCCR)
研究发现Cb和Cr的残差彼此呈相反的关系,因此建议利用这种现象并引入一种用于色度残差的联合编码的模式。在这种联合模式中,对于TU的两个色度块只有一个残差。如下图所示,编码端根据Cb和Cr的残差计算出联合残差resJointC,并将其编码。解码端再根据resJointC推导出resCb和resCr。
JCCR有三种模式,所选模式由色度CBF隐式表示。
编码端:
解码端:
JCCR技术细节:H.266/VVC技术学习:色度联合编码(JCCR)技术_涵小呆的博客-CSDN博客
六、变换代码实现
H.266/VVC变换的入口函数:transformNxN
一次变换(Primary Transform)的函数:xT函数
二次变换(Secondary Transform)的函数:xFwdLfnst函数
变换跳过(TransformSkip)的函数:xTransformSkip函数
1. 帧内变换流程
帧内编码端的变换涉及到变换最佳模式的选择,和变换部分相关的代码又比较杂,这里仅仅总结其中一部分代码。
帧内模式选择的入口函数是xCheckRDCostIntra,函数调用框图如图所示:
- xCheckRDCostIntra函数主要是进行了相应变换块可选变换模式集的遍历,通过并计算RD Cost选出最佳变换模式。
- estIntraPredChromaQT和estIntraPredLumaQT函数主要是分别对色度和亮度选择最佳预测模式
- xRecurIntraChromaCodingQT函数分别进行Cb Cr单独编码和JointCbCr联合编码,从而选出色度最佳编码模式。
- xIntraCodingLumaISP函数用于决定用于进行ISP分区、预测并进行变换等
- xRecurIntraCodingLumaQT函数用于对上层传来的变换集进行遍历
- xIntraCodingTUBlock用于对上层传来的预测模式和变换模式进行帧内编码从而计算失真。
- TransformNxN是变换的入口函数
对于帧内变换,相应的变换块的变换模式集对应如图所示:
2. 帧间变换
帧间变换入口函数:
H.266/VVC代码学习:xEncodeInterResidual函数_涵小呆的博客-CSDN博客
VVC中帧间变换技术包括MTS和SBT,但在VTM的Common Tst Condition下,帧间MTS是 off 状态。
帧间变换的RDO过程复杂主要为 SBT 的模式遍历,包括许多SBT相关快速算法。
量化
量化将原始数据分为多个不同的区间,每个区间中的多个数值都用一个数值表示,可以大大减少数据量。
在对残差系数进行完变换之后,通常变换系数具有很高的动态范围,此时对变换系数进行量化,可以减小变换系数的取值空间,更好的进行后面的熵编码。
量化分为标量量化和矢量量化。标量量化是将图像中像素的取值范围划分为若干区间,每个区间仅用一个数值(标量)来表示该区间中所有的像素值,每个像素的量化取值是一个标量,并且独立于其他的像素值。矢量量化是将图像的每n个像素看成是一个n维矢量,将每个n维取值空间划分为若干个子空间,每个子空间用一个n维“代表”矢量表示该子空间所有的矢量取值。由于矢量量化利用的多个像素间的相关性,一般来说,其压缩率要高于标量量化,但是计算复杂度比较高。
目前的视频编码标准中,都采用的是标量量化。
VVC在HEVC的常规量化和RDOQ量化基础上,引入了依赖性标量量化DQ。代码和算法详细内容介绍如下: