Commit ba922c21 authored by Hongtao Wang's avatar Hongtao Wang

JVET-M0883: Using regular merge index signaling for triangle mode

parent b6cefc80
......@@ -848,6 +848,7 @@ const uint8_t g_triangleWeightLengthChroma[2][2] = { { 5, 7 }, { 3, 3 } };
uint8_t g_triangleMvStorage[TRIANGLE_DIR_NUM][MAX_CU_DEPTH - MIN_CU_LOG2 + 1][MAX_CU_DEPTH - MIN_CU_LOG2 + 1][MAX_CU_SIZE >> MIN_CU_LOG2][MAX_CU_SIZE >> MIN_CU_LOG2];
#if !JVET_M0883_TRIANGLE_SIGNALING
const uint8_t g_triangleCombination[TRIANGLE_MAX_NUM_CANDS][3] =
{
{ 0, 1, 0 }, { 1, 0, 1 }, { 1, 0, 2 }, { 0, 0, 1 }, { 0, 2, 0 },
......@@ -867,4 +868,5 @@ const uint8_t g_triangleIdxBins[TRIANGLE_MAX_NUM_CANDS] =
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10
};
#endif
//! \}
......@@ -253,8 +253,10 @@ extern const uint8_t g_triangleWeightLengthLuma[2];
extern const uint8_t g_triangleWeightLengthChroma[2][2];
#endif
extern uint8_t g_triangleMvStorage[TRIANGLE_DIR_NUM][MAX_CU_DEPTH - MIN_CU_LOG2 + 1][MAX_CU_DEPTH - MIN_CU_LOG2 + 1][MAX_CU_SIZE >> MIN_CU_LOG2][MAX_CU_SIZE >> MIN_CU_LOG2];
#if !JVET_M0883_TRIANGLE_SIGNALING
extern const uint8_t g_triangleCombination[TRIANGLE_MAX_NUM_CANDS][3];
extern const uint8_t g_triangleIdxBins[TRIANGLE_MAX_NUM_CANDS];
#endif
#endif //__TCOMROM__
......@@ -55,6 +55,7 @@
#define JVET_M0063_BDOF_FIX 1 // BDOF bitdepth bugfix
#define JVET_M0265_MV_ROUNDING_CLEANUP 1 // Unify MV roundings and make SW/WD allignment
#define JVET_M0883_TRIANGLE_SIGNALING 1 // Using regular merge index signaling for triangle mode
#define JVET_M0228_REMOVE_CPMV_COMPARE 1 // Remove CPMV comparisons for construnted affine merge candidates from JVET-M0228, M0166, M0477
......
......@@ -343,6 +343,11 @@ void PredictionUnit::initData()
// inter data
mergeFlag = false;
mergeIdx = MAX_UCHAR;
#if JVET_M0883_TRIANGLE_SIGNALING
triangleSplitDir = MAX_UCHAR;
triangleMergeIdx0 = MAX_UCHAR;
triangleMergeIdx1 = MAX_UCHAR;
#endif
mmvdMergeFlag = false;
mmvdMergeIdx = MAX_UINT;
interDir = MAX_UCHAR;
......@@ -388,6 +393,11 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData)
{
mergeFlag = predData.mergeFlag;
mergeIdx = predData.mergeIdx;
#if JVET_M0883_TRIANGLE_SIGNALING
triangleSplitDir = predData.triangleSplitDir ;
triangleMergeIdx0 = predData.triangleMergeIdx0 ;
triangleMergeIdx1 = predData.triangleMergeIdx1 ;
#endif
mmvdMergeFlag = predData.mmvdMergeFlag;
mmvdMergeIdx = predData.mmvdMergeIdx;
interDir = predData.interDir;
......@@ -428,6 +438,11 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other )
mergeFlag = other.mergeFlag;
mergeIdx = other.mergeIdx;
#if JVET_M0883_TRIANGLE_SIGNALING
triangleSplitDir = other.triangleSplitDir ;
triangleMergeIdx0 = other.triangleMergeIdx0 ;
triangleMergeIdx1 = other.triangleMergeIdx1 ;
#endif
mmvdMergeFlag = other.mmvdMergeFlag;
mmvdMergeIdx = other.mmvdMergeIdx;
interDir = other.interDir;
......
......@@ -358,6 +358,11 @@ struct InterPredictionData
{
bool mergeFlag;
uint8_t mergeIdx;
#if JVET_M0883_TRIANGLE_SIGNALING
uint8_t triangleSplitDir;
uint8_t triangleMergeIdx0;
uint8_t triangleMergeIdx1;
#endif
bool mmvdMergeFlag;
uint32_t mmvdMergeIdx;
uint8_t interDir;
......
......@@ -3955,7 +3955,6 @@ void PU::getTriangleMergeCandidates( const PredictionUnit &pu, MergeCtx& triangl
candCount++;
}
}
// put uni-prediction candidate to the triangle candidate list
for( int32_t i = 0; i < candCount; i++ )
{
......@@ -4117,9 +4116,19 @@ bool PU::getTriangleWeights( const PredictionUnit& pu, MergeCtx &triangleMrgCtx,
}
#endif
#if JVET_M0883_TRIANGLE_SIGNALING
void PU::spanTriangleMotionInfo( PredictionUnit &pu, MergeCtx &triangleMrgCtx, const bool splitDir, const uint8_t candIdx0, const uint8_t candIdx1 )
#else
void PU::spanTriangleMotionInfo( PredictionUnit &pu, MergeCtx &triangleMrgCtx, const uint8_t mergeIdx, const bool splitDir, const uint8_t candIdx0, const uint8_t candIdx1 )
#endif
{
#if JVET_M0883_TRIANGLE_SIGNALING
pu.triangleSplitDir = splitDir;
pu.triangleMergeIdx0 = candIdx0;
pu.triangleMergeIdx1 = candIdx1;
#else
pu.mergeIdx = mergeIdx;
#endif
MotionBuf mb = pu.getMotionBuf();
MotionInfo biMv;
......
......@@ -163,7 +163,11 @@ namespace PU
#if !JVET_M0328_KEEP_ONE_WEIGHT_GROUP
bool getTriangleWeights (const PredictionUnit &pu, MergeCtx &triangleMrgCtx, const uint8_t candIdx0, const uint8_t candIdx1);
#endif
#if JVET_M0883_TRIANGLE_SIGNALING
void spanTriangleMotionInfo ( PredictionUnit &pu, MergeCtx &triangleMrgCtx, const bool splitDir, const uint8_t candIdx0, const uint8_t candIdx1);
#else
void spanTriangleMotionInfo ( PredictionUnit &pu, MergeCtx &triangleMrgCtx, const uint8_t mergeIdx, const bool splitDir, const uint8_t candIdx0, const uint8_t candIdx1);
#endif
int32_t mappingRefPic (const PredictionUnit &pu, int32_t refPicPoc, bool targetRefPicList);
void getIbcMVPsEncOnly(PredictionUnit &pu, Mv* MvPred, int& nbPred);
bool getDerivedBV(PredictionUnit &pu, const Mv& currentMv, Mv& derivedMv);
......
......@@ -1637,6 +1637,38 @@ void CABACReader::merge_idx( PredictionUnit& pu )
if( pu.cu->triangle )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET( STATS__CABAC_BITS__TRIANGLE_INDEX );
#if JVET_M0883_TRIANGLE_SIGNALING
bool splitDir;
uint8_t candIdx0;
uint8_t candIdx1;
splitDir = m_BinDecoder.decodeBinEP();
auto decodeOneIdx = [this](int numCandminus1) -> uint8_t
{
uint8_t decIdx = 0;
if( numCandminus1 > 0 )
{
if( this->m_BinDecoder.decodeBin( Ctx::MergeIdx() ) )
{
decIdx++;
for( ; decIdx < numCandminus1; decIdx++ )
{
if( !this->m_BinDecoder.decodeBinEP() )
break;
}
}
}
return decIdx;
};
candIdx0 = decodeOneIdx(TRIANGLE_MAX_NUM_UNI_CANDS - 1);
candIdx1 = decodeOneIdx(TRIANGLE_MAX_NUM_UNI_CANDS - 2);
candIdx1 += candIdx1 >= candIdx0 ? 1 : 0;
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_split_dir=%d\n", splitDir );
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx0=%d\n", candIdx0 );
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx1=%d\n", candIdx1 );
pu.triangleSplitDir = splitDir;
pu.triangleMergeIdx0 = candIdx0;
pu.triangleMergeIdx1 = candIdx1;
#else
if( m_BinDecoder.decodeBin( Ctx::TriangleIdx() ) == 0 )
{
pu.mergeIdx += m_BinDecoder.decodeBinEP();
......@@ -1647,6 +1679,7 @@ void CABACReader::merge_idx( PredictionUnit& pu )
}
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx=%d\n", pu.mergeIdx );
#endif
return;
}
......
......@@ -352,12 +352,22 @@ void DecCu::xReconInter(CodingUnit &cu)
{
if( cu.triangle )
{
#if JVET_M0883_TRIANGLE_SIGNALING
const bool splitDir = cu.firstPU->triangleSplitDir;
const uint8_t candIdx0 = cu.firstPU->triangleMergeIdx0;
const uint8_t candIdx1 = cu.firstPU->triangleMergeIdx1;
#else
const uint8_t mergeIdx = cu.firstPU->mergeIdx;
const bool splitDir = g_triangleCombination[mergeIdx][0];
const uint8_t candIdx0 = g_triangleCombination[mergeIdx][1];
const uint8_t candIdx1 = g_triangleCombination[mergeIdx][2];
#endif
m_pcInterPred->motionCompensation4Triangle( cu, m_triangleMrgCtx, splitDir, candIdx0, candIdx1 );
#if JVET_M0883_TRIANGLE_SIGNALING
PU::spanTriangleMotionInfo( *cu.firstPU, m_triangleMrgCtx, splitDir, candIdx0, candIdx1 );
#else
PU::spanTriangleMotionInfo( *cu.firstPU, m_triangleMrgCtx, mergeIdx, splitDir, candIdx0, candIdx1 );
#endif
}
else
{
......
......@@ -1519,6 +1519,38 @@ void CABACWriter::merge_idx( const PredictionUnit& pu )
{
if( pu.cu->triangle )
{
#if JVET_M0883_TRIANGLE_SIGNALING
bool splitDir = pu.triangleSplitDir;
uint8_t candIdx0 = pu.triangleMergeIdx0;
uint8_t candIdx1 = pu.triangleMergeIdx1;
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_split_dir=%d\n", splitDir );
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx0=%d\n", candIdx0 );
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx1=%d\n", candIdx1 );
candIdx1 -= candIdx1 < candIdx0 ? 0 : 1;
auto encodeOneIdx = [this](uint8_t mrgIdx, int numCandminus1)
{
if(mrgIdx == 0)
{
this->m_BinEncoder.encodeBin( 0, Ctx::MergeIdx() );
return;
}
else
{
this->m_BinEncoder.encodeBin( 1, Ctx::MergeIdx() );
for( unsigned idx = 1; idx < numCandminus1; idx++ )
{
this->m_BinEncoder.encodeBinEP( mrgIdx == idx ? 0 : 1 );
if( mrgIdx == idx )
{
break;
}
}
}
};
m_BinEncoder.encodeBinEP(splitDir);
encodeOneIdx(candIdx0, TRIANGLE_MAX_NUM_UNI_CANDS - 1);
encodeOneIdx(candIdx1, TRIANGLE_MAX_NUM_UNI_CANDS - 2);
#else
if( pu.mergeIdx < 2 )
{
m_BinEncoder.encodeBin( 0, Ctx::TriangleIdx() );
......@@ -1531,6 +1563,7 @@ void CABACWriter::merge_idx( const PredictionUnit& pu )
}
DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() triangle_idx=%d\n", pu.mergeIdx );
#endif
return;
}
int numCandminus1 = int( pu.cs->slice->getMaxNumMergeCand() ) - 1;
......
......@@ -64,6 +64,19 @@ extern std::recursive_mutex g_cache_mutex;
// ====================================================================================================================
// Constructor / destructor / create / destroy
// ====================================================================================================================
#if JVET_M0883_TRIANGLE_SIGNALING
const TriangleMotionInfo EncCu::m_triangleModeTest[TRIANGLE_MAX_NUM_CANDS] =
{
TriangleMotionInfo( 0, 1, 0 ), TriangleMotionInfo( 1, 0, 1 ), TriangleMotionInfo( 1, 0, 2 ), TriangleMotionInfo( 0, 0, 1 ), TriangleMotionInfo( 0, 2, 0 ),
TriangleMotionInfo( 1, 0, 3 ), TriangleMotionInfo( 1, 0, 4 ), TriangleMotionInfo( 1, 1, 0 ), TriangleMotionInfo( 0, 3, 0 ), TriangleMotionInfo( 0, 4, 0 ),
TriangleMotionInfo( 0, 0, 2 ), TriangleMotionInfo( 0, 1, 2 ), TriangleMotionInfo( 1, 1, 2 ), TriangleMotionInfo( 0, 0, 4 ), TriangleMotionInfo( 0, 0, 3 ),
TriangleMotionInfo( 0, 1, 3 ), TriangleMotionInfo( 0, 1, 4 ), TriangleMotionInfo( 1, 1, 4 ), TriangleMotionInfo( 1, 1, 3 ), TriangleMotionInfo( 1, 2, 1 ),
TriangleMotionInfo( 1, 2, 0 ), TriangleMotionInfo( 0, 2, 1 ), TriangleMotionInfo( 0, 4, 3 ), TriangleMotionInfo( 1, 3, 0 ), TriangleMotionInfo( 1, 3, 2 ),
TriangleMotionInfo( 1, 3, 4 ), TriangleMotionInfo( 1, 4, 0 ), TriangleMotionInfo( 1, 3, 1 ), TriangleMotionInfo( 1, 2, 3 ), TriangleMotionInfo( 1, 4, 1 ),
TriangleMotionInfo( 0, 4, 1 ), TriangleMotionInfo( 0, 2, 3 ), TriangleMotionInfo( 1, 4, 2 ), TriangleMotionInfo( 0, 3, 2 ), TriangleMotionInfo( 1, 4, 3 ),
TriangleMotionInfo( 0, 3, 1 ), TriangleMotionInfo( 0, 2, 4 ), TriangleMotionInfo( 1, 2, 4 ), TriangleMotionInfo( 0, 4, 2 ), TriangleMotionInfo( 0, 3, 4 ),
};
#endif
void EncCu::create( EncCfg* encCfg )
{
......@@ -147,6 +160,20 @@ void EncCu::create( EncCfg* encCfg )
{
m_acRealMergeBuffer[ui].create(chromaFormat, Area(0, 0, uiMaxWidth, uiMaxHeight));
}
#if JVET_M0883_TRIANGLE_SIGNALING
for( unsigned ui = 0; ui < TRIANGLE_MAX_NUM_UNI_CANDS; ui++ )
{
for( unsigned uj = 0; uj < TRIANGLE_MAX_NUM_UNI_CANDS; uj++ )
{
if(ui == uj)
continue;
uint8_t idxBits0 = ui + (ui == TRIANGLE_MAX_NUM_UNI_CANDS - 1 ? 0 : 1);
uint8_t candIdx1Enc = uj - (uj > ui ? 1 : 0);
uint8_t idxBits1 = candIdx1Enc + (candIdx1Enc == TRIANGLE_MAX_NUM_UNI_CANDS - 2 ? 0 : 1);
m_triangleIdxBins[1][ui][uj] = m_triangleIdxBins[0][ui][uj] = 1 + idxBits0 + idxBits1;
}
}
#endif
for( unsigned ui = 0; ui < TRIANGLE_MAX_NUM_CANDS; ui++ )
{
m_acTriangleWeightedBuffer[ui].create( chromaFormat, Area( 0, 0, uiMaxWidth, uiMaxHeight ) );
......@@ -2363,11 +2390,23 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
for( uint8_t mergeCand = 0; mergeCand < numTriangleCandidate; mergeCand++ )
{
#if JVET_M0883_TRIANGLE_SIGNALING
bool splitDir = m_triangleModeTest[mergeCand].m_splitDir;
uint8_t candIdx0 = m_triangleModeTest[mergeCand].m_candIdx0;
uint8_t candIdx1 = m_triangleModeTest[mergeCand].m_candIdx1;
#else
bool splitDir = g_triangleCombination[mergeCand][0];
uint8_t candIdx0 = g_triangleCombination[mergeCand][1];
uint8_t candIdx1 = g_triangleCombination[mergeCand][2];
#endif
#if JVET_M0883_TRIANGLE_SIGNALING
pu.triangleSplitDir = splitDir;
pu.triangleMergeIdx0 = candIdx0;
pu.triangleMergeIdx1 = candIdx1;
#else
pu.mergeIdx = mergeCand;
#endif
pu.mergeFlag = true;
triangleWeightedBuffer[mergeCand] = m_acTriangleWeightedBuffer[mergeCand].getBuf( localUnitArea );
triangleBuffer[candIdx0] = m_acMergeBuffer[candIdx0].getBuf( localUnitArea );
......@@ -2382,7 +2421,11 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
Distortion uiSad = distParam.distFunc( distParam );
#if JVET_M0883_TRIANGLE_SIGNALING
uint32_t uiBitsCand = m_triangleIdxBins[splitDir][candIdx0][candIdx1];
#else
uint32_t uiBitsCand = g_triangleIdxBins[mergeCand];
#endif
double cost = (double)uiSad + (double)uiBitsCand * sqrtLambdaForFirstPass;
......@@ -2406,11 +2449,23 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
for( uint8_t i = 0; i < triangleNumMrgSATDCand; i++ )
{
uint8_t mergeCand = triangleRdModeList[i];
#if JVET_M0883_TRIANGLE_SIGNALING
bool splitDir = m_triangleModeTest[mergeCand].m_splitDir;
uint8_t candIdx0 = m_triangleModeTest[mergeCand].m_candIdx0;
uint8_t candIdx1 = m_triangleModeTest[mergeCand].m_candIdx1;
#else
bool splitDir = g_triangleCombination[mergeCand][0];
uint8_t candIdx0 = g_triangleCombination[mergeCand][1];
uint8_t candIdx1 = g_triangleCombination[mergeCand][2];
#endif
#if JVET_M0883_TRIANGLE_SIGNALING
pu.triangleSplitDir = splitDir;
pu.triangleMergeIdx0 = candIdx0;
pu.triangleMergeIdx1 = candIdx1;
#else
pu.mergeIdx = mergeCand;
#endif
pu.mergeFlag = true;
#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP
......@@ -2437,9 +2492,15 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
continue;
}
#if JVET_M0883_TRIANGLE_SIGNALING
bool splitDir = m_triangleModeTest[mergeCand].m_splitDir;
uint8_t candIdx0 = m_triangleModeTest[mergeCand].m_candIdx0;
uint8_t candIdx1 = m_triangleModeTest[mergeCand].m_candIdx1;
#else
bool splitDir = g_triangleCombination[mergeCand][0];
uint8_t candIdx0 = g_triangleCombination[mergeCand][1];
uint8_t candIdx1 = g_triangleCombination[mergeCand][2];
#endif
CodingUnit &cu = tempCS->addCU(tempCS->area, partitioner.chType);
......@@ -2458,10 +2519,20 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru
cu.GBiIdx = GBI_DEFAULT;
PredictionUnit &pu = tempCS->addPU(cu, partitioner.chType);
#if JVET_M0883_TRIANGLE_SIGNALING
pu.triangleSplitDir = splitDir;
pu.triangleMergeIdx0 = candIdx0;
pu.triangleMergeIdx1 = candIdx1;
#else
pu.mergeIdx = mergeCand;
#endif
pu.mergeFlag = true;
#if JVET_M0883_TRIANGLE_SIGNALING
PU::spanTriangleMotionInfo(pu, triangleMrgCtx, splitDir, candIdx0, candIdx1 );
#else
PU::spanTriangleMotionInfo(pu, triangleMrgCtx, mergeCand, splitDir, candIdx0, candIdx1 );
#endif
if( tempBufSet )
{
......
......@@ -68,6 +68,16 @@ class EncSlice;
// ====================================================================================================================
/// CU encoder class
#if JVET_M0883_TRIANGLE_SIGNALING
struct TriangleMotionInfo
{
uint8_t m_splitDir;
uint8_t m_candIdx0;
uint8_t m_candIdx1;
TriangleMotionInfo ( uint8_t splitDir, uint8_t candIdx0, uint8_t candIdx1 ): m_splitDir(splitDir), m_candIdx0(candIdx0), m_candIdx1(candIdx1) { }
};
#endif
class EncCu
#if REUSE_CU_RESULTS
: DecCu
......@@ -135,6 +145,10 @@ private:
#endif
int m_bestGbiIdx[2];
double m_bestGbiCost[2];
#if JVET_M0883_TRIANGLE_SIGNALING
static const TriangleMotionInfo m_triangleModeTest[TRIANGLE_MAX_NUM_CANDS];
uint8_t m_triangleIdxBins[2][TRIANGLE_MAX_NUM_UNI_CANDS][TRIANGLE_MAX_NUM_UNI_CANDS];
#endif
#if SHARP_LUMA_DELTA_QP
void updateLambda ( Slice* slice, double dQP );
#endif
......
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