Commit 003824b2 authored by Xiaoyu Xiu's avatar Xiaoyu Xiu Committed by Xiang Li

JVET-N0329: IBC Search Improvement

parent 8ac77cab
......@@ -274,6 +274,9 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand,
// find the block with least candidates
size_t minSize = MAX_UINT;
unsigned int targetHashOneBlock = 0;
#if JVET_N0329_IBC_SEARCH_IMP
Position targetBlockOffsetInCu(0, 0);
#endif
for (SizeType y = 0; y < lumaArea.height && minSize > 1; y += MIN_PU_SIZE)
{
for (SizeType x = 0; x < lumaArea.width && minSize > 1; x += MIN_PU_SIZE)
......@@ -283,6 +286,9 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand,
{
minSize = m_hash2Pos[hash].size();
targetHashOneBlock = hash;
#if JVET_N0329_IBC_SEARCH_IMP
targetBlockOffsetInCu.repositionTo(Position(x, y));
#endif
}
}
}
......@@ -294,11 +300,20 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand,
// check whether whole block match
for (std::vector<Position>::iterator refBlockPos = candOneBlock.begin(); refBlockPos != candOneBlock.end(); refBlockPos++)
{
#if JVET_N0329_IBC_SEARCH_IMP
Position topLeft = refBlockPos->offset(-targetBlockOffsetInCu.x, -targetBlockOffsetInCu.y);
Position bottomRight = topLeft.offset(lumaArea.width - 1, lumaArea.height - 1);
#else
Position bottomRight = refBlockPos->offset(lumaArea.width - 1, lumaArea.height - 1);
#endif
bool wholeBlockMatch = true;
if (lumaArea.width > MIN_PU_SIZE || lumaArea.height > MIN_PU_SIZE)
{
#if JVET_N0329_IBC_SEARCH_IMP
if (!cs.isDecomp(bottomRight, cs.chType) || bottomRight.x >= m_picWidth || bottomRight.y >= m_picHeight || topLeft.x < 0 || topLeft.y < 0)
#else
if (!cs.isDecomp(bottomRight, cs.chType) || bottomRight.x >= m_picWidth || bottomRight.y >= m_picHeight)
#endif
{
continue;
}
......@@ -307,20 +322,33 @@ bool IbcHashMap::ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand,
for (SizeType x = 0; x < lumaArea.width && wholeBlockMatch; x += MIN_PU_SIZE)
{
// whether the reference block and current block has the same hash
#if JVET_N0329_IBC_SEARCH_IMP
wholeBlockMatch &= (m_pos2Hash[lumaArea.pos().y + y][lumaArea.pos().x + x] == m_pos2Hash[topLeft.y + y][topLeft.x + x]);
#else
wholeBlockMatch &= (m_pos2Hash[lumaArea.pos().y + y][lumaArea.pos().x + x] == m_pos2Hash[refBlockPos->y + y][refBlockPos->x + x]);
#endif
}
}
}
else
{
#if JVET_N0329_IBC_SEARCH_IMP
CHECK(topLeft != *refBlockPos, "4x4 target block should not have offset!");
if (abs(topLeft.x - lumaArea.x) > searchRange4SmallBlk || abs(topLeft.y - lumaArea.y) > searchRange4SmallBlk || !cs.isDecomp(bottomRight, cs.chType))
#else
if (abs(refBlockPos->x - lumaArea.x) > searchRange4SmallBlk || abs(refBlockPos->y - lumaArea.y) > searchRange4SmallBlk || !cs.isDecomp(bottomRight, cs.chType))
#endif
{
continue;
}
}
if (wholeBlockMatch)
{
#if JVET_N0329_IBC_SEARCH_IMP
cand.push_back(topLeft);
#else
cand.push_back(*refBlockPos);
#endif
if (cand.size() > maxCand)
{
break;
......@@ -349,5 +377,76 @@ int IbcHashMap::getHashHitRatio(const Area& lumaArea)
return 100 * hit / total;
}
#if JVET_N0329_IBC_SEARCH_IMP
int IbcHashMap::calHashBlkMatchPerc(const Area& lumaArea)
{
int maxX = std::min((int)(lumaArea.x + lumaArea.width), m_picWidth);
int maxY = std::min((int)(lumaArea.y + lumaArea.height), m_picHeight);
int maxUsage[100];
unsigned int mostSelHash[100];
static int numExcludedHashValue = 36;
for (int i = 0; i < numExcludedHashValue; i++)
{
maxUsage[i] = 0;
mostSelHash[i] = 0;
}
for (std::unordered_map<unsigned int, std::vector<Position>>::iterator it = m_hash2Pos.begin(); it != m_hash2Pos.end(); ++it)
{
unsigned int hash = it->first;
int usage = (int)it->second.size();
assert(usage == m_hash2Pos[hash].size());
int insertPos = -1;
for (insertPos = 0; insertPos < numExcludedHashValue; insertPos++)
{
if (usage > maxUsage[insertPos])
{
break;
}
}
assert(insertPos <= numExcludedHashValue);
if (insertPos < numExcludedHashValue)
{
for (int i = (numExcludedHashValue - 1); i >= (insertPos + 1); i--)
{
maxUsage[i] = maxUsage[i - 1];
mostSelHash[i] = mostSelHash[i - 1];
}
maxUsage[insertPos] = usage;
mostSelHash[insertPos] = hash;
}
}
int hit = 0, total = 0;
for (int y = lumaArea.y; y < maxY; y += MIN_PU_SIZE)
{
for (int x = lumaArea.x; x < maxX; x += MIN_PU_SIZE)
{
unsigned int hash = m_pos2Hash[y][x];
bool excludedHash = false;
for (int i = 0; i < numExcludedHashValue && !excludedHash; i++)
{
if (hash == mostSelHash[i])
{
excludedHash = true;
}
}
if (excludedHash)
{
continue;
}
hit += (m_hash2Pos[hash].size() > 1);
total++;
}
}
return 100 * hit / total;
}
#endif
//! \}
......@@ -82,6 +82,10 @@ public:
bool ibcHashMatch(const Area& lumaArea, std::vector<Position>& cand, const CodingStructure& cs, const int maxCand, const int searchRange4SmallBlk);
int getHashHitRatio(const Area& lumaArea);
#if JVET_N0329_IBC_SEARCH_IMP
int calHashBlkMatchPerc(const Area& lumaArea);
#endif
#ifdef TARGET_SIMD_X86
void initIbcHashMapX86();
template <X86_VEXT vext>
......
......@@ -224,4 +224,11 @@ struct LutMotionCand
static_vector<MotionInfo, MAX_NUM_HMVP_CANDS> lutShare;
static_vector<MotionInfo, MAX_NUM_HMVP_CANDS> lutShareIbc;
};
#if JVET_N0329_IBC_SEARCH_IMP
struct PatentBvCand
{
Mv m_bvCands[IBC_NUM_CANDIDATES];
int currCnt;
};
#endif
#endif // __MOTIONINFO__
......@@ -179,7 +179,11 @@ public:
inline Distortion getBvCostMultiplePreds(int x, int y, bool useIMV)
{
#if JVET_N0329_IBC_SEARCH_IMP
return Distortion(m_dCost * getBitsMultiplePreds(x, y, useIMV));
#else
return Distortion((m_dCost * getBitsMultiplePreds(x, y, useIMV)) / 65536.0);
#endif
}
unsigned int getBitsMultiplePreds(int x, int y, bool useIMV)
......
......@@ -1828,6 +1828,9 @@ private:
int m_apsId;
APS* m_aps;
bool m_tileGroupAlfEnabledFlag;
#if JVET_N0329_IBC_SEARCH_IMP
bool m_disableSATDForRd;
#endif
SliceReshapeInfo m_sliceReshapeInfo;
public:
Slice();
......@@ -2114,7 +2117,10 @@ public:
bool getTileGroupAlfEnabledFlag() const { return m_tileGroupAlfEnabledFlag; }
void setTileGroupAlfEnabledFlag(bool b) { m_tileGroupAlfEnabledFlag = b; }
#if JVET_N0329_IBC_SEARCH_IMP
void setDisableSATDForRD(bool b) { m_disableSATDForRd = b; }
bool getDisableSATDForRD() { return m_disableSATDForRd; }
#endif
const SliceReshapeInfo& getReshapeInfo() const { return m_sliceReshapeInfo; }
SliceReshapeInfo& getReshapeInfo() { return m_sliceReshapeInfo; }
protected:
......
......@@ -58,6 +58,8 @@
#define JVET_N0242_NON_LINEAR_ALF 1 // enable CE5-3.2, Non-linear ALF based on clipping function
#define JVET_N0329_IBC_SEARCH_IMP 1 // IBC encoder-side improvement
#define JVET_N0325_BDOF 1 // unified right-shifts for BDOF derivation
#define JVET_N0449_MMVD_SIMP 1 // Configurable number of mmvd distance entries used
......
......@@ -2186,9 +2186,121 @@ bool PU::isDiffMER(const PredictionUnit &pu1, const PredictionUnit &pu2)
return false;
}
#if JVET_N0329_IBC_SEARCH_IMP
bool PU::isAddNeighborMv(const Mv& currMv, Mv* neighborMvs, int numNeighborMv)
{
bool existed = false;
for (uint32_t cand = 0; cand < numNeighborMv && !existed; cand++)
{
if (currMv == neighborMvs[cand])
{
existed = true;
}
}
if (!existed)
{
return true;
}
else
{
return false;
}
}
#endif
#if JVET_N0329_IBC_SEARCH_IMP
void PU::getIbcMVPsEncOnly(PredictionUnit &pu, Mv* mvPred, int& nbPred)
#else
void PU::getIbcMVPsEncOnly(PredictionUnit &pu, Mv* MvPred, int& nbPred)
#endif
{
#if JVET_N0329_IBC_SEARCH_IMP
const PreCalcValues &pcv = *pu.cs->pcv;
const int cuWidth = pu.blocks[COMPONENT_Y].width;
const int cuHeight = pu.blocks[COMPONENT_Y].height;
const int log2UnitWidth = g_aucLog2[pcv.minCUWidth];
const int log2UnitHeight = g_aucLog2[pcv.minCUHeight];
const int totalAboveUnits = (cuWidth >> log2UnitWidth) + 1;
const int totalLeftUnits = (cuHeight >> log2UnitHeight) + 1;
nbPred = 0;
Position posLT = pu.Y().topLeft();
// above-left
const PredictionUnit *aboveLeftPU = pu.cs->getPURestricted(posLT.offset(-1, -1), pu, pu.cs->chType);
if (aboveLeftPU && CU::isIBC(*aboveLeftPU->cu))
{
if (isAddNeighborMv(aboveLeftPU->bv, mvPred, nbPred))
{
mvPred[nbPred++] = aboveLeftPU->bv;
}
}
// above neighbors
for (uint32_t dx = 0; dx < totalAboveUnits && nbPred < IBC_NUM_CANDIDATES; dx++)
{
const PredictionUnit* tmpPU = pu.cs->getPURestricted(posLT.offset((dx << log2UnitWidth), -1), pu, pu.cs->chType);
if (tmpPU && CU::isIBC(*tmpPU->cu))
{
if (isAddNeighborMv(tmpPU->bv, mvPred, nbPred))
{
mvPred[nbPred++] = tmpPU->bv;
}
}
}
// left neighbors
for (uint32_t dy = 0; dy < totalLeftUnits && nbPred < IBC_NUM_CANDIDATES; dy++)
{
const PredictionUnit* tmpPU = pu.cs->getPURestricted(posLT.offset(-1, (dy << log2UnitHeight)), pu, pu.cs->chType);
if (tmpPU && CU::isIBC(*tmpPU->cu))
{
if (isAddNeighborMv(tmpPU->bv, mvPred, nbPred))
{
mvPred[nbPred++] = tmpPU->bv;
}
}
}
size_t numAvaiCandInLUT = pu.cs->motionLut.lutIbc.size();
for (uint32_t cand = 0; cand < numAvaiCandInLUT && nbPred < IBC_NUM_CANDIDATES; cand++)
{
MotionInfo neibMi = pu.cs->motionLut.lutIbc[cand];
if (isAddNeighborMv(neibMi.bv, mvPred, nbPred))
{
mvPred[nbPred++] = neibMi.bv;
}
}
bool isBvCandDerived[IBC_NUM_CANDIDATES];
::memset(isBvCandDerived, false, IBC_NUM_CANDIDATES);
int curNbPred = nbPred;
if (curNbPred < IBC_NUM_CANDIDATES)
{
do
{
curNbPred = nbPred;
for (uint32_t idx = 0; idx < curNbPred && nbPred < IBC_NUM_CANDIDATES; idx++)
{
if (!isBvCandDerived[idx])
{
Mv derivedBv;
if (getDerivedBV(pu, mvPred[idx], derivedBv))
{
if (isAddNeighborMv(derivedBv, mvPred, nbPred))
{
mvPred[nbPred++] = derivedBv;
}
}
isBvCandDerived[idx] = true;
}
}
} while (nbPred > curNbPred && nbPred < IBC_NUM_CANDIDATES);
}
#else
//-- Get Spatial MV
Position posLT = pu.Y().topLeft();
Position posRT = pu.Y().topRight();
......@@ -2257,6 +2369,7 @@ void PU::getIbcMVPsEncOnly(PredictionUnit &pu, Mv* MvPred, int& nbPred)
if (getDerivedBV(pu, MvPred[nbPred - 1], MvPred[nbPred]))
nbPred++;
}
#endif
}
bool PU::getDerivedBV(PredictionUnit &pu, const Mv& currentMv, Mv& derivedMv)
......
......@@ -184,7 +184,12 @@ namespace PU
bool isUniqueTriangleCandidates (const PredictionUnit &pu, MergeCtx &triangleMrgCtx);
void spanTriangleMotionInfo ( PredictionUnit &pu, MergeCtx &triangleMrgCtx, const bool splitDir, const uint8_t candIdx0, const uint8_t candIdx1);
int32_t mappingRefPic (const PredictionUnit &pu, int32_t refPicPoc, bool targetRefPicList);
#if JVET_N0329_IBC_SEARCH_IMP
bool isAddNeighborMv (const Mv& currMv, Mv* neighborMvs, int numNeighborMv);
void getIbcMVPsEncOnly(PredictionUnit &pu, Mv* mvPred, int& nbPred);
#else
void getIbcMVPsEncOnly(PredictionUnit &pu, Mv* MvPred, int& nbPred);
#endif
bool getDerivedBV(PredictionUnit &pu, const Mv& currentMv, Mv& derivedMv);
bool isBlockVectorValid(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xStartInCU, int yStartInCU, int xBv, int yBv, int ctuSize);
bool checkDMVRCondition(const PredictionUnit& pu);
......
......@@ -1803,7 +1803,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
PredictionUnit &pu = tempCS->addPU( cu, partitioner.chType );
DistParam distParam;
#if JVET_N0329_IBC_SEARCH_IMP
const bool bUseHadamard = !encTestMode.lossless && !tempCS->slice->getDisableSATDForRD();
#else
const bool bUseHadamard= !encTestMode.lossless;
#endif
m_pcRdCost->setDistParam (distParam, tempCS->getOrgBuf().Y(), m_acMergeBuffer[0].Y(), sps.getBitDepth (CHANNEL_TYPE_LUMA), COMPONENT_Y, bUseHadamard);
const UnitArea localUnitArea( tempCS->area.chromaFormat, Area( 0, 0, tempCS->area.Y().width, tempCS->area.Y().height) );
......@@ -2308,7 +2312,11 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
}
DistParam distParam;
#if JVET_N0329_IBC_SEARCH_IMP
const bool useHadamard = !encTestMode.lossless && !tempCS->slice->getDisableSATDForRD();
#else
const bool useHadamard = !encTestMode.lossless;
#endif
m_pcRdCost->setDistParam( distParam, tempCS->getOrgBuf().Y(), m_acMergeBuffer[0].Y(), sps.getBitDepth( CHANNEL_TYPE_LUMA ), COMPONENT_Y, useHadamard );
const UnitArea localUnitArea( tempCS->area.chromaFormat, Area( 0, 0, tempCS->area.Y().width, tempCS->area.Y().height) );
......@@ -2627,7 +2635,11 @@ void EncCu::xCheckRDCostAffineMerge2Nx2N( CodingStructure *&tempCS, CodingStruct
PredictionUnit &pu = tempCS->addPU( cu, partitioner.chType );
DistParam distParam;
#if JVET_N0329_IBC_SEARCH_IMP
const bool bUseHadamard = !encTestMode.lossless && !tempCS->slice->getDisableSATDForRD();
#else
const bool bUseHadamard = !encTestMode.lossless;
#endif
m_pcRdCost->setDistParam( distParam, tempCS->getOrgBuf().Y(), m_acMergeBuffer[0].Y(), sps.getBitDepth( CHANNEL_TYPE_LUMA ), COMPONENT_Y, bUseHadamard );
const UnitArea localUnitArea( tempCS->area.chromaFormat, Area( 0, 0, tempCS->area.Y().width, tempCS->area.Y().height ) );
......@@ -2887,7 +2899,11 @@ void EncCu::xCheckRDCostIBCModeMerge2Nx2N(CodingStructure *&tempCS, CodingStruct
cu.mmvdSkip = false;
cu.triangle = false;
DistParam distParam;
#if JVET_N0329_IBC_SEARCH_IMP
const bool bUseHadamard = !encTestMode.lossless && !cu.slice->getDisableSATDForRD();
#else
const bool bUseHadamard = !encTestMode.lossless;
#endif
PredictionUnit &pu = tempCS->addPU(cu, partitioner.chType); //tempCS->addPU(cu);
pu.mmvdMergeFlag = false;
Picture* refPic = pu.cu->slice->getPic();
......
......@@ -1533,7 +1533,11 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
if( lastTestMode().type != ETM_INTRA && cuECtx.bestCS && cuECtx.bestCU && interHadActive( cuECtx ) )
{
// Get SATD threshold from best Inter-CU
#if JVET_N0329_IBC_SEARCH_IMP
if (!cs.slice->isIRAP() && m_pcEncCfg->getUsePbIntraFast() && !cs.slice->getDisableSATDForRD())
#else
if( !cs.slice->isIRAP() && m_pcEncCfg->getUsePbIntraFast() )
#endif
{
CodingUnit* bestCU = cuECtx.bestCU;
if (bestCU && !CU::isIntra(*bestCU))
......
......@@ -738,6 +738,9 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
rpcSlice->setMaxBTSizeIChroma( rpcSlice->getSPS()->getMaxBTSizeIChroma() );
rpcSlice->setMaxTTSizeIChroma( rpcSlice->getSPS()->getMaxTTSizeIChroma() );
}
#if JVET_N0329_IBC_SEARCH_IMP
rpcSlice->setDisableSATDForRD(false);
#endif
}
......@@ -1584,11 +1587,20 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
if ( pcSlice->getSPS()->getDisFracMmvdEnabledFlag() ||
(pcSlice->getSPS()->getIBCFlag() && m_pcCuEncoder->getEncCfg()->getIBCHashSearch()))
{
#if JVET_N0329_IBC_SEARCH_IMP
m_pcCuEncoder->getIbcHashMap().rebuildPicHashMap(cs.picture->getTrueOrigBuf());
if (m_pcCfg->getIntraPeriod() != -1)
{
int hashBlkHitPerc = m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y());
cs.slice->setDisableSATDForRD(hashBlkHitPerc > 59);
}
#else
if (pcSlice->getSPS()->getUseReshaper() && m_pcLib->getReshaper()->getCTUFlag() && pcSlice->getSPS()->getIBCFlag())
cs.picture->getOrigBuf(COMPONENT_Y).rspSignal(m_pcLib->getReshaper()->getFwdLUT());
m_pcCuEncoder->getIbcHashMap().rebuildPicHashMap( cs.picture->getOrigBuf() );
if (pcSlice->getSPS()->getUseReshaper() && m_pcLib->getReshaper()->getCTUFlag() && pcSlice->getSPS()->getIBCFlag())
cs.picture->getOrigBuf().copyFrom(cs.picture->getTrueOrigBuf());
#endif
}
checkDisFracMmvd( pcPic, startCtuTsAddr, boundingCtuTsAddr );
// for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment)
......
......@@ -198,7 +198,15 @@ void InterSearch::init( EncCfg* pcEncCfg,
{
CHECK(m_isInitialized, "Already initialized");
m_numBVs = 0;
#if JVET_N0329_IBC_SEARCH_IMP
for (int i = 0; i < IBC_NUM_CANDIDATES; i++)
{
m_defaultCachedBvs.m_bvCands[i].setZero();
}
m_defaultCachedBvs.currCnt = 0;
#else
m_numBV16s = 0;
#endif
m_pcEncCfg = pcEncCfg;
m_pcTrQuant = pcTrQuant;
m_iSearchRange = iSearchRange;
......@@ -747,7 +755,11 @@ Distortion InterSearch::xGetInterPredictionError( PredictionUnit& pu, PelUnitBuf
DistParam cDistParam;
cDistParam.applyWeight = false;
#if JVET_N0329_IBC_SEARCH_IMP
m_pcRdCost->setDistParam(cDistParam, origBuf.Y(), predBuf.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, m_pcEncCfg->getUseHADME() && !pu.cu->transQuantBypass && !pu.cu->slice->getDisableSATDForRD());
#else
m_pcRdCost->setDistParam( cDistParam, origBuf.Y(), predBuf.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, m_pcEncCfg->getUseHADME() && !pu.cu->transQuantBypass );
#endif
return (Distortion)cDistParam.distFunc( cDistParam );
}
......@@ -805,6 +817,13 @@ int InterSearch::xIBCSearchMVChromaRefine(PredictionUnit& pu,
UnitArea allCompBlocks(pu.chromaFormat, (Area)pu.block(COMPONENT_Y));
for (int cand = 0; cand < CHROMA_REFINEMENT_CANDIDATES; cand++)
{
#if JVET_N0329_IBC_SEARCH_IMP
if (sadBestCand[cand] == std::numeric_limits<Distortion>::max())
{
continue;
}
#endif
if ((!cMVCand[cand].getHor()) && (!cMVCand[cand].getVer()))
continue;
......@@ -869,10 +888,22 @@ int InterSearch::xIBCSearchMVChromaRefine(PredictionUnit& pu,
return bestCandIdx;
}
#if JVET_N0329_IBC_SEARCH_IMP
static unsigned int xMergeCandLists(Mv *dst, unsigned int dn, unsigned int dstTotalLength, Mv *src, unsigned int sn)
{
for (unsigned int cand = 0; cand < sn && dn < dstTotalLength; cand++)
#else
static unsigned int xMergeCandLists(Mv *dst, unsigned int dn, Mv *src, unsigned int sn)
{
for (unsigned int cand = 0; cand < sn && dn<IBC_NUM_CANDIDATES; cand++)
#endif
{
#if JVET_N0329_IBC_SEARCH_IMP
if (src[cand] == Mv())
{
continue;
}
#endif
bool found = false;
for (int j = 0; j<dn; j++)
{
......@@ -942,7 +973,12 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS
Distortion tempSadBest = 0;
int srLeft = srchRngHorLeft, srRight = srchRngHorRight, srTop = srchRngVerTop, srBottom = srchRngVerBottom;
#if JVET_N0329_IBC_SEARCH_IMP
m_numBVs = 0;
m_numBVs = xMergeCandLists(m_acBVs, m_numBVs, (2 * IBC_NUM_CANDIDATES), m_defaultCachedBvs.m_bvCands, m_defaultCachedBvs.currCnt);
Mv cMvPredEncOnly[IBC_NUM_CANDIDATES];
#else
if (roiWidth>8 || roiHeight>8)
{
m_numBVs = 0;
......@@ -953,9 +989,14 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS
}
Mv cMvPredEncOnly[16];
#endif
int nbPreds = 0;
PU::getIbcMVPsEncOnly(pu, cMvPredEncOnly, nbPreds);
#if JVET_N0329_IBC_SEARCH_IMP
m_numBVs = xMergeCandLists(m_acBVs, m_numBVs, (2 * IBC_NUM_CANDIDATES), cMvPredEncOnly, nbPreds);
#else
m_numBVs = xMergeCandLists(m_acBVs, m_numBVs, cMvPredEncOnly, nbPreds);
#endif
for (unsigned int cand = 0; cand < m_numBVs; cand++)
{
......@@ -1196,6 +1237,23 @@ void InterSearch::xIntraPatternSearch(PredictionUnit& pu, IntTZSearchStruct& cS
ruiCost = sadBest;
end:
#if JVET_N0329_IBC_SEARCH_IMP
m_numBVs = 0;
m_numBVs = xMergeCandLists(m_acBVs, m_numBVs, (2 * IBC_NUM_CANDIDATES), m_defaultCachedBvs.m_bvCands, m_defaultCachedBvs.currCnt);
m_defaultCachedBvs.currCnt = 0;
m_defaultCachedBvs.currCnt = xMergeCandLists(m_defaultCachedBvs.m_bvCands, m_defaultCachedBvs.currCnt, IBC_NUM_CANDIDATES, cMVCand, CHROMA_REFINEMENT_CANDIDATES);
m_defaultCachedBvs.currCnt = xMergeCandLists(m_defaultCachedBvs.m_bvCands, m_defaultCachedBvs.currCnt, IBC_NUM_CANDIDATES, m_acBVs, m_numBVs);
for (unsigned int cand = 0; cand < CHROMA_REFINEMENT_CANDIDATES; cand++)
{
if (cMVCand[cand].getHor() == 0 && cMVCand[cand].getVer() == 0)
{
continue;
}
m_ctuRecord[pu.lumaPos()][pu.lumaSize()].bvRecord[cMVCand[cand]] = sadBestCand[cand];
}
#else
if (roiWidth + roiHeight > 8)
{
m_numBVs = xMergeCandLists(m_acBVs, m_numBVs, cMVCand, CHROMA_REFINEMENT_CANDIDATES);
......@@ -1205,6 +1263,7 @@ end:
m_numBV16s = m_numBVs;
}
}
#endif
return;
}
......@@ -1218,10 +1277,57 @@ void InterSearch::xIBCEstimation(PredictionUnit& pu, PelUnitBuf& origBuf,
Distortion &ruiCost, const int localSearchRangeX, const int localSearchRangeY
)
{
#if JVET_N0329_IBC_SEARCH_IMP
const int iPicWidth = pu.cs->slice->getSPS()->getPicWidthInLumaSamples();
const int iPicHeight = pu.cs->slice->getSPS()->getPicHeightInLumaSamples();
const unsigned int lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth();
const int cuPelX = pu.Y().x;
const int cuPelY = pu.Y().y;
int iRoiWidth = pu.lwidth();
int iRoiHeight = pu.lheight();
PelUnitBuf* pBuf = &origBuf;
// Search key pattern initialization