1、calcSaoStatsCu函数里面调用了calcSaoStatsCuOrg
Void TEncSampleAdaptiveOffset::calcSaoStatsCu(Int iAddr, Int iPartIdx, Int iYCbCr)
{
if(!m_bUseNIF)//!< true for performing non-cross slice boundary ALF
{
calcSaoStatsCuOrg( iAddr, iPartIdx, iYCbCr);
}
}
2、calcSaoStatsCuOrg 遍历计算CTU中各种SAO_TYPE的统计信息。包括EO_0,EO_1,EO_2,EO_3,BO五种。
A、BO
iEndX = (uiRPelX == iPicWidthTmp) ? iLcuWidth : iLcuWidth-numSkipLineRight;
iEndY = (uiBPelY == iPicHeightTmp) ? iLcuHeight : iLcuHeight-numSkipLine;//我也不懂numSkipLine是什么,求指教。
for (y=0; y<iEndY; y++)
{
for (x=0; x<iEndX; x++)
{
iClassIdx = pTableBo[pRec[x]]; //参考博客http://blog.csdn.net/hevc_cjl/article/details/8288479
if (iClassIdx) //有32个值 1---32
{
iStats[iClassIdx] += (pOrg[x] - pRec[x]); //得到差值的和,以便于后面计算offset。
iCount[iClassIdx] ++;//得到每个Class的像素的个数。
}
}
pOrg += iStride;
pRec += iStride;
}
B、EO_0
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;
iStats[m_auiEoTable[uiEdgeType]] += (pOrg[x] - pRec[x]);//得到差值的和,以便于后面计算offset。
iCount[m_auiEoTable[uiEdgeType]] ++;//得到每个Class的像素的个数。
}
pOrg += iStride;
pRec += iStride;
}
C、EO_1, EO_2,EO_3的方法类似B中的方法。