/** Calculate SAO statistics for current LCU
* \param iAddr, iPartIdx, iYCbCr
*/
Void TEncSampleAdaptiveOffset::calcSaoStatsCu(Int iAddr, Int iPartIdx, Int iYCbCr)
{
if(!m_bUseNIF) //!< true for performing non-cross slice boundary ALF
{
calcSaoStatsCuOrg( iAddr, iPartIdx, iYCbCr);
}
else
{
Int64** ppStats = m_iOffsetOrg[iPartIdx]; //!< [MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS] ??
Int64** ppCount = m_iCount [iPartIdx]; //!< [MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS]
//parameters
Int isChroma = (iYCbCr != 0)? 1:0;
Int stride = (iYCbCr != 0)?(m_pcPic->getCStride()):(m_pcPic->getStride());
Pel* pPicOrg = getPicYuvAddr (m_pcPic->getPicYuvOrg(), iYCbCr);
Pel* pPicRec = getPicYuvAddr(m_pcYuvTmp, iYCbCr);
std::vector<NDBFBlockInfo>& vFilterBlocks = *(m_pcPic->getCU(iAddr)->getNDBFilterBlocks());
//variables
UInt xPos, yPos, width, height;
Bool* pbBorderAvail;
UInt posOffset;
for(Int i=0; i< vFilterBlocks.size(); i++)
{
xPos = vFilterBlocks[i].posX >> isChroma;
yPos = vFilterBlocks[i].posY >> isChroma;
width = vFilterBlocks[i].width >> isChroma;
height = vFilterBlocks[i].height >> isChroma;
pbBorderAvail = vFilterBlocks[i].isBorderAvailable;
posOffset = (yPos* stride) + xPos;
//! 对ppStats,ppCount赋值,分别计算出对应滤波模式下原始像素与重建像素之间的差值,重建值对应的classIdx的统计值
calcSaoStatsBlock(pPicRec+ posOffset, pPicOrg+ posOffset, stride, ppStats, ppCount,width, height, pbBorderAvail, iYCbCr);
}
}
}
/** Calculate SAO statistics for non-cross-slice or non-cross-tile processing
* \param pRecStart to-be-filtered block buffer pointer
* \param pOrgStart original block buffer pointer
* \param stride picture buffer stride
* \param ppStat statistics buffer
* \param ppCount counter buffer
* \param width block width
* \param height block height
* \param pbBorderAvail availabilities o