Newer
Older
if (m_pcEncCfg->getReshaper() && (cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag()) && !cu.firstPU->mhIntraFlag && !cu.ibc)
{
cs.getRecoBuf().Y().rspSignal(m_pcReshape->getFwdLUT());
}
#endif

Karsten Suehring
committed
}
// add an empty TU
cs.addTU(CS::isDualITree(cs) ? cu : cs.area, partitioner.chType);

Karsten Suehring
committed
Distortion distortion = 0;
for (int comp = 0; comp < numValidComponents; comp++)
{
const ComponentID compID = ComponentID(comp);
if (compID == COMPONENT_Y && !luma)
continue;
if (compID != COMPONENT_Y && !chroma)
continue;

Karsten Suehring
committed
CPelBuf reco = cs.getRecoBuf (compID);
CPelBuf org = cs.getOrgBuf (compID);
#if WCG_EXT
#if JVET_M0427_INLOOP_RESHAPER
if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
m_pcEncCfg->getReshaper() && (cs.slice->getReshapeInfo().getUseSliceReshaper()&& m_pcReshape->getCTUFlag())))
#else

Karsten Suehring
committed
if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )

Karsten Suehring
committed
{
const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
#if JVET_M0427_INLOOP_RESHAPER
if (compID == COMPONENT_Y)
{
const CompArea &areaY = cu.Y();
CompArea tmpArea1(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
tmpRecLuma.copyFrom(reco);
tmpRecLuma.rspSignal(m_pcReshape->getInvLUT());
distortion += m_pcRdCost->getDistPart(org, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
}
else
#endif

Karsten Suehring
committed
distortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma );
}
else
#endif
distortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
}
m_CABACEstimator->resetBits();
if( pps.getTransquantBypassEnabledFlag() )
{
m_CABACEstimator->cu_transquant_bypass_flag( cu );
}
PredictionUnit &pu = *cs.getPU( partitioner.chType );
m_CABACEstimator->cu_skip_flag ( cu );
m_CABACEstimator->subblock_merge_flag( cu );
m_CABACEstimator->triangle_mode ( cu );
if (cu.mmvdSkip)
{
m_CABACEstimator->mmvd_merge_idx(pu);
}
else

Karsten Suehring
committed
m_CABACEstimator->merge_idx ( pu );
cs.dist = distortion;
cs.fracBits = m_CABACEstimator->getEstFracBits();
cs.cost = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
return;
}
// Residual coding.
if (luma)
{
cs.getResiBuf().bufs[0].copyFrom(cs.getOrgBuf().bufs[0]);
#if JVET_M0427_INLOOP_RESHAPER
if (cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag())
{
const CompArea &areaY = cu.Y();
CompArea tmpArea(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
PelBuf tmpPred = m_tmpStorageLCU.getBuf(tmpArea);
tmpPred.copyFrom(cs.getPredBuf(COMPONENT_Y));
tmpPred.rspSignal(m_pcReshape->getFwdLUT());
cs.getResiBuf(COMPONENT_Y).rspSignal(m_pcReshape->getFwdLUT());
cs.getResiBuf(COMPONENT_Y).subtract(tmpPred);
}
else
#endif
cs.getResiBuf().bufs[0].subtract(cs.getPredBuf().bufs[0]);
}
if (chroma)
{
cs.getResiBuf().bufs[1].copyFrom(cs.getOrgBuf().bufs[1]);
cs.getResiBuf().bufs[2].copyFrom(cs.getOrgBuf().bufs[2]);
cs.getResiBuf().bufs[1].subtract(cs.getPredBuf().bufs[1]);
cs.getResiBuf().bufs[2].subtract(cs.getPredBuf().bufs[2]);
}

Karsten Suehring
committed
Distortion zeroDistortion = 0;
const TempCtx ctxStart( m_CtxCache, m_CABACEstimator->getCtx() );
if (luma)
{
cs.getOrgResiBuf().bufs[0].copyFrom(cs.getResiBuf().bufs[0]);
}
if (chroma)
{
cs.getOrgResiBuf().bufs[1].copyFrom(cs.getResiBuf().bufs[1]);
cs.getOrgResiBuf().bufs[2].copyFrom(cs.getResiBuf().bufs[2]);
}
xEstimateInterResidualQT(cs, partitioner, &zeroDistortion, luma, chroma);

Karsten Suehring
committed
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
TransformUnit &firstTU = *cs.getTU( partitioner.chType );
cu.rootCbf = false;
m_CABACEstimator->resetBits();
m_CABACEstimator->rqt_root_cbf( cu );
const uint64_t zeroFracBits = m_CABACEstimator->getEstFracBits();
double zeroCost;
{
#if WCG_EXT
if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )
{
zeroCost = cs.isLossless ? ( cs.cost + 1 ) : m_pcRdCost->calcRdCost( zeroFracBits, zeroDistortion, false );
}
else
#endif
zeroCost = cs.isLossless ? ( cs.cost + 1 ) : m_pcRdCost->calcRdCost( zeroFracBits, zeroDistortion );
}
const int numValidTBlocks = ::getNumberValidTBlocks( *cs.pcv );
for (uint32_t i = 0; i < numValidTBlocks; i++)
{
cu.rootCbf |= TU::getCbfAtDepth(firstTU, ComponentID(i), 0);

Karsten Suehring
committed
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
}
// -------------------------------------------------------
// If a block full of 0's is efficient, then just use 0's.
// The costs at this point do not include header bits.
if (zeroCost < cs.cost || !cu.rootCbf)
{
cu.rootCbf = false;
cs.clearTUs();
// add a new "empty" TU spanning the whole CU
TransformUnit& tu = cs.addTU(cu, partitioner.chType);
for (int comp = 0; comp < numValidComponents; comp++)
{
tu.rdpcm[comp] = RDPCM_OFF;
}
cu.firstTU = cu.lastTU = &tu;
}
// all decisions now made. Fully encode the CU, including the headers:
m_CABACEstimator->getCtx() = ctxStart;
uint64_t finalFracBits = xGetSymbolFracBitsInter( cs, partitioner );
// we've now encoded the CU, and so have a valid bit cost
if (!cu.rootCbf)
{
if (luma)
{
cs.getResiBuf().bufs[0].fill(0); // Clear the residual image, if we didn't code it.
}
if (chroma)
{
cs.getResiBuf().bufs[1].fill(0); // Clear the residual image, if we didn't code it.
cs.getResiBuf().bufs[2].fill(0); // Clear the residual image, if we didn't code it.
}
}
if (luma)
{
#if JVET_M0427_INLOOP_RESHAPER
if (cu.rootCbf && cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag())
{
const CompArea &areaY = cu.Y();
CompArea tmpArea(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
PelBuf tmpPred = m_tmpStorageLCU.getBuf(tmpArea);
tmpPred.copyFrom(cs.getPredBuf(COMPONENT_Y));
tmpPred.rspSignal(m_pcReshape->getFwdLUT());
cs.getRecoBuf(COMPONENT_Y).reconstruct(tmpPred, cs.getResiBuf(COMPONENT_Y), cs.slice->clpRng(COMPONENT_Y));
}
else
{
#endif
cs.getRecoBuf().bufs[0].reconstruct(cs.getPredBuf().bufs[0], cs.getResiBuf().bufs[0], cs.slice->clpRngs().comp[0]);
#if JVET_M0427_INLOOP_RESHAPER
if (cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag() && !cu.firstPU->mhIntraFlag && !cu.ibc)
{
cs.getRecoBuf().bufs[0].rspSignal(m_pcReshape->getFwdLUT());
}
}
#endif
}
if (chroma)
{
cs.getRecoBuf().bufs[1].reconstruct(cs.getPredBuf().bufs[1], cs.getResiBuf().bufs[1], cs.slice->clpRngs().comp[1]);
cs.getRecoBuf().bufs[2].reconstruct(cs.getPredBuf().bufs[2], cs.getResiBuf().bufs[2], cs.slice->clpRngs().comp[2]);
}

Karsten Suehring
committed
// update with clipped distortion and cost (previously unclipped reconstruction values were used)
Distortion finalDistortion = 0;
for (int comp = 0; comp < numValidComponents; comp++)
{
const ComponentID compID = ComponentID(comp);
if (compID == COMPONENT_Y && !luma)
continue;
if (compID != COMPONENT_Y && !chroma)
continue;

Karsten Suehring
committed
CPelBuf reco = cs.getRecoBuf (compID);
CPelBuf org = cs.getOrgBuf (compID);
#if WCG_EXT
#if JVET_M0427_INLOOP_RESHAPER
if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (
m_pcEncCfg->getReshaper() && (cs.slice->getReshapeInfo().getUseSliceReshaper() && m_pcReshape->getCTUFlag() ) ) )
#else

Karsten Suehring
committed
if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() )

Karsten Suehring
committed
{
const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
#if JVET_M0427_INLOOP_RESHAPER
if (compID == COMPONENT_Y)
{
const CompArea &areaY = cu.Y();
CompArea tmpArea1(COMPONENT_Y, areaY.chromaFormat, Position(0, 0), areaY.size());
PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
tmpRecLuma.copyFrom(reco);
tmpRecLuma.rspSignal(m_pcReshape->getInvLUT());
finalDistortion += m_pcRdCost->getDistPart(org, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
}
else
#endif
finalDistortion += m_pcRdCost->getDistPart(org, reco, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);

Karsten Suehring
committed
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
}
else
#endif
{
finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE );
}
}
cs.dist = finalDistortion;
cs.fracBits = finalFracBits;
cs.cost = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
CHECK(cs.tus.size() == 0, "No TUs present");
}
uint64_t InterSearch::xGetSymbolFracBitsInter(CodingStructure &cs, Partitioner &partitioner)
{
uint64_t fracBits = 0;
CodingUnit &cu = *cs.getCU( partitioner.chType );
m_CABACEstimator->resetBits();

Karsten Suehring
committed
{
cu.skip = true;
if( cs.pps->getTransquantBypassEnabledFlag() )
{
m_CABACEstimator->cu_transquant_bypass_flag( cu );
}
m_CABACEstimator->cu_skip_flag ( cu );
m_CABACEstimator->subblock_merge_flag( cu );
m_CABACEstimator->triangle_mode ( cu );
if (cu.mmvdSkip)
{
m_CABACEstimator->mmvd_merge_idx(*cu.firstPU);
}
else

Karsten Suehring
committed
m_CABACEstimator->merge_idx ( *cu.firstPU );
fracBits += m_CABACEstimator->getEstFracBits();
}
else
{
CHECK( cu.skip, "Skip flag has to be off at this point!" );
if( cs.pps->getTransquantBypassEnabledFlag() )
{
m_CABACEstimator->cu_transquant_bypass_flag( cu );
}

Karsten Suehring
committed
m_CABACEstimator->cu_skip_flag( cu );
m_CABACEstimator->pred_mode ( cu );
m_CABACEstimator->cu_pred_data( cu );
CUCtx cuCtx;
cuCtx.isDQPCoded = true;
cuCtx.isChromaQpAdjCoded = true;
m_CABACEstimator->cu_residual ( cu, partitioner, cuCtx );
fracBits += m_CABACEstimator->getEstFracBits();
}
return fracBits;
}
double InterSearch::xGetMEDistortionWeight(uint8_t gbiIdx, RefPicList eRefPicList)
{
if( gbiIdx != GBI_DEFAULT )
{
return fabs((double)getGbiWeight(gbiIdx, eRefPicList) / (double)g_GbiWeightBase);
}
else
{
return 0.5;
}
}
bool InterSearch::xReadBufferedUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv& pcMvPred, Mv& rcMv, uint32_t& ruiBits, Distortion& ruiCost)
{
if (m_uniMotions.isReadMode((uint32_t)eRefPicList, (uint32_t)iRefIdx))
m_uniMotions.copyTo(rcMv, ruiCost, (uint32_t)eRefPicList, (uint32_t)iRefIdx);
m_pcRdCost->setPredictor(pcMvPred);
m_pcRdCost->setCostScale(0);
unsigned imvShift = pu.cu->imv << 1;
uint32_t uiMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(rcMv.getHor(), rcMv.getVer(), imvShift);
ruiBits += uiMvBits;
ruiCost += m_pcRdCost->getCost(ruiBits);
return true;
}
return false;
}
bool InterSearch::xReadBufferedAffineUniMv(PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv acMvPred[3], Mv acMv[3], uint32_t& ruiBits, Distortion& ruiCost)
{
if (m_uniMotions.isReadModeAffine((uint32_t)eRefPicList, (uint32_t)iRefIdx, pu.cu->affineType))
m_uniMotions.copyAffineMvTo(acMv, ruiCost, (uint32_t)eRefPicList, (uint32_t)iRefIdx, pu.cu->affineType);
m_pcRdCost->setCostScale(0);
uint32_t uiMvBits = 0;
for (int iVerIdx = 0; iVerIdx<(pu.cu->affineType ? 3 : 2); iVerIdx++)
{
if (iVerIdx)
{
m_pcRdCost->setPredictor(acMvPred[iVerIdx] + acMv[0] - acMvPred[0]);
}
else
{
m_pcRdCost->setPredictor(acMvPred[iVerIdx]);
}
uiMvBits += m_pcRdCost->getBitsOfVectorWithPredictor(acMv[iVerIdx].getHor(), acMv[iVerIdx].getVer(), 0);
}
ruiBits += uiMvBits;
ruiCost += m_pcRdCost->getCost(ruiBits);
return true;
}
return false;
}
void InterSearch::initWeightIdxBits()
{
for (int n = 0; n < GBI_NUM; ++n)
{
m_estWeightIdxBits[n] = deriveWeightIdxBits(n);
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
void InterSearch::xClipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS& sps )
{
int mvShift = MV_FRACTIONAL_BITS_INTERNAL;
int offset = 8;
int horMax = ( sps.getPicWidthInLumaSamples() + offset - ( int ) pos.x - 1 ) << mvShift;
int horMin = ( -( int ) sps.getMaxCUWidth() - offset - ( int ) pos.x + 1 ) << mvShift;
int verMax = ( sps.getPicHeightInLumaSamples() + offset - ( int ) pos.y - 1 ) << mvShift;
int verMin = ( -( int ) sps.getMaxCUHeight() - offset - ( int ) pos.y + 1 ) << mvShift;
if( sps.getWrapAroundEnabledFlag() )
{
int horMax = ( sps.getPicWidthInLumaSamples() + sps.getMaxCUWidth() - size.width + offset - ( int ) pos.x - 1 ) << mvShift;
int horMin = ( -( int ) sps.getMaxCUWidth() - offset - ( int ) pos.x + 1 ) << mvShift;
rcMv.setHor( std::min( horMax, std::max( horMin, rcMv.getHor() ) ) );
rcMv.setVer( std::min( verMax, std::max( verMin, rcMv.getVer() ) ) );
return;
}
rcMv.setHor( std::min( horMax, std::max( horMin, rcMv.getHor() ) ) );
rcMv.setVer( std::min( verMax, std::max( verMin, rcMv.getVer() ) ) );
}
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
#if JVET_M0444_SMVD
void InterSearch::symmvdCheckBestMvp(
PredictionUnit& pu,
PelUnitBuf& origBuf,
Mv curMv,
RefPicList curRefList,
AMVPInfo amvpInfo[2][33],
int32_t gbiIdx,
Mv cMvPredSym[2],
int32_t mvpIdxSym[2],
Distortion& bestCost,
bool skip
)
{
RefPicList tarRefList = (RefPicList)(1 - curRefList);
int32_t refIdxCur = pu.cu->slice->getSymRefIdx(curRefList);
int32_t refIdxTar = pu.cu->slice->getSymRefIdx(tarRefList);
MvField cCurMvField, cTarMvField;
cCurMvField.setMvField(curMv, refIdxCur);
AMVPInfo& amvpCur = amvpInfo[curRefList][refIdxCur];
AMVPInfo& amvpTar = amvpInfo[tarRefList][refIdxTar];
m_pcRdCost->setCostScale(0);
// get prediction of eCurRefPicList
PelUnitBuf predBufA = m_tmpPredStorage[curRefList].getBuf(UnitAreaRelative(*pu.cu, pu));
const Picture* picRefA = pu.cu->slice->getRefPic(curRefList, cCurMvField.refIdx);
Mv mvA = cCurMvField.mv;
mvA.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
clipMv(mvA, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps);
xPredInterBlk(COMPONENT_Y, pu, picRefA, mvA, predBufA, true, pu.cu->slice->clpRng(COMPONENT_Y), false, false);
int32_t skipMvpIdx[2];
skipMvpIdx[0] = skip ? mvpIdxSym[0] : -1;
skipMvpIdx[1] = skip ? mvpIdxSym[1] : -1;
for (int i = 0; i < amvpCur.numCand; i++)
{
for (int j = 0; j < amvpTar.numCand; j++)
{
if (skipMvpIdx[curRefList] == i && skipMvpIdx[tarRefList] == j)
continue;
cTarMvField.setMvField(curMv.getSymmvdMv(amvpCur.mvCand[i], amvpTar.mvCand[j]), refIdxTar);
// get prediction of eTarRefPicList
PelUnitBuf predBufB = m_tmpPredStorage[tarRefList].getBuf(UnitAreaRelative(*pu.cu, pu));
const Picture* picRefB = pu.cu->slice->getRefPic(tarRefList, cTarMvField.refIdx);
Mv mvB = cTarMvField.mv;
mvB.changePrecision(MV_PRECISION_QUARTER, MV_PRECISION_INTERNAL);
clipMv(mvB, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps);
xPredInterBlk(COMPONENT_Y, pu, picRefB, mvB, predBufB, true, pu.cu->slice->clpRng(COMPONENT_Y), false, false);
PelUnitBuf bufTmp = m_tmpStorageLCU.getBuf(UnitAreaRelative(*pu.cu, pu));
if (gbiIdx != GBI_DEFAULT)
bufTmp.Y().addWeightedAvg(predBufA.Y(), predBufB.Y(), pu.cu->slice->clpRng(COMPONENT_Y), gbiIdx);
else
bufTmp.Y().addAvg(predBufA.Y(), predBufB.Y(), pu.cu->slice->clpRng(COMPONENT_Y));
// calc distortion
Distortion cost = m_pcRdCost->getDistPart(bufTmp.Y(), origBuf.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, DF_HAD);
m_pcRdCost->setPredictor(amvpCur.mvCand[i]);
uint32_t bits = m_pcRdCost->getBitsOfVectorWithPredictor(curMv.hor, curMv.ver, (pu.cu->imv << 1));
bits += m_auiMVPIdxCost[i][AMVP_MAX_NUM_CANDS];
bits += m_auiMVPIdxCost[j][AMVP_MAX_NUM_CANDS];
cost += m_pcRdCost->getCost(bits);
if (cost < bestCost)
{
bestCost = cost;
cMvPredSym[curRefList] = amvpCur.mvCand[i];
cMvPredSym[tarRefList] = amvpTar.mvCand[j];
mvpIdxSym[curRefList] = i;
mvpIdxSym[tarRefList] = j;
}
}
}
}
#endif