Newer
Older

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;
}
}
{
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;
}
}
{
CHECK(mpm_idx >= numMPMs, "use of non-MPM");
}
else
{
m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
}

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

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

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

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

Karsten Suehring
committed
}
}
}
void CABACWriter::intra_chroma_pred_modes( const CodingUnit& cu )
{
if( cu.chromaFormat == CHROMA_400 || ( cu.isSepTree() && cu.chType == CHANNEL_TYPE_LUMA ) )

Karsten Suehring
committed
{
return;
}
const PredictionUnit* pu = cu.firstPU;
intra_chroma_pred_mode( *pu );
}
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
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
void CABACWriter::intra_chroma_lmc_mode(const PredictionUnit& pu)
{
const unsigned intraDir = pu.intraDir[1];
int lmModeList[10];
PU::getLMSymbolList(pu, lmModeList);
int symbol = -1;
for (int k = 0; k < LM_SYMBOL_NUM; k++)
{
if (lmModeList[k] == intraDir)
{
symbol = k;
break;
}
}
CHECK(symbol < 0, "invalid symbol found");
m_BinEncoder.encodeBin(symbol == 0 ? 0 : 1, Ctx::IntraChromaPredMode(0));
if (symbol > 0)
{
CHECK(symbol > 2, "invalid symbol for MMLM");
unsigned int symbol_minus_1 = symbol - 1;
m_BinEncoder.encodeBinEP(symbol_minus_1);
}
}
void CABACWriter::intra_chroma_pred_mode(const PredictionUnit& pu)
{
const unsigned intraDir = pu.intraDir[1];
if (pu.cs->sps->getUseLMChroma() && pu.cu->checkCCLMAllowed())
{
m_BinEncoder.encodeBin(PU::isLMCMode(intraDir) ? 1 : 0, Ctx::CclmModeFlag(0));
if (PU::isLMCMode(intraDir))
{
intra_chroma_lmc_mode(pu);
return;
}
}
const bool isDerivedMode = intraDir == DM_CHROMA_IDX;
m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
if (isDerivedMode)
{
return;
}
// chroma candidate index
unsigned chromaCandModes[NUM_CHROMA_MODE];
PU::getIntraChromaCandModes(pu, chromaCandModes);

Karsten Suehring
committed
int candId = 0;
for (; candId < NUM_CHROMA_MODE; candId++)
{
if (intraDir == chromaCandModes[candId])
{
break;
}
}

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

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

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

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

Karsten Suehring
committed
if( !cu.rootCbf )
{
return;
}
}
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] = false;
cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;

Karsten Suehring
committed
if( cu.ispMode && isLuma( partitioner.chType ) )
{
TUIntraSubPartitioner subTuPartitioner( partitioner );
transform_tree( *cu.cs, subTuPartitioner, cuCtx, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType) ), 0 );
}
else
{
transform_tree( *cu.cs, partitioner, cuCtx );
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 );
}
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
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
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
&& ( !cu.isSepTree() || cu.chromaFormat == CHROMA_400 || isChroma( cu.chType ) )

Karsten Suehring
committed
)
{
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 );
}
}
}
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);
TransformUnit& tu = *cu.firstTU;
uint32_t indexMaxSize = cu.useEscape[compBegin] ? (cu.curPLTSize[compBegin] + 1) : cu.curPLTSize[compBegin];

Karsten Suehring
committed
if (cu.lastPLTSize[compBegin])
{
xEncodePLTPredIndicator(cu, MAXPLTSIZE, compBegin);
}

Karsten Suehring
committed
uint32_t reusedPLTnum = 0;
for (int idx = 0; idx < cu.lastPLTSize[compBegin]; idx++)
{
if (cu.reuseflag[compBegin][idx])
reusedPLTnum++;
}

Karsten Suehring
committed
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;
Yin Zhao
committed
m_scanOrder = 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_scanOrder[idx].y;
uint32_t posx = m_scanOrder[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]);
}
Yin Zhao
committed
if (cu.useEscape[compBegin] && cu.cs->pps->getUseDQP() && !cuCtx.isDQPCoded)
{
{
cu_qp_delta(cu, cuCtx.qp, cu.qp);
cuCtx.qp = cu.qp;
cuCtx.isDQPCoded = true;
}
}
if ( cu.useEscape[compBegin] && cu.cs->slice->getUseChromaQpAdj() && !cuCtx.isChromaQpAdjCoded)
{
if (!CS::isDualITree(*tu.cs) || isChroma(tu.chType))
{
cu_chroma_qp_offset(cu);
cuCtx.isChromaQpAdjCoded = true;
}
}
Yin Zhao
committed
uint32_t strPos = 0;
uint32_t endPos = height * width;
auto parsedIdxEnd = parsedIdx.end();
auto parsedIdxIter = parsedIdx.begin();
while (strPos < endPos)
{
uint32_t posy = m_scanOrder[strPos].y;
uint32_t posx = m_scanOrder[strPos].x;
uint32_t posyprev = strPos == 0 ? 0 : m_scanOrder[strPos - 1].y;
uint32_t posxprev = strPos == 0 ? 0 : m_scanOrder[strPos - 1].x;
Yin Zhao
committed
if (indexMaxSize > 1)
{
if (((posy == 0) && !cu.useRotation[compBegin]) || ((posx == 0) && cu.useRotation[compBegin]))
Yin Zhao
committed
{
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
{
Frank Bossen
committed
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());
}
}
}
Yin Zhao
committed
if (runType.at(posx, posy) == PLT_RUN_INDEX)
{
if (parsedIdxIter != parsedIdxEnd)
curLevel = *parsedIdxIter++;
}
else
{
}
}
Yin Zhao
committed
if (indexMaxSize > 1)
{
numIndices -= (runType.at(posx, posy) == PLT_RUN_INDEX);
Frank Bossen
committed
cu_run_val(runLength.at(posx, posy) - 1, (PLTRunMode)runType.at(posx, posy), curLevel, endPos - strPos - numIndices - 1 - lastRunType);
Yin Zhao
committed
Yin Zhao
committed
strPos += (runLength.at(posx, posy));
}
assert(strPos == endPos);
Yin Zhao
committed
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_scanOrder[strPos].y;
uint32_t posx = m_scanOrder[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_scanOrder[idx].y;
uint32_t posx = m_scanOrder[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_scanOrder[idx - 1].y;
uint32_t prevposx = m_scanOrder[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)
{
if (refScanOrder)
{
uint32_t posy = m_scanOrder[idx].y;
uint32_t posx = m_scanOrder[idx].x;
uint32_t posyprev = (idx == 0) ? 0 : m_scanOrder[idx - 1].y;
uint32_t posxprev = (idx == 0) ? 0 : m_scanOrder[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_paletteRunLeftLut[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;
ctxLut = (runtype == PLT_RUN_INDEX) ? g_paletteRunLeftLut : g_paletteRunTopLut;
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;
Yung-Hsuan Chao (Jessie)
committed
uint32_t msbP1 = xWriteTruncMsbP1(symbol, runtype, floorLog2(maxVal) + 1, uiCtxT);
Yung-Hsuan Chao (Jessie)
committed
uint32_t numBins = floorLog2(maxVal) + 1;
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
//================================================================================
// 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 )
{
CHECK( pu.cu->treeType == TREE_C, "cannot be chroma CU" );

Karsten Suehring
committed
#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 )
{

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
{
CHECK( pu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" );
}
else

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

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

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

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

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

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

Karsten Suehring
committed
}
}

Karsten Suehring
committed
mvp_flag ( pu, REF_PIC_LIST_1 );
}
}
}
void CABACWriter::smvd_mode( const PredictionUnit& pu )
{
if ( pu.interDir != 3 || pu.cu->affine )
{
return;
}
if ( pu.cs->slice->getBiDirPred() == false )
{
return;
}
m_BinEncoder.encodeBin( pu.cu->smvdMode ? 1 : 0, Ctx::SmvdFlag() );
DTRACE( g_trace_ctx, D_SYNTAX, "symmvd_flag() symmvd=%d pos=(%d,%d) size=%dx%d\n", pu.cu->smvdMode ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height );
}
void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
{
Ruoyang Yu
committed
if ( !cu.cs->slice->isIntra() && (cu.slice->getMaxNumAffineMergeCand() > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
{
unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
Tangi Poirier
committed
m_BinEncoder.encodeBin( cu.affine, Ctx::SubblockMergeFlag( 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 );

Karsten Suehring
committed
}
void CABACWriter::merge_data(const PredictionUnit& pu)
{
if (CU::isIBC(*pu.cu))
{
merge_idx(pu);
return;
}
subblock_merge_flag(*pu.cu);
if (pu.cu->affine)
{
merge_idx(pu);
return;
}
const bool triangleAvailable = pu.cu->cs->slice->getSPS()->getUseTriangle() && pu.cu->cs->slice->isInterB() && pu.cu->cs->slice->getMaxNumTriangleCand() > 1;
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
const bool ciipAvailable = pu.cs->sps->getUseMHIntra() && !pu.cu->skip && pu.cu->lwidth() < MAX_CU_SIZE && pu.cu->lheight() < MAX_CU_SIZE;
if (pu.cu->lwidth() * pu.cu->lheight() >= 64
&& (triangleAvailable || ciipAvailable))
{
m_BinEncoder.encodeBin(pu.regularMergeFlag, Ctx::RegularMergeFlag(pu.cu->skip ? 0 : 1));
}
if (pu.regularMergeFlag)
{
if (pu.cs->sps->getUseMMVD())
{
m_BinEncoder.encodeBin(pu.mmvdMergeFlag, Ctx::MmvdFlag(0));
DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", pu.mmvdMergeFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height);
}
if (pu.mmvdMergeFlag || pu.cu->mmvdSkip)
{
mmvd_merge_idx(pu);
}
else
{
merge_idx(pu);
}
}
else
{
if (triangleAvailable && ciipAvailable)
{
MHIntra_flag(pu);
}
merge_idx(pu);
}

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

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

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

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

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

Karsten Suehring
committed
{