From beb39fd3530e03a4b1e7b5275f95b4ed2112f265 Mon Sep 17 00:00:00 2001 From: Philippe Hanhart <philippe.hanhart@interdigital.com> Date: Wed, 28 Nov 2018 11:23:16 -0800 Subject: [PATCH] JVET-L0231 Horizontal wrap-around motion compensation for inter prediction --- source/App/EncoderApp/EncApp.cpp | 5 ++ source/App/EncoderApp/EncAppCfg.cpp | 23 +++++ source/App/EncoderApp/EncAppCfg.h | 5 ++ source/Lib/CommonLib/InterPrediction.cpp | 57 +++++++++++-- source/Lib/CommonLib/Mv.cpp | 17 +++- source/Lib/CommonLib/Mv.h | 6 +- source/Lib/CommonLib/Picture.cpp | 30 +++++-- source/Lib/CommonLib/Slice.cpp | 4 + source/Lib/CommonLib/Slice.h | 11 +++ source/Lib/CommonLib/TypeDef.h | 2 + source/Lib/DecoderLib/VLCReader.cpp | 8 ++ source/Lib/EncoderLib/EncCfg.h | 12 +++ source/Lib/EncoderLib/EncLib.cpp | 5 ++ source/Lib/EncoderLib/InterSearch.cpp | 102 +++++++++++++++++++---- source/Lib/EncoderLib/VLCWriter.cpp | 8 ++ 15 files changed, 264 insertions(+), 31 deletions(-) diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index f48428987..d4857b50d 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -275,6 +275,11 @@ void EncApp::xInitLibCfg() m_cEncLib.setCPRFastMethod ( m_CPRFastMethod ); #endif +#if JVET_L0231_WRAPAROUND + m_cEncLib.setUseWraparound ( m_Wraparound ); + m_cEncLib.setWraparoundOffset ( m_WraparoundOffset ); +#endif + // ADD_NEW_TOOL : (encoder app) add setting of tool enabling flags and associated parameters here m_cEncLib.setMaxCUWidth ( m_uiCTUSize ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 89356829f..924bdb3d9 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -879,6 +879,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ( "CPRFastMethod", m_CPRFastMethod, 6u, "Fast methods for CPR") #endif +#if JVET_L0231_WRAPAROUND + ("Wraparound", m_Wraparound, false, "Enable horizontal wrap-around motion compensation for inter prediction (0:off, 1:on) [default: off]") + ("WraparoundOffset", m_WraparoundOffset, 0u, "Offset in luma samples used for computing the horizontal wrap-around position") +#endif + // ADD_NEW_TOOL : (encoder app) add parsing parameters here ("LCTUFast", m_useFastLCTU, false, "Fast methods for large CTU") @@ -1959,6 +1964,9 @@ bool EncAppCfg::xCheckParameter() #endif #if JVET_L0124_L0208_TRIANGLE xConfirmPara( m_Triangle, "Triangle is only allowed with NEXT profile" ); +#endif +#if JVET_L0231_WRAPAROUND + xConfirmPara( m_Wraparound, "Horizontal wrap-around motion compensation for inter prediction is only allowed with NEXT profile" ); #endif // ADD_NEW_TOOL : (parameter check) add a check for next tools here } @@ -1983,6 +1991,14 @@ bool EncAppCfg::xCheckParameter() xConfirmPara(m_Affine && !m_highPrecisionMv, "Affine is not yet implemented for HighPrecMv off."); #endif +#if JVET_L0231_WRAPAROUND + if( m_Wraparound ) + { + xConfirmPara(m_WraparoundOffset == 0, "Wrap-around offset must be greater than 0"); + xConfirmPara(m_WraparoundOffset > m_iSourceWidth, "Wrap-around offset must not be greater than the source picture width"); + xConfirmPara(m_WraparoundOffset % SPS::getWinUnitX(m_chromaFormatIDC) != 0, "Wrap-around offset must be an integer multiple of the specified chroma subsampling"); + } +#endif } #if ENABLE_SPLIT_PARALLELISM @@ -3164,6 +3180,13 @@ void EncAppCfg::xPrintParameter() } #if JVET_L0293_CPR msg(VERBOSE, "CPR:%d ", m_CPRMode); +#endif +#if JVET_L0231_WRAPAROUND + msg( VERBOSE, "Wraparound:%d ", m_Wraparound); + if( m_Wraparound ) + { + msg( VERBOSE, "WraparoundOffset:%d ", m_WraparoundOffset ); + } #endif // ADD_NEW_TOOL (add some output indicating the usage of tools) diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index bd140d91d..226a9369a 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -257,6 +257,11 @@ protected: unsigned m_CPRFastMethod; #endif +#if JVET_L0231_WRAPAROUND + bool m_Wraparound; + unsigned m_WraparoundOffset; +#endif + // ADD_NEW_TOOL : (encoder app) add tool enabling flags and associated parameters here unsigned m_uiMaxCUWidth; ///< max. CU width in pixel diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index 959ba16d6..e57de7d12 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -460,7 +460,11 @@ void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList& mv[0] = pu.mv[eRefPicList]; } if ( !pu.cu->affine ) - clipMv(mv[0], pu.cu->lumaPos(), sps); + clipMv(mv[0], pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + sps); for( uint32_t comp = COMPONENT_Y; comp < pcYuvPred.bufs.size() && comp <= m_maxCompIDToPred; comp++ ) @@ -727,7 +731,11 @@ void InterPrediction::xPredAffineBlk( const ComponentID& compID, const Predictio ) { Mv mvTemp = _mv[0]; - clipMv( mvTemp, pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( mvTemp, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); xPredInterBlk( compID, pu, refPic, mvTemp, dstPic, bi, clpRng #if JVET_L0256_BIO , false @@ -822,10 +830,25 @@ void InterPrediction::xPredAffineBlk( const ComponentID& compID, const Predictio roundAffineMv(iMvScaleTmpHor, iMvScaleTmpVer, shift); // clip and scale - iMvScaleTmpHor = std::min<int>(iHorMax, std::max<int>(iHorMin, iMvScaleTmpHor)); - iMvScaleTmpVer = std::min<int>(iVerMax, std::max<int>(iVerMin, iMvScaleTmpVer)); +#if JVET_L0231_WRAPAROUND + if (sps.getSpsNext().getUseWraparound()) + { + m_storedMv[h / AFFINE_MIN_BLOCK_SIZE * MVBUFFER_SIZE + w / AFFINE_MIN_BLOCK_SIZE].set(iMvScaleTmpHor, iMvScaleTmpVer); + Mv tmpMv(iMvScaleTmpHor, iMvScaleTmpVer); + clipMv(tmpMv, Position(pu.Y().x + w, pu.Y().y + h), Size(blockWidth, blockHeight), sps); + iMvScaleTmpHor = tmpMv.getHor(); + iMvScaleTmpVer = tmpMv.getVer(); + } + else + { +#endif + iMvScaleTmpHor = std::min<int>(iHorMax, std::max<int>(iHorMin, iMvScaleTmpHor)); + iMvScaleTmpVer = std::min<int>(iVerMax, std::max<int>(iVerMin, iMvScaleTmpVer)); - m_storedMv[h / AFFINE_MIN_BLOCK_SIZE * MVBUFFER_SIZE + w / AFFINE_MIN_BLOCK_SIZE].set(iMvScaleTmpHor, iMvScaleTmpVer); + m_storedMv[h / AFFINE_MIN_BLOCK_SIZE * MVBUFFER_SIZE + w / AFFINE_MIN_BLOCK_SIZE].set(iMvScaleTmpHor, iMvScaleTmpVer); +#if JVET_L0231_WRAPAROUND + } +#endif } else { @@ -835,6 +858,12 @@ void InterPrediction::xPredAffineBlk( const ComponentID& compID, const Predictio m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE + 1)* MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE + 1)] + Mv(2, 2)); curMv.set(curMv.getHor() >> 2, curMv.getVer() >> 2); +#if JVET_L0231_WRAPAROUND + if (sps.getSpsNext().getUseWraparound()) + { + clipMv(curMv, Position(pu.Y().x + (w << iScaleX), pu.Y().y + (h << iScaleY)), Size(blockWidth << iScaleX, blockHeight << iScaleY), sps); + } +#endif iMvScaleTmpHor = curMv.hor; iMvScaleTmpVer = curMv.ver; } @@ -844,8 +873,22 @@ void InterPrediction::xPredAffineBlk( const ComponentID& compID, const Predictio roundAffineMv( iMvScaleTmpHor, iMvScaleTmpVer, shift ); // clip and scale - iMvScaleTmpHor = std::min<int>( iHorMax, std::max<int>( iHorMin, iMvScaleTmpHor ) ); - iMvScaleTmpVer = std::min<int>( iVerMax, std::max<int>( iVerMin, iMvScaleTmpVer ) ); +#if JVET_L0231_WRAPAROUND + if (sps.getSpsNext().getUseWraparound()) + { + Mv tmpMv(iMvScaleTmpHor, iMvScaleTmpVer); + clipMv(tmpMv, Position(pu.Y().x + (w << iScaleX), pu.Y().y + (h << iScaleY)), Size(blockWidth << iScaleX, blockHeight << iScaleY), sps); + iMvScaleTmpHor = tmpMv.getHor(); + iMvScaleTmpVer = tmpMv.getVer(); + } + else + { +#endif + iMvScaleTmpHor = std::min<int>( iHorMax, std::max<int>( iHorMin, iMvScaleTmpHor ) ); + iMvScaleTmpVer = std::min<int>( iVerMax, std::max<int>( iVerMin, iMvScaleTmpVer ) ); +#if JVET_L0231_WRAPAROUND + } +#endif #endif // get the MV in high precision int xFrac, yFrac, xInt, yInt; diff --git a/source/Lib/CommonLib/Mv.cpp b/source/Lib/CommonLib/Mv.cpp index 6e91ad386..aa46498ad 100644 --- a/source/Lib/CommonLib/Mv.cpp +++ b/source/Lib/CommonLib/Mv.cpp @@ -63,7 +63,11 @@ void roundAffineMv( int& mvx, int& mvy, int nShift ) mvy = mvy >= 0 ? (mvy + nOffset) >> nShift : -((-mvy + nOffset) >> nShift); } -void clipMv( Mv& rcMv, const Position& pos, const SPS& sps ) +void clipMv( Mv& rcMv, const Position& pos, +#if JVET_L0231_WRAPAROUND + const struct Size& size, +#endif + const SPS& sps ) { #if !REMOVE_MV_ADAPT_PREC int iMvShift = 2 + (rcMv.highPrec ? VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : 0); @@ -80,6 +84,17 @@ void clipMv( Mv& rcMv, const Position& pos, const SPS& sps ) int iVerMax = ( sps.getPicHeightInLumaSamples() + iOffset - ( int ) pos.y - 1 ) << iMvShift; int iVerMin = ( -( int ) sps.getMaxCUHeight() - iOffset - ( int ) pos.y + 1 ) << iMvShift; +#if JVET_L0231_WRAPAROUND + if( sps.getSpsNext().getUseWraparound() ) + { + 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() ) ) ); + rcMv.setVer( std::min( iVerMax, std::max( iVerMin, rcMv.getVer() ) ) ); + return; + } +#endif + rcMv.setHor( std::min( iHorMax, std::max( iHorMin, rcMv.getHor() ) ) ); rcMv.setVer( std::min( iVerMax, std::max( iVerMin, rcMv.getVer() ) ) ); } diff --git a/source/Lib/CommonLib/Mv.h b/source/Lib/CommonLib/Mv.h index c86c4354f..a1525ddc7 100644 --- a/source/Lib/CommonLib/Mv.h +++ b/source/Lib/CommonLib/Mv.h @@ -287,7 +287,11 @@ namespace std }; #endif void roundMV( Mv& rcMv, unsigned imvShift ); -void clipMv ( Mv& rcMv, const struct Position& pos, const class SPS& sps ); +void clipMv ( Mv& rcMv, const struct Position& pos, +#if JVET_L0231_WRAPAROUND + const struct Size& size, +#endif + const class SPS& sps ); void roundAffineMv( int& mvx, int& mvy, int nShift ); diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp index dad3fc9cb..78b614a9a 100644 --- a/source/Lib/CommonLib/Picture.cpp +++ b/source/Lib/CommonLib/Picture.cpp @@ -1004,15 +1004,35 @@ void Picture::extendPicBorder() Pel* pi = piTxt; // do left and right margins - for (int y = 0; y < p.height; y++) +#if JVET_L0231_WRAPAROUND + if (cs->sps->getSpsNext().getUseWraparound()) { - for (int x = 0; x < xmargin; x++ ) + int xoffset = cs->sps->getSpsNext().getWraparoundOffset() >> getComponentScaleX( compID, cs->area.chromaFormat ); + for (int y = 0; y < p.height; y++) { - pi[ -xmargin + x ] = pi[0]; - pi[ p.width + x ] = pi[p.width-1]; + for (int x = 0; x < xmargin; x++ ) + { + pi[ -xmargin + x ] = pi[ -xmargin + x + xoffset ]; + pi[ p.width + x ] = pi[ p.width + x - xoffset ]; + } + pi += p.stride; } - pi += p.stride; } + else + { +#endif + for (int y = 0; y < p.height; y++) + { + for (int x = 0; x < xmargin; x++ ) + { + pi[ -xmargin + x ] = pi[0]; + pi[ p.width + x ] = pi[p.width-1]; + } + pi += p.stride; + } +#if JVET_L0231_WRAPAROUND + } +#endif // pi is now the (0,height) (bottom left of image within bigger picture pi -= (p.stride + xmargin); diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 0f77bcbfc..a6a6d3b95 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1829,6 +1829,10 @@ SPSNext::SPSNext( SPS& sps ) , m_compositeRefEnabled ( false ) #if JVET_L0293_CPR , m_CPRMode ( 0 ) +#endif +#if JVET_L0231_WRAPAROUND + , m_Wraparound ( false ) + , m_WraparoundOffset ( 0 ) #endif // ADD_NEW_TOOL : (sps extension) add tool enabling flags here (with "false" as default values) { diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index c54d840c0..0d5f1bec7 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -868,6 +868,11 @@ private: unsigned m_CPRMode; #endif +#if JVET_L0231_WRAPAROUND + bool m_Wraparound; + unsigned m_WraparoundOffset; +#endif + // ADD_NEW_TOOL : (sps extension) add tool enabling flags and associated parameters here public: @@ -989,6 +994,12 @@ public: #if JVET_L0293_CPR void setCPRMode (unsigned CPRMode) { m_CPRMode = CPRMode; } unsigned getCPRMode () const { return m_CPRMode; } +#endif +#if JVET_L0231_WRAPAROUND + void setUseWraparound ( bool b ) { m_Wraparound = b; } + bool getUseWraparound () const { return m_Wraparound; } + void setWraparoundOffset ( unsigned offset ) { m_WraparoundOffset = offset; } + unsigned getWraparoundOffset () const { return m_WraparoundOffset; } #endif // ADD_NEW_TOOL : (sps extension) add access functions for tool enabling flags and associated parameters here diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 9f4077909..b1043bf31 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_L0231_WRAPAROUND 1 // Wrap-around MC + #define TRAINED_CABAC_INIT_TABLES 1 // Trained values for VTM3 #define JVET_L0410_TC_TAB 1 // Change TC table for QP 51-63 diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index a72c94c67..f5c83a27e 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -930,6 +930,14 @@ void HLSyntaxReader::parseSPSNext( SPSNext& spsNext, const bool usePCM ) } } #endif + +#if JVET_L0231_WRAPAROUND + READ_FLAG( symbol, "ref_wraparound_enabled_flag" ); spsNext.setUseWraparound( symbol != 0 ); + if( spsNext.getUseWraparound() ) + { + READ_UVLC( symbol, "ref_wraparound_offset" ); spsNext.setWraparoundOffset( symbol ); + } +#endif // ADD_NEW_TOOL : (sps extension parser) read tool enabling flags and associated parameters here } diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 60709f112..1ce03c6ec 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -239,6 +239,11 @@ protected: unsigned m_CPRFastMethod; #endif +#if JVET_L0231_WRAPAROUND + bool m_Wraparound; + unsigned m_WraparoundOffset; +#endif + // ADD_NEW_TOOL : (encoder lib) add tool enabling flags and associated parameters here bool m_useFastLCTU; @@ -732,6 +737,13 @@ public: unsigned getCPRFastMethod () const { return m_CPRFastMethod; } #endif +#if JVET_L0231_WRAPAROUND + void setUseWraparound ( bool b ) { m_Wraparound = b; } + bool getUseWraparound () const { return m_Wraparound; } + void setWraparoundOffset ( unsigned u ) { m_WraparoundOffset = u; } + unsigned getWraparoundOffset () const { return m_WraparoundOffset; } +#endif + // ADD_NEW_TOOL : (encoder lib) add access functions here diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index e57939ac7..8a102ef7c 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -882,6 +882,11 @@ void EncLib::xInitSPS(SPS &sps) #if JVET_L0293_CPR sps.getSpsNext().setCPRMode ( m_CPRMode ); #endif + +#if JVET_L0231_WRAPAROUND + sps.getSpsNext().setUseWraparound ( m_Wraparound ); + sps.getSpsNext().setWraparoundOffset ( m_WraparoundOffset ); +#endif // ADD_NEW_TOOL : (encoder lib) set tool enabling flags and associated parameters here int minCUSize = sps.getMaxCUWidth() >> sps.getLog2DiffMaxMinCodingBlockSize(); diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index 0ff695df8..44f0b1d07 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -1270,8 +1270,16 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR rcMvSrchRngLT <<= 2; rcMvSrchRngRB <<= 2; - clipMv(rcMvSrchRngLT, pu.cu->lumaPos(), sps); - clipMv(rcMvSrchRngRB, pu.cu->lumaPos(), sps); + clipMv(rcMvSrchRngLT, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + sps); + clipMv(rcMvSrchRngRB, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + sps); rcMvSrchRngLT >>= 2; rcMvSrchRngRB >>= 2; } @@ -2328,7 +2336,11 @@ Distortion InterSearch::xGetTemplateCost( const PredictionUnit& pu, cMvCand.hor = cMvCand.hor << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; cMvCand.ver = cMvCand.ver << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; #endif - clipMv( cMvCand, pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( cMvCand, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); // prediction pattern @@ -2566,7 +2578,11 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu, cFPMvPred.hor = cFPMvPred.hor << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; cFPMvPred.ver = cFPMvPred.ver << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; #endif - clipMv( cFPMvPred, pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( cFPMvPred, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); #if !REMOVE_MV_ADAPT_PREC Mv mvTL(cFPMvPred.getHor() - (iSrchRng << iMvShift), cFPMvPred.getVer() - (iSrchRng << iMvShift), cFPMvPred.highPrec); @@ -2576,8 +2592,16 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu, Mv mvBR(cFPMvPred.getHor() + (iSrchRng << iMvShift), cFPMvPred.getVer() + (iSrchRng << iMvShift)); #endif - clipMv( mvTL, pu.cu->lumaPos(), *pu.cs->sps ); - clipMv( mvBR, pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( mvTL, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); + clipMv( mvBR, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); mvTL.divideByPowerOf2( iMvShift ); mvBR.divideByPowerOf2( iMvShift ); @@ -2727,7 +2751,11 @@ void InterSearch::xTZSearch( const PredictionUnit& pu, rcMv.hor = rcMv.hor << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; rcMv.ver = rcMv.ver << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; #endif - clipMv( rcMv, pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( rcMv, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); #if REMOVE_MV_ADAPT_PREC rcMv.hor = rcMv.hor >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; rcMv.ver = rcMv.ver >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; @@ -2768,7 +2796,11 @@ void InterSearch::xTZSearch( const PredictionUnit& pu, integerMv2Nx2NPred.hor = integerMv2Nx2NPred.hor << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; integerMv2Nx2NPred.ver = integerMv2Nx2NPred.ver << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; #endif - clipMv( integerMv2Nx2NPred, pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( integerMv2Nx2NPred, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); #if REMOVE_MV_ADAPT_PREC integerMv2Nx2NPred.hor = integerMv2Nx2NPred.hor >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; integerMv2Nx2NPred.ver = integerMv2Nx2NPred.ver >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; @@ -3005,7 +3037,11 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu, rcMv.hor = rcMv.hor << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; rcMv.ver = rcMv.ver << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; #endif - clipMv( rcMv, pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( rcMv, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); #if REMOVE_MV_ADAPT_PREC rcMv.hor = rcMv.hor >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; rcMv.ver = rcMv.ver >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; @@ -3040,7 +3076,11 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu, integerMv2Nx2NPred.hor = integerMv2Nx2NPred.hor << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; integerMv2Nx2NPred.ver = integerMv2Nx2NPred.ver << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; #endif - clipMv( integerMv2Nx2NPred, pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( integerMv2Nx2NPred, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); #if REMOVE_MV_ADAPT_PREC integerMv2Nx2NPred.hor = integerMv2Nx2NPred.hor >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; integerMv2Nx2NPred.ver = integerMv2Nx2NPred.ver >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; @@ -3191,7 +3231,11 @@ void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct& cTempMV.hor = cTempMV.hor << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; cTempMV.ver = cTempMV.ver << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; #endif - clipMv(cTempMV, pu.cu->lumaPos(), sps); + clipMv(cTempMV, pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + sps); #if REMOVE_MV_ADAPT_PREC cTempMV.hor = cTempMV.hor >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; cTempMV.ver = cTempMV.ver >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; @@ -3458,13 +3502,21 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit& pu, vy = mvScaleVer + dMvHorY * (pu.Y().x - mvInfo->x) + dMvVerY * (pu.Y().y - mvInfo->y); roundAffineMv(vx, vy, shift); mvTmp[0] = Mv(vx, vy); - clipMv(mvTmp[0], pu.cu->lumaPos(), *pu.cs->sps); + clipMv(mvTmp[0], pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps); mvTmp[0].roundMV2SignalPrecision(); vx = mvScaleHor + dMvHorX * (pu.Y().x + pu.Y().width - mvInfo->x) + dMvVerX * (pu.Y().y - mvInfo->y); vy = mvScaleVer + dMvHorY * (pu.Y().x + pu.Y().width - mvInfo->x) + dMvVerY * (pu.Y().y - mvInfo->y); roundAffineMv(vx, vy, shift); mvTmp[1] = Mv(vx, vy); - clipMv(mvTmp[1], pu.cu->lumaPos(), *pu.cs->sps); + clipMv(mvTmp[1], pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps); mvTmp[1].roundMV2SignalPrecision(); #if REMOVE_MV_ADAPT_PREC mvTmp[0].hor = mvTmp[0].hor >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE; @@ -4245,11 +4297,23 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu, uint32_t uiBitsBest = 0; // do motion compensation with origin mv - clipMv( acMvTemp[0], pu.cu->lumaPos(), *pu.cs->sps ); - clipMv( acMvTemp[1], pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( acMvTemp[0], pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); + clipMv( acMvTemp[1], pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); if ( pu.cu->affineType == AFFINEMODEL_6PARAM ) { - clipMv( acMvTemp[2], pu.cu->lumaPos(), *pu.cs->sps ); + clipMv( acMvTemp[2], pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps ); } xPredAffineBlk( COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cs->slice->clpRng( COMPONENT_Y ) ); @@ -4422,7 +4486,11 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu, acMvTemp[i].hor = Clip3( -32768, 32767, acMvTemp[i].hor ); acMvTemp[i].ver = Clip3( -32768, 32767, acMvTemp[i].ver ); acMvTemp[i].roundMV2SignalPrecision(); - clipMv(acMvTemp[i], pu.cu->lumaPos(), *pu.cs->sps); + clipMv(acMvTemp[i], pu.cu->lumaPos(), +#if JVET_L0231_WRAPAROUND + pu.cu->lumaSize(), +#endif + *pu.cs->sps); } xPredAffineBlk( COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cu->slice->clpRng( COMPONENT_Y ) ); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index dbb3dd213..1c7f05de6 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -640,6 +640,14 @@ void HLSWriter::codeSPSNext( const SPSNext& spsNext, const bool usePCM ) } } #endif + +#if JVET_L0231_WRAPAROUND + WRITE_FLAG( spsNext.getUseWraparound() ? 1 : 0, "ref_wraparound_enabled_flag" ); + if( spsNext.getUseWraparound() ) + { + WRITE_UVLC( spsNext.getWraparoundOffset(), "ref_wraparound_offset" ); + } +#endif // ADD_NEW_TOOL : (sps extension writer) write tool enabling flags and associated parameters here } -- GitLab