diff --git a/source/Lib/CommonLib/Mv.cpp b/source/Lib/CommonLib/Mv.cpp index 7edfa2c56903738f79ce174ae35d224d855d16b3..732e756b5ff21ed995286ef3344c52670bdc348a 100644 --- a/source/Lib/CommonLib/Mv.cpp +++ b/source/Lib/CommonLib/Mv.cpp @@ -65,7 +65,14 @@ void clipMv( Mv& rcMv, const Position& pos, { int iHorMax = ( sps.getPicWidthInLumaSamples() + sps.getMaxCUWidth() - size.width + iOffset - ( int ) pos.x - 1 ) << iMvShift; int iHorMin = ( -( int ) sps.getMaxCUWidth() - iOffset - ( int ) pos.x + 1 ) << iMvShift; - rcMv.setHor( std::min( iHorMax, std::max( iHorMin, rcMv.getHor() ) ) ); + int mvX = rcMv.getHor(); + while( mvX > iHorMax ) { + mvX -= ( sps.getWrapAroundOffset() << iMvShift ); + } + while( mvX < iHorMin ) { + mvX += ( sps.getWrapAroundOffset() << iMvShift ); + } + rcMv.setHor( mvX ); rcMv.setVer( std::min( iVerMax, std::max( iVerMin, rcMv.getVer() ) ) ); return; } diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp index 4c96307cb2196d52f9886c1189987f91d09c69c8..d319f1f7ed99cae3d0b589db280489359e00733d 100644 --- a/source/Lib/CommonLib/Picture.cpp +++ b/source/Lib/CommonLib/Picture.cpp @@ -1011,7 +1011,7 @@ void Picture::extendPicBorder() { for (int x = 0; x < xmargin; x++ ) { - pi[ -xmargin + x ] = pi[ -xmargin + x + xoffset ]; + pi[ -x - 1 ] = pi[ -x - 1 + xoffset ]; pi[ p.width + x ] = pi[ p.width + x - xoffset ]; } pi += p.stride; diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index 81ac4b33788300d47ba88f0e0bdf0092564d0a1e..233d90017647044e9c6019f8cfa234262263dffa 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -1270,10 +1270,10 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR rcMvSrchRngLT <<= 2; rcMvSrchRngRB <<= 2; - clipMv(rcMvSrchRngLT, pu.cu->lumaPos(), + xClipMv(rcMvSrchRngLT, pu.cu->lumaPos(), pu.cu->lumaSize(), sps); - clipMv(rcMvSrchRngRB, pu.cu->lumaPos(), + xClipMv(rcMvSrchRngRB, pu.cu->lumaPos(), pu.cu->lumaSize(), sps); rcMvSrchRngLT >>= 2; @@ -2583,10 +2583,10 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu, Mv mvTL(cFPMvPred.getHor() - (iSrchRng << iMvShift), cFPMvPred.getVer() - (iSrchRng << iMvShift)); Mv mvBR(cFPMvPred.getHor() + (iSrchRng << iMvShift), cFPMvPred.getVer() + (iSrchRng << iMvShift)); - clipMv( mvTL, pu.cu->lumaPos(), + xClipMv( mvTL, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps ); - clipMv( mvBR, pu.cu->lumaPos(), + xClipMv( mvBR, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps ); @@ -5847,6 +5847,29 @@ void InterSearch::initWeightIdxBits() } } +void InterSearch::xClipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS& sps ) +{ + int mvShift = MV_FRACTIONAL_BITS_INTERNAL; + int offset = 8; + int horMax = ( sps.getPicWidthInLumaSamples() + offset - ( int ) pos.x - 1 ) << mvShift; + int horMin = ( -( int ) sps.getMaxCUWidth() - offset - ( int ) pos.x + 1 ) << mvShift; + + int verMax = ( sps.getPicHeightInLumaSamples() + offset - ( int ) pos.y - 1 ) << mvShift; + int verMin = ( -( int ) sps.getMaxCUHeight() - offset - ( int ) pos.y + 1 ) << mvShift; + + if( sps.getWrapAroundEnabledFlag() ) + { + int horMax = ( sps.getPicWidthInLumaSamples() + sps.getMaxCUWidth() - size.width + offset - ( int ) pos.x - 1 ) << mvShift; + int horMin = ( -( int ) sps.getMaxCUWidth() - offset - ( int ) pos.x + 1 ) << mvShift; + rcMv.setHor( std::min( horMax, std::max( horMin, rcMv.getHor() ) ) ); + rcMv.setVer( std::min( verMax, std::max( verMin, rcMv.getVer() ) ) ); + return; + } + + rcMv.setHor( std::min( horMax, std::max( horMin, rcMv.getHor() ) ) ); + rcMv.setVer( std::min( verMax, std::max( verMin, rcMv.getVer() ) ) ); +} + #if JVET_M0444_SMVD void InterSearch::symmvdCheckBestMvp( PredictionUnit& pu, diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h index f9edc9438352622bd17b04cddf91a8c1a235074a..6d63e96515f0889023b0448e805007d766c5a185 100644 --- a/source/Lib/EncoderLib/InterSearch.h +++ b/source/Lib/EncoderLib/InterSearch.h @@ -411,6 +411,9 @@ protected: bool xReadBufferedAffineUniMv ( PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv acMvPred[3], Mv acMv[3], uint32_t& ruiBits, Distortion& ruiCost); double xGetMEDistortionWeight ( uint8_t gbiIdx, RefPicList eRefPicList); bool xReadBufferedUniMv ( PredictionUnit& pu, RefPicList eRefPicList, int32_t iRefIdx, Mv& pcMvPred, Mv& rcMv, uint32_t& ruiBits, Distortion& ruiCost); + + void xClipMv ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps ); + public: void resetBufferedUniMotions () { m_uniMotions.reset(); } uint32_t getWeightIdxBits ( uint8_t gbiIdx ) { return m_estWeightIdxBits[gbiIdx]; }