void IntraPrediction::predIntraAng( const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu)
{
const ComponentID compID = MAP_CHROMA( compId );
const ChannelType channelType = toChannelType( compID );
const int iWidth = piPred.width;
const int iHeight = piPred.height;
CHECK(iWidth == 2, "Width of 2 is not supported");
CHECK(PU::isMIP(pu, toChannelType(compId)), "We should not get here for MIP.");
//uiDirMode中获得当前块的预测模式(不管是亮度还是色度)
const uint32_t uiDirMode = isLuma( compId ) && pu.cu->bdpcmMode ? BDPCM_IDX : !isLuma(compId) && pu.cu->bdpcmModeChroma ? BDPCM_IDX : PU::getFinalIntraMode(pu, channelType);
CHECK( floorLog2(iWidth) < 2 && pu.cs->pcv->noChroma2x2, "Size not allowed" );
CHECK( floorLog2(iWidth) > 7, "Size not allowed" );
const int srcStride = m_refBufferStride[compID];//宽度,用于下一行
const int srcHStride = 2; //高度,用于下一列(为什么是2??)
const CPelBuf & srcBuf = CPelBuf(getPredictorPtr(compID), srcStride, srcHStride);
const ClpRng& clpRng(pu.cu->cs->slice->clpRng(compID));
switch (uiDirMode)
{//根据模式调用不同的预测函数
case(PLANAR_IDX): xPredIntraPlanar(srcBuf, piPred); break;
case(DC_IDX): xPredIntraDc(srcBuf, piPred, channelType, false); break;
case(BDPCM_IDX): xPredIntraBDPCM(srcBuf, piPred, isLuma(compID) ? pu.cu->bdpcmMode : pu.cu->bdpcmModeChroma, clpRng); break;
default: xPredIntraAng(srcBuf, piPred, channelType, clpRng); break;
}
//PDPC模式
if (m_ipaParam.applyPDPC)
{
PelBuf dstBuf = piPred;
const int scale = ((floorLog2(iWidth) - 2 + floorLog2(iHeight) - 2 + 2) >> 2);
CHECK(scale < 0 || scale > 31, "PDPC: scale < 0 || scale > 31");
if (uiDirMode == PLANAR_IDX || uiDirMode == DC_IDX)
{//对于planar和dc模式,使用上和左同时修正
for (int y = 0; y < iHeight; y++)
{
const int wT = 32 >> std::min(31, ((y << 1) >> scale));
const Pel left = srcBuf.at(y + 1, 1);
for (int x = 0; x < iWidth; x++)
{
const int wL = 32 >> std::min(31, ((x << 1) >> scale));
const Pel top = srcBuf.at(x + 1, 0);
const Pel val = dstBuf.at(x, y);
dstBuf.at(x, y) = val + ((wL * (left - val) + wT * (top - val) + 32) >> 6);
}
}
}
}
}
xPredIntraAng函数解析
PDPC技术及代码解析