Newer
Older
m_testAMTForFullRD[i] = coeffAbsSum[i].first;
#if JVET_Y0142_ADAPT_INTRA_MTS
m_numCandAMTForFullRD = nCands;
#else
#endif
#if !JVET_Y0142_ADAPT_INTRA_MTS
if (m_pcEncCfg->getUseFastLFNST())
{
double skipThreshold = 1.0 + 1.0 / sqrt((double)(area.width*area.height));
skipThreshold = std::max(skipThreshold, 1.03);
for (int i = 1; i < m_numCandAMTForFullRD; i++)
{
if (coeffAbsSum[i].second > skipThreshold * coeffAbsSum[0].second)
{
m_numCandAMTForFullRD = i;
break;
}
}
}

Karsten Suehring
committed
void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &compID, Distortion& ruiDist, const int &default0Save1Load2, uint32_t* numSig, std::vector<TrMode>* trModes, const bool loadTr)

Karsten Suehring
committed
{
if (!tu.blocks[compID].valid())
{
return;
}
CodingStructure &cs = *tu.cs;
m_pcRdCost->setChromaFormat(cs.sps->getChromaFormatIdc());

Karsten Suehring
committed
const CompArea &area = tu.blocks[compID];
const SPS &sps = *cs.sps;
#if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER

Karsten Suehring
committed
const ChannelType chType = toChannelType(compID);
const int bitDepth = sps.getBitDepth(chType);
PelBuf piOrg = cs.getOrgBuf (area);
PelBuf piPred = cs.getPredBuf (area);
PelBuf piResi = cs.getResiBuf (area);
PelBuf piReco = cs.getRecoBuf (area);
const PredictionUnit &pu = *cs.getPU(area.pos(), chType);
const uint32_t uiChFinalMode = PU::getFinalIntraMode(pu, chType);
//===== init availability pattern =====
CHECK( tu.jointCbCr && compID == COMPONENT_Cr, "wrong combination of compID and jointCbCr" );
bool jointCbCr = tu.jointCbCr && compID == COMPONENT_Cb;

Xiaoyu Xiu
committed
if (compID == COMPONENT_Y)

Karsten Suehring
committed
PelBuf sharedPredTS( m_pSharedPredTransformSkip[compID], area );
if( default0Save1Load2 != 2 )

Karsten Suehring
committed
bool predRegDiffFromTB = CU::isPredRegDiffFromTB(*tu.cu, compID);
bool firstTBInPredReg = CU::isFirstTBInPredReg(*tu.cu, compID, area);
CompArea areaPredReg(COMPONENT_Y, tu.chromaFormat, area);
if (tu.cu->ispMode && isLuma(compID))

Karsten Suehring
committed
if (predRegDiffFromTB)

Karsten Suehring
committed
if (firstTBInPredReg)
{
CU::adjustPredArea(areaPredReg);
initIntraPatternChTypeISP(*tu.cu, areaPredReg, piReco);
}

Karsten Suehring
committed
else

Karsten Suehring
committed
initIntraPatternChTypeISP(*tu.cu, area, piReco);

Karsten Suehring
committed
{

Karsten Suehring
committed
initIntraPatternChType(*tu.cu, area);

Karsten Suehring
committed
}

Karsten Suehring
committed
//===== get prediction signal =====
if(compID != COMPONENT_Y && !tu.cu->bdpcmModeChroma && PU::isLMCMode(uiChFinalMode))

Karsten Suehring
committed
xGetLumaRecPixels( pu, area );
predIntraChromaLM( compID, piPred, pu, area, uiChFinalMode );
#if JVET_V0130_INTRA_TMP
if( PU::isTmp( pu, chType ) )
{
int foundCandiNum;
RefTemplateType tempType = getRefTemplateType( *(tu.cu), tu.cu->blocks[COMPONENT_Y] );
if( tempType != NO_TEMPLATE )
getTargetTemplate( tu.cu, pu.lwidth(), pu.lheight(), tempType );
candidateSearchIntra( tu.cu, pu.lwidth(), pu.lheight(), tempType );
generateTMPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum );
generateTmDcPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), 1 << (tu.cu->cs->sps->getBitDepth( CHANNEL_TYPE_LUMA ) - 1) );
getTargetTemplate( tu.cu, pu.lwidth(), pu.lheight() );
candidateSearchIntra( tu.cu, pu.lwidth(), pu.lheight() );
generateTMPrediction( piPred.buf, piPred.stride, pu.lwidth(), pu.lheight(), foundCandiNum );
CHECK( foundCandiNum < 1, "" );
}
else if( PU::isMIP( pu, chType ) )

Karsten Suehring
committed
if( PU::isMIP( pu, chType ) )
Adarsh Krishnan Ramasubramonian
committed
{

Karsten Suehring
committed
initIntraMip( pu, area );
predIntraMip( compID, piPred, pu );
}
else
{
if (predRegDiffFromTB)
{
if (firstTBInPredReg)
{
PelBuf piPredReg = cs.getPredBuf(areaPredReg);
predIntraAng(compID, piPredReg, pu);
}
}
else
Adarsh Krishnan Ramasubramonian
committed
{

Karsten Suehring
committed
predIntraAng(compID, piPred, pu);
Adarsh Krishnan Ramasubramonian
committed
}
}

Karsten Suehring
committed

Karsten Suehring
committed
// save prediction
if( default0Save1Load2 == 1 )
{
sharedPredTS.copyFrom( piPred );
}
}
else

Karsten Suehring
committed
{

Karsten Suehring
committed
// load prediction
piPred.copyFrom( sharedPredTS );

Karsten Suehring
committed
}
}
DTRACE( g_trace_ctx, D_PRED, "@(%4d,%4d) [%2dx%2d] IMode=%d\n", tu.lx(), tu.ly(), tu.lwidth(), tu.lheight(), uiChFinalMode );
//DTRACE_PEL_BUF( D_PRED, piPred, tu, tu.cu->predMode, COMPONENT_Y );
bool flag = slice.getLmcsEnabledFlag() && (slice.isIntra() || (!slice.isIntra() && m_pcReshape->getCTUFlag()));
#if JVET_W0103_INTRA_MTS
if (!tu.cu->mtsFlag && isLuma(compID))
#else
if (isLuma(compID))

Karsten Suehring
committed
//===== get residual signal =====
piResi.copyFrom( piOrg );
if (slice.getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)

Karsten Suehring
committed
{
piResi.rspSignal( m_pcReshape->getFwdLUT() );
piResi.subtract( piPred );

Karsten Suehring
committed
}
else
{
piResi.subtract( piPred );
}

Karsten Suehring
committed
//===== transform and quantization =====
//--- init rate estimation arrays for RDOQ ---
//--- transform and quantization ---
TCoeff uiAbsSum = 0;
const QpParam cQP(tu, compID);
#if RDOQ_CHROMA_LAMBDA
m_pcTrQuant->selectLambda(compID);
#endif
flag =flag && (tu.blocks[compID].width*tu.blocks[compID].height > 4);
if (flag && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() )
double cResScale = (double)(1 << CSCALE_FP_PREC) / (double)cResScaleInv;
m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cResScale*cResScale));
PelBuf crOrg;
PelBuf crPred;
PelBuf crResi;
PelBuf crReco;
if (isChroma(compID))
{
const CompArea &crArea = tu.blocks[ COMPONENT_Cr ];
crOrg = cs.getOrgBuf ( crArea );
crPred = cs.getPredBuf ( crArea );
crResi = cs.getResiBuf ( crArea );
crReco = cs.getRecoBuf ( crArea );
}
if ( jointCbCr )
{
// Lambda is loosened for the joint mode with respect to single modes as the same residual is used for both chroma blocks
const int absIct = abs( TU::getICTMode(tu) );
const double lfact = ( absIct == 1 || absIct == 3 ? 0.8 : 0.5 );
m_pcTrQuant->setLambda( lfact * m_pcTrQuant->getLambda() );
if ( sps.getJointCbCrEnabledFlag() && isChroma(compID) && (tu.cu->cs->slice->getSliceQp() > 18) )
{
m_pcTrQuant->setLambda( 1.3 * m_pcTrQuant->getLambda() );
}
if( isLuma(compID) )
{
#if JVET_Y0142_ADAPT_INTRA_MTS
m_pcTrQuant->transformNxN(tu, compID, cQP, trModes, 8);
#else
m_pcTrQuant->transformNxN(tu, compID, cQP, trModes, m_pcEncCfg->getMTSIntraMaxCand());
tu.mtsIdx[compID] = trModes->at(0).first;
if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) || tu.cu->bdpcmMode != 0)
{
m_pcTrQuant->transformNxN(tu, compID, cQP, uiAbsSum, m_CABACEstimator->getCtx(), loadTr);
}

Karsten Suehring
committed
DTRACE(g_trace_ctx, D_TU_ABS_SUM, "%d: comp=%d, abssum=%d\n", DTRACE_GET_COUNTER(g_trace_ctx, D_TU_ABS_SUM), compID,
uiAbsSum);

Karsten Suehring
committed
if (tu.cu->ispMode && isLuma(compID) && CU::isISPLast(*tu.cu, area, area.compID) && CU::allLumaCBFsAreZero(*tu.cu))
{
// ISP has to have at least one non-zero CBF
ruiDist = MAX_INT;
return;
}
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
#if JVET_Y0142_ADAPT_INTRA_MTS
if (isLuma(compID) && tu.mtsIdx[compID] >= MTS_DST7_DST7)
{
bool signHiding = cs.slice->getSignDataHidingEnabledFlag();
CoeffCodingContext cctx(tu, compID, signHiding);
const TCoeff* coeff = tu.getCoeffs(compID).buf;
int scanPosLast = -1;
uint64_t coeffAbsSum = 0;
for (int scanPos = 0; scanPos < cctx.maxNumCoeff(); scanPos++)
{
unsigned blkPos = cctx.blockPos(scanPos);
if (coeff[blkPos])
{
scanPosLast = scanPos;
coeffAbsSum += abs(coeff[blkPos]);
}
}
int nCands = (coeffAbsSum > MTS_TH_COEFF[1]) ? MTS_NCANDS[2] : (coeffAbsSum > MTS_TH_COEFF[0]) ? MTS_NCANDS[1] : MTS_NCANDS[0];
bool isInvalid = (scanPosLast <= 0) || ((tu.mtsIdx[COMPONENT_Y] - MTS_DST7_DST7) >= nCands);
if (isInvalid)
{
m_validMTSReturn = false;
ruiDist = MAX_INT;
return;
}
}
#endif
if ((m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0)
&& 0 == tu.cu->bdpcmMode)
{
uiAbsSum = 0;
tu.getCoeffs(compID).fill(0);
TU::setCbfAtDepth(tu, compID, tu.depth, 0);
}

Karsten Suehring
committed
//--- inverse transform ---
if (uiAbsSum > 0)
{
m_pcTrQuant->invTransformNxN(tu, compID, piResi, cQP);
}
else
{
piResi.fill(0);
}
}
else // chroma
{
int codedCbfMask = 0;

Christian Helmrich
committed
ComponentID codeCompId = (tu.jointCbCr ? (tu.jointCbCr >> 1 ? COMPONENT_Cb : COMPONENT_Cr) : compID);
const QpParam qpCbCr(tu, codeCompId);
if( tu.jointCbCr )
{
ComponentID otherCompId = ( codeCompId==COMPONENT_Cr ? COMPONENT_Cb : COMPONENT_Cr );
tu.getCoeffs( otherCompId ).fill(0); // do we need that?
TU::setCbfAtDepth (tu, otherCompId, tu.depth, false );
}
PelBuf& codeResi = ( codeCompId == COMPONENT_Cr ? crResi : piResi );
uiAbsSum = 0;
m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, trModes, m_pcEncCfg->getMTSIntraMaxCand());
tu.mtsIdx[codeCompId] = trModes->at(0).first;
if (tu.jointCbCr)
{
tu.mtsIdx[(codeCompId == COMPONENT_Cr) ? COMPONENT_Cb : COMPONENT_Cr] = MTS_DCT2_DCT2;
}
}
// encoder bugfix: Set loadTr to aovid redundant transform process
if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) || tu.cu->bdpcmModeChroma != 0)
Takeshi Tsukuba
committed
{
m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, uiAbsSum, m_CABACEstimator->getCtx(), loadTr);
}
if ((m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) && 0 == tu.cu->bdpcmModeChroma)
Takeshi Tsukuba
committed
{
uiAbsSum = 0;
tu.getCoeffs(compID).fill(0);
TU::setCbfAtDepth(tu, compID, tu.depth, 0);
}
DTRACE( g_trace_ctx, D_TU_ABS_SUM, "%d: comp=%d, abssum=%d\n", DTRACE_GET_COUNTER( g_trace_ctx, D_TU_ABS_SUM ), codeCompId, uiAbsSum );
if( uiAbsSum > 0 )
{

Christian Helmrich
committed
m_pcTrQuant->invTransformNxN(tu, codeCompId, codeResi, qpCbCr);
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
codedCbfMask += ( codeCompId == COMPONENT_Cb ? 2 : 1 );
}
else
{
codeResi.fill(0);
}
if( tu.jointCbCr )
{
if( tu.jointCbCr == 3 && codedCbfMask == 2 )
{
codedCbfMask = 3;
TU::setCbfAtDepth (tu, COMPONENT_Cr, tu.depth, true );
}
if( tu.jointCbCr != codedCbfMask )
{
ruiDist = std::numeric_limits<Distortion>::max();
return;
}
m_pcTrQuant->invTransformICT( tu, piResi, crResi );
uiAbsSum = codedCbfMask;
}
}

Karsten Suehring
committed
//===== reconstruction =====
if ( flag && uiAbsSum > 0 && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag() )
piResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(compID));
if( jointCbCr )
{
crResi.scaleSignal(tu.getChromaAdj(), 0, tu.cu->cs->slice->clpRng(COMPONENT_Cr));
}

Karsten Suehring
committed
if (slice.getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() && compID == COMPONENT_Y)
{
CompArea tmpArea(COMPONENT_Y, area.chromaFormat, Position(0,0), area.size());
PelBuf tmpPred = m_tmpStorageLCU.getBuf(tmpArea);
tmpPred.copyFrom(piPred);
piReco.reconstruct(tmpPred, piResi, cs.slice->clpRng(compID));
}
{
piReco.reconstruct(piPred, piResi, cs.slice->clpRng( compID ));
if( jointCbCr )
{
crReco.reconstruct(crPred, crResi, cs.slice->clpRng( COMPONENT_Cr ));
}
}
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
#if INTRA_TRANS_ENC_OPT
bool doSignPrediction = true;
if (isLuma(compID) && ((tu.mtsIdx[COMPONENT_Y] > MTS_SKIP) || (CS::isDualITree(cs) && tu.cu->lfnstIdx && !tu.cu->ispMode)))
{
bool signHiding = cs.slice->getSignDataHidingEnabledFlag();
CoeffCodingContext cctx(tu, COMPONENT_Y, signHiding);
int scanPosLast = -1;
TCoeff* coeff = tu.getCoeffs(compID).buf;
for (int scanPos = cctx.maxNumCoeff() - 1; scanPos >= 0; scanPos--)
{
unsigned blkPos = cctx.blockPos(scanPos);
if (coeff[blkPos])
{
scanPosLast = scanPos;
break;
}
}
if (scanPosLast < 1)
{
doSignPrediction = false;
}
}
#endif
#if SIGN_PREDICTION
if ( sps.getNumPredSigns() > 0)
{
#if INTRA_TRANS_ENC_OPT
if (doSignPrediction)
{
#endif
bool bJccrWithCr = tu.jointCbCr && !(tu.jointCbCr >> 1);
bool bIsJccr = tu.jointCbCr && isChroma(compID);
ComponentID signPredCompID = bIsJccr ? (bJccrWithCr ? COMPONENT_Cr : COMPONENT_Cb) : compID;
bool reshapeChroma = flag && (TU::getCbf(tu, signPredCompID) || tu.jointCbCr) && isChroma(signPredCompID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag();
m_pcTrQuant->predCoeffSigns(tu, compID, reshapeChroma);
#if INTRA_TRANS_ENC_OPT
}
#endif

Karsten Suehring
committed
#if INTRA_TRANS_ENC_OPT
if (doSignPrediction)
#endif
#if JVET_V0094_BILATERAL_FILTER
CompArea tmpArea1(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
PelBuf tmpRecLuma;
if(isLuma(compID))
{
tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
tmpRecLuma.copyFrom(piReco);
}
#if JVET_X0071_CHROMA_BILATERAL_FILTER
CompArea tmpArea2(compID, area.chromaFormat, Position(0, 0), area.size());
PelBuf tmpRecChroma;
if(isChroma(compID))
{
tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2);
tmpRecChroma.copyFrom(piReco);
}
#endif
if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcEncCfg->getLmcs()
&& slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD()))))
{
const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
if (compID == COMPONENT_Y)
{
if(!(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
{
tmpRecLuma.rspSignal(m_pcReshape->getInvLUT());
if (pps.getUseBIF() /*&& (uiAbsSum > 0)*/ && isLuma(compID) && (tu.cu->qp > 17) && (128 > std::max(tu.lumaSize().width, tu.lumaSize().height)))
CompArea compArea = tu.blocks[compID];
PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
if(!(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
{
m_bilateralFilter->bilateralFilterRDOdiamond5x5(tmpRecLuma, tmpRecLuma, tmpRecLuma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, true, m_pcReshape->getInvLUT());
}
else
{
std::vector<Pel> dummy_invLUT;
m_bilateralFilter->bilateralFilterRDOdiamond5x5(tmpRecLuma, tmpRecLuma, tmpRecLuma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, false, dummy_invLUT);
}
ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if(pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17))
CompArea compArea = tu.blocks[compID];
PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
bool isCb = compID == COMPONENT_Cb ? true : false;
m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb);
ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecChroma, bitDepth, compID, DF_SSE_WTD, &orgLuma);
#else
ruiDist += m_pcRdCost->getDistPart(piOrg, piReco, bitDepth, compID, DF_SSE_WTD, &orgLuma);
#endif
if( jointCbCr )
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if(compID == COMPONENT_Cr)
{
ruiDist += m_pcRdCost->getDistPart(crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
}
else
{
ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
}
ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
#endif
if (pps.getUseBIF() /*&& (uiAbsSum > 0)*/ && isLuma(compID) && (tu.cu->qp > 17) && (128 > std::max(tu.lumaSize().width, tu.lumaSize().height)))
{
CompArea compArea = tu.blocks[compID];
PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
std::vector<Pel> my_invLUT;
m_bilateralFilter->bilateralFilterRDOdiamond5x5(tmpRecLuma, tmpRecLuma, tmpRecLuma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, false, my_invLUT);
}
ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecLuma, bitDepth, compID, DF_SSE );
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if (pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17))
CompArea compArea = tu.blocks[compID];
PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
bool isCb = compID == COMPONENT_Cb ? true : false;
m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb);
ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecChroma, bitDepth, compID, DF_SSE );
#else
ruiDist += m_pcRdCost->getDistPart( piOrg, piReco, bitDepth, compID, DF_SSE );
#endif
if( jointCbCr )
#if JVET_X0071_CHROMA_BILATERAL_FILTER
if(compID == COMPONENT_Cr)
{
ruiDist += m_pcRdCost->getDistPart( crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE );
}
else
{
ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE );
}
ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE );
#endif

Karsten Suehring
committed
//===== update distortion =====
#if JVET_X0071_CHROMA_BILATERAL_FILTER
CompArea tmpArea2(compID, area.chromaFormat, Position(0, 0), area.size());
PelBuf tmpRecChroma;
if(isChroma(compID))
{
tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2);
tmpRecChroma.copyFrom(piReco);
}
#if WCG_EXT
if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcEncCfg->getLmcs() && slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD()))))
{
const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
if(isLuma(compID))
{
if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
CompArea tmpArea1(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
tmpRecLuma.rspSignal( piReco, m_pcReshape->getInvLUT() );
ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
}
else
{
ruiDist += m_pcRdCost->getDistPart(piOrg, piReco, bitDepth, compID, DF_SSE_WTD, &orgLuma);
if( jointCbCr )
{
ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
}
}
}
else
{
if(pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17))
{
CompArea compArea = tu.blocks[compID];
PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
bool isCb = compID == COMPONENT_Cb ? true : false;
m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb);
ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecChroma, bitDepth, compID, DF_SSE_WTD, &orgLuma);
if( jointCbCr )
{
if(compID == COMPONENT_Cr)
{
ruiDist += m_pcRdCost->getDistPart(crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
}
else
{
ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
}
}
}
}
else
#endif
{
if(isLuma(compID))
{
ruiDist += m_pcRdCost->getDistPart( piOrg, piReco, bitDepth, compID, DF_SSE );
}
else
{
if (pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17))
CompArea compArea = tu.blocks[compID];
PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea);
bool isCb = compID == COMPONENT_Cb ? true : false;
m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb);
ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecChroma, bitDepth, compID, DF_SSE );
}
if( jointCbCr )
{
if(compID == COMPONENT_Cr)
{
ruiDist += m_pcRdCost->getDistPart( crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE );
ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE );
}
#else

Karsten Suehring
committed
#if WCG_EXT
if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcEncCfg->getLmcs()
&& slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD()))))
const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] );
if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled()))
{
CompArea tmpArea1(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size());
PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1);
tmpRecLuma.rspSignal( piReco, m_pcReshape->getInvLUT() );
ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma);
}
else
{
ruiDist += m_pcRdCost->getDistPart(piOrg, piReco, bitDepth, compID, DF_SSE_WTD, &orgLuma);
if( jointCbCr )
{
ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma);
}
}
ruiDist += m_pcRdCost->getDistPart( piOrg, piReco, bitDepth, compID, DF_SSE );
if( jointCbCr )
{
ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE );
}
}

Karsten Suehring
committed
#endif
#endif

Karsten Suehring
committed
}
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
void IntraSearch::xIntraCodingACTTUBlock(TransformUnit &tu, const ComponentID &compID, Distortion& ruiDist, std::vector<TrMode>* trModes, const bool loadTr)
{
if (!tu.blocks[compID].valid())
{
CHECK(1, "tu does not exist");
}
CodingStructure &cs = *tu.cs;
const SPS &sps = *cs.sps;
const Slice &slice = *cs.slice;
const CompArea &area = tu.blocks[compID];
const CompArea &crArea = tu.blocks[COMPONENT_Cr];
PelBuf piOrgResi = cs.getOrgResiBuf(area);
PelBuf piResi = cs.getResiBuf(area);
PelBuf crOrgResi = cs.getOrgResiBuf(crArea);
PelBuf crResi = cs.getResiBuf(crArea);
TCoeff uiAbsSum = 0;
CHECK(tu.jointCbCr && compID == COMPONENT_Cr, "wrong combination of compID and jointCbCr");
bool jointCbCr = tu.jointCbCr && compID == COMPONENT_Cb;
m_pcRdCost->setChromaFormat(cs.sps->getChromaFormatIdc());
if (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless())
m_pcTrQuant->lambdaAdjustColorTrans(true);
if (jointCbCr)
{
ComponentID compIdCode = (tu.jointCbCr >> 1 ? COMPONENT_Cb : COMPONENT_Cr);
m_pcTrQuant->selectLambda(compIdCode);
}
else
{
m_pcTrQuant->selectLambda(compID);
}
bool flag = slice.getLmcsEnabledFlag() && (slice.isIntra() || (!slice.isIntra() && m_pcReshape->getCTUFlag())) && (tu.blocks[compID].width*tu.blocks[compID].height > 4);
if (flag && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag())
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
{
int cResScaleInv = tu.getChromaAdj();
double cResScale = (double)(1 << CSCALE_FP_PREC) / (double)cResScaleInv;
m_pcTrQuant->setLambda(m_pcTrQuant->getLambda() / (cResScale*cResScale));
}
if (jointCbCr)
{
// Lambda is loosened for the joint mode with respect to single modes as the same residual is used for both chroma blocks
const int absIct = abs(TU::getICTMode(tu));
const double lfact = (absIct == 1 || absIct == 3 ? 0.8 : 0.5);
m_pcTrQuant->setLambda(lfact * m_pcTrQuant->getLambda());
}
if (sps.getJointCbCrEnabledFlag() && isChroma(compID) && (slice.getSliceQp() > 18))
{
m_pcTrQuant->setLambda(1.3 * m_pcTrQuant->getLambda());
}
if (isLuma(compID))
{
QpParam cQP(tu, compID);
if (trModes)
{
m_pcTrQuant->transformNxN(tu, compID, cQP, trModes, m_pcEncCfg->getMTSIntraMaxCand());
tu.mtsIdx[compID] = trModes->at(0).first;
}
if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) || tu.cu->bdpcmMode != 0)
{
m_pcTrQuant->transformNxN(tu, compID, cQP, uiAbsSum, m_CABACEstimator->getCtx(), loadTr);
}
if ((m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[compID] == 0) && tu.cu->bdpcmMode == 0)
{
uiAbsSum = 0;
tu.getCoeffs(compID).fill(0);
TU::setCbfAtDepth(tu, compID, tu.depth, 0);
}
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
if (uiAbsSum > 0)
{
m_pcTrQuant->invTransformNxN(tu, compID, piResi, cQP);
}
else
{
piResi.fill(0);
}
}
else
{
int codedCbfMask = 0;
ComponentID codeCompId = (tu.jointCbCr ? (tu.jointCbCr >> 1 ? COMPONENT_Cb : COMPONENT_Cr) : compID);
QpParam qpCbCr(tu, codeCompId);
if (tu.jointCbCr)
{
ComponentID otherCompId = (codeCompId == COMPONENT_Cr ? COMPONENT_Cb : COMPONENT_Cr);
tu.getCoeffs(otherCompId).fill(0);
TU::setCbfAtDepth(tu, otherCompId, tu.depth, false);
}
PelBuf& codeResi = (codeCompId == COMPONENT_Cr ? crResi : piResi);
uiAbsSum = 0;
if (trModes)
{
m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, trModes, m_pcEncCfg->getMTSIntraMaxCand());
tu.mtsIdx[codeCompId] = trModes->at(0).first;
if (tu.jointCbCr)
{
tu.mtsIdx[(codeCompId == COMPONENT_Cr) ? COMPONENT_Cb : COMPONENT_Cr] = MTS_DCT2_DCT2;
}
}
if (!(m_pcEncCfg->getCostMode() == COST_LOSSLESS_CODING && slice.isLossless() && tu.mtsIdx[codeCompId] == 0) || tu.cu->bdpcmModeChroma != 0)
{
m_pcTrQuant->transformNxN(tu, codeCompId, qpCbCr, uiAbsSum, m_CABACEstimator->getCtx(), loadTr);
}
if (uiAbsSum > 0)
{
m_pcTrQuant->invTransformNxN(tu, codeCompId, codeResi, qpCbCr);
codedCbfMask += (codeCompId == COMPONENT_Cb ? 2 : 1);
}
else
{
codeResi.fill(0);
}
if (tu.jointCbCr)
{
if (tu.jointCbCr == 3 && codedCbfMask == 2)
{
codedCbfMask = 3;
TU::setCbfAtDepth(tu, COMPONENT_Cr, tu.depth, true);
}
if (tu.jointCbCr != codedCbfMask)
{
ruiDist = std::numeric_limits<Distortion>::max();
if (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless())
m_pcTrQuant->lambdaAdjustColorTrans(false);
return;
}
m_pcTrQuant->invTransformICT(tu, piResi, crResi);
uiAbsSum = codedCbfMask;
}
}
#if !JVET_S0234_ACT_CRS_FIX
if (flag && uiAbsSum > 0 && isChroma(compID) && slice.getPicHeader()->getLmcsChromaResidualScaleFlag())
{
piResi.scaleSignal(tu.getChromaAdj(), 0, slice.clpRng(compID));
if (jointCbCr)
{
crResi.scaleSignal(tu.getChromaAdj(), 0, slice.clpRng(COMPONENT_Cr));
}
}
#endif
if (m_pcEncCfg->getCostMode() != COST_LOSSLESS_CODING || !slice.isLossless())
m_pcTrQuant->lambdaAdjustColorTrans(false);
ruiDist += m_pcRdCost->getDistPart(piOrgResi, piResi, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE);
if (jointCbCr)
{
ruiDist += m_pcRdCost->getDistPart(crOrgResi, crResi, sps.getBitDepth(toChannelType(COMPONENT_Cr)), COMPONENT_Cr, DF_SSE);
}
}
bool IntraSearch::xIntraCodingLumaISP(CodingStructure& cs, Partitioner& partitioner, const double bestCostSoFar)
{
int subTuCounter = 0;
const CodingUnit& cu = *cs.getCU(partitioner.currArea().lumaPos(), partitioner.chType);
bool earlySkipISP = false;
const PartSplit ispType = CU::getISPType(cu, COMPONENT_Y);
cs.cost = 0;
partitioner.splitCurrArea(ispType, cs);
CUCtx cuCtx;
cuCtx.isDQPCoded = true;
cuCtx.isChromaQpAdjCoded = true;
do // subpartitions loop
{
uint32_t numSig = 0;
Distortion singleDistTmpLuma = 0;
uint64_t singleTmpFracBits = 0;
double singleCostTmp = 0;
TransformUnit& tu = cs.addTU(CS::getArea(cs, partitioner.currArea(), partitioner.chType), partitioner.chType);
tu.depth = partitioner.currTrDepth;
// Encode TU

Karsten Suehring
committed
xIntraCodingTUBlock(tu, COMPONENT_Y, singleDistTmpLuma, 0, &numSig);
#if SIGN_PREDICTION
cs.picture->getRecoBuf( partitioner.currArea() ).copyFrom( cs.getRecoBuf( partitioner.currArea() ) );
#endif
if (singleDistTmpLuma == MAX_INT) // all zero CBF skip
{
earlySkipISP = true;
partitioner.exitCurrSplit();
cs.cost = MAX_DOUBLE;
return false;
}
if (m_pcRdCost->calcRdCost(cs.fracBits, cs.dist + singleDistTmpLuma) > bestCostSoFar)
// The accumulated cost + distortion is already larger than the best cost so far, so it is not necessary to
// calculate the rate
earlySkipISP = true;
}
else
{
singleTmpFracBits = xGetIntraFracBitsQT(cs, partitioner, true, false, subTuCounter, ispType, &cuCtx);
singleCostTmp = m_pcRdCost->calcRdCost(singleTmpFracBits, singleDistTmpLuma);
cs.cost += singleCostTmp;
cs.dist += singleDistTmpLuma;
cs.fracBits += singleTmpFracBits;
subTuCounter++;
splitCbfLuma |= TU::getCbfAtDepth(*cs.getTU(partitioner.currArea().lumaPos(), partitioner.chType, subTuCounter - 1), COMPONENT_Y, partitioner.currTrDepth);
int nSubPartitions = m_ispTestedModes[cu.lfnstIdx].numTotalParts[cu.ispMode - 1];
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
if (subTuCounter < nSubPartitions)
{
// exit condition if the accumulated cost is already larger than the best cost so far (no impact in RD performance)
if (cs.cost > bestCostSoFar)
{
earlySkipISP = true;
break;
}
else if (subTuCounter < nSubPartitions)
{
// more restrictive exit condition
double threshold = nSubPartitions == 2 ? 0.95 : subTuCounter == 1 ? 0.83 : 0.91;
if (subTuCounter < nSubPartitions && cs.cost > bestCostSoFar * threshold)
{
earlySkipISP = true;
break;
}
}
}
} while (partitioner.nextPart(cs)); // subpartitions loop
partitioner.exitCurrSplit();
const UnitArea& currArea = partitioner.currArea();
const uint32_t currDepth = partitioner.currTrDepth;
if (earlySkipISP)
{
cs.cost = MAX_DOUBLE;
}
else
{
cs.cost = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist);
// The cost check is necessary here again to avoid superfluous operations if the maximum number of coded subpartitions was reached and yet ISP did not win
if (cs.cost < bestCostSoFar)
{
cs.setDecomp(cu.Y());
cs.picture->getRecoBuf(currArea.Y()).copyFrom(cs.getRecoBuf(currArea.Y()));
for (auto& ptu : cs.tus)
{
if (currArea.Y().contains(ptu->Y()))
{
TU::setCbfAtDepth(*ptu, COMPONENT_Y, currDepth, splitCbfLuma ? 1 : 0);
}
}
}
else
{
earlySkipISP = true;
}
}
return !earlySkipISP;
}
bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &partitioner, const double bestCostSoFar, const int subTuIdx, const PartSplit ispType, const bool ispIsCurrentWinner, bool mtsCheckRangeFlag, int mtsFirstCheckId, int mtsLastCheckId, bool moreProbMTSIdxFirst )
{
int subTuCounter = subTuIdx;
const UnitArea &currArea = partitioner.currArea();
const CodingUnit &cu = *cs.getCU( currArea.lumaPos(), partitioner.chType );
bool earlySkipISP = false;
const SPS &sps = *cs.sps;

Karsten Suehring
committed
bool bCheckFull = true;
bool bCheckSplit = false;
bCheckFull = !partitioner.canSplit( TU_MAX_TR_SPLIT, cs );
bCheckSplit = partitioner.canSplit( TU_MAX_TR_SPLIT, cs );
const Slice &slice = *cs.slice;

Karsten Suehring
committed
if( cu.ispMode )
{
bCheckSplit = partitioner.canSplit( ispType, cs );
bCheckFull = !bCheckSplit;
}

Karsten Suehring
committed
uint32_t numSig = 0;
double dSingleCost = MAX_DOUBLE;
Distortion uiSingleDistLuma = 0;
uint64_t singleFracBits = 0;
bool checkTransformSkip = sps.getTransformSkipEnabledFlag();
int bestModeId[ MAX_NUM_COMPONENT ] = { 0, 0, 0 };
uint8_t nNumTransformCands = cu.mtsFlag ? 4 : 1;
uint8_t numTransformIndexCands = nNumTransformCands;

Karsten Suehring
committed
const TempCtx ctxStart ( m_CtxCache, m_CABACEstimator->getCtx() );
TempCtx ctxBest ( m_CtxCache );
CodingStructure *csSplit = nullptr;
CodingStructure *csFull = nullptr;
CUCtx cuCtx;
cuCtx.isDQPCoded = true;
cuCtx.isChromaQpAdjCoded = true;

Karsten Suehring
committed
if( bCheckSplit )