欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

VVC帧内预测(二)CCLM

程序员文章站 2022-07-07 11:58:36
...

跨分支线性模型(Cross-component linear model,CCLM)预测中假设同一个编码块的色度像素值和对应的亮度像素值有线性关系,所以CCLM使用一个线性模型从亮度像素的重建值生成对应色度像素的预测值。

 

VVC帧内预测(二)CCLM

CCLM的参数α和β由相邻的4个色度像素和对应的降采样的亮度像素生成,假设当前块尺寸是WxH,则W′和H′由下列步骤生成:

  • 当使用LM模式时,W′=W,H′=H

  • 当使用LM-A模式时,W′=W+H

  • 当使用LM-L模式时,H′=H+W

上方相邻的像素位置用S[0, -1]…S[W’-1, -1] 表示,左方相邻的像素位置用S[-1, 0]…S[-1, H’-1]表示。则需要的4个像素的选取方式如下:

  • 当使用LM模式且上方和左方相邻的像素都可用时,S[W’/4, -1], S[3W’/4, -1], S[-1, H’/4], S[-1, 3H’/4]

  • 当使用LM-A模式且只有上方相邻的像素都可用时,S[W’/8, -1], S[3W’/8, -1], S[5W’/8, -1], S[7W’/8, -1]

  • 当使用LM-L模式且只有左方相邻的像素都可用时,S[-1, H’/8], S[-1, 3H’/8], S[-1, 5H’/8], S[-1, 7H’/8]

选择的对应位置的4个亮度像素需要进行降采样,并且经过4次比较找出2个较小值VVC帧内预测(二)CCLM和两个较大的值VVC帧内预测(二)CCLM它们对应的色度值分别为VVC帧内预测(二)CCLM

则由下式可以计算得相关参数:

VVC帧内预测(二)CCLM

 

下图展示了计算过程中需要使用的像素值

VVC帧内预测(二)CCLM

 

从上面公式可以看出α计算过程中出现了除法,为了避免除法运算采用查表法计算α。同时为了减少存储表的空间,将diff值(最大值和最小值的差值)和α使用指数形式表示。其中diff可以表示为一个4bit的底数和一个指数,所以1/diff的底数可以用一个16个元素的表表示为

DivTable [ ] = { 0, 7, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 1, 1, 0 }

在LM-A模式中,只使用上方的参考像素计算线性模型参数,为了获得更多的参考像素需要将上方的参考像素扩展为(W+H)。在LM-L模式中,只使用左方的参考像素计算线性模型参数,为了获得更多的参考像素需要将左方的参考像素扩展为(H+W)。

对于非正方形块,上方的参考像素扩展为(W+W),左方的参考像素扩展为(H+H)。

对于4:2:0的序列,提供了2种降采样滤波器使亮度分量在水平和垂直方向进行2倍降采样。可以在SPS中指定该参数,2种降采样滤波器分别表示为"type-0"和"type-2",分别如下:

VVC帧内预测(二)CCLM

 

注意:当上方的参考像素正好位于CTU边界时,只使用1行亮度像素进行降采样。

α和β也可以在解码端计算得到,所以在传输码流时不需要传输α和β相关的语法元素。

在VTM5中计算CCLM相关代码如下:

if (leftAvailable || aboveAvailable)
  {
    int diff = maxLuma[0] - minLuma[0];
    if (diff > 0)
    {
      int diffC = maxLuma[1] - minLuma[1];
      int x = floorLog2( diff );
      static const uint8_t DivSigTable[1 << 4] = {
        // 4bit significands - 8 ( MSB is omitted ) //!<DivTable 
        0,  7,  6,  5,  5,  4,  4,  3,  3,  2,  2,  1,  1,  1,  1,  0
      };
      int normDiff = (diff << 4 >> x) & 15;
      int v = DivSigTable[normDiff] | 8;
      x += normDiff != 0;
​
      int y = floorLog2( abs( diffC ) ) + 1;
      int add = 1 << y >> 1;
      a = (diffC * v + add) >> y;
      iShift = 3 + x - y;
      if ( iShift < 1 ) {
        iShift = 1;
        a = ( (a == 0)? 0: (a < 0)? -15 : 15 );   // a=Sign(a)*15
      }
      b = minLuma[1] - ((a * minLuma[0]) >> iShift);
    }
    else
    {
      a = 0;
      b = minLuma[1];
      iShift = 0;
    }
  }
  else
  {
    a = 0;
​
    b = 1 << (internalBitDepth - 1);
​
    iShift = 0;
  }

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

VVC帧内预测(二)CCLM