diff --git a/doc/figures/YUView.png b/doc/figures/YUView.png new file mode 100644 index 0000000000000000000000000000000000000000..0b6b81f0954adc8df0fa95e4b10f78c337e2667c Binary files /dev/null and b/doc/figures/YUView.png differ diff --git a/doc/figures/raceHorsesShot2MotionVectors.png b/doc/figures/raceHorsesShot2MotionVectors.png new file mode 100644 index 0000000000000000000000000000000000000000..4a35a3928103d6ac5f052bbd5fdacb2ed283b084 Binary files /dev/null and b/doc/figures/raceHorsesShot2MotionVectors.png differ diff --git a/doc/figures/raceHorsesShot3SkipFlag.png b/doc/figures/raceHorsesShot3SkipFlag.png new file mode 100644 index 0000000000000000000000000000000000000000..b4b50ee752d19b94ad1620c5174521e528850785 Binary files /dev/null and b/doc/figures/raceHorsesShot3SkipFlag.png differ diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index ede8d83edc59b0b1acf952398d651a13cdd9adb1..cd524e4c7d019bf30961f3722be968b92082887a 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -765,11 +765,22 @@ void InterPrediction::xPredAffineBlk( const ComponentID& compID, const Predictio else { #if JVET_M0265_MV_ROUNDING_CLEANUP +#if JVET_M0192_AFF_CHROMA_SIMPL + Mv curMv = m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE) * MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE)] + + m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE + 1)* MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE + 1)]; + roundAffineMv(curMv.hor, curMv.ver, 1); +#else Mv curMv = m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE) * MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE)] + m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE + 1)* MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE)] + m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE)* MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE + 1)] + m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE + 1)* MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE + 1)]; roundAffineMv(curMv.hor, curMv.ver, 2); +#endif +#else +#if JVET_M0192_AFF_CHROMA_SIMPL + Mv curMv = m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE) * MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE)] + + m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE + 1)* MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE + 1)]; + roundAffineMv(curMv.hor, curMv.ver, 1); #else Mv curMv = (m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE) * MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE)] + m_storedMv[((h << iScaleY) / AFFINE_MIN_BLOCK_SIZE + 1)* MVBUFFER_SIZE + ((w << iScaleX) / AFFINE_MIN_BLOCK_SIZE)] + @@ -777,6 +788,7 @@ 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); +#endif #endif if (sps.getWrapAroundEnabledFlag()) { @@ -1288,12 +1300,37 @@ void InterPrediction::motionCompensation4Triangle( CodingUnit &cu, MergeCtx &tri PU::spanMotionInfo( pu ); motionCompensation( pu, predBuf ); +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + weightedTriangleBlk( pu, splitDir, MAX_NUM_CHANNEL_TYPE, predBuf, tmpTriangleBuf, predBuf ); +#else weightedTriangleBlk( pu, PU::getTriangleWeights(pu, triangleMrgCtx, candIdx0, candIdx1), splitDir, MAX_NUM_CHANNEL_TYPE, predBuf, tmpTriangleBuf, predBuf ); +#endif } } +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP +void InterPrediction::weightedTriangleBlk( PredictionUnit &pu, const bool splitDir, int32_t channel, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 ) +#else void InterPrediction::weightedTriangleBlk( PredictionUnit &pu, bool weights, const bool splitDir, int32_t channel, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 ) +#endif { +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + if( channel == CHANNEL_TYPE_LUMA ) + { + xWeightedTriangleBlk( pu, pu.lumaSize().width, pu.lumaSize().height, COMPONENT_Y, splitDir, predDst, predSrc0, predSrc1 ); + } + else if( channel == CHANNEL_TYPE_CHROMA ) + { + xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cb, splitDir, predDst, predSrc0, predSrc1 ); + xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cr, splitDir, predDst, predSrc0, predSrc1 ); + } + else + { + xWeightedTriangleBlk( pu, pu.lumaSize().width, pu.lumaSize().height, COMPONENT_Y, splitDir, predDst, predSrc0, predSrc1 ); + xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cb, splitDir, predDst, predSrc0, predSrc1 ); + xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cr, splitDir, predDst, predSrc0, predSrc1 ); + } +#else if( channel == CHANNEL_TYPE_LUMA ) { xWeightedTriangleBlk( pu, pu.lumaSize().width, pu.lumaSize().height, COMPONENT_Y, splitDir, weights, predDst, predSrc0, predSrc1 ); @@ -1309,9 +1346,14 @@ void InterPrediction::weightedTriangleBlk( PredictionUnit &pu, bool weights, con xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cb, splitDir, weights, predDst, predSrc0, predSrc1 ); xWeightedTriangleBlk( pu, pu.chromaSize().width, pu.chromaSize().height, COMPONENT_Cr, splitDir, weights, predDst, predSrc0, predSrc1 ); } +#endif } +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP +void InterPrediction::xWeightedTriangleBlk( const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const bool splitDir, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 ) +#else void InterPrediction::xWeightedTriangleBlk( const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const bool splitDir, const bool weights, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 ) +#endif { Pel* dst = predDst .get(compIdx).buf; Pel* src0 = predSrc0.get(compIdx).buf; @@ -1330,13 +1372,23 @@ void InterPrediction::xWeightedTriangleBlk( const PredictionUnit &pu, const uint const int32_t ratioWH = (width > height) ? (width / height) : 1; const int32_t ratioHW = (width > height) ? 1 : (height / width); +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + const bool longWeight = (compIdx == COMPONENT_Y) || ( predDst.chromaFormat == CHROMA_444 ); + const int32_t weightedLength = longWeight ? 7 : 3; +#else const Pel* pelWeighted = (compIdx == COMPONENT_Y) ? g_trianglePelWeightedLuma[splitDir][weights] : g_trianglePelWeightedChroma[predDst.chromaFormat == CHROMA_444 ? 0 : 1][splitDir][weights]; const int32_t weightedLength = (compIdx == COMPONENT_Y) ? g_triangleWeightLengthLuma[weights] : g_triangleWeightLengthChroma[predDst.chromaFormat == CHROMA_444 ? 0 : 1][weights]; +#endif int32_t weightedStartPos = ( splitDir == 0 ) ? ( 0 - (weightedLength >> 1) * ratioWH ) : ( width - ((weightedLength + 1) >> 1) * ratioWH ); int32_t weightedEndPos = weightedStartPos + weightedLength * ratioWH - 1; int32_t weightedPosoffset =( splitDir == 0 ) ? ratioWH : -ratioWH; +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + Pel tmpPelWeighted; + int32_t weightIdx; +#else const Pel* tmpPelWeighted; +#endif int32_t x, y, tmpX, tmpY, tmpWeightedStart, tmpWeightedEnd; for( y = 0; y < height; y+= ratioHW ) @@ -1352,18 +1404,36 @@ void InterPrediction::xWeightedTriangleBlk( const PredictionUnit &pu, const uint tmpWeightedStart = std::max((int32_t)0, weightedStartPos); tmpWeightedEnd = std::min(weightedEndPos, (int32_t)(width - 1)); +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + weightIdx = 1; +#else tmpPelWeighted = pelWeighted; +#endif if( weightedStartPos < 0 ) { +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + weightIdx += abs(weightedStartPos) / ratioWH; +#else tmpPelWeighted += abs(weightedStartPos) / ratioWH; +#endif } for( x = tmpWeightedStart; x <= tmpWeightedEnd; x+= ratioWH ) { for( tmpX = ratioWH; tmpX > 0; tmpX-- ) { +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + tmpPelWeighted = Clip3( 1, 7, longWeight ? weightIdx : (weightIdx * 2)); + tmpPelWeighted = splitDir ? ( 8 - tmpPelWeighted ) : tmpPelWeighted; + *dst++ = ClipPel( rightShift( (tmpPelWeighted*(*src0++) + ((8 - tmpPelWeighted) * (*src1++)) + offsetWeighted), shiftWeighted ), clipRng ); +#else *dst++ = ClipPel( rightShift( ((*tmpPelWeighted)*(*src0++) + ((8 - (*tmpPelWeighted)) * (*src1++)) + offsetWeighted), shiftWeighted ), clipRng ); +#endif } +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + weightIdx ++; +#else tmpPelWeighted++; +#endif } for( x = weightedEndPos + 1; x < width; x++ ) diff --git a/source/Lib/CommonLib/InterPrediction.h b/source/Lib/CommonLib/InterPrediction.h index 741cc655a871a28fd86ec8db87b0aace19a1c1af..5574f28e05bdd8a2abb7b1ab9a54ea7a1a26f9c5 100644 --- a/source/Lib/CommonLib/InterPrediction.h +++ b/source/Lib/CommonLib/InterPrediction.h @@ -129,7 +129,11 @@ protected: void xWeightedAverage ( const PredictionUnit& pu, const CPelUnitBuf& pcYuvSrc0, const CPelUnitBuf& pcYuvSrc1, PelUnitBuf& pcYuvDst, const BitDepths& clipBitDepths, const ClpRngs& clpRngs, const bool& bioApplied ); void xPredAffineBlk( const ComponentID& compID, const PredictionUnit& pu, const Picture* refPic, const Mv* _mv, PelUnitBuf& dstPic, const bool& bi, const ClpRng& clpRng ); +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + void xWeightedTriangleBlk ( const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const bool splitDir, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 ); +#else void xWeightedTriangleBlk ( const PredictionUnit &pu, const uint32_t width, const uint32_t height, const ComponentID compIdx, const bool splitDir, const bool weights, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 ); +#endif static bool xCheckIdenticalMotion( const PredictionUnit& pu ); @@ -160,7 +164,11 @@ public: ); void motionCompensation4Triangle( CodingUnit &cu, MergeCtx &triangleMrgCtx, const bool splitDir, const uint8_t candIdx0, const uint8_t candIdx1 ); +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + void weightedTriangleBlk ( PredictionUnit &pu, const bool splitDir, int32_t channel, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 ); +#else void weightedTriangleBlk ( PredictionUnit &pu, bool weights, const bool splitDir, int32_t channel, PelUnitBuf& predDst, PelUnitBuf& predSrc0, PelUnitBuf& predSrc1 ); +#endif #if JVET_J0090_MEMORY_BANDWITH_MEASURE void cacheAssign( CacheModel *cache ); diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index a485d9fadf0a04f6d7a1aa3e0a9cc7ae868502a9..0d6cee99ea5671ff8358ebbc3fac0df5d4f16f95 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -806,6 +806,7 @@ const uint8_t g_NonMPM[257] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8 }; +#if !JVET_M0328_KEEP_ONE_WEIGHT_GROUP const Pel g_trianglePelWeightedLuma[TRIANGLE_DIR_NUM][2][7] = { { // TRIANGLE_DIR_135 @@ -843,9 +844,11 @@ const Pel g_trianglePelWeightedChroma[2][TRIANGLE_DIR_NUM][2][7] = const uint8_t g_triangleWeightLengthLuma[2] = { 5, 7 }; const uint8_t g_triangleWeightLengthChroma[2][2] = { { 5, 7 }, { 3, 3 } }; +#endif 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 }, @@ -865,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 //! \} diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h index 2a856a448d8bd7b4f06454e42cbf9806a8022191..63520f58e341698dc48697f9fa38263bd9aa8cf7 100644 --- a/source/Lib/CommonLib/Rom.h +++ b/source/Lib/CommonLib/Rom.h @@ -246,13 +246,17 @@ constexpr uint8_t g_tbMax[257] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, //! \} +#if !JVET_M0328_KEEP_ONE_WEIGHT_GROUP extern const Pel g_trianglePelWeightedLuma[TRIANGLE_DIR_NUM][2][7]; extern const Pel g_trianglePelWeightedChroma[2][TRIANGLE_DIR_NUM][2][7]; 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__ diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 7e6d305a1236dd48a4fd82550c19fd840b018c9b..eafa690993ea9e0f292e2ca43912712e9ad12f3f 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1801,9 +1801,6 @@ SPSNext::SPSNext( SPS& sps ) , m_MTTEnabled ( false ) , m_MHIntra ( false ) , m_Triangle ( false ) -#if JVET_M0255_FRACMMVD_SWITCH - , allowDisFracMMVD ( false ) -#endif #if ENABLE_WPP_PARALLELISM , m_NextDQP ( false ) #endif @@ -1873,6 +1870,9 @@ SPS::SPS() , m_bPCMFilterDisableFlag (false) , m_sbtmvpEnabledFlag (false) , m_bdofEnabledFlag (false) +#if JVET_M0255_FRACMMVD_SWITCH +, m_disFracMmvdEnabledFlag ( false ) +#endif , m_uiBitsForPOC ( 8) , m_numLongTermRefPicSPS ( 0) , m_uiMaxTrSize ( 32) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 3298cd8406fc3666eb195c941dab7c1ff0c87b0a..d28d9ebfb635362568ecd2ef11e9b3b07a2884f5 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -820,9 +820,6 @@ private: bool m_MTTEnabled; // bool m_MHIntra; bool m_Triangle; -#if JVET_M0255_FRACMMVD_SWITCH - bool allowDisFracMMVD; -#endif #if ENABLE_WPP_PARALLELISM bool m_NextDQP; #endif @@ -919,10 +916,6 @@ public: bool getUseTriangle () const { return m_Triangle; } void setIBCMode (unsigned IBCMode) { m_IBCMode = IBCMode; } unsigned getIBCMode () const { return m_IBCMode; } -#if JVET_M0255_FRACMMVD_SWITCH - void setAllowDisFracMMVD ( bool b ) { allowDisFracMMVD = b; } - bool getAllowDisFracMMVD () const { return allowDisFracMMVD; } -#endif }; @@ -997,7 +990,9 @@ private: bool m_sbtmvpEnabledFlag; bool m_bdofEnabledFlag; - +#if JVET_M0255_FRACMMVD_SWITCH + bool m_disFracMmvdEnabledFlag; +#endif uint32_t m_uiBitsForPOC; uint32_t m_numLongTermRefPicSPS; uint32_t m_ltRefPicPocLsbSps[MAX_NUM_LONG_TERM_REF_PICS]; @@ -1200,6 +1195,11 @@ public: void setBDOFEnabledFlag(bool b) { m_bdofEnabledFlag = b; } bool getBDOFEnabledFlag() const { return m_bdofEnabledFlag; } +#if JVET_M0255_FRACMMVD_SWITCH + bool getDisFracMmvdEnabledFlag() const { return m_disFracMmvdEnabledFlag; } + void setDisFracMmvdEnabledFlag( bool b ) { m_disFracMmvdEnabledFlag = b; } +#endif + uint32_t getMaxTLayers() const { return m_uiMaxTLayers; } void setMaxTLayers( uint32_t uiMaxTLayers ) { CHECK( uiMaxTLayers > MAX_TLAYER, "Invalid number T-layers" ); m_uiMaxTLayers = uiMaxTLayers; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index cecbc4a8e8656ecca050212767b1493afb8852c6..073e626f77e499c7e35ed79c2928cace4effab6c 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,11 +50,16 @@ #include <assert.h> #include <cassert> +#define JVET_M0193_PAIR_AVG_REDUCTION 1 //Use only one pairwise average candidate + +#define JVET_M0192_AFF_CHROMA_SIMPL 1 // Affine chroma MV derivation simplification and rounding unification + #define JVET_M0116_ATMVP_LEFT_NB_FOR_OFFSET 1 // Only use left neighbor for ATMVP offset derivation, from M0273, M0240, M0116, M0338, M0204 #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 @@ -79,6 +84,7 @@ #define JVET_M0142_CCLM_COLLOCATED_CHROMA 1 // Adding support for chroma sample location type 2 in CCLM +#define JVET_M0328_KEEP_ONE_WEIGHT_GROUP 1 #define JVET_M0479_18BITS_MV_CLIP 1 diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index bb4d9470ca183c7fc17ce36418b3d1db1b967979..abcb04ae3245f96f581d39f035ff151ffeaca3c9 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -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; @@ -391,6 +396,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; @@ -431,6 +441,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; diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index a1e1a75b6e7220573877e6f796ba45b3612b5c49..9d5322234d7465abc72c28e4d7f351bd458140f9 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -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; diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 2e955f53f410d1378c6ed8016d2e863ce06ebd5a..c997743d28bb1a2ecbc822daa5269f517b7de351 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -1222,15 +1222,24 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, #if JVET_L0090_PAIR_AVG // pairwise-average candidates { +#if !JVET_M0193_PAIR_AVG_REDUCTION 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 }; +#endif +#if JVET_M0193_PAIR_AVG_REDUCTION + // skip when only 1 candidate is added so far or one is BV and one is MV + if( cnt > 1 && cnt < maxNumMergeCand && !(mrgCtx.mrgTypeNeighbours[0] != mrgCtx.mrgTypeNeighbours[1] && pu.cs->sps->getSpsNext().getIBCMode())) +#else for( int idx = 0; idx < end && cnt != maxNumMergeCand; idx++ ) +#endif { +#if !JVET_M0193_PAIR_AVG_REDUCTION const int i = PRIORITY_LIST0[idx]; const int j = PRIORITY_LIST1[idx]; +#endif mrgCtx.mvFieldNeighbours[cnt * 2].setMvField( Mv( 0, 0 ), NOT_VALID ); mrgCtx.mvFieldNeighbours[cnt * 2 + 1].setMvField( Mv( 0, 0 ), NOT_VALID ); @@ -1238,15 +1247,22 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, unsigned char interDir = 0; +#if !JVET_M0193_PAIR_AVG_REDUCTION // skip when one is BV and one is MV if (mrgCtx.mrgTypeNeighbours[i] != mrgCtx.mrgTypeNeighbours[j] && pu.cs->sps->getSpsNext().getIBCMode()) { continue; } +#endif for( int refListId = 0; refListId < (slice.isInterB() ? 2 : 1); refListId++ ) { +#if JVET_M0193_PAIR_AVG_REDUCTION + const short refIdxI = mrgCtx.mvFieldNeighbours[0 * 2 + refListId].refIdx; + const short refIdxJ = mrgCtx.mvFieldNeighbours[1 * 2 + refListId].refIdx; +#else const short refIdxI = mrgCtx.mvFieldNeighbours[i * 2 + refListId].refIdx; const short refIdxJ = mrgCtx.mvFieldNeighbours[j * 2 + refListId].refIdx; +#endif // both MVs are invalid, skip if( (refIdxI == NOT_VALID) && (refIdxJ == NOT_VALID) ) @@ -1258,8 +1274,13 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, // both MVs are valid, average these two MVs if( (refIdxI != NOT_VALID) && (refIdxJ != NOT_VALID) ) { +#if JVET_M0193_PAIR_AVG_REDUCTION + const Mv& MvI = mrgCtx.mvFieldNeighbours[0 * 2 + refListId].mv; + const Mv& MvJ = mrgCtx.mvFieldNeighbours[1 * 2 + refListId].mv; +#else const Mv& MvI = mrgCtx.mvFieldNeighbours[i * 2 + refListId].mv; const Mv& MvJ = mrgCtx.mvFieldNeighbours[j * 2 + refListId].mv; +#endif // average two MVs Mv avgMv = MvI; @@ -1272,7 +1293,11 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, #endif +#if JVET_M0193_PAIR_AVG_REDUCTION + if (mrgCtx.mrgTypeNeighbours[0] == MRG_TYPE_IBC && mrgCtx.mrgTypeNeighbours[1] == MRG_TYPE_IBC && pu.cs->sps->getSpsNext().getIBCMode()) +#else if (mrgCtx.mrgTypeNeighbours[i] == MRG_TYPE_IBC && mrgCtx.mrgTypeNeighbours[j] == MRG_TYPE_IBC && pu.cs->sps->getSpsNext().getIBCMode()) +#endif { mrgCtx.mrgTypeNeighbours[cnt] = MRG_TYPE_IBC; avgMv.setHor((avgMv.getHor() / 16) << 4); @@ -1284,12 +1309,20 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, // only one MV is valid, take the only one MV else if( refIdxI != NOT_VALID ) { +#if JVET_M0193_PAIR_AVG_REDUCTION + Mv singleMv = mrgCtx.mvFieldNeighbours[0 * 2 + refListId].mv; +#else Mv singleMv = mrgCtx.mvFieldNeighbours[i * 2 + refListId].mv; +#endif mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxI ); } else if( refIdxJ != NOT_VALID ) { +#if JVET_M0193_PAIR_AVG_REDUCTION + Mv singleMv = mrgCtx.mvFieldNeighbours[1 * 2 + refListId].mv; +#else Mv singleMv = mrgCtx.mvFieldNeighbours[j * 2 + refListId].mv; +#endif mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxJ ); } } @@ -3955,7 +3988,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++ ) { @@ -4090,6 +4122,7 @@ bool PU::isUniqueTriangleCandidates( const PredictionUnit &pu, MergeCtx& triangl return true; } +#if !JVET_M0328_KEEP_ONE_WEIGHT_GROUP bool PU::getTriangleWeights( const PredictionUnit& pu, MergeCtx &triangleMrgCtx, const uint8_t candIdx0, const uint8_t candIdx1 ) { RefPicList refPicListCand0 = triangleMrgCtx.interDirNeighbours[candIdx0] == 1 ? REF_PIC_LIST_0 : REF_PIC_LIST_1; @@ -4114,10 +4147,21 @@ bool PU::getTriangleWeights( const PredictionUnit& pu, MergeCtx &triangleMrgCtx, return false; } +#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; diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 0b7c97f00bbcb8f128e2befbc791a9d559ad5034..3795ed91c9decc2c1068c12130746a8b73bac5af 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -160,8 +160,14 @@ namespace PU int getNarrowShape (const int width, const int height); void getTriangleMergeCandidates (const PredictionUnit &pu, MergeCtx &triangleMrgCtx); bool isUniqueTriangleCandidates (const PredictionUnit &pu, MergeCtx &triangleMrgCtx); +#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); diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 7f57b25d50054957d4a3adfb2925760ab830a814..265d98ded7b171f372acf87b64cbba858c489921 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -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; } diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index 6913f67f690f184b7f47a0e3664118494d989372..b36cb3207e8d2c10913f78b4826506b09c758e22 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -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 { diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 53c2b7cc38408311b5476901fb10083363dd936c..94b555869904b70a7f95e1705f277fa1c903028a 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -818,9 +818,6 @@ void HLSyntaxReader::parseSPSNext( SPSNext& spsNext, const bool usePCM ) } READ_FLAG( symbol, "mtt_enabled_flag" ); spsNext.setMTTMode ( symbol ); READ_FLAG( symbol, "mhintra_flag" ); spsNext.setUseMHIntra ( symbol != 0 ); -#if JVET_M0255_FRACMMVD_SWITCH - READ_FLAG( symbol, "sps_fracmmvd_disabled_flag" ); spsNext.setAllowDisFracMMVD ( symbol != 0 ); -#endif READ_FLAG( symbol, "triangle_flag" ); spsNext.setUseTriangle ( symbol != 0 ); #if ENABLE_WPP_PARALLELISM READ_FLAG( symbol, "next_dqp_enabled_flag" ); spsNext.setUseNextDQP ( symbol != 0 ); @@ -1050,7 +1047,10 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) } READ_FLAG( uiCode, "sps_bdof_enable_flag" ); pcSPS->setBDOFEnabledFlag ( uiCode != 0 ); - +#if JVET_M0255_FRACMMVD_SWITCH + READ_FLAG( uiCode, "sps_fracmmvd_disabled_flag" ); pcSPS->setDisFracMmvdEnabledFlag ( uiCode != 0 ); +#endif + #if HEVC_USE_SCALING_LISTS READ_FLAG( uiCode, "scaling_list_enabled_flag" ); pcSPS->setScalingListFlag ( uiCode ); if(pcSPS->getScalingListFlag()) @@ -1771,7 +1771,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para pcSlice->setMaxNumAffineMergeCand( AFFINE_MRG_MAX_NUM_CANDS - uiCode ); } #if JVET_M0255_FRACMMVD_SWITCH - if ( sps->getSpsNext().getAllowDisFracMMVD() ) + if ( sps->getDisFracMmvdEnabledFlag() ) { READ_FLAG( uiCode, "tile_group_fracmmvd_disabled_flag" ); pcSlice->setDisFracMMVD( uiCode ? true : false ); diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 862ed9835939e286b518776f3f6c1381e626fa7b..010808ea87a76da78ca9084ce4e34f4690cf7a86 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -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; diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index a4fd0463202cd0050276c7dd2597ad3ae430a766..1500c9a368c1b8924a0aec9ef59c8b4bcb54b1e6 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -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 ) ); @@ -2383,23 +2410,42 @@ 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 ); triangleBuffer[candIdx1] = m_acMergeBuffer[candIdx1].getBuf( localUnitArea ); +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + m_pcInterSearch->weightedTriangleBlk( pu, splitDir, CHANNEL_TYPE_LUMA, triangleWeightedBuffer[mergeCand], triangleBuffer[candIdx0], triangleBuffer[candIdx1] ); +#else m_pcInterSearch->weightedTriangleBlk( pu, PU::getTriangleWeights(pu, triangleMrgCtx, candIdx0, candIdx1), splitDir, CHANNEL_TYPE_LUMA, triangleWeightedBuffer[mergeCand], triangleBuffer[candIdx0], triangleBuffer[candIdx1] ); - +#endif distParam.cur = triangleWeightedBuffer[mergeCand].Y(); 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; @@ -2423,14 +2469,30 @@ 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 + m_pcInterSearch->weightedTriangleBlk( pu, splitDir, CHANNEL_TYPE_CHROMA, triangleWeightedBuffer[mergeCand], triangleBuffer[candIdx0], triangleBuffer[candIdx1] ); +#else m_pcInterSearch->weightedTriangleBlk( pu, PU::getTriangleWeights(pu, triangleMrgCtx, candIdx0, candIdx1), splitDir, CHANNEL_TYPE_CHROMA, triangleWeightedBuffer[mergeCand], triangleBuffer[candIdx0], triangleBuffer[candIdx1] ); +#endif } tempCS->initStructData( encTestMode.qp, encTestMode.lossless ); @@ -2450,9 +2512,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); @@ -2471,10 +2539,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 ) { @@ -2485,7 +2563,11 @@ void EncCu::xCheckRDCostMergeTriangle2Nx2N( CodingStructure *&tempCS, CodingStru triangleBuffer[candIdx0] = m_acMergeBuffer[candIdx0].getBuf( localUnitArea ); triangleBuffer[candIdx1] = m_acMergeBuffer[candIdx1].getBuf( localUnitArea ); PelUnitBuf predBuf = tempCS->getPredBuf(); +#if JVET_M0328_KEEP_ONE_WEIGHT_GROUP + m_pcInterSearch->weightedTriangleBlk( pu, splitDir, MAX_NUM_CHANNEL_TYPE, predBuf, triangleBuffer[candIdx0], triangleBuffer[candIdx1] ); +#else m_pcInterSearch->weightedTriangleBlk( pu, PU::getTriangleWeights(pu, triangleMrgCtx, candIdx0, candIdx1), splitDir, MAX_NUM_CHANNEL_TYPE, predBuf, triangleBuffer[candIdx0], triangleBuffer[candIdx1] ); +#endif } #if JVET_M0464_UNI_MTS diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h index 0d4d0d2b56711742ed500b76d8237f98251ec20d..920e0eca595016e272842c99c0eb4cf9f29e72dd 100644 --- a/source/Lib/EncoderLib/EncCu.h +++ b/source/Lib/EncoderLib/EncCu.h @@ -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 @@ -160,7 +174,7 @@ public: void setMergeBestSATDCost(double cost) { m_mergeBestSATDCost = cost; } double getMergeBestSATDCost() { return m_mergeBestSATDCost; } #if JVET_M0255_FRACMMVD_SWITCH - IbcHashMap& getCprHashMap() { return m_ibcHashMap; } + IbcHashMap& getIbcHashMap() { return m_ibcHashMap; } EncCfg* getEncCfg() const { return m_pcEncCfg; } #endif diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index bbf61d5839316b212182d9662dc98a9ab8dc3b78..e3fa09d81e87633dda9bc6cd79bc73259dda47cf 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -892,7 +892,7 @@ void EncLib::xInitSPS(SPS &sps) sps.getSpsNext().setUseMHIntra ( m_MHIntra ); sps.getSpsNext().setUseTriangle ( m_Triangle ); #if JVET_M0255_FRACMMVD_SWITCH - sps.getSpsNext().setAllowDisFracMMVD ( m_allowDisFracMMVD ); + sps.setDisFracMmvdEnabledFlag ( m_allowDisFracMMVD ); #endif sps.getSpsNext().setIBCMode ( m_IBCMode ); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index dae751b02850c032e49a4dd6338a26b43fbe02c0..3fa94373cc81e1c3832a4ea2c85456ecb4119e12 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1401,7 +1401,7 @@ void EncSlice::checkDisFracMmvd( Picture* pcPic, uint32_t startCtuTsAddr, uint32 uint32_t totalCtu = 0; uint32_t hashRatio = 0; - if ( !pcSlice->getSPS()->getSpsNext().getAllowDisFracMMVD() ) + if ( !pcSlice->getSPS()->getDisFracMmvdEnabledFlag() ) { return; } @@ -1419,7 +1419,7 @@ void EncSlice::checkDisFracMmvd( Picture* pcPic, uint32_t startCtuTsAddr, uint32 const Position pos ( ctuXPosInCtus * pcv.maxCUWidth, ctuYPosInCtus * pcv.maxCUHeight ); const UnitArea ctuArea( cs.area.chromaFormat, Area( pos.x, pos.y, pcv.maxCUWidth, pcv.maxCUHeight ) ); - hashRatio += m_pcCuEncoder->getCprHashMap().getHashHitRatio( ctuArea.Y() ); + hashRatio += m_pcCuEncoder->getIbcHashMap().getHashHitRatio( ctuArea.Y() ); totalCtu++; } @@ -1484,10 +1484,10 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons } #endif #if JVET_M0255_FRACMMVD_SWITCH - if ( pcSlice->getSPS()->getSpsNext().getAllowDisFracMMVD() || + if ( pcSlice->getSPS()->getDisFracMmvdEnabledFlag() || ( pcSlice->getSPS()->getSpsNext().getIBCMode() && m_pcCuEncoder->getEncCfg()->getIBCHashSearch() ) ) { - m_pcCuEncoder->getCprHashMap().rebuildPicHashMap( cs.picture->getOrigBuf() ); + m_pcCuEncoder->getIbcHashMap().rebuildPicHashMap( cs.picture->getOrigBuf() ); } checkDisFracMmvd( pcPic, startCtuTsAddr, boundingCtuTsAddr ); #endif diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 531a6693536ba5640f5b423ed553d4e409067e44..5d4ea024ffd108d353f9f38b3971d13b22eff878 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -559,9 +559,6 @@ void HLSWriter::codeSPSNext( const SPSNext& spsNext, const bool usePCM ) WRITE_FLAG( spsNext.getMTTEnabled() ? 1 : 0, "mtt_enabled_flag" ); WRITE_FLAG( spsNext.getUseMHIntra() ? 1 : 0, "mhintra_flag" ); -#if JVET_M0255_FRACMMVD_SWITCH - WRITE_FLAG( spsNext.getAllowDisFracMMVD() ? 1 : 0, "sps_fracmmvd_disabled_flag" ); -#endif WRITE_FLAG( spsNext.getUseTriangle() ? 1: 0, "triangle_flag" ); #if ENABLE_WPP_PARALLELISM WRITE_FLAG( spsNext.getUseNextDQP(), "next_dqp_enabled_flag" ); @@ -724,6 +721,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) } WRITE_FLAG( pcSPS->getBDOFEnabledFlag() ? 1 : 0, "sps_bdof_enabled_flag" ); +#if JVET_M0255_FRACMMVD_SWITCH + WRITE_FLAG( pcSPS->getDisFracMmvdEnabledFlag() ? 1 : 0, "sps_fracmmvd_disabled_flag" ); +#endif #if HEVC_USE_SCALING_LISTS WRITE_FLAG( pcSPS->getScalingListFlag() ? 1 : 0, "scaling_list_enabled_flag" ); @@ -1289,7 +1289,7 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) WRITE_UVLC( AFFINE_MRG_MAX_NUM_CANDS - pcSlice->getMaxNumAffineMergeCand(), "five_minus_max_num_affine_merge_cand" ); } #if JVET_M0255_FRACMMVD_SWITCH - if ( pcSlice->getSPS()->getSpsNext().getAllowDisFracMMVD() ) + if ( pcSlice->getSPS()->getDisFracMmvdEnabledFlag() ) { WRITE_FLAG( pcSlice->getDisFracMMVD(), "tile_group_fracmmvd_disabled_flag" ); }