Commit 4d6dd9e1 authored by Yuling Hsiao's avatar Yuling Hsiao

JVET_L0090_PAIR_AVG: Add pairwise average candidates, replace HEVC combined candidates

parent 51f5c25d
......@@ -50,6 +50,8 @@
#include <assert.h>
#include <cassert>
#define JVET_L0090_PAIR_AVG 1 // Add pairwise average candidates, replace HEVC combined candidates
#define JVET_L0392_ALF_INIT_STATE 1
#define JVET_L0664_ALF_REMOVE_LUMA_5x5 1
......
......@@ -502,11 +502,16 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
const uint32_t maxNumMergeCand = slice.getMaxNumMergeCand();
const bool canFastExit = pu.cs->pps->getLog2ParallelMergeLevelMinus2() == 0;
#if !JVET_L0090_PAIR_AVG
// this variable is unused if remove HEVC combined candidates
bool isCandInter[MRG_MAX_NUM_CANDS];
#endif
for (uint32_t ui = 0; ui < maxNumMergeCand; ++ui)
{
#if !JVET_L0090_PAIR_AVG
isCandInter[ui] = false;
#endif
mrgCtx.interDirNeighbours[ui] = 0;
mrgCtx.mrgTypeNeighbours [ui] = MRG_TYPE_DEFAULT_N;
mrgCtx.mvFieldNeighbours[(ui << 1) ].refIdx = NOT_VALID;
......@@ -532,7 +537,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
{
miLeft = puLeft->getMotionInfo( posLB.offset(-1, 0) );
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miLeft.interDir;
......@@ -570,7 +577,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( !isAvailableA1 || ( miAbove != miLeft ) )
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miAbove.interDir;
......@@ -612,7 +621,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( !isAvailableB1 || ( miAbove != miAboveRight ) )
#endif
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miAboveRight.interDir;
......@@ -653,7 +664,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( !isAvailableA1 || ( miBelowLeft != miLeft ) )
#endif
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miBelowLeft.interDir;
......@@ -700,7 +713,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( isAvailableSubPu )
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
mrgCtx.mrgTypeNeighbours[cnt] = MRG_TYPE_SUBPU_ATMVP;
......@@ -736,7 +751,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( ( !isAvailableA1 || ( miLeft != miAboveLeft ) ) && ( !isAvailableB1 || ( miAbove != miAboveLeft ) ) )
#endif
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miAboveLeft.interDir;
......@@ -867,7 +884,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( addTMvp )
{
mrgCtx.interDirNeighbours[uiArrayAddr] = dir;
#if !JVET_L0090_PAIR_AVG
isCandInter [uiArrayAddr] = true;
#endif
if( mrgCandIdx == cnt && canFastExit )
{
......@@ -885,7 +904,97 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
return;
}
#if JVET_L0090_PAIR_AVG
// pairwise-average candidates
{
const int cutoff = std::min( cnt, 4 );
const int end = cutoff * (cutoff - 1) / 2;
constexpr int PRIORITY_LIST0[] = { 0, 0, 1, 0, 1, 2 };
constexpr int PRIORITY_LIST1[] = { 1, 2, 2, 3, 3, 3 };
for( int idx = 0; idx < end && cnt != maxNumMergeCand; idx++ )
{
const int i = PRIORITY_LIST0[idx];
const int j = PRIORITY_LIST1[idx];
mrgCtx.mvFieldNeighbours[cnt * 2].setMvField( Mv( 0, 0 ), NOT_VALID );
mrgCtx.mvFieldNeighbours[cnt * 2 + 1].setMvField( Mv( 0, 0 ), NOT_VALID );
// calculate average MV for L0 and L1 seperately
unsigned char interDir = 0;
for( int refListId = 0; refListId < (slice.isInterB() ? 2 : 1); refListId++ )
{
const short refIdxI = mrgCtx.mvFieldNeighbours[i * 2 + refListId].refIdx;
const short refIdxJ = mrgCtx.mvFieldNeighbours[j * 2 + refListId].refIdx;
// both MVs are invalid, skip
if( (refIdxI == NOT_VALID) && (refIdxJ == NOT_VALID) )
{
continue;
}
interDir += 1 << refListId;
// both MVs are valid, average these two MVs
if( (refIdxI != NOT_VALID) && (refIdxJ != NOT_VALID) )
{
const Mv& MvI = mrgCtx.mvFieldNeighbours[i * 2 + refListId].mv;
const Mv& MvJ = mrgCtx.mvFieldNeighbours[j * 2 + refListId].mv;
// average two MVs
Mv avgMv = MvI;
#if !REMOVE_MV_ADAPT_PREC
if( pu.cs->sps->getSpsNext().getUseHighPrecMv() )
{
avgMv.setHighPrec();
}
#endif
avgMv += MvJ;
avgMv.setHor( avgMv.getHor() / 2 );
avgMv.setVer( avgMv.getVer() / 2 );
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( avgMv, refIdxI );
}
// only one MV is valid, take the only one MV
else if( refIdxI != NOT_VALID )
{
Mv singleMv = mrgCtx.mvFieldNeighbours[i * 2 + refListId].mv;
#if !REMOVE_MV_ADAPT_PREC
if( pu.cs->sps->getSpsNext().getUseHighPrecMv() )
{
singleMv.setHighPrec();
}
#endif
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxI );
}
else if( refIdxJ != NOT_VALID )
{
Mv singleMv = mrgCtx.mvFieldNeighbours[j * 2 + refListId].mv;
#if !REMOVE_MV_ADAPT_PREC
if( pu.cs->sps->getSpsNext().getUseHighPrecMv() )
{
singleMv.setHighPrec();
}
#endif
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxJ );
}
}
mrgCtx.interDirNeighbours[cnt] = interDir;
if( interDir > 0 )
{
cnt++;
}
}
// early termination
if( cnt == maxNumMergeCand )
{
return;
}
}
#endif
uint32_t uiArrayAddr = cnt;
#if !JVET_L0090_PAIR_AVG
uint32_t uiCutoff = std::min( uiArrayAddr, 4u );
if (slice.isInterB())
......@@ -928,6 +1037,7 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
{
return;
}
#endif
int iNumRefIdx = slice.isInterB() ? std::min(slice.getNumRefIdx(REF_PIC_LIST_0), slice.getNumRefIdx(REF_PIC_LIST_1)) : slice.getNumRefIdx(REF_PIC_LIST_0);
......@@ -935,7 +1045,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
int refcnt = 0;
while (uiArrayAddr < maxNumMergeCand)
{
#if !JVET_L0090_PAIR_AVG
isCandInter [uiArrayAddr ] = true;
#endif
mrgCtx.interDirNeighbours [uiArrayAddr ] = 1;
mrgCtx.mvFieldNeighbours [uiArrayAddr << 1].setMvField(Mv(0, 0), r);
......
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