diff --git a/cfg/encoder_intra_vtm.cfg b/cfg/encoder_intra_vtm.cfg index 814bf20d9368cd7c9a6675e9840f2ec1ae4c2e13..59ccd79d22efd033933d0a3887c8d8aec4fc088f 100644 --- a/cfg/encoder_intra_vtm.cfg +++ b/cfg/encoder_intra_vtm.cfg @@ -112,6 +112,7 @@ DepQuant : 1 IMV : 2 ALF : 1 IBC : 0 # turned off in CTC +AllowDisFracMMVD : 1 # Fast tools PBIntraFast : 1 diff --git a/cfg/encoder_lowdelay_P_vtm.cfg b/cfg/encoder_lowdelay_P_vtm.cfg index 132d9db5c55967284a1d2ee5497da6c44ee39ed5..7b36027e2da7f6636732156674d3e943531772a8 100644 --- a/cfg/encoder_lowdelay_P_vtm.cfg +++ b/cfg/encoder_lowdelay_P_vtm.cfg @@ -129,6 +129,7 @@ IMV : 2 ALF : 1 MHIntra : 1 IBC : 0 # turned off in CTC +AllowDisFracMMVD : 1 # Fast tools PBIntraFast : 1 diff --git a/cfg/encoder_lowdelay_vtm.cfg b/cfg/encoder_lowdelay_vtm.cfg index 7d8350f9257c2d87be841e0083792ada75bc11b3..53ba9df9aa8936b3b66b71ffc92870bc4705938b 100644 --- a/cfg/encoder_lowdelay_vtm.cfg +++ b/cfg/encoder_lowdelay_vtm.cfg @@ -132,6 +132,7 @@ GBiFast : 1 MHIntra : 1 Triangle : 1 IBC : 0 # turned off in CTC +AllowDisFracMMVD : 1 # Fast tools PBIntraFast : 1 diff --git a/cfg/encoder_randomaccess_vtm.cfg b/cfg/encoder_randomaccess_vtm.cfg index f3404e3f2b958461236f98e56e0387d315808658..ba6baf1c44fd5ac1d5563d58fa5124960bd51740 100644 --- a/cfg/encoder_randomaccess_vtm.cfg +++ b/cfg/encoder_randomaccess_vtm.cfg @@ -147,6 +147,7 @@ BIO : 1 MHIntra : 1 Triangle : 1 IBC : 0 # turned off in CTC +AllowDisFracMMVD : 1 # Fast tools PBIntraFast : 1 diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 6afd8db7333f1376da1346246b9cd70f6ae5befa..eee3ac2643a8777165bdd46364510553426a9530 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -257,7 +257,9 @@ void EncApp::xInitLibCfg() #endif m_cEncLib.setUseMHIntra ( m_MHIntra ); m_cEncLib.setUseTriangle ( m_Triangle ); - +#if JVET_M0255_FRACMMVD_SWITCH + m_cEncLib.setAllowDisFracMMVD ( m_allowDisFracMMVD ); +#endif m_cEncLib.setIBCMode ( m_IBCMode ); m_cEncLib.setIBCLocalSearchRangeX ( m_IBCLocalSearchRangeX ); m_cEncLib.setIBCLocalSearchRangeY ( m_IBCLocalSearchRangeY ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index d2a324e4a992197fc3753558dc5ba5c66be4a765..a1709b0d3f6099610091ce32df39da172126e7a3 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -864,7 +864,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) #endif ("MHIntra", m_MHIntra, false, "Enable MHIntra mode") ("Triangle", m_Triangle, false, "Enable triangular shape motion vector prediction (0:off, 1:on)") - +#if JVET_M0255_FRACMMVD_SWITCH + ("AllowDisFracMMVD", m_allowDisFracMMVD, false, "Disable fractional MVD in MMVD mode adaptively") +#endif ( "IBC", m_IBCMode, 0u, "IBCMode (0x1:enabled, 0x0:disabled) [default: disabled]") ( "IBCLocalSearchRangeX", m_IBCLocalSearchRangeX, 128u, "Search range of IBC local search in x direction") ( "IBCLocalSearchRangeY", m_IBCLocalSearchRangeY, 128u, "Search range of IBC local search in y direction") @@ -3145,6 +3147,9 @@ void EncAppCfg::xPrintParameter() #endif msg(VERBOSE, "MHIntra:%d ", m_MHIntra); msg( VERBOSE, "Triangle:%d ", m_Triangle ); +#if JVET_M0255_FRACMMVD_SWITCH + msg( VERBOSE, "AllowDisFracMMVD:%d ", m_allowDisFracMMVD ); +#endif } msg(VERBOSE, "IBC:%d ", m_IBCMode); msg( VERBOSE, "WrapAround:%d ", m_wrapAround); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 8b67d948decc874a2639cc402a27ee0d900cf67b..b1910b56b7d52708154d3272acf7a6739145fa81 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -237,7 +237,9 @@ protected: bool m_MHIntra; bool m_Triangle; - +#if JVET_M0255_FRACMMVD_SWITCH + bool m_allowDisFracMMVD; +#endif unsigned m_IBCMode; unsigned m_IBCLocalSearchRangeX; diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp index d52ea51e00383a3719d16ecc733dd3f968afda60..a1939413874f994b01d0181ec7eb447e7034e9df 100644 --- a/source/Lib/CommonLib/ContextModelling.cpp +++ b/source/Lib/CommonLib/ContextModelling.cpp @@ -501,8 +501,15 @@ void MergeCtx::setMmvdMergeCandiInfo(PredictionUnit& pu, int candIdx) tempIdx = tempIdx - fPosBaseIdx * (MMVD_MAX_REFINE_NUM); fPosStep = tempIdx / 4; fPosPosition = tempIdx - fPosStep * (4); - +#if JVET_M0255_FRACMMVD_SWITCH + int offset = refMvdCands[fPosStep]; + if ( pu.cu->slice->getDisFracMMVD() ) + { + offset <<= 2; + } +#else const int offset = refMvdCands[fPosStep]; +#endif const int refList0 = mmvdBaseMv[fPosBaseIdx][0].refIdx; const int refList1 = mmvdBaseMv[fPosBaseIdx][1].refIdx; diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 00f16676bcbef8eece7b89a92ad3b667df5a08cc..acca43bad98fc7fe56159d14609ec24b7e61b234 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -92,6 +92,9 @@ Slice::Slice() , m_colRefIdx ( 0 ) , m_maxNumMergeCand ( 0 ) , m_maxNumAffineMergeCand ( 0 ) +#if JVET_M0255_FRACMMVD_SWITCH +, m_disFracMMVD ( false ) +#endif , m_uiTLayer ( 0 ) , m_bTLayerSwitchingFlag ( false ) , m_sliceMode ( NO_SLICES ) @@ -214,6 +217,9 @@ void Slice::initSlice() m_bFinalized=false; +#if JVET_M0255_FRACMMVD_SWITCH + m_disFracMMVD = false; +#endif m_substreamSizes.clear(); m_cabacInitFlag = false; m_cabacWinUpdateMode = 0; @@ -864,6 +870,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll) m_enableTMVPFlag = pSrc->m_enableTMVPFlag; m_maxNumMergeCand = pSrc->m_maxNumMergeCand; m_maxNumAffineMergeCand = pSrc->m_maxNumAffineMergeCand; +#if JVET_M0255_FRACMMVD_SWITCH + m_disFracMMVD = pSrc->m_disFracMMVD; +#endif if( cpyAlmostAll ) m_encCABACTableIdx = pSrc->m_encCABACTableIdx; m_splitConsOverrideFlag = pSrc->m_splitConsOverrideFlag; m_uiMinQTSize = pSrc->m_uiMinQTSize; @@ -1789,6 +1798,9 @@ 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 diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 05b8ea8f046b66ed3bc1e72b0d4288b506ea31dd..3298cd8406fc3666eb195c941dab7c1ff0c87b0a 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -820,6 +820,9 @@ 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 @@ -916,6 +919,10 @@ 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 }; @@ -1602,7 +1609,9 @@ private: uint32_t m_colRefIdx; uint32_t m_maxNumMergeCand; uint32_t m_maxNumAffineMergeCand; - +#if JVET_M0255_FRACMMVD_SWITCH + bool m_disFracMMVD; +#endif double m_lambdas[MAX_NUM_COMPONENT]; bool m_abEqualRef [NUM_REF_PIC_LIST_01][MAX_NUM_REF][MAX_NUM_REF]; @@ -1846,7 +1855,10 @@ public: uint32_t getMaxNumMergeCand() const { return m_maxNumMergeCand; } void setMaxNumAffineMergeCand( uint32_t val ) { m_maxNumAffineMergeCand = val; } uint32_t getMaxNumAffineMergeCand() const { return m_maxNumAffineMergeCand; } - +#if JVET_M0255_FRACMMVD_SWITCH + void setDisFracMMVD( bool val ) { m_disFracMMVD = val; } + bool getDisFracMMVD() const { return m_disFracMMVD; } +#endif void setNoOutputPriorPicsFlag( bool val ) { m_noOutputPriorPicsFlag = val; } bool getNoOutputPriorPicsFlag() const { return m_noOutputPriorPicsFlag; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 0021c2ca8314b590d278e9ea747480eefad739ca..31f6ff87a8696f11d57188974d65c5fce89a2969 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -86,6 +86,7 @@ #define JVET_M0464_UNI_MTS 1 #define JVET_M0068_M0171_MMVD_CLEANUP 1 // MMVD cleanup with 1) flip removal, 2) L1 zero vector fix, 3) bi-pred restriction after merge/MMVD +#define JVET_M0255_FRACMMVD_SWITCH 1 // disable fractional MVD in MMVD adaptively #if JVET_M0464_UNI_MTS typedef std::pair<int, bool> TrMode; diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 8e1725797c1a84d4eb0812d62a0b0356e20d60f7..4e2909e0dfaade90f4a584dfdd673bbd7dbc8154 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -818,6 +818,9 @@ 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 ); @@ -1767,6 +1770,13 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para READ_UVLC( uiCode, "five_minus_max_num_affine_merge_cand" ); pcSlice->setMaxNumAffineMergeCand( AFFINE_MRG_MAX_NUM_CANDS - uiCode ); } +#if JVET_M0255_FRACMMVD_SWITCH + if ( sps->getSpsNext().getAllowDisFracMMVD() ) + { + READ_FLAG( uiCode, "tile_group_fracmmvd_disabled_flag" ); + pcSlice->setDisFracMMVD( uiCode ? true : false ); + } +#endif } READ_SVLC( iCode, "slice_qp_delta" ); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 0fdf461193b496844a0114d1dc5da9f382ac02bf..24561541aaaba574191f431cc60803309ef2c966 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -238,7 +238,9 @@ protected: bool m_MHIntra; bool m_Triangle; - +#if JVET_M0255_FRACMMVD_SWITCH + bool m_allowDisFracMMVD; +#endif unsigned m_IBCMode; unsigned m_IBCLocalSearchRangeX; unsigned m_IBCLocalSearchRangeY; @@ -754,7 +756,10 @@ public: bool getUseMHIntra () const { return m_MHIntra; } void setUseTriangle ( bool b ) { m_Triangle = b; } bool getUseTriangle () const { return m_Triangle; } - +#if JVET_M0255_FRACMMVD_SWITCH + void setAllowDisFracMMVD ( bool b ) { m_allowDisFracMMVD = b; } + bool getAllowDisFracMMVD () const { return m_allowDisFracMMVD; } +#endif void setIBCMode (unsigned n) { m_IBCMode = n; } unsigned getIBCMode () const { return m_IBCMode; } diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 363af63c23f6e41c96e67d2ac6bf30c5e2dc5621..3667f70d95cd8b695aedfdb2dfe64eaf43fb417a 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -292,7 +292,11 @@ void EncCu::init( EncLib* pcEncLib, const SPS& sps PARL_PARAM( const int tId ) ) ::memset(m_subMergeBlkNum, 0, sizeof(m_subMergeBlkNum)); m_prevPOC = MAX_UINT; +#if JVET_M0255_FRACMMVD_SWITCH + if ( ( m_pcEncCfg->getIBCHashSearch() && m_pcEncCfg->getIBCMode() ) || m_pcEncCfg->getAllowDisFracMMVD() ) +#else if (m_pcEncCfg->getIBCHashSearch() && m_pcEncCfg->getIBCMode()) +#endif { m_ibcHashMap.init(m_pcEncCfg->getSourceWidth(), m_pcEncCfg->getSourceHeight()); } @@ -304,10 +308,12 @@ void EncCu::init( EncLib* pcEncLib, const SPS& sps PARL_PARAM( const int tId ) ) void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsigned ctuRsAddr, const int prevQP[], const int currQP[] ) { +#if !JVET_M0255_FRACMMVD_SWITCH if (m_pcEncCfg->getIBCHashSearch() && ctuRsAddr == 0 && cs.slice->getSPS()->getSpsNext().getIBCMode()) { m_ibcHashMap.rebuildPicHashMap(cs.picture->getOrigBuf()); } +#endif m_modeCtrl->initCTUEncoding( *cs.slice ); #if ENABLE_SPLIT_PARALLELISM diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h index 7bc45282b4654d9c7307262f8dfd3cd515addcc8..0d4d0d2b56711742ed500b76d8237f98251ec20d 100644 --- a/source/Lib/EncoderLib/EncCu.h +++ b/source/Lib/EncoderLib/EncCu.h @@ -159,6 +159,10 @@ public: void setMergeBestSATDCost(double cost) { m_mergeBestSATDCost = cost; } double getMergeBestSATDCost() { return m_mergeBestSATDCost; } +#if JVET_M0255_FRACMMVD_SWITCH + IbcHashMap& getCprHashMap() { return m_ibcHashMap; } + EncCfg* getEncCfg() const { return m_pcEncCfg; } +#endif #if JVET_M0170_MRG_SHARELIST Position shareParentPos; diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 56f49fc8620590b9f275d78e319747df63f7f826..bbf61d5839316b212182d9662dc98a9ab8dc3b78 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -891,7 +891,9 @@ 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 ); +#endif sps.getSpsNext().setIBCMode ( m_IBCMode ); sps.setWrapAroundEnabledFlag ( m_wrapAround ); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 73b9cc08af94ddc2c3d3f85d2b5f2769b108401e..44bca844fc0e1d485274e811ad2c37a8cbee5007 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1387,8 +1387,48 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c } +#if JVET_M0255_FRACMMVD_SWITCH +void EncSlice::checkDisFracMmvd( Picture* pcPic, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr ) +{ + CodingStructure& cs = *pcPic->cs; + Slice* pcSlice = cs.slice; + const PreCalcValues& pcv = *cs.pcv; + const uint32_t widthInCtus = pcv.widthInCtus; +#if HEVC_TILES_WPP + const TileMap& tileMap = *pcPic->tileMap; +#endif + const uint32_t hashThreshold = 20; + uint32_t totalCtu = 0; + uint32_t hashRatio = 0; + + if ( !pcSlice->getSPS()->getSpsNext().getAllowDisFracMMVD() ) + { + return; + } + + for ( uint32_t ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuTsAddr++ ) + { +#if HEVC_TILES_WPP + const uint32_t ctuRsAddr = tileMap.getCtuTsToRsAddrMap( ctuTsAddr ); +#else + const uint32_t ctuRsAddr = ctuTsAddr; +#endif + const uint32_t ctuXPosInCtus = ctuRsAddr % widthInCtus; + const uint32_t ctuYPosInCtus = ctuRsAddr / widthInCtus; + 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() ); + totalCtu++; + } + + if ( hashRatio > totalCtu * hashThreshold ) + { + pcSlice->setDisFracMMVD( true ); + } +} +#endif void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr, EncLib* pEncLib ) { @@ -1439,7 +1479,14 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons #if HEVC_DEPENDENT_SLICES } #endif - +#if JVET_M0255_FRACMMVD_SWITCH + if ( pcSlice->getSPS()->getSpsNext().getAllowDisFracMMVD() || + ( pcSlice->getSPS()->getSpsNext().getIBCMode() && m_pcCuEncoder->getEncCfg()->getIBCHashSearch() ) ) + { + m_pcCuEncoder->getCprHashMap().rebuildPicHashMap( cs.picture->getOrigBuf() ); + } + checkDisFracMmvd( pcPic, startCtuTsAddr, boundingCtuTsAddr ); +#endif // for every CTU in the slice segment (may terminate sooner if there is a byte limit on the slice-segment) for( uint32_t ctuTsAddr = startCtuTsAddr; ctuTsAddr < boundingCtuTsAddr; ctuTsAddr++ ) { diff --git a/source/Lib/EncoderLib/EncSlice.h b/source/Lib/EncoderLib/EncSlice.h index 39dca4341792cc7f13838691c458417380d64734..7314ca287c92b95f69de9f5cba362641ea72994b 100644 --- a/source/Lib/EncoderLib/EncSlice.h +++ b/source/Lib/EncoderLib/EncSlice.h @@ -146,7 +146,9 @@ public: static #endif void encodeCtus ( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr, EncLib* pcEncLib ); - +#if JVET_M0255_FRACMMVD_SWITCH + void checkDisFracMmvd ( Picture* pcPic, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr ); +#endif // misc. functions void setSearchRange ( Slice* pcSlice ); ///< set ME range adaptively diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 34a8b308db02f6ede5d36002a8614f3214b78a6f..a3e7362f00a51eb87d8310e669dc0ffcf8ee18d2 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -559,6 +559,9 @@ 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" ); @@ -1285,6 +1288,12 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) CHECK( pcSlice->getMaxNumAffineMergeCand() > AFFINE_MRG_MAX_NUM_CANDS, "More affine merge candidates signalled than supported" ); 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() ) + { + WRITE_FLAG( pcSlice->getDisFracMMVD(), "tile_group_fracmmvd_disabled_flag" ); + } +#endif } int iCode = pcSlice->getSliceQp() - ( pcSlice->getPPS()->getPicInitQPMinus26() + 26 ); WRITE_SVLC( iCode, "slice_qp_delta" );