Commit 6178ac75 authored by Yan Zhang's avatar Yan Zhang

1/16-pel motion vector storage

Motion vecotrs are always stored with 1/16-pel precision and the
following strategies are followed:

1. Motion vector data in the buffer are always stored in high precision.
2. Motion vector used for motion compensation are always in high
precision.
3. Motion vector difference data are always in low precision.
4. Encoder side motion estimation always use low precision.
5. Motion vector bits calculation are always performed in low precision.
6. Candidates of motion vector prediction list are always in low
precision.
parent ad6f5903
......@@ -769,7 +769,11 @@ void MergeCtx::setMergeInfo( PredictionUnit& pu, int candIdx )
{
pu.cu->ibc = true;
pu.bv = pu.mv[REF_PIC_LIST_0];
#if REMOVE_MV_ADAPT_PREC
pu.bv >>= (2 + VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE);
#else
pu.bv >>= 2; // used for only integer resolution
#endif
}
#endif
#if JEM_TOOLS
......
This diff is collapsed.
......@@ -508,10 +508,12 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
if( cu.cs->sps->getSpsNext().getUseHighPrecMv() )
{
#if !REMOVE_MV_ADAPT_PREC
mvP0.setHighPrec();
mvP1.setHighPrec();
mvQ0.setHighPrec();
mvQ1.setHighPrec();
#endif
nThreshold = 4 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
}
#endif
......@@ -571,8 +573,10 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
if( cu.cs->sps->getSpsNext().getUseHighPrecMv() )
{
#if !REMOVE_MV_ADAPT_PREC
mvP0.setHighPrec();
mvQ0.setHighPrec();
#endif
nThreshold = 4 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
}
#endif
......
......@@ -44,7 +44,9 @@
void roundMV( Mv & rMV, unsigned imvShift )
{
CHECK( imvShift == 0, "roundMV called for imvShift=0" );
if( rMV.highPrec ) imvShift += VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
#if !REMOVE_MV_ADAPT_PREC
if (rMV.highPrec) imvShift += VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
#endif
int offset = 1 << ( imvShift - 1 );
rMV.setHor( ( ( rMV.getHor() + offset ) >> imvShift ) << imvShift );
......@@ -63,10 +65,16 @@ void roundAffineMv( int& mvx, int& mvy, int nShift )
void clipMv( Mv& rcMv, const Position& pos, const SPS& sps )
{
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
int iMvShift = 2 + ( rcMv.highPrec ? VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : 0 );
#else
int iMvShift = 2;
#endif
#if REMOVE_MV_ADAPT_PREC
if (sps.getSpsNext().getUseHighPrecMv())
{
iMvShift += VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
}
#endif
int iOffset = 8;
int iHorMax = ( sps.getPicWidthInLumaSamples() + iOffset - ( int ) pos.x - 1 ) << iMvShift;
......
......@@ -53,7 +53,7 @@ class Mv
public:
int hor; ///< horizontal component of motion vector
int ver; ///< vertical component of motion vector
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
bool highPrec;///< true if the vector is high precision
#endif
......@@ -61,7 +61,7 @@ public:
// constructors
// ------------------------------------------------------------------------------------------------------------------
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
Mv( ) : hor( 0 ), ver( 0 ), highPrec( false ) {}
Mv( int iHor, int iVer, bool _highPrec = false ) : hor( iHor ), ver( iVer ), highPrec( _highPrec ) {}
#if DMVR_JVET_K0217
......@@ -80,9 +80,33 @@ public:
return (hor == 0 && ver == 0);
}
#endif
#else
#if JEM_TOOLS
#if REMOVE_MV_ADAPT_PREC && DMVR_JVET_K0217
Mv() : hor(0), ver(0) {}
Mv(int iHor, int iVer) : hor(iHor), ver(iVer) {}
// explicit Mv(const Mv &newMv) : hor(newMv.hor), ver(newMv.ver) {} // use default copy constructor
explicit Mv(int iHorAndiVer) : hor(iHorAndiVer), ver(iHorAndiVer) {}
Mv operator << (int i)
{
return Mv(hor << i, ver << i);
}
Mv operator - (void)
{
return Mv(-hor, -ver);
}
bool IsZero(void)
{
return (hor == 0 && ver == 0);
}
#else
Mv() : hor(0), ver(0) {}
Mv(int iHor, int iVer) : hor(iHor), ver(iVer) {}
#endif
#else
Mv( ) : hor( 0 ), ver( 0 ) {}
Mv( int iHor, int iVer ) : hor( iHor ), ver( iVer ) {}
#endif
#endif
// ------------------------------------------------------------------------------------------------------------------
......@@ -109,7 +133,7 @@ public:
const Mv& operator += (const Mv& _rcMv)
{
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( highPrec == _rcMv.highPrec )
{
hor += _rcMv.hor;
......@@ -120,7 +144,7 @@ public:
{
Mv rcMv = _rcMv;
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( highPrec && !rcMv.highPrec ) rcMv.setHighPrec();
if( !highPrec && rcMv.highPrec ) setHighPrec();
#endif
......@@ -132,7 +156,7 @@ public:
const Mv& operator-= (const Mv& _rcMv)
{
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( highPrec == _rcMv.highPrec )
{
hor -= _rcMv.hor;
......@@ -143,7 +167,7 @@ public:
{
Mv rcMv = _rcMv;
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( highPrec && !rcMv.highPrec ) rcMv.setHighPrec();
if( !highPrec && rcMv.highPrec ) setHighPrec();
#endif
......@@ -182,7 +206,7 @@ public:
const Mv operator - ( const Mv& rcMv ) const
{
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( rcMv.highPrec == highPrec )
{
return Mv( hor - rcMv.hor, ver - rcMv.ver, highPrec );
......@@ -201,7 +225,7 @@ public:
const Mv operator + ( const Mv& rcMv ) const
{
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( rcMv.highPrec == highPrec )
{
return Mv( hor + rcMv.hor, ver + rcMv.ver, highPrec );
......@@ -220,7 +244,7 @@ public:
bool operator== ( const Mv& rcMv ) const
{
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( rcMv.highPrec == highPrec )
{
return ( hor == rcMv.hor && ver == rcMv.ver );
......@@ -247,7 +271,7 @@ public:
{
const int mvx = Clip3( -32768, 32767, (iScale * getHor() + 127 + (iScale * getHor() < 0)) >> 8 );
const int mvy = Clip3( -32768, 32767, (iScale * getVer() + 127 + (iScale * getVer() < 0)) >> 8 );
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
return Mv( mvx, mvy, highPrec );
#else
return Mv( mvx, mvy );
......@@ -257,27 +281,40 @@ public:
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
void roundMV2SignalPrecision()
{
#if REMOVE_MV_ADAPT_PREC
setLowPrec();
setHighPrec();
#else
const bool isHP = highPrec;
setLowPrec();
if( isHP ) setHighPrec();
#endif
}
void setLowPrec()
{
if( !highPrec ) return;
#if !REMOVE_MV_ADAPT_PREC
if (!highPrec) return;
#endif
const int nShift = VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
const int nOffset = 1 << ( nShift - 1 );
hor = hor >= 0 ? ( hor + nOffset ) >> nShift : -( ( -hor + nOffset ) >> nShift );
ver = ver >= 0 ? ( ver + nOffset ) >> nShift : -( ( -ver + nOffset ) >> nShift );
#if !REMOVE_MV_ADAPT_PREC
highPrec = false;
#endif
}
void setHighPrec()
{
if( highPrec ) return;
#if !REMOVE_MV_ADAPT_PREC
if (highPrec) return;
#endif
hor = hor >= 0 ? ( hor ) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : -( ( -hor ) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE );
ver = ver >= 0 ? ( ver ) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : -( ( -ver ) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE );
#if !REMOVE_MV_ADAPT_PREC
highPrec = true;
#endif
}
#endif
};// END CLASS DEFINITION MV
......
......@@ -187,7 +187,7 @@ public:
void setPredictor ( const Mv& rcMv )
{
m_mvPredictor = rcMv;
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( m_mvPredictor.highPrec )
{
m_mvPredictor = Mv( m_mvPredictor.hor >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, m_mvPredictor.ver >> VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false );
......
......@@ -128,6 +128,8 @@
#define JVET_K0357_AMVR 1 // Adaptive motion vector resolution separated from JEM_TOOLS macro
#define REMOVE_MV_ADAPT_PREC 1 // remove the high precision flag in the MV class
#if JVET_K0485_BIO
#define JVET_K0485_BIO_EXTEND_SIZE 1
#endif
......
This diff is collapsed.
......@@ -189,14 +189,22 @@ namespace PU
void getAffineMergeCand (const PredictionUnit &pu, MvField (*mvFieldNeighbours)[3], unsigned char &interDirNeighbours, int &numValidMergeCand );
#endif
void setAllAffineMvField ( PredictionUnit &pu, MvField *mvField, RefPicList eRefList );
void setAllAffineMv ( PredictionUnit &pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList );
void setAllAffineMv ( PredictionUnit &pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList
#if REMOVE_MV_ADAPT_PREC
, bool setHighPrec = false
#endif
);
bool isBIOLDB (const PredictionUnit &pu);
#endif
#if !JEM_TOOLS && JVET_K_AFFINE
bool isAffineMrgFlagCoded (const PredictionUnit &pu );
void getAffineMergeCand (const PredictionUnit &pu, MvField (*mvFieldNeighbours)[3], unsigned char &interDirNeighbours, int &numValidMergeCand );
void setAllAffineMvField ( PredictionUnit &pu, MvField *mvField, RefPicList eRefList );
void setAllAffineMv ( PredictionUnit &pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList );
void setAllAffineMv ( PredictionUnit &pu, Mv affLT, Mv affRT, Mv affLB, RefPicList eRefList
#if REMOVE_MV_ADAPT_PREC
, bool setHighPrec = false
#endif
);
#endif
#if !JEM_TOOLS && JVET_K0346
bool getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx &mrgCtx, bool& LICFlag, const int count
......
......@@ -606,9 +606,13 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
#if JVET_K0337_AFFINE_MVD_PREDICTION
mvRT += pu.mvdAffi[eRefList][0];
#endif
CHECK( !mvLT.highPrec, "unexpected lp mv" );
CHECK( !mvRT.highPrec, "unexpected lp mv" );
#if REMOVE_MV_ADAPT_PREC
mvLT.setHighPrec();
mvRT.setHighPrec();
#else
CHECK(!mvLT.highPrec, "unexpected lp mv");
CHECK(!mvRT.highPrec, "unexpected lp mv");
#endif
#if JVET_K_AFFINE_BUG_FIXES
Mv mvLB;
......@@ -619,7 +623,11 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
#if JVET_K0337_AFFINE_MVD_PREDICTION
mvLB += pu.mvdAffi[eRefList][0];
#endif
CHECK( !mvLB.highPrec, "unexpected lp mv" );
#if REMOVE_MV_ADAPT_PREC
mvLB.setHighPrec();
#else
CHECK(!mvLB.highPrec, "unexpected lp mv");
#endif
}
#endif
#else
......@@ -658,10 +666,12 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
if (eRefList == REF_PIC_LIST_0 && pu.cs->slice->getRefPic(eRefList, pu.refIdx[eRefList])->getPOC() == pu.cs->slice->getPOC())
{
pu.cu->ibc = true;
#if !REMOVE_MV_ADAPT_PREC
#if REUSE_CU_RESULTS
if (!cu.cs->pcv->isEncoder)
#endif
mvd <<= 2;
#endif
}
pu.mv[eRefList] = amvpInfo.mvCand[pu.mvpIdx[eRefList]] + mvd;
#else
......@@ -669,7 +679,11 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
#endif
#if JEM_TOOLS || JVET_K_AFFINE
if( pu.cs->sps->getSpsNext().getUseAffine() )
if( pu.cs->sps->getSpsNext().getUseAffine()
#if REMOVE_MV_ADAPT_PREC
|| pu.cs->sps->getSpsNext().getUseHighPrecMv()
#endif
)
{
pu.mv[eRefList].setHighPrec();
}
......
......@@ -2703,7 +2703,7 @@ void CABACWriter::mvd_coding( const Mv &rMvd )
unsigned horAbs = unsigned( horMvd < 0 ? -horMvd : horMvd );
unsigned verAbs = unsigned( verMvd < 0 ? -verMvd : verMvd );
#if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE
#if (JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE) && !REMOVE_MV_ADAPT_PREC
if( rMvd.highPrec )
{
CHECK( horAbs & ((1<<VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE)-1), "mvd-x has high precision fractional part." );
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment