帧内预测之 fillReferenceSamples函数记录

今天抽空看了看 fillReferenceSamples函数,主要功能是针对帧内预测时所需要的参考像素进行填充功能,如果得不到任何参考像素,则每个值赋值为128,如果每个参考值都能找到,则将其原样复制给重建的参考值,如果是一部分知道的话具体参考draft 8.4.4.2.2,代码里一些重要部分的解释都给了,如果有不对的地方还请指出:


Void fillReferenceSamples( const Int bitDepth, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags,


                           const Int iNumIntraNeighbor, const Int unitWidth, const Int unitHeight, const Int iAboveUnits, const Int iLeftUnits,
                           const UInt uiCuWidth, const UInt uiCuHeight, const UInt uiWidth, const UInt uiHeight, const Int iPicStride,
                           const ChannelType chType, const ChromaFormat chFmt )
{
  // NOTE: RExt - This function has been modified for increased flexibility as part of the Square TU 4:2:2 implementation,piAdiTemp为填充后的值
  const Pel* piRoiTemp;
  Int  i, j;
  Int  iDCValue = 1 << (bitDepth - 1);//bitDepth为8
  const Int iTotalUnits = iAboveUnits + iLeftUnits + 1; //+1 for top-left


  if (iNumIntraNeighbor == 0)
  {
    // Fill border with DC value
    for (i=0; i<uiWidth; i++)
    {
      piAdiTemp[i] = iDCValue;
    }
    for (i=1; i<uiHeight; i++)
    {
      piAdiTemp[i*uiWidth] = iDCValue;
    }
  }
  else if (iNumIntraNeighbor == iTotalUnits)
  {
    // Fill top-left border and top and top right with rec. samples
    piRoiTemp = piRoiOrigin - iPicStride - 1;//左上角像素(top_left)


    for (i=0; i<uiWidth; i++)
    {
#if RExt__O0043_BEST_EFFORT_DECODING
      piAdiTemp[i] = piRoiTemp[i] << bitDepthDelta;
#else
      piAdiTemp[i] = piRoiTemp[i];
#endif
    }


    // Fill left and below left border with rec. samples
    piRoiTemp = piRoiOrigin - 1;//左边第一个像素


    for (i=1; i<uiHeight; i++)
    {
#if RExt__O0043_BEST_EFFORT_DECODING
      piAdiTemp[i*uiWidth] = (*(piRoiTemp)) << bitDepthDelta;
#else
      piAdiTemp[i*uiWidth] = *(piRoiTemp);
#endif
      piRoiTemp += iPicStride;
    }
  }
  else // reference samples are partially available
  {
    // all above units have "unitWidth" samples each, all left/below-left units have "unitHeight" samples each
    const Int  iTotalSamples = (iLeftUnits * unitHeight) + ((iAboveUnits + 1) * unitWidth);//每行有iAboveUnits个units,每个unit有unitWidth个像素,同理用到高度上,uiWidth-1=iAboveUnits*unitWidth切勿弄错。
    Pel  piAdiLine[5 * MAX_CU_SIZE];
    Pel  *piAdiLineTemp;
    const Bool *pbNeighborFlags;




    // Initialize
    for (i=0; i<iTotalSamples; i++)
    {
      piAdiLine[i] = iDCValue;
    }


    // Fill top-left sample
    piRoiTemp = piRoiOrigin - iPicStride - 1;
    piAdiLineTemp = piAdiLine + (iLeftUnits * unitHeight);
    pbNeighborFlags = bNeighborFlags + iLeftUnits;
    if (*pbNeighborFlags)
    {
#if RExt__O0043_BEST_EFFORT_DECODING
      Pel topLeftVal=piRoiTemp[0] << bitDepthDelta;
#else
      Pel topLeftVal=piRoiTemp[0];
#endif
      for (i=0; i<unitWidth; i++)
      {
        piAdiLineTemp[i] = topLeftVal;
      }
    }


    // Fill left & below-left samples (downwards)
    piRoiTemp += iPicStride;
    piAdiLineTemp--;
    pbNeighborFlags--;


    for (j=0; j<iLeftUnits; j++)
    {
      if (*pbNeighborFlags)
      {
        for (i=0; i<unitHeight; i++)
        {
#if RExt__O0043_BEST_EFFORT_DECODING
          piAdiLineTemp[-i] = piRoiTemp[i*iPicStride] << bitDepthDelta;
#else
          piAdiLineTemp[-i] = piRoiTemp[i*iPicStride];
#endif
        }
      }
      piRoiTemp += unitHeight*iPicStride;
      piAdiLineTemp -= unitHeight;
      pbNeighborFlags--;
    }


    // Fill above & above-right samples (left-to-right) (each unit has "unitWidth" samples)
    piRoiTemp = piRoiOrigin - iPicStride;
    // offset line buffer by iNumUints2*unitHeight (for left/below-left) + unitWidth (for above-left)
    piAdiLineTemp = piAdiLine + (iLeftUnits * unitHeight) + unitWidth;
    pbNeighborFlags = bNeighborFlags + iLeftUnits + 1;
    for (j=0; j<iAboveUnits; j++)
    {
      if (*pbNeighborFlags)
      {
        for (i=0; i<unitWidth; i++)
        {
#if RExt__O0043_BEST_EFFORT_DECODING
          piAdiLineTemp[i] = piRoiTemp[i] << bitDepthDelta;
#else
          piAdiLineTemp[i] = piRoiTemp[i];
#endif
        }
      }
      piRoiTemp += unitWidth;
      piAdiLineTemp += unitWidth;
      pbNeighborFlags++;
    }


    // Pad reference samples when necessary
    Int iCurrJnit = 0;
    Pel  *piAdiLineCur   = piAdiLine;
    const UInt piAdiLineTopRowOffset = iLeftUnits * (unitHeight - unitWidth);


    if (!bNeighborFlags[0])
    {
      // very bottom unit of bottom-left; at least one unit will be valid.
      {
        Int   iNext = 1;
        while (iNext < iTotalUnits && !bNeighborFlags[iNext])
        {
          iNext++;
        }
        Pel *piAdiLineNext = piAdiLine + ((iNext < iLeftUnits) ? (iNext * unitHeight) : (piAdiLineTopRowOffset + (iNext * unitWidth)));
        const Pel refSample = *piAdiLineNext;
        // Pad unavailable samples with new value
        Int iNextOrTop = std::min<Int>(iNext, iLeftUnits);
        // fill left column
        while (iCurrJnit < iNextOrTop)
        {
          for (i=0; i<unitHeight; i++)
          {
            piAdiLineCur[i] = refSample;
          }
          piAdiLineCur += unitHeight;
          iCurrJnit++;
        }
        // fill top row
        while (iCurrJnit < iNext)
        {
          for (i=0; i<unitWidth; i++)
          {
            piAdiLineCur[i] = refSample;
          }
          piAdiLineCur += unitWidth;
          iCurrJnit++;
        }
      }
    }


    // pad all other reference samples.
    while (iCurrJnit < iTotalUnits)
    {
      if (!bNeighborFlags[iCurrJnit]) // samples not available
      {
        {
          const Int numSamplesInCurrUnit = (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight;
          const Pel refSample = *(piAdiLineCur-1);
          for (i=0; i<numSamplesInCurrUnit; i++)
          {
            piAdiLineCur[i] = refSample;
          }
          piAdiLineCur += numSamplesInCurrUnit;
          iCurrJnit++;
        }
      }
      else
      {
        piAdiLineCur += (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight;
        iCurrJnit++;
      }
    }


    // Copy processed samples


    piAdiLineTemp = piAdiLine + uiHeight + unitWidth - 2;
    // top left, top and top right samples
    for (i=0; i<uiWidth; i++)
    {
      piAdiTemp[i] = piAdiLineTemp[i];
    }


    piAdiLineTemp = piAdiLine + uiHeight - 1;
    for (i=1; i<uiHeight; i++)
    {
      piAdiTemp[i*uiWidth] = piAdiLineTemp[-i];
    }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值