Commit 54963145 authored by Huanbang Chen's avatar Huanbang Chen

Integrate all AFFINE adoptions in JVET-L meeting, including:

1. JVET-L0271:              Simplification of affine AMVP list construction
2. JVET_L0694/L0045/L0047:  Combination of affine mode clean up and line buffer reduction
3. JVET_L0632/L0142:        Affine merge list construction
4. JVET_L0369:              Moving ATMVP into the affine merge list
parent d1194f46
......@@ -311,7 +311,9 @@ void EncApp::xInitLibCfg()
m_cEncLib.setPCMLog2MaxSize ( m_pcmLog2MaxSize);
m_cEncLib.setMaxNumMergeCand ( m_maxNumMergeCand );
#if JVET_L0632_AFFINE_MERGE
m_cEncLib.setMaxNumAffineMergeCand ( m_maxNumAffineMergeCand );
#endif
//====== Weighted Prediction ========
m_cEncLib.setUseWP ( m_useWeightedPred );
......
......@@ -1067,6 +1067,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
("SignHideFlag,-SBH", m_signDataHidingEnabledFlag, false )
#endif
("MaxNumMergeCand", m_maxNumMergeCand, 5u, "Maximum number of merge candidates")
#if JVET_L0632_AFFINE_MERGE
("MaxNumAffineMergeCand", m_maxNumAffineMergeCand, 5u, "Maximum number of affine merge candidates")
#endif
/* Misc. */
("SEIDecodedPictureHash,-dph", tmpDecodedPictureHashSEIMappedType, 0, "Control generation of decode picture hash SEI messages\n"
"\t3: checksum\n"
......@@ -2309,6 +2312,18 @@ bool EncAppCfg::xCheckParameter()
{
xConfirmPara( m_maxNumMergeCand > 5, "MaxNumMergeCand must be 5 or smaller." );
}
#if JVET_L0632_AFFINE_MERGE
xConfirmPara( m_maxNumAffineMergeCand < 1, "MaxNumAffineMergeCand must be 1 or greater." );
xConfirmPara( m_maxNumAffineMergeCand > 5, "MaxNumAffineMergeCand must be 5 or smaller." );
#if JVET_L0369_SUBBLOCK_MERGE
if ( m_Affine == 0 )
{
m_maxNumAffineMergeCand = m_SubPuMvpMode;
}
#endif
#endif
xConfirmPara( m_EMT < 0 || m_EMT >3, "EMT must be 0, 1, 2 or 3" );
xConfirmPara( m_FastEMT < 0 || m_FastEMT >3, "FEMT must be 0, 1, 2 or 3" );
if( m_usePCM)
......@@ -3055,6 +3070,9 @@ void EncAppCfg::xPrintParameter()
}
msg( DETAILS, "Max Num Merge Candidates : %d\n", m_maxNumMergeCand );
#if JVET_L0632_AFFINE_MERGE
msg( DETAILS, "Max Num Affine Merge Candidates : %d\n", m_maxNumAffineMergeCand );
#endif
msg( DETAILS, "\n");
msg( VERBOSE, "TOOL CFG: ");
......
......@@ -428,6 +428,9 @@ protected:
uint32_t m_log2ParallelMergeLevel; ///< Parallel merge estimation region
uint32_t m_maxNumMergeCand; ///< Max number of merge candidates
#if JVET_L0632_AFFINE_MERGE
uint32_t m_maxNumAffineMergeCand; ///< Max number of affine merge candidates
#endif
int m_TMVPModeId;
bool m_depQuantEnabledFlag;
......
......@@ -141,6 +141,9 @@ static const int AMVP_MAX_NUM_CANDS = 2; ///< AMVP
static const int AMVP_MAX_NUM_CANDS_MEM = 3; ///< AMVP: advanced motion vector prediction - max number of candidates
static const int AMVP_DECIMATION_FACTOR = 2;
static const int MRG_MAX_NUM_CANDS = 7; ///< MERGE
#if JVET_L0632_AFFINE_MERGE
static const int AFFINE_MRG_MAX_NUM_CANDS = 5; ///< AFFINE MERGE
#endif
static const int MAX_TLAYER = 7; ///< Explicit temporal layer QP offset - max number of temporal layer
......@@ -372,6 +375,9 @@ static const int FAST_SKIP_DEPTH = 2;
static const double PBINTRA_RATIO = 1.1;
static const int NUM_MRG_SATD_CAND = 4;
static const double MRG_FAST_RATIO = 1.25;
#if JVET_L0632_AFFINE_MERGE
static const int NUM_AFF_MRG_SATD_CAND = 1;
#endif
static const double AMAXBT_TH32 = 15.0;
static const double AMAXBT_TH64 = 30.0;
......
......@@ -316,6 +316,29 @@ public:
void setMergeInfo( PredictionUnit& pu, int candIdx );
};
#if JVET_L0632_AFFINE_MERGE
class AffineMergeCtx
{
public:
AffineMergeCtx() : numValidMergeCand( 0 ) { for ( unsigned i = 0; i < AFFINE_MRG_MAX_NUM_CANDS; i++ ) affineType[i] = AFFINEMODEL_4PARAM; }
~AffineMergeCtx() {}
public:
MvField mvFieldNeighbours[AFFINE_MRG_MAX_NUM_CANDS << 1][3]; // double length for mv of both lists
unsigned char interDirNeighbours[AFFINE_MRG_MAX_NUM_CANDS];
EAffineModel affineType[AFFINE_MRG_MAX_NUM_CANDS];
#if JVET_L0646_GBI
uint8_t GBiIdx[AFFINE_MRG_MAX_NUM_CANDS];
#endif
int numValidMergeCand;
int maxNumMergeCand;
#if JVET_L0369_SUBBLOCK_MERGE
MergeCtx *mrgCtx;
MergeType mergeType[AFFINE_MRG_MAX_NUM_CANDS];
#endif
};
#endif
namespace DeriveCtx
{
......
......@@ -407,6 +407,15 @@ const CtxSet ContextSetCfg::AffineType = ContextSetCfg::addCtxSet
{ CNU, },
});
#if JVET_L0632_AFFINE_MERGE
const CtxSet ContextSetCfg::AffMergeIdx = ContextSetCfg::addCtxSet
( {
{ 137, CNU, CNU, CNU, CNU, },
{ 122, CNU, CNU, CNU, CNU, },
{ CNU, CNU, CNU, CNU, CNU, },
} );
#endif
#if JVET_L0646_GBI
const CtxSet ContextSetCfg::GBiIdx = ContextSetCfg::addCtxSet
({
......
......@@ -173,6 +173,9 @@ public:
#endif
static const CtxSet AffineFlag;
static const CtxSet AffineType;
#if JVET_L0632_AFFINE_MERGE
static const CtxSet AffMergeIdx;
#endif
static const CtxSet Mvd;
static const CtxSet TransSubdivFlag;
static const CtxSet QtRootCbf;
......
......@@ -255,6 +255,11 @@ void InterPrediction::xSubPuMC( PredictionUnit& pu, PelUnitBuf& predBuf, const R
subPu.cu = pu.cu;
subPu.mergeType = MRG_TYPE_DEFAULT_N;
#if JVET_L0369_SUBBLOCK_MERGE
bool bAffine = pu.cu->affine;
subPu.cu->affine = false;
#endif
// join sub-pus containing the same motion
bool verMC = puSize.height > puSize.width;
int fstStart = (!verMC ? puPos.y : puPos.x);
......@@ -299,6 +304,10 @@ void InterPrediction::xSubPuMC( PredictionUnit& pu, PelUnitBuf& predBuf, const R
secDim = later - secStep;
}
}
#if JVET_L0369_SUBBLOCK_MERGE
pu.cu->affine = bAffine;
#endif
}
......@@ -314,10 +323,16 @@ void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList&
{
CHECK( iRefIdx < 0, "iRefIdx incorrect." );
#if JVET_L0694_AFFINE_LINEBUFFER_CLEANUP
mv[0] = pu.mvAffi[eRefPicList][0];
mv[1] = pu.mvAffi[eRefPicList][1];
mv[2] = pu.mvAffi[eRefPicList][2];
#else
const CMotionBuf &mb = pu.getMotionBuf();
mv[0] = mb.at( 0, 0 ).mv[eRefPicList];
mv[1] = mb.at( mb.width - 1, 0 ).mv[eRefPicList];
mv[2] = mb.at( 0, mb.height - 1 ).mv[eRefPicList];
#endif
}
else
{
......
......@@ -90,6 +90,9 @@ Slice::Slice()
, m_handleCraAsBlaFlag ( false )
, m_colRefIdx ( 0 )
, m_maxNumMergeCand ( 0 )
#if JVET_L0632_AFFINE_MERGE
, m_maxNumAffineMergeCand ( 0 )
#endif
, m_uiTLayer ( 0 )
, m_bTLayerSwitchingFlag ( false )
, m_sliceMode ( NO_SLICES )
......@@ -209,6 +212,9 @@ void Slice::initSlice()
}
m_maxNumMergeCand = MRG_MAX_NUM_CANDS;
#if JVET_L0632_AFFINE_MERGE
m_maxNumAffineMergeCand = AFFINE_MRG_MAX_NUM_CANDS;
#endif
m_bFinalized=false;
......@@ -838,6 +844,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
m_subPuMvpSubBlkSizeSliceEnable = pSrc->m_subPuMvpSubBlkSizeSliceEnable;
m_subPuMvpSubBlkLog2Size = pSrc->m_subPuMvpSubBlkLog2Size;
m_maxNumMergeCand = pSrc->m_maxNumMergeCand;
#if JVET_L0632_AFFINE_MERGE
m_maxNumAffineMergeCand = pSrc->m_maxNumAffineMergeCand;
#endif
if( cpyAlmostAll ) m_encCABACTableIdx = pSrc->m_encCABACTableIdx;
#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT
m_splitConsOverrideFlag = pSrc->m_splitConsOverrideFlag;
......
......@@ -1535,6 +1535,9 @@ private:
uint32_t m_colRefIdx;
uint32_t m_maxNumMergeCand;
#if JVET_L0632_AFFINE_MERGE
uint32_t m_maxNumAffineMergeCand;
#endif
double m_lambdas[MAX_NUM_COMPONENT];
......@@ -1776,6 +1779,10 @@ public:
);
void setMaxNumMergeCand(uint32_t val ) { m_maxNumMergeCand = val; }
uint32_t getMaxNumMergeCand() const { return m_maxNumMergeCand; }
#if JVET_L0632_AFFINE_MERGE
void setMaxNumAffineMergeCand( uint32_t val ) { m_maxNumAffineMergeCand = val; }
uint32_t getMaxNumAffineMergeCand() const { return m_maxNumAffineMergeCand; }
#endif
void setNoOutputPriorPicsFlag( bool val ) { m_noOutputPriorPicsFlag = val; }
bool getNoOutputPriorPicsFlag() const { return m_noOutputPriorPicsFlag; }
......
......@@ -89,6 +89,14 @@
#define JVET_L0628_4TAP_INTRA 1 // 4-tap intra-interpolation filtering with switching between Gaussian and DCT-IF filters for luma component
#define JVET_L_AFFINE 1
#if JVET_L_AFFINE
#define JVET_L0271_AFFINE_AMVP_SIMPLIFY 1 // Simplification of affine AMVP list construction
#define JVET_L0694_AFFINE_LINEBUFFER_CLEANUP 1 // Combination of affine mode clean up and line buffer reduction
#define JVET_L0632_AFFINE_MERGE 1 // Affine merge list construction
#define JVET_L0369_SUBBLOCK_MERGE 1 // Moving ATMVP into the affine merge list
#endif
#define REUSE_CU_RESULTS 1
#define REMOVE_MV_ADAPT_PREC 1 // remove the high precision flag in the MV class
......
......@@ -344,6 +344,12 @@ void PredictionUnit::initData()
{
mvdAffi[i][j].setZero();
}
#if JVET_L0694_AFFINE_LINEBUFFER_CLEANUP
for ( uint32_t j = 0; j < 3; j++ )
{
mvAffi[i][j].setZero();
}
#endif
}
}
......@@ -378,6 +384,12 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData)
{
mvdAffi[i][j] = predData.mvdAffi[i][j];
}
#if JVET_L0694_AFFINE_LINEBUFFER_CLEANUP
for ( uint32_t j = 0; j < 3; j++ )
{
mvAffi[i][j] = predData.mvAffi[i][j];
}
#endif
}
return *this;
......@@ -409,6 +421,12 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other )
{
mvdAffi[i][j] = other.mvdAffi[i][j];
}
#if JVET_L0694_AFFINE_LINEBUFFER_CLEANUP
for ( uint32_t j = 0; j < 3; j++ )
{
mvAffi[i][j] = other.mvAffi[i][j];
}
#endif
}
return *this;
......
......@@ -364,6 +364,9 @@ struct InterPredictionData
int16_t refIdx [NUM_REF_PIC_LIST_01];
MergeType mergeType;
Mv mvdAffi [NUM_REF_PIC_LIST_01][3];
#if JVET_L0694_AFFINE_LINEBUFFER_CLEANUP
Mv mvAffi[NUM_REF_PIC_LIST_01][3];
#endif
};
struct PredictionUnit : public UnitArea, public IntraPredictionData, public InterPredictionData
......
This diff is collapsed.
......@@ -133,17 +133,24 @@ namespace PU
bool addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool isCandInter[MRG_MAX_NUM_CANDS], bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos);
#endif
void addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList, const RefPicList eRefPicList2nd, const int currRefPOC, AMVPInfo &info, uint8_t imv);
#endif
#if JVET_L0271_AFFINE_AMVP_SIMPLIFY
bool addAffineMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &eRefPicList, const int &iRefIdx, const Position &pos, const MvpDir &eDir, AffineAMVPInfo &affiAmvpInfo );
#endif
bool isBipredRestriction (const PredictionUnit &pu);
void spanMotionInfo ( PredictionUnit &pu, const MergeCtx &mrgCtx = MergeCtx() );
void applyImv ( PredictionUnit &pu, MergeCtx &mrgCtx, InterPrediction *interPred = NULL );
#if JVET_L0632_AFFINE_MERGE
void getAffineControlPointCand( const PredictionUnit &pu, MotionInfo mi[4], bool bAvailable[4], int verIdx[4], int modelIdx, int verNum, AffineMergeCtx& affMrgCtx );
void getAffineMergeCand( const PredictionUnit &pu, AffineMergeCtx& affMrgCtx, const int mrgCandIdx = -1 );
#else
#if JVET_L0646_GBI
void getAffineMergeCand (const PredictionUnit &pu, MvField(*mvFieldNeighbours)[3], unsigned char &interDirNeighbours, unsigned char &gbiIdx, int &numValidMergeCand);
#else
void getAffineMergeCand (const PredictionUnit &pu, MvField (*mvFieldNeighbours)[3], unsigned char &interDirNeighbours, int &numValidMergeCand );
#endif
bool isAffineMrgFlagCoded (const PredictionUnit &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
#if REMOVE_MV_ADAPT_PREC
......
......@@ -1159,7 +1159,11 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx )
}
if( pu.mergeFlag )
{
#if JVET_L0369_SUBBLOCK_MERGE
subblock_merge_flag( *pu.cu );
#else
affine_flag ( *pu.cu );
#endif
#if JVET_L0054_MMVD
if (pu.mmvdMergeFlag)
{
......@@ -1232,8 +1236,43 @@ void CABACReader::prediction_unit( PredictionUnit& pu, MergeCtx& mrgCtx )
PU::spanMotionInfo( pu, mrgCtx );
}
#if JVET_L0369_SUBBLOCK_MERGE
void CABACReader::subblock_merge_flag( CodingUnit& cu )
{
if ( !cu.cs->slice->isIntra() && (cu.cs->sps->getSpsNext().getUseAffine() || cu.cs->sps->getSpsNext().getUseSubPuMvp()) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__AFFINE_FLAG );
unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
cu.affine = m_BinDecoder.decodeBin( Ctx::AffineFlag( ctxId ) );
DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
}
}
#endif
void CABACReader::affine_flag( CodingUnit& cu )
{
#if JVET_L0369_SUBBLOCK_MERGE
if ( !cu.cs->slice->isIntra() && cu.cs->sps->getSpsNext().getUseAffine() && cu.lumaSize().width > 8 && cu.lumaSize().height > 8 )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__AFFINE_FLAG );
unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
cu.affine = m_BinDecoder.decodeBin( Ctx::AffineFlag( ctxId ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_flag() affine=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
if ( cu.affine && cu.cs->sps->getSpsNext().getUseAffineType() )
{
ctxId = 0;
cu.affineType = m_BinDecoder.decodeBin( Ctx::AffineType( ctxId ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_type() affine_type=%d ctx=%d pos=(%d,%d)\n", cu.affineType ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
}
else
{
cu.affineType = AFFINEMODEL_4PARAM;
}
}
#else
if( cu.cs->slice->isIntra() || !cu.cs->sps->getSpsNext().getUseAffine() || cu.partSize != SIZE_2Nx2N )
{
return;
......@@ -1244,7 +1283,11 @@ void CABACReader::affine_flag( CodingUnit& cu )
return;
}
#if JVET_L0632_AFFINE_MERGE
if ( cu.firstPU->mergeFlag && !(cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8) )
#else
if( cu.firstPU->mergeFlag && !PU::isAffineMrgFlagCoded( *cu.firstPU ) )
#endif
{
return;
}
......@@ -1274,6 +1317,7 @@ void CABACReader::affine_flag( CodingUnit& cu )
{
cu.affineType = AFFINEMODEL_4PARAM;
}
#endif
}
void CABACReader::merge_flag( PredictionUnit& pu )
......@@ -1295,10 +1339,13 @@ void CABACReader::merge_flag( PredictionUnit& pu )
void CABACReader::merge_data( PredictionUnit& pu )
{
#if !JVET_L0632_AFFINE_MERGE
if ( pu.cu->affine )
{
return;
}
#endif
#if JVET_L0054_MMVD
if (pu.cu->mmvdSkip)
{
......@@ -1314,6 +1361,41 @@ void CABACReader::merge_idx( PredictionUnit& pu )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__MERGE_INDEX );
#if JVET_L0632_AFFINE_MERGE
if ( pu.cu->affine )
{
int numCandminus1 = int( pu.cs->slice->getMaxNumAffineMergeCand() ) - 1;
pu.mergeIdx = 0;
if ( numCandminus1 > 0 )
{
if ( m_BinDecoder.decodeBin( Ctx::AffMergeIdx() ) )
{
bool useExtCtx = pu.cs->sps->getSpsNext().getUseSubPuMvp();
pu.mergeIdx++;
for ( ; pu.mergeIdx < numCandminus1; pu.mergeIdx++ )
{
if ( useExtCtx )
{
if ( !m_BinDecoder.decodeBin( Ctx::AffMergeIdx( std::min<int>( pu.mergeIdx, NUM_MERGE_IDX_EXT_CTX - 1 ) ) ) )
{
break;
}
}
else
{
if ( !m_BinDecoder.decodeBinEP() )
{
break;
}
}
}
}
}
DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", pu.mergeIdx );
}
else
{
#endif
int numCandminus1 = int( pu.cs->slice->getMaxNumMergeCand() ) - 1;
pu.mergeIdx = 0;
if( numCandminus1 > 0 )
......@@ -1348,6 +1430,9 @@ void CABACReader::merge_idx( PredictionUnit& pu )
}
}
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", pu.mergeIdx );
#if JVET_L0632_AFFINE_MERGE
}
#endif
}
#if JVET_L0054_MMVD
......
......@@ -96,6 +96,9 @@ public:
void merge_flag ( PredictionUnit& pu );
void merge_data ( PredictionUnit& pu );
void affine_flag ( CodingUnit& cu );
#if JVET_L0369_SUBBLOCK_MERGE
void subblock_merge_flag ( CodingUnit& cu );
#endif
void merge_idx ( PredictionUnit& pu );
#if JVET_L0054_MMVD
void mmvd_merge_idx(PredictionUnit& pu);
......
......@@ -411,7 +411,7 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
}
#endif
#if JVET_L0646_GBI
#if JVET_L0646_GBI && !JVET_L0632_AFFINE_MERGE
uint8_t gbiIdx = GBI_DEFAULT;
#endif
......@@ -472,6 +472,26 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
{
if( pu.cu->affine )
{
#if JVET_L0632_AFFINE_MERGE
AffineMergeCtx affineMergeCtx;
#if JVET_L0369_SUBBLOCK_MERGE
if ( pu.cs->sps->getSpsNext().getUseSubPuMvp() )
{
Size bufSize = g_miScaling.scale( pu.lumaSize() );
mrgCtx.subPuMvpMiBuf = MotionBuf( m_SubPuMiBuf, bufSize );
affineMergeCtx.mrgCtx = &mrgCtx;
}
#endif
PU::getAffineMergeCand( pu, affineMergeCtx, pu.mergeIdx );
pu.interDir = affineMergeCtx.interDirNeighbours[pu.mergeIdx];
pu.cu->affineType = affineMergeCtx.affineType[pu.mergeIdx];
#if JVET_L0632_AFFINE_MERGE
pu.cu->GBiIdx = affineMergeCtx.GBiIdx[pu.mergeIdx];
#endif
#if JVET_L0369_SUBBLOCK_MERGE
pu.mergeType = affineMergeCtx.mergeType[pu.mergeIdx];
#endif
#else
pu.mergeIdx = 0;
MvField affineMvField[2][3];
unsigned char interDirNeighbours;
......@@ -482,31 +502,48 @@ void DecCu::xDeriveCUMV( CodingUnit &cu )
PU::getAffineMergeCand( pu, affineMvField, interDirNeighbours, numValidMergeCand );
#endif
pu.interDir = interDirNeighbours;
#endif
#if JVET_L0369_SUBBLOCK_MERGE
if ( pu.mergeType == MRG_TYPE_SUBPU_ATMVP )
{
pu.refIdx[0] = affineMergeCtx.mvFieldNeighbours[(pu.mergeIdx << 1) + 0][0].refIdx;
pu.refIdx[1] = affineMergeCtx.mvFieldNeighbours[(pu.mergeIdx << 1) + 1][0].refIdx;
}
else
{
#endif
for( int i = 0; i < 2; ++i )
{
if( pu.cs->slice->getNumRefIdx( RefPicList( i ) ) > 0 )
{
#if JVET_L0632_AFFINE_MERGE
MvField* mvField = affineMergeCtx.mvFieldNeighbours[(pu.mergeIdx << 1) + i];
#else
MvField* mvField = affineMvField[i];
#endif
pu.mvpIdx[i] = 0;
pu.mvpNum[i] = 0;
pu.mvd[i] = Mv();
PU::setAllAffineMvField( pu, mvField, RefPicList( i ) );
#if JVET_L0646_GBI
#if JVET_L0646_GBI && !JVET_L0632_AFFINE_MERGE
pu.cu->GBiIdx = gbiIdx;
#endif
}
}
#if JVET_L0369_SUBBLOCK_MERGE
}
#endif
PU::spanMotionInfo( pu, mrgCtx );
}
else
{
#if !JVET_L0369_SUBBLOCK_MERGE
if( pu.cs->sps->getSpsNext().getUseSubPuMvp() )
{
Size bufSize = g_miScaling.scale( pu.lumaSize() );
mrgCtx.subPuMvpMiBuf = MotionBuf( m_SubPuMiBuf, bufSize );
}
#endif
if( cu.cs->pps->getLog2ParallelMergeLevelMinus2() && cu.partSize != SIZE_2Nx2N && cu.lumaSize().width <= 8 )
{
if( !mrgCtx.hasMergedCandList )
......
......@@ -1777,6 +1777,25 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
{
READ_UVLC( uiCode, sps->getSpsNext().getUseSubPuMvp() ? "seven_minus_max_num_merge_cand" : "five_minus_max_num_merge_cand");
pcSlice->setMaxNumMergeCand(MRG_MAX_NUM_CANDS - uiCode - ( sps->getSpsNext().getUseSubPuMvp() ? 0 : 2 ) );
#if JVET_L0632_AFFINE_MERGE
#if JVET_L0369_SUBBLOCK_MERGE
if ( sps->getSpsNext().getUseSubPuMvp() && !sps->getSpsNext().getUseAffine() ) // ATMVP only
{
pcSlice->setMaxNumAffineMergeCand( 1 );
}
else if ( !sps->getSpsNext().getUseSubPuMvp() && !sps->getSpsNext().getUseAffine() ) // both off
{
pcSlice->setMaxNumAffineMergeCand( 0 );
}
else
#endif
if ( sps->getSpsNext().getUseAffine() )
{
READ_UVLC( uiCode, "five_minus_max_num_affine_merge_cand" );
pcSlice->setMaxNumAffineMergeCand( AFFINE_MRG_MAX_NUM_CANDS - uiCode );
}
#endif
}
READ_SVLC( iCode, "slice_qp_delta" );
......
......@@ -1120,7 +1120,11 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu )
}
if( pu.mergeFlag )
{
#if JVET_L0369_SUBBLOCK_MERGE
subblock_merge_flag( *pu.cu );
#else
affine_flag ( *pu.cu );
#endif
#if JVET_L0054_MMVD
if (pu.mmvdMergeFlag)
{
......@@ -1176,8 +1180,35 @@ void CABACWriter::prediction_unit( const PredictionUnit& pu )
}
}
#if JVET_L0369_SUBBLOCK_MERGE
void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
{
if ( !cu.cs->slice->isIntra() && (cu.cs->sps->getSpsNext().getUseAffine() || cu.cs->sps->getSpsNext().getUseATMVP()) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
{
unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) );
DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
}
}
#endif
void CABACWriter::affine_flag( const CodingUnit& cu )
{
#if JVET_L0369_SUBBLOCK_MERGE
if ( !cu.cs->slice->isIntra() && cu.cs->sps->getSpsNext().getUseAffine() && cu.lumaSize().width > 8 && cu.lumaSize().height > 8 )
{
unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) );
DTRACE( g_trace_ctx, D_SYNTAX, "affine_flag() affine=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );