Newer
Older

Karsten Suehring
committed
}
}
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 || ( 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 )
{
{
#if JVET_N0185_UNIFIED_MPM
unsigned ctx = (pu.cu->ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
if (pu.multiRefIdx == 0)
m_BinEncoder.encodeBin( mpm_idx > 0, Ctx::HarmonizedMPMIdx(ctx) );
#else

Karsten Suehring
committed
m_BinEncoder.encodeBinEP( mpm_idx > 0 );

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
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
}
}
}
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::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
if( pu.cs->sps->getUseLMChroma() )

Karsten Suehring
committed
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
{
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 )
{

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;
}
}
ChromaCbfs chromaCbfs;
if( cu.ispMode && isLuma( partitioner.chType ) )
{
TUIntraSubPartitioner subTuPartitioner( partitioner );
transform_tree( *cu.cs, subTuPartitioner, cuCtx, chromaCbfs, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType ) ), 0 );
}
else
{
transform_tree( *cu.cs, partitioner, cuCtx, chromaCbfs );
}

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 );
}
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
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
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
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
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 (CU::isIBC(*pu.cu))
{
merge_idx(pu);
return;
}
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 );
}
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);
}

Karsten Suehring
committed
else
{
int8_t affineMvdShift = pu.cu->imv ? ( pu.cu->imv == 1 ? -1 : 1 ) : 0;

Karsten Suehring
committed
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 )
{
mvd_coding( pu.mvdAffi[REF_PIC_LIST_0][0], affineMvdShift );
mvd_coding( pu.mvdAffi[REF_PIC_LIST_0][1], affineMvdShift );
if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
{
mvd_coding( pu.mvdAffi[REF_PIC_LIST_0][2], affineMvdShift );
}

Karsten Suehring
committed
}
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 */ )
{

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], affineMvdShift );
mvd_coding( pu.mvdAffi[REF_PIC_LIST_1][1], affineMvdShift );
if ( pu.cu->affineType == AFFINEMODEL_6PARAM )
{
mvd_coding( pu.mvdAffi[REF_PIC_LIST_1][2], affineMvdShift );
}

Karsten Suehring
committed
}
else
{
mvd_coding( pu.mvd[REF_PIC_LIST_1], pu.cu->imv );
}
}

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 ( cu.firstPU->mergeFlag && (cu.firstPU->mmvdMergeFlag || cu.mmvdSkip) )
{
return;
}
if ( !cu.cs->slice->isIntra() && (cu.cs->sps->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->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 (pu.mergeFlag && CU::isIBC(*pu.cu))
{
return;
}
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 )
{

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;
}
unsigned ctxId = DeriveCtx::CtxIMVFlag( cu );
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( sps->getAMVREnabledFlag() && cu.imv > 0 )

Karsten Suehring
committed
{
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 );
}
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
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( 4 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", ( cu.imv > 0 ), 4 );
if( cu.imv > 0 )
{
m_BinEncoder.encodeBin( ( cu.imv > 1 ), Ctx::ImvFlag( 5 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", ( cu.imv > 1 ), 5 );
}
DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() IMVFlag=%d\n", cu.imv );
}

Karsten Suehring
committed
void CABACWriter::merge_idx( const PredictionUnit& pu )
{
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
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 )
{
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
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(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);
encodeOneIdx(candIdx0, TRIANGLE_MAX_NUM_UNI_CANDS - 1);
encodeOneIdx(candIdx1, TRIANGLE_MAX_NUM_UNI_CANDS - 2);
return;
}

Karsten Suehring
committed
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
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
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
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 ( pu.cu->smvdMode )
{
CHECK( pu.refIdx[eRefList] != pu.cs->slice->getSymRefIdx( eRefList ), "Invalid reference index!\n" );
return;
}

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

Karsten Suehring
committed
1704
1705
1706
1707
1708
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
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->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()->getUseTriangle() || !cu.cs->slice->isInterB() || cu.lwidth() * cu.lheight() < TRIANGLE_MIN_SIZE || cu.affine )
{
return;
}
Ruoyang Yu
committed
if ( cu.firstPU->mmvdMergeFlag || cu.mmvdSkip )
{
return;
}
if ( cu.firstPU->mhIntraFlag )
{
return;
}
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
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
{
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 )
//================================================================================
void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, ChromaCbfs& chromaCbfs, const PartSplit ispType, const int subTuIdx )

Karsten Suehring
committed
{
ChromaCbfs chromaCbfsLastDepth;
chromaCbfsLastDepth.Cb = chromaCbfs.Cb;
chromaCbfsLastDepth.Cr = chromaCbfs.Cr;

Karsten Suehring
committed
const UnitArea& area = partitioner.currArea();
int subTuCounter = subTuIdx;
const TransformUnit& tu = *cs.getTU( area.blocks[partitioner.chType].pos(), partitioner.chType, subTuIdx );

Karsten Suehring
committed
const CodingUnit& cu = *tu.cu;
const unsigned trDepth = partitioner.currTrDepth;
const bool split = ( tu.depth > trDepth );
const bool chromaCbfISP = area.blocks[COMPONENT_Cb].valid() && cu.ispMode && !split;

Karsten Suehring
committed
// split_transform_flag

Karsten Suehring
committed
{

Karsten Suehring
committed
}
else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
{
CHECK( !split, "transform split implied - sbt" );
}
CHECK( split && !cu.ispMode, "transform split not allowed with QTBT" );

Karsten Suehring
committed
// cbf_cb & cbf_cr
if( area.chromaFormat != CHROMA_400 && area.blocks[COMPONENT_Cb].valid() && ( !CS::isDualITree( cs ) || partitioner.chType == CHANNEL_TYPE_CHROMA ) && ( !cu.ispMode || chromaCbfISP ) )

Karsten Suehring
committed
{
{
unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
if( trDepth == 0 || chromaCbfs.Cb || chromaCbfISP )
{
chromaCbfs.Cb = TU::getCbfAtDepth( tu, COMPONENT_Cb, trDepth );
if( !( cu.sbtInfo && trDepth == 1 ) )
cbf_comp( cs, chromaCbfs.Cb, area.blocks[COMPONENT_Cb], cbfDepth );
}
else
{
CHECK( TU::getCbfAtDepth( tu, COMPONENT_Cb, cbfDepth ) != chromaCbfs.Cb, "incorrect Cb cbf" );
}
if( trDepth == 0 || chromaCbfs.Cr || chromaCbfISP )
{
chromaCbfs.Cr = TU::getCbfAtDepth( tu, COMPONENT_Cr, trDepth );
if( !( cu.sbtInfo && trDepth == 1 ) )
cbf_comp( cs, chromaCbfs.Cr, area.blocks[COMPONENT_Cr], cbfDepth, chromaCbfs.Cb );
}
else
{
CHECK( TU::getCbfAtDepth( tu, COMPONENT_Cr, cbfDepth ) != chromaCbfs.Cr, "incorrect Cr cbf" );
}

Karsten Suehring
committed
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
}
}
else if( CS::isDualITree( cs ) )
{
chromaCbfs = ChromaCbfs( false );
}
if( split )
{
if( area.chromaFormat != CHROMA_400 )
{
chromaCbfs.Cb = TU::getCbfAtDepth( tu, COMPONENT_Cb, trDepth );
chromaCbfs.Cr = TU::getCbfAtDepth( tu, COMPONENT_Cr, trDepth );
}
if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
{
#if ENABLE_TRACING
const CompArea &tuArea = partitioner.currArea().blocks[partitioner.chType];
DTRACE( g_trace_ctx, D_SYNTAX, "transform_tree() maxTrSplit chType=%d pos=(%d,%d) size=%dx%d\n", partitioner.chType, tuArea.x, tuArea.y, tuArea.width, tuArea.height );
#endif
partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
}
else if( cu.ispMode )
{
partitioner.splitCurrArea( ispType, cs );
}
else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
{
partitioner.splitCurrArea( PartSplit( cu.getSbtTuSplit() ), cs );
}

Karsten Suehring
committed
else
THROW( "Implicit TU split not available" );
do
{
ChromaCbfs subChromaCbfs = chromaCbfs;
transform_tree( cs, partitioner, cuCtx, subChromaCbfs, ispType, subTuCounter );
subTuCounter += subTuCounter != -1 ? 1 : 0;

Karsten Suehring
committed
} while( partitioner.nextPart( cs ) );
partitioner.exitCurrSplit();
}
else
{
DTRACE( g_trace_ctx, D_SYNTAX, "transform_unit() pos=(%d,%d) size=%dx%d depth=%d trDepth=%d\n", tu.blocks[tu.chType].x, tu.blocks[tu.chType].y, tu.blocks[tu.chType].width, tu.blocks[tu.chType].height, cu.depth, partitioner.currTrDepth );
if( !isChroma( partitioner.chType ) )