VVC 帧内预测 predIntraAng()函数 (getCoLocatedLumaPU没写)

H.266/VVC-VTM代码学习-帧内预测05-Angular模式下计算预测像素值xPredIntraAng_liaojq2020的博客-CSDN博客

VVC学习之五:帧内预测——67个模式预测信号生成 predIntraAng()_Aidoneus_y的博客-CSDN博客

piPred:里面有W,H,Stride三个参数,建议在最边缘有填充的CTU时运行一下,看一下具体操作

void IntraPrediction::predIntraAng( const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu)
{
  const ComponentID    compID       = MAP_CHROMA( compId );
  const ChannelType    channelType  = toChannelType( compID );
  const int            iWidth       = piPred.width;
  const int            iHeight      = piPred.height;
  CHECK(iWidth == 2, "Width of 2 is not supported");
  CHECK(PU::isMIP(pu, toChannelType(compId)), "We should not get here for MIP.");
  const uint32_t       uiDirMode    = isLuma( compId ) && pu.cu->bdpcmMode ? BDPCM_IDX : !isLuma(compId) && pu.cu->bdpcmModeChroma ? BDPCM_IDX : PU::getFinalIntraMode(pu, channelType);

  CHECK( floorLog2(iWidth) < 2 && pu.cs->pcv->noChroma2x2, "Size not allowed" );
  CHECK( floorLog2(iWidth) > 7, "Size not allowed" );

  const int srcStride  = m_refBufferStride[compID];
  const int srcHStride = 2;

  const CPelBuf & srcBuf = CPelBuf(getPredictorPtr(compID), srcStride, srcHStride);
  const ClpRng& clpRng(pu.cu->cs->slice->clpRng(compID));//嵌位的范围
  
  /************ 根据模式进入对应的操作 ************/
  switch (uiDirMode)
  {
    case(PLANAR_IDX): xPredIntraPlanar(srcBuf, piPred); break;
    case(DC_IDX):     xPredIntraDc(srcBuf, piPred, channelType, false); break;
    case(BDPCM_IDX):  xPredIntraBDPCM(srcBuf, piPred, isLuma(compID) ? pu.cu->bdpcmMode : pu.cu->bdpcmModeChroma, clpRng); break;
    default:          xPredIntraAng(srcBuf, piPred, channelType, clpRng); break;
  }

 

uiDirMode:亮度BDPCM模式?BDPCM_IDX:色度BDPCM模式?BDPCM_IDX:getFinalIntraMode()

getFinalIntraMode():如果是色度,进行预测模式转换:0~66.解析在最后

srcStride :从m_refBufferStride[compID],根据分量的不同,从参考像素步长缓冲区取出值。所以应该是左或上的参考像素的长度,值为当前区域的(宽或高)*2+1.因为有一个最左上像素。以块为64X64为例,srcStride =129

这里给出HEVC中的定义:

\param srcStride the stride of the reconstructed sample array

重建像素数组的步长,重建像素也被当成参考像素

还可以参考​​​​​​H.266/VVC代码学习:帧内预测之角度预测函数(predIntraAng、xPredIntraAng)_涵小呆的博客-CSDN博客_vvc 帧内预测

H.266/VVC代码学习20:角度预测入口 / 特殊模式的PDPC技术(predIntraAng)_海洋之心。的博客-CSDN博客

srcHStride:这个2代表有两条参考像素,上边和左边。如果用了MRL可能会有变化,srcBuf存了上边和左边参考像素的信息

srcBuf:存储了当前块预测要用的参考像素,第0行存的是上边的参考像素,第1行存的是左边的参考像素

ClpRng:clip range,应该是截取范围的意思

getPredictorPtr():ptr应该是pointer的意思。这个函数根据refFilterFlag的不同,返回滤波与未滤波的参考像素

 /************ PDDC模式(当前仅对planar.DC模式) ************/
  if (m_ipaParam.applyPDPC)
  {
    PelBuf dstBuf = piPred;
    const int scale = ((floorLog2(iWidth) - 2 + floorLog2(iHeight) - 2 + 2) >> 2);//缩放
    CHECK(scale < 0 || scale > 31, "PDPC: scale < 0 || scale > 31");

    if (uiDirMode == PLANAR_IDX || uiDirMode == DC_IDX)
    {
      for (int y = 0; y < iHeight; y++)
      {
        const int wT   = 32 >> std::min(31, ((y << 1) >> scale));//距离大于32,则权重就为0
        const Pel left = srcBuf.at(y + 1, 1);
        for (int x = 0; x < iWidth; x++)
        {
          const int wL    = 32 >> std::min(31, ((x << 1) >> scale));
          const Pel top   = srcBuf.at(x + 1, 0);
          const Pel val   = dstBuf.at(x, y);
          dstBuf.at(x, y) = val + ((wL * (left - val) + wT * (top - val) + 32) >> 6);
        }
      }
    }
  }
}

 H.266/VVC技术学习:帧内预测之PDPC技术_涵小呆的博客-CSDN博客

 WT:当前测试像素与最上方参考像素的权重

WL:当前测试像素与最左方参考像素的权重。举例,x,y(0,0)时,WL=32,但x,y(10,0)时,WL=1,因为当前预测像素离左边参考像素过远,所以权重下降

注意left,top读取的是srcBuf中的值,并不是整个块的dstBuf。所以这里也表示,srcBuf中第0列存的是上边的参考像素,第1列存的是左边的参考像素,有点像一个二维数组

注意:因为看了后面的xPredIntraPlanar()函数,有点对不上。所以推测srcBuf[0,0],srcBuf[0,0],都存的是同一个值,是两个参考像素共有的最左上角像素。在进行PDPC时,未计算最左上角像素的权重。

举例,当前预测像素(x,y)为(0,0),left为srcBuf.at(1, 1),即(-1,0),top为srcBuf.at(x + 1, 0),即(0,-1),刚好对应

VAL:当前预测像素(x,y)的像素值,注意,这里读取的是dstBuf

dstBuf.at(x, y):经过PDPC后的预测值(当前公式仅适用于planar,DC模式。其他的有变化)

1.2 getFinalIntraMode()函数解析

uint32_t PU::getFinalIntraMode( const PredictionUnit &pu, const ChannelType &chType )
{
  //当前测试模式
  uint32_t uiIntraMode = pu.intraDir[chType];
  //当前预测模式为70且为色度,由函数决定
  if( uiIntraMode == DM_CHROMA_IDX && !isLuma( chType ) )
  {
    uiIntraMode = getCoLocatedIntraLumaMode(pu);
  }
  //若为422,色度,测试模式小于67.
  //422的一个表做转换得出测试模式序号
  if( pu.chromaFormat == CHROMA_422 && !isLuma( chType ) && uiIntraMode < NUM_LUMA_MODE ) // map directional, planar and dc
  {
    uiIntraMode = g_chroma422IntraAngleMappingTable[uiIntraMode];
  }
  return uiIntraMode;
}

H.266/VVC代码学习14:色度列表及DM模式代码(getFinalIntraMode、getIntraChromaCandModes)_海洋之心。的博客-CSDN博客

DM_CHROMA_IDX:derived mode (DM),由亮度模式导出的色度模式号,DM_CHROMA_IDX =(NUM_LUMA_MODE + NUM_LMC_MODE)

getCoLocatedLumaPU():之后写,这个是用在色度预测里的

返回当前的预测模式序号

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值