predIntraGetPredValDC函数返回当前块的DC值。
xDCPredFiltering函数则对小于等于16x16大小的亮度块DC预测值滤波。
Pel TComPrediction::predIntraGetPredValDC( const Pel* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight)
{
// pSrc为当前重建块指针
assert(iWidth > 0 && iHeight > 0);
Int iInd, iSum = 0; // iSum统计参考像素的和
Pel pDcVal; // DC值
for (iInd = 0;iInd < iWidth;iInd++)
{
// 加上当前块上方的参考像素
iSum += pSrc[iInd-iSrcStride];
}
for (iInd = 0;iInd < iHeight;iInd++)
{
// 加上左方的参考像素
iSum += pSrc[iInd*iSrcStride-1];
}
// 求平均值,iSum之所以加iWidth是为了四舍五入
pDcVal = (iSum + iWidth) / (iWidth + iHeight);
return pDcVal;
}
Void TComPrediction::xDCPredFiltering( const Pel* pSrc, Int iSrcStride, Pel* pDst, Int iDstStride, Int iWidth, Int iHeight, ChannelType channelType )
{
//pSrc重建块指针 pDst预测块指针
Int x, y, iDstStride2, iSrcStride2;
// 判断条件,亮度分量且小于等于16大小的块才需要进行滤波
if (isLuma(channelType) && (iWidth <= MAXIMUM_INTRA_FILTERED_WIDTH) && (iHeight <= MAXIMUM_INTRA_FILTERED_HEIGHT))
{
//top-left 对预测块左上角像素滤波
pDst[0] = (Pel)((pSrc[-iSrcStride] + pSrc[-1] + 2 * pDst[0] + 2) >> 2);
//top row (vertical filter)
for ( x = 1; x < iWidth; x++ )
{
// 对最上方一行预测像素滤波
pDst[x] = (Pel)((pSrc[x - iSrcStride] + 3 * pDst[x] + 2) >> 2);
}
//left column (horizontal filter)
for ( y = 1, iDstStride2 = iDstStride, iSrcStride2 = iSrcStride-1; y < iHeight; y++, iDstStride2+=iDstStride, iSrcStride2+=iSrcStride )
{
// 对最左边一列预测像素滤波
pDst[iDstStride2] = (Pel)((pSrc[iSrcStride2] + 3 * pDst[iDstStride2] + 2) >> 2);
}
}
return;
}