Newer
Older

Karsten Suehring
committed
{
if( !cu.Y().valid() )
{
return;
}
Weijia
committed
#if JVET_O0315_RDPCM_INTRAMODE_ALIGN
cu.firstPU->intraDir[0] = cu.bdpcmMode == 2? VER_IDX : HOR_IDX;
#else
PredictionUnit *pu = cu.firstPU;
unsigned mpm_pred[NUM_MOST_PROBABLE_MODES];
PU::getIntraMPMs( *pu, mpm_pred );
cu.firstPU->intraDir[0] = mpm_pred[0];
Weijia
committed
#endif
mip_flag(cu);
if (cu.mipFlag)
{
mip_pred_modes(cu);
return;
}
extend_ref_line( cu );
isp_mode( cu );
const int numMPMs = NUM_MOST_PROBABLE_MODES;
const int numBlocks = CU::getNumPUs( cu );
unsigned mpm_preds [4][numMPMs];
unsigned mpm_idxs [4];
unsigned ipred_modes [4];

Karsten Suehring
committed
const PredictionUnit* pu = cu.firstPU;
// prev_intra_luma_pred_flag
for( int k = 0; k < numBlocks; k++ )
{
unsigned* mpm_pred = mpm_preds[k];

Karsten Suehring
committed
unsigned& mpm_idx = mpm_idxs[k];
unsigned& ipred_mode = ipred_modes[k];
PU::getIntraMPMs( *pu, mpm_pred );
ipred_mode = pu->intraDir[0];
mpm_idx = numMPMs;
for( unsigned idx = 0; idx < numMPMs; idx++ )
{
if( ipred_mode == mpm_pred[idx] )
{
mpm_idx = idx;
break;
}
}
if( pu->multiRefIdx || ( cu.ispMode && isLuma( cu.chType ) ) )
{
CHECK(mpm_idx >= numMPMs, "use of non-MPM");
}
else
{
m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
}

Karsten Suehring
committed
pu = pu->next;
}
pu = cu.firstPU;
// mpm_idx / rem_intra_luma_pred_mode
for( int k = 0; k < numBlocks; k++ )
{
const unsigned& mpm_idx = mpm_idxs[k];
if( mpm_idx < numMPMs )
{
{
unsigned ctx = (pu->cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
if (pu->multiRefIdx == 0)
m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx));

Karsten Suehring
committed
if( mpm_idx )
{
m_BinEncoder.encodeBinEP( mpm_idx > 1 );
}
if (mpm_idx > 1)
{
m_BinEncoder.encodeBinEP(mpm_idx > 2);
}
if (mpm_idx > 2)
{
m_BinEncoder.encodeBinEP(mpm_idx > 3);
}
if (mpm_idx > 3)
{
m_BinEncoder.encodeBinEP(mpm_idx > 4);
}

Karsten Suehring
committed
}
}
else
{
unsigned* mpm_pred = mpm_preds[k];
unsigned ipred_mode = ipred_modes[k];
// sorting of MPMs
std::sort( mpm_pred, mpm_pred + numMPMs );
{
for (int idx = numMPMs - 1; idx >= 0; idx--)

Karsten Suehring
committed
{
if (ipred_mode > mpm_pred[idx])
{
ipred_mode--;
}
}
CHECK(ipred_mode >= 64, "Incorrect mode");
xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES); // Remaining mode is truncated binary coded

Karsten Suehring
committed
}
}
DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) mode=%d\n", k, pu->lumaPos().x, pu->lumaPos().y, pu->intraDir[0] );
pu = pu->next;
}
}
void CABACWriter::intra_luma_pred_mode( const PredictionUnit& pu )
{
mip_flag(*pu.cu);
if (pu.cu->mipFlag)
{
mip_pred_mode(pu);
return;
}
extend_ref_line( pu );
isp_mode( *pu.cu );

Karsten Suehring
committed
// prev_intra_luma_pred_flag
const int numMPMs = NUM_MOST_PROBABLE_MODES;
unsigned mpm_pred[numMPMs];

Karsten Suehring
committed
PU::getIntraMPMs( pu, mpm_pred );
unsigned ipred_mode = pu.intraDir[0];
unsigned mpm_idx = numMPMs;
for( int idx = 0; idx < numMPMs; idx++ )

Karsten Suehring
committed
{
if( ipred_mode == mpm_pred[idx] )
{
mpm_idx = idx;
break;
}
}
if( pu.multiRefIdx || ( pu.cu->ispMode && isLuma( pu.cu->chType ) ) )
{
CHECK(mpm_idx >= numMPMs, "use of non-MPM");
}
else
{
m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
}

Karsten Suehring
committed
// mpm_idx / rem_intra_luma_pred_mode
if( mpm_idx < numMPMs )
{
{
unsigned ctx = (pu.cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
if (pu.multiRefIdx == 0)
m_BinEncoder.encodeBin( mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx) );

Karsten Suehring
committed
if( mpm_idx )
{
m_BinEncoder.encodeBinEP( mpm_idx > 1 );
}
if (mpm_idx > 1)
{
m_BinEncoder.encodeBinEP(mpm_idx > 2);
}
if (mpm_idx > 2)
{
m_BinEncoder.encodeBinEP(mpm_idx > 3);
}
if (mpm_idx > 3)
{
m_BinEncoder.encodeBinEP(mpm_idx > 4);
}

Karsten Suehring
committed
}
}
else
{
std::sort( mpm_pred, mpm_pred + numMPMs );
{
for (int idx = numMPMs - 1; idx >= 0; idx--)

Karsten Suehring
committed
{
if (ipred_mode > mpm_pred[idx])
{
ipred_mode--;
}
}
xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES); // Remaining mode is truncated binary coded

Karsten Suehring
committed
}
}
}
void CABACWriter::intra_chroma_pred_modes( const CodingUnit& cu )
{
if( cu.chromaFormat == CHROMA_400 || ( CS::isDualITree( *cu.cs ) && cu.chType == CHANNEL_TYPE_LUMA ) )
{
return;
}
const PredictionUnit* pu = cu.firstPU;
intra_chroma_pred_mode( *pu );
}
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
#if JVET_O1153_INTRA_CHROMAMODE_CODING
void CABACWriter::intra_chroma_lmc_mode(const PredictionUnit& pu)
{
const unsigned intraDir = pu.intraDir[1];
int lmModeList[10];
PU::getLMSymbolList(pu, lmModeList);
int symbol = -1;
for (int k = 0; k < LM_SYMBOL_NUM; k++)
{
if (lmModeList[k] == intraDir)
{
symbol = k;
break;
}
}
CHECK(symbol < 0, "invalid symbol found");
m_BinEncoder.encodeBin(symbol == 0 ? 0 : 1, Ctx::IntraChromaPredMode(0));
if (symbol > 0)
{
CHECK(symbol > 2, "invalid symbol for MMLM");
unsigned int symbol_minus_1 = symbol - 1;
m_BinEncoder.encodeBinEP(symbol_minus_1);
}
}
void CABACWriter::intra_chroma_pred_mode(const PredictionUnit& pu)
{
const unsigned intraDir = pu.intraDir[1];
#if JVET_O1124_ALLOW_CCLM_COND
if (pu.cs->sps->getUseLMChroma() && pu.cu->checkCCLMAllowed())
#else
if (pu.cs->sps->getUseLMChroma())
#endif
{
m_BinEncoder.encodeBin(PU::isLMCMode(intraDir) ? 1 : 0, Ctx::CclmModeFlag(0));
if (PU::isLMCMode(intraDir))
{
intra_chroma_lmc_mode(pu);
return;
}
}
const bool isDerivedMode = intraDir == DM_CHROMA_IDX;
m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
if (isDerivedMode)
{
return;
}
// chroma candidate index
unsigned chromaCandModes[NUM_CHROMA_MODE];
PU::getIntraChromaCandModes(pu, chromaCandModes);

Karsten Suehring
committed
int candId = 0;
for (; candId < NUM_CHROMA_MODE; candId++)
{
if (intraDir == chromaCandModes[candId])
{
break;
}
}
CHECK(candId >= NUM_CHROMA_MODE, "Chroma prediction mode index out of bounds");
CHECK(chromaCandModes[candId] == DM_CHROMA_IDX, "The intra dir cannot be DM_CHROMA for this path");
{
m_BinEncoder.encodeBinsEP(candId, 2);
}
}
#else

Karsten Suehring
committed
void CABACWriter::intra_chroma_lmc_mode( const PredictionUnit& pu )
{
const unsigned intraDir = pu.intraDir[1];
int lmModeList[10];
int maxSymbol = PU::getLMSymbolList( pu, lmModeList );
int symbol = -1;
for ( int k = 0; k < LM_SYMBOL_NUM; k++ )
{
if ( lmModeList[k] == intraDir || ( lmModeList[k] == -1 && intraDir < LM_CHROMA_IDX ) )
{
symbol = k;
break;
}
}
CHECK( symbol < 0, "invalid symbol found" );
unary_max_symbol(symbol, Ctx::IntraChromaPredMode(1), Ctx::IntraChromaPredMode(2), maxSymbol - 1);

Karsten Suehring
committed
}
void CABACWriter::intra_chroma_pred_mode( const PredictionUnit& pu )
{
const unsigned intraDir = pu.intraDir[1];
const bool isDerivedMode = intraDir == DM_CHROMA_IDX;
m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
if (isDerivedMode)

Karsten Suehring
committed
{

Karsten Suehring
committed
}
// LM chroma mode
Yin Zhao
committed
#if JVET_O1124_ALLOW_CCLM_COND
if( pu.cs->sps->getUseLMChroma() && pu.cu->checkCCLMAllowed() )
#else
if( pu.cs->sps->getUseLMChroma() )
Yin Zhao
committed
#endif

Karsten Suehring
committed
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
{
intra_chroma_lmc_mode( pu );
if ( PU::isLMCMode( intraDir ) )
{
return;
}
}
// chroma candidate index
unsigned chromaCandModes[ NUM_CHROMA_MODE ];
PU::getIntraChromaCandModes( pu, chromaCandModes );
int candId = 0;
for ( ; candId < NUM_CHROMA_MODE; candId++ )
{
if( intraDir == chromaCandModes[ candId ] )
{
break;
}
}
CHECK( candId >= NUM_CHROMA_MODE, "Chroma prediction mode index out of bounds" );
CHECK( chromaCandModes[ candId ] == DM_CHROMA_IDX, "The intra dir cannot be DM_CHROMA for this path" );
{
m_BinEncoder.encodeBinsEP( candId, 2 );
}
}

Karsten Suehring
committed
void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx )
{

Karsten Suehring
committed
{
PredictionUnit& pu = *cu.firstPU;

Karsten Suehring
committed
{
rqt_root_cbf( cu );
}
if( cu.rootCbf )
{
sbt_mode( cu );
}

Karsten Suehring
committed
if( !cu.rootCbf )
{
return;
}
}
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] = false;
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;
#endif
#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
cuCtx.lastScanPos[COMPONENT_Y ] = -1;
cuCtx.lastScanPos[COMPONENT_Cb] = -1;
cuCtx.lastScanPos[COMPONENT_Cr] = -1;
#endif

Karsten Suehring
committed
#if !JVET_O0596_CBF_SIG_ALIGN_TO_SPEC

Karsten Suehring
committed
ChromaCbfs chromaCbfs;
#endif
if( cu.ispMode && isLuma( partitioner.chType ) )
{
TUIntraSubPartitioner subTuPartitioner( partitioner );
#if JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
transform_tree( *cu.cs, subTuPartitioner, cuCtx, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType) ), 0 );
#else
transform_tree( *cu.cs, subTuPartitioner, cuCtx, chromaCbfs, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType ) ), 0 );
#endif
}
else
{
#if JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
transform_tree( *cu.cs, partitioner, cuCtx );
#else
transform_tree( *cu.cs, partitioner, cuCtx, chromaCbfs );
#endif
residual_lfnst_mode( cu, cuCtx );

Karsten Suehring
committed
}
void CABACWriter::rqt_root_cbf( const CodingUnit& cu )
{
m_BinEncoder.encodeBin( cu.rootCbf, Ctx::QtRootCbf() );
DTRACE( g_trace_ctx, D_SYNTAX, "rqt_root_cbf() ctx=0 root_cbf=%d pos=(%d,%d)\n", cu.rootCbf ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y );
}
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
void CABACWriter::sbt_mode( const CodingUnit& cu )
{
uint8_t sbtAllowed = cu.checkAllowedSbt();
if( !sbtAllowed )
{
return;
}
SizeType cuWidth = cu.lwidth();
SizeType cuHeight = cu.lheight();
uint8_t sbtIdx = cu.getSbtIdx();
uint8_t sbtPos = cu.getSbtPos();
//bin - flag
bool sbtFlag = cu.sbtInfo != 0;
uint8_t ctxIdx = ( cuWidth * cuHeight <= 256 ) ? 1 : 0;
m_BinEncoder.encodeBin( sbtFlag, Ctx::SbtFlag( ctxIdx ) );
if( !sbtFlag )
{
return;
}
bool sbtQuadFlag = sbtIdx == SBT_HOR_QUAD || sbtIdx == SBT_VER_QUAD;
bool sbtHorFlag = sbtIdx == SBT_HOR_HALF || sbtIdx == SBT_HOR_QUAD;
bool sbtPosFlag = sbtPos == SBT_POS1;
uint8_t sbtVerHalfAllow = CU::targetSbtAllowed( SBT_VER_HALF, sbtAllowed );
uint8_t sbtHorHalfAllow = CU::targetSbtAllowed( SBT_HOR_HALF, sbtAllowed );
uint8_t sbtVerQuadAllow = CU::targetSbtAllowed( SBT_VER_QUAD, sbtAllowed );
uint8_t sbtHorQuadAllow = CU::targetSbtAllowed( SBT_HOR_QUAD, sbtAllowed );
//bin - type
if( ( sbtHorHalfAllow || sbtVerHalfAllow ) && ( sbtHorQuadAllow || sbtVerQuadAllow ) )
{
m_BinEncoder.encodeBin( sbtQuadFlag, Ctx::SbtQuadFlag( 0 ) );
}
else
{
assert( sbtQuadFlag == 0 );
}
//bin - dir
if( ( sbtQuadFlag && sbtVerQuadAllow && sbtHorQuadAllow ) || ( !sbtQuadFlag && sbtVerHalfAllow && sbtHorHalfAllow ) ) //both direction allowed
{
uint8_t ctxIdx = ( cuWidth == cuHeight ) ? 0 : ( cuWidth < cuHeight ? 1 : 2 );
m_BinEncoder.encodeBin( sbtHorFlag, Ctx::SbtHorFlag( ctxIdx ) );
}
else
{
assert( sbtHorFlag == ( ( sbtQuadFlag && sbtHorQuadAllow ) || ( !sbtQuadFlag && sbtHorHalfAllow ) ) );
}
//bin - pos
m_BinEncoder.encodeBin( sbtPosFlag, Ctx::SbtPosFlag( 0 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "sbt_mode() pos=(%d,%d) sbtInfo=%d\n", cu.lx(), cu.ly(), (int)cu.sbtInfo );
}

Karsten Suehring
committed
void CABACWriter::end_of_ctu( const CodingUnit& cu, CUCtx& cuCtx )
{
const Slice* slice = cu.cs->slice;
const int currentCTUTsAddr = cu.cs->picture->brickMap->getCtuRsToBsAddrMap( CU::getCtuAddr( cu ) );

Karsten Suehring
committed
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
const bool isLastSubCUOfCtu = CU::isLastSubCUOfCtu( cu );
if ( isLastSubCUOfCtu
&& ( !CS::isDualITree( *cu.cs ) || cu.chromaFormat == CHROMA_400 || isChroma( cu.chType ) )
)
{
cuCtx.isDQPCoded = ( cu.cs->pps->getUseDQP() && !cuCtx.isDQPCoded );
// The 1-terminating bit is added to all streams, so don't add it here when it's 1.
// i.e. when the slice segment CurEnd CTU address is the current CTU address+1.
if(slice->getSliceCurEndCtuTsAddr() != currentCTUTsAddr + 1)
{
m_BinEncoder.encodeBinTrm( 0 );
}
}
}
//================================================================================
// clause 7.3.8.6
//--------------------------------------------------------------------------------
// void prediction_unit ( pu );
// void merge_flag ( pu );
// void merge_idx ( pu );
// void inter_pred_idc ( pu );
// void ref_idx ( pu, refList );
// void mvp_flag ( pu, refList );
//================================================================================
void CABACWriter::prediction_unit( const PredictionUnit& pu )
{
#if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
CHECK( pu.cacheUsed, "Processing a PU that should be in cache!" );
CHECK( pu.cu->cacheUsed, "Processing a CU that should be in cache!" );
#endif
if( pu.cu->skip )
{
CHECK( !pu.mergeFlag, "merge_flag must be true for skipped CUs" );
}
else
{
merge_flag( pu );
}
if( pu.mergeFlag )
{
#if JVET_O0249_MERGE_SYNTAX
merge_data(pu);
#else
if (CU::isIBC(*pu.cu))
{
merge_idx(pu);
return;
}
subblock_merge_flag( *pu.cu );
MHIntra_flag( pu );
if (!pu.mhIntraFlag)
{
if (!pu.cu->affine && !pu.mmvdMergeFlag && !pu.cu->mmvdSkip)
{
CHECK(!pu.cu->triangle, "triangle_flag must be true");
}
}
if (pu.mmvdMergeFlag)
{
mmvd_merge_idx(pu);
}
else
merge_idx ( pu );

Karsten Suehring
committed
}
else if (CU::isIBC(*pu.cu))
{
ref_idx(pu, REF_PIC_LIST_0);
Mv mvd = pu.mvd[REF_PIC_LIST_0];
mvd.changeIbcPrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision
#if JVET_O0162_IBC_MVP_FLAG
if ( pu.cu->slice->getMaxNumMergeCand() == 1 )
{
CHECK( pu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" );
}
else
#endif

Karsten Suehring
committed
else
{
inter_pred_idc( pu );
affine_flag ( *pu.cu );

Karsten Suehring
committed
if( pu.interDir != 2 /* PRED_L1 */ )
{
ref_idx ( pu, REF_PIC_LIST_0 );
if ( pu.cu->affine )
{
Mv mvd = pu.mvdAffi[REF_PIC_LIST_0][0];
mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision
mvd = pu.mvdAffi[REF_PIC_LIST_0][1];
mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision
if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
{
mvd = pu.mvdAffi[REF_PIC_LIST_0][2];
mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision

Karsten Suehring
committed
}
else
{
Mv mvd = pu.mvd[REF_PIC_LIST_0];
mvd.changeTransPrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision

Karsten Suehring
committed
}
mvp_flag ( pu, REF_PIC_LIST_0 );
}
if( pu.interDir != 1 /* PRED_L0 */ )
{

Karsten Suehring
committed
ref_idx ( pu, REF_PIC_LIST_1 );
if( !pu.cs->slice->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
{
if ( pu.cu->affine )
{
Mv mvd = pu.mvdAffi[REF_PIC_LIST_1][0];
mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision
mvd = pu.mvdAffi[REF_PIC_LIST_1][1];
mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision
if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
{
mvd = pu.mvdAffi[REF_PIC_LIST_1][2];
mvd.changeAffinePrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision

Karsten Suehring
committed
}
else
{
Mv mvd = pu.mvd[REF_PIC_LIST_1];
mvd.changeTransPrecInternal2Amvr(pu.cu->imv);
mvd_coding(mvd, 0); // already changed to signaling precision

Karsten Suehring
committed
}
}

Karsten Suehring
committed
mvp_flag ( pu, REF_PIC_LIST_1 );
}
}
}
void CABACWriter::smvd_mode( const PredictionUnit& pu )
{
if ( pu.interDir != 3 || pu.cu->affine )
{
return;
}
if ( pu.cs->slice->getBiDirPred() == false )
{
return;
}
m_BinEncoder.encodeBin( pu.cu->smvdMode ? 1 : 0, Ctx::SmvdFlag() );
DTRACE( g_trace_ctx, D_SYNTAX, "symmvd_flag() symmvd=%d pos=(%d,%d) size=%dx%d\n", pu.cu->smvdMode ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height );
}
void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
{
#if !JVET_O0249_MERGE_SYNTAX
if ( cu.firstPU->mergeFlag && (cu.firstPU->mmvdMergeFlag || cu.mmvdSkip) )
{
return;
}
Ruoyang Yu
committed
#if JVET_O0220_METHOD1_SUBBLK_FLAG_PARSING
if ( !cu.cs->slice->isIntra() && (cu.slice->getMaxNumAffineMergeCand() > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
#else
if ( !cu.cs->slice->isIntra() && (cu.cs->sps->getUseAffine() || cu.cs->sps->getSBTMVPEnabledFlag()) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
Ruoyang Yu
committed
#endif
{
unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
Tangi Poirier
committed
#if JVET_O0500_SEP_CTX_AFFINE_SUBBLOCK_MRG
m_BinEncoder.encodeBin( cu.affine, Ctx::SubblockMergeFlag( ctxId ) );
#else
m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) );
Tangi Poirier
committed
#endif
DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
}
}

Karsten Suehring
committed
void CABACWriter::affine_flag( const CodingUnit& cu )
{
if ( !cu.cs->slice->isIntra() && cu.cs->sps->getUseAffine() && cu.lumaSize().width > 8 && cu.lumaSize().height > 8 )
{
unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_flag() affine=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
if ( cu.affine && cu.cs->sps->getUseAffineType() )
{
unsigned ctxId = 0;
m_BinEncoder.encodeBin( cu.affineType, Ctx::AffineType( ctxId ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_type() affine_type=%d ctx=%d pos=(%d,%d)\n", cu.affineType ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
}
}

Karsten Suehring
committed
}
void CABACWriter::merge_flag( const PredictionUnit& pu )
{
m_BinEncoder.encodeBin( pu.mergeFlag, Ctx::MergeFlag() );
DTRACE( g_trace_ctx, D_SYNTAX, "merge_flag() merge=%d pos=(%d,%d) size=%dx%d\n", pu.mergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height );
#if !JVET_O0249_MERGE_SYNTAX
if (pu.mergeFlag && CU::isIBC(*pu.cu))
{
return;
}
if (!pu.cs->sps->getUseMMVD() && (pu.lwidth() * pu.lheight() == 32))
{
CHECK(!pu.regularMergeFlag, "regular_merge_flag must be true!");
}
else
{
m_BinEncoder.encodeBin(pu.regularMergeFlag, Ctx::RegularMergeFlag(1));
DTRACE(g_trace_ctx, D_SYNTAX, "regularMergeFlag() ctx=%d regularMergeFlag=%d\n", 1, pu.regularMergeFlag?1:0);
}
if (pu.cs->sps->getUseMMVD())
{
bool isCUWithOnlyRegularAndMMVD=((pu.lwidth() == 8 && pu.lheight() == 4) || (pu.lwidth() == 4 && pu.lheight() == 8));
if (isCUWithOnlyRegularAndMMVD)
{
CHECK(pu.mmvdMergeFlag==pu.regularMergeFlag, "mmvdMergeFlag must be !regularMergeFlag");
}
else if (!pu.regularMergeFlag)
{
m_BinEncoder.encodeBin(pu.mmvdMergeFlag, Ctx::MmvdFlag(0));
DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", pu.mmvdMergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height);
}

Karsten Suehring
committed
}
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
#if JVET_O0249_MERGE_SYNTAX
void CABACWriter::merge_data(const PredictionUnit& pu)
{
if (CU::isIBC(*pu.cu))
{
merge_idx(pu);
return;
}
subblock_merge_flag(*pu.cu);
if (pu.cu->affine)
{
merge_idx(pu);
return;
}
const bool triangleAvailable = pu.cu->cs->slice->getSPS()->getUseTriangle() && pu.cu->cs->slice->isInterB();
const bool ciipAvailable = pu.cs->sps->getUseMHIntra() && !pu.cu->skip && pu.cu->lwidth() < MAX_CU_SIZE && pu.cu->lheight() < MAX_CU_SIZE;
if (pu.cu->lwidth() * pu.cu->lheight() >= 64
&& (triangleAvailable || ciipAvailable))
{
m_BinEncoder.encodeBin(pu.regularMergeFlag, Ctx::RegularMergeFlag(pu.cu->skip ? 0 : 1));
}
if (pu.regularMergeFlag)
{
if (pu.cs->sps->getUseMMVD())
{
m_BinEncoder.encodeBin(pu.mmvdMergeFlag, Ctx::MmvdFlag(0));
DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", pu.mmvdMergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height);
}
if (pu.mmvdMergeFlag || pu.cu->mmvdSkip)
{
mmvd_merge_idx(pu);
}
else
{
merge_idx(pu);
}
}
else
{
if (triangleAvailable && ciipAvailable)
{
MHIntra_flag(pu);
}
merge_idx(pu);
}

Karsten Suehring
committed
}

Karsten Suehring
committed
void CABACWriter::imv_mode( const CodingUnit& cu )
{

Karsten Suehring
committed
if( !sps->getAMVREnabledFlag() )

Karsten Suehring
committed
{
return;
}
if ( cu.affine )
{
return;
}

Karsten Suehring
committed
bool bNonZeroMvd = CU::hasSubCUNonZeroMVd( cu );
if( !bNonZeroMvd )
{
return;
}
m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 0 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 0), 0 );

Karsten Suehring
committed
if( sps->getAMVREnabledFlag() && cu.imv > 0 )

Karsten Suehring
committed
{
#if JVET_O0057_ALTHPELIF
if (!CU::isIBC(cu))
{
m_BinEncoder.encodeBin(cu.imv < IMV_HPEL, Ctx::ImvFlag(4));
DTRACE(g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", cu.imv < 3, 4);
}
if (cu.imv < IMV_HPEL)
{
#endif
m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 1 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 1), 1 );
#if JVET_O0057_ALTHPELIF
}
#endif

Karsten Suehring
committed
}
DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() IMVFlag=%d\n", cu.imv );
}
void CABACWriter::affine_amvr_mode( const CodingUnit& cu )
{
const SPS* sps = cu.slice->getSPS();
if( !sps->getAffineAmvrEnabledFlag() || !cu.affine )
{
return;
}
if ( !CU::hasSubCUNonZeroAffineMVd( cu ) )
{
return;
}
m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 2 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 0), 2 );
if( cu.imv > 0 )
{
m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 3 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 1), 3 );
}
DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() IMVFlag=%d\n", cu.imv );
}

Karsten Suehring
committed
void CABACWriter::merge_idx( const PredictionUnit& pu )
{
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
if ( pu.cu->affine )
{
int numCandminus1 = int( pu.cs->slice->getMaxNumAffineMergeCand() ) - 1;
if ( numCandminus1 > 0 )
{
if ( pu.mergeIdx == 0 )
{
m_BinEncoder.encodeBin( 0, Ctx::AffMergeIdx() );
DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", pu.mergeIdx );
return;
}
else
{
m_BinEncoder.encodeBin( 1, Ctx::AffMergeIdx() );
for ( unsigned idx = 1; idx < numCandminus1; idx++ )
{
m_BinEncoder.encodeBinEP( pu.mergeIdx == idx ? 0 : 1 );
if ( pu.mergeIdx == idx )
{
break;
}
}
}
}
DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", pu.mergeIdx );
}
else
{
if( pu.cu->triangle )
{
bool splitDir = pu.triangleSplitDir;
uint8_t candIdx0 = pu.triangleMergeIdx0;
uint8_t candIdx1 = pu.triangleMergeIdx1;
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_split_dir=%d\n", splitDir );
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx0=%d\n", candIdx0 );
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx1=%d\n", candIdx1 );
candIdx1 -= candIdx1 < candIdx0 ? 0 : 1;
auto encodeOneIdx = [this](uint8_t mrgIdx, int numCandminus1)
{
if (numCandminus1 == 0)
{
CHECK(mrgIdx, "Incorrect index!");
return;
}
if(mrgIdx == 0)
{
this->m_BinEncoder.encodeBin( 0, Ctx::MergeIdx() );
return;
}
else
{
this->m_BinEncoder.encodeBin( 1, Ctx::MergeIdx() );
for( unsigned idx = 1; idx < numCandminus1; idx++ )
{
this->m_BinEncoder.encodeBinEP( mrgIdx == idx ? 0 : 1 );
if( mrgIdx == idx )
{
break;
}
}
}
};
m_BinEncoder.encodeBinEP(splitDir);
const int maxNumTriangleCand = pu.cs->slice->getMaxNumTriangleCand();
CHECK(maxNumTriangleCand < 2, "Incorrect max number of triangle candidates");
CHECK(candIdx0 >= maxNumTriangleCand, "Incorrect candIdx0");
CHECK(candIdx1 >= maxNumTriangleCand, "Incorrect candIdx1");
encodeOneIdx(candIdx0, maxNumTriangleCand - 1);
encodeOneIdx(candIdx1, maxNumTriangleCand - 2);
return;
}
#if JVET_O0455_IBC_MAX_MERGE_NUM
int numCandminus1;
if (pu.cu->predMode == MODE_IBC)
numCandminus1 = int(pu.cs->slice->getMaxNumIBCMergeCand()) - 1;
else
numCandminus1 = int(pu.cs->slice->getMaxNumMergeCand()) - 1;
#else
int numCandminus1 = int(pu.cs->slice->getMaxNumMergeCand()) - 1;
#endif

Karsten Suehring
committed
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
if( numCandminus1 > 0 )
{
if( pu.mergeIdx == 0 )
{
m_BinEncoder.encodeBin( 0, Ctx::MergeIdx() );
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx );
return;
}
else
{
m_BinEncoder.encodeBin( 1, Ctx::MergeIdx() );
for( unsigned idx = 1; idx < numCandminus1; idx++ )
{
m_BinEncoder.encodeBinEP( pu.mergeIdx == idx ? 0 : 1 );
if( pu.mergeIdx == idx )
{
break;
}
}
}
}
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx );

Karsten Suehring
committed
}
void CABACWriter::mmvd_merge_idx(const PredictionUnit& pu)
{
int var0, var1, var2;
int mvpIdx = pu.mmvdMergeIdx;
var0 = mvpIdx / MMVD_MAX_REFINE_NUM;
var1 = (mvpIdx - (var0 * MMVD_MAX_REFINE_NUM)) / 4;
var2 = mvpIdx - (var0 * MMVD_MAX_REFINE_NUM) - var1 * 4;

Karsten Suehring
committed
int numCand = int(pu.cs->slice->getMaxNumMergeCand());
int numCandminus1_base = (numCand > 1) ? MMVD_BASE_MV_NUM - 1 : 0;
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
if (numCandminus1_base > 0)
{
if (var0 == 0)
{
m_BinEncoder.encodeBin(0, Ctx::MmvdMergeIdx());
}
else
{
m_BinEncoder.encodeBin(1, Ctx::MmvdMergeIdx());
for (unsigned idx = 1; idx < numCandminus1_base; idx++)
{
m_BinEncoder.encodeBinEP(var0 == idx ? 0 : 1);
if (var0 == idx)
{
break;
}
}
}
}
DTRACE(g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", var0);
int numCandminus1_step = MMVD_REFINE_STEP - 1;
if (numCandminus1_step > 0)
{
if (var1 == 0)
{
m_BinEncoder.encodeBin(0, Ctx::MmvdStepMvpIdx());