Commit d3851b48 authored by Frank Bossen's avatar Frank Bossen

67 intra modes with 3 MPMs

Based on patch provided by @naraechoi
parent b80bf727
......@@ -102,7 +102,7 @@ MaxBTDepthISliceL : 3
MaxBTDepthISliceC : 3
MTT : 1
Intra65Ang : 1
#Intra65Ang : 1
EMT : 3
EMTFast : 3
NSST : 1
......
......@@ -118,7 +118,7 @@ MaxBTDepthISliceL : 3
MaxBTDepthISliceC : 3
MTT : 1
Intra65Ang : 1
#Intra65Ang : 1
EMT : 3
EMTFast : 3
NSST : 1
......
......@@ -118,7 +118,7 @@ MaxBTDepthISliceL : 3
MaxBTDepthISliceC : 3
MTT : 1
Intra65Ang : 1
#Intra65Ang : 1
EMT : 3
EMTFast : 3
NSST : 1
......
......@@ -132,7 +132,7 @@ MaxBTDepthISliceL : 3
MaxBTDepthISliceC : 3
MTT : 1
Intra65Ang : 1
#Intra65Ang : 1
EMT : 3
EMTFast : 3
NSST : 1
......
......@@ -219,7 +219,9 @@ Void EncApp::xInitLibCfg()
#if JEM_TOOLS
m_cEncLib.setNSST ( m_NSST );
m_cEncLib.setIntra4Tap ( m_Intra4Tap );
#if !INTRA67_3MPM
m_cEncLib.setIntra65Ang ( m_Intra65Ang );
#endif
m_cEncLib.setUseIntraBoundaryFilter ( m_IntraBoundaryFilter);
#endif
m_cEncLib.setLargeCTU ( m_LargeCTU );
......
......@@ -807,7 +807,9 @@ Bool EncAppCfg::parseCfg( Int argc, TChar* argv[] )
#if JEM_TOOLS
("NSST", m_NSST, false, "Enable NSST (0:off, 1:on) [default: off]")
("Intra4Tap", m_Intra4Tap, false, "Enable 4-tap intra filter (0:off, 1:on) [default: off]")
#if !INTRA67_3MPM
("Intra65Ang", m_Intra65Ang, false, "Enable 65 intra prediction modes (0:off, 1:on) [default: off]")
#endif
("IntraBoundaryFilter", m_IntraBoundaryFilter, false, "Enable Intra boundary filter (0:off, 1:on) [default: off]")
#if ENABLE_BMS
("SubPuMvp", m_SubPuMvpMode, 0, "Enable Sub-PU temporal motion vector prediction (0:off, 1:ATMVP, 2:STMVP, 3:ATMVP+STMVP) [default: off]")
......@@ -1920,7 +1922,9 @@ Bool EncAppCfg::xCheckParameter()
xConfirmPara( m_QTBT, "QTBT only allowed with NEXT profile" );
#if JEM_TOOLS
xConfirmPara( m_NSST, "NSST only allowed with NEXT profile" );
#if !INTRA67_3MPM
xConfirmPara( m_Intra65Ang, "Intra 65 Ang only allowed with NEXT profile" );
#endif
xConfirmPara( m_Intra4Tap, "Intra 4 Tap only allowed with NEXT profile" );
xConfirmPara( m_IntraBoundaryFilter, "Intra boundary filter is only allowed with NEXT profile" );
xConfirmPara( m_LMChroma, "LMChroma only allowed with NEXT profile" );
......@@ -2025,8 +2029,10 @@ Bool EncAppCfg::xCheckParameter()
#if HEVC_USE_INTRA_SMOOTHING_T32 || HEVC_USE_INTRA_SMOOTHING_T64
xConfirmPara( (m_IntraPDPC & 2) && m_useStrongIntraSmoothing, "PDPC==2 requires disabling strong intra smoothing" );
#endif
#if !INTRA67_3MPM
xConfirmPara( ( m_LMChroma > 1 ) && !m_Intra65Ang, "ELM (LMChroma > 1) requires Intra65Ang" );
#endif
#endif
#if JEM_TOOLS
xConfirmPara( m_CIPF > 2, "CIPF must be in range [0:2]" );
#endif
......@@ -3213,7 +3219,9 @@ Void EncAppCfg::xPrintParameter()
msg( VERBOSE, "\nNEXT TOOL CFG: " );
#if JEM_TOOLS
msg( VERBOSE, "Intra4Tap:%d ", m_Intra4Tap );
#if !INTRA67_3MPM
msg( VERBOSE, "Intra65Ang:%d ", m_Intra65Ang );
#endif
msg( VERBOSE, "IntraBoundaryFilter:%d ", m_IntraBoundaryFilter );
msg( VERBOSE, "NSST:%d ", m_NSST );
msg( VERBOSE, "Affine:%d ", m_Affine );
......
......@@ -205,7 +205,9 @@ protected:
#if JEM_TOOLS
bool m_NSST;
bool m_Intra4Tap;
#if !INTRA67_3MPM
bool m_Intra65Ang;
#endif
bool m_IntraBoundaryFilter; ///< Indicates whether intra boundary filter is used
#endif
bool m_LargeCTU;
......
......@@ -220,8 +220,12 @@ static const UInt EMT_INTRA_MAX_CU_WITH_QTBT = 64; ///< Max
static const UInt EMT_INTER_MAX_CU_WITH_QTBT = 64; ///< Max Inter CU size applying EMT, supported values: 8, 16, 32, 64, 128
#endif
static const Int NUM_MOST_PROBABLE_MODES = 3;
static const Int NUM_MOST_PROBABLE_MODES_67 = 6;
#if INTRA67_3MPM
static const int NUM_MOST_PROBABLE_MODES = 3;
#else
static const Int NUM_MOST_PROBABLE_MODES = 3;
static const Int NUM_MOST_PROBABLE_MODES_67 = 6;
#endif
#if JEM_TOOLS
static const Int MMLM_SAMPLE_NEIGHBOR_LINES = 2;
static const Int LM_SYMBOL_NUM = (1 + NUM_LMC_MODE);
......
......@@ -948,6 +948,11 @@ const CtxSet ContextSetCfg::IPredMode[] =
{
ContextSetCfg::addCtxSet
({
#if INTRA67_3MPM
{ 183 },
{ 154 },
{ 184 },
#else
#if JVET_B0051_NON_MPM_MODE
{ 183, CNU, CNU, CNU, 184 },
{ 154, CNU, CNU, CNU, 184 },
......@@ -956,6 +961,7 @@ const CtxSet ContextSetCfg::IPredMode[] =
{ 183, CNU, CNU, CNU, },
{ 154, CNU, CNU, CNU, },
{ 184, CNU, CNU, CNU, },
#endif
#endif
}),
ContextSetCfg::addCtxSet
......@@ -1682,7 +1688,11 @@ void CtxWSizeStore::xInitMappingTable( const SPS* sps )
const SPSNext& spsNext = sps->getSpsNext();
unsigned numCtxSplitFlag = ( spsNext.getUseLargeCTU() ? 5 : 3 ); // hard-wired in JEM
unsigned numCtxMergeIdx = ( true /* COM16_C806_GEN_MRG_IMPROVEMENT */ ? 5 : 1 );
#if INTRA67_3MPM
unsigned numCtxIPredLuma = 1;
#else
unsigned numCtxIPredLuma = ( spsNext.getUseIntra65Ang() ? ( false /*JVET_B0051_NON_MPM_MODE */ ? 12 : 9 ) : 1 ); // hard-wired in JEM
#endif
unsigned numCtxIPredChroma = ( true /* JVET_E0077_ENHANCED_LM */ ? 8 : 2 ) + ( spsNext.getUseMDMS() ? 4 : 0 );
unsigned numCtxTransSubdiv = ( spsNext.getUseLargeCTU() || spsNext.getUseQTBT() ? 4 : 3 ); // hard-wired in JEM
unsigned numCtxLastXY = ( spsNext.getUseLargeCTU() || spsNext.getUseQTBT() ? 25 : 15 ); // hard-wired in JEM
......
......@@ -262,8 +262,13 @@ void IntraPrediction::predIntraAng( const ComponentID compId, PelBuf &piPred, co
}
else
{
#if INTRA67_3MPM
pPdpcParWidth = g_pdpc_pred_param[idxW][uiDirMode];
pPdpcParHeight = g_pdpc_pred_param[idxH][uiDirMode];
#else
pPdpcParWidth = g_pdpc_pred_param[idxW][g_intraMode65to33AngMapping[uiDirMode]];
pPdpcParHeight = g_pdpc_pred_param[idxH][g_intraMode65to33AngMapping[uiDirMode]];
#endif
}
const int *pPdpcParMain = (iWidth < iHeight) ? pPdpcParHeight : pPdpcParWidth;
......
......@@ -197,9 +197,11 @@ const Int g_aiMMLM_MinSize[] = { 0, 0 };
const Int g_aiNonLMPosThrs[] = { 3, 1, 0 };
Int g_aiLMCodeWord[LM_SYMBOL_NUM][16];
#if !INTRA67_3MPM
#if JVET_B0051_NON_MPM_MODE
const Int g_ipred_mode_table[] = { 1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13,13,14,14,14,15,15,15 };
#endif
#endif
#endif
......@@ -608,6 +610,7 @@ const UChar g_chroma422IntraAngleMappingTable[NUM_INTRA_MODE] =
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, DM
{ 0, 1, 2, 2, 2, 2, 2, 2, 2, 3, 4, 6, 8, 10, 12, 13, 14, 16, 18, 20, 22, 23, 24, 26, 28, 30, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 44, 44, 45, 46, 46, 46, 47, 48, 48, 48, 49, 50, 51, 52, 52, 52, 53, 54, 54, 54, 55, 56, 56, 56, 57, 58, 59, 60, DM_CHROMA_IDX };
#if !INTRA67_3MPM
extern const UChar g_intraMode65to33AngMapping[NUM_INTRA_MODE] =
// H D V
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, DM
......@@ -617,6 +620,7 @@ extern const UChar g_intraMode33to65AngMapping[36] =
// H D V
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, DM
{ 0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, DM_CHROMA_IDX };
#endif
#if JEM_TOOLS
const Int g_intraCubicFilter[32][4] = {
......
......@@ -119,6 +119,7 @@ extern const UChar g_aucIntraModeNumFast_UseMPM [MAX_CU_DEPTH];
extern const UChar g_aucIntraModeNumFast_NotUseMPM[MAX_CU_DEPTH];
extern const UChar g_chroma422IntraAngleMappingTable[NUM_INTRA_MODE];
#if !INTRA67_3MPM
extern const UChar g_intraMode65to33AngMapping[NUM_INTRA_MODE];
extern const UChar g_intraMode33to65AngMapping[36];
......@@ -128,6 +129,7 @@ static const unsigned mpmCtx[NUM_INTRA_MODE] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // HOR domain
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 // VER domain
};
#endif
#if JEM_TOOLS
extern const Int g_intraCubicFilter[32][4];
......@@ -285,11 +287,12 @@ extern const Int g_aiNonLMPosThrs[];
extern const UChar g_NonMPM[257];
#if !INTRA67_3MPM
#if JVET_B0051_NON_MPM_MODE
extern const Int g_ipred_mode_table[];
#endif
#endif
#endif
//! \}
......
......@@ -1713,7 +1713,9 @@ SPSNext::SPSNext( SPS& sps )
#if JEM_TOOLS
, m_NSST ( false )
, m_Intra4Tap ( false )
#if !INTRA67_3MPM
, m_Intra65Ang ( false )
#endif
#endif
, m_LargeCTU ( false )
#if JEM_TOOLS
......
......@@ -804,7 +804,9 @@ private:
#if JEM_TOOLS
bool m_NSST; // 2
bool m_Intra4Tap; // 3
#if !INTRA67_3MPM
bool m_Intra65Ang; // 4
#endif
#endif
bool m_LargeCTU; // 5
#if JEM_TOOLS
......@@ -930,8 +932,10 @@ public:
bool getUseNSST () const { return m_NSST; }
void setUseIntra4Tap ( bool b ) { m_Intra4Tap = b; }
bool getUseIntra4Tap () const { return m_Intra4Tap; }
#if !INTRA67_3MPM
void setUseIntra65Ang ( bool b ) { m_Intra65Ang = b; }
bool getUseIntra65Ang () const { return m_Intra65Ang; }
#endif
#endif
void setUseLargeCTU ( bool b ) { m_LargeCTU = b; }
bool getUseLargeCTU () const { return m_LargeCTU; }
......@@ -2251,10 +2255,14 @@ public:
, lumaWidth ( sps.getPicWidthInLumaSamples() )
, lumaHeight ( sps.getPicHeightInLumaSamples() )
, fastDeltaQPCuMaxSize( Clip3(sps.getMaxCUHeight() >> (sps.getLog2DiffMaxMinCodingBlockSize()), sps.getMaxCUHeight(), 32u) )
#if INTRA67_3MPM
, numMPMs (NUM_MOST_PROBABLE_MODES)
#else
#if JEM_TOOLS
, numMPMs ( sps.getSpsNext().getUseIntra65Ang() ? NUM_MOST_PROBABLE_MODES_67 : NUM_MOST_PROBABLE_MODES )
#else
, numMPMs ( NUM_MOST_PROBABLE_MODES )
#endif
#endif
, noRQT ( sps.getSpsNext().getUseQTBT() )
, rectCUs ( sps.getSpsNext().getUseQTBT() )
......
......@@ -138,9 +138,11 @@ void xTrMxN_EMT( const Int bitDepth, const Pel *residual, size_t stride, TCoeff
#else
void xTrMxN_EMT( const Int bitDepth, const Pel *residual, size_t stride, TCoeff *coeff, Int iWidth, Int iHeight, const int maxLog2TrDynamicRange,
#endif
const UChar ucMode, const UChar ucTrIdx, const bool use65intraModes
, const bool useQTBT
)
const UChar ucMode, const UChar ucTrIdx
#if !INTRA67_3MPM
, const bool use65intraModes
#endif
, const bool useQTBT )
{
const Int TRANSFORM_MATRIX_SHIFT = g_transformMatrixShift[TRANSFORM_FORWARD];
const Int shift_1st = ((g_aucLog2[iWidth ]) + bitDepth + TRANSFORM_MATRIX_SHIFT) - maxLog2TrDynamicRange + COM16_C806_TRANS_PREC;
......@@ -181,6 +183,10 @@ void xTrMxN_EMT( const Int bitDepth, const Pel *residual, size_t stride, TCoeff
if( ucMode != INTER_MODE_IDX && ucTrIdx != DCT2_EMT )
{
UInt nTrSubsetHor, nTrSubsetVer;
#if INTRA67_3MPM
nTrSubsetHor = g_aucTrSetHorz[ucMode];
nTrSubsetVer = g_aucTrSetVert[ucMode];
#else
if( use65intraModes )
{
nTrSubsetHor = g_aucTrSetHorz[ucMode];
......@@ -191,6 +197,7 @@ void xTrMxN_EMT( const Int bitDepth, const Pel *residual, size_t stride, TCoeff
nTrSubsetHor = g_aucTrSetHorz35[ucMode];
nTrSubsetVer = g_aucTrSetVert35[ucMode];
}
#endif
nTrIdxHor = g_aiTrSubsetIntra[nTrSubsetHor][ucTrIdx & 1];
nTrIdxVer = g_aiTrSubsetIntra[nTrSubsetVer][ucTrIdx >> 1];
}
......@@ -221,10 +228,18 @@ void xTrMxN_EMT( const Int bitDepth, const Pel *residual, size_t stride, TCoeff
*/
#if HEVC_USE_4x4_DSTVII
#if INTRA67_3MPM
void xITrMxN_EMT(const Int bitDepth, const TCoeff *coeff, Pel *residual, size_t stride, Int iWidth, Int iHeight, UInt uiSkipWidth, UInt uiSkipHeight, Bool useDST, const Int maxLog2TrDynamicRange, UChar ucMode, UChar ucTrIdx )
#else
void xITrMxN_EMT( const Int bitDepth, const TCoeff *coeff, Pel *residual, size_t stride, Int iWidth, Int iHeight, UInt uiSkipWidth, UInt uiSkipHeight, Bool useDST, const Int maxLog2TrDynamicRange, UChar ucMode, UChar ucTrIdx, bool use65intraModes )
#endif
#else
#if INTRA67_3MPM
void xITrMxN_EMT(const Int bitDepth, const TCoeff *coeff, Pel *residual, size_t stride, Int iWidth, Int iHeight, UInt uiSkipWidth, UInt uiSkipHeight, const Int maxLog2TrDynamicRange, UChar ucMode, UChar ucTrIdx )
#else
void xITrMxN_EMT( const Int bitDepth, const TCoeff *coeff, Pel *residual, size_t stride, Int iWidth, Int iHeight, UInt uiSkipWidth, UInt uiSkipHeight, const Int maxLog2TrDynamicRange, UChar ucMode, UChar ucTrIdx, bool use65intraModes )
#endif
#endif
{
const Int TRANSFORM_MATRIX_SHIFT = g_transformMatrixShift[TRANSFORM_INVERSE];
const TCoeff clipMinimum = -( 1 << maxLog2TrDynamicRange );
......@@ -244,6 +259,10 @@ void xITrMxN_EMT( const Int bitDepth, const TCoeff *coeff, Pel *residual, size_t
if( ucMode != INTER_MODE_IDX && ucTrIdx != DCT2_EMT )
{
UInt nTrSubsetHor, nTrSubsetVer;
#if INTRA67_3MPM
nTrSubsetHor = g_aucTrSetHorz[ucMode];
nTrSubsetVer = g_aucTrSetVert[ucMode];
#else
if( use65intraModes )
{
nTrSubsetHor = g_aucTrSetHorz[ucMode];
......@@ -254,6 +273,7 @@ void xITrMxN_EMT( const Int bitDepth, const TCoeff *coeff, Pel *residual, size_t
nTrSubsetHor = g_aucTrSetHorz35[ucMode];
nTrSubsetVer = g_aucTrSetVert35[ucMode];
}
#endif
nTrIdxHor = g_aiTrSubsetIntra[nTrSubsetHor][ucTrIdx & 1];
nTrIdxVer = g_aiTrSubsetIntra[nTrSubsetVer][ucTrIdx >> 1];
}
......@@ -508,8 +528,10 @@ Void TrQuant::init( const Quant* otherQuant,
#endif
const bool bEnc,
const bool useTransformSkipFast,
#if !INTRA67_3MPM
#if JEM_TOOLS
const bool use65IntraModes,
#endif
#endif
const bool rectTUs
)
......@@ -517,8 +539,10 @@ Void TrQuant::init( const Quant* otherQuant,
m_uiMaxTrSize = uiMaxTrSize;
m_bEnc = bEnc;
m_useTransformSkipFast = useTransformSkipFast;
#if !INTRA67_3MPM
#if JEM_TOOLS
m_use65IntraModes = use65IntraModes;
#endif
#endif
m_rectTUs = rectTUs;
......@@ -1008,10 +1032,18 @@ void TrQuant::xT( const TransformUnit &tu, const ComponentID &compID, const CPel
if( ucTrIdx != DCT2_HEVC )
{
#if INTRA67_3MPM
#if HEVC_USE_4x4_DSTVII
xTrMxN_EMT(channelBitDepth, resi.buf, resi.stride, dstCoeff.buf, iWidth, iHeight, useDST, maxLog2TrDynamicRange, ucMode, ucTrIdx
#else
xTrMxN_EMT(channelBitDepth, resi.buf, resi.stride, dstCoeff.buf, iWidth, iHeight, maxLog2TrDynamicRange, ucMode, ucTrIdx
#endif
#else
#if HEVC_USE_4x4_DSTVII
xTrMxN_EMT( channelBitDepth, resi.buf, resi.stride, dstCoeff.buf, iWidth, iHeight, useDST, maxLog2TrDynamicRange, ucMode, ucTrIdx, m_use65IntraModes
#else
xTrMxN_EMT( channelBitDepth, resi.buf, resi.stride, dstCoeff.buf, iWidth, iHeight, maxLog2TrDynamicRange, ucMode, ucTrIdx, m_use65IntraModes
#endif
#endif
, m_rectTUs
);
......@@ -1055,11 +1087,18 @@ void TrQuant::xIT( const TransformUnit &tu, const ComponentID &compID, const CCo
iSkipWidth = pCoeff.width >> 1;
iSkipHeight = pCoeff.height >> 1;
}
#if INTRA67_3MPM
#if HEVC_USE_4x4_DSTVII
xITrMxN_EMT(channelBitDepth, pCoeff.buf, pResidual.buf, pResidual.stride, pCoeff.width, pCoeff.height, iSkipWidth, iSkipHeight, useDST, maxLog2TrDynamicRange, ucMode, ucTrIdx );
#else
xITrMxN_EMT(channelBitDepth, pCoeff.buf, pResidual.buf, pResidual.stride, pCoeff.width, pCoeff.height, iSkipWidth, iSkipHeight, maxLog2TrDynamicRange, ucMode, ucTrIdx );
#endif
#else
#if HEVC_USE_4x4_DSTVII
xITrMxN_EMT( channelBitDepth, pCoeff.buf, pResidual.buf, pResidual.stride, pCoeff.width, pCoeff.height, iSkipWidth, iSkipHeight, useDST, maxLog2TrDynamicRange, ucMode, ucTrIdx, m_use65IntraModes );
#else
xITrMxN_EMT( channelBitDepth, pCoeff.buf, pResidual.buf, pResidual.stride, pCoeff.width, pCoeff.height, iSkipWidth, iSkipHeight, maxLog2TrDynamicRange, ucMode, ucTrIdx, m_use65IntraModes );
#endif
#endif
}
else
......@@ -1176,10 +1215,14 @@ UChar TrQuant::getEmtMode( TransformUnit tu, const ComponentID compID )
CodingStructure &cs = *tu.cs;
const PredictionUnit &pu = *cs.getPU( tu.blocks[compID].pos(), toChannelType( compID ) );
const UInt uiChFinalMode = PU::getFinalIntraMode( pu, toChannelType( compID ) );
#if INTRA67_3MPM
ucMode = uiChFinalMode;
#else
#if JEM_TOOLS
ucMode = m_use65IntraModes ? uiChFinalMode : g_intraMode65to33AngMapping[uiChFinalMode];
#else
ucMode = g_intraMode65to33AngMapping[uiChFinalMode];
#endif
#endif
}
else
......
......@@ -82,8 +82,10 @@ public:
#endif
const bool bEnc = false,
const bool useTransformSkipFast = false,
#if !INTRA67_3MPM
#if JEM_TOOLS
const bool use65IntraModes = false,
#endif
#endif
const bool rectTUs = false
);
......@@ -135,8 +137,10 @@ protected:
Bool m_bEnc;
Bool m_useTransformSkipFast;
#if !INTRA67_3MPM
#if JEM_TOOLS
bool m_use65IntraModes;
#endif
#endif
bool m_rectTUs;
......
......@@ -53,6 +53,10 @@
#define DEBLOCKING_GRID_8x8 1
#define DB_TU_FIX 1 // fix in JVET_K0307, JVET-K0237, JVET-K0369, JVET-K0232, JVET-K0315
#ifndef INTRA67_3MPM // JVET-K0529
#define INTRA67_3MPM 1
#endif
#define JVET_K0072 1
#define JVET_K0220_ENC_CTRL 1 // remove HM_NO_ADDITIONAL_SPEEDUPS when adopting
......
......@@ -505,7 +505,11 @@ int PU::getIntraMPMs( const PredictionUnit &pu, unsigned* mpm, const ChannelType
const unsigned numMPMs = pu.cs->pcv->numMPMs;
#endif
#if JEM_TOOLS
if( pu.cs->sps->getSpsNext().getUseIntra65Ang() || isChromaMDMS )
#if INTRA67_3MPM
if (isChromaMDMS)
#else
if (pu.cs->sps->getSpsNext().getUseIntra65Ang() || isChromaMDMS)
#endif
{
Int numCand = -1;
UInt modeIdx = 0;
......@@ -660,6 +664,86 @@ int PU::getIntraMPMs( const PredictionUnit &pu, unsigned* mpm, const ChannelType
}
else
#endif
#if INTRA67_3MPM
{
int numCand = -1;
int leftIntraDir = DC_IDX, aboveIntraDir = DC_IDX;
const CompArea &area = pu.block(getFirstComponentOfChannel(channelType));
const Position &pos = area.pos();
// Get intra direction of left PU
const PredictionUnit *puLeft = pu.cs->getPURestricted(pos.offset(-1, 0), pu, channelType);
if (puLeft && CU::isIntra(*puLeft->cu))
{
leftIntraDir = puLeft->intraDir[channelType];
if (isChroma(channelType) && leftIntraDir == DM_CHROMA_IDX)
{
leftIntraDir = puLeft->intraDir[0];
}
}
// Get intra direction of above PU
const PredictionUnit *puAbove = pu.cs->getPURestricted(pos.offset(0, -1), pu, channelType);
if (puAbove && CU::isIntra(*puAbove->cu) && CU::isSameCtu(*pu.cu, *puAbove->cu))
{
aboveIntraDir = puAbove->intraDir[channelType];
if (isChroma(channelType) && aboveIntraDir == DM_CHROMA_IDX)
{
aboveIntraDir = puAbove->intraDir[0];
}
}
CHECK(2 >= numMPMs, "Invalid number of most probable modes");
const int offset = (int) NUM_LUMA_MODE - 5;
const int mod = offset + 3;
if (leftIntraDir == aboveIntraDir)
{
numCand = 1;
if (leftIntraDir > DC_IDX) // angular modes
{
mpm[0] = leftIntraDir;
mpm[1] = ((leftIntraDir + offset) % mod) + 2;
mpm[2] = ((leftIntraDir - 1) % mod) + 2;
}
else // non-angular
{
mpm[0] = PLANAR_IDX;
mpm[1] = DC_IDX;
mpm[2] = VER_IDX;
}
}
else
{
numCand = 2;
mpm[0] = leftIntraDir;
mpm[1] = aboveIntraDir;
if (leftIntraDir && aboveIntraDir) // both modes are non-planar
{
mpm[2] = PLANAR_IDX;
}
else
{
mpm[2] = (leftIntraDir + aboveIntraDir) < 2 ? VER_IDX : DC_IDX;
}
}
for (int i = 0; i < numMPMs; i++)
{
CHECK(mpm[i] >= NUM_LUMA_MODE, "Invalid MPM");
}
CHECK(numCand == 0, "No candidates found");
return numCand;
}
#else
{
Int numCand = -1;
Int leftIntraDir = DC_IDX, aboveIntraDir = DC_IDX;
......@@ -740,6 +824,7 @@ int PU::getIntraMPMs( const PredictionUnit &pu, unsigned* mpm, const ChannelType
CHECK( numCand == 0, "No candidates found" );
return numCand;
}
#endif
}
#if JEM_TOOLS
......
......@@ -93,6 +93,10 @@ inline void dtraceModeCost(CodingStructure &cs, double lambda)
bool isIntra = CU::isIntra( *cs.cus.front() );
int intraModeL = isIntra ? cs.pus.front()->intraDir[0] : 0;
int intraModeC = isIntra ? cs.pus.front()->intraDir[1] : 0;
#if INTRA67_3MPM
if (isIntra && intraModeC == DM_CHROMA_IDX)
intraModeC = 68;
#else
#if JEM_TOOLS
bool is65Ang = cs.sps->getSpsNext().getUseIntra65Ang();
if( isIntra && !is65Ang ) intraModeL = g_intraMode65to33AngMapping[intraModeL];
......@@ -103,6 +107,7 @@ inline void dtraceModeCost(CodingStructure &cs, double lambda)
if( isIntra && intraModeC == DM_CHROMA_IDX ) intraModeC = 36;
else if( isIntra ) intraModeC = g_intraMode65to33AngMapping[intraModeC];
#endif
#endif
#if JEM_TOOLS
DTRACE( g_trace_ctx, D_MODE_COST, "ModeCost: %6lld %3d @(%4d,%4d) [%2dx%2d] %d (qp%d,pm%d,ptSize%d,skip%d,mrg%d,fruc%d,obmc%d,ic%d,imv%d,affn%d,%d,%d) tempCS = %lld (%d,%d)\n",
DTRACE_GET_COUNTER( g_trace_ctx, D_MODE_COST ),
......@@ -172,6 +177,7 @@ inline void dtraceBestMode(CodingStructure *&tempCS, CodingStructure *&bestCS, d
bool isIntra = CU::isIntra( *tempCS->cus[0] );
int intraModeL = isIntra ? tempCS->pus[0]->intraDir[0] : 0;
int intraModeC = isIntra ? tempCS->pus[0]->intraDir[1] : 0;
#if !INTRA67_3MPM
#if JEM_TOOLS
bool is65Ang = tempCS->sps->getSpsNext().getUseIntra65Ang();
if( isIntra && !is65Ang ) intraModeL = g_intraMode65to33AngMapping[intraModeL];
......@@ -181,6 +187,7 @@ inline void dtraceBestMode(CodingStructure *&tempCS, CodingStructure *&bestCS, d
if( isIntra ) intraModeL = g_intraMode65to33AngMapping[intraModeL];
if( isIntra && intraModeC == DM_CHROMA_IDX ) intraModeC = 36;
else if( isIntra ) intraModeC = g_intraMode65to33AngMapping[intraModeC];
#endif
#endif
if(!bSplitCS)
......
......@@ -1443,8 +1443,10 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
}
PredictionUnit *pu = cu.firstPU;
#if !INTRA67_3MPM
#if JEM_TOOLS
const bool use65Ang = cu.cs->sps->getSpsNext().getUseIntra65Ang();
#endif
#endif
// mpm_idx / rem_intra_luma_pred_mode
......@@ -1456,6 +1458,7 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
if( mpmFlag[k] )
{
unsigned ipred_idx = 0;
#if !INTRA67_3MPM
#if JEM_TOOLS
if( use65Ang )
{
......@@ -1468,6 +1471,7 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
ipred_idx = decode_sparse_dt( dt );
}
else
#endif
#endif
{
ipred_idx = m_BinDecoder.decodeBinEP();
......@@ -1482,6 +1486,7 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
{
unsigned ipred_mode = 0;
#if !INTRA67_3MPM
#if JEM_TOOLS
if( use65Ang )
{
......@@ -1508,26 +1513,39 @@ void CABACReader::intra_luma_pred_modes( CodingUnit &cu )
#endif
}
else
#endif
#endif
{
#if INTRA67_3MPM
ipred_mode = m_BinDecoder.decodeBinsEP(6);
#else
ipred_mode = m_BinDecoder.decodeBinsEP( 5 );
#endif
}
//postponed sorting of MPMs (only in remaining branch)
std::sort( mpm_pred, mpm_pred + cu.cs->pcv->numMPMs );
for( unsigned i = 0; i < cu.cs->pcv->numMPMs; i++ )
{
#if !INTRA67_3MPM
#if JEM_TOOLS
ipred_mode += use65Ang ? ( ipred_mode >= mpm_pred[i] ) : ( ipred_mode >= g_intraMode65to33AngMapping[mpm_pred[i]] );
#else
ipred_mode += ipred_mode >= g_intraMode65to33AngMapping[mpm_pred[i]];
#endif
#else
ipred_mode += (ipred_mode >= mpm_pred[i]);
#endif
}
#if !INTRA67_3MPM
#if JEM_TOOLS
pu->intraDir[0] = use65Ang ? ipred_mode : g_intraMode33to65AngMapping[ipred_mode];
#else
pu->intraDir[0] = g_intraMode33to65AngMapping[ipred_mode];
#endif
#else
pu->intraDir[0] = ipred_mode;
#endif
}
......
......@@ -790,10 +790,18 @@ Void DecLib::xActivateParameterSets()
m_cCuDecoder.init( &m_cTrQuant, &m_cIntraPred, &m_cInterPred );
#if JEM_TOOLS
#if JVET_K0072
#if INTRA67_3MPM
m_cTrQuant.init(nullptr, sps->getMaxTrSize(), false, false, false, false, false, pps->pcv->rectCUs);
#else
m_cTrQuant.init( nullptr, sps->getMaxTrSize(), false, false, false, false, false, sps->getSpsNext().getUseIntra65Ang(), pps->pcv->rectCUs );
#endif
#else
#if INTRA67_3MPM
m_cTrQuant.init(nullptr, sps->getMaxTrSize(), false, false, false, 0, false, false, pps->pcv->rectCUs);
#else
m_cTrQuant.init( nullptr, sps->getMaxTrSize(), false, false, false, 0, false, false, sps->getSpsNext().getUseIntra65Ang(), pps->pcv->rectCUs );
#endif
#endif
#else
m_cTrQuant.init( nullptr, sps->getMaxTrSize(), false, false, false, false, false, pps->pcv->rectCUs );
#endif
......
......@@ -801,7 +801,9 @@ void HLSyntaxReader::parseSPSNext( SPSNext& spsNext, const bool usePCM )
#if JEM_TOOLS
READ_FLAG( symbol, "nsst_enabled_flag" ); spsNext.setUseNSST ( symbol != 0 );
READ_FLAG( symbol, "intra_4tap_flag" ); spsNext.setUseIntra4Tap ( symbol != 0 );
#if !INTRA67_3MPM
READ_FLAG( symbol, "intra_65ang_flag" ); spsNext.setUseIntra65Ang ( symbol != 0 );
#endif
#endif
READ_FLAG( symbol, "large_ctu_flag" ); spsNext.setUseLargeCTU ( symbol != 0 );
#if JEM_TOOLS
......
......@@ -1421,8 +1421,10 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
unsigned ipred_modes [4];
const PredictionUnit* pu = cu.firstPU;
#if !INTRA67_3MPM
#if JEM_TOOLS
const bool use65Ang = cu.cs->sps->getSpsNext().getUseIntra65Ang();
#endif
#endif
// prev_intra_luma_pred_flag
......@@ -1458,6 +1460,7 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
const unsigned& mpm_idx = mpm_idxs[k];
if( mpm_idx < numMPMs )
{
#if !INTRA67_3MPM
#if JEM_TOOLS
if( use65Ang )
{
......@@ -1470,6 +1473,7 @@ void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
encode_sparse_dt( dt, mpm_idx );