/*
得到当前PU的neighbor可用信息
过程:
1.计算tu的像素size、tu以4x4block为单位的size
2.得到相邻leftTop、rightTop、leftBottom的索引
3.检查各个neighbor是否可用,统计neighbor的数据信息
4.存储下neignbor的数据信息
*/
void Predict::initIntraNeighbors(const CUData& cu, uint32_t absPartIdx, uint32_t tuDepth, bool isLuma, IntraNeighbors *intraNeighbors)
{
//tu的size = CUsize - tu深度,log(Pixel)为单位
uint32_t log2TrSize = cu.m_log2CUSize[0] - tuDepth;
//unit默认大小为4x4 pixel
int log2UnitWidth = LOG2_UNIT_SIZE;
int log2UnitHeight = LOG2_UNIT_SIZE;
//若非luma,则chroma的尺寸要相应做出变化
if (!isLuma)
{
log2TrSize -= cu.m_hChromaShift;
log2UnitWidth -= cu.m_hChromaShift;
log2UnitHeight -= cu.m_vChromaShift;
}
//可用neighbor的个数
int numIntraNeighbor;
//neighbor是否可用的flag标记
bool* bNeighborFlags = intraNeighbors->bNeighborFlags;
//tu的尺寸,像素为单位
uint32_t tuSize = 1 << log2TrSize;
//tu的宽和高,4x4unit为单位
int tuWidthInUnits = tuSize >> log2UnitWidth;
int tuHeightInUnits = tuSize >> log2UnitHeight;
//above和left的4x4unit单元个数
int aboveUnits = tuWidthInUnits << 1;
int leftUnits = tuHeightInUnits << 1;
//leftTop、rightTop、leftBottom的索引
uint32_t partIdxLT = cu.m_absIdxInCTU + absPartIdx;
uint32_t partIdxRT = g_rasterToZscan[g_zscanToRaster[partIdxLT] + tuWidthInUnits - 1];
uint32_t partIdxLB = g_rasterToZscan[g_zscanToRaster[partIdxLT] + ((tuHeightInUnits - 1) << LOG2_RASTER_SIZE)];
/* 统计neighbor的信息
其中isXXXAvailable<true/false>()表示是否限制neighbor也必须要intra才可用?
若isXXXAvailable<false>(),则只需要有neighbor而无需其intra即可用,反之,
若isXXXAvailable<true>(),则当前仅当neighbor存在且也是intra才可用 */
//若Islice || 没开启bConstrainedIntraPred
if (cu.m_slice->isIntra() || !cu.m_slice->m_pps->bConstrainedIntraPred)
{
//检查left、above、aboveRight、left、leftBottom是否可用,存储到bNeighborFlags向量中,并统计可用个数到numIntraNeighbor
bNeighborFlags[leftUnits] = isAboveLeftAvailable<false>(cu, partIdxLT);
numIntraNeighbor = (int)(bNeighborFlags[leftUnits]);
numIntraNeighbor += isAboveAvailable<false>(cu, partIdxLT, partIdxRT, bNeighborFlags + leftUnits + 1);
numIntraNeighbor += isAboveRightAvailable<false>(cu, partIdxRT, bNeighborFlags + leftUnits + 1 + tuWidthInUnits, tuWidthInUnits);
numIntraNeighbor += isLeftAvailable<false>(cu, partIdxLT, partIdxLB, bNeighborFlags + leftUnits - 1);
numIntraNeighbor += isBelowLeftAvailable<false>(cu, partIdxLB, bNeighborFlags + tuHeightInUnits - 1, tuHeightInUnits);
}
//Pslice、Bslice,且开启了bConstrainedIntraPred
else
{
bNeighborFlags[leftUnits] = isAboveLeftAvailable<true>(cu, partIdxLT);
numIntraNeighbor = (int)(bNeighborFlags[leftUnits]);
numIntraNeighbor += isAboveAvailable<true>(cu, partIdxLT, partIdxRT, bNeighborFlags + leftUnits + 1);
numIntraNeighbor += isAboveRightAvailable<true>(cu, partIdxRT, bNeighborFlags + leftUnits + 1 + tuWidthInUnits, tuWidthInUnits);
numIntraNeighbor += isLeftAvailable<true>(cu, partIdxLT, partIdxLB, bNeighborFlags + leftUnits - 1);
numIntraNeighbor += isBelowLeftAvailable<true>(cu, partIdxLB, bNeighborFlags + tuHeightInUnits - 1, tuHeightInUnits);
}
//存储下neignbor的数据
intraNeighbors->numIntraNeighbor = numIntraNeighbor;
intraNeighbors->totalUnits = aboveUnits + leftUnits + 1;//total=above+left+leftAbove
intraNeighbors->aboveUnits = aboveUnits;
intraNeighbors->leftUnits = leftUnits;
intraNeighbors->unitWidth = 1 << log2UnitWidth;
intraNeighbors->unitHeight = 1 << log2UnitHeight;
intraNeighbors->log2TrSize = log2TrSize;
}
Predict::initIntraNeighbors()
最新推荐文章于 2021-11-27 11:14:35 发布