Newer
Older
int val = 1 << thresh;
assert(val <= maxSymbol);
assert((val << 1) > maxSymbol);
assert(symbol < maxSymbol);
int b = maxSymbol - val;
assert(b < val);
if (symbol < val - b)
symbol += val - b;
assert(symbol < (val << 1));
assert((symbol >> 1) >= val - b);
m_BinEncoder.encodeBinsEP(symbol, thresh + 1);
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
void CABACWriter::extend_ref_line(const PredictionUnit& pu)
{
const CodingUnit& cu = *pu.cu;
if (!cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType))
{
return;
}
bool isFirstLineOfCtu = (((cu.block(COMPONENT_Y).y)&((cu.cs->sps)->getMaxCUWidth() - 1)) == 0);
if (isFirstLineOfCtu)
{
return;
}
int multiRefIdx = pu.multiRefIdx;
if (MRL_NUM_REF_LINES > 1)
{
m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0));
if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0])
{
m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1));
if (MRL_NUM_REF_LINES > 3 && multiRefIdx != MULTI_REF_LINE_IDX[1])
{
m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[2], Ctx::MultiRefLineIdx(2));
}
}
}
}
void CABACWriter::extend_ref_line(const CodingUnit& cu)
{
if (!cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType))
{
return;
}
const int numBlocks = CU::getNumPUs(cu);
const PredictionUnit* pu = cu.firstPU;
for (int k = 0; k < numBlocks; k++)
{
bool isFirstLineOfCtu = (((cu.block(COMPONENT_Y).y)&((cu.cs->sps)->getMaxCUWidth() - 1)) == 0);
if (isFirstLineOfCtu)
{
return;
}
int multiRefIdx = pu->multiRefIdx;
if (MRL_NUM_REF_LINES > 1)
{
m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0));
if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0])
{
m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1));
if (MRL_NUM_REF_LINES > 3 && multiRefIdx != MULTI_REF_LINE_IDX[1])
{
m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[2], Ctx::MultiRefLineIdx(2));
}
}
}
pu = pu->next;
}
}

Karsten Suehring
committed
void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
{
if( !cu.Y().valid() )
{
return;
}
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)
{
CHECK(mpm_idx >= numMPMs, "use of non-MPM");
}
else

Karsten Suehring
committed
m_BinEncoder.encodeBin( mpm_idx < numMPMs, Ctx::IPredMode[0]() );
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 )
{
{
m_BinEncoder.encodeBinEP( mpm_idx > 0 );
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 )
{
// 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)
{
CHECK(mpm_idx >= numMPMs, "use of non-MPM");
}
else

Karsten Suehring
committed
m_BinEncoder.encodeBin( mpm_idx < numMPMs, Ctx::IPredMode[0]() );
// mpm_idx / rem_intra_luma_pred_mode
if( mpm_idx < numMPMs )
{
{
m_BinEncoder.encodeBinEP( mpm_idx > 0 );
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
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
}
}
}
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 );
}
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::IPredMode[1]( 2 ), Ctx::IPredMode[1]( 3 ), maxSymbol - 1 );
}
void CABACWriter::intra_chroma_pred_mode( const PredictionUnit& pu )
{
const unsigned intraDir = pu.intraDir[1];
{
if( intraDir == DM_CHROMA_IDX )
{
m_BinEncoder.encodeBin( 0, Ctx::IPredMode[1]( 1 ) );
return;
}
m_BinEncoder.encodeBin( 1, Ctx::IPredMode[1]( 1 ) );
}
// LM chroma mode
if( pu.cs->sps->getSpsNext().getUseLMChroma() )
{
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 );
}
}
void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx )
{
#if IBC_SEPERATE_MODE
if (!CU::isIntra(cu))
#else

Karsten Suehring
committed
if( CU::isInter( cu ) )

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

Karsten Suehring
committed
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
{
rqt_root_cbf( cu );
}
if( !cu.rootCbf )
{
return;
}
}
ChromaCbfs chromaCbfs;
transform_tree( *cu.cs, partitioner, cuCtx, chromaCbfs );
}
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 );
}
void CABACWriter::end_of_ctu( const CodingUnit& cu, CUCtx& cuCtx )
{
const Slice* slice = cu.cs->slice;
#if HEVC_TILES_WPP
const TileMap& tileMap = *cu.cs->picture->tileMap;
const int currentCTUTsAddr = tileMap.getCtuRsToTsAddrMap( CU::getCtuAddr( cu ) );
#else
const int currentCTUTsAddr = CU::getCtuAddr( cu );
#endif
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 HEVC_DEPENDENT_SLICES
if( slice->getSliceSegmentCurEndCtuTsAddr() != currentCTUTsAddr + 1 )
#else
if(slice->getSliceCurEndCtuTsAddr() != currentCTUTsAddr + 1)
#endif
{
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 IBC_SEPERATE_MODE
if (CU::isIBC(*pu.cu))
{
merge_idx(pu);
return;
}
#endif
subblock_merge_flag( *pu.cu );
MHIntra_flag( pu );
{
MHIntra_luma_pred_modes( *pu.cu );
}
triangle_mode( *pu.cu );
if (pu.mmvdMergeFlag)
{
mmvd_merge_idx(pu);
}
else

Karsten Suehring
committed
merge_idx ( pu );
}
#if IBC_SEPERATE_MODE
else if (CU::isIBC(*pu.cu))
{
ref_idx(pu, REF_PIC_LIST_0);
mvd_coding(pu.mvd[REF_PIC_LIST_0], pu.cu->imv);
mvp_flag(pu, REF_PIC_LIST_0);
}
#endif

Karsten Suehring
committed
else
{
inter_pred_idc( pu );
affine_flag ( *pu.cu );
#if JVET_M0444_SMVD
smvd_mode( pu );
#endif

Karsten Suehring
committed
if( pu.interDir != 2 /* PRED_L1 */ )
{
ref_idx ( pu, REF_PIC_LIST_0 );
if ( pu.cu->affine )
{
mvd_coding(pu.mvdAffi[REF_PIC_LIST_0][0], 0);
mvd_coding(pu.mvdAffi[REF_PIC_LIST_0][1], 0);
if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
{
mvd_coding(pu.mvdAffi[REF_PIC_LIST_0][2], 0);
}
}
else
{
mvd_coding( pu.mvd[REF_PIC_LIST_0], pu.cu->imv );
}
mvp_flag ( pu, REF_PIC_LIST_0 );
}
if( pu.interDir != 1 /* PRED_L0 */ )
{
#if JVET_M0444_SMVD
if ( pu.cu->smvdMode != 1 )
{
#endif

Karsten Suehring
committed
ref_idx ( pu, REF_PIC_LIST_1 );
if( !pu.cs->slice->getMvdL1ZeroFlag() || pu.interDir != 3 /* PRED_BI */ )
{
if ( pu.cu->affine )
{
mvd_coding(pu.mvdAffi[REF_PIC_LIST_1][0], 0);
mvd_coding(pu.mvdAffi[REF_PIC_LIST_1][1], 0);
if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
{
mvd_coding(pu.mvdAffi[REF_PIC_LIST_1][2], 0);
}
}
else
{
mvd_coding( pu.mvd[REF_PIC_LIST_1], pu.cu->imv );
}
}
#if JVET_M0444_SMVD
}
#endif

Karsten Suehring
committed
mvp_flag ( pu, REF_PIC_LIST_1 );
}
}
}
#if JVET_M0444_SMVD
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 );
}
#endif
void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
{
if ( cu.firstPU->mergeFlag && (cu.firstPU->mmvdMergeFlag || cu.mmvdSkip) )
{
return;
}
if ( !cu.cs->slice->isIntra() && (cu.cs->sps->getSpsNext().getUseAffine() || cu.cs->sps->getSBTMVPEnabledFlag()) && 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, "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->getSpsNext().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->getSpsNext().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 IBC_SEPERATE_MODE
if (pu.mergeFlag && CU::isIBC(*pu.cu))
{
return;
}
#endif
if (pu.mergeFlag)
{
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
}
void CABACWriter::imv_mode( const CodingUnit& cu )
{
const SPSNext& spsNext = cu.cs->sps->getSpsNext();
if( !spsNext.getUseIMV() )
{
return;
}
bool bNonZeroMvd = CU::hasSubCUNonZeroMVd( cu );
if( !bNonZeroMvd )
{
return;
}
unsigned ctxId = DeriveCtx::CtxIMVFlag( cu );
#if IBC_SEPERATE_MODE
if (CU::isIBC(cu) == false)
#else
if (!(cu.firstPU->interDir == 1 && cu.cs->slice->getRefPic(REF_PIC_LIST_0, cu.firstPU->refIdx[REF_PIC_LIST_0])->getPOC() == cu.cs->slice->getPOC())) // the first bin of IMV flag does need to be signaled in IBC block
m_BinEncoder.encodeBin( ( cu.imv > 0 ), Ctx::ImvFlag( ctxId ) );

Karsten Suehring
committed
DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 0), ctxId );
if( spsNext.getImvMode() == IMV_4PEL && cu.imv > 0 )
{
m_BinEncoder.encodeBin( ( cu.imv > 1 ), Ctx::ImvFlag( 3 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", ( cu.imv > 1 ), 3 );
}
DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() IMVFlag=%d\n", cu.imv );
}
void CABACWriter::merge_idx( const PredictionUnit& pu )
{
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
{
Guillaume Laroche
committed
#if !JVET_M0381_ONE_CTX_FOR_SUBBLOCK_MRG_IDX
bool useExtCtx = pu.cs->sps->getSBTMVPEnabledFlag();
Guillaume Laroche
committed
#endif
m_BinEncoder.encodeBin( 1, Ctx::AffMergeIdx() );
for ( unsigned idx = 1; idx < numCandminus1; idx++ )
{
Guillaume Laroche
committed
#if !JVET_M0381_ONE_CTX_FOR_SUBBLOCK_MRG_IDX
if ( useExtCtx )
{
m_BinEncoder.encodeBin( pu.mergeIdx == idx ? 0 : 1, Ctx::AffMergeIdx( std::min<int>( idx, NUM_MERGE_IDX_EXT_CTX - 1 ) ) );
}
else
{
Guillaume Laroche
committed
#endif
m_BinEncoder.encodeBinEP( pu.mergeIdx == idx ? 0 : 1 );
Guillaume Laroche
committed
#if !JVET_M0381_ONE_CTX_FOR_SUBBLOCK_MRG_IDX
Guillaume Laroche
committed
#endif
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 )
{
if( pu.mergeIdx < 2 )
{
m_BinEncoder.encodeBin( 0, Ctx::TriangleIdx() );
m_BinEncoder.encodeBinEP( pu.mergeIdx );
}
else
{
m_BinEncoder.encodeBin( 1, Ctx::TriangleIdx() );
exp_golomb_eqprob( pu.mergeIdx - 2, 2 );
}
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx=%d\n", pu.mergeIdx );
return;
}

Karsten Suehring
committed
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
int numCandminus1 = int( pu.cs->slice->getMaxNumMergeCand() ) - 1;
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
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
int numCandminus1_base = MMVD_BASE_MV_NUM - 1;
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());
}
else
{
m_BinEncoder.encodeBin(1, Ctx::MmvdStepMvpIdx());
for (unsigned idx = 1; idx < numCandminus1_step; idx++)
{
m_BinEncoder.encodeBinEP(var1 == idx ? 0 : 1);
if (var1 == idx)
{
break;
}
}
}
}
DTRACE(g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", var1);
m_BinEncoder.encodeBinsEP(var2, 2);
DTRACE(g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", var2);
DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.mmvdMergeIdx);
}

Karsten Suehring
committed
void CABACWriter::inter_pred_idc( const PredictionUnit& pu )
{
if( !pu.cs->slice->isInterB() )
{
return;
}

Karsten Suehring
committed
{
unsigned ctxId = DeriveCtx::CtxInterDir(pu);
if( pu.interDir == 3 )
{
m_BinEncoder.encodeBin( 1, Ctx::InterDir(ctxId) );
DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=%d value=%d pos=(%d,%d)\n", ctxId, pu.interDir, pu.lumaPos().x, pu.lumaPos().y );
return;
}
else
{
m_BinEncoder.encodeBin( 0, Ctx::InterDir(ctxId) );
}
}
m_BinEncoder.encodeBin( ( pu.interDir == 2 ), Ctx::InterDir( 4 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=4 value=%d pos=(%d,%d)\n", pu.interDir, pu.lumaPos().x, pu.lumaPos().y );
}
void CABACWriter::ref_idx( const PredictionUnit& pu, RefPicList eRefList )
{
#if JVET_M0444_SMVD
if ( pu.cu->smvdMode )
{
CHECK( pu.refIdx[eRefList] != pu.cs->slice->getSymRefIdx( eRefList ), "Invalid reference index!\n" );
return;
}
#endif

Karsten Suehring
committed
int numRef = pu.cs->slice->getNumRefIdx(eRefList);
#if IBC_SEPERATE_MODE
if (eRefList == REF_PIC_LIST_0 && pu.cs->sps->getSpsNext().getIBCMode())
{
if (CU::isIBC(*pu.cu))
return;
}
#endif

Karsten Suehring
committed
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
if( numRef <= 1 )
{
return;
}
int refIdx = pu.refIdx[eRefList];
m_BinEncoder.encodeBin( (refIdx > 0), Ctx::RefPic() );
if( numRef <= 2 || refIdx == 0 )
{
DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, pu.lumaPos().x, pu.lumaPos().y );
return;
}
m_BinEncoder.encodeBin( (refIdx > 1), Ctx::RefPic(1) );
if( numRef <= 3 || refIdx == 1 )
{
DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, pu.lumaPos().x, pu.lumaPos().y );
return;
}
for( int idx = 3; idx < numRef; idx++ )
{
if( refIdx > idx - 1 )
{
m_BinEncoder.encodeBinEP( 1 );
}
else
{
m_BinEncoder.encodeBinEP( 0 );
break;
}
}
DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, pu.lumaPos().x, pu.lumaPos().y );
}
void CABACWriter::mvp_flag( const PredictionUnit& pu, RefPicList eRefList )
{
m_BinEncoder.encodeBin( pu.mvpIdx[eRefList], Ctx::MVPIdx() );
DTRACE( g_trace_ctx, D_SYNTAX, "mvp_flag() value=%d pos=(%d,%d)\n", pu.mvpIdx[eRefList], pu.lumaPos().x, pu.lumaPos().y );
DTRACE( g_trace_ctx, D_SYNTAX, "mvpIdx(refList:%d)=%d\n", eRefList, pu.mvpIdx[eRefList] );
}
void CABACWriter::MHIntra_flag(const PredictionUnit& pu)
{
if (!pu.cs->sps->getSpsNext().getUseMHIntra())
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra SPS");
return;
}
if (pu.cu->skip)
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra and skip");
return;
}
if (pu.mmvdMergeFlag)
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra and mmvd");
return;
}
if (pu.cu->affine)
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra and affine");
return;
}
if (pu.cu->lwidth() * pu.cu->lheight() < 64 || pu.cu->lwidth() >= MAX_CU_SIZE || pu.cu->lheight() >= MAX_CU_SIZE)
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra and blk");
return;
}
m_BinEncoder.encodeBin(pu.mhIntraFlag, Ctx::MHIntraFlag());
DTRACE(g_trace_ctx, D_SYNTAX, "MHIntra_flag() MHIntra=%d pos=(%d,%d) size=%dx%d\n", pu.mhIntraFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height);
}
void CABACWriter::MHIntra_luma_pred_modes(const CodingUnit& cu)
{
if (!cu.Y().valid())
{
return;
}
const int numMPMs = 3;
int numBlocks = CU::getNumPUs(cu);
unsigned mpm_idxs[4];
unsigned pred_modes[4];
const PredictionUnit* pu = cu.firstPU;
unsigned mpm_pred[numMPMs];
for (int k = 0; k < numBlocks; k++)
{
unsigned& mpm_idx = mpm_idxs[k];
unsigned& pred_mode = pred_modes[k];
PU::getMHIntraMPMs(*pu, mpm_pred);
pred_mode = pu->intraDir[0];
mpm_idx = numMPMs;
for (int idx = 0; idx < numMPMs; idx++)
{
if (pred_mode == mpm_pred[idx])
{
mpm_idx = idx;
break;
}
}
if (PU::getNarrowShape(pu->lwidth(), pu->lheight()) == 0)
{
m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::MHIntraPredMode());
}
pu = pu->next;
}
pu = cu.firstPU;

Karsten Suehring
committed
// 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)
{
m_BinEncoder.encodeBinEP(mpm_idx > 0);
if (mpm_idx)
{
m_BinEncoder.encodeBinEP(mpm_idx > 1);
}
}
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;
}
}

Karsten Suehring
committed
void CABACWriter::triangle_mode( const CodingUnit& cu )
{
if( !cu.cs->slice->getSPS()->getSpsNext().getUseTriangle() || !cu.cs->slice->isInterB() || cu.lwidth() * cu.lheight() < TRIANGLE_MIN_SIZE || cu.affine )
{
return;
}
Ruoyang Yu
committed
#if JVET_M0118_M0185_TRIANGLE_FLAG_FIX
if ( cu.firstPU->mmvdMergeFlag || cu.mmvdSkip )
{
return;
}
if ( cu.firstPU->mhIntraFlag )
{
return;
}
#endif
unsigned flag_idx = DeriveCtx::CtxTriangleFlag( cu );
m_BinEncoder.encodeBin( cu.triangle, Ctx::TriangleFlag(flag_idx) );
DTRACE( g_trace_ctx, D_SYNTAX, "triangle_mode() triangle_mode=%d pos=(%d,%d) size: %dx%d\n", cu.triangle, cu.Y().x, cu.Y().y, cu.lumaSize().width, cu.lumaSize().height );
}

Karsten Suehring
committed
//================================================================================
// clause 7.3.8.7
//--------------------------------------------------------------------------------
// void pcm_samples( tu )
//================================================================================
void CABACWriter::pcm_samples( const TransformUnit& tu )
{
CHECK( !tu.cu->ipcm, "pcm mode expected" );
const SPS& sps = *tu.cu->cs->sps;
const CodingStructure *cs = tu.cs;
const ChannelType chType = tu.chType;
ComponentID compStr = (CS::isDualITree(*cs) && !isLuma(chType)) ? COMPONENT_Cb: COMPONENT_Y;
ComponentID compEnd = (CS::isDualITree(*cs) && isLuma(chType)) ? COMPONENT_Y : COMPONENT_Cr;
for( ComponentID compID = compStr; compID <= compEnd; compID = ComponentID(compID+1) )

Karsten Suehring
committed
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
{
const CPelBuf samples = tu.getPcmbuf( compID );
const unsigned sampleBits = sps.getPCMBitDepth( toChannelType(compID) );
for( unsigned y = 0; y < samples.height; y++ )
{
for( unsigned x = 0; x < samples.width; x++ )
{
m_BinEncoder.encodeBinsPCM( samples.at(x, y), sampleBits );
}
}
}
m_BinEncoder.restart();
}
//================================================================================
// clause 7.3.8.8
//--------------------------------------------------------------------------------
// void transform_tree ( cs, area, cuCtx, chromaCbfs )
// bool split_transform_flag( split, depth )
// bool cbf_comp ( cbf, area, depth )
//================================================================================