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
{
const SPS& sps = *(cu.cs->sps);
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
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++)
{
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 height = cu.block(compBegin).height;
uint32_t width = cu.block(compBegin).width;
m_puiScanOrder = g_scanOrder[SCAN_UNGROUPED][(cu.useRotation[compBegin]) ? SCAN_TRAV_VER : SCAN_TRAV_HOR][gp_sizeIdxInfo->idxFrom(width)][gp_sizeIdxInfo->idxFrom(height)];
uint32_t total = height * width;
int lastRunPos = -1;
uint32_t lastRunType = 0;
uint32_t numIndices = 0;
std::vector<int> idxPos, parsedIdx;
idxPos.reserve(total);
parsedIdx.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)
{
idxPos.push_back(idx);
numIndices++;
}
lastRunType = runType.at(posx, posy);
run = runLength.at(posx, posy);
idx += run;
}
uint32_t currParam = 3 + ((indexMaxSize) >> 3);
uint32_t mappedValue;
assert(numIndices);
assert(numIndices > 0);
mappedValue = numIndices - 1;
m_BinEncoder.encodeRemAbsEP(mappedValue, currParam, false, MAX_NUM_CHANNEL_TYPE); // JC: code number of indices (PLT_RUN_INDEX)
auto idxPosEnd = idxPos.end();
for (auto iter = idxPos.begin(); iter != idxPosEnd; ++iter)
parsedIdx.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;
}
}
Yung-Hsuan Chao (Jessie)
committed
#if JVET_O1168_CU_CHROMA_QP_OFFSET
if ( cu.useEscape[compBegin] && cu.cs->slice->getUseChromaQpAdj() && !cuCtx.isChromaQpAdjCoded)
Yung-Hsuan Chao (Jessie)
committed
#else
if (cu.cs->slice->getUseChromaQpAdj() && !cu.transQuantBypass && !cuCtx.isChromaQpAdjCoded)
Yung-Hsuan Chao (Jessie)
committed
#endif
{
if (!CS::isDualITree(*tu.cs) || isChroma(tu.chType))
{
cu_chroma_qp_offset(cu);
cuCtx.isChromaQpAdjCoded = true;
}
}
uint32_t strPos = 0;
uint32_t endPos = height * width;
auto parsedIdxEnd = parsedIdx.end();
auto parsedIdxIter = parsedIdx.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 (numIndices && strPos < endPos - 1) // if numIndices (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());
}
}
}
if (runType.at(posx, posy) == PLT_RUN_INDEX)
{
if (parsedIdxIter != parsedIdxEnd)
curLevel = *parsedIdxIter++;
}
else
{
}
}
if (indexMaxSize > 1)
{
numIndices -= (runType.at(posx, posy) == PLT_RUN_INDEX);
cu_run_val(runLength.at(posx, posy) - 1, (PLTRunMode)runType.at(posx, posy), curLevel, endPos - strPos - numIndices - 1 - lastRunType);
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
}
}
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++)
{
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);
}
}
}
}
}
Yung-Hsuan Chao (Jessie)
committed
}
void CABACWriter::codeScanRotationModeFlag(const CodingUnit& cu, ComponentID compBegin)
{
m_BinEncoder.encodeBin((cu.useRotation[compBegin]), Ctx::RotationFlag());
Yung-Hsuan Chao (Jessie)
committed
}
void CABACWriter::xEncodePLTPredIndicator(const CodingUnit& cu, uint32_t maxPLTSize, ComponentID compBegin)
Yung-Hsuan Chao (Jessie)
committed
{
int lastPredIdx = -1;
uint32_t run = 0;
uint32_t numPLTPredicted = 0;
for (uint32_t idx = 0; idx < cu.lastPLTSize[compBegin]; idx++)
{
if (cu.reuseflag[compBegin][idx])
{
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 ((numPLTPredicted < maxPLTSize && lastPredIdx + 1 < cu.lastPLTSize[compBegin]) || !numPLTPredicted)
{
exp_golomb_eqprob(1, 0);
}
Yung-Hsuan Chao (Jessie)
committed
}
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 curLevel = (paletteIdx.at(posx, posy) == cu.curPLTSize[compBegin]) ? (maxSymbol - 1) : paletteIdx.at(posx, posy);
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)
{
Pel leftLevel = paletteIdx.at(prevposx, prevposy); // left index
if (leftLevel == cu.curPLTSize[compBegin]) // escape mode
leftLevel = maxSymbol - 1;
assert(leftLevel != curLevel);
if (curLevel > leftLevel)
}
}
else
{
if (cu.useRotation[compBegin])
{
assert(prevposx > 0);
aboveLevel = paletteIdx.at(posx - 1, posy);
if (paletteIdx.at(posx - 1, posy) == cu.curPLTSize[compBegin]) // escape mode
{
aboveLevel = maxSymbol - 1;
}
}
else
{
assert(prevposy > 0);
aboveLevel = paletteIdx.at(posx, posy - 1);
if (paletteIdx.at(posx, posy - 1) == cu.curPLTSize[compBegin]) // escape mode
{
aboveLevel = maxSymbol - 1;
}
}
assert(curLevel != aboveLevel);
if (curLevel > aboveLevel)
}
}
maxSymbol--;
}
assert(maxSymbol > 0);
assert(curLevel >= 0);
assert(maxSymbol > curLevel);
if (maxSymbol > 1)
{
xWriteTruncBinCode(curLevel, maxSymbol);
Yung-Hsuan Chao (Jessie)
committed
}
void CABACWriter::encodeRunType(const CodingUnit& cu, PLTtypeBuf& runType, uint32_t idx, ScanElement *refScanOrder, ComponentID compBegin)
{
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
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());
}
Yung-Hsuan Chao (Jessie)
committed
}

Karsten Suehring
committed
void CABACWriter::cu_run_val(uint32_t run, PLTRunMode runtype, const uint32_t paletteIdx, const uint32_t maxRun)
Yung-Hsuan Chao (Jessie)
committed
{
if (runtype == PLT_RUN_COPY)
{
}
else
{
g_ucRunLeftLut[0] = (paletteIdx < PLT_RUN_MSB_IDX_CTX_T1 ? 0 : (paletteIdx < PLT_RUN_MSB_IDX_CTX_T2 ? 1 : 2));
xWriteTruncMsbP1RefinementBits(run, runtype, maxRun, PLT_RUN_MSB_IDX_CABAC_BYPASS_THRE);
Yung-Hsuan Chao (Jessie)
committed
}
uint32_t CABACWriter::xWriteTruncMsbP1(uint32_t symbol, PLTRunMode runtype, uint32_t uiMax, uint32_t uiCtxT)
Yung-Hsuan Chao (Jessie)
committed
{
if (uiMax == 0)
return 0;
uint8_t *ctxLut;
ctxLut = (runtype == PLT_RUN_INDEX) ? g_ucRunLeftLut : g_ucRunTopLut;
uint32_t msbP1;
for (msbP1 = 0; symbol > 0; msbP1++)
symbol >>= 1;
if (msbP1 > uiCtxT)
{
m_BinEncoder.encodeBinEP(1);
}
else
m_BinEncoder.encodeBin(1, (msbP1 <= uiCtxT)
? ((runtype == PLT_RUN_INDEX) ? Ctx::IdxRunModel(ctxLut[msbP1]) : Ctx::CopyRunModel(ctxLut[msbP1]))
: ((runtype == PLT_RUN_INDEX) ? Ctx::IdxRunModel(ctxLut[uiCtxT]) : Ctx::CopyRunModel(ctxLut[uiCtxT])));
assert(msbP1 <= uiMax);
if (msbP1 < uiMax)
{
m_BinEncoder.encodeBinEP(0);
}
else
m_BinEncoder.encodeBin(0, msbP1 <= uiCtxT
? ((runtype == PLT_RUN_INDEX) ? Ctx::IdxRunModel(ctxLut[msbP1]) : Ctx::CopyRunModel(ctxLut[msbP1]))
: ((runtype == PLT_RUN_INDEX) ? Ctx::IdxRunModel(ctxLut[uiCtxT]) : Ctx::CopyRunModel(ctxLut[uiCtxT])));
//m_pcBinIf->encodeBin(0, msbP1 <= uiCtxT? pcSCModel[ctxLut[msbP1]] : pcSCModel[ctxLut[uiCtxT]]);
Yung-Hsuan Chao (Jessie)
committed
}

Karsten Suehring
committed
void CABACWriter::xWriteTruncMsbP1RefinementBits(uint32_t symbol, PLTRunMode runtype, uint32_t maxVal, uint32_t uiCtxT)
Yung-Hsuan Chao (Jessie)
committed
{
return;
uint32_t msbP1 = xWriteTruncMsbP1(symbol, runtype, g_getMsbP1Idx(maxVal), uiCtxT);
if (msbP1 > 1)
uint32_t numBins = g_getMsbP1Idx(maxVal);
if (msbP1 < numBins)
uint32_t bits = msbP1 - 1;
m_BinEncoder.encodeBinsEP(symbol & ((1 << bits) - 1), bits);
}
else
{
uint32_t curValue = 1 << (numBins - 1);
xWriteTruncBinCode(symbol - curValue, maxVal + 1 - curValue);
}
}
Yung-Hsuan Chao (Jessie)
committed
}

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

Karsten Suehring
committed
1850
1851
1852
1853
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
//================================================================================
// 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 );
}
}
}
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() );