Commit 1090b2ce authored by Frank Bossen's avatar Frank Bossen
Browse files

Merge branch 'jvet_m0421_splitsig' into 'master'

JVET-M0421

See merge request !153
parents d6d0ef21 15342a40
Pipeline #513 passed with stage
......@@ -150,6 +150,116 @@ void CoeffCodingContext::initSubblock( int SubsetId, bool sigGroupFlag )
#if JVET_M0421_SPLIT_SIG
void DeriveCtx::CtxSplit( const CodingStructure& cs, Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, bool* _canSplit /*= nullptr */ )
{
const Position pos = partitioner.currArea().blocks[partitioner.chType];
const unsigned curSliceIdx = cs.slice->getIndependentSliceIdx();
#if HEVC_TILES_WPP
const unsigned curTileIdx = cs.picture->tileMap->getTileIdxMap( partitioner.currArea().lumaPos() );
#endif
// get left depth
#if HEVC_TILES_WPP
const CodingUnit* cuLeft = cs.getCURestricted( pos.offset( -1, 0 ), curSliceIdx, curTileIdx, partitioner.chType );
#else
const CodingUnit* cuLeft = cs.getCURestricted( pos.offset( -1, 0 ), curSliceIdx, partitioner.chType );
#endif
// get above depth
#if HEVC_TILES_WPP
const CodingUnit* cuAbove = cs.getCURestricted( pos.offset( 0, -1 ), curSliceIdx, curTileIdx, partitioner.chType );
#else
const CodingUnit* cuAbove = cs.getCURestricted( pos.offset( 0, -1 ), curSliceIdx, partitioner.chType );
#endif
bool canSplit[6];
if( _canSplit == nullptr )
{
partitioner.canSplit( cs, canSplit[0], canSplit[1], canSplit[2], canSplit[3], canSplit[4], canSplit[5] );
}
else
{
memcpy( canSplit, _canSplit, 6 * sizeof( bool ) );
}
///////////////////////
// CTX do split (0-8)
///////////////////////
const unsigned widthCurr = partitioner.currArea().blocks[partitioner.chType].width;
const unsigned heightCurr = partitioner.currArea().blocks[partitioner.chType].height;
ctxSpl = 0;
if( cuLeft )
{
const unsigned heightLeft = cuLeft->blocks[partitioner.chType].height;
ctxSpl += ( heightLeft < heightCurr ? 1 : 0 );
}
if( cuAbove )
{
const unsigned widthAbove = cuAbove->blocks[partitioner.chType].width;
ctxSpl += ( widthAbove < widthCurr ? 1 : 0 );
}
unsigned numSplit = 0;
if( canSplit[1] ) numSplit += 2;
if( canSplit[2] ) numSplit += 1;
if( canSplit[3] ) numSplit += 1;
if( canSplit[4] ) numSplit += 1;
if( canSplit[5] ) numSplit += 1;
if( numSplit > 0 ) numSplit--;
ctxSpl += 3 * ( numSplit >> 1 );
//////////////////////////
// CTX is qt split (0-5)
//////////////////////////
ctxQt = ( cuLeft && cuLeft->qtDepth > partitioner.currQtDepth ) ? 1 : 0;
ctxQt += ( cuAbove && cuAbove->qtDepth > partitioner.currQtDepth ) ? 1 : 0;
ctxQt += partitioner.currQtDepth < 2 ? 0 : 3;
////////////////////////////
// CTX is ver split (0-4)
////////////////////////////
ctxHv = 0;
const unsigned numHor = ( canSplit[2] ? 1 : 0 ) + ( canSplit[4] ? 1 : 0 );
const unsigned numVer = ( canSplit[3] ? 1 : 0 ) + ( canSplit[5] ? 1 : 0 );
if( numVer == numHor )
{
const Area& area = partitioner.currArea().blocks[partitioner.chType];
const unsigned wAbove = cuAbove ? cuAbove->blocks[partitioner.chType].width : 1;
const unsigned hLeft = cuLeft ? cuLeft ->blocks[partitioner.chType].height : 1;
const unsigned depAbove = area.width / wAbove;
const unsigned depLeft = area.height / hLeft;
if( depAbove == depLeft || !cuLeft || !cuAbove ) ctxHv = 0;
else if( depAbove < depLeft ) ctxHv = 1;
else ctxHv = 2;
}
else if( numVer < numHor )
{
ctxHv = 3;
}
else
{
ctxHv = 4;
}
//////////////////////////
// CTX is h/v bt (0-3)
//////////////////////////
ctxHorBt = ( partitioner.currBtDepth >= 2 ? 1 : 0 );
ctxVerBt = ( partitioner.currBtDepth >= 2 ? 3 : 2 );
}
#else
unsigned DeriveCtx::CtxCUsplit( const CodingStructure& cs, Partitioner& partitioner )
{
auto adPartitioner = dynamic_cast<AdaptiveDepthPartitioner*>( &partitioner );
......@@ -186,6 +296,7 @@ unsigned DeriveCtx::CtxCUsplit( const CodingStructure& cs, Partitioner& partitio
return ctxId;
}
#endif
unsigned DeriveCtx::CtxQtCbf( const ComponentID compID, const unsigned trDepth, const bool prevCbCbf )
{
......@@ -258,6 +369,7 @@ unsigned DeriveCtx::CtxIMVFlag( const CodingUnit& cu )
return ctxId;
}
#if !JVET_M0421_SPLIT_SIG
unsigned DeriveCtx::CtxBTsplit(const CodingStructure& cs, Partitioner& partitioner)
{
const Position pos = partitioner.currArea().blocks[partitioner.chType];
......@@ -306,6 +418,7 @@ unsigned DeriveCtx::CtxBTsplit(const CodingStructure& cs, Partitioner& partition
return ctx;
}
#endif
unsigned DeriveCtx::CtxTriangleFlag( const CodingUnit& cu )
{
const CodingStructure *cs = cu.cs;
......
......@@ -294,8 +294,12 @@ public:
namespace DeriveCtx
{
#if JVET_M0421_SPLIT_SIG
void CtxSplit ( const CodingStructure& cs, Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, bool* canSplit = nullptr );
#else
unsigned CtxCUsplit ( const CodingStructure& cs, Partitioner& partitioner );
unsigned CtxBTsplit ( const CodingStructure& cs, Partitioner& partitioner );
#endif
unsigned CtxQtCbf ( const ComponentID compID, const unsigned trDepth, const bool prevCbCbf );
unsigned CtxInterDir ( const PredictionUnit& pu );
unsigned CtxSkipFlag ( const CodingUnit& cu );
......
......@@ -349,6 +349,15 @@ std::vector<std::vector<uint8_t>> ContextSetCfg::sm_InitTables( NUMBER_OF_SLICE_
// clang-format off
const CtxSet ContextSetCfg::SplitFlag = ContextSetCfg::addCtxSet
({
#if JVET_M0421_SPLIT_SIG
// |-------- do split ctx -------------------|
{ 93, 124, 141, 123, 125, 141, 139, 126, 157, },
{ 108, 139, 156, 138, 140, 141, 139, 141, 143, },
{ 153, 154, 172, 153, 140, 156, 154, 127, 159, },
#if JVET_M0453_CABAC_ENGINE
{ DWS, DWS, DWS, DWS, DWS, DWS, DWS, DWS, DWS, },
#endif
#else
#if JVET_M0453_CABAC_ENGINE
{ 107, 110, 127, 106, 123, 140,},
{ 138, 140, 142, 106, 123, 125,},
......@@ -359,8 +368,40 @@ const CtxSet ContextSetCfg::SplitFlag = ContextSetCfg::addCtxSet
{ 138, 111, 143, 107, 138, 140, },
{ 138, 141, 158, 151, 124, 126, },
#endif
#endif
});
#if JVET_M0421_SPLIT_SIG
const CtxSet ContextSetCfg::SplitQtFlag = ContextSetCfg::addCtxSet
({
{ 153, 126, 142, 137, 109, 155, },
{ 153, 126, 157, 122, 138, 140, },
{ 153, 125, 127, 137, 153, 155, },
#if JVET_M0453_CABAC_ENGINE
{ DWS, DWS, DWS, DWS, DWS, DWS, },
#endif
});
const CtxSet ContextSetCfg::SplitHvFlag = ContextSetCfg::addCtxSet
({
{ 154, 168, 155, 153, 155, },
{ 154, 168, 170, 153, 170, },
{ 154, 153, 140, 153, 154, },
#if JVET_M0453_CABAC_ENGINE
{ DWS, DWS, DWS, DWS, DWS, },
#endif
});
const CtxSet ContextSetCfg::Split12Flag = ContextSetCfg::addCtxSet
({
{ 140, 154, 140, 154, },
{ 155, 169, 140, 154, },
{ 155, 154, 155, 154, },
#if JVET_M0453_CABAC_ENGINE
{ DWS, DWS, DWS, DWS, },
#endif
});
#else
const CtxSet ContextSetCfg::BTSplitFlag = ContextSetCfg::addCtxSet
({
// |-------- 1st bin, 9 ctx for luma + 3 ctx for chroma------| |--2nd bin--| |3rd bin|
......@@ -375,6 +416,7 @@ const CtxSet ContextSetCfg::BTSplitFlag = ContextSetCfg::addCtxSet
{ 139, 141, 157, 139, 155, 142, 153, 125, 141, 154, 154, 154, 154, 154, 154, 140, },
#endif
});
#endif
const CtxSet ContextSetCfg::SkipFlag = ContextSetCfg::addCtxSet
({
......
......@@ -245,7 +245,13 @@ class ContextSetCfg
public:
// context sets: specify offset and size
static const CtxSet SplitFlag;
#if JVET_M0421_SPLIT_SIG
static const CtxSet SplitQtFlag;
static const CtxSet SplitHvFlag;
static const CtxSet Split12Flag;
#else
static const CtxSet BTSplitFlag;
#endif
static const CtxSet SkipFlag;
static const CtxSet MergeFlag;
static const CtxSet MergeIdx;
......
......@@ -50,6 +50,8 @@
#include <assert.h>
#include <cassert>
#define JVET_M0421_SPLIT_SIG 1
#define REMOVE_BIN_DECISION_TREE 1
// clang-format off
......
......@@ -297,8 +297,97 @@ void QTBTPartitioner::splitCurrArea( const PartSplit split, const CodingStructur
}
}
#if JVET_M0421_SPLIT_SIG
void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& canQt, bool& canBh, bool& canBv, bool& canTh, bool& canTv )
{
const PartSplit implicitSplit = m_partStack.back().checkdIfImplicit ? m_partStack.back().implicitSplit : getImplicitSplit( cs );
const unsigned maxBTD = cs.pcv->getMaxBtDepth( *cs.slice, chType ) + currImplicitBtDepth;
const unsigned maxBtSize = cs.pcv->getMaxBtSize ( *cs.slice, chType );
const unsigned minBtSize = cs.pcv->getMinBtSize ( *cs.slice, chType );
const unsigned maxTtSize = cs.pcv->getMaxTtSize ( *cs.slice, chType );
const unsigned minTtSize = cs.pcv->getMinTtSize ( *cs.slice, chType );
const unsigned minQtSize = cs.pcv->getMinQtSize ( *cs.slice, chType );
canNo = canQt = canBh = canTh = canBv = canTv = true;
bool canBtt = currMtDepth < maxBTD;
// the minimal and maximal sizes are given in luma samples
const CompArea& area = currArea().Y();
PartLevel& level = m_partStack.back();
const PartSplit lastSplit = level.split;
const PartSplit parlSplit = lastSplit == CU_TRIH_SPLIT ? CU_HORZ_SPLIT : CU_VERT_SPLIT;
// don't allow QT-splitting below a BT split
if( lastSplit != CTU_LEVEL && lastSplit != CU_QUAD_SPLIT ) canQt = false;
if( area.width <= minQtSize ) canQt = false;
if( implicitSplit != CU_DONT_SPLIT )
{
canNo = canTh = canTv = false;
canBh = implicitSplit == CU_HORZ_SPLIT;
canBv = implicitSplit == CU_VERT_SPLIT;
return;
}
if( ( lastSplit == CU_TRIH_SPLIT || lastSplit == CU_TRIV_SPLIT ) && currPartIdx() == 1 )
{
canBh = parlSplit != CU_HORZ_SPLIT;
canBv = parlSplit != CU_VERT_SPLIT;
}
if( canBtt && ( area.width <= minBtSize && area.height <= minBtSize )
&& ( ( area.width <= minTtSize && area.height <= minTtSize )
|| cs.sps->getSpsNext().getMTTMode() == 0 ) )
{
canBtt = false;
}
if( canBtt && ( area.width > maxBtSize || area.height > maxBtSize )
&& ( ( area.width > maxTtSize || area.height > maxTtSize )
|| cs.sps->getSpsNext().getMTTMode() == 0 ) )
{
canBtt = false;
}
if( !canBtt )
{
canBh = canTh = canBv = canTv = false;
return;
}
// specific check for BT splits
if( area.height <= minBtSize || area.height > maxBtSize ) canBh = false;
if( area.width > MAX_TU_SIZE_FOR_PROFILE && area.height <= MAX_TU_SIZE_FOR_PROFILE ) canBh = false;
if( area.width <= minBtSize || area.width > maxBtSize ) canBv = false;
if( area.width <= MAX_TU_SIZE_FOR_PROFILE && area.height > MAX_TU_SIZE_FOR_PROFILE ) canBv = false;
if( ( cs.sps->getSpsNext().getMTTMode() & 1 ) != 1 ) canTh = false;
if( area.height <= 2 * minTtSize || area.height > maxTtSize || area.width > maxTtSize )
canTh = false;
if( area.width > MAX_TU_SIZE_FOR_PROFILE || area.height > MAX_TU_SIZE_FOR_PROFILE ) canTh = false;
if( ( cs.sps->getSpsNext().getMTTMode() & 1 ) != 1 ) canTv = false;
if( area.width <= 2 * minTtSize || area.width > maxTtSize || area.height > maxTtSize )
canTv = false;
if( area.width > MAX_TU_SIZE_FOR_PROFILE || area.height > MAX_TU_SIZE_FOR_PROFILE ) canTv = false;
}
#endif
bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs )
{
#if JVET_M0421_SPLIT_SIG
const CompArea area = currArea().Y();
const unsigned maxTrSize = cs.sps->getMaxTrSize();
bool canNo, canQt, canBh, canTh, canBv, canTv;
canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
#else
const PartSplit implicitSplit = getImplicitSplit( cs );
// the minimal and maximal sizes are given in luma samples
......@@ -319,6 +408,7 @@ bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs
return false;
}
#endif
switch( split )
{
case CTU_LEVEL:
......@@ -328,6 +418,20 @@ bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs
case TU_MAX_TR_SPLIT:
return area.width > maxTrSize || area.height > maxTrSize;
break;
#if JVET_M0421_SPLIT_SIG
case CU_QUAD_SPLIT:
return canQt;
case CU_DONT_SPLIT:
return canNo;
case CU_HORZ_SPLIT:
return canBh;
case CU_VERT_SPLIT:
return canBv;
case CU_TRIH_SPLIT:
return canTh;
case CU_TRIV_SPLIT:
return canTv;
#else
case CU_QUAD_SPLIT:
{
// don't allow QT-splitting below a BT split
......@@ -369,8 +473,15 @@ bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs
}
if( implicitSplit == split ) return true;
if( implicitSplit != CU_DONT_SPLIT && implicitSplit != split ) return false;
#endif
case CU_MT_SPLIT:
#if JVET_M0421_SPLIT_SIG
return ( canBh || canTh || canBv || canTv );
#endif
case CU_BT_SPLIT:
#if JVET_M0421_SPLIT_SIG
return ( canBh || canBv );
#else
{
if( currMtDepth >= maxBTD ) return false;
if( ( area.width <= minBtSize && area.height <= minBtSize )
......@@ -382,13 +493,14 @@ bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs
return false;
}
}
#endif
break;
default:
THROW( "Unknown split mode" );
return false;
break;
}
#if !JVET_M0421_SPLIT_SIG
// specific check for BT splits
switch( split )
{
......@@ -413,6 +525,7 @@ bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs
default:
break;
}
#endif
return true;
}
......
......@@ -128,6 +128,9 @@ public:
virtual void copyState ( const Partitioner& other );
public:
#if JVET_M0421_SPLIT_SIG
virtual void canSplit ( const CodingStructure &cs, bool& canNo, bool& canQt, bool& canBh, bool& canBv, bool& canTh, bool& canTv ) = 0;
#endif
virtual bool canSplit ( const PartSplit split, const CodingStructure &cs ) = 0;
virtual bool isSplitImplicit ( const PartSplit split, const CodingStructure &cs ) = 0;
virtual PartSplit getImplicitSplit ( const CodingStructure &cs ) = 0;
......@@ -147,7 +150,10 @@ public:
void exitCurrSplit ();
bool nextPart ( const CodingStructure &cs, bool autoPop = false );
bool hasNextPart ();
#if JVET_M0421_SPLIT_SIG
void canSplit ( const CodingStructure &cs, bool& canNo, bool& canQt, bool& canBh, bool& canBv, bool& canTh, bool& canTv );
#endif
bool canSplit ( const PartSplit split, const CodingStructure &cs );
bool isSplitImplicit ( const PartSplit split, const CodingStructure &cs );
PartSplit getImplicitSplit ( const CodingStructure &cs );
......
......@@ -421,6 +421,14 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
}
}
#if JVET_M0421_SPLIT_SIG
const PartSplit splitMode = split_cu_mode( cs, partitioner );
CHECK( !partitioner.canSplit( splitMode, cs ), "Got an invalid split!" );
if( splitMode != CU_DONT_SPLIT )
{
#else
const PartSplit implicitSplit = partitioner.getImplicitSplit( cs );
// QT
......@@ -440,6 +448,7 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
// quad-tree split
if( qtSplit )
{
#endif
if (CS::isDualITree(cs) && pPartitionerChroma != nullptr && (partitioner.currArea().lwidth() >= 64 || partitioner.currArea().lheight() >= 64))
{
partitioner.splitCurrArea(CU_QUAD_SPLIT, cs);
......@@ -519,7 +528,11 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
}
else
{
#if JVET_M0421_SPLIT_SIG
partitioner.splitCurrArea( splitMode, cs );
#else
partitioner.splitCurrArea( CU_QUAD_SPLIT, cs );
#endif
do
{
if( !lastSegment && cs.area.blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) )
......@@ -531,9 +544,12 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
partitioner.exitCurrSplit();
}
return lastSegment;
#if !JVET_M0421_SPLIT_SIG
}
#endif
}
#if !JVET_M0421_SPLIT_SIG
{
// MT
bool mtSplit = partitioner.canSplit( CU_MT_SPLIT, cs );
......@@ -560,7 +576,7 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
}
}
#endif
CodingUnit& cu = cs.addCU( CS::getArea( cs, currArea, partitioner.chType ), partitioner.chType );
partitioner.setCUData( cu );
......@@ -595,6 +611,76 @@ bool CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
return isLastCtu;
}
#if JVET_M0421_SPLIT_SIG
PartSplit CABACReader::split_cu_mode( CodingStructure& cs, Partitioner &partitioner )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET_SIZE2( STATS__CABAC_BITS__SPLIT_FLAG, partitioner.currArea().blocks[partitioner.chType].size(), partitioner.chType );
PartSplit mode = CU_DONT_SPLIT;
bool canNo, canQt, canBh, canBv, canTh, canTv;
partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
bool canSpl[6] = { canNo, canQt, canBh, canBv, canTh, canTv };
unsigned ctxSplit = 0, ctxQtSplit = 0, ctxBttHV = 0, ctxBttH12 = 0, ctxBttV12;
DeriveCtx::CtxSplit( cs, partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl );
bool isSplit = canBh || canBv || canTh || canTv || canQt;
if( canNo && isSplit )
{
isSplit = m_BinDecoder.decodeBin( Ctx::SplitFlag( ctxSplit ) );
}
DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d split=%d\n", ctxSplit, isSplit );
if( !isSplit )
{
return CU_DONT_SPLIT;
}
const bool canBtt = canBh || canBv || canTh || canTv;
bool isQt = canQt;
if( isQt && canBtt )
{
isQt = m_BinDecoder.decodeBin( Ctx::SplitQtFlag( ctxQtSplit ) );
}
DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d qt=%d\n", ctxQtSplit, isQt );
if( isQt )
{
return CU_QUAD_SPLIT;
}
const bool canHor = canBh || canTh;
bool isVer = canBv || canTv;
if( isVer && canHor )
{
isVer = m_BinDecoder.decodeBin( Ctx::SplitHvFlag( ctxBttHV ) );
}
const bool can14 = isVer ? canTv : canTh;
bool is12 = isVer ? canBv : canBh;
if( is12 && can14 )
{
is12 = m_BinDecoder.decodeBin( Ctx::Split12Flag( isVer ? ctxBttV12 : ctxBttH12 ) );
}
if ( isVer && is12 ) mode = CU_VERT_SPLIT;
else if( isVer && !is12 ) mode = CU_TRIV_SPLIT;
else if( !isVer && is12 ) mode = CU_HORZ_SPLIT;
else mode = CU_TRIH_SPLIT;
DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctxHv=%d ctx12=%d mode=%d\n", ctxBttHV, isVer ? ctxBttV12 : ctxBttH12, mode );
return mode;
}
#else
PartSplit CABACReader::split_cu_mode_mt( CodingStructure& cs, Partitioner &partitioner )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__SPLIT_FLAG );
......@@ -694,6 +780,7 @@ bool CABACReader::split_cu_flag( CodingStructure& cs, Partitioner &partitioner )
return split;
}
#endif
//================================================================================
// clause 7.3.8.5
......
......@@ -70,8 +70,12 @@ public:
// coding (quad)tree (clause 7.3.8.4)
bool coding_tree ( CodingStructure& cs, Partitioner& pm, CUCtx& cuCtx, Partitioner* pPartitionerChroma = nullptr, CUCtx* pCuCtxChroma = nullptr);
#if JVET_M0421_SPLIT_SIG
PartSplit split_cu_mode ( CodingStructure& cs, Partitioner& pm );
#else
bool split_cu_flag ( CodingStructure& cs, Partitioner& pm );
PartSplit split_cu_mode_mt ( CodingStructure& cs, Partitioner& pm );
#endif
// coding unit (clause 7.3.8.5)
bool coding_unit ( CodingUnit& cu, Partitioner& pm, CUCtx& cuCtx );
......
......@@ -396,6 +396,16 @@ void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitione
}
}
#if JVET_M0421_SPLIT_SIG
const PartSplit splitMode = CU::getSplitAtDepth( cu, partitioner.currDepth );
split_cu_mode( splitMode, cs, partitioner );
CHECK( !partitioner.canSplit( splitMode, cs ), "The chosen split mode is invalid!" );