diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index 6c53825bec82e618483d8fb95a161c3c70554d1b..802a7cdc7b5c85b804cedef18b6732c5d50fa4bc 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -512,6 +512,15 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred) #if JVET_N0266_SMALL_BLOCKS CHECK( !pu.cu->affine && pu.refIdx[0] >= 0 && pu.refIdx[1] >= 0 && ( pu.lwidth() + pu.lheight() == 12 ), "invalid 4x8/8x4 bi-predicted blocks" ); #endif +#if JVET_N0146_DMVR_BDOF_CONDITION + 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); +#endif + bool bioApplied = false; if (pu.cs->sps->getBDOFEnabledFlag()) { @@ -521,7 +530,11 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred) } else { +#if JVET_N0146_DMVR_BDOF_CONDITION + const bool biocheck0 = !((wp0[COMPONENT_Y].bPresentFlag || wp1[COMPONENT_Y].bPresentFlag) && slice.getSliceType() == B_SLICE); +#else const bool biocheck0 = !(pps.getWPBiPred() && slice.getSliceType() == B_SLICE); +#endif const bool biocheck1 = !(pps.getUseWP() && slice.getSliceType() == P_SLICE); if (biocheck0 && biocheck1 @@ -597,6 +610,33 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred) } } } +#if JVET_N0146_DMVR_BDOF_CONDITION + CPelUnitBuf srcPred0 = ( pu.chromaFormat == CHROMA_400 ? + CPelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvPred[0][0], pcYuvPred.Y())) : + CPelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvPred[0][0], pcYuvPred.Y()), PelBuf(m_acYuvPred[0][1], pcYuvPred.Cb()), PelBuf(m_acYuvPred[0][2], pcYuvPred.Cr())) ); + CPelUnitBuf srcPred1 = ( pu.chromaFormat == CHROMA_400 ? + CPelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvPred[1][0], pcYuvPred.Y())) : + CPelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvPred[1][0], pcYuvPred.Y()), PelBuf(m_acYuvPred[1][1], pcYuvPred.Cb()), PelBuf(m_acYuvPred[1][2], pcYuvPred.Cr())) ); + if( (!dmvrApplied) && (!bioApplied) && pps.getWPBiPred() && slice.getSliceType() == B_SLICE && pu.cu->GBiIdx==GBI_DEFAULT) + { + xWeightedPredictionBi( pu, srcPred0, srcPred1, pcYuvPred, m_maxCompIDToPred ); + } + else if( pps.getUseWP() && slice.getSliceType() == P_SLICE ) + { + xWeightedPredictionUni( pu, srcPred0, REF_PIC_LIST_0, pcYuvPred, -1, m_maxCompIDToPred ); + } + else + { + if (dmvrApplied) + { + xProcessDMVR(pu, pcYuvPred, slice.clpRngs(), bioApplied); + } + else + { + xWeightedAverage( pu, srcPred0, srcPred1, pcYuvPred, slice.getSPS()->getBitDepths(), slice.clpRngs(), bioApplied ); + } + } +#else if (dmvrApplied) { xProcessDMVR(pu, pcYuvPred, slice.clpRngs(), bioApplied); @@ -624,6 +664,7 @@ void InterPrediction::xPredInterBi(PredictionUnit& pu, PelUnitBuf &pcYuvPred) xWeightedAverage( pu, srcPred0, srcPred1, pcYuvPred, slice.getSPS()->getBitDepths(), slice.clpRngs(), bioApplied ); } } +#endif } void InterPrediction::xPredInterBlk ( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv& _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng @@ -1151,7 +1192,28 @@ void InterPrediction::xWeightedAverage(const PredictionUnit& pu, const CPelUnitB pcYuvDst.bufs[0].addAvg(CPelBuf(pSrcY0, src0Stride, pu.lumaSize()), CPelBuf(pSrcY1, src1Stride, pu.lumaSize()), clpRngs.comp[0]); } } +#if JVET_N0146_DMVR_BDOF_CONDITION + if (pu.cs->pps->getWPBiPred()) + { + const int iRefIdx0 = pu.refIdx[0]; + const int iRefIdx1 = pu.refIdx[1]; + WPScalingParam *pwp0; + WPScalingParam *pwp1; + getWpScaling(pu.cu->slice, iRefIdx0, iRefIdx1, pwp0, pwp1); + if (!bioApplied) + { + addWeightBiComponent(pcYuvSrc0, pcYuvSrc1, pu.cu->slice->clpRngs(), pwp0, pwp1, pcYuvDst, true, COMPONENT_Y); + } + addWeightBiComponent(pcYuvSrc0, pcYuvSrc1, pu.cu->slice->clpRngs(), pwp0, pwp1, pcYuvDst, true, COMPONENT_Cb); + addWeightBiComponent(pcYuvSrc0, pcYuvSrc1, pu.cu->slice->clpRngs(), pwp0, pwp1, pcYuvDst, true, COMPONENT_Cr); + } + else + { + pcYuvDst.addAvg(pcYuvSrc0, pcYuvSrc1, clpRngs, bioApplied); + } +#else pcYuvDst.addAvg(pcYuvSrc0, pcYuvSrc1, clpRngs, bioApplied); +#endif } else if( iRefIdx0 >= 0 && iRefIdx1 < 0 ) { diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 057ef2e8fb4451fce176aeeab9c26e2f9b9be999..eae8e65c887ae847e7e85c98c9c8491700aa0a3d 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_N0146_DMVR_BDOF_CONDITION 1 // JVET-N146/N0162/N0442/N0153/N0262/N0440/N0086 applicable condition of DMVR and BDOF + #define JVET_N0470_SMVD_FIX 1 // remove mvd_l1_zero_flag condition, align to spec text. #define JVET_N0235_SMVD_SPS 1 diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 61e48236adcfd483dc8f066a04a25dfe035b11d2..43bfb9bf62cbc991ebbaf2473eab130a07b97cf6 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -1917,6 +1917,14 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, } bool PU::checkDMVRCondition(const PredictionUnit& pu) { +#if JVET_N0146_DMVR_BDOF_CONDITION + 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); +#endif if (pu.cs->sps->getUseDMVR()) { return pu.mergeFlag @@ -1931,6 +1939,10 @@ bool PU::checkDMVRCondition(const PredictionUnit& pu) && ((pu.lheight() * pu.lwidth()) >= 128) #else && ((pu.lheight() * pu.lwidth()) >= 64) +#endif +#if JVET_N0146_DMVR_BDOF_CONDITION + && (pu.cu->GBiIdx == GBI_DEFAULT) + && ((!wp0[COMPONENT_Y].bPresentFlag) && (!wp1[COMPONENT_Y].bPresentFlag)) #endif ; } diff --git a/source/Lib/CommonLib/WeightPrediction.cpp b/source/Lib/CommonLib/WeightPrediction.cpp index 8495736e89b85b9ef48ec2111027fd8a74986bcb..6a645952d4a6ce6aa898327960ab83f63e6b31a4 100644 --- a/source/Lib/CommonLib/WeightPrediction.cpp +++ b/source/Lib/CommonLib/WeightPrediction.cpp @@ -215,6 +215,64 @@ void WeightPrediction::addWeightBi(const CPelUnitBuf &pcYuvSrc0, } // compID loop } +#if JVET_N0146_DMVR_BDOF_CONDITION +void WeightPrediction::addWeightBiComponent(const CPelUnitBuf &pcYuvSrc0, + const CPelUnitBuf &pcYuvSrc1, + const ClpRngs &clpRngs, + const WPScalingParam *const wp0, + const WPScalingParam *const wp1, + PelUnitBuf &rpcYuvDst, + const bool bRoundLuma /*= true*/, + const ComponentID Comp) +{ + const bool enableRounding[MAX_NUM_COMPONENT] = { bRoundLuma, true, true }; + + const ComponentID compID = ComponentID(Comp); + + const Pel* src0 = pcYuvSrc0.bufs[compID].buf; + const Pel* src1 = pcYuvSrc1.bufs[compID].buf; + Pel* dst = rpcYuvDst.bufs[compID].buf; + + // Luma : -------------------------------------------- + const ClpRng& clpRng = clpRngs.comp[compID]; + const int w0 = wp0[compID].w; + const int offset = wp0[compID].offset; + const int clipBD = clpRng.bd; + const int shiftNum = std::max<int>(2, (IF_INTERNAL_PREC - clipBD)); + const int shift = wp0[compID].shift + shiftNum; + const int round = (enableRounding[compID] && (shift > 0)) ? (1 << (shift - 1)) : 0; + const int w1 = wp1[compID].w; + const int height = rpcYuvDst.bufs[compID].height; + const int width = rpcYuvDst.bufs[compID].width; + + const uint32_t src0Stride = pcYuvSrc0.bufs[compID].stride; + const uint32_t src1Stride = pcYuvSrc1.bufs[compID].stride; + const uint32_t dstStride = rpcYuvDst.bufs[compID].stride; + + for (int y = height - 1; y >= 0; y--) + { + // do it in batches of 4 (partial unroll) + int x = width - 1; + + for (; x >= 3; ) + { + dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); x--; + dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); x--; + dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); x--; + dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); x--; + } + for (; x >= 0; x--) + { + dst[x] = weightBidir(w0, src0[x], w1, src1[x], round, shift, offset, clpRng ); + } + + src0 += src0Stride; + src1 += src1Stride; + dst += dstStride; + } // y loop +} +#endif + void WeightPrediction::addWeightUni(const CPelUnitBuf &pcYuvSrc0, const ClpRngs &clpRngs, const WPScalingParam *const wp0, @@ -351,6 +409,10 @@ void WeightPrediction::xWeightedPredictionBi(const PredictionUnit &pu, CHECK( !pu.cs->pps->getWPBiPred(), "Weighted Bi-prediction disabled" ); +#if JVET_N0146_DMVR_BDOF_CONDITION + if (iRefIdx0 < 0 && iRefIdx1 < 0) return; +#endif + getWpScaling(pu.cu->slice, iRefIdx0, iRefIdx1, pwp0, pwp1, maxNumComp); if (iRefIdx0 >= 0 && iRefIdx1 >= 0) diff --git a/source/Lib/CommonLib/WeightPrediction.h b/source/Lib/CommonLib/WeightPrediction.h index 2cbb82fa608e06ad25ff95a80fbc822a7aa16c37..86671665fbb0281d99f56961040e69e2b334b8aa 100644 --- a/source/Lib/CommonLib/WeightPrediction.h +++ b/source/Lib/CommonLib/WeightPrediction.h @@ -71,6 +71,17 @@ public: const bool bRoundLuma = true, const ComponentID maxNumComp = MAX_NUM_COMPONENT ); +#if JVET_N0146_DMVR_BDOF_CONDITION + void addWeightBiComponent( const CPelUnitBuf &pcYuvSrc0, + const CPelUnitBuf &pcYuvSrc1, + const ClpRngs &clpRngs, + const WPScalingParam *const wp0, + const WPScalingParam *const wp1, + PelUnitBuf &rpcYuvDst, + const bool bRoundLuma = true, + const ComponentID Comp = COMPONENT_Y); +#endif + void addWeightUni( const CPelUnitBuf &pcYuvSrc0, const ClpRngs &clpRngs, const WPScalingParam *const wp0,