HM10.0中calcSaoStatsCuOrg的解析

来源:互联网 发布:油性皮肤美白 知乎 编辑:程序博客网 时间:2024/06/08 02:28


rdoSaoUnitAll 中的 calcSaoStatsCu()

简单分析一下calcSaoStatsCuOrg这个函数

if(!m_bUseNIF)//!< true for performing non-cross slice boundary ALF  {    calcSaoStatsCuOrg( iAddr, iPartIdx, iYCbCr);  }



/** Calculate SAO statistics for current LCU without non-crossing slice * \param  iAddr,  iPartIdx,  iYCbCr */Void TEncSampleAdaptiveOffset::calcSaoStatsCuOrg(Int iAddr, Int iPartIdx, Int iYCbCr){  Int x,y;  TComDataCU *pTmpCu = m_pcPic->getCU(iAddr);  TComSPS *pTmpSPS =  m_pcPic->getSlice(0)->getSPS();  Pel* pOrg;  Pel* pRec;  Int iStride;  Int iLcuHeight = pTmpSPS->getMaxCUHeight();  Int iLcuWidth  = pTmpSPS->getMaxCUWidth();  UInt uiLPelX   = pTmpCu->getCUPelX();  UInt uiTPelY   = pTmpCu->getCUPelY();  UInt uiRPelX;  UInt uiBPelY;  Int64* iStats;  Int64* iCount;  Int iClassIdx;  Int iPicWidthTmp;  Int iPicHeightTmp;  Int iStartX;  Int iStartY;  Int iEndX;  Int iEndY;  Pel* pTableBo = (iYCbCr==0)?m_lumaTableBo:m_chromaTableBo;  Int iIsChroma = (iYCbCr!=0)? 1:0;  Int numSkipLine = iIsChroma? 2:4;  if (m_saoLcuBasedOptimization == 0)  {    numSkipLine = 0;  }  Int numSkipLineRight = iIsChroma? 3:5;  if (m_saoLcuBasedOptimization == 0)  {    numSkipLineRight = 0;  }  iPicWidthTmp  = m_iPicWidth  >> iIsChroma;  iPicHeightTmp = m_iPicHeight >> iIsChroma;  iLcuWidth     = iLcuWidth    >> iIsChroma;  iLcuHeight    = iLcuHeight   >> iIsChroma;  uiLPelX       = uiLPelX      >> iIsChroma;  uiTPelY       = uiTPelY      >> iIsChroma;  uiRPelX       = uiLPelX + iLcuWidth  ;  uiBPelY       = uiTPelY + iLcuHeight ;  uiRPelX       = uiRPelX > iPicWidthTmp  ? iPicWidthTmp  : uiRPelX;  uiBPelY       = uiBPelY > iPicHeightTmp ? iPicHeightTmp : uiBPelY;  iLcuWidth     = uiRPelX - uiLPelX;  iLcuHeight    = uiBPelY - uiTPelY;  iStride    =  (iYCbCr == 0)? m_pcPic->getStride(): m_pcPic->getCStride();//if(iSaoType == BO_0 || iSaoType == BO_1)  {    if( m_saoLcuBasedOptimization && m_saoLcuBoundary )    {      numSkipLine = iIsChroma? 1:3;      numSkipLineRight = iIsChroma? 2:4;    }    iStats = m_iOffsetOrg[iPartIdx][SAO_BO];    iCount = m_iCount    [iPartIdx][SAO_BO];    pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);    pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);    iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth : iLcuWidth-numSkipLineRight;    iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight : iLcuHeight-numSkipLine;    for (y=0; y<iEndY; y++)    {      for (x=0; x<iEndX; x++)      {        iClassIdx = pTableBo[pRec[x]];//pTableBo[256],iClassIdx就是1~32中的一种,就是band类型,        if (iClassIdx)        {          iStats[iClassIdx] += (pOrg[x] - pRec[x]); //iStats统计org和rec的偏差总和,iStats = m_iOffsetOrg[iPartIdx][SAO_BO]          iCount[iClassIdx] ++;//iCount = m_iCount    [iPartIdx][SAO_BO]; iCount统计iClassIdx的个数        }      }      pOrg += iStride;      pRec += iStride;    }  }  Int iSignLeft;  Int iSignRight;  Int iSignDown;  Int iSignDown1;  Int iSignDown2;  UInt uiEdgeType;//if (iSaoType == EO_0  || iSaoType == EO_1 || iSaoType == EO_2 || iSaoType == EO_3)  {//E0 水平比较  //if (iSaoType == EO_0)    {      if( m_saoLcuBasedOptimization && m_saoLcuBoundary )      {        numSkipLine = iIsChroma? 1:3;        numSkipLineRight = iIsChroma? 3:5;      }      iStats = m_iOffsetOrg[iPartIdx][SAO_EO_0];      iCount = m_iCount    [iPartIdx][SAO_EO_0];      pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);      pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);      iStartX = (uiLPelX == 0) ? 1 : 0;//如果当前像素是第0列,它左边没有像素了,就令iStartX = 1  //如果当前块的最后像素等于图像宽度,意味着没有右边像素,就令iEndX = 63,      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight;      for (y=0; y<iLcuHeight-numSkipLine; y++)      {        iSignLeft = xSign(pRec[iStartX] - pRec[iStartX-1]);        for (x=iStartX; x< iEndX; x++)        {          iSignRight =  xSign(pRec[x] - pRec[x+1]);           uiEdgeType =  iSignRight + iSignLeft + 2;          iSignLeft  = -iSignRight;//好巧妙啊,这样就可以少算了。  //m_auiEoTable[uiEdgeType]映射EO类型,将好计算的结果映射到规范中对于的类型          iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);          iCount[m_auiEoTable[uiEdgeType]] ++;        }        pOrg += iStride;        pRec += iStride;      }    }  //if (iSaoType == EO_1)    {//垂直类型      if( m_saoLcuBasedOptimization && m_saoLcuBoundary )      {        numSkipLine = iIsChroma? 2:4;        numSkipLineRight = iIsChroma? 2:4;      }      iStats = m_iOffsetOrg[iPartIdx][SAO_EO_1];      iCount = m_iCount    [iPartIdx][SAO_EO_1];      pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);      pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);      iStartY = (uiTPelY == 0) ? 1 : 0;      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth : iLcuWidth-numSkipLineRight;      iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine;      if (uiTPelY == 0)      {        pOrg += iStride;        pRec += iStride;      }      for (x=0; x< iLcuWidth; x++)      {        m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride]);      }      for (y=iStartY; y<iEndY; y++)      {        for (x=0; x<iEndX; x++)        {          iSignDown     =  xSign(pRec[x] - pRec[x+iStride]);           uiEdgeType    =  iSignDown + m_iUpBuff1[x] + 2;          m_iUpBuff1[x] = -iSignDown;          iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);          iCount[m_auiEoTable[uiEdgeType]] ++;        }        pOrg += iStride;        pRec += iStride;      }    }  //if (iSaoType == EO_2)    {//45°      if( m_saoLcuBasedOptimization && m_saoLcuBoundary )      {        numSkipLine = iIsChroma? 2:4;        numSkipLineRight = iIsChroma? 3:5;      }      iStats = m_iOffsetOrg[iPartIdx][SAO_EO_2];      iCount = m_iCount    [iPartIdx][SAO_EO_2];      pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);      pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);      iStartX = (uiLPelX == 0) ? 1 : 0;      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight;      iStartY = (uiTPelY == 0) ? 1 : 0;      iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine;      if (uiTPelY == 0)      {        pOrg += iStride;        pRec += iStride;      }      for (x=iStartX; x<iEndX; x++)      {        m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride-1]);      }      for (y=iStartY; y<iEndY; y++)      {        iSignDown2 = xSign(pRec[iStride+iStartX] - pRec[iStartX-1]);        for (x=iStartX; x<iEndX; x++)        {          iSignDown1      =  xSign(pRec[x] - pRec[x+iStride+1]) ;          uiEdgeType      =  iSignDown1 + m_iUpBuff1[x] + 2;          m_iUpBufft[x+1] = -iSignDown1;           iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);          iCount[m_auiEoTable[uiEdgeType]] ++;        }        m_iUpBufft[iStartX] = iSignDown2;        ipSwap     = m_iUpBuff1;        m_iUpBuff1 = m_iUpBufft;        m_iUpBufft = ipSwap;        pRec += iStride;        pOrg += iStride;      }    }   //if (iSaoType == EO_3  )    {      if( m_saoLcuBasedOptimization && m_saoLcuBoundary )      {        numSkipLine = iIsChroma? 2:4;        numSkipLineRight = iIsChroma? 3:5;      }      iStats = m_iOffsetOrg[iPartIdx][SAO_EO_3];      iCount = m_iCount    [iPartIdx][SAO_EO_3];      pOrg = getPicYuvAddr(m_pcPic->getPicYuvOrg(), iYCbCr, iAddr);      pRec = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr, iAddr);      iStartX = (uiLPelX == 0) ? 1 : 0;      iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth-numSkipLineRight;      iStartY = (uiTPelY == 0) ? 1 : 0;      iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight-numSkipLine;      if (iStartY == 1)      {        pOrg += iStride;        pRec += iStride;      }      for (x=iStartX-1; x<iEndX; x++)      {        m_iUpBuff1[x] = xSign(pRec[x] - pRec[x-iStride+1]);      }      for (y=iStartY; y<iEndY; y++)      {        for (x=iStartX; x<iEndX; x++)        {          iSignDown1      =  xSign(pRec[x] - pRec[x+iStride-1]) ;          uiEdgeType      =  iSignDown1 + m_iUpBuff1[x] + 2;          m_iUpBuff1[x-1] = -iSignDown1;           iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);          iCount[m_auiEoTable[uiEdgeType]] ++;        }        m_iUpBuff1[iEndX-1] = xSign(pRec[iEndX-1 + iStride] - pRec[iEndX]);        pRec += iStride;        pOrg += iStride;      }     }   }}


原创粉丝点击