Commit fd177314 authored by Hongbin Liu's avatar Hongbin Liu

JVET-M0255: MMVD without Fractional Distances for SCC.

parent 02116053
......@@ -112,6 +112,7 @@ DepQuant : 1
IMV : 2
ALF : 1
CPR : 0 # turned off in CTC
AllowDisFracMMVD : 1
# Fast tools
PBIntraFast : 1
......
......@@ -129,6 +129,7 @@ IMV : 2
ALF : 1
MHIntra : 1
CPR : 0 # turned off in CTC
AllowDisFracMMVD : 1
# Fast tools
PBIntraFast : 1
......
......@@ -132,6 +132,7 @@ GBiFast : 1
MHIntra : 1
Triangle : 1
CPR : 0 # turned off in CTC
AllowDisFracMMVD : 1
# Fast tools
PBIntraFast : 1
......
......@@ -147,6 +147,7 @@ BIO : 1
MHIntra : 1
Triangle : 1
CPR : 0 # turned off in CTC
AllowDisFracMMVD : 1
# Fast tools
PBIntraFast : 1
......
......@@ -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.setCPRMode ( m_CPRMode );
m_cEncLib.setCPRLocalSearchRangeX ( m_CPRLocalSearchRangeX );
m_cEncLib.setCPRLocalSearchRangeY ( m_CPRLocalSearchRangeY );
......
......@@ -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
( "CPR", m_CPRMode, 0u, "CPRMode (0x1:enabled, 0x0:disabled) [default: disabled]")
( "CPRLocalSearchRangeX", m_CPRLocalSearchRangeX, 128u, "Search range of CPR local search in x direction")
( "CPRLocalSearchRangeY", m_CPRLocalSearchRangeY, 128u, "Search range of CPR 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, "CPR:%d ", m_CPRMode);
msg( VERBOSE, "WrapAround:%d ", m_wrapAround);
......
......@@ -237,7 +237,9 @@ protected:
bool m_MHIntra;
bool m_Triangle;
#if JVET_M0255_FRACMMVD_SWITCH
bool m_allowDisFracMMVD;
#endif
unsigned m_CPRMode;
unsigned m_CPRLocalSearchRangeX;
......
......@@ -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;
......
......@@ -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 )
......@@ -211,6 +214,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;
......@@ -861,6 +867,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;
......@@ -1767,6 +1776,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
......
......@@ -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 setCPRMode (unsigned CPRMode) { m_CPRMode = CPRMode; }
unsigned getCPRMode () const { return m_CPRMode; }
#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];
......@@ -1843,7 +1852,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; }
......
......@@ -64,6 +64,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;
......
......@@ -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" );
......
......@@ -238,7 +238,9 @@ protected:
bool m_MHIntra;
bool m_Triangle;
#if JVET_M0255_FRACMMVD_SWITCH
bool m_allowDisFracMMVD;
#endif
unsigned m_CPRMode;
unsigned m_CPRLocalSearchRangeX;
unsigned m_CPRLocalSearchRangeY;
......@@ -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 setCPRMode (unsigned n) { m_CPRMode = n; }
unsigned getCPRMode () const { return m_CPRMode; }
......
......@@ -280,7 +280,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->getCPRHashSearch() && m_pcEncCfg->getCPRMode() ) || m_pcEncCfg->getAllowDisFracMMVD() )
#else
if (m_pcEncCfg->getCPRHashSearch() && m_pcEncCfg->getCPRMode())
#endif
{
m_cprHashMap.init(m_pcEncCfg->getSourceWidth(), m_pcEncCfg->getSourceHeight());
}
......@@ -292,10 +296,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->getCPRHashSearch() && ctuRsAddr == 0 && cs.slice->getSPS()->getSpsNext().getCPRMode())
{
m_cprHashMap.rebuildPicHashMap(cs.picture->getOrigBuf());
}
#endif
m_modeCtrl->initCTUEncoding( *cs.slice );
#if ENABLE_SPLIT_PARALLELISM
......
......@@ -151,6 +151,10 @@ public:
void setMergeBestSATDCost(double cost) { m_mergeBestSATDCost = cost; }
double getMergeBestSATDCost() { return m_mergeBestSATDCost; }
#if JVET_M0255_FRACMMVD_SWITCH
CprHashMap& getCprHashMap() { return m_cprHashMap; }
EncCfg* getEncCfg() const { return m_pcEncCfg; }
#endif
~EncCu();
......
......@@ -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().setCPRMode ( m_CPRMode );
sps.setWrapAroundEnabledFlag ( m_wrapAround );
......
......@@ -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().getCPRMode() && m_pcCuEncoder->getEncCfg()->getCPRHashSearch() ) )
{
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++ )
{
......
......@@ -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
......
......@@ -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" );
......
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