/* Deblocking filter process in CU-based (the same function as conventional's)
* param Edge the direction of the edge in block boundary (horizonta/vertical), which is added newly
基于CU进行环路滤波:
过程:
1.递归找到每个CU,基于CU进行进行环路滤波
2.确定滤波边界,设置边界强度
1.默认给CU内部的PU边界设置block strength = 1
2.默认给CU内部的TU边界递归设置block strength = 2
3.默认给CU边界但非帧边界设置block strength = 2,帧边界block strength = 0
4.对于非0的8x8block,获取其boundary strength,并将其赋值给block strength
3.进行边界滤波
*/
void Deblock::deblockCU(const CUData* cu, const CUGeom& cuGeom, const int32_t dir, uint8_t blockStrength[])
{
uint32_t absPartIdx = cuGeom.absPartIdx;
uint32_t depth = cuGeom.depth;
if (cu->m_predMode[absPartIdx] == MODE_NONE)
return;
// 若当前cuGeom.depth深度没有达到之前分析的最优深度m_cuDepth[absPartIdx],则递归
if (cu->m_cuDepth[absPartIdx] > depth)
{
// 拆分当前CU
for (uint32_t subPartIdx = 0; subPartIdx < 4; subPartIdx++)
{
// 得到subCU的几何形状
const CUGeom& childGeom = *(&cuGeom + cuGeom.childOffset + subPartIdx);
// 若当前subCU呈现出来,则递归deblock
if (childGeom.flags & CUGeom::PRESENT)
deblockCU(cu, childGeom, dir, blockStrength);
}
return;
}
/* 确定滤波边界 */
// CU的4x4block个数
uint32_t numUnits = 1 << (cuGeom.log2CUSize - LOG2_UNIT_SIZE);
// PU边界给1
setEdgefilterPU(cu, absPartIdx, dir, blockStrength, numUnits);
// 递归对TU边界给2
setEdgefilterTU(cu, absPartIdx, 0, dir, blockStrength);
// CU边界给2,图像边界给0
setEdgefilterMultiple(absPartIdx, dir, 0, bsCuEdge(cu, absPartIdx, dir), blockStrength, numUnits);
/* 获取边界强度 */
// CU的4x4block个数
uint32_t numParts = cuGeom.numPartitions;
// 遍历当前CU的每个4x4block
for (uint32_t partIdx = absPartIdx; partIdx < absPartIdx + numParts; partIdx++)
{
// 因为这里遍历单位4x4block,而滤波边界单位为8x8block,
// 所以bsCheck过滤掉非8x8block边界
uint32_t bsCheck = !(partIdx & (1 << dir));
// 若是8x8边界,且blockStrength非0,则获取获取边界强度
if (bsCheck && blockStrength[partIdx])
blockStrength[partIdx] = getBoundaryStrength(cu, dir, partIdx, blockStrength);
}
/* 执行环路滤波 */
// 最小环路滤波执行单位DEBLOCK_SMALLEST_BLOCK = 8x8中,有partIdxIncr块4x4block,
// 遍历时计数器增长单位为partIdxIncr
const uint32_t partIdxIncr = DEBLOCK_SMALLEST_BLOCK >> LOG2_UNIT_SIZE;
uint32_t shiftFactor = (dir == EDGE_VER) ? cu->m_hChromaShift : cu->m_vChromaShift;
uint32_t chromaMask = ((DEBLOCK_SMALLEST_BLOCK << shiftFactor) >> LOG2_UNIT_SIZE) - 1;
uint32_t e0 = (dir == EDGE_VER ? g_zscanToPelX[absPartIdx] : g_zscanToPelY[absPartIdx]) >> LOG2_UNIT_SIZE;
// 以8x8block为单位遍历进行边界滤波
for (uint32_t e = 0; e < numUnits; e += partIdxIncr)
{
// 进行luma环路滤波
edgeFilterLuma(cu, absPartIdx, depth, dir, e, blockStrength);
// 进行chroma环路滤波
if (!((e0 + e) & chromaMask) && cu->m_chromaFormat != X265_CSP_I400)
edgeFilterChroma(cu, absPartIdx, depth, dir, e, blockStrength);
}
}
Deblock::deblockCU()
最新推荐文章于 2021-04-21 20:02:02 发布