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;
}
}
}
}