Newer
Older
#if !ENABLE_JVET_L0283_MRL
return;
#endif
if ( !cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType) || cu.ipcm || cu.bdpcmMode )
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
{
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));
}
}
pu = pu->next;
}
}

Karsten Suehring
committed
void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
{
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
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
}
}
}
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
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
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
{
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;
}
}
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] = false;
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;
#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 );
}
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
1426
1427
1428
1429
1430
1431
1432
1433
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
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 );
}
}
}
Yung-Hsuan Chao (Jessie)
committed
#if JVET_O0119_BASE_PALETTE_444
void CABACWriter::cu_palette_info(const CodingUnit& cu, ComponentID compBegin, uint32_t numComp, CUCtx& cuCtx)
Yung-Hsuan Chao (Jessie)
committed
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
{
const SPS& sps = *(cu.cs->sps);
TransformUnit& tu = *cu.firstTU;
uint32_t indexMaxSize = cu.useEscape[compBegin] ? (cu.curPLTSize[compBegin] + 1) : cu.curPLTSize[compBegin];
if (cu.lastPLTSize[compBegin])
{
xEncodePLTPredIndicator(cu, MAXPLTSIZE, compBegin);
}
uint32_t reusedPLTnum = 0;
for (int idx = 0; idx < cu.lastPLTSize[compBegin]; idx++)
{
if (cu.reuseflag[compBegin][idx])
reusedPLTnum++;
}
if (reusedPLTnum < MAXPLTSIZE)
{
exp_golomb_eqprob(cu.curPLTSize[compBegin] - reusedPLTnum, 0);
}
for (int comp = compBegin; comp < (compBegin + numComp); comp++)
Yung-Hsuan Chao (Jessie)
committed
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
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
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
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
{
for (int idx = cu.reusePLTSize[compBegin]; idx < cu.curPLTSize[compBegin]; idx++)
{
ComponentID compID = (ComponentID)comp;
const int channelBitDepth = sps.getBitDepth(toChannelType(compID));
m_BinEncoder.encodeBinsEP(cu.curPLT[comp][idx], channelBitDepth);
}
}
uint32_t signalEscape = (cu.useEscape[compBegin]) ? 1 : 0;
if (cu.curPLTSize[compBegin] > 0)
{
m_BinEncoder.encodeBinEP(signalEscape);
}
//encode index map
PLTtypeBuf runType = tu.getrunType(compBegin);
PelBuf runLength = tu.getrunLength(compBegin);
PelBuf curPLTIdx = tu.getcurPLTIdx(compBegin);
uint32_t uiHeight = cu.block(compBegin).height;
uint32_t uiWidth = cu.block(compBegin).width;
m_puiScanOrder = g_scanOrder[SCAN_UNGROUPED][(cu.useRotation[compBegin]) ? SCAN_TRAV_VER : SCAN_TRAV_HOR][gp_sizeIdxInfo->idxFrom(uiWidth)][gp_sizeIdxInfo->idxFrom(uiHeight)];
uint32_t total = uiHeight * uiWidth;
int iLastRunPos = -1;
uint32_t lastRunType = 0;
uint32_t uiNumIndices = 0;
std::vector<int> vIdxPos, vParsedIdx;
vIdxPos.reserve(total);
vParsedIdx.reserve(total);
if (indexMaxSize > 1)
{
int idx = 0, run = 0;
while (idx < total)
{
uint32_t posy = m_puiScanOrder[idx].y;
uint32_t posx = m_puiScanOrder[idx].x;
if (runType.at(posx, posy) == PLT_RUN_INDEX)
{
vIdxPos.push_back(idx);
uiNumIndices++;
}
lastRunType = runType.at(posx, posy);
iLastRunPos = idx;
run = runLength.at(posx, posy);
idx += run;
}
uint32_t currParam = 3 + ((indexMaxSize) >> 3);
uint32_t uiMappedValue;
assert(uiNumIndices);
assert(uiNumIndices > 0);
uiMappedValue = uiNumIndices - 1;
m_BinEncoder.encodeRemAbsEP(uiMappedValue, currParam, false, MAX_NUM_CHANNEL_TYPE); // JC: code number of indices (PLT_RUN_INDEX)
auto vIdxPosEnd = vIdxPos.end();
for (auto iter = vIdxPos.begin(); iter != vIdxPosEnd; ++iter)
{
vParsedIdx.push_back( writePLTIndex(cu, *iter, curPLTIdx, runType, indexMaxSize, compBegin));
}
m_BinEncoder.encodeBin(lastRunType, Ctx::RunTypeFlag());
codeScanRotationModeFlag(cu, compBegin);
}
else
{
assert(!cu.useRotation[compBegin]);
}
if (cu.useEscape[compBegin] && cu.cs->pps->getUseDQP() && !cuCtx.isDQPCoded)
{
if (!CS::isDualITree(*tu.cs) || isLuma(tu.chType))
{
cu_qp_delta(cu, cuCtx.qp, cu.qp);
cuCtx.qp = cu.qp;
cuCtx.isDQPCoded = true;
}
}
#if JVET_O1168_CU_CHROMA_QP_OFFSET
if ( cu.useEscape[compBegin] && cu.cs->slice->getUseChromaQpAdj() && !cuCtx.isChromaQpAdjCoded)
#else
if (cu.cs->slice->getUseChromaQpAdj() && !cu.transQuantBypass && !cuCtx.isChromaQpAdjCoded)
#endif
{
if (!CS::isDualITree(*tu.cs) || isChroma(tu.chType))
{
cu_chroma_qp_offset(cu);
cuCtx.isChromaQpAdjCoded = true;
}
}
uint32_t strPos = 0;
uint32_t endPos = uiHeight * uiWidth;
auto vParsedIdxEnd = vParsedIdx.end();
auto vParsedIdxIter = vParsedIdx.begin();
while (strPos < endPos)
{
uint32_t posy = m_puiScanOrder[strPos].y;
uint32_t posx = m_puiScanOrder[strPos].x;
uint32_t posyprev = strPos == 0 ? 0 : m_puiScanOrder[strPos - 1].y;
uint32_t posxprev = strPos == 0 ? 0 : m_puiScanOrder[strPos - 1].x;
if (indexMaxSize > 1)
{
if (((posy == 0) && !cu.useRotation[compBegin]) || ((posx == 0) && cu.useRotation[compBegin]))
{
assert(runType.at(posx, posy) == PLT_RUN_INDEX);
}
else if (strPos != 0 && runType.at(posxprev, posyprev) == PLT_RUN_COPY)
{
assert(runType.at(posx, posy) == PLT_RUN_INDEX);
}
else
{
if (uiNumIndices && strPos < endPos - 1) // if uiNumIndices (decoder will know this value) == 0 - > only CopyAbove, if strPos == endPos - 1, the last RunType was already coded
{
m_BinEncoder.encodeBin((runType.at(posx, posy)), Ctx::RunTypeFlag());
}
}
}
Pel siCurLevel = 0;
if (runType.at(posx, posy) == PLT_RUN_INDEX)
{
if (vParsedIdxIter != vParsedIdxEnd)
{
siCurLevel = *vParsedIdxIter++;
}
else
{
siCurLevel = 0;
}
}
if (indexMaxSize > 1)
{
if (iLastRunPos != strPos)
{
uiNumIndices -= (runType.at(posx, posy) == PLT_RUN_INDEX);
cu_run_val(runLength.at(posx, posy) - 1, (PLTRunMode)runType.at(posx, posy), siCurLevel, endPos - strPos - uiNumIndices - 1 - lastRunType);
}
}
strPos += (runLength.at(posx, posy));
}
assert(strPos == endPos);
uint32_t scaleX = getComponentScaleX(COMPONENT_Cb, sps.getChromaFormatIdc());
uint32_t scaleY = getComponentScaleY(COMPONENT_Cb, sps.getChromaFormatIdc());
for (int comp = compBegin; comp < (compBegin + numComp); comp++)
Yung-Hsuan Chao (Jessie)
committed
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
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
{
ComponentID compID = (ComponentID)comp;
for (strPos = 0; strPos < endPos; strPos++)
{
uint32_t posy = m_puiScanOrder[strPos].y;
uint32_t posx = m_puiScanOrder[strPos].x;
if (curPLTIdx.at(posx, posy) == cu.curPLTSize[compBegin])
{
{
PLTescapeBuf escapeValue = tu.getescapeValue((ComponentID)comp);
if (compID == COMPONENT_Y || compBegin != COMPONENT_Y)
{
exp_golomb_eqprob((unsigned)escapeValue.at(posx, posy), 3);
}
if (compBegin == COMPONENT_Y && compID != COMPONENT_Y && posy % (1 << scaleY) == 0 && posx % (1 << scaleX) == 0)
{
uint32_t posxC = posx >> scaleX;
uint32_t posyC = posy >> scaleY;
exp_golomb_eqprob((unsigned)escapeValue.at(posxC, posyC), 3);
}
}
}
}
}
}
void CABACWriter::codeScanRotationModeFlag(const CodingUnit& cu, ComponentID compBegin)
{
m_BinEncoder.encodeBin((cu.useRotation[compBegin]), Ctx::RotationFlag());
}
void CABACWriter::xEncodePLTPredIndicator(const CodingUnit& cu, uint32_t uiMaxPLTSize, ComponentID compBegin)
{
int lastPredIdx = -1;
uint32_t run = 0;
uint32_t uiNumPLTPredicted = 0;
for (uint32_t idx = 0; idx < cu.lastPLTSize[compBegin]; idx++)
{
if (cu.reuseflag[compBegin][idx])
{
uiNumPLTPredicted++;
lastPredIdx = idx;
}
}
int idx = 0;
while (idx <= lastPredIdx)
{
if (cu.reuseflag[compBegin][idx])
{
exp_golomb_eqprob(run ? run + 1 : run, 0);
run = 0;
}
else
{
run++;
}
idx++;
}
if ((uiNumPLTPredicted < uiMaxPLTSize && lastPredIdx + 1 < cu.lastPLTSize[compBegin]) || !uiNumPLTPredicted)
{
exp_golomb_eqprob(1, 0);
}
}
Pel CABACWriter::writePLTIndex(const CodingUnit& cu, uint32_t idx, PelBuf& paletteIdx, PLTtypeBuf& paletteRunType, int maxSymbol, ComponentID compBegin)
Yung-Hsuan Chao (Jessie)
committed
{
uint32_t posy = m_puiScanOrder[idx].y;
uint32_t posx = m_puiScanOrder[idx].x;
Pel siCurLevel = (paletteIdx.at(posx, posy) == cu.curPLTSize[compBegin]) ? (maxSymbol - 1) : paletteIdx.at(posx, posy);
Yung-Hsuan Chao (Jessie)
committed
if (idx) // R0348: remove index redundancy
{
uint32_t prevposy = m_puiScanOrder[idx - 1].y;
uint32_t prevposx = m_puiScanOrder[idx - 1].x;
if (paletteRunType.at(prevposx, prevposy) == PLT_RUN_INDEX)
Yung-Hsuan Chao (Jessie)
committed
{
Pel siLeftLevel = paletteIdx.at(prevposx, prevposy); // left index
Yung-Hsuan Chao (Jessie)
committed
if (siLeftLevel == cu.curPLTSize[compBegin]) // escape mode
{
siLeftLevel = maxSymbol - 1;
}
assert(siLeftLevel != siCurLevel);
if (siCurLevel > siLeftLevel)
{
siCurLevel--;
}
}
else
{
Pel siAboveLevel;
if (cu.useRotation[compBegin])
{
assert(prevposx > 0);
siAboveLevel = paletteIdx.at(posx - 1, posy);
if (paletteIdx.at(posx - 1, posy) == cu.curPLTSize[compBegin]) // escape mode
Yung-Hsuan Chao (Jessie)
committed
{
siAboveLevel = maxSymbol - 1;
}
}
else
{
assert(prevposy > 0);
siAboveLevel = paletteIdx.at(posx, posy - 1);
if (paletteIdx.at(posx, posy - 1) == cu.curPLTSize[compBegin]) // escape mode
Yung-Hsuan Chao (Jessie)
committed
1734
1735
1736
1737
1738
1739
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
{
siAboveLevel = maxSymbol - 1;
}
}
assert(siCurLevel != siAboveLevel);
if (siCurLevel > siAboveLevel)
{
siCurLevel--;
}
}
maxSymbol--;
}
assert(maxSymbol > 0);
assert(siCurLevel >= 0);
assert(maxSymbol > siCurLevel);
if (maxSymbol > 1)
{
xWriteTruncBinCode(siCurLevel, maxSymbol);
}
return siCurLevel;
}
void CABACWriter::encodeRunType(const CodingUnit& cu, PLTtypeBuf& runType, uint32_t idx, ScanElement *refScanOrder, ComponentID compBegin)
{
if (refScanOrder)
{
m_puiScanOrder = refScanOrder;
}
uint32_t posy = m_puiScanOrder[idx].y;
uint32_t posx = m_puiScanOrder[idx].x;
uint32_t posyprev = (idx == 0) ? 0 : m_puiScanOrder[idx - 1].y;
uint32_t posxprev = (idx == 0) ? 0 : m_puiScanOrder[idx - 1].x;
if (((posy == 0) && !cu.useRotation[compBegin]) || ((posx == 0) && cu.useRotation[compBegin]))
{
assert(runType.at(posx, posy) == PLT_RUN_INDEX);
}
else if (idx != 0 && runType.at(posxprev, posyprev) == PLT_RUN_COPY)
{
assert(runType.at(posx, posy) == PLT_RUN_INDEX);
}
else
{
m_BinEncoder.encodeBin((runType.at(posx, posy)), Ctx::RunTypeFlag());
}
}

Karsten Suehring
committed
Yung-Hsuan Chao (Jessie)
committed
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
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
void CABACWriter::cu_run_val(uint32_t uiRun, PLTRunMode runtype, const uint32_t uiPltIdx, const uint32_t uiMaxRun)
{
if (runtype == PLT_RUN_COPY)
{
}
else
{
g_ucRunLeftLut[0] = (uiPltIdx < PLT_RUN_MSB_IDX_CTX_T1 ? 0 : (uiPltIdx < PLT_RUN_MSB_IDX_CTX_T2 ? 1 : 2));
}
xWriteTruncMsbP1RefinementBits(uiRun, runtype, uiMaxRun, PLT_RUN_MSB_IDX_CABAC_BYPASS_THRE);
}
uint32_t CABACWriter::xWriteTruncMsbP1(uint32_t uiSymbol, PLTRunMode runtype, uint32_t uiMax, uint32_t uiCtxT)
{
if (uiMax == 0)
return 0;
uint8_t *ucCtxLut;
ucCtxLut = (runtype == PLT_RUN_INDEX) ? g_ucRunLeftLut : g_ucRunTopLut;
uint32_t uiMsbP1;
for (uiMsbP1 = 0; uiSymbol > 0; uiMsbP1++)
{
uiSymbol >>= 1;
if (uiMsbP1 > uiCtxT)
{
m_BinEncoder.encodeBinEP(1);
}
else
m_BinEncoder.encodeBin(1, (uiMsbP1 <= uiCtxT)
? ((runtype == PLT_RUN_INDEX) ? Ctx::IdxRunModel(ucCtxLut[uiMsbP1]) : Ctx::CopyRunModel(ucCtxLut[uiMsbP1]))
: ((runtype == PLT_RUN_INDEX) ? Ctx::IdxRunModel(ucCtxLut[uiCtxT]) : Ctx::CopyRunModel(ucCtxLut[uiCtxT])));
}
assert(uiMsbP1 <= uiMax);
if (uiMsbP1 < uiMax)
{
if (uiMsbP1 > uiCtxT)
{
m_BinEncoder.encodeBinEP(0);
}
else
m_BinEncoder.encodeBin(0, uiMsbP1 <= uiCtxT
? ((runtype == PLT_RUN_INDEX) ? Ctx::IdxRunModel(ucCtxLut[uiMsbP1]) : Ctx::CopyRunModel(ucCtxLut[uiMsbP1]))
: ((runtype == PLT_RUN_INDEX) ? Ctx::IdxRunModel(ucCtxLut[uiCtxT]) : Ctx::CopyRunModel(ucCtxLut[uiCtxT])));
//m_pcBinIf->encodeBin(0, uiMsbP1 <= uiCtxT? pcSCModel[ucCtxLut[uiMsbP1]] : pcSCModel[ucCtxLut[uiCtxT]]);
}
return uiMsbP1;
}

Karsten Suehring
committed
Yung-Hsuan Chao (Jessie)
committed
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
void CABACWriter::xWriteTruncMsbP1RefinementBits(uint32_t uiSymbol, PLTRunMode runtype, uint32_t uiMax, uint32_t uiCtxT)
{
if (uiMax == 0)
return;
uint32_t uiMsbP1 = xWriteTruncMsbP1(uiSymbol, runtype, g_getMsbP1Idx(uiMax), uiCtxT);
if (uiMsbP1 > 1)
{
uint32_t uiNumBins = g_getMsbP1Idx(uiMax);
if (uiMsbP1 < uiNumBins)
{
uint32_t uiBits = uiMsbP1 - 1;
m_BinEncoder.encodeBinsEP(uiSymbol & ((1 << uiBits) - 1), uiBits);
}
else
{
uint32_t curValue = 1 << (uiNumBins - 1);
xWriteTruncBinCode(uiSymbol - curValue, uiMax + 1 - curValue);
}
}
}

Karsten Suehring
committed
Yung-Hsuan Chao (Jessie)
committed
#endif

Karsten Suehring
committed
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
//================================================================================
// 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 );
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 );
}
}
}