Commit a375e85c authored by Shelly Chiang's avatar Shelly Chiang

merge MHIntra into VTM

parent 8fa61a05
...@@ -127,6 +127,7 @@ LMChroma : 1 # use CCLM only ...@@ -127,6 +127,7 @@ LMChroma : 1 # use CCLM only
DepQuant : 1 DepQuant : 1
IMV : 2 IMV : 2
ALF : 1 ALF : 1
MHIntra : 1
# Fast tools # Fast tools
PBIntraFast : 1 PBIntraFast : 1
......
...@@ -129,6 +129,7 @@ IMV : 2 ...@@ -129,6 +129,7 @@ IMV : 2
ALF : 1 ALF : 1
GBi : 1 GBi : 1
GBiFast : 1 GBiFast : 1
MHIntra : 1
# Fast tools # Fast tools
PBIntraFast : 1 PBIntraFast : 1
......
...@@ -143,6 +143,7 @@ IMV : 2 ...@@ -143,6 +143,7 @@ IMV : 2
ALF : 1 ALF : 1
GBi : 1 GBi : 1
GBiFast : 1 GBiFast : 1
MHIntra : 1
# Fast tools # Fast tools
PBIntraFast : 1 PBIntraFast : 1
......
...@@ -242,6 +242,9 @@ void EncApp::xInitLibCfg() ...@@ -242,6 +242,9 @@ void EncApp::xInitLibCfg()
#if JVET_L0646_GBI #if JVET_L0646_GBI
m_cEncLib.setUseGBi ( m_GBi ); m_cEncLib.setUseGBi ( m_GBi );
m_cEncLib.setUseGBiFast ( m_GBiFast ); m_cEncLib.setUseGBiFast ( m_GBiFast );
#endif
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
m_cEncLib.setUseMHIntra ( m_MHIntra );
#endif #endif
// ADD_NEW_TOOL : (encoder app) add setting of tool enabling flags and associated parameters here // ADD_NEW_TOOL : (encoder app) add setting of tool enabling flags and associated parameters here
......
...@@ -847,6 +847,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ...@@ -847,6 +847,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
#if JVET_L0646_GBI #if JVET_L0646_GBI
("GBi", m_GBi, false, "Enable Generalized Bi-prediction(GBi)") ("GBi", m_GBi, false, "Enable Generalized Bi-prediction(GBi)")
("GBiFast", m_GBiFast, false, "Fast methods for Generalized Bi-prediction(GBi)\n") ("GBiFast", m_GBiFast, false, "Fast methods for Generalized Bi-prediction(GBi)\n")
#endif
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
("MHIntra", m_MHIntra, false, "Enable MHIntra mode")
#endif #endif
// ADD_NEW_TOOL : (encoder app) add parsing parameters here // ADD_NEW_TOOL : (encoder app) add parsing parameters here
...@@ -3122,6 +3125,9 @@ void EncAppCfg::xPrintParameter() ...@@ -3122,6 +3125,9 @@ void EncAppCfg::xPrintParameter()
#if JVET_L0646_GBI #if JVET_L0646_GBI
msg( VERBOSE, "GBi:%d ", m_GBi ); msg( VERBOSE, "GBi:%d ", m_GBi );
msg( VERBOSE, "GBiFast:%d ", m_GBiFast ); msg( VERBOSE, "GBiFast:%d ", m_GBiFast );
#endif
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
msg(VERBOSE, "MHIntra:%d ", m_MHIntra);
#endif #endif
} }
// ADD_NEW_TOOL (add some output indicating the usage of tools) // ADD_NEW_TOOL (add some output indicating the usage of tools)
......
...@@ -225,6 +225,10 @@ protected: ...@@ -225,6 +225,10 @@ protected:
bool m_GBi; bool m_GBi;
bool m_GBiFast; bool m_GBiFast;
#endif #endif
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
bool m_MHIntra;
#endif
// ADD_NEW_TOOL : (encoder app) add tool enabling flags and associated parameters here // ADD_NEW_TOOL : (encoder app) add tool enabling flags and associated parameters here
unsigned m_uiMaxCUWidth; ///< max. CU width in pixel unsigned m_uiMaxCUWidth; ///< max. CU width in pixel
......
...@@ -106,6 +106,9 @@ enum CodingStatisticsType ...@@ -106,6 +106,9 @@ enum CodingStatisticsType
STATS__CABAC_BITS__EMT_CU_FLAG, STATS__CABAC_BITS__EMT_CU_FLAG,
STATS__CABAC_BITS__EMT_TU_INDEX, STATS__CABAC_BITS__EMT_TU_INDEX,
STATS__TOOL_EMT, STATS__TOOL_EMT,
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
STATS__CABAC_BITS__MH_INTRA_FLAG,
#endif
STATS__TOOL_TOTAL, STATS__TOOL_TOTAL,
STATS__NUM_STATS STATS__NUM_STATS
}; };
...@@ -178,6 +181,9 @@ static inline const char* getName(CodingStatisticsType name) ...@@ -178,6 +181,9 @@ static inline const char* getName(CodingStatisticsType name)
#endif #endif
"CABAC_BITS__EMT_CU_FLAG", "CABAC_BITS__EMT_CU_FLAG",
"CABAC_BITS__EMT_TU_INDX", "CABAC_BITS__EMT_TU_INDX",
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
"CABAC_BITS__MH_INTRA_FLAG",
#endif
"CABAC_BITS__OTHER", "CABAC_BITS__OTHER",
"CABAC_BITS__INVALID", "CABAC_BITS__INVALID",
"TOOL_FRAME", "TOOL_FRAME",
......
...@@ -777,6 +777,21 @@ const CtxSet ContextSetCfg::ctbAlfFlag = ...@@ -777,6 +777,21 @@ const CtxSet ContextSetCfg::ctbAlfFlag =
} ) } )
}; };
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
const CtxSet ContextSetCfg::MHIntraFlag = ContextSetCfg::addCtxSet
({
{ 154, },
{ 110, },
{ CNU, },
});
const CtxSet ContextSetCfg::MHIntraPredMode = ContextSetCfg::addCtxSet
({
{ 183, CNU, CNU, CNU, },
{ 154, CNU, CNU, CNU, },
{ 184, CNU, CNU, CNU, },
});
#endif
const unsigned ContextSetCfg::NumberOfContexts = (unsigned)ContextSetCfg::sm_InitTables[0].size(); const unsigned ContextSetCfg::NumberOfContexts = (unsigned)ContextSetCfg::sm_InitTables[0].size();
......
...@@ -195,6 +195,10 @@ public: ...@@ -195,6 +195,10 @@ public:
static const CtxSet GBiIdx; static const CtxSet GBiIdx;
#endif #endif
static const CtxSet ctbAlfFlag; static const CtxSet ctbAlfFlag;
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
static const CtxSet MHIntraFlag;
static const CtxSet MHIntraPredMode;
#endif
static const unsigned NumberOfContexts; static const unsigned NumberOfContexts;
// combined sets for less complex copying // combined sets for less complex copying
......
...@@ -141,6 +141,15 @@ IntraPrediction::IntraPrediction() ...@@ -141,6 +141,15 @@ IntraPrediction::IntraPrediction()
m_piYuvExt[ch][buf] = nullptr; m_piYuvExt[ch][buf] = nullptr;
} }
} }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)
{
for (uint32_t buf = 0; buf < 4; buf++)
{
m_yuvExt2[ch][buf] = nullptr;
}
}
#endif
m_piTemp = nullptr; m_piTemp = nullptr;
} }
...@@ -160,6 +169,16 @@ void IntraPrediction::destroy() ...@@ -160,6 +169,16 @@ void IntraPrediction::destroy()
m_piYuvExt[ch][buf] = nullptr; m_piYuvExt[ch][buf] = nullptr;
} }
} }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)
{
for (uint32_t buf = 0; buf < 4; buf++)
{
delete[] m_yuvExt2[ch][buf];
m_yuvExt2[ch][buf] = nullptr;
}
}
#endif
delete[] m_piTemp; delete[] m_piTemp;
m_piTemp = nullptr; m_piTemp = nullptr;
...@@ -173,6 +192,13 @@ void IntraPrediction::init(ChromaFormat chromaFormatIDC, const unsigned bitDepth ...@@ -173,6 +192,13 @@ void IntraPrediction::init(ChromaFormat chromaFormatIDC, const unsigned bitDepth
destroy(); destroy();
} }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
if (m_yuvExt2[COMPONENT_Y][0] != nullptr && m_currChromaFormat != chromaFormatIDC)
{
destroy();
}
#endif
m_currChromaFormat = chromaFormatIDC; m_currChromaFormat = chromaFormatIDC;
if (m_piYuvExt[COMPONENT_Y][PRED_BUF_UNFILTERED] == nullptr) // check if first is null (in which case, nothing initialised yet) if (m_piYuvExt[COMPONENT_Y][PRED_BUF_UNFILTERED] == nullptr) // check if first is null (in which case, nothing initialised yet)
...@@ -188,6 +214,21 @@ void IntraPrediction::init(ChromaFormat chromaFormatIDC, const unsigned bitDepth ...@@ -188,6 +214,21 @@ void IntraPrediction::init(ChromaFormat chromaFormatIDC, const unsigned bitDepth
} }
} }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
if (m_yuvExt2[COMPONENT_Y][0] == nullptr) // check if first is null (in which case, nothing initialised yet)
{
m_yuvExtSize2 = (MAX_CU_SIZE) * (MAX_CU_SIZE);
for (uint32_t ch = 0; ch < MAX_NUM_COMPONENT; ch++)
{
for (uint32_t buf = 0; buf < 4; buf++)
{
m_yuvExt2[ch][buf] = new Pel[m_yuvExtSize2];
}
}
}
#endif
int shift = bitDepthY + 4; int shift = bitDepthY + 4;
for (int i = 32; i < 64; i++) for (int i = 32; i < 64; i++)
{ {
...@@ -796,6 +837,133 @@ bool IntraPrediction::useDPCMForFirstPassIntraEstimation(const PredictionUnit &p ...@@ -796,6 +837,133 @@ bool IntraPrediction::useDPCMForFirstPassIntraEstimation(const PredictionUnit &p
return CU::isRDPCMEnabled(*pu.cu) && pu.cu->transQuantBypass && (uiDirMode == HOR_IDX || uiDirMode == VER_IDX); return CU::isRDPCMEnabled(*pu.cu) && pu.cu->transQuantBypass && (uiDirMode == HOR_IDX || uiDirMode == VER_IDX);
} }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
void IntraPrediction::geneWeightedPred(const ComponentID compId, PelBuf &pred, const PredictionUnit &pu, Pel *srcBuf)
{
const int width = pred.width;
const int height = pred.height;
const int srcStride = width;
const int dstStride = pred.stride;
const uint32_t dirMode = PU::getFinalIntraMode(pu, toChannelType(compId));
const ClpRng& clpRng(pu.cu->cs->slice->clpRng(compId));
Pel* dstBuf = pred.buf;
int k, l;
bool modeDC = (dirMode <= DC_IDX);
Pel wIntra1 = 6, wInter1 = 2, wIntra2 = 5, wInter2 = 3, wIntra3 = 3, wInter3 = 5, wIntra4 = 2, wInter4 = 6;
if (modeDC || width < 4 || height < 4)
{
for (k = 0; k<height; k++)
{
for (l = 0; l<width; l++)
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * 4) + (srcBuf[k*srcStride + l] * 4)) >> 3), clpRng);
}
}
}
else
{
if (dirMode <= DIA_IDX)
{
int interval = (width >> 2);
for (k = 0; k<height; k++)
{
for (l = 0; l<width; l++)
{
if (l<interval)
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * wInter1) + (srcBuf[k*srcStride + l] * wIntra1)) >> 3), clpRng);
}
else if (l >= interval && l < (2 * interval))
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * wInter2) + (srcBuf[k*srcStride + l] * wIntra2)) >> 3), clpRng);
}
else if (l >= (interval * 2) && l < (3 * interval))
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * wInter3) + (srcBuf[k*srcStride + l] * wIntra3)) >> 3), clpRng);
}
else
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * wInter4) + (srcBuf[k*srcStride + l] * wIntra4)) >> 3), clpRng);
}
}
}
}
else
{
int interval = (height >> 2);
for (k = 0; k<height; k++)
{
for (l = 0; l<width; l++)
{
if (k<interval)
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * wInter1) + (srcBuf[k*srcStride + l] * wIntra1)) >> 3), clpRng);
}
else if (k >= interval && k < (2 * interval))
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * wInter2) + (srcBuf[k*srcStride + l] * wIntra2)) >> 3), clpRng);
}
else if (k >= (interval * 2) && k < (3 * interval))
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * wInter3) + (srcBuf[k*srcStride + l] * wIntra3)) >> 3), clpRng);
}
else
{
dstBuf[k*dstStride + l] = ClipPel((((dstBuf[k*dstStride + l] * wInter4) + (srcBuf[k*srcStride + l] * wIntra4)) >> 3), clpRng);
}
}
}
}
}
}
void IntraPrediction::switchBuffer(const PredictionUnit &pu, ComponentID compID, PelBuf srcBuff, Pel *dst)
{
Pel *src = srcBuff.bufAt(0, 0);
int compWidth = compID == COMPONENT_Y ? pu.Y().width : pu.Cb().width;
int compHeight = compID == COMPONENT_Y ? pu.Y().height : pu.Cb().height;
for (int i = 0; i < compHeight; i++)
{
for (int j = 0; j < compWidth; j++)
{
dst[j] = src[j];
}
src += srcBuff.stride;
dst += compWidth;
}
}
void IntraPrediction::geneIntrainterPred(const CodingUnit &cu)
{
if (!cu.firstPU->MHIntraFlag)
{
return;
}
const PredictionUnit* pu = cu.firstPU;
bool isUseFilter = IntraPrediction::useFilteredIntraRefSamples(COMPONENT_Y, *pu, true, *pu);
initIntraPatternChType(cu, pu->Y(), isUseFilter);
predIntraAng(COMPONENT_Y, cu.cs->getPredBuf(*pu).Y(), *pu, isUseFilter);
isUseFilter = IntraPrediction::useFilteredIntraRefSamples(COMPONENT_Cb, *pu, true, *pu);
initIntraPatternChType(cu, pu->Cb(), isUseFilter);
predIntraAng(COMPONENT_Cb, cu.cs->getPredBuf(*pu).Cb(), *pu, isUseFilter);
isUseFilter = IntraPrediction::useFilteredIntraRefSamples(COMPONENT_Cr, *pu, true, *pu);
initIntraPatternChType(cu, pu->Cr(), isUseFilter);
predIntraAng(COMPONENT_Cr, cu.cs->getPredBuf(*pu).Cr(), *pu, isUseFilter);
for (int currCompID = 0; currCompID < 3; currCompID++)
{
ComponentID currCompID2 = (ComponentID)currCompID;
PelBuf tmpBuf = currCompID == 0 ? cu.cs->getPredBuf(*pu).Y() : (currCompID == 1 ? cu.cs->getPredBuf(*pu).Cb() : cu.cs->getPredBuf(*pu).Cr());
switchBuffer(*pu, currCompID2, tmpBuf, getPredictorPtr2(currCompID2, 0));
}
}
#endif
inline bool isAboveLeftAvailable ( const CodingUnit &cu, const ChannelType &chType, const Position &posLT ); inline bool isAboveLeftAvailable ( const CodingUnit &cu, const ChannelType &chType, const Position &posLT );
inline int isAboveAvailable ( const CodingUnit &cu, const ChannelType &chType, const Position &posLT, const uint32_t uiNumUnitsInPU, const uint32_t unitWidth, bool *validFlags ); inline int isAboveAvailable ( const CodingUnit &cu, const ChannelType &chType, const Position &posLT, const uint32_t uiNumUnitsInPU, const uint32_t unitWidth, bool *validFlags );
inline int isLeftAvailable ( const CodingUnit &cu, const ChannelType &chType, const Position &posLT, const uint32_t uiNumUnitsInPU, const uint32_t unitWidth, bool *validFlags ); inline int isLeftAvailable ( const CodingUnit &cu, const ChannelType &chType, const Position &posLT, const uint32_t uiNumUnitsInPU, const uint32_t unitWidth, bool *validFlags );
......
...@@ -69,6 +69,10 @@ private: ...@@ -69,6 +69,10 @@ private:
Pel* m_piYuvExt[MAX_NUM_COMPONENT][NUM_PRED_BUF]; Pel* m_piYuvExt[MAX_NUM_COMPONENT][NUM_PRED_BUF];
int m_iYuvExtSize; int m_iYuvExtSize;
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
Pel* m_yuvExt2[MAX_NUM_COMPONENT][4];
int m_yuvExtSize2;
#endif
static const uint8_t m_aucIntraFilter[MAX_NUM_CHANNEL_TYPE][MAX_INTRA_FILTER_DEPTHS]; static const uint8_t m_aucIntraFilter[MAX_NUM_CHANNEL_TYPE][MAX_INTRA_FILTER_DEPTHS];
...@@ -126,6 +130,13 @@ public: ...@@ -126,6 +130,13 @@ public:
static bool useFilteredIntraRefSamples( const ComponentID &compID, const PredictionUnit &pu, bool modeSpecific, const UnitArea &tuArea ); static bool useFilteredIntraRefSamples( const ComponentID &compID, const PredictionUnit &pu, bool modeSpecific, const UnitArea &tuArea );
static bool useDPCMForFirstPassIntraEstimation(const PredictionUnit &pu, const uint32_t &uiDirMode); static bool useDPCMForFirstPassIntraEstimation(const PredictionUnit &pu, const uint32_t &uiDirMode);
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
void geneWeightedPred (const ComponentID compId, PelBuf &pred, const PredictionUnit &pu, Pel *srcBuf);
Pel* getPredictorPtr2 (const ComponentID compID, uint32_t idx) { return m_yuvExt2[compID][idx]; }
void switchBuffer (const PredictionUnit &pu, ComponentID compID, PelBuf srcBuff, Pel *dst);
void geneIntrainterPred (const CodingUnit &cu);
#endif
}; };
//! \} //! \}
......
...@@ -353,7 +353,11 @@ void initROM() ...@@ -353,7 +353,11 @@ void initROM()
// g_aucLog2[ x ]: log2(x), if x=1 -> 0, x=2 -> 1, x=4 -> 2, x=8 -> 3, x=16 -> 4, ... // g_aucLog2[ x ]: log2(x), if x=1 -> 0, x=2 -> 1, x=4 -> 2, x=8 -> 3, x=16 -> 4, ...
::memset(g_aucLog2, 0, sizeof(g_aucLog2)); ::memset(g_aucLog2, 0, sizeof(g_aucLog2));
c = 0; c = 0;
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
for( int i = 0, n = 0; i <= (1 << (MAX_CU_DEPTH + 1)); i++ )
#else
for( int i = 0, n = 0; i <= MAX_CU_SIZE; i++ ) for( int i = 0, n = 0; i <= MAX_CU_SIZE; i++ )
#endif
{ {
g_aucNextLog2[i] = i <= 1 ? 0 : c + 1; g_aucNextLog2[i] = i <= 1 ? 0 : c + 1;
...@@ -697,9 +701,15 @@ const DecisionTreeTemplate g_mtSplitDTT = compile( ...@@ -697,9 +701,15 @@ const DecisionTreeTemplate g_mtSplitDTT = compile(
// ==================================================================================================================== // ====================================================================================================================
SizeIndexInfo* gp_sizeIdxInfo = NULL; SizeIndexInfo* gp_sizeIdxInfo = NULL;
int g_BlockSizeTrafoScale[MAX_CU_SIZE + 1][MAX_CU_SIZE + 1][2]; int g_BlockSizeTrafoScale[MAX_CU_SIZE + 1][MAX_CU_SIZE + 1][2];
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
int8_t g_aucLog2 [(1 << (MAX_CU_DEPTH + 1)) + 1];
int8_t g_aucNextLog2[(1 << (MAX_CU_DEPTH + 1)) + 1];
int8_t g_aucPrevLog2[(1 << (MAX_CU_DEPTH + 1)) + 1];
#else
int8_t g_aucLog2 [MAX_CU_SIZE + 1]; int8_t g_aucLog2 [MAX_CU_SIZE + 1];
int8_t g_aucNextLog2[MAX_CU_SIZE + 1]; int8_t g_aucNextLog2[MAX_CU_SIZE + 1];
int8_t g_aucPrevLog2[MAX_CU_SIZE + 1]; int8_t g_aucPrevLog2[MAX_CU_SIZE + 1];
#endif
UnitScale g_miScaling( MIN_CU_LOG2, MIN_CU_LOG2 ); UnitScale g_miScaling( MIN_CU_LOG2, MIN_CU_LOG2 );
......
...@@ -165,9 +165,15 @@ extern const DecisionTreeTemplate g_qtbtSplitDTT; ...@@ -165,9 +165,15 @@ extern const DecisionTreeTemplate g_qtbtSplitDTT;
// ==================================================================================================================== // ====================================================================================================================
extern SizeIndexInfo* gp_sizeIdxInfo; extern SizeIndexInfo* gp_sizeIdxInfo;
extern int g_BlockSizeTrafoScale [MAX_CU_SIZE + 1][MAX_CU_SIZE + 1][2]; extern int g_BlockSizeTrafoScale [MAX_CU_SIZE + 1][MAX_CU_SIZE + 1][2];
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
extern int8_t g_aucLog2 [(1 << (MAX_CU_DEPTH + 1)) + 1];
extern int8_t g_aucNextLog2 [(1 << (MAX_CU_DEPTH + 1)) + 1];
extern int8_t g_aucPrevLog2 [(1 << (MAX_CU_DEPTH + 1)) + 1];
#else
extern int8_t g_aucLog2 [MAX_CU_SIZE + 1]; extern int8_t g_aucLog2 [MAX_CU_SIZE + 1];
extern int8_t g_aucNextLog2 [MAX_CU_SIZE + 1]; extern int8_t g_aucNextLog2 [MAX_CU_SIZE + 1];
extern int8_t g_aucPrevLog2 [MAX_CU_SIZE + 1]; extern int8_t g_aucPrevLog2 [MAX_CU_SIZE + 1];
#endif
extern const int8_t i2Log2Tab[257]; extern const int8_t i2Log2Tab[257];
inline bool is34( const SizeType& size ) inline bool is34( const SizeType& size )
......
...@@ -1640,6 +1640,9 @@ SPSNext::SPSNext( SPS& sps ) ...@@ -1640,6 +1640,9 @@ SPSNext::SPSNext( SPS& sps )
, m_Affine ( false ) , m_Affine ( false )
, m_AffineType ( false ) , m_AffineType ( false )
, m_MTTEnabled ( false ) , m_MTTEnabled ( false )
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
, m_MHIntra ( false )
#endif
#if ENABLE_WPP_PARALLELISM #if ENABLE_WPP_PARALLELISM
, m_NextDQP ( false ) , m_NextDQP ( false )
#endif #endif
......
...@@ -814,6 +814,9 @@ private: ...@@ -814,6 +814,9 @@ private:
bool m_GBi; // bool m_GBi; //
#endif #endif
bool m_MTTEnabled; // bool m_MTTEnabled; //
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
bool m_MHIntra;
#endif
#if ENABLE_WPP_PARALLELISM #if ENABLE_WPP_PARALLELISM
bool m_NextDQP; bool m_NextDQP;
#endif #endif
...@@ -921,6 +924,11 @@ public: ...@@ -921,6 +924,11 @@ public:
void setUseCompositeRef(bool b) { m_compositeRefEnabled = b; } void setUseCompositeRef(bool b) { m_compositeRefEnabled = b; }
bool getUseCompositeRef() const { return m_compositeRefEnabled; } bool getUseCompositeRef() const { return m_compositeRefEnabled; }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
void setUseMHIntra ( bool b ) { m_MHIntra = b; }
bool getUseMHIntra () const { return m_MHIntra; }
#endif
// ADD_NEW_TOOL : (sps extension) add access functions for tool enabling flags and associated parameters here // ADD_NEW_TOOL : (sps extension) add access functions for tool enabling flags and associated parameters here
}; };
......
...@@ -50,6 +50,8 @@ ...@@ -50,6 +50,8 @@
#include <assert.h> #include <assert.h>
#include <cassert> #include <cassert>
#define JVET_L0100_MULTI_HYPOTHESIS_INTRA 1 // Combine intra mode with an extra merge indexed prediction
#define JVET_L0553_FIX_INITQP 1 #define JVET_L0553_FIX_INITQP 1
#define JVET_L0147_ALF_SUBSAMPLED_LAPLACIAN 1 // Subsampled Laplacian calculation #define JVET_L0147_ALF_SUBSAMPLED_LAPLACIAN 1 // Subsampled Laplacian calculation
......
...@@ -331,6 +331,11 @@ void PredictionUnit::initData() ...@@ -331,6 +331,11 @@ void PredictionUnit::initData()
mvdAffi[i][j].setZero(); mvdAffi[i][j].setZero();
} }
} }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
MHIntraFlag = false;
intraDir2[0] = PLANAR_IDX;
intraDir2[1] = DM_CHROMA_IDX;
#endif
} }
PredictionUnit& PredictionUnit::operator=(const IntraPredictionData& predData) PredictionUnit& PredictionUnit::operator=(const IntraPredictionData& predData)
...@@ -361,6 +366,11 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData) ...@@ -361,6 +366,11 @@ PredictionUnit& PredictionUnit::operator=(const InterPredictionData& predData)
mvdAffi[i][j] = predData.mvdAffi[i][j]; mvdAffi[i][j] = predData.mvdAffi[i][j];
} }
} }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
MHIntraFlag = predData.MHIntraFlag;
intraDir2[0] = predData.intraDir2[0];
intraDir2[1] = predData.intraDir2[1];
#endif
return *this; return *this;
} }
...@@ -388,6 +398,11 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other ) ...@@ -388,6 +398,11 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other )
mvdAffi[i][j] = other.mvdAffi[i][j]; mvdAffi[i][j] = other.mvdAffi[i][j];
} }
} }
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
MHIntraFlag = other.MHIntraFlag;
intraDir2[0] = other.intraDir2[0];
intraDir2[1] = other.intraDir2[1];
#endif
return *this; return *this;
} }
......
...@@ -357,6 +357,10 @@ struct InterPredictionData ...@@ -357,6 +357,10 @@ struct InterPredictionData
int16_t refIdx [NUM_REF_PIC_LIST_01]; int16_t refIdx [NUM_REF_PIC_LIST_01];
MergeType mergeType; MergeType mergeType;
Mv mvdAffi [NUM_REF_PIC_LIST_01][3]; Mv mvdAffi [NUM_REF_PIC_LIST_01][3];
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
bool MHIntraFlag;
uint32_t intraDir2[MAX_NUM_CHANNEL_TYPE];
#endif
}; };
struct PredictionUnit : public UnitArea, public IntraPredictionData, public InterPredictionData struct PredictionUnit : public UnitArea, public IntraPredictionData, public InterPredictionData
......
...@@ -309,22 +309,42 @@ int PU::getIntraMPMs( const PredictionUnit &pu, unsigned* mpm, const ChannelType ...@@ -309,22 +309,42 @@ int PU::getIntraMPMs( const PredictionUnit &pu, unsigned* mpm, const ChannelType
// Get intra direction of left PU // Get intra direction of left PU
const PredictionUnit *puLeft = pu.cs->getPURestricted(pos.offset(-1, 0), pu, channelType); const PredictionUnit *puLeft = pu.cs->getPURestricted(pos.offset(-1, 0), pu, channelType);
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
if (puLeft && (CU::isIntra(*puLeft->cu) || (channelType == CHANNEL_TYPE_LUMA && puLeft->MHIntraFlag)))
#else
if (puLeft && CU::isIntra(*puLeft->cu)) if (puLeft && CU::isIntra(*puLeft->cu))
#endif
{ {
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
leftIntraDir = puLeft->MHIntraFlag ? puLeft->intraDir2[channelType] : puLeft->intraDir[channelType];
#else
leftIntraDir = puLeft->intraDir[channelType]; leftIntraDir = puLeft->intraDir[channelType];
#endif
if (isChroma(channelType) && leftIntraDir == DM_CHROMA_IDX) if (isChroma(channelType) && leftIntraDir == DM_CHROMA_IDX)
{ {
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
leftIntraDir = puLeft->MHIntraFlag ? puLeft->intraDir2[0] : puLeft->intraDir[0];
#else
leftIntraDir = puLeft->intraDir[0]; leftIntraDir = puLeft->intraDir[0];
#endif
} }
} }
// Get intra direction of above PU // Get intra direction of above PU
const PredictionUnit *puAbove = pu.cs->getPURestricted(pos.offset(0, -1), pu, channelType); const PredictionUnit *puAbove = pu.cs->getPURestricted(pos.offset(0, -1), pu, channelType);
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
if (puAbove && (CU::isIntra(*puAbove->cu) || (channelType == CHANNEL_TYPE_LUMA && puAbove->MHIntraFlag)) && CU::isSameCtu(*pu.cu, *puAbove->cu))
#else
if (puAbove && CU::isIntra(*puAbove->cu) && CU::isSameCtu(*pu.cu, *puAbove->cu)) if (puAbove && CU::isIntra(*puAbove->cu) && CU::isSameCtu(*pu.cu, *puAbove->cu))
#endif
{ {
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
aboveIntraDir = puAbove->MHIntraFlag ? puAbove->intraDir2[channelType] : puAbove->intraDir[channelType];
#else
aboveIntraDir = puAbove->intraDir[channelType]; aboveIntraDir = puAbove->intraDir[channelType];
#endif
if (isChroma(channelType) && aboveIntraDir == DM_CHROMA_IDX) if (isChroma(channelType) && aboveIntraDir == DM_CHROMA_IDX)
{ {
...@@ -478,14 +498,168 @@ bool PU::isChromaIntraModeCrossCheckMode( const PredictionUnit &pu ) ...@@ -478,14 +498,168 @@ bool PU::isChromaIntraModeCrossCheckMode( const PredictionUnit &pu )
return pu.intraDir[CHANNEL_TYPE_CHROMA] == DM_CHROMA_IDX; return pu.intraDir[CHANNEL_TYPE_CHROMA] == DM_CHROMA_IDX;
} }