diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index f9f3af1a1e85ed98f196ea538d67974fc6e5716e..ea9f998733c0f05294342c7811f9ca197e3bdd25 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -22829,15 +22829,56 @@ void IntraPrediction::initEipParams(const PredictionUnit& pu, const ComponentID CPelBuf recoLeft(piReco + refPosPicX + (refPosPicY + refSizeY) * picStride, picStride, refSizeX, refHeight - refSizeY); PelBuf refLeft(m_eipBuffer + refWidth * refSizeY, refWidth, refSizeX, refHeight - refSizeY); refLeft.copyFrom(recoLeft); + +#if JVET_AH0086_EIP_BIAS_AND_CLIP + int min = MAX_INT; + int max = 0; + int startY = refPosPicY < 0 ? -refPosPicY : 0; + const int startX = refPosPicX < 0 ? -refPosPicX : 0; + for(int y=startY;y<refTopAndTopLeft.height;y++) + { + for(int x=startX;x<refTopAndTopLeft.width;x++) + { + int sample = refTopAndTopLeft.at(x,y); + min = sample < min ? sample : min; + max = sample > max ? sample : max; + } + } + startY = (refPosPicY + refSizeY) < 0 ? -(refPosPicY + refSizeY) : 0; + for(int y=startY;y<refLeft.height;y++) + { + for(int x=startX;x<refLeft.width;x++) + { + int sample = refLeft.at(x,y); + min = sample < min ? sample : min; + max = sample > max ? sample : max; + } + } + m_eipClipMin = min; + m_eipClipMax = max; + m_eipBias = 1 << (pu.cu->slice->getSPS()->getBitDepth(chType) - 1); +#endif } -void setInputsVec(Pel *inputs, PelBuf &reco, int w, int h, int filterShape) +#if JVET_AH0086_EIP_BIAS_AND_CLIP +void IntraPrediction::setInputsVec(Pel *inputs, PelBuf &reco, int w, int h, int filterShape) +{ + inputs[EIP_FILTER_TAP - 1] = m_eipBias; + + for(int idx = 0; idx < EIP_FILTER_TAP - 1; idx++) + { + inputs[idx] = reco.at(w + g_eipFilter[filterShape][idx].x, h + g_eipFilter[filterShape][idx].y); + } +} +#else +void setInputsVec(Pel *inputs, PelBuf &reco, int w, int h, int filterShape) { for(int idx = 0; idx < EIP_FILTER_TAP; idx++) { inputs[idx] = reco.at(w + g_eipFilter[filterShape][idx].x, h + g_eipFilter[filterShape][idx].y); } } +#endif void IntraPrediction::getCurEipCands(const PredictionUnit& pu, static_vector<EipModelCandidate, NUM_DERIVED_EIP>& candList, const ComponentID compId, const bool fastTest) { @@ -22933,7 +22974,13 @@ void IntraPrediction::getCurEipCands(const PredictionUnit& pu, static_vector<Eip { for (int x = startX; x < endX; x++) { +#if JVET_AH0086_EIP_BIAS_AND_CLIP + m_a[numInputs - 1][numSamples] = m_eipBias; + + for (int inputIdx = 0; inputIdx < numInputs - 1; inputIdx++) +#else for (int inputIdx = 0; inputIdx < numInputs; inputIdx++) +#endif { m_a[inputIdx][numSamples] = refBuf.at(x + g_eipFilter[filterShape][inputIdx].x, y + g_eipFilter[filterShape][inputIdx].y); } @@ -23019,7 +23066,13 @@ void IntraPrediction::eipPred(const PredictionUnit& pu, PelBuf& piPred, const Co const ScanElement* scan = g_scanOrder[SCAN_UNGROUPED][SCAN_DIAG][gp_sizeIdxInfo->idxFrom(blockWidth)][gp_sizeIdxInfo->idxFrom(blockHeight)]; const int num = blockWidth * blockHeight; Pel inputs[EIP_FILTER_TAP]; +#if JVET_AH0086_EIP_BIAS_AND_CLIP + ClpRng clipRng = pu.cu->slice->clpRngs().comp[compId]; + clipRng.min = std::max( clipRng.min, m_eipClipMin); + clipRng.max = std::min( clipRng.max, m_eipClipMax); +#else const ClpRng clipRng = pu.cu->slice->clpRngs().comp[compId]; +#endif for (int scanIdx = 0; scanIdx < num; scanIdx++) { setInputsVec(inputs, predBuf, scan[scanIdx].x, scan[scanIdx].y, model.filterShape); @@ -23510,7 +23563,13 @@ void IntraPrediction::reorderEipCands(const PredictionUnit& pu, static_vector<Ei static_vector<EipModelCandidate, MAX_MERGE_EIP> tmpCandList; Pel inputs[EIP_FILTER_TAP]; const ChannelType chType = toChannelType(compId); +#if JVET_AH0086_EIP_BIAS_AND_CLIP + ClpRng clipRng = pu.cu->slice->clpRngs().comp[compId]; + clipRng.min = std::max( clipRng.min, m_eipClipMin); + clipRng.max = std::min( clipRng.max, m_eipClipMax); +#else const ClpRng clipRng = pu.cu->slice->clpRngs().comp[compId]; +#endif for(auto model: candList) { CccmModel cand(EIP_FILTER_TAP, pu.cu->slice->getSPS()->getBitDepth(toChannelType(compId))); diff --git a/source/Lib/CommonLib/IntraPrediction.h b/source/Lib/CommonLib/IntraPrediction.h index e732808434c96a3e8aad304da1542ad12d51ce3c..bca6799e8daab922a474a0417521a290a471a70e 100644 --- a/source/Lib/CommonLib/IntraPrediction.h +++ b/source/Lib/CommonLib/IntraPrediction.h @@ -272,6 +272,11 @@ protected: bool bSrcBufFilled[NUM_EIP_SHAPE * NUM_EIP_BASE_RECOTYPE]; bool bDstBufFilled[NUM_EIP_BASE_RECOTYPE]; int numSamplesBuf[NUM_EIP_BASE_RECOTYPE]; +#if JVET_AH0086_EIP_BIAS_AND_CLIP + Pel m_eipBias; + int m_eipClipMin; + int m_eipClipMax; +#endif #endif private: #if JVET_AG0136_INTRA_TMP_LIC @@ -849,6 +854,9 @@ public: void getNeiEipCands(const PredictionUnit &pu, static_vector<EipModelCandidate, MAX_MERGE_EIP> &candList, const ComponentID compId = COMPONENT_Y); void reorderEipCands(const PredictionUnit &pu, static_vector<EipModelCandidate, MAX_MERGE_EIP> &candList, const ComponentID compId = COMPONENT_Y); +#if JVET_AH0086_EIP_BIAS_AND_CLIP + void setInputsVec(Pel *inputs, PelBuf &reco, int w, int h, int filterShape); +#endif #endif #if JVET_Z0056_GPM_SPLIT_MODE_REORDERING && JVET_Y0065_GPM_INTRA protected: diff --git a/source/Lib/CommonLib/Rom.cpp b/source/Lib/CommonLib/Rom.cpp index 5468f1c270b6bcdaeb3a8d08ca64f9c368563cd3..7d5826cbf5679bf76ba4856e30629da943a8b8ba 100644 --- a/source/Lib/CommonLib/Rom.cpp +++ b/source/Lib/CommonLib/Rom.cpp @@ -4266,14 +4266,23 @@ const uint8_t g_aucTrSet[80][4] = #endif #if JVET_AG0058_EIP +#if JVET_AH0086_EIP_BIAS_AND_CLIP +// Note: Positions here are identical to the definition in the #else branch, just omitting the last position from each array +const Position g_eipFilter[NUM_EIP_SHAPE][EIP_FILTER_TAP - 1] = +{ + { Position(-1, 0), Position(-2, 0), Position(-3, 0), Position( 0, -1), Position(-1, -1), Position(-2, -1), Position(-3, -1), Position( 0, -2), Position(-1, -2), Position(-2, -2), Position(-3, -2), Position( 0, -3), Position(-1, -3), Position(-2, -3) }, + { Position(-1, 0), Position( 0, -1), Position(-1, -1), Position( 0, -2), Position(-1, -2), Position( 0, -3), Position(-1, -3), Position( 0, -4), Position(-1, -4), Position( 0, -5), Position(-1, -5), Position( 0, -6), Position(-1, -6), Position( 0, -7) }, + { Position( 0, -1), Position(-1, 0), Position(-1, -1), Position(-2, 0), Position(-2, -1), Position(-3, 0), Position(-3, -1), Position(-4, 0), Position(-4, -1), Position(-5, 0), Position(-5, -1), Position(-6, 0), Position(-6, -1), Position(-7, 0) }, +}; +#else const Position g_eipFilter[NUM_EIP_SHAPE][EIP_FILTER_TAP] = { { Position(-1, 0), Position(-2, 0), Position(-3, 0), Position( 0, -1), Position(-1, -1), Position(-2, -1), Position(-3, -1), Position( 0, -2), Position(-1, -2), Position(-2, -2), Position(-3, -2), Position( 0, -3), Position(-1, -3), Position(-2, -3), Position(-3, -3) }, { Position(-1, 0), Position( 0, -1), Position(-1, -1), Position( 0, -2), Position(-1, -2), Position( 0, -3), Position(-1, -3), Position( 0, -4), Position(-1, -4), Position( 0, -5), Position(-1, -5), Position( 0, -6), Position(-1, -6), Position( 0, -7), Position(-1, -7) }, { Position( 0, -1), Position(-1, 0), Position(-1, -1), Position(-2, 0), Position(-2, -1), Position(-3, 0), Position(-3, -1), Position(-4, 0), Position(-4, -1), Position(-5, 0), Position(-5, -1), Position(-6, 0), Position(-6, -1), Position(-7, 0), Position(-7, -1) }, }; - -const EIPInfo g_eipInfoLut[4][4][9] = +#endif +const EIPInfo g_eipInfoLut[4][4][9] = { { { EIPInfo(EIP_AL_A_L, EIP_FILTER_S), EIPInfo(EIP_AL_A_L, EIP_FILTER_V), EIPInfo(EIP_AL_A_L, EIP_FILTER_H), EIPInfo(), EIPInfo(), EIPInfo(), EIPInfo(), EIPInfo(), EIPInfo() }, // 4x4, 3modes diff --git a/source/Lib/CommonLib/Rom.h b/source/Lib/CommonLib/Rom.h index 575cf0f82a32bcc4753e746cf9be3c8bef254df0..976e949ab4c90c66ac4902b8365c3487d03c0048 100644 --- a/source/Lib/CommonLib/Rom.h +++ b/source/Lib/CommonLib/Rom.h @@ -447,7 +447,11 @@ extern const int8_t g_amvpSbTmvp_mvd_offset[6]; extern uint32_t g_picAmvpSbTmvpEnabledArea; #endif #if JVET_AG0058_EIP +#if JVET_AH0086_EIP_BIAS_AND_CLIP +extern const Position g_eipFilter[NUM_EIP_SHAPE][EIP_FILTER_TAP - 1]; +#else extern const Position g_eipFilter[NUM_EIP_SHAPE][EIP_FILTER_TAP]; +#endif extern const EIPInfo g_eipInfoLut[4][4][9]; #endif #if JVET_AG0276_LIC_SLOPE_ADJUST diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 9a48f57775bfa9445b07ca0c22eb1e7e425aa23a..e95c92f46b0e434024ef02d9862f73e39d2de677 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -204,6 +204,7 @@ #define JVET_AG0154_DECODER_DERIVED_CCP_FUSION 1 // JVET-AG0154: Decoder derived CCP mode with fusion candidates #define JVET_AG0059_CCP_MERGE_ENHANCEMENT 1 // JVET-AG0059: Enhancements on CCP merge for chroma intra coding #define JVET_AH0065_RELAX_LINE_BUFFER 1 // JVET-AH0065: Relaxing line buffer restriction +#define JVET_AH0086_EIP_BIAS_AND_CLIP 1 // JVET-AH0086: EIP with bias and clipping //IBC #define JVET_Y0058_IBC_LIST_MODIFY 1 // JVET-Y0058: Modifications of IBC merge/AMVP list construction, ARMC-TM-IBC part is included under JVET_W0090_ARMC_TM