作用:
bool QTBTPartitioner::nextPart( const CodingStructure &cs, bool autoPop /*= false*/ )
{
//prevpos即当前CU的位置
const Position &prevPos = currArea().blocks[chType].pos();
unsigned currIdx = ++m_partStack.back().idx;
m_partStack.back().checkdIfImplicit = false;
m_partStack.back().isImplicit = false;
if( currIdx == 1 )
{
const CodingUnit* prevCU = cs.getCU( prevPos, chType );
m_partStack.back().firstSubPartSplit = prevCU ? CU::getSplitAtDepth( *prevCU, currDepth ) : CU_DONT_SPLIT;
}
//如果currIdx 小于当前CU所属的父CU划分出的子CU个数
if( currIdx < m_partStack.back().parts.size() )
{
//如果当前CU的划分为TT
if( m_partStack.back().split == CU_TRIH_SPLIT || m_partStack.back().split == CU_TRIV_SPLIT )
{
// adapt the current bt depth
//调整当前BT深度
if( currIdx == 1 ) currBtDepth--;
else currBtDepth++;
if( currIdx == 1 ) currSubdiv--;
else currSubdiv++;
}
if( currQgEnable() )
currQgPos = currArea().lumaPos();
if( currQgChromaEnable() )
currQgChromaPos = currArea().chromaPos();
#if _DEBUG
m_currArea = m_partStack.back().parts[currIdx];
#endif
return true;
}
else
{
if( autoPop ) exitCurrSplit();
return false;
}
}
currIdx:因为当前父CU有多个子CU,所以currIdx代表当前CU的idx,这里m_partStack的idx也加1。
这个会在接下来的exitCurrSplit()函数有相应设置
if语句(currIdx == 1):prevCU代表当前CU的area,这里推测应该是根据prevCU的情况来判断当前层的第一个子CU的划分情况并写入m_partStack的firstSubPartSplit。当前层为现在CU的父CU所划分的那几个CU
if语句(currIdx < m_partStack.back().parts.size() ):如果当前idx小于当前CU所属父CU所划分的CU个数,最终返回true,继续循环,测试其他子CU。如果大于或等于,则跳出循环
void QTBTPartitioner::exitCurrSplit()
{
PartSplit currSplit = m_partStack.back().split;
unsigned currIdx = m_partStack.back().idx;
//把已测试完的父CU这层去掉
m_partStack.pop_back();
CHECK( currDepth == 0, "depth is '0', although a split was performed" );
//一些深度参数做调整
currDepth--;
currSubdiv--;
if( currQgEnable() )
currQgPos = currArea().lumaPos();
if( currArea().chromaFormat != CHROMA_400 && currQgChromaEnable() )
currQgChromaPos = currArea().chromaPos();
#if _DEBUG
//当前CU的area
m_currArea = m_partStack.back().parts[m_partStack.back().idx];
#endif
if( currSplit == CU_HORZ_SPLIT || currSplit == CU_VERT_SPLIT || currSplit == CU_TRIH_SPLIT || currSplit == CU_TRIV_SPLIT )
{
CHECK( !m_partStack.back().checkdIfImplicit, "Didn't check if the current split is implicit" );
CHECK( currBtDepth == 0, "BT depth is '0', athough a BT split was performed" );
CHECK( currMtDepth == 0, "MT depth is '0', athough a BT split was performed" );
currMtDepth--;
if( m_partStack.back().isImplicit ) currImplicitBtDepth--;
currBtDepth--;
if( ( currSplit == CU_TRIH_SPLIT || currSplit == CU_TRIV_SPLIT ) && currIdx != 1 )
{
CHECK( currBtDepth == 0, "BT depth is '0', athough a TT split was performed" );
currBtDepth--;
currSubdiv--;
}
}
else if( currSplit == TU_MAX_TR_SPLIT )
{
CHECK( currTrDepth == 0, "TR depth is '0', although a TU split was performed" );
currTrDepth--;
}
else if( currSplit >= SBT_VER_HALF_POS0_SPLIT && currSplit <= SBT_HOR_QUAD_POS1_SPLIT )
{
CHECK( currTrDepth == 0, "TR depth is '0', although a TU split was performed" );
currTrDepth--;
}
else
{
CHECK( currTrDepth > 0, "RQT found with QTBT partitioner" );
CHECK( currQtDepth == 0, "QT depth is '0', although a QT split was performed" );
currQtDepth--;
currSubdiv--;
}
}
这里的currSplit为父CU的划分方式,因为子CU已经不能划分
注意:若currSplit为TT划分,currSubdiv要自减2
若currSplit等于其他如TU_MAX_TR_SPLIT,另有深度参数的调整