参考像素是否进行滤波的条件在initPredIntraParams,也就是帧内预测参数初始化。
如果满足以下任一条件,则参考像素不进行滤波操作:
- 若SPS标识参考像素滤波不可用
- 或当前块不是Luma块
- 或使用ISP(多划分预测)
- 或使用MIP(矩阵加权帧内预测)
- 或使用非第0行参考像素
- 或使用DC模式时
- 或使用luma的BDPCM
chtype是用来接收compID的,compID是表面componet的;
/********************判断是否对参考像素进行滤波**********************/
//high level conditions and DC intra prediction
//若SPS标识参考像素滤波不可用
//或当前块不是Luma块
//或使用ISP(多划分预测)
//或使用MIP(矩阵加权帧内预测)
//或使用非第0行参考像素
//或使用DC模式时
//或使用luma的BDPCM
//不进行之后的判断并且保持不滤波的初始设置(0)
// ——————————————————————
// 是Luma 且 不使用ISP 且 不使用MIP 且 使用第零行参考像素 且 不适用DC模式 且 不使用Luma的BDPCM
// high level conditions and DC intra prediction
// 是亮度分量吗? && 不适用ISP && 不使用MIP吗?&&第零行参考像素 && 1 != dirmode
if (isLuma(chType) && !useISP && !PU::isMIP(pu, chType) && m_ipaParam.multiRefIndex == 0 && DC_IDX != dirMode
&& !pu.cu->bdpcmMode)
// 参考像素滤波
void IntraPrediction::xFilterReferenceSamples(const Pel *refBufUnfiltered, Pel *refBufFiltered, const CompArea &area,
const SPS &sps, int multiRefIdx)
{ //compID我有点懂了,分量标志
/************************ 初始化 **************************/
if (area.compID != COMPONENT_Y) //如果不是亮度分量,也就是如果是色度的话,只用一行参考
{
multiRefIdx = 0; // 参考行取第一行
}
const int predSize = m_topRefLength + multiRefIdx; // 2w+索引
const int predHSize = m_leftRefLength + multiRefIdx; // 2h+索引
const ptrdiff_t predStride = m_refBufferStride[area.compID];
const Pel topLeft =
(refBufUnfiltered[0] + refBufUnfiltered[1] + refBufUnfiltered[predStride] + refBufUnfiltered[predStride + 1] + 2)
>> 2;
// 左上角滤波后像素,先存左上
refBufFiltered[0] = topLeft;
// 遍历上方像素
for (int i = 1; i < predSize; i++)
{
// 这应该是在滤波,因为是 滤波 = 未滤波操作,[1 2 1]滤波
refBufFiltered[i] = (refBufUnfiltered[i - 1] + 2 * refBufUnfiltered[i] + refBufUnfiltered[i + 1] + 2) >> 2;
}
//最右上角像素
refBufFiltered[predSize] = refBufUnfiltered[predSize];
refBufFiltered += predStride; // 是不是每个都加了?这样[0]就变动了
refBufUnfiltered += predStride;
// 第一个存的是topleft,为什么要存两次,是不是因为上面无差别+,然后需要再存一次,我想是这样的
refBufFiltered[0] = topLeft;
// 又开始对左侧进行相同的滤波操作
for (int i = 1; i < predHSize; i++)
{
refBufFiltered[i] = (refBufUnfiltered[i - 1] + 2 * refBufUnfiltered[i] + refBufUnfiltered[i + 1] + 2) >> 2;
}
// 最左下,其他都是要操作,最后一个不用
refBufFiltered[predHSize] = refBufUnfiltered[predHSize];
}