H.266/VVC-VTM代码学习-帧内预测04-Planar模式下计算预测像素值xPredIntraPlanar

H.266/VVC专栏传送

上一篇:H.266/VVC-VTM代码学习-帧内预测03-DC模式下计算预测像素值xPredIntraDc、xGetPredValDc
下一篇:H.266/VVC-VTM代码学习-帧内预测05-Angular模式下计算预测像素值xPredIntraAng

前言

VTM是H.266/VVC视频编码标准的参考软件,研究VTM代码给研究人员解释了VVC编码标准的详细标准规范与细节。

本文是笔者对VTM代码的一点学习记录,成文于笔者刚开始接触VVC期间,期间很多概念和理论框架还很不成熟,若文中存在错误欢迎批评指正,也欢迎广大视频编码学习者沟通交流、共同进步。

VTM代码的下载及编译请参考博文:
【视频编码学习】H.266/VVC参考软件VTM配置运行(VTM-6.0版本)
本文涉及的代码存在于工程下的/lib/CommonLib/SourceFiles/IntraPrediction.cpp文件中。

一、主要函数

1.函数代码

void IntraPrediction::xPredIntraPlanar( const CPelBuf &pSrc, PelBuf &pDst )
{
  const uint32_t width  = pDst.width;
  const uint32_t height = pDst.height;

  const uint32_t log2W = floorLog2( width );
  const uint32_t log2H = floorLog2( height );

  int leftColumn[MAX_CU_SIZE + 1], topRow[MAX_CU_SIZE + 1], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
  const uint32_t offset = 1 << (log2W + log2H);

  // Get left and above reference column and row获取参考像素
  CHECK(width > MAX_CU_SIZE, "width greater than limit");
  for( int k = 0; k < width + 1; k++ )
  {
    //获得正上方参考像素值
    topRow[k] = pSrc.at( k + 1, 0 );
  }

  CHECK(height > MAX_CU_SIZE, "height greater than limit");
  for( int k = 0; k < height + 1; k++ )
  {
    //获得正左侧参考像素值
    leftColumn[k] = pSrc.at(k + 1, 1);
  }

  // Prepare intermediate variables used in interpolation准备用于插值的中间变量
  //TU左下角参考像素
  int bottomLeft = leftColumn[height];
  //TU右上角参考像素
  int topRight = topRow[width];

  //遍历整行
  for( int k = 0; k < width; k++ )
  {
    bottomRow[k] = bottomLeft - topRow[k];//bottomRow = 左下角像素点 - 对应topRow的值
    topRow[k]    = topRow[k] << log2H;//topRow = topRow * height
  }

  //遍历整列
  for( int k = 0; k < height; k++ )
  {
    rightColumn[k] = topRight - leftColumn[k];//rightColumn = 右上角像素点 - 对应leftColumn的值
    leftColumn[k]  = leftColumn[k] << log2W;//leftColumn = leftColumn * width
  }

  const uint32_t finalShift = 1 + log2W + log2H;
  const uint32_t stride     = pDst.stride;
  Pel*       pred       = pDst.buf;
  
  //遍历所有行,通过内层循环求各行的水平预测值
  for( int y = 0; y < height; y++, pred += stride )
  {
    //用于存储水平预测值
    //leftColumn = leftColumn * width
    int horPred = leftColumn[y];
    
    //内层循环遍历当前行,计算对应预测值
    for( int x = 0; x < width; x++ )
    {
      //因为,rightColumn = topRight - leftColumn,leftColumn = leftColumn * width
      //所以,水平预测值为(leftColumn * width) + (topRight - leftColumn[k]) * (x + 1)
      //x表示当前像素所在列,随着遍历当前行,topRight的权重会对应增加
      horPred += rightColumn[y];

      //因为,topRow = topRow * height,bottomRow = bottomLeft - topRow
      //所以,垂直预测值为(topRow * height) * (y + 1) + (bottomLeft - topRow)
      //x表示当前像素所在列,每次遍历到不同行相同列位置,垂直预测值中的bottomLeft权重就会对应增加
      topRow[x] += bottomRow[x];
      
      //用于存储垂直预测值
      int vertPred = topRow[x];
      //最终预测值pred = ((horpred * H) + (vertPred * W)) / (2 * W * H)
      pred[x]      = ( ( horPred << log2H ) + ( vertPred << log2W ) + offset ) >> finalShift;
    }
  }
}

2.逻辑结构

1.获取参考像素:分别使用循环获取当前块正上方参考像素和正左侧参考像素值。

2.设置bottomRow和rightColumn分别存储bottomLeft与对应topRow的差值、topRight与对应leftColumn的差值。

3.外层循环遍历所有行。

4.内存循环遍历当前行的所有列,并计算出水平预测值和垂直预测值,再通过将二者求平均直接得到当前像素点的预测值。

上一篇:H.266/VVC-VTM代码学习-帧内预测03-DC模式下计算预测像素值xPredIntraDc、xGetPredValDc
下一篇:H.266/VVC-VTM代码学习-帧内预测05-Angular模式下计算预测像素值xPredIntraAng

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值