xPredIntraAng

来源:互联网 发布:游戏变速器源码 编辑:程序博客网 时间:2024/06/07 20:09
Void TComPrediction::xPredIntraAng(       Int bitDepth,                                    const Pel* pSrc,     Int srcStride,                                          Pel* pTrueDst, Int dstStrideTrue,                                          UInt uiWidth, UInt uiHeight, ChannelType channelType,                                          UInt dirMode, const Bool bEnableEdgeFilters                                  ){  Int width=Int(uiWidth);  Int height=Int(uiHeight);  // Map the mode index to main prediction direction and angle  assert( dirMode != PLANAR_IDX ); //no planar 不是planar模式  const Bool modeDC        = dirMode==DC_IDX;  // Do the DC prediction 按DC模式进行预测  if (modeDC)  {    const Pel dcval = predIntraGetPredValDC(pSrc, srcStride, width, height);    for (Int y=height;y>0;y--, pTrueDst+=dstStrideTrue)    {      for (Int x=0; x<width;) //宽度总是4的倍数 width is always a multiple of 4.      {        pTrueDst[x++] = dcval;      }    }  }  /*******************************************角度预测模式****************************************************/  else // Do angular predictions 角度模式进行预测  {    const Bool       bIsModeVer         = (dirMode >= 18);    const Int        intraPredAngleMode = (bIsModeVer) ? (Int)dirMode - VER_IDX :  -((Int)dirMode - HOR_IDX);    const Int        absAngMode         = abs(intraPredAngleMode);    const Int        signAng            = intraPredAngleMode < 0 ? -1 : 1;    const Bool       edgeFilter         = bEnableEdgeFilters && isLuma(channelType) && (width <= MAXIMUM_INTRA_FILTERED_WIDTH) && (height <= MAXIMUM_INTRA_FILTERED_HEIGHT);    // Set bitshifts and scale the angle parameter to block size    static const Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};    static const Int invAngTable[9] = {0, 4096, 1638, 910, 630, 482, 390, 315, 256}; // (256 * 32) / Angle    Int invAngle                    = invAngTable[absAngMode];    Int absAng                      = angTable[absAngMode];    Int intraPredAngle              = signAng * absAng;    Pel* refMain;    Pel* refSide;    Pel  refAbove[2*MAX_CU_SIZE+1];    Pel  refLeft[2*MAX_CU_SIZE+1];    // Initialize the Main and Left reference array.初始化左侧参照的数组    if (intraPredAngle < 0)    {      const Int refMainOffsetPreScale = (bIsModeVer ? height : width ) - 1;      const Int refMainOffset         = height - 1;      for (Int x=0;x<width+1;x++)//上方的参考像素      {        refAbove[x+refMainOffset] = pSrc[x-srcStride-1];      }      for (Int y=0;y<height+1;y++)//左侧的参考像素      {        refLeft[y+refMainOffset] = pSrc[(y-1)*srcStride-1];      }      refMain = (bIsModeVer ? refAbove : refLeft)  + refMainOffset;      refSide = (bIsModeVer ? refLeft  : refAbove) + refMainOffset;      // Extend the Main reference to the left.      Int invAngleSum    = 128;       // rounding for (shift by 8)      for (Int k=-1; k>(refMainOffsetPreScale+1)*intraPredAngle>>5; k--)      {        invAngleSum += invAngle;        refMain[k] = refSide[invAngleSum>>8];      }    }    else    {      for (Int x=0;x<2*width+1;x++)      {        refAbove[x] = pSrc[x-srcStride-1];      }      for (Int y=0;y<2*height+1;y++)      {        refLeft[y] = pSrc[(y-1)*srcStride-1];      }      refMain = bIsModeVer ? refAbove : refLeft ;      refSide = bIsModeVer ? refLeft  : refAbove;    }    // swap width/height if we are doing a horizontal mode:如果是水平模式的话交换宽和高    Pel tempArray[MAX_CU_SIZE*MAX_CU_SIZE];    const Int dstStride = bIsModeVer ? dstStrideTrue : MAX_CU_SIZE;    Pel *pDst = bIsModeVer ? pTrueDst : tempArray;    if (!bIsModeVer)    {      std::swap(width, height);    }    if (intraPredAngle == 0)  // pure vertical or pure horizontal 纯水平和竖直模式    {      for (Int y=0;y<height;y++)      {        for (Int x=0;x<width;x++)        {          pDst[y*dstStride+x] = refMain[x+1];        }      }      if (edgeFilter)      {        for (Int y=0;y<height;y++)        {          pDst[y*dstStride] = Clip3 (0, ((1 << bitDepth) - 1), pDst[y*dstStride] + (( refSide[y+1] - refSide[0] ) >> 1) );        }      }    }    else    {      Pel *pDsty=pDst;      for (Int y=0, deltaPos=intraPredAngle; y<height; y++, deltaPos+=intraPredAngle, pDsty+=dstStride)      {        const Int deltaInt   = deltaPos >> 5;        const Int deltaFract = deltaPos & (32 - 1);        if (deltaFract)        {          // Do linear filtering 线性滤波          const Pel *pRM=refMain+deltaInt+1;          Int lastRefMainPel=*pRM++;          for (Int x=0;x<width;pRM++,x++)          {            Int thisRefMainPel=*pRM;            pDsty[x+0] = (Pel) ( ((32-deltaFract)*lastRefMainPel + deltaFract*thisRefMainPel +16) >> 5 );            lastRefMainPel=thisRefMainPel;          }        }        else        {          // Just copy the integer samples 整体拷贝样本          for (Int x=0;x<width; x++)          {            pDsty[x] = refMain[x+deltaInt+1];          }        }      }    }    // Flip the block if this is the horizontal mode如果是水平模式则将块翻转    if (!bIsModeVer)    {      for (Int y=0; y<height; y++)      {        for (Int x=0; x<width; x++)        {          pTrueDst[x*dstStrideTrue] = pDst[x];        }        pTrueDst++;        pDst+=dstStride;      }    }  }}

0 0
原创粉丝点击