...
 
Commits (26)
......@@ -330,7 +330,11 @@ void InterPrediction::xSubPuMC( PredictionUnit& pu, PelUnitBuf& predBuf, const R
pu.cu->affine = isAffine;
}
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
void InterPrediction::xSubPuBio(PredictionUnit& pu, PelUnitBuf& predBuf, const RefPicList &eRefPicList /*= REF_PIC_LIST_X*/, PelUnitBuf* yuvDstTmp /*= NULL*/)
#else
void InterPrediction::xSubPuBio(PredictionUnit& pu, PelUnitBuf& predBuf, const RefPicList &eRefPicList /*= REF_PIC_LIST_X*/)
#endif
{
// compute the location of the current PU
Position puPos = pu.lumaPos();
......@@ -344,6 +348,9 @@ void InterPrediction::xSubPuBio(PredictionUnit& pu, PelUnitBuf& predBuf, const R
subPu.mmvdMergeFlag = pu.mmvdMergeFlag;
subPu.mmvdEncOptMode = pu.mmvdEncOptMode;
subPu.mergeFlag = pu.mergeFlag;
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
subPu.mhIntraFlag = pu.mhIntraFlag;
#endif
subPu.mvRefine = pu.mvRefine;
subPu.refIdx[0] = pu.refIdx[0];
subPu.refIdx[1] = pu.refIdx[1];
......@@ -368,6 +375,14 @@ void InterPrediction::xSubPuBio(PredictionUnit& pu, PelUnitBuf& predBuf, const R
subPu = curMi;
PelUnitBuf subPredBuf = predBuf.subBuf(UnitAreaRelative(pu, subPu));
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvDstTmp)
{
PelUnitBuf subPredBufTmp = yuvDstTmp->subBuf(UnitAreaRelative(pu, subPu));
motionCompensation(subPu, subPredBuf, eRefPicList, true, true, &subPredBufTmp);
}
else
#endif
motionCompensation(subPu, subPredBuf, eRefPicList);
}
}
......@@ -463,7 +478,11 @@ void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList&
}
}
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred, PelUnitBuf* yuvPredTmp /*= NULL*/)
#else
void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
#endif
{
const PPS &pps = *pu.cs->pps;
const Slice &slice = *pu.cs->slice;
......@@ -476,7 +495,11 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
pu.cs->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
bool bioApplied = false;
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
if (pu.cs->sps->getBDOFEnabledFlag() && (!pu.cs->slice->getDisBdofDmvrFlag()))
#else
if (pu.cs->sps->getBDOFEnabledFlag())
#endif
{
if (pu.cu->affine || m_subPuMC)
{
......@@ -496,6 +519,11 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
}
}
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (bioApplied && pu.mhIntraFlag)
bioApplied = false;
#endif
if (bioApplied && pu.cu->smvdMode)
{
bioApplied = false;
......@@ -532,7 +560,15 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
if (pu.refIdx[0] >= 0 && pu.refIdx[1] >= 0)
{
if (dmvrApplied)
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
{
if (yuvPredTmp)
xPredInterUni(pu, eRefPicList, pcMbBuf, true, false, true, true);
continue;
}
#else
continue; // mc will happen in processDMVR
#endif
xPredInterUni ( pu, eRefPicList, pcMbBuf, true
, bioApplied
, true, true
......@@ -565,20 +601,38 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred)
if( (!dmvrApplied) && (!bioApplied) && pps.getWPBiPred() && slice.getSliceType() == B_SLICE && pu.cu->GBiIdx==GBI_DEFAULT)
{
xWeightedPredictionBi( pu, srcPred0, srcPred1, pcYuvPred, m_maxCompIDToPred );
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvPredTmp)
yuvPredTmp->copyFrom(pcYuvPred);
#endif
}
else if( pps.getUseWP() && slice.getSliceType() == P_SLICE )
{
xWeightedPredictionUni( pu, srcPred0, REF_PIC_LIST_0, pcYuvPred, -1, m_maxCompIDToPred );
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvPredTmp)
yuvPredTmp->copyFrom(pcYuvPred);
#endif
}
else
{
if (dmvrApplied)
{
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvPredTmp)
{
yuvPredTmp->addAvg(srcPred0, srcPred1, slice.clpRngs(), false);
}
#endif
xProcessDMVR(pu, pcYuvPred, slice.clpRngs(), bioApplied);
}
else
{
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
xWeightedAverage( pu, srcPred0, srcPred1, pcYuvPred, slice.getSPS()->getBitDepths(), slice.clpRngs(), bioApplied, yuvPredTmp);
#else
xWeightedAverage( pu, srcPred0, srcPred1, pcYuvPred, slice.getSPS()->getBitDepths(), slice.clpRngs(), bioApplied );
#endif
}
}
}
......@@ -1117,7 +1171,11 @@ void InterPrediction::xCalcBlkGradient(int sx, int sy, int *arraysGx2, int
g_pelBufOP.calcBlkGradient(sx, sy, arraysGx2, arraysGxGy, arraysGxdI, arraysGy2, arraysGydI, sGx2, sGy2, sGxGy, sGxdI, sGydI, width, height, unitSize);
}
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitBuf& pcYuvSrc0, const CPelUnitBuf& pcYuvSrc1, PelUnitBuf& pcYuvDst, const BitDepths& clipBitDepths, const ClpRngs& clpRngs, const bool& bioApplied, PelUnitBuf* yuvDstTmp /*= NULL*/)
#else
void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitBuf& pcYuvSrc0, const CPelUnitBuf& pcYuvSrc1, PelUnitBuf& pcYuvDst, const BitDepths& clipBitDepths, const ClpRngs& clpRngs, const bool& bioApplied )
#endif
{
const int iRefIdx0 = pu.refIdx[0];
const int iRefIdx1 = pu.refIdx[1];
......@@ -1128,6 +1186,10 @@ void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitB
{
CHECK(bioApplied, "GBi is disallowed with BIO");
pcYuvDst.addWeightedAvg(pcYuvSrc0, pcYuvSrc1, clpRngs, pu.cu->GBiIdx);
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvDstTmp)
yuvDstTmp->copyFrom(pcYuvDst);
#endif
return;
}
if (bioApplied)
......@@ -1145,10 +1207,18 @@ void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitB
if (bioEnabled)
{
applyBiOptFlow(pu, pcYuvSrc0, pcYuvSrc1, iRefIdx0, iRefIdx1, pcYuvDst, clipBitDepths);
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvDstTmp)
yuvDstTmp->bufs[0].addAvg(CPelBuf(pSrcY0, src0Stride, pu.lumaSize()), CPelBuf(pSrcY1, src1Stride, pu.lumaSize()), clpRngs.comp[0]);
#endif
}
else
{
pcYuvDst.bufs[0].addAvg(CPelBuf(pSrcY0, src0Stride, pu.lumaSize()), CPelBuf(pSrcY1, src1Stride, pu.lumaSize()), clpRngs.comp[0]);
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvDstTmp)
yuvDstTmp->bufs[0].copyFrom(pcYuvDst.bufs[0]);
#endif
}
}
if (pu.cs->pps->getWPBiPred())
......@@ -1169,6 +1239,18 @@ void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitB
{
pcYuvDst.addAvg(pcYuvSrc0, pcYuvSrc1, clpRngs, bioApplied);
}
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvDstTmp)
{
if (bioApplied)
{
yuvDstTmp->bufs[1].copyFrom(pcYuvDst.bufs[1]);
yuvDstTmp->bufs[2].copyFrom(pcYuvDst.bufs[2]);
}
else
yuvDstTmp->copyFrom(pcYuvDst);
}
#endif
}
else if( iRefIdx0 >= 0 && iRefIdx1 < 0 )
{
......@@ -1178,6 +1260,10 @@ void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitB
}
else
pcYuvDst.copyClip( pcYuvSrc0, clpRngs );
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvDstTmp)
yuvDstTmp->copyFrom(pcYuvDst);
#endif
}
else if( iRefIdx0 < 0 && iRefIdx1 >= 0 )
{
......@@ -1187,13 +1273,24 @@ void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitB
}
else
pcYuvDst.copyClip( pcYuvSrc1, clpRngs );
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (yuvDstTmp)
yuvDstTmp->copyFrom(pcYuvDst);
#endif
}
}
void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBuf, const RefPicList &eRefPicList
, const bool luma, const bool chroma
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
, PelUnitBuf* predBufWOBIO /*= NULL*/
#endif
)
{
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
CHECK(predBufWOBIO && pu.mhIntraFlag, "the case should not happen!");
#endif
// dual tree handling for IBC as the only ref
if ((!luma || !chroma) && eRefPicList == REF_PIC_LIST_0)
{
......@@ -1217,6 +1314,9 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
if( eRefPicList != REF_PIC_LIST_X )
{
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
CHECK(predBufWOBIO != NULL, "the case should not happen!");
#endif
if( ( ( sliceType == P_SLICE && pps.getUseWP() ) || ( sliceType == B_SLICE && pps.getWPBiPred() ) ) )
{
xPredInterUni ( pu, eRefPicList, predBuf, true
......@@ -1245,7 +1345,11 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
pu.cs->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
bool bioApplied = false;
const Slice &slice = *pu.cs->slice;
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
if (pu.cs->sps->getBDOFEnabledFlag() && (!pu.cs->slice->getDisBdofDmvrFlag()))
#else
if (pu.cs->sps->getBDOFEnabledFlag())
#endif
{
if (pu.cu->affine || m_subPuMC)
......@@ -1266,6 +1370,13 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
}
}
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (bioApplied && pu.mhIntraFlag)
{
bioApplied = false;
}
#endif
if (bioApplied && pu.cu->smvdMode)
{
bioApplied = false;
......@@ -1283,11 +1394,18 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
dmvrApplied = (pu.mvRefine) && PU::checkDMVRCondition(pu);
if ((pu.lumaSize().width > MAX_BDOF_APPLICATION_REGION || pu.lumaSize().height > MAX_BDOF_APPLICATION_REGION) && pu.mergeType != MRG_TYPE_SUBPU_ATMVP && (bioApplied && !dmvrApplied))
{
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
xSubPuBio(pu, predBuf, eRefPicList, predBufWOBIO);
#else
xSubPuBio(pu, predBuf, eRefPicList);
#endif
}
else
if (pu.mergeType != MRG_TYPE_DEFAULT_N && pu.mergeType != MRG_TYPE_IBC)
{
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
CHECK(predBufWOBIO != NULL, "the case should not happen!");
#endif
xSubPuMC( pu, predBuf, eRefPicList );
}
else if( xCheckIdenticalMotion( pu ) )
......@@ -1296,10 +1414,18 @@ void InterPrediction::motionCompensation( PredictionUnit &pu, PelUnitBuf &predBu
, false
, true, true
);
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
if (predBufWOBIO)
predBufWOBIO->copyFrom(predBuf);
#endif
}
else
{
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
xPredInterBi(pu, predBuf, predBufWOBIO);
#else
xPredInterBi( pu, predBuf );
#endif
}
}
return;
......
......@@ -121,7 +121,11 @@ protected:
, const bool& bioApplied
, const bool luma, const bool chroma
);
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
void xPredInterBi ( PredictionUnit& pu, PelUnitBuf &pcYuvPred, PelUnitBuf* yuvPredTmp = NULL );
#else
void xPredInterBi ( PredictionUnit& pu, PelUnitBuf &pcYuvPred );
#endif
void xPredInterBlk ( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv& _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng
, const bool& bioApplied
, bool isIBC
......@@ -136,7 +140,11 @@ protected:
void xBioGradFilter (Pel* pSrc, int srcStride, int width, int height, int gradStride, Pel* gradX, Pel* gradY, int bitDepth);
void xCalcBIOPar (const Pel* srcY0Temp, const Pel* srcY1Temp, const Pel* gradX0, const Pel* gradX1, const Pel* gradY0, const Pel* gradY1, int* dotProductTemp1, int* dotProductTemp2, int* dotProductTemp3, int* dotProductTemp5, int* dotProductTemp6, const int src0Stride, const int src1Stride, const int gradStride, const int widthG, const int heightG, int bitDepth);
void xCalcBlkGradient (int sx, int sy, int *arraysGx2, int *arraysGxGy, int *arraysGxdI, int *arraysGy2, int *arraysGydI, int &sGx2, int &sGy2, int &sGxGy, int &sGxdI, int &sGydI, int width, int height, int unitSize);
void xWeightedAverage ( const PredictionUnit& pu, const CPelUnitBuf& pcYuvSrc0, const CPelUnitBuf& pcYuvSrc1, PelUnitBuf& pcYuvDst, const BitDepths& clipBitDepths, const ClpRngs& clpRngs, const bool& bioApplied );
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
void xWeightedAverage ( const PredictionUnit& pu, const CPelUnitBuf& pcYuvSrc0, const CPelUnitBuf& pcYuvSrc1, PelUnitBuf& pcYuvDst, const BitDepths& clipBitDepths, const ClpRngs& clpRngs, const bool& bioApplied, PelUnitBuf* yuvDstTmp = NULL );
#else
void xWeightedAverage ( const PredictionUnit& pu, const CPelUnitBuf& pcYuvSrc0, const CPelUnitBuf& pcYuvSrc1, PelUnitBuf& pcYuvDst, const BitDepths& clipBitDepths, const ClpRngs& clpRngs, const bool& bioApplied );
#endif
void xPredAffineBlk( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv* _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng );
void xWeightedTriangleBlk ( const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const bool splitDir, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 );
......@@ -144,7 +152,11 @@ protected:
static bool xCheckIdenticalMotion( const PredictionUnit& pu );
void xSubPuMC(PredictionUnit& pu, PelUnitBuf& predBuf, const RefPicList &eRefPicList = REF_PIC_LIST_X);
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
void xSubPuBio(PredictionUnit& pu, PelUnitBuf& predBuf, const RefPicList &eRefPicList = REF_PIC_LIST_X, PelUnitBuf* yuvDstTmp = NULL);
#else
void xSubPuBio(PredictionUnit& pu, PelUnitBuf& predBuf, const RefPicList &eRefPicList = REF_PIC_LIST_X);
#endif
void destroy();
......@@ -162,6 +174,9 @@ public:
// inter
void motionCompensation (PredictionUnit &pu, PelUnitBuf& predBuf, const RefPicList &eRefPicList = REF_PIC_LIST_X
, const bool luma = true, const bool chroma = true
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
, PelUnitBuf* predBufWOBIO = NULL
#endif
);
void motionCompensation (PredictionUnit &pu, const RefPicList &eRefPicList = REF_PIC_LIST_X
, const bool luma = true, const bool chroma = true
......
......@@ -177,6 +177,8 @@ void LoopFilter::loopFilterPic( CodingStructure& cs
m_ctuYLumaSamples = y << pcv.maxCUHeightLog2;
const UnitArea ctuArea( pcv.chrFormat, Area( x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth ) );
CodingUnit* firstCU = cs.getCU( ctuArea.lumaPos(), CH_L);
cs.slice = firstCU->slice;
// CU-based deblocking
for( auto &currCU : cs.traverseCUs( CS::getArea( cs, ctuArea, CH_L ), CH_L ) )
......@@ -214,6 +216,8 @@ void LoopFilter::loopFilterPic( CodingStructure& cs
m_ctuYLumaSamples = y << pcv.maxCUHeightLog2;
const UnitArea ctuArea( pcv.chrFormat, Area( x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth ) );
CodingUnit* firstCU = cs.getCU( ctuArea.lumaPos(), CH_L);
cs.slice = firstCU->slice;
// CU-based deblocking
for( auto &currCU : cs.traverseCUs( CS::getArea( cs, ctuArea, CH_L ), CH_L ) )
......@@ -1140,7 +1144,8 @@ void LoopFilter::xEdgeFilterChroma(const CodingUnit& cu, const DeblockEdgeDir ed
if (bS[0] > 0 || bS[1] > 0)
{
const CodingUnit& cuQ = cu;
const CodingUnit& cuP = *cu.cs->getCU( recalcPosition( cu.chromaFormat, CHANNEL_TYPE_LUMA, cu.chType, pos.offset( xoffset - uiNumPelsLuma, yoffset - uiNumPelsLuma ) ), cu.chType );
CodingUnit& cuP1 = *cu.cs->getCU( recalcPosition( cu.chromaFormat, CHANNEL_TYPE_LUMA, cu.chType, pos.offset( xoffset - uiNumPelsLuma, yoffset - uiNumPelsLuma ) ), cu.chType );
CodingUnit& cuP = *cu.cs->getCU( recalcPosition( cu.chromaFormat, CHANNEL_TYPE_LUMA, ((!cuP1.cs->pcv->ISingleTree && cuP1.slice->isIntra()) ? CHANNEL_TYPE_CHROMA : cu.chType), pos.offset( xoffset - uiNumPelsLuma, yoffset - uiNumPelsLuma ) ), ((!cuP1.cs->pcv->ISingleTree && cuP1.slice->isIntra()) ? CHANNEL_TYPE_CHROMA : cu.chType));
if (edgeDir == EDGE_VER)
{
......
......@@ -430,6 +430,10 @@ void initROM()
}
}
#endif
#if JVET_O0592_ENC_ME_IMP
::memset(g_isReusedUniMVsFilled, 0, sizeof(g_isReusedUniMVsFilled));
#endif
}
void destroyROM()
......@@ -753,5 +757,9 @@ uint8_t g_triangleMvStorage[TRIANGLE_DIR_NUM][MAX_CU_DEPTH - MIN_CU_LOG2 + 1][MA
#if JVET_O0280_SIMD_TRIANGLE_WEIGHTING
int16_t *g_triangleWeights[2][TRIANGLE_DIR_NUM][MAX_CU_DEPTH - MIN_CU_LOG2 + 2][MAX_CU_DEPTH - MIN_CU_LOG2 + 2];
#endif
#if JVET_O0592_ENC_ME_IMP
Mv g_reusedUniMVs[32][32][8][8][2][33];
bool g_isReusedUniMVsFilled[32][32][8][8];
#endif
//! \}
......@@ -226,5 +226,11 @@ extern int16_t *g_triangleWeights[2][TRIANGLE_DIR_NUM][MAX_CU_DEPTH - MIN_CU_LOG
extern bool g_mctsDecCheckEnabled;
#if JVET_O0592_ENC_ME_IMP
class Mv;
extern Mv g_reusedUniMVs[32][32][8][8][2][33];
extern bool g_isReusedUniMVsFilled[32][32][8][8];
#endif
#endif //__TCOMROM__
......@@ -687,13 +687,17 @@ void SampleAdaptiveOffset::xPCMLFDisableProcess(CodingStructure& cs)
void SampleAdaptiveOffset::xPCMCURestoration(CodingStructure& cs, const UnitArea &ctuArea)
{
const SPS& sps = *cs.sps;
uint32_t numComponents = CS::isDualITree(cs) ? 1 : m_numberOfComponents;
uint32_t numComponents;
bool anyDualTree = false;
for( auto &cu : cs.traverseCUs( ctuArea, CH_L ) )
{
// restore PCM samples
if( ( cu.ipcm && sps.getPCMFilterDisableFlag() ) || CU::isLosslessCoded( cu ) )
{
cs.slice = cu.slice;
anyDualTree |= CS::isDualITree(cs);
numComponents = CS::isDualITree(cs) ? 1 : m_numberOfComponents;
for( uint32_t comp = 0; comp < numComponents; comp++ )
{
xPCMSampleRestoration( cu, ComponentID( comp ) );
......@@ -701,10 +705,15 @@ void SampleAdaptiveOffset::xPCMCURestoration(CodingStructure& cs, const UnitArea
}
}
numComponents = m_numberOfComponents;
if (CS::isDualITree(cs) && numComponents)
if (anyDualTree && numComponents)
{
for (auto &cu : cs.traverseCUs(ctuArea, CH_C))
{
if (cu.slice->isIntra() == false)
{
continue;
}
// restore PCM samples
if ((cu.ipcm && sps.getPCMFilterDisableFlag()) || CU::isLosslessCoded(cu))
{
......
......@@ -83,6 +83,9 @@ Slice::Slice()
, m_maxNumAffineMergeCand ( 0 )
, m_maxNumTriangleCand ( 0 )
, m_disFracMMVD ( false )
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
, m_disBdofDmvrFlag ( false )
#endif
, m_uiTLayer ( 0 )
, m_bTLayerSwitchingFlag ( false )
, m_sliceMode ( NO_SLICES )
......@@ -193,6 +196,9 @@ void Slice::initSlice()
m_bFinalized=false;
m_disFracMMVD = false;
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
m_disBdofDmvrFlag = false;
#endif
m_substreamSizes.clear();
m_cabacInitFlag = false;
#if JVET_O0105_ICT
......@@ -695,6 +701,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
m_maxNumAffineMergeCand = pSrc->m_maxNumAffineMergeCand;
m_maxNumTriangleCand = pSrc->m_maxNumTriangleCand;
m_disFracMMVD = pSrc->m_disFracMMVD;
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
m_disBdofDmvrFlag = pSrc->m_disBdofDmvrFlag;
#endif
if( cpyAlmostAll ) m_encCABACTableIdx = pSrc->m_encCABACTableIdx;
m_splitConsOverrideFlag = pSrc->m_splitConsOverrideFlag;
m_uiMinQTSize = pSrc->m_uiMinQTSize;
......@@ -1401,6 +1410,9 @@ SPS::SPS()
, m_sbtmvpEnabledFlag (false)
, m_bdofEnabledFlag (false)
, m_fpelMmvdEnabledFlag ( false )
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
, m_BdofDmvrSlicePresentFlag ( false )
#endif
, m_uiBitsForPOC ( 8)
, m_numLongTermRefPicSPS ( 0)
#if MAX_TB_SIZE_SIGNALLING
......@@ -1458,14 +1470,14 @@ SPS::~SPS()
void SPS::createRPLList0(int numRPL)
{
m_RPLList0.destroy();
m_RPLList0.create(numRPL);
m_RPLList0.create(numRPL + 1);
m_numRPL0 = numRPL;
m_rpl1IdxPresentFlag = (m_numRPL0 != m_numRPL1) ? true : false;
}
void SPS::createRPLList1(int numRPL)
{
m_RPLList1.destroy();
m_RPLList1.create(numRPL);
m_RPLList1.create(numRPL + 1);
m_numRPL1 = numRPL;
m_rpl1IdxPresentFlag = (m_numRPL0 != m_numRPL1) ? true : false;
......
......@@ -713,6 +713,9 @@ private:
bool m_sbtmvpEnabledFlag;
bool m_bdofEnabledFlag;
bool m_fpelMmvdEnabledFlag;
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
bool m_BdofDmvrSlicePresentFlag;
#endif
uint32_t m_uiBitsForPOC;
uint32_t m_numLongTermRefPicSPS;
uint32_t m_ltRefPicPocLsbSps[MAX_NUM_LONG_TERM_REF_PICS];
......@@ -911,6 +914,10 @@ public:
void setUseDMVR(bool b) { m_DMVR = b; }
bool getUseMMVD()const { return m_MMVD; }
void setUseMMVD(bool b) { m_MMVD = b; }
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
bool getBdofDmvrSlicePresentFlag()const { return m_BdofDmvrSlicePresentFlag; }
void setBdofDmvrSlicePresentFlag(bool b) { m_BdofDmvrSlicePresentFlag = b; }
#endif
uint32_t getMaxTLayers() const { return m_uiMaxTLayers; }
void setMaxTLayers( uint32_t uiMaxTLayers ) { CHECK( uiMaxTLayers > MAX_TLAYER, "Invalid number T-layers" ); m_uiMaxTLayers = uiMaxTLayers; }
......@@ -1438,6 +1445,9 @@ private:
uint32_t m_maxNumAffineMergeCand;
uint32_t m_maxNumTriangleCand;
bool m_disFracMMVD;
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
bool m_disBdofDmvrFlag;
#endif
double m_lambdas[MAX_NUM_COMPONENT];
bool m_abEqualRef [NUM_REF_PIC_LIST_01][MAX_NUM_REF][MAX_NUM_REF];
......@@ -1685,6 +1695,10 @@ public:
uint32_t getMaxNumTriangleCand() const { return m_maxNumTriangleCand;}
void setDisFracMMVD( bool val ) { m_disFracMMVD = val; }
bool getDisFracMMVD() const { return m_disFracMMVD; }
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
void setDisBdofDmvrFlag(bool val) { m_disBdofDmvrFlag = val; }
bool getDisBdofDmvrFlag() const { return m_disBdofDmvrFlag; }
#endif
void setNoOutputPriorPicsFlag( bool val ) { m_noOutputPriorPicsFlag = val; }
bool getNoOutputPriorPicsFlag() const { return m_noOutputPriorPicsFlag; }
......
......@@ -50,6 +50,12 @@
#include <assert.h>
#include <cassert>
#define JVET_O0315_RDPCM_INTRAMODE_ALIGN 1 // JVET-O0200/O0205/O0296/O0342/O0463/O0542: Intra prediction mode alignment for BDPCM
#define JVET_O0284_CONDITION_SMVD_MVDL1ZEROFLAG 1 // JVET-O0284: condition sym_mvd_flag on mvd_l1_zero_flag
#define JVET_O0438_SPS_AFFINE_AMVR_FLAG 1 // JVET-O0438: affine AMVR control flag conditioned on affine control flag in SPS
#define JVET_O0052_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT 1 // JVET-O0052 Method-1: TU-level context coded bin constraint
#define JVET_O0105_ICT 1 // JVET-O0105: inter-chroma transform (ICT) as extension of joint chroma coding (JCC)
......@@ -110,6 +116,13 @@
#define JVET_O0126_BPWA_INDEX_CODING_FIX 1 // JVET-O0126 align BPWA index coding with specification
#define JVET_O0592_ENC_ME_IMP 1 // JVET-O0592 encoder ME improvement
#define JVET_O0108_DIS_DMVR_BDOF_CIIP 1 // JVET_O0108 CE9-2.2: disable DMVR and BDOF for CIIP
#define JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG 1 // JVET-O1140 slice level disable flag for BDOF and DMVR
#define FIX_DB_MAX_TRANSFORM_SIZE 1
#define MRG_SHARELIST_SHARSIZE 32
......
......@@ -1597,16 +1597,23 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
}
bool PU::checkDMVRCondition(const PredictionUnit& pu)
{
WPScalingParam *wp0;
WPScalingParam *wp1;
int refIdx0 = pu.refIdx[REF_PIC_LIST_0];
int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
pu.cs->slice->getWpScaling(REF_PIC_LIST_0, refIdx0, wp0);
pu.cs->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
WPScalingParam *wp0;
WPScalingParam *wp1;
int refIdx0 = pu.refIdx[REF_PIC_LIST_0];
int refIdx1 = pu.refIdx[REF_PIC_LIST_1];
pu.cu->slice->getWpScaling(REF_PIC_LIST_0, refIdx0, wp0);
pu.cu->slice->getWpScaling(REF_PIC_LIST_1, refIdx1, wp1);
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
if (pu.cs->sps->getUseDMVR() && (!pu.cs->slice->getDisBdofDmvrFlag()))
#else
if (pu.cs->sps->getUseDMVR())
#endif
{
return pu.mergeFlag
&& pu.mergeType == MRG_TYPE_DEFAULT_N
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
&& !pu.mhIntraFlag
#endif
&& !pu.cu->affine
&& !pu.mmvdMergeFlag
&& !pu.cu->mmvdSkip
......
......@@ -1180,10 +1180,14 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
if( cu.bdpcmMode )
{
#if JVET_O0315_RDPCM_INTRAMODE_ALIGN
cu.firstPU->intraDir[0] = cu.bdpcmMode == 2? VER_IDX : HOR_IDX;
#else
PredictionUnit *pu = cu.firstPU;
unsigned mpm_pred[NUM_MOST_PROBABLE_MODES];
PU::getIntraMPMs(*pu, mpm_pred);
cu.firstPU->intraDir[0] = mpm_pred[0];
#endif
return;
}
......
......@@ -1207,6 +1207,9 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
}
if (pcSlice->getSPS()->getUseSMVD() && pcSlice->getCheckLDC() == false
#if JVET_O0284_CONDITION_SMVD_MVDL1ZEROFLAG
&& pcSlice->getMvdL1ZeroFlag() == false
#endif
)
{
int currPOC = pcSlice->getPOC();
......
......@@ -184,7 +184,7 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
resetGbiCodingOrder(true, cs);
}
if ((cs.slice->getSliceType() != I_SLICE || cs.sps->getIBCFlag()) && ctuXPosInCtus == 0)
if ((cs.slice->getSliceType() != I_SLICE || cs.sps->getIBCFlag()) && ctuXPosInCtus == tileXPosInCtus)
{
cs.motionLut.lut.resize(0);
cs.motionLut.lutIbc.resize(0);
......
......@@ -1087,7 +1087,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
//Read candidate for List0
READ_UVLC(uiCode, "num_ref_pic_lists_in_sps[0]");
uint32_t numberOfRPL = uiCode;
pcSPS->createRPLList0(numberOfRPL + 1);
pcSPS->createRPLList0(numberOfRPL);
RPLList* rplList = pcSPS->getRPLList0();
ReferencePictureList* rpl;
for (uint32_t ii = 0; ii < numberOfRPL; ii++)
......@@ -1101,7 +1101,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
{
READ_UVLC(uiCode, "num_ref_pic_lists_in_sps[1]");
numberOfRPL = uiCode;
pcSPS->createRPLList1(numberOfRPL + 1);
pcSPS->createRPLList1(numberOfRPL);
rplList = pcSPS->getRPLList1();
for (uint32_t ii = 0; ii < numberOfRPL; ii++)
{
......@@ -1216,9 +1216,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
READ_FLAG( uiCode, "sps_amvr_enabled_flag" ); pcSPS->setAMVREnabledFlag ( uiCode != 0 );
READ_FLAG( uiCode, "sps_bdof_enabled_flag" ); pcSPS->setBDOFEnabledFlag ( uiCode != 0 );
#if !JVET_O0438_SPS_AFFINE_AMVR_FLAG
READ_FLAG( uiCode, "sps_affine_amvr_enabled_flag" ); pcSPS->setAffineAmvrEnabledFlag ( uiCode != 0 );
#endif
READ_FLAG(uiCode, "sps_dmvr_enable_flag"); pcSPS->setUseDMVR(uiCode != 0);
READ_FLAG(uiCode, "sps_mmvd_enable_flag"); pcSPS->setUseMMVD(uiCode != 0);
// KJS: sps_cclm_enabled_flag
......@@ -1241,6 +1241,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
if ( pcSPS->getUseAffine() )
{
READ_FLAG( uiCode, "affine_type_flag" ); pcSPS->setUseAffineType ( uiCode != 0 );
#if JVET_O0438_SPS_AFFINE_AMVR_FLAG
READ_FLAG( uiCode, "sps_affine_amvr_enabled_flag" ); pcSPS->setAffineAmvrEnabledFlag ( uiCode != 0 );
#endif
}
READ_FLAG( uiCode, "gbi_flag" ); pcSPS->setUseGBi ( uiCode != 0 );
READ_FLAG(uiCode, "ibc_flag"); pcSPS->setIBCFlag(uiCode);
......@@ -1251,7 +1254,12 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
{
READ_FLAG( uiCode, "sps_fpel_mmvd_enabled_flag" ); pcSPS->setFpelMmvdEnabledFlag ( uiCode != 0 );
}
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
if (pcSPS->getBDOFEnabledFlag() || pcSPS->getUseDMVR())
{
READ_FLAG(uiCode, "sps_bdof_dmvr_slice_level_present_flag"); pcSPS->setBdofDmvrSlicePresentFlag(uiCode != 0);
}
#endif
READ_FLAG( uiCode, "triangle_flag" ); pcSPS->setUseTriangle ( uiCode != 0 );
READ_FLAG( uiCode, "sps_mip_flag"); pcSPS->setUseMIP ( uiCode != 0 );
......@@ -1982,6 +1990,13 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
READ_FLAG( uiCode, "tile_group_fracmmvd_disabled_flag" );
pcSlice->setDisFracMMVD( uiCode ? true : false );
}
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
if (sps->getBdofDmvrSlicePresentFlag())
{
READ_FLAG(uiCode, "tile_group_bdof_dmvr_disabled_flag");
pcSlice->setDisBdofDmvrFlag(uiCode ? true : false);
}
#endif
if (sps->getUseTriangle() && pcSlice->getMaxNumMergeCand() >= 2)
{
READ_UVLC(uiCode, "max_num_merge_cand_minus_max_num_triangle_cand");
......
......@@ -969,10 +969,14 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
if( cu.bdpcmMode )
{
#if JVET_O0315_RDPCM_INTRAMODE_ALIGN
cu.firstPU->intraDir[0] = cu.bdpcmMode == 2? VER_IDX : HOR_IDX;
#else
PredictionUnit *pu = cu.firstPU;
unsigned mpm_pred[NUM_MOST_PROBABLE_MODES];
PU::getIntraMPMs( *pu, mpm_pred );
cu.firstPU->intraDir[0] = mpm_pred[0];
#endif
return;
}
......
......@@ -130,6 +130,9 @@ void EncCu::create( EncCfg* encCfg )
for (unsigned ui = 0; ui < MRG_MAX_NUM_CANDS; ui++)
{
m_acRealMergeBuffer[ui].create(chromaFormat, Area(0, 0, uiMaxWidth, uiMaxHeight));
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
m_acMergeTmpBuffer[ui].create(chromaFormat, Area(0, 0, uiMaxWidth, uiMaxHeight));
#endif
}
const unsigned maxNumTriangleCand = encCfg->getMaxNumTriangleCand();
for (unsigned i = 0; i < maxNumTriangleCand; i++)
......@@ -218,6 +221,9 @@ void EncCu::destroy()
for (unsigned ui = 0; ui < MRG_MAX_NUM_CANDS; ui++)
{
m_acRealMergeBuffer[ui].destroy();
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
m_acMergeTmpBuffer[ui].destroy();
#endif
}
for( unsigned ui = 0; ui < TRIANGLE_MAX_NUM_CANDS; ui++ )
{
......@@ -266,6 +272,9 @@ void EncCu::init( EncLib* pcEncLib, const SPS& sps PARL_PARAM( const int tId ) )
m_modeCtrl->init( m_pcEncCfg, m_pcRateCtrl, m_pcRdCost );
m_pcInterSearch->setModeCtrl( m_modeCtrl );
#if JVET_O0592_ENC_ME_IMP
m_modeCtrl->setInterSearch(m_pcInterSearch);
#endif
m_pcIntraSearch->setModeCtrl( m_modeCtrl );
if ( ( m_pcEncCfg->getIBCHashSearch() && m_pcEncCfg->getIBCMode() ) || m_pcEncCfg->getAllowDisFracMMVD() )
......@@ -1188,6 +1197,14 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
AffineMVInfo tmpMVInfo;
bool isAffMVInfoSaved;
m_pcInterSearch->savePrevAffMVInfo(0, tmpMVInfo, isAffMVInfoSaved);
#if JVET_O0592_ENC_ME_IMP
BlkUniMvInfo tmpUniMvInfo;
bool isUniMvInfoSaved = false;
if (!tempCS->slice->isIntra())
{
m_pcInterSearch->savePrevUniMvInfo(tempCS->area.Y(), tmpUniMvInfo, isUniMvInfoSaved);
}
#endif
do
{
......@@ -1319,6 +1336,12 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
if (isAffMVInfoSaved)
m_pcInterSearch->addAffMVInfo(tmpMVInfo);
#if JVET_O0592_ENC_ME_IMP
if (!tempCS->slice->isIntra() && isUniMvInfoSaved)
{
m_pcInterSearch->addUniMvInfo(tmpUniMvInfo);
}
#endif
tempCS->motionLut = oldMotionLut;
......@@ -1864,6 +1887,9 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
bool bestIsSkip = false;
bool bestIsMMVDSkip = true;
PelUnitBuf acMergeBuffer[MRG_MAX_NUM_CANDS];
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
PelUnitBuf acMergeTmpBuffer[MRG_MAX_NUM_CANDS];
#endif
PelUnitBuf acMergeRealBuffer[MMVD_MRG_MAX_RD_BUF_NUM];
PelUnitBuf * acMergeTempBuffer[MMVD_MRG_MAX_RD_NUM];
PelUnitBuf * singleMergeTempBuffer;
......@@ -1985,7 +2011,12 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
PU::spanMotionInfo( pu, mergeCtx );
pu.mvRefine = true;
distParam.cur = singleMergeTempBuffer->Y();
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
acMergeTmpBuffer[uiMergeCand] = m_acMergeTmpBuffer[uiMergeCand].getBuf(localUnitArea);
m_pcInterSearch->motionCompensation(pu, *singleMergeTempBuffer, REF_PIC_LIST_X, true, true, &(acMergeTmpBuffer[uiMergeCand]));
#else
m_pcInterSearch->motionCompensation(pu, *singleMergeTempBuffer);
#endif
acMergeBuffer[uiMergeCand] = m_acRealMergeBuffer[uiMergeCand].getBuf(localUnitArea);
acMergeBuffer[uiMergeCand].copyFrom(*singleMergeTempBuffer);
pu.mvRefine = false;
......@@ -2049,7 +2080,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
for (uint32_t mergeCnt = 0; mergeCnt < std::min(std::min(NUM_MRG_SATD_CAND, (const int)mergeCtx.numValidMergeCand), 4); mergeCnt++)
{
uint32_t mergeCand = MHIntraMergeCand[mergeCnt];
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
acMergeTmpBuffer[mergeCand] = m_acMergeTmpBuffer[mergeCand].getBuf(localUnitArea);
#else
acMergeBuffer[mergeCand] = m_acRealMergeBuffer[mergeCand].getBuf(localUnitArea);
#endif
// estimate merge bits
mergeCtx.setMergeInfo(pu, mergeCand);
......@@ -2064,7 +2099,11 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
m_pcIntraSearch->predIntraAng(COMPONENT_Y, pu.cs->getPredBuf(pu).Y(), pu);
m_pcIntraSearch->switchBuffer(pu, COMPONENT_Y, pu.cs->getPredBuf(pu).Y(), m_pcIntraSearch->getPredictorPtr2(COMPONENT_Y, intraCnt));
}
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
pu.cs->getPredBuf(pu).copyFrom(acMergeTmpBuffer[mergeCand]);
#else
pu.cs->getPredBuf(pu).copyFrom(acMergeBuffer[mergeCand]);
#endif
if (pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
{
pu.cs->getPredBuf(pu).Y().rspSignal(m_pcReshape->getFwdLUT());
......@@ -2287,17 +2326,29 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
{
uint32_t bufIdx = 0;
PelBuf tmpBuf = tempCS->getPredBuf(pu).Y();
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Y());
#else
tmpBuf.copyFrom(acMergeBuffer[uiMergeCand].Y());
#endif
if (pu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
{
tmpBuf.rspSignal(m_pcReshape->getFwdLUT());
}
m_pcIntraSearch->geneWeightedPred(COMPONENT_Y, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Y, bufIdx));
tmpBuf = tempCS->getPredBuf(pu).Cb();
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cb());
#else
tmpBuf.copyFrom(acMergeBuffer[uiMergeCand].Cb());
#endif
m_pcIntraSearch->geneWeightedPred(COMPONENT_Cb, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Cb, bufIdx));
tmpBuf = tempCS->getPredBuf(pu).Cr();
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cr());
#else
tmpBuf.copyFrom(acMergeBuffer[uiMergeCand].Cr());
#endif
m_pcIntraSearch->geneWeightedPred(COMPONENT_Cr, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Cr, bufIdx));
}
else
......
......@@ -123,6 +123,9 @@ private:
PelStorage m_acMergeBuffer[MMVD_MRG_MAX_RD_BUF_NUM];
PelStorage m_acRealMergeBuffer[MRG_MAX_NUM_CANDS];
#if JVET_O0108_DIS_DMVR_BDOF_CIIP
PelStorage m_acMergeTmpBuffer[MRG_MAX_NUM_CANDS];
#endif
PelStorage m_acTriangleWeightedBuffer[TRIANGLE_MAX_NUM_CANDS]; // to store weighted prediction pixles
double m_mergeBestSATDCost;
MotionInfo m_SubPuMiBuf [( MAX_CU_SIZE * MAX_CU_SIZE ) >> ( MIN_CU_LOG2 << 1 )];
......
......@@ -1804,6 +1804,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
}
if ( pcSlice->getSPS()->getUseSMVD() && pcSlice->getCheckLDC() == false
#if JVET_O0284_CONDITION_SMVD_MVDL1ZEROFLAG
&& pcSlice->getMvdL1ZeroFlag() == false
#endif
)
{
int currPOC = pcSlice->getPOC();
......
......@@ -931,6 +931,9 @@ void EncLib::xInitSPS(SPS &sps)
sps.setUseTriangle ( m_Triangle );
sps.setUseMMVD ( m_MMVD );
sps.setFpelMmvdEnabledFlag (( m_MMVD ) ? m_allowDisFracMMVD : false);
#if JVET_O1140_SLICE_DISABLE_BDOF_DMVR_FLAG
sps.setBdofDmvrSlicePresentFlag(m_DMVR || m_BIO);
#endif
sps.setAffineAmvrEnabledFlag ( m_AffineAmvr );
sps.setUseDMVR ( m_DMVR );
......@@ -1291,8 +1294,8 @@ void EncLib::xInitRPL(SPS &sps, bool isFieldCoding)
ReferencePictureList* rpl;
int numRPLCandidates = getRPLCandidateSize(0);
sps.createRPLList0(numRPLCandidates + 1);
sps.createRPLList1(numRPLCandidates + 1);
sps.createRPLList0(numRPLCandidates);
sps.createRPLList1(numRPLCandidates);
RPLList* rplList = 0;
for (int i = 0; i < 2; i++)
......@@ -1317,7 +1320,7 @@ void EncLib::xInitRPL(SPS &sps, bool isFieldCoding)
//Check RPLL0 first
const RPLList* rplList0 = sps.getRPLList0();
const RPLList* rplList1 = sps.getRPLList1();
uint32_t numberOfRPL = sps.getNumRPL0() - 1;
uint32_t numberOfRPL = sps.getNumRPL0();
bool isAllEntriesinRPLHasSameSignFlag = true;
bool isFirstEntry = true;
......@@ -1339,7 +1342,7 @@ void EncLib::xInitRPL(SPS &sps, bool isFieldCoding)
}
}
//Check RPLL1. Skip it if it is already found out that this flag is not true for RPL0 or if RPL1 is the same as RPL0
numberOfRPL = sps.getNumRPL1() - 1;
numberOfRPL = sps.getNumRPL1();
isFirstEntry = true;
lastSign = true;
for (uint32_t ii = 0; isAllEntriesinRPLHasSameSignFlag && !sps.getRPL1CopyFromRPL0Flag() && ii < numberOfRPL; ii++)
......
......@@ -1795,6 +1795,18 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
{
CHECK( encTestmode.type != ETM_POST_DONT_SPLIT, "Unknown mode" );
#if JVET_O0592_ENC_ME_IMP
if ((cuECtx.get<double>(BEST_NO_IMV_COST) == (MAX_DOUBLE * .5) || cuECtx.get<bool>(IS_REUSING_CU)) && !slice.isIntra())
{
unsigned idx1, idx2, idx3, idx4;
getAreaIdx(partitioner.currArea().Y(), *slice.getPPS()->pcv, idx1, idx2, idx3, idx4);
if (g_isReusedUniMVsFilled[idx1][idx2][idx3][idx4])
{
m_pcInterSearch->insertUniMvCands(partitioner.currArea().Y(), g_reusedUniMVs[idx1][idx2][idx3][idx4]);
}
}
#endif
if( !bestCS || ( bestCS && isModeSplit( bestMode ) ) )
{
return false;
......
......@@ -43,6 +43,9 @@
#include "CommonLib/CommonDef.h"
#include "CommonLib/CodingStructure.h"
#if JVET_O0592_ENC_ME_IMP
#include "InterSearch.h"
#endif
#include <typeinfo>
#include <vector>
......@@ -258,6 +261,9 @@ protected:
#if ENABLE_SPLIT_PARALLELISM
int m_runNextInParallel;
#endif
#if JVET_O0592_ENC_ME_IMP
InterSearch* m_pcInterSearch;
#endif
public:
......@@ -315,6 +321,9 @@ public:
void setBestCostWithoutSplitFlags ( double cost ) { m_ComprCUCtxList.back().bestCostWithoutSplitFlags = cost; }
double getMtsFirstPassNoIspCost () const { return m_ComprCUCtxList.back().bestCostMtsFirstPassNoIsp; }
void setMtsFirstPassNoIspCost ( double cost ) { m_ComprCUCtxList.back().bestCostMtsFirstPassNoIsp = cost; }
#if JVET_O0592_ENC_ME_IMP
void setInterSearch (InterSearch* pcInterSearch) { m_pcInterSearch = pcInterSearch; }
#endif
protected:
void xExtractFeatures ( const EncTestMode encTestmode, CodingStructure& cs );
......
......@@ -1415,6 +1415,9 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c
writeBlockStatisticsHeader(sps);
#endif
m_pcInterSearch->resetAffineMVList();
#if JVET_O0592_ENC_ME_IMP
m_pcInterSearch->resetUniMvList();
#endif
encodeCtus( pcPic, bCompressEntireSlice, bFastDeltaQP, startCtuTsAddr, boundingCtuTsAddr, m_pcLib );
......@@ -1578,7 +1581,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
DTRACE_UPDATE( g_trace_ctx, std::make_pair( "ctu", ctuRsAddr ) );
if( pCfg->getSwitchPOC() != pcPic->poc || -1 == pCfg->getDebugCTU() )
if ((cs.slice->getSliceType() != I_SLICE || cs.sps->getIBCFlag()) && ctuXPosInCtus == 0)
if ((cs.slice->getSliceType() != I_SLICE || cs.sps->getIBCFlag()) && ctuXPosInCtus == tileXPosInCtus)
{
cs.motionLut.lut.resize(0);
cs.motionLut.lutIbc.resize(0);
......
......@@ -112,6 +112,11 @@ InterSearch::InterSearch()
m_affMVList = nullptr;
m_affMVListSize = 0;
m_affMVListIdx = 0;
#if JVET_O0592_ENC_ME_IMP
m_uniMvList = nullptr;
m_uniMvListSize = 0;
m_uniMvListIdx = 0;
#endif
m_histBestSbt = MAX_UCHAR;
m_histBestMtsIdx = MAX_UCHAR;
}
......@@ -156,6 +161,15 @@ void InterSearch::destroy()
}
m_affMVListIdx = 0;
m_affMVListSize = 0;
#if JVET_O0592_ENC_ME_IMP
if (m_uniMvList)
{
delete[] m_uniMvList;
m_uniMvList = nullptr;
}
m_uniMvListIdx = 0;
m_uniMvListSize = 0;
#endif
m_isInitialized = false;
}
......@@ -255,6 +269,15 @@ void InterSearch::init( EncCfg* pcEncCfg,
m_affMVList = new AffineMVInfo[m_affMVListMaxSize];
m_affMVListIdx = 0;
m_affMVListSize = 0;
#if JVET_O0592_ENC_ME_IMP
m_uniMvListMaxSize = 15;
if (!m_uniMvList)
{
m_uniMvList = new BlkUniMvInfo[m_uniMvListMaxSize];
}
m_uniMvListIdx = 0;
m_uniMvListSize = 0;
#endif
m_isInitialized = true;
}
......@@ -2399,6 +2422,18 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
}
}
#if JVET_O0592_ENC_ME_IMP
::memcpy(cMvHevcTemp, cMvTemp, sizeof(cMvTemp));
if (cu.imv == 0 && (!cu.slice->getSPS()->getUseGBi() || gbiIdx == GBI_DEFAULT))
{
insertUniMvCands(pu.Y(), cMvTemp);
unsigned idx1, idx2, idx3, idx4;
getAreaIdx(cu.Y(), *cu.slice->getPPS()->pcv, idx1, idx2, idx3, idx4);
::memcpy(&(g_reusedUniMVs[idx1][idx2][idx3][idx4][0][0]), cMvTemp, 2 * 33 * sizeof(Mv));
g_isReusedUniMVsFilled[idx1][idx2][idx3][idx4] = true;
}
#else
if (cu.Y().width > 8 && cu.Y().height > 8 && cu.slice->getSPS()->getUseAffine()
&& checkAffine
&& (gbiIdx == GBI_DEFAULT || m_affineModeSelected || !m_pcEncCfg->getUseGBiFast())
......@@ -2406,6 +2441,7 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
{
::memcpy( cMvHevcTemp, cMvTemp, sizeof( cMvTemp ) );
}
#endif
// Bi-predictive Motion estimation
if( ( cs.slice->isInterB() ) && ( PU::isBipredRestriction( pu ) == false )
&& (cu.slice->getCheckLDC() || gbiIdx == GBI_DEFAULT || !m_affineModeSelected || !m_pcEncCfg->getUseGBiFast())
......@@ -2648,11 +2684,48 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
costStart += m_pcRdCost->getCost(bits);
std::vector<Mv> symmvdCands;
#if JVET_O0592_ENC_ME_IMP
auto smmvdCandsGen = [&](Mv mvCand, bool mvPrecAdj)
{
if (mvPrecAdj && pu.cu->imv)
{
mvCand.roundIbcPrecInternal2Amvr(pu.cu->imv);
}
bool toAddMvCand = true;
for (std::vector<Mv>::iterator pos = symmvdCands.begin(); pos != symmvdCands.end(); pos++)
{
if (*pos == mvCand)
{
toAddMvCand = false;
break;
}
}
if (toAddMvCand)
{
symmvdCands.push_back(mvCand);
}
};
smmvdCandsGen(cMvHevcTemp[curRefList][refIdxCur], false);
smmvdCandsGen(cMvTemp[curRefList][refIdxCur], false);
if (iRefIdxBi[curRefList] == refIdxCur)
{
smmvdCandsGen(cMvBi[curRefList], false);
}
for (int i = 0; i < m_uniMvListSize; i++)
{
BlkUniMvInfo* curMvInfo = m_uniMvList + ((m_uniMvListIdx - 1 - i + m_uniMvListMaxSize) % (m_uniMvListMaxSize));
smmvdCandsGen(curMvInfo->uniMvs[curRefList][refIdxCur], true);
}
#else
symmvdCands.push_back(cMvTemp[curRefList][refIdxCur]);
if (iRefIdxBi[curRefList] == refIdxCur && cMvBi[curRefList] != cMvTemp[curRefList][refIdxCur])
{
symmvdCands.push_back(cMvBi[curRefList]);
}
#endif
for (auto mvStart : symmvdCands)
{
......@@ -2662,7 +2735,13 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
checked |= (mvStart == aacAMVPInfo[curRefList][refIdxCur].mvCand[i]);
}
if (checked)
#if JVET_O0592_ENC_ME_IMP
{
continue;
}
#else
break;
#endif
Distortion bestCost = costStart;
symmvdCheckBestMvp(pu, origBuf, mvStart, (RefPicList)curRefList, aacAMVPInfo, gbiIdx, cMvPredSym, mvpIdxSym, costStart);
......@@ -3288,13 +3367,63 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
// Do integer search
if( ( m_motionEstimationSearchMethod == MESEARCH_FULL ) || bBi || bQTBTMV )
{
#if JVET_O0592_ENC_ME_IMP
cStruct.subShiftMode = m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE3 ? 2 : 0;
m_pcRdCost->setDistParam(m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode);
Mv bestInitMv = (bBi ? rcMv : rcMvPred);
Mv cTmpMv = bestInitMv;
clipMv(cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps);
cTmpMv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
m_cDistParam.cur.buf = cStruct.piRefY + (cTmpMv.ver * cStruct.iRefStride) + cTmpMv.hor;
Distortion uiBestSad = m_cDistParam.distFunc(m_cDistParam);
uiBestSad += m_pcRdCost->getCostOfVectorWithPredictor(cTmpMv.hor, cTmpMv.ver, cStruct.imvShift);
for (int i = 0; i < m_uniMvListSize; i++)
{
BlkUniMvInfo* curMvInfo = m_uniMvList + ((m_uniMvListIdx - 1 - i + m_uniMvListMaxSize) % (m_uniMvListMaxSize));
int j = 0;
for (; j < i; j++)
{
BlkUniMvInfo *prevMvInfo = m_uniMvList + ((m_uniMvListIdx - 1 - j + m_uniMvListMaxSize) % (m_uniMvListMaxSize));
if (curMvInfo->uniMvs[eRefPicList][iRefIdxPred] == prevMvInfo->uniMvs[eRefPicList][iRefIdxPred])
{
break;
}
}
if (j < i)
continue;
cTmpMv = curMvInfo->uniMvs[eRefPicList][iRefIdxPred];
clipMv(cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps);
cTmpMv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
m_cDistParam.cur.buf = cStruct.piRefY + (cTmpMv.ver * cStruct.iRefStride) + cTmpMv.hor;
Distortion uiSad = m_cDistParam.distFunc(m_cDistParam);
uiSad += m_pcRdCost->getCostOfVectorWithPredictor(cTmpMv.hor, cTmpMv.ver, cStruct.imvShift);
if (uiSad < uiBestSad)
{
uiBestSad = uiSad;
bestInitMv = curMvInfo->uniMvs[eRefPicList][iRefIdxPred];
m_cDistParam.maximumDistortionForEarlyExit = uiSad;
}
}
#endif
if( !bQTBTMV )
{
#if JVET_O0592_ENC_ME_IMP
xSetSearchRange(pu, bestInitMv, iSrchRng, cStruct.searchRange
#else
xSetSearchRange(pu, (bBi ? rcMv : rcMvPred), iSrchRng, cStruct.searchRange
#endif
, cStruct
);
}
#if !JVET_O0592_ENC_ME_IMP
cStruct.subShiftMode = m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE3 ? 2 : 0;
#endif
xPatternSearch( cStruct, rcMv, ruiCost);
}
else if( bQTBTMV2 )
......@@ -3303,7 +3432,11 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
cStruct.subShiftMode = ( !m_pcEncCfg->getRestrictMESampling() && m_pcEncCfg->getMotionEstimationSearchMethod() == MESEARCH_SELECTIVE ) ? 1 :
( m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE3 ) ? 2 : 0;
#if JVET_O0592_ENC_ME_IMP
xTZSearch(pu, eRefPicList, iRefIdxPred, cStruct, rcMv, ruiCost, NULL, false, true);
#else
xTZSearch( pu, cStruct, rcMv, ruiCost, NULL, false, true );
#endif
}
else
{
......@@ -3311,7 +3444,11 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref
( m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE3 ) ? 2 : 0;
rcMv = rcMvPred;
const Mv *pIntegerMv2Nx2NPred = 0;
#if JVET_O0592_ENC_ME_IMP
xPatternSearchFast(pu, eRefPicList, iRefIdxPred, cStruct, rcMv, ruiCost, pIntegerMv2Nx2NPred);
#else
xPatternSearchFast( pu, cStruct, rcMv, ruiCost, pIntegerMv2Nx2NPred );
#endif
if( blkCache )
{
blkCache->setMv( pu.cs->area, eRefPicList, iRefIdxPred, rcMv );
......@@ -3471,6 +3608,10 @@ void InterSearch::xPatternSearch( IntTZSearchStruct& cStruct,
void InterSearch::xPatternSearchFast( const PredictionUnit& pu,
#if JVET_O0592_ENC_ME_IMP
RefPicList eRefPicList,
int iRefIdxPred,
#endif
IntTZSearchStruct& cStruct,
Mv& rcMv,
Distortion& ruiSAD,
......@@ -3479,15 +3620,27 @@ void InterSearch::xPatternSearchFast( const PredictionUnit& pu,
switch ( m_motionEstimationSearchMethod )
{
case MESEARCH_DIAMOND:
#if JVET_O0592_ENC_ME_IMP
xTZSearch ( pu, eRefPicList, iRefIdxPred, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred, false );
#else
xTZSearch ( pu, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred, false );
#endif
break;
case MESEARCH_SELECTIVE:
#if JVET_O0592_ENC_ME_IMP
xTZSearchSelective( pu, eRefPicList, iRefIdxPred, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred );
#else
xTZSearchSelective( pu, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred );
#endif
break;
case MESEARCH_DIAMOND_ENHANCED:
#if JVET_O0592_ENC_ME_IMP
xTZSearch ( pu, eRefPicList, iRefIdxPred, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred, true );
#else
xTZSearch ( pu, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred, true );
#endif
break;
case MESEARCH_FULL: // shouldn't get here.
......@@ -3498,6 +3651,10 @@ void InterSearch::xPatternSearchFast( const PredictionUnit& pu,
void InterSearch::xTZSearch( const PredictionUnit& pu,
#if JVET_O0592_ENC_ME_IMP
RefPicList eRefPicList,
int iRefIdxPred,
#endif
IntTZSearchStruct& cStruct,
Mv& rcMv,
Distortion& ruiSAD,
......@@ -3588,6 +3745,41 @@ void InterSearch::xTZSearch( const PredictionUnit& pu,
xTZSearchHelp( cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
}
}
#if JVET_O0592_ENC_ME_IMP
for (int i = 0; i < m_uniMvListSize; i++)
{
BlkUniMvInfo* curMvInfo = m_uniMvList + ((m_uniMvListIdx - 1 - i + m_uniMvListMaxSize) % (m_uniMvListMaxSize));
int j = 0;
for (; j < i; j++)
{
BlkUniMvInfo *prevMvInfo = m_uniMvList + ((m_uniMvListIdx - 1 - j + m_uniMvListMaxSize) % (m_uniMvListMaxSize));
if (curMvInfo->uniMvs[eRefPicList][iRefIdxPred] == prevMvInfo->uniMvs[eRefPicList][iRefIdxPred])
{
break;
}
}
if (j < i)
continue;
Mv cTmpMv = curMvInfo->uniMvs[eRefPicList][iRefIdxPred];
clipMv(cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps);
cTmpMv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
m_cDistParam.cur.buf = cStruct.piRefY + (cTmpMv.ver * cStruct.iRefStride) + cTmpMv.hor;
Distortion uiSad = m_cDistParam.distFunc(m_cDistParam);
uiSad += m_pcRdCost->getCostOfVectorWithPredictor(cTmpMv.hor, cTmpMv.ver, cStruct.imvShift);
if (uiSad < cStruct.uiBestSad)
{
cStruct.uiBestSad = uiSad;
cStruct.iBestX = cTmpMv.hor;
cStruct.iBestY = cTmpMv.ver;
m_cDistParam.maximumDistortionForEarlyExit = uiSad;
}
}
#endif
{
// set search range
Mv currBestMv(cStruct.iBestX, cStruct.iBestY );
......@@ -3804,6 +3996,10 @@ void InterSearch::xTZSearch( const PredictionUnit& pu,
void InterSearch::xTZSearchSelective( const PredictionUnit& pu,
#if JVET_O0592_ENC_ME_IMP
RefPicList eRefPicList,
int iRefIdxPred,
#endif
IntTZSearchStruct& cStruct,
Mv &rcMv,
Distortion &ruiSAD,
......@@ -3859,6 +4055,41 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu,
xTZSearchHelp( cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
}
#if JVET_O0592_ENC_ME_IMP
for (int i = 0; i < m_uniMvListSize; i++)
{
BlkUniMvInfo* curMvInfo = m_uniMvList + ((m_uniMvListIdx - 1 - i + m_uniMvListMaxSize) % (m_uniMvListMaxSize));
int j = 0;
for (; j < i; j++)
{
BlkUniMvInfo *prevMvInfo = m_uniMvList + ((m_uniMvListIdx - 1 - j + m_uniMvListMaxSize) % (m_uniMvListMaxSize));
if (curMvInfo->uniMvs[eRefPicList][iRefIdxPred] == prevMvInfo->uniMvs[eRefPicList][iRefIdxPred])
{
break;
}
}
if (j < i)
continue;
Mv cTmpMv = curMvInfo->uniMvs[eRefPicList][iRefIdxPred];
clipMv(cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps);
cTmpMv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT);
m_cDistParam.cur.buf = cStruct.piRefY + (cTmpMv.ver * cStruct.iRefStride) + cTmpMv.hor;
Distortion uiSad = m_cDistParam.distFunc(m_cDistParam);
uiSad += m_pcRdCost->getCostOfVectorWithPredictor(cTmpMv.hor, cTmpMv.ver, cStruct.imvShift);
if (uiSad < cStruct.uiBestSad)
{
cStruct.uiBestSad = uiSad;
cStruct.iBestX = cTmpMv.hor;
cStruct.iBestY = cTmpMv.ver;
m_cDistParam.maximumDistortionForEarlyExit = uiSad;
}
}
#endif
{
// set search range
Mv currBestMv(cStruct.iBestX, cStruct.iBestY );
......@@ -5445,6 +5676,7 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
const uint32_t mvShift = mvShiftTable[pu.cu->imv];
if (uiCostBest <= AFFINE_ME_LIST_MVP_TH*m_hevcCost)
{
#if !JVET_O0592_ENC_ME_IMP
//search 8 nearest neighbors; integer distance
int testPos[8][2] = { { -1, 0 },{ 0, -1 },{ 0, 1 },{ 1, 0 },{ -1, -1 },{ -1, 1 },{ 1, 1 },{ 1, -1 } };
const int maxSearchRound = 3;
......@@ -5491,6 +5723,7 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
}
}
}
#endif
Mv mvPredTmp[3] = { acMvPred[0], acMvPred[1], acMvPred[2] };
Mv mvME[3];
......@@ -5535,6 +5768,57 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu,
checkCPMVRdCost(acMvTemp);
}
#if JVET_O0592_ENC_ME_IMP
// 8 nearest neighbor search
int testPos[8][2] = { { -1, 0 },{ 0, -1 },{ 0, 1 },{ 1, 0 },{ -1, -1 },{ -1, 1 },{ 1, 1 },{ 1, -1 } };
const int maxSearchRound = (pu.cu->imv) ? 3 : ((m_pcEncCfg->getUseAffineAmvrEncOpt() && m_pcEncCfg->getIntraPeriod() == (uint32_t)-1) ? 2