diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 73782942d09146ba761f6a8ae552e10c29f561bc..50d05215d9acb147a60f5cac4f7df2979b269c6c 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1621,6 +1621,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) m_framesToBeEncoded = int( m_framesToBeEncoded * m_fractionOfFrames ); } +#if RPR_ENABLE + if ( m_switchPocPeriod >= 0 ) +#endif if (m_resChangeInClvsEnabled && !m_switchPocPeriod) { m_switchPocPeriod = m_iFrameRate / 2 / m_iGOPSize * m_iGOPSize; diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.h b/source/Lib/CommonLib/AdaptiveLoopFilter.h index f453b63a885e58937b6d9a797517f1fa9b9ee6c8..bdcf249ce3c5911589a3af4ff48f4c7132633422 100644 --- a/source/Lib/CommonLib/AdaptiveLoopFilter.h +++ b/source/Lib/CommonLib/AdaptiveLoopFilter.h @@ -108,6 +108,9 @@ public: void ALFProcess(CodingStructure& cs); void create( const int picWidth, const int picHeight, const ChromaFormat format, const int maxCUWidth, const int maxCUHeight, const int maxCUDepth, const int inputBitDepth[MAX_NUM_CHANNEL_TYPE] ); void destroy(); +#if RPR_ENABLE + Size getAlfSize() { return Size(m_tempBuf.get(COMPONENT_Y).width, m_tempBuf.get(COMPONENT_Y).height); } +#endif #if ALF_IMPROVEMENT diff --git a/source/Lib/CommonLib/BilateralFilter.cpp b/source/Lib/CommonLib/BilateralFilter.cpp index 42cc8ae28661366f1073f7525f0ec62b903e2f93..43f1268e10cca9e6ce8e851cbbce31b712d79e04 100755 --- a/source/Lib/CommonLib/BilateralFilter.cpp +++ b/source/Lib/CommonLib/BilateralFilter.cpp @@ -824,8 +824,15 @@ void BilateralFilter::bilateralFilterDiamond5x5NoClip(const CPelUnitBuf& src, Pe const CompArea& myArea = currTU.blocks[COMPONENT_Y]; topAltAvailable = myArea.y - 2 >= 0; leftAltAvailable = myArea.x - 2 >= 0; +#if RPR_ENABLE + int curPicWidth = currTU.cu->cs->pcv->lumaWidth; + int curPicHeight = currTU.cu->cs->pcv->lumaHeight; + bool bottomAltAvailable = myArea.y + myArea.height + 1 < curPicHeight; + bool rightAltAvailable = myArea.x + myArea.width + 1 < curPicWidth; +#else bool bottomAltAvailable = myArea.y + myArea.height + 1 < currTU.cu->slice->getSPS()->getMaxPicHeightInLumaSamples(); bool rightAltAvailable = myArea.x + myArea.width + 1 < currTU.cu->slice->getSPS()->getMaxPicWidthInLumaSamples(); +#endif uint32_t uiWidthExt = uiWidth + (NUMBER_PADDED_SAMPLES << 1); uint32_t uiHeightExt = uiHeight + (NUMBER_PADDED_SAMPLES << 1); @@ -1051,9 +1058,16 @@ void BilateralFilter::bilateralFilterDiamond5x5(const CPelUnitBuf& src, PelUnitB const CompArea &myArea = currTU.blocks[COMPONENT_Y]; topAltAvailable = myArea.y - 2 >= 0; leftAltAvailable = myArea.x - 2 >= 0; +#if RPR_ENABLE + int curPicWidth = currTU.cu->cs->pcv->lumaWidth; + int curPicHeight = currTU.cu->cs->pcv->lumaHeight; + bool bottomAltAvailable = myArea.y + myArea.height + 1 < curPicHeight; + bool rightAltAvailable = myArea.x + myArea.width + 1 < curPicWidth; +#else bool bottomAltAvailable = myArea.y + myArea.height + 1 < currTU.cu->slice->getSPS()->getMaxPicHeightInLumaSamples(); bool rightAltAvailable = myArea.x + myArea.width + 1 < currTU.cu->slice->getSPS()->getMaxPicWidthInLumaSamples(); - +#endif + uint32_t uiWidthExt = uiWidth + (NUMBER_PADDED_SAMPLES << 1); uint32_t uiHeightExt = uiHeight + (NUMBER_PADDED_SAMPLES << 1); diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp index 86baddca55f7ec3426a658f01bc41a2c429c5c62..6f06719126b3ad64bb45ca8c3ef04140c7cd2b29 100644 --- a/source/Lib/CommonLib/CodingStructure.cpp +++ b/source/Lib/CommonLib/CodingStructure.cpp @@ -1655,9 +1655,23 @@ const CMotionBuf CodingStructure::getMotionBuf( const Area& _area ) const return MotionBuf( m_motionBuf + rsAddr( miArea.pos(), selfArea.pos(), selfArea.width ), selfArea.width, miArea.size() ); } +#if JVET_W0123_TIMD_FUSION && RPR_ENABLE +bool CodingStructure::picContain( const Position _pos ) +{ + const Picture* pic = picture->unscaledPic; + const int width = pic->getPicWidthInLumaSamples(); + const int height = pic->getPicHeightInLumaSamples(); + return (_pos.x >= 0) && (_pos.x < width) && (_pos.y >= 0) && (_pos.y < height); +} +#endif + MotionInfo& CodingStructure::getMotionInfo( const Position& pos ) { +#if JVET_W0123_TIMD_FUSION && RPR_ENABLE + CHECKD( !picContain( pos ), "Trying to access motion information outside of this coding structure"); +#else CHECKD( !area.Y().contains( pos ), "Trying to access motion information outside of this coding structure" ); +#endif //return getMotionBuf().at( g_miScaling.scale( pos - area.lumaPos() ) ); // bypass the motion buf calling and get the value directly @@ -1706,7 +1720,11 @@ const CIpmBuf CodingStructure::getIpmBuf( const Area& _area ) const uint8_t& CodingStructure::getIpmInfo( const Position& pos ) { +#if RPR_ENABLE + CHECKD( !picContain( pos ), "Trying to access motion information outside of this coding structure"); +#else CHECKD( !area.Y().contains( pos ), "Trying to access motion information outside of this coding structure" ); +#endif //return getIpmBuf().at( g_miScaling.scale( pos - area.lumaPos() ) ); // bypass the intra prediction mode buf calling and get the value directly diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h index 77560642231dcd6930ade4eb53d44db0c31df67b..f924c9ebfdbcd9966c15380edbc542f8740de89d 100644 --- a/source/Lib/CommonLib/CodingStructure.h +++ b/source/Lib/CommonLib/CodingStructure.h @@ -275,6 +275,10 @@ public: MotionInfo& getMotionInfo( const Position& pos ); const MotionInfo& getMotionInfo( const Position& pos ) const; +#if JVET_W0123_TIMD_FUSION && RPR_ENABLE + bool picContain( const Position _pos ); +#endif + #if JVET_W0123_TIMD_FUSION IpmBuf getIpmBuf( const Area& _area ); IpmBuf getIpmBuf( const UnitArea& _area ) { return getIpmBuf( _area.Y() ); } diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index b4b5688e9157acab555f60e6b69a52aeca3a8fa9..aa8618b3fc414cd407bf7945cbceeec654f9a294 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -1760,6 +1760,11 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio } #if INTER_LIC +#if RPR_ENABLE + } + PelBuf& dstBuf = dstPic.bufs[compID]; +#endif + if( m_storeBeforeLIC ) { m_predictionBeforeLIC.bufs[compID].copyFrom( dstBuf ); @@ -1777,6 +1782,10 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio #if !JVET_W0090_ARMC_TM CHECK( pu.ciipFlag, "CIIP mode is not used with LIC" ); #endif +#if RPR_ENABLE + if (PU::checkRprLicCondition(pu)) + { +#endif #if JVET_W0090_ARMC_TM if (AML) { @@ -1785,9 +1794,14 @@ void InterPrediction::xPredInterBlk ( const ComponentID& compID, const Predictio else #endif xLocalIlluComp( pu, compID, *refPic, _mv, bi, dstBuf ); - } +#if RPR_ENABLE + } #endif + } +#if !RPR_ENABLE } +#endif +#endif } #if !AFFINE_RM_CONSTRAINTS_AND_OPT @@ -2467,6 +2481,9 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction } if (pu.cu->LICFlag) +#if RPR_ENABLE + if ( PU::checkRprLicCondition(pu) ) +#endif { PelBuf &dstBuf = dstPic.bufs[compID]; int LICshift = 0, scale = 0, offset = 0; @@ -4796,13 +4813,26 @@ void InterPrediction::getBlkAMLRefTemplate(PredictionUnit &pu, PelUnitBuf &pcBuf clipMv(mvTop, pu.lumaPos(), pu.lumaSize(), *pu.cs->sps, *pu.cs->pps); -#if INTER_LIC +#if RPR_ENABLE + const Picture* picRef = pu.cu->slice->getRefPic(REF_PIC_LIST_0, pu.refIdx[0])->unscaledPic; + const std::pair<int, int>& scalingRatio = pu.cu->slice->getScalingRatio(REF_PIC_LIST_0, pu.refIdx[0]); + #if INTER_LIC + xPredInterBlk(COMPONENT_Y, pu, picRef, mvTop, pcBufPredRefTop, + false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true, true, + mvCurr); + #else + xPredInterBlk(COMPONENT_Y, pu, picRef, mvTop, pcBufPredRefTop, + false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true); + #endif +#else + #if INTER_LIC xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(REF_PIC_LIST_0, pu.refIdx[0]), mvTop, pcBufPredRefTop, false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true, true, mvCurr); -#else + #else xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(REF_PIC_LIST_0, pu.refIdx[0]), mvTop, pcBufPredRefTop, false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true); + #endif #endif } if (m_bAMLTemplateAvailabe[1]) @@ -4812,13 +4842,26 @@ void InterPrediction::getBlkAMLRefTemplate(PredictionUnit &pu, PelUnitBuf &pcBuf clipMv(mvLeft, pu.lumaPos(), pu.lumaSize(), *pu.cs->sps, *pu.cs->pps); -#if INTER_LIC +#if RPR_ENABLE + const Picture* picRef = pu.cu->slice->getRefPic(REF_PIC_LIST_0, pu.refIdx[0])->unscaledPic; + const std::pair<int, int>& scalingRatio = pu.cu->slice->getScalingRatio(REF_PIC_LIST_0, pu.refIdx[0]); + #if INTER_LIC + xPredInterBlk(COMPONENT_Y, pu, picRef, mvLeft, pcBufPredRefLeft, + false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true, true, + mvCurr); + #else + xPredInterBlk(COMPONENT_Y, pu, picRef, mvLeft, pcBufPredRefLeft, + false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true); + #endif +#else + #if INTER_LIC xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(REF_PIC_LIST_0, pu.refIdx[0]), mvLeft, pcBufPredRefLeft, false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true, true, mvCurr); -#else + #else xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(REF_PIC_LIST_0, pu.refIdx[0]), mvLeft, pcBufPredRefLeft, false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true); + #endif #endif } } @@ -4853,24 +4896,50 @@ void InterPrediction::getBlkAMLRefTemplate(PredictionUnit &pu, PelUnitBuf &pcBuf if (pu.refIdx[0] >= 0 && pu.refIdx[1] >= 0) { -#if INTER_LIC +#if RPR_ENABLE + const Picture* picRef = pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList])->unscaledPic; + const std::pair<int, int>& scalingRatio = pu.cu->slice->getScalingRatio(eRefPicList, pu.refIdx[refList]); + #if INTER_LIC + xPredInterBlk(COMPONENT_Y, pu, picRef, mvTop, pcMbBuf, true, + pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true, true, + mvCurr); + #else + xPredInterBlk(COMPONENT_Y, pu, picRef, mvTop, pcMbBuf, true, + pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true); + #endif +#else + #if INTER_LIC xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList]), mvTop, pcMbBuf, true, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true, true, mvCurr); -#else + #else xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList]), mvTop, pcMbBuf, true, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true); + #endif #endif } else { -#if INTER_LIC +#if RPR_ENABLE + const Picture* picRef = pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList])->unscaledPic; + const std::pair<int, int>& scalingRatio = pu.cu->slice->getScalingRatio(eRefPicList, pu.refIdx[refList]); + #if INTER_LIC + xPredInterBlk(COMPONENT_Y, pu, picRef, mvTop, pcMbBuf, + false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true, + true, mvCurr); + #else + xPredInterBlk(COMPONENT_Y, pu, picRef, mvTop, pcMbBuf, + false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true); + #endif +#else + #if INTER_LIC xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList]), mvTop, pcMbBuf, false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true, true, mvCurr); -#else + #else xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList]), mvTop, pcMbBuf, false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true); + #endif #endif } } @@ -4886,24 +4955,50 @@ void InterPrediction::getBlkAMLRefTemplate(PredictionUnit &pu, PelUnitBuf &pcBuf if (pu.refIdx[0] >= 0 && pu.refIdx[1] >= 0) { -#if INTER_LIC +#if RPR_ENABLE + const Picture* picRef = pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList])->unscaledPic; + const std::pair<int, int>& scalingRatio = pu.cu->slice->getScalingRatio(eRefPicList, pu.refIdx[refList]); + #if INTER_LIC + xPredInterBlk(COMPONENT_Y, pu, picRef, mvLeft, pcMbBuf, + true, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true, + true, mvCurr); + #else + xPredInterBlk(COMPONENT_Y, pu, picRef, mvLeft, pcMbBuf, + true, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true); + #endif +#else + #if INTER_LIC xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList]), mvLeft, pcMbBuf, true, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true, true, mvCurr); -#else + #else xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList]), mvLeft, pcMbBuf, true, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true); + #endif #endif } else { -#if INTER_LIC +#if RPR_ENABLE + const Picture* picRef = pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList])->unscaledPic; + const std::pair<int, int>& scalingRatio = pu.cu->slice->getScalingRatio(eRefPicList, pu.refIdx[refList]); + #if INTER_LIC + xPredInterBlk(COMPONENT_Y, pu, picRef, mvLeft, pcMbBuf, + false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true, + true, mvCurr); + #else + xPredInterBlk(COMPONENT_Y, pu, picRef, mvLeft, pcMbBuf, + false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, scalingRatio, 0, 0, false, NULL, 0, true); + #endif +#else + #if INTER_LIC xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList]), mvLeft, pcMbBuf, false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true, true, mvCurr); -#else + #else xPredInterBlk(COMPONENT_Y, pu, pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList]), mvLeft, pcMbBuf, false, pu.cu->slice->clpRng(COMPONENT_Y), false, false, SCALE_1X, 0, 0, false, NULL, 0, true); + #endif #endif } } @@ -5000,6 +5095,17 @@ void InterPrediction::adjustAffineMergeCandidates(PredictionUnit &pu, AffineMer PelUnitBuf pcBufPredRefLeft = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight))); PelUnitBuf pcBufPredCurLeft = (PelUnitBuf(pu.chromaFormat, PelBuf(m_acYuvCurAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight))); +#if RPR_ENABLE + bool bRefIsRescaled = false; + for (uint32_t refList = 0; refList < NUM_REF_PIC_LIST_01; refList++) + { + const RefPicList eRefPicList = refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0; + bRefIsRescaled |= (pu.refIdx[refList] >= 0) ? pu.cu->slice->getRefPic(eRefPicList, pu.refIdx[refList])->isRefScaled(pu.cs->pps) : false; + } + if ( !bRefIsRescaled ) + { +#endif + getAffAMLRefTemplate(pu, pcBufPredRefTop, pcBufPredRefLeft); if (m_bAMLTemplateAvailabe[0]) @@ -5015,6 +5121,10 @@ void InterPrediction::adjustAffineMergeCandidates(PredictionUnit &pu, AffineMer uiCost += cDistParam.distFunc(cDistParam); } + +#if RPR_ENABLE + } +#endif } updateCandList(uiMergeCand, uiCost, ADAPTIVE_AFFINE_SUB_GROUP_SIZE, RdCandList[uiMergeCand / ADAPTIVE_AFFINE_SUB_GROUP_SIZE], candCostList[uiMergeCand / ADAPTIVE_AFFINE_SUB_GROUP_SIZE]); } @@ -5484,21 +5594,26 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio, const int extSize = isLuma( compID ) ? 1 : 2; #if IF_12TAP - int vFilterSize = isLuma(compID) ? NTAPS_LUMA(1) : NTAPS_CHROMA; + #if RPR_ENABLE + const int iTap = 0; + #else + const int iTap = 1; + #endif + int vFilterSize = isLuma(compID) ? NTAPS_LUMA(iTap) : NTAPS_CHROMA; #else int vFilterSize = isLuma( compID ) ? NTAPS_LUMA : NTAPS_CHROMA; #endif int yInt0 = ( (int32_t)y0Int + offY ) >> posShift; #if IF_12TAP - yInt0 = std::min(std::max(-(NTAPS_LUMA(1) / 2), yInt0), (refPicHeight >> ::getComponentScaleY(compID, chFmt)) + (NTAPS_LUMA(1) / 2)); + yInt0 = std::min(std::max(-(NTAPS_LUMA(iTap) / 2), yInt0), (refPicHeight >> ::getComponentScaleY(compID, chFmt)) + (NTAPS_LUMA(iTap) / 2)); #else yInt0 = std::min( std::max( -(NTAPS_LUMA / 2), yInt0 ), ( refPicHeight >> ::getComponentScaleY( compID, chFmt ) ) + (NTAPS_LUMA / 2) ); #endif int xInt0 = ( (int32_t)x0Int + offX ) >> posShift; #if IF_12TAP - xInt0 = std::min(std::max(-(NTAPS_LUMA(1) / 2), xInt0), (refPicWidth >> ::getComponentScaleX(compID, chFmt)) + (NTAPS_LUMA(1) / 2)); + xInt0 = std::min(std::max(-(NTAPS_LUMA(iTap) / 2), xInt0), (refPicWidth >> ::getComponentScaleX(compID, chFmt)) + (NTAPS_LUMA(iTap) / 2)); #else xInt0 = std::min( std::max( -(NTAPS_LUMA / 2), xInt0 ), ( refPicWidth >> ::getComponentScaleX( compID, chFmt ) ) + (NTAPS_LUMA / 2) ); #endif @@ -5517,7 +5632,7 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio, int posX = (int32_t)x0Int + col * stepX; xInt = ( posX + offX ) >> posShift; #if IF_12TAP - xInt = std::min(std::max(-(NTAPS_LUMA(1) / 2), xInt), (refPicWidth >> ::getComponentScaleX(compID, chFmt)) + (NTAPS_LUMA(1) / 2)); + xInt = std::min(std::max(-(NTAPS_LUMA(iTap) / 2), xInt), (refPicWidth >> ::getComponentScaleX(compID, chFmt)) + (NTAPS_LUMA(iTap) / 2)); #else xInt = std::min( std::max( -(NTAPS_LUMA / 2), xInt ), ( refPicWidth >> ::getComponentScaleX( compID, chFmt ) ) + (NTAPS_LUMA / 2) ); #endif @@ -5537,7 +5652,7 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio, int posY = (int32_t)y0Int + row * stepY; yInt = ( posY + offY ) >> posShift; #if IF_12TAP - yInt = std::min(std::max(-(NTAPS_LUMA(1) / 2), yInt), (refPicHeight >> ::getComponentScaleY(compID, chFmt)) + (NTAPS_LUMA(1) / 2)); + yInt = std::min(std::max(-(NTAPS_LUMA(iTap) / 2), yInt), (refPicHeight >> ::getComponentScaleY(compID, chFmt)) + (NTAPS_LUMA(iTap) / 2)); #else yInt = std::min( std::max( -(NTAPS_LUMA / 2), yInt ), ( refPicHeight >> ::getComponentScaleY( compID, chFmt ) ) + (NTAPS_LUMA / 2) ); #endif diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp index 1ade3f0b867eabd229f41ebb5f7d8c9bf11b2f74..8c98f043c17a0dbd8413fe8793d70740ef4cd806 100644 --- a/source/Lib/CommonLib/Picture.cpp +++ b/source/Lib/CommonLib/Picture.cpp @@ -748,12 +748,19 @@ void Picture::sampleRateConv( const std::pair<int, int> scalingRatio, const std: filterVer = &DownsamplingFilterSRC[verFilter][0][0]; } #if IF_12TAP + #if RPR_ENABLE + #else CHECK(true, "Called at un-handled point"); + #endif const int filterLength = downsampling ? 12 : (useLumaFilter ? NTAPS_LUMA(1) : NTAPS_CHROMA); #else const int filterLength = downsampling ? 12 : (useLumaFilter ? NTAPS_LUMA : NTAPS_CHROMA); #endif +#if RPR_ENABLE && IF_12TAP + const int log2Norm = downsampling ? 14 : 16; +#else const int log2Norm = downsampling ? 14 : 12; +#endif int *buf = new int[orgHeight * scaledWidth]; int maxVal = ( 1 << bitDepth ) - 1; @@ -796,7 +803,11 @@ void Picture::sampleRateConv( const std::pair<int, int> scalingRatio, const std: for( int i = 0; i < scaledWidth; i++ ) { +#if RPR_ENABLE && IF_12TAP + uint64_t sum = 0; +#else int sum = 0; +#endif int* tmp = buf + i; const TFilterCoeff* f = filterVer + frac * filterLength; @@ -806,7 +817,13 @@ void Picture::sampleRateConv( const std::pair<int, int> scalingRatio, const std: sum += f[k] * tmp[yInt*scaledWidth]; } +#if RPR_ENABLE && IF_12TAP + const uint64_t one = 1; + int sumS = (int)((sum + (one << (log2Norm - 1))) >> log2Norm); + dst[i] = std::min<int>(std::max(0, sumS), maxVal); +#else dst[i] = std::min<int>( std::max( 0, ( sum + ( 1 << ( log2Norm - 1 ) ) ) >> log2Norm ), maxVal ); +#endif } dst += scaledStride; diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp index 97061c6a7ee4161c9ac62518389b45a1b42ad4a6..854fa7780e7aff02dbf3257dc488463c821f0299 100644 --- a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp +++ b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp @@ -140,10 +140,12 @@ void SampleAdaptiveOffset::create( int picWidth, int picHeight, ChromaFormat for m_numberOfComponents = getNumberValidComponents(format); #if JVET_W0066_CCSAO + #if !RPR_ENABLE if (m_created) { return; } + #endif m_created = true; m_ccSaoBuf.destroy(); @@ -171,10 +173,12 @@ void SampleAdaptiveOffset::destroy() m_tempBuf.destroy(); #if JVET_W0066_CCSAO + #if !RPR_ENABLE if (!m_created) { return; } + #endif m_created = false; m_ccSaoBuf.destroy(); diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.h b/source/Lib/CommonLib/SampleAdaptiveOffset.h index 107eb9642551745120380657aabf81acb5a8a6e9..ff661085a99e94af76ede7543540a3632fb22922 100644 --- a/source/Lib/CommonLib/SampleAdaptiveOffset.h +++ b/source/Lib/CommonLib/SampleAdaptiveOffset.h @@ -77,6 +77,9 @@ public: #if JVET_V0094_BILATERAL_FILTER BilateralFilter m_bilateralFilter; #endif +#if RPR_ENABLE + Size getSaoSize() { return Size(m_tempBuf.get(COMPONENT_Y).width, m_tempBuf.get(COMPONENT_Y).height); } +#endif #if JVET_W0066_CCSAO void CCSAOProcess(CodingStructure& cs); CcSaoComParam& getCcSaoComParam() { return m_ccSaoComParam; } diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 4f9b4c8aa86464a0210f127ebebf403f9bbd2c99..a2dc36a68e80e21452f4c2306c3705fc2642418a 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -4950,8 +4950,14 @@ void Slice::setUseLICOnPicLevel( bool fastMode ) //----- get negated histogram of current picture ----- int32_t numValues = 1 << getSPS()->getBitDepth( CHANNEL_TYPE_LUMA ); std::vector<int32_t> negCurrHist( numValues, 0 ); +#if RPR_ENABLE + const Picture* curPic = m_pcPic->unscaledPic; + int32_t numSamples = curPic->getOrigBuf().Y().width * curPic->getOrigBuf().Y().height; + curPic->getOrigBuf().Y().subtractHistogram(negCurrHist); +#else int32_t numSamples = m_pcPic->getOrigBuf().Y().width * m_pcPic->getOrigBuf().Y().height; getPic()->getOrigBuf().Y().subtractHistogram( negCurrHist ); +#endif //----- get SAD threshold ----- double sampleThres = 0.06; @@ -4969,7 +4975,13 @@ void Slice::setUseLICOnPicLevel( bool fastMode ) { // get delta histogram deltaHist = negCurrHist; + +#if RPR_ENABLE + const Picture* refPic = getRefPic(eList, refIdx)->unscaledPic; + refPic->getOrigBuf().Y().updateHistogram(deltaHist); +#else getRefPic(eList, refIdx)->getOrigBuf().Y().updateHistogram(deltaHist); +#endif // get SAD of delta histogram int32_t sadHist = 0; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index a4609a80b2fb5dc553461c1e1a6b2618d92cbf99..1d38bbbc1559c2d38a9d7a15e87631db4227744e 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define RPR_ENABLE 1 + #define BASE_ENCODER 1 #define BASE_NORMATIVE 1 diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 696ebef0f5fe1a0175a75133f3197706e9db2544..5665ecdbbd9af57773b4c65824e30bc90d78c533 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -2325,6 +2325,27 @@ bool PU::checkBDMVRCondition(const PredictionUnit& pu) } #endif +#if INTER_LIC && RPR_ENABLE +bool PU::checkRprLicCondition( const PredictionUnit & pu ) +{ + if ( pu.cs->sps->getLicEnabledFlag() ) + { + if (pu.refIdx[0] >= 0 && pu.refIdx[1] >= 0) return false; + + bool bLicEnabled = true; + int iRefIdx = (pu.refIdx[0] >= 0) ? pu.refIdx[0] : pu.refIdx[1]; + RefPicList eRefPicList = (pu.refIdx[0] >= 0) ? REF_PIC_LIST_0 : REF_PIC_LIST_1; + + const bool isResamplingPossible = pu.cs->sps->getRprEnabledFlag(); + if ( isResamplingPossible && pu.cu->slice->getRefPic(eRefPicList, iRefIdx)->isRefScaled(pu.cs->pps) ) + bLicEnabled = false; + return bLicEnabled; + } + else + return false; +} +#endif + static int xGetDistScaleFactor(const int &iCurrPOC, const int &iCurrRefPOC, const int &iColPOC, const int &iColRefPOC) { int iDiffPocD = iColPOC - iColRefPOC; @@ -4617,6 +4638,48 @@ void PU::spanIpmInfoIntra( PredictionUnit &pu) ib.fill(ipm); } +#if RPR_ENABLE +void scalePositionInRef( PredictionUnit& pu, const PPS& pps, RefPicList refList, int refIdx, Position& PosY ) +{ + const Picture* refPic = pu.cu->slice->getRefPic( refList, refIdx )->unscaledPic; + const bool scaled = refPic->isRefScaled( &pps ); + if (scaled) + { + const SPS* sps = pu.cu->cs->sps; + ChromaFormat chFmt = sps->getChromaFormatIdc(); + + const std::pair<int, int> scalingRatio = pu.cu->slice->getScalingRatio( refList, refIdx ); + + int64_t x0Int; + int64_t y0Int; + + int posX = PosY.x; + int posY = PosY.y; + + const int posShift = SCALE_RATIO_BITS - 4; + + int shiftHor = MV_FRACTIONAL_BITS_INTERNAL ; + int shiftVer = MV_FRACTIONAL_BITS_INTERNAL ; + int offX = 1 << (posShift - shiftHor - 1); + int offY = 1 << (posShift - shiftVer - 1); + + x0Int = (posX << (4)) * (int64_t)scalingRatio.first ; + x0Int = SIGN(x0Int) * ((llabs(x0Int) + ((long long)1 << 7)) >> 8) + ((refPic->getScalingWindow().getWindowLeftOffset() * SPS::getWinUnitX(chFmt)) << (posShift)); + + y0Int = (posY << (4)) * (int64_t)scalingRatio.second ; + y0Int = SIGN(y0Int) * ((llabs(y0Int) + ((long long)1 << 7)) >> 8) + ((refPic->getScalingWindow().getWindowTopOffset() * SPS::getWinUnitY(chFmt)) << (posShift)); + + int xInt0 = ((int32_t)x0Int + offX) >> posShift; + int yInt0 = ((int32_t)y0Int + offY) >> posShift; + + PosY.x = std::min( std::max(xInt0, 0), (int)refPic->unscaledPic->getPicWidthInLumaSamples() - 1 ); + PosY.y = std::min( std::max(yInt0, 0), (int)refPic->unscaledPic->getPicHeightInLumaSamples() - 1 ); + } + //else + // clipColPos( PosY.x, PosY.y, pu ); +} +#endif + void PU::spanIpmInfoInter( PredictionUnit &pu, MotionBuf &mb, IpmBuf &ib) { const unsigned scale = 4 * std::max<int>(1, 4 * AMVP_DECIMATION_FACTOR / 4); @@ -4632,8 +4695,13 @@ void PU::spanIpmInfoInter( PredictionUnit &pu, MotionBuf &mb, IpmBuf &ib) Position PosY1; Mv cMv0; Mv cMv1; +#if RPR_ENABLE + const Picture* pRefPic0; + const Picture* pRefPic1; +#else Picture* pRefPic0; Picture* pRefPic1; +#endif uint8_t* ii = ib.buf; int ibH = mb.height; int ibW = mb.width; @@ -4667,31 +4735,52 @@ void PU::spanIpmInfoInter( PredictionUnit &pu, MotionBuf &mb, IpmBuf &ib) PosY.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv.getHor(); PosY.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv.getVer(); clipColPos(PosY.x, PosY.y, pu); +#if RPR_ENABLE + scalePositionInRef( pu, *pu.cs->pps, refList, refIdx, PosY ); + PosY.x = (PosY.x & mask); + PosY.y = (PosY.y & mask); + ipm = pu.cu->slice->getRefPic(refList, refIdx)->unscaledPic->cs->getIpmInfo(PosY); +#else PosY.x = (PosY.x & mask); PosY.y = (PosY.y & mask); ipm = pu.cu->slice->getRefPic(refList, refIdx)->cs->getIpmInfo(PosY); +#endif } } else { +#if RPR_ENABLE + pRefPic0 = pu.cu->slice->getRefPic(REF_PIC_LIST_0, tempMi.refIdx[0])->unscaledPic; +#else pRefPic0 = pu.cu->slice->getRefPic(REF_PIC_LIST_0, tempMi.refIdx[0]); +#endif cMv0 = tempMi.mv[0]; cMv0.changePrecision(MV_PRECISION_SIXTEENTH, MV_PRECISION_INT); PosY0.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv0.getHor(); PosY0.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv0.getVer(); clipColPos(PosY0.x, PosY0.y, pu); +#if RPR_ENABLE + scalePositionInRef( pu, *pu.cs->pps, REF_PIC_LIST_0, tempMi.refIdx[0], PosY0 ); +#endif PosY0.x = (PosY0.x & mask); PosY0.y = (PosY0.y & mask); mi0 = pRefPic0->cs->getMotionInfo(PosY0); int ipm0 = pRefPic0->cs->getIpmInfo(PosY0); int pocDiff0 = abs(pRefPic0->getPOC() - pu.cu->slice->getPOC()); +#if RPR_ENABLE + pRefPic1 = pu.cu->slice->getRefPic(REF_PIC_LIST_1, tempMi.refIdx[1])->unscaledPic; +#else pRefPic1 = pu.cu->slice->getRefPic(REF_PIC_LIST_1, tempMi.refIdx[1]); +#endif cMv1 = tempMi.mv[1]; cMv1.changePrecision(MV_PRECISION_SIXTEENTH, MV_PRECISION_INT); PosY1.x = pu.Y().x + (x << MIN_CU_LOG2) + cMv1.getHor(); PosY1.y = pu.Y().y + (y << MIN_CU_LOG2) + cMv1.getVer(); clipColPos(PosY1.x, PosY1.y, pu); +#if RPR_ENABLE + scalePositionInRef( pu, *pu.cs->pps, REF_PIC_LIST_1, tempMi.refIdx[1], PosY1 ); +#endif PosY1.x = (PosY1.x & mask); PosY1.y = (PosY1.y & mask); mi1 = pRefPic1->cs->getMotionInfo(PosY1); diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index c7587afa231b63343a9882f606826176f8f5607c..4db01b8bf7d2c64df379c67b4c7fcad838ab52d8 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -269,6 +269,9 @@ namespace PU #if MULTI_PASS_DMVR bool checkBDMVRCondition(const PredictionUnit& pu); #endif +#if INTER_LIC && RPR_ENABLE + bool checkRprLicCondition(const PredictionUnit& pu); +#endif #if INTER_LIC void spanLICFlags(PredictionUnit &pu, const bool LICFlag); diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 6db6669c99d8b45f36e79ec0bef0b26ec71161ab..479ddd62defa0decf38d03b62102e48bad8dd323 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -352,6 +352,9 @@ int EncGOP::xWritePPS( AccessUnit &accessUnit, const PPS *pps, const int layerId OutputNALUnit nalu(NAL_UNIT_PPS); m_HLSWriter->setBitstream( &nalu.m_Bitstream ); nalu.m_nuhLayerId = layerId; +#if RPR_ENABLE + nalu.m_temporalId = accessUnit.temporalId; +#endif CHECK( nalu.m_temporalId < accessUnit.temporalId, "TemporalId shall be greater than or equal to the TemporalId of the layer access unit containing the NAL unit" ); m_HLSWriter->codePPS( pps ); accessUnit.push_back(new NALUnitEBSP(nalu)); @@ -3045,6 +3048,26 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } +#if RPR_ENABLE + // create SAO object based on the picture size + if ( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() ) + { + Size saoSize = m_pcSAO->getSaoSize(); + if ( saoSize.width != picWidth || saoSize.height != picHeight ) { + const uint32_t widthInCtus = (picWidth + maxCUWidth - 1) / maxCUWidth; + const uint32_t heightInCtus = (picHeight + maxCUHeight - 1) / maxCUHeight; + const uint32_t numCtuInFrame = widthInCtus * heightInCtus; + const uint32_t log2SaoOffsetScaleLuma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) - MAX_SAO_TRUNCATED_BITDEPTH); + const uint32_t log2SaoOffsetScaleChroma = (uint32_t)std::max(0, pcSlice->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - MAX_SAO_TRUNCATED_BITDEPTH); + + m_pcSAO->create(picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, log2SaoOffsetScaleLuma, log2SaoOffsetScaleChroma); + m_pcSAO->destroyEncData(); + m_pcSAO->createEncData(m_pcCfg->getSaoCtuBoundary(), numCtuInFrame); + m_pcSAO->setReshaper(m_pcReshaper); + } + } +#endif + if( pcSlice->getSPS()->getScalingListFlag() && m_pcCfg->getUseScalingListId() == SCALING_LIST_FILE_READ ) { picHeader->setExplicitScalingListEnabledFlag(true); @@ -3174,6 +3197,18 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, m_pcSAO->jointClipSaoBifCcSao( cs ); #endif +#if RPR_ENABLE + // create ALF object based on the picture size + if ( pcSlice->getSPS()->getALFEnabledFlag() ) + { + Size alfSize = m_pcALF->getAlfSize(); + if ( alfSize.width != picWidth || alfSize.height != picHeight ) { + m_pcALF->destroy(); + m_pcALF->create( m_pcCfg, picWidth, picHeight, chromaFormatIDC, maxCUWidth, maxCUHeight, maxTotalCUDepth, m_pcCfg->getBitDepth(), m_pcCfg->getInputBitDepth() ); + } + } +#endif + if( pcSlice->getSPS()->getALFEnabledFlag() ) { for (int s = 0; s < uiNumSliceSegments; s++) diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index f5d606e94f39a30018bebe32e4e48b2aacd4f23d..67dcd7ffd90437b453a01f9126bad687fb4c12c4 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -710,11 +710,22 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu } #endif +#if RPR_ENABLE +#else if( m_resChangeInClvsEnabled && m_intraPeriod == -1 ) +#endif { const int poc = m_iPOCLast + ( m_compositeRefEnabled ? 2 : 1 ); +#if RPR_ENABLE + ppsID = 0; + bool bApplyRpr = false; + bApplyRpr |= (m_switchPocPeriod < 0); // RPR applied for all pictures + bApplyRpr |= (m_switchPocPeriod > 0) && (poc / m_switchPocPeriod % 2); // RPR applied for periods RA or LDB + if( bApplyRpr ) +#else if( poc / m_switchPocPeriod % 2 ) +#endif { ppsID = ENC_PPS_ID_RPR; } diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index f1f72dc9c2ecea9adf3584e0ea097ab01185420f..8539d7faaed79858103e7de9a7aedb8ae86ef46a 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -3618,6 +3618,11 @@ void InterSearch::xEstimateMvPredAMVP( PredictionUnit& pu, PelUnitBuf& origBuf, #endif ); } +#if INTER_LIC && RPR_ENABLE + // xPredInterBlk may call PU::checkRprLicCondition() + pu.refIdx[eRefPicList] = iRefIdx; + pu.refIdx[1 - eRefPicList] = NOT_VALID; +#endif // initialize Mvp index & Mvp iBestIdx = 0; @@ -3812,6 +3817,11 @@ Distortion InterSearch::xGetAffineTemplateCost( PredictionUnit& pu, PelUnitBuf& Distortion uiCost = std::numeric_limits<Distortion>::max(); const Picture* picRef = pu.cu->slice->getRefPic( eRefPicList, iRefIdx ); +#if INTER_LIC && RPR_ENABLE + // xPredAffineBlk may call PU::checkRprLicCondition() + pu.refIdx[eRefPicList] = iRefIdx; + pu.refIdx[1-eRefPicList] = NOT_VALID; +#endif // prediction pattern const bool bi = pu.cu->slice->testWeightPred() && pu.cu->slice->getSliceType()==P_SLICE