VVC变换编码(二)低频不可分离变换LFNST

不出门、不聚集,抗击疫情不给国家添麻烦。

不可分离变换:整个变换就是一个二维矩阵乘法过程。

可分离变换:将二维矩阵乘法分为水平和垂直方向两个一维向量乘法,复杂度较低。

二次变换:就是在主变换(Primary transform)之后对频域信号进行第二次变换,将信号从一个变换域转换至另外一个变换域,之后再进行量化,熵编码等操作,其目的是进一步去除统计冗余。

在VTM5中低频不可分离变换 (LFNST,low-frequency non-separable transform)被看作是缩减的二次变换。如下图所示,在编码端,LFNST用在变换和量化之间。在解码端,LFNST用在反量化和反变换之间。根据块的尺寸不同,LFNST可以选择4x4和8x8的不可分离变换。例如对小尺寸块(min (width, height) < 8)使用4x4变换,对大尺寸块(min (width, height) >4)使用8x8变换。

下面是一个4x4LFNST的例子,输入X是一个4x4矩阵:

首先将矩阵X拉伸为一个一维向量:

然后进行不可分离变换计算:

最后将结果16x1的系数向量转换成4x4的系数矩阵。

缩减的不可分离变换(reduced non-separable transform,RST)

LFNST基于不可分离变换所以只需要一次矩阵乘法就可以完成变换操作。但是为了降低计算复杂度和变换系数的内存空间需要将不可分离变换矩阵进行缩减。缩减的不可分离变换(reduced non-separable transform,RST)主要思想是将N维向量映射为另一个空间的R维向量,其中N/R (R<N)是缩减因子。这样一个NxN的矩阵经过RST处理后变为一个RxN的矩阵,如下所示。

R是N维空间的R基底。其逆矩阵是正变换矩阵的转置矩阵

上面有一个4x4LFNST的例子,同样对于8x8LFNST,输入X是一个8x8矩阵拉伸为64x1的向量,矩阵T为64x64,使用RST缩减因子是4时T变为16x64,结果是16x1的向量转换为4x4矩阵,所以8x8二次变换结果只有左上角4x4其他三个4x4块变换系数都是0。

void TrQuant::fwdLfnstNxN( int* src, int* dst, const uint32_t mode, const uint32_t index, const uint32_t size, int zeroOutSize )
{
  const int8_t* trMat  = ( size > 4 ) ? g_lfnst8x8[ mode ][ index ][ 0 ] : g_lfnst4x4[ mode ][ index ][ 0 ];
  const int     trSize = ( size > 4 ) ? 48 : 16;	//!<RST对于8x8块使用左上角3个4x4块维度为48
  int           coef;
  int*          out    = dst;

  assert( index < 3 );
  //!<LFNST计算
  for( int j = 0; j < zeroOutSize; j++ )
  {
    int*          srcPtr   = src;
    const int8_t* trMatTmp = trMat;
    coef = 0;
    for( int i = 0; i < trSize; i++ )	//!<矩阵一行乘以一列
    {
      coef += *srcPtr++ * *trMatTmp++;
    }
    *out++ = ( coef + 64 ) >> 7;
    trMat += trSize;	//!<矩阵下一行
  }
  //!<剩余元素置零
  ::memset( out, 0, ( trSize - zeroOutSize ) * sizeof( int ) );
}
//!<将结果一维向量转换成二维矩阵
const ScanElement * scanPtr = scan;
int lfnstCoeffNum = ( sbSize == 4 ) ? sbSize * sbSize : 48;
for( y = 0; y < lfnstCoeffNum; y++ )
{
    coeffTemp[ scanPtr->idx ] = *lfnstTemp++;
    scanPtr++;
}

在VTM5中,8x8LFNST变换矩阵进一步缩减从16x64变为16x48,逆矩阵为48x16,输入X只取左上角三个4x4块展开成48维向量,如下图所示。由于维度缩减存储所有LFNST矩阵的空间由10KB减少到8KB而性能未下降太多。

为了减少TU(4x4或8x8)在方面最坏情况下的乘法运算数量,对8x8和4x4TU分别使用8x

48和8x16矩阵。对于尺寸大于8x8的块由于不会发生最坏情况所以使用16x48的矩阵。对于8x4或4x8的TU只对其左上角4x4块使用4x4LFNST(16x16矩阵)。对4xN或Nx4的TU(N≧16)只对其左上角两个邻接4x4块使用4x4LFNST。经过这些简化,最坏情况下每个像素只需要做8次乘法运算。

LFNST变换选择

LFNST中预设了4个变换集,每个变换集有2个不可分离变换。

const int8_t g_lfnst8x8[ 4 ][ 2 ][ 16 ][ 48 ]
const int8_t g_lfnst4x4[ 4 ][ 2 ][ 16 ][ 16 ]

使用哪个变换集由其所使用的帧内预测模式决定,帧内预测模式和变换集对应关系如下:

const uint8_t g_lfnstLut[ NUM_INTRA_MODE + NUM_EXT_LUMA_MODE - 1 ] =
{//0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
   0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};

对于每个变换集还需要传输一个标志位表示使用的不可分离变换矩阵索引。在码流中这个索引位于变换系数之后,且每个CU都需要一个索引。

LFNST索引的传输及与其他工具的交互

8x8 LFNST在前向变换中使用16x48的矩阵,所以在这个8x8块中只有左上角4x4块才有非零值。换句话说,如果8x8块使用了LFNST那么除了左上角4x4块外其他系数都为0。所以如果在8x8块除左上角区域外检测到非零值则表明未使用LFNST则不需要传输LFNST index,这种情况下默认LFNST index=0。如果LFNST index=0表示不使用LFNST模式,否则表示使用LFNST模式。此外,LFNST index进行上下文编码时不依赖于帧内预测模式,且仅第一个bin是上下文编码。

当满足以下两个条件时使用逆LFNST:

  • 块尺寸大于等于给定阈值(W>=4 && H>=4);

  • 变换跳过模式标志位等于0;

如果W>4&&H>4,那么对左上角8x8区域进行8x8LFNST。否则对左上角min(8, W) × min(8, H)区域进行 4x4 LFNST。

LFNST只用于帧内和帧间slice内的帧内CU。对亮度和色度分量都适用。如果允许使用对偶树亮度和色度的LFNST indices分开传输。对于帧间slice(不允许使用对偶树)亮度和色度使用同一个LFNST indices。

如果使用ISP模式则不允许使用LFNST且RST index也不需要传输。因为即使将RST应用于每个可行的分块,性能提升也很有限。不对ISP预测残差使用RST还能减少编码复杂度。对MIP模式也不允许使用LFNST和传输RST index。

参考

JVET-N1002

JVET-N0193

JVET-N0105

感兴趣的请关注微信公众号Video Coding

 

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值