diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index ea263a36c68697e97d8fd830d83910f40f74e03b..1e24e4cdb824a6ce6bc2b49fc0f6993ee8ca6001 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -932,6 +932,9 @@ void EncApp::xInitLibCfg() #if JVET_AD0085_MPM_SORTING m_cEncLib.setUseMpmSorting ( m_mpmSorting ); #endif +#if JVET_AH0136_CHROMA_REORDERING + m_cEncLib.setUseChromaReordering (m_chromaReordering); +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING m_cEncLib.setUseCccm ( m_cccm ); #endif diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index d55f74efba6d61908ffa848fbc627bfa5e774807..d8032107fd686efe39aca62eefc471f6a3772748 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1154,6 +1154,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) #if JVET_AD0085_MPM_SORTING ( "MPMSorting", m_mpmSorting, true, "Enable template-based intra MPM list construction\n" ) #endif +#if JVET_AH0136_CHROMA_REORDERING + ("ChromaReordering", m_chromaReordering, true, "Enable template-based intra chroma list reordering\n") +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING ( "CCCM", m_cccm, 2, "CCCM mode (0:off, 1:on, 2:on subsampling and no subsampling) [default: 2]") #endif @@ -4096,6 +4099,13 @@ bool EncAppCfg::xCheckParameter() m_mpmSorting = false; } #endif +#if JVET_AH0136_CHROMA_REORDERING + if (m_chromaReordering) + { + msg(WARNING, "ChromaReordering is forcefully disabled since the enable flag of non-inter-TM tools is set off. \n"); + m_chromaReordering = false; + } +#endif #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS if (m_tmibc) { @@ -5790,6 +5800,9 @@ void EncAppCfg::xPrintParameter() #if JVET_AD0085_MPM_SORTING && !JVET_AE0174_NONINTER_TM_TOOLS_CONTROL msg(VERBOSE, "MPMSorting:%d ", m_mpmSorting); #endif +#if JVET_AH0136_CHROMA_REORDERING && !JVET_AE0174_NONINTER_TM_TOOLS_CONTROL + msg(VERBOSE, "ChromaReordering:%d ", m_chromaReordering); +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING msg(VERBOSE, "CCCM:%d ", m_cccm); #endif @@ -5843,6 +5856,9 @@ void EncAppCfg::xPrintParameter() #if JVET_AD0085_MPM_SORTING msg(VERBOSE, "MPMsorting:%d ", m_mpmSorting); #endif +#if JVET_AH0136_CHROMA_REORDERING + msg(VERBOSE, "ChromaReordering:%d ", m_chromaReordering); +#endif #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS msg(VERBOSE, "TM-IBC:%d ", m_tmibc); #endif diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 5b2b551ed988340459efa8f0e43d963d729b2cde..dc8a06a036134f157de7739e160dc8c15c53d0e1 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -502,6 +502,9 @@ protected: #if JVET_AD0085_MPM_SORTING bool m_mpmSorting; #endif +#if JVET_AH0136_CHROMA_REORDERING + bool m_chromaReordering; +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING int m_cccm; #endif diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 03f4a55ab0b4cf650bc2ef122b3a127d76fb7119..f3d49686ca1cd2932392cd7bb777a78f3b169c9a 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -663,8 +663,24 @@ static const int MDLM_T_IDX = LM_CHROMA_IDX + 2; ///< M #if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD static const int DIMD_CHROMA_IDX = NUM_INTRA_MODE; ///< chroma mode index for derived by DIMD method #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING +static const int DBV_CHROMA_IDX = NUM_INTRA_MODE + 1; +static const int DBV_CHROMA_IDX1 = NUM_INTRA_MODE + 2; +static const int DBV_CHROMA_IDX2 = NUM_INTRA_MODE + 3; +static const int DBV_CHROMA_IDX3 = NUM_INTRA_MODE + 4; +static const int DBV_CHROMA_IDX4 = NUM_INTRA_MODE + 5; +static const int DBV_CHROMA_IDX5 = NUM_INTRA_MODE + 6; +static const int DBV_CHROMA_IDX6 = NUM_INTRA_MODE + 7; +static const int DBV_CHROMA_IDX7 = NUM_INTRA_MODE + 8; +static const int DBV_CHROMA_IDX8 = NUM_INTRA_MODE + 9; +static const int DBV_CHROMA_IDX9 = NUM_INTRA_MODE + 10; +static const int DM_CHROMA_IDX = NUM_INTRA_MODE + 11; ///< chroma mode index for derived from luma intra mode +static const int NUM_CHROMA_TM_LINES_IN_REORDERING = 1; +static const int NUM_CHROMA_LIST_MODE = 7 + 4 + 5 + 10; /// 7 orginal modes + 4 collocated modes + 5 neighboring modes + 10 DBV modes +#else static const int DBV_CHROMA_IDX = NUM_INTRA_MODE + 1; static const int DM_CHROMA_IDX = NUM_INTRA_MODE + 2; ///< chroma mode index for derived from luma intra mode +#endif #else static const int DM_CHROMA_IDX = NUM_INTRA_MODE + 1; ///< chroma mode index for derived from luma intra mode #endif diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h index 2b58835eee88b72000b82a5d53b2150c8191e915..dab3c18766aad92d2783479b8cac4027da80cfae 100644 --- a/source/Lib/CommonLib/ContextModelling.h +++ b/source/Lib/CommonLib/ContextModelling.h @@ -72,13 +72,22 @@ public: static inline bool getSwitchCondition(const CodingUnit &cu,ChannelType channelType) { bool condition = cu.predMode == MODE_INTRA && cu.slice->getSliceType() != I_SLICE && - ((!cu.tmpFlag && channelType == CHANNEL_TYPE_LUMA)||(channelType == CHANNEL_TYPE_CHROMA && cu.firstPU->intraDir[1] != DBV_CHROMA_IDX)); + ((!cu.tmpFlag && channelType == CHANNEL_TYPE_LUMA)||(channelType == CHANNEL_TYPE_CHROMA +#if JVET_AH0136_CHROMA_REORDERING + && !(cu.firstPU->intraDir[1] >= DBV_CHROMA_IDX && cu.firstPU->intraDir[1] <= DBV_CHROMA_IDX9) +#else + && cu.firstPU->intraDir[1] != DBV_CHROMA_IDX +#endif + )); assert(cu.slice->getSliceType() != I_SLICE || channelType == cu.chType); int tmpMaxSize = cu.cs->sps->getIntraTMPMaxSize(); condition = condition || (cu.predMode == MODE_IBC && channelType == CHANNEL_TYPE_LUMA && cu.slice->getSliceType() == I_SLICE) || (cu.predMode == MODE_INTRA && ((channelType == CHANNEL_TYPE_LUMA && cu.tmpFlag && !cu.bdpcmMode && !cu.dimd - && cu.lwidth() <= tmpMaxSize && cu.lheight() <= tmpMaxSize) || - (channelType == CHANNEL_TYPE_CHROMA && cu.firstPU->intraDir[1] == DBV_CHROMA_IDX)) && cu.slice->getSliceType() == I_SLICE); + && cu.lwidth() <= tmpMaxSize && cu.lheight() <= tmpMaxSize) +#if !JVET_AH0136_CHROMA_REORDERING + || (channelType == CHANNEL_TYPE_CHROMA && cu.firstPU->intraDir[1] == DBV_CHROMA_IDX) +#endif + ) && cu.slice->getSliceType() == I_SLICE); return condition; } #endif diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index d29044c58b0a54209b9ce73ba88874c607d86c91..6aa0217fd4fbf39feb0461079957a661fcbab647 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -4371,7 +4371,11 @@ void IntraPrediction::generateDimdBlending(PelBuf &piPred, const PredictionUnit #if JVET_Z0050_DIMD_CHROMA_FUSION #if JVET_AD0188_CCP_MERGE -void IntraPrediction::geneChromaFusionPred( const ComponentID compId, PelBuf &piPred, PredictionUnit &pu ) +void IntraPrediction::geneChromaFusionPred( const ComponentID compId, PelBuf &piPred, PredictionUnit &pu +#if JVET_AH0136_CHROMA_REORDERING + , InterPrediction *pcInterPred +#endif +) #else void IntraPrediction::geneChromaFusionPred(const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu) #endif @@ -4406,9 +4410,19 @@ void IntraPrediction::geneChromaFusionPred(const ComponentID compId, PelBuf &piP pu2.intraDir[1] = LM_CHROMA_IDX + pu.isChromaFusion - 2; if (!pu.cs->pcv->isEncoder || !pu2.cs->slice->isIntra() || !CS::isDualITree(*pu.cs)) { +#if JVET_AH0136_CHROMA_REORDERING + xCflmCreateChromaPred(pu, compId, piPred, pcInterPred); +#else xCflmCreateChromaPred(pu, compId, piPred); +#endif } predIntraChromaLM(compId, piPred, pu2, area, pu2.intraDir[1]); +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (PU::isDbvMode(pu.intraDir[1]) && pu.cu->rribcFlipType != 0) + { + piPred.flipSignal(pu.cu->rribcFlipType == 1); + } +#endif return; } #endif @@ -4516,7 +4530,11 @@ void IntraPrediction::geneChromaFusionPred(const ComponentID compId, PelBuf &piP #endif #if JVET_AC0071_DBV && JVET_AA0070_RRIBC +#if JVET_AH0136_CHROMA_REORDERING + if (PU::isDbvMode(pu.intraDir[1]) && pu.cu->rribcFlipType != 0) +#else if (pu.intraDir[1] == DBV_CHROMA_IDX && pu.cu->rribcFlipType != 0) +#endif { predLmBuffer.flipSignal(pu.cu->rribcFlipType == 1); } @@ -5712,6 +5730,282 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf } } +#if JVET_AH0136_CHROMA_REORDERING +void IntraPrediction::xFillReferenceSamplesForCoLuma(const CPelBuf &recoBuf, Pel* refBufUnfiltered, const CompArea &area, const CodingUnit &cu) +{ + const ChannelType chType = toChannelType(area.compID); + const CodingStructure &cs = *cu.cs; + const SPS &sps = *cs.sps; + const PreCalcValues &pcv = *cs.pcv; + + const int multiRefIdx = 0; + + const int tuWidth = area.width; + const int tuHeight = area.height; + const int predSize = m_topRefLength; + const int predHSize = m_leftRefLength; + const int predStride = predSize + 1 + multiRefIdx; + m_refBufferStride[area.compID] = predStride; + + const bool noShift = pcv.noChroma2x2 && area.width == 4; // don't shift on the lowest level (chroma not-split) + const int unitWidth = tuWidth <= 2 && cu.ispMode && isLuma(area.compID) ? tuWidth : pcv.minCUWidth >> (noShift ? 0 : getComponentScaleX(area.compID, sps.getChromaFormatIdc())); + const int unitHeight = tuHeight <= 2 && cu.ispMode && isLuma(area.compID) ? tuHeight : pcv.minCUHeight >> (noShift ? 0 : getComponentScaleY(area.compID, sps.getChromaFormatIdc())); + + const int totalAboveUnits = (predSize + (unitWidth - 1)) / unitWidth; + const int totalLeftUnits = (predHSize + (unitHeight - 1)) / unitHeight; + const int totalUnits = totalAboveUnits + totalLeftUnits + 1; //+1 for top-left + + const int numAboveUnits = std::max<int>(tuWidth / unitWidth, 1); + const int numLeftUnits = std::max<int>(tuHeight / unitHeight, 1); + const int numAboveRightUnits = totalAboveUnits - numAboveUnits; + const int numLeftBelowUnits = totalLeftUnits - numLeftUnits; + + CHECK(numAboveUnits <= 0 || numLeftUnits <= 0 || numAboveRightUnits <= 0 || numLeftBelowUnits <= 0, "Size not supported"); + + // ----- Step 1: analyze neighborhood ----- + bool neighborFlags[4 * MAX_NUM_PART_IDXS_IN_CTU_WIDTH + 1]; + int numIntraNeighbor = 0; + + memset(neighborFlags, 0, totalUnits); + + neighborFlags[totalLeftUnits] = area.x > 0 && area.y > 0; + numIntraNeighbor += neighborFlags[totalLeftUnits] ? 1 : 0; + numIntraNeighbor += area.y > 0 ? numAboveUnits : 0; + for (int i = totalLeftUnits + 1; i < totalLeftUnits + 1 + numAboveUnits; i++) + { + neighborFlags[i] = area.y > 0 ? true : false; + } + int picWidth = sps.getMaxPicWidthInLumaSamples(); + int ctuWidth = sps.getCTUSize(); + int ctuWidthInNum = area.x / ctuWidth; + int wUnit = std::min((picWidth - area.x - tuWidth) / unitWidth, ((ctuWidthInNum + 1) * ctuWidth - area.x - tuWidth) / unitWidth); + numIntraNeighbor += area.y > 0 ? std::min(numAboveRightUnits, wUnit) : 0; + for (int i = totalLeftUnits + 1 + numAboveUnits; i < totalLeftUnits + 1 + numAboveUnits + numAboveRightUnits; i++) + { + neighborFlags[i] = area.y > 0 ? ( i - (totalLeftUnits + 1 + numAboveUnits) < wUnit ? true : false) : false; + } + numIntraNeighbor += area.x > 0 ? numLeftUnits : 0; + for (int i = totalLeftUnits - 1; i > totalLeftUnits - 1 - numLeftUnits; i--) + { + neighborFlags[i] = area.x > 0 ? true : false; + } + int picHeight = sps.getMaxPicHeightInLumaSamples(); + int ctuHeight = sps.getCTUSize(); + int ctuHeightInNum = area.y / ctuHeight; + int hUnit = std::min((picHeight - area.y - tuHeight) / unitHeight, ((ctuHeightInNum + 1) * ctuHeight - area.y - tuHeight) / unitHeight); + numIntraNeighbor += area.x > 0 ? std::min(numLeftBelowUnits, hUnit) : 0; + int y = 0; + for (int i = totalLeftUnits - 1 - numLeftUnits; i > totalLeftUnits - 1 - numLeftUnits - numLeftBelowUnits; i--) + { + neighborFlags[i] = area.x > 0 ? (y < hUnit ? true : false) : false; + y++; + } + + // ----- Step 2: fill reference samples (depending on neighborhood) ----- + + const Pel* srcBuf = recoBuf.buf; + const int srcStride = recoBuf.stride; + Pel* ptrDst = refBufUnfiltered; + const Pel* ptrSrc; + const Pel valueDC = 1 << (sps.getBitDepth(chType) - 1); + + if (numIntraNeighbor == 0) + { + // Fill border with DC value + for (int j = 0; j <= predSize + multiRefIdx; j++) + { + ptrDst[j] = valueDC; + } + for (int i = 0; i <= predHSize + multiRefIdx; i++) + { + ptrDst[i + predStride] = valueDC; + } + } + else if (numIntraNeighbor == totalUnits) + { + // Fill top-left border and top and top right with rec. samples + ptrSrc = srcBuf - (1 + multiRefIdx) * srcStride - (1 + multiRefIdx); + + std::memcpy(ptrDst, ptrSrc, sizeof(*ptrDst) * (predSize + multiRefIdx + 1)); + + for (int i = 0; i <= predHSize + multiRefIdx; i++) + { + ptrDst[i + predStride] = ptrSrc[i * srcStride]; + } + } + else // reference samples are partially available + { + // Fill top-left sample(s) if available + ptrSrc = srcBuf - (1 + multiRefIdx) * srcStride - (1 + multiRefIdx); + ptrDst = refBufUnfiltered; + if (neighborFlags[totalLeftUnits]) + { + ptrDst[0] = ptrSrc[0]; + ptrDst[predStride] = ptrSrc[0]; + for (int i = 1; i <= multiRefIdx; i++) + { + ptrDst[i] = ptrSrc[i]; + ptrDst[i + predStride] = ptrSrc[i * srcStride]; + } + } + + // Fill left & below-left samples if available (downwards) + ptrSrc += (1 + multiRefIdx) * srcStride; + ptrDst += (1 + multiRefIdx) + predStride; + for (int unitIdx = totalLeftUnits - 1; unitIdx > 0; unitIdx--) + { + if (neighborFlags[unitIdx]) + { + for (int i = 0; i < unitHeight; i++) + { + ptrDst[i] = ptrSrc[i * srcStride]; + } + } + ptrSrc += unitHeight * srcStride; + ptrDst += unitHeight; + } + // Fill last below-left sample(s) + if (neighborFlags[0]) + { + int lastSample = (predHSize % unitHeight == 0) ? unitHeight : predHSize % unitHeight; + for (int i = 0; i < lastSample; i++) + { + ptrDst[i] = ptrSrc[i * srcStride]; + } + } + + // Fill above & above-right samples if available (left-to-right) + ptrSrc = srcBuf - srcStride * (1 + multiRefIdx); + ptrDst = refBufUnfiltered + 1 + multiRefIdx; + for (int unitIdx = totalLeftUnits + 1; unitIdx < totalUnits - 1; unitIdx++) + { + if (neighborFlags[unitIdx]) + { + for (int j = 0; j < unitWidth; j++) + { + ptrDst[j] = ptrSrc[j]; + } + } + ptrSrc += unitWidth; + ptrDst += unitWidth; + } + // Fill last above-right sample(s) + if (neighborFlags[totalUnits - 1]) + { + int lastSample = (predSize % unitWidth == 0) ? unitWidth : predSize % unitWidth; + for (int j = 0; j < lastSample; j++) + { + ptrDst[j] = ptrSrc[j]; + } + } + + // pad from first available down to the last below-left + ptrDst = refBufUnfiltered; + int lastAvailUnit = 0; + if (!neighborFlags[0]) + { + int firstAvailUnit = 1; + while (firstAvailUnit < totalUnits && !neighborFlags[firstAvailUnit]) + { + firstAvailUnit++; + } + + // first available sample + int firstAvailRow = -1; + int firstAvailCol = 0; + + if (firstAvailUnit < totalLeftUnits) + { + firstAvailRow = (totalLeftUnits - firstAvailUnit) * unitHeight + multiRefIdx; + } + else if (firstAvailUnit == totalLeftUnits) + { + firstAvailRow = multiRefIdx; + } + else + { + firstAvailCol = (firstAvailUnit - totalLeftUnits - 1) * unitWidth + 1 + multiRefIdx; + } + + const Pel firstAvailSample = ptrDst[firstAvailRow < 0 ? firstAvailCol : firstAvailRow + predStride]; + + // last sample below-left (n.a.) + int lastRow = predHSize + multiRefIdx; + + // fill left column + for (int i = lastRow; i > firstAvailRow; i--) + { + ptrDst[i + predStride] = firstAvailSample; + } + // fill top row + if (firstAvailCol > 0) + { + for (int j = 0; j < firstAvailCol; j++) + { + ptrDst[j] = firstAvailSample; + } + } + lastAvailUnit = firstAvailUnit; + } + + // pad all other reference samples. + int currUnit = lastAvailUnit + 1; + while (currUnit < totalUnits) + { + if (!neighborFlags[currUnit]) // samples not available + { + // last available sample + int lastAvailRow = -1; + int lastAvailCol = 0; + if (lastAvailUnit < totalLeftUnits) + { + lastAvailRow = (totalLeftUnits - lastAvailUnit - 1) * unitHeight + multiRefIdx + 1; + } + else if (lastAvailUnit == totalLeftUnits) + { + lastAvailCol = multiRefIdx; + } + else + { + lastAvailCol = (lastAvailUnit - totalLeftUnits) * unitWidth + multiRefIdx; + } + const Pel lastAvailSample = ptrDst[lastAvailRow < 0 ? lastAvailCol : lastAvailRow + predStride]; + + // fill current unit with last available sample + if (currUnit < totalLeftUnits) + { + for (int i = lastAvailRow - 1; i >= lastAvailRow - unitHeight; i--) + { + ptrDst[i + predStride] = lastAvailSample; + } + } + else if (currUnit == totalLeftUnits) + { + for (int i = 0; i < multiRefIdx + 1; i++) + { + ptrDst[i + predStride] = lastAvailSample; + } + for (int j = 0; j < multiRefIdx + 1; j++) + { + ptrDst[j] = lastAvailSample; + } + } + else + { + int numSamplesInUnit = (currUnit == totalUnits - 1) ? ((predSize % unitWidth == 0) ? unitWidth : predSize % unitWidth) : unitWidth; + for (int j = lastAvailCol + 1; j <= lastAvailCol + numSamplesInUnit; j++) + { + ptrDst[j] = lastAvailSample; + } + } + } + lastAvailUnit = currUnit; + currUnit++; + } + } +} +#endif + void IntraPrediction::xFilterReferenceSamples(const Pel *refBufUnfiltered, Pel *refBufFiltered, const CompArea &area, const SPS &sps, int multiRefIdx) { @@ -9846,61 +10140,946 @@ void IntraPrediction::deriveDimdChromaMode(const CPelBuf &recoBufY, const CPelBu #if !JVET_AC0094_REF_SAMPLES_OPT buildHistogram(pRecoAboveY, iStrideY, 1, uiWidthAboveY, piHistogram, 2, uiWidthY, uiHeightY); #endif - buildHistogram(pRecoAboveCb, iStrideCb, 1, uiWidthAboveC, piHistogram, 2, uiWidthCb, uiHeightCb); - buildHistogram(pRecoAboveCr, iStrideCr, 1, uiWidthAboveC, piHistogram, 2, uiWidthCr, uiHeightCr); - } - if (numIntraLeft && numIntraAbove) - { -#if !JVET_AC0094_REF_SAMPLES_OPT - const Pel *pRecoAboveLeftY = pRecoY - 2 - iStrideY * 2; + buildHistogram(pRecoAboveCb, iStrideCb, 1, uiWidthAboveC, piHistogram, 2, uiWidthCb, uiHeightCb); + buildHistogram(pRecoAboveCr, iStrideCr, 1, uiWidthAboveC, piHistogram, 2, uiWidthCr, uiHeightCr); + } + if (numIntraLeft && numIntraAbove) + { +#if !JVET_AC0094_REF_SAMPLES_OPT + const Pel *pRecoAboveLeftY = pRecoY - 2 - iStrideY * 2; +#endif + const Pel *pRecoAboveLeftCb = pRecoCb - 2 - iStrideCb * 2; + const Pel *pRecoAboveLeftCr = pRecoCr - 2 - iStrideCr * 2; +#if !JVET_AC0094_REF_SAMPLES_OPT + buildHistogram(pRecoAboveLeftY, iStrideY, 2, 2, piHistogram, 3, uiWidthY, uiHeightY); +#endif + buildHistogram(pRecoAboveLeftCb, iStrideCb, 2, 2, piHistogram, 3, uiWidthCb, uiHeightCb); + buildHistogram(pRecoAboveLeftCr, iStrideCr, 2, 2, piHistogram, 3, uiWidthCr, uiHeightCr); + } + + int firstAmp = 0, secondAmp = 0, curAmp = 0; + int firstMode = 0, secondMode = 0, curMode = 0; + + for (int i = 0; i < NUM_LUMA_MODE; i++) + { + curAmp = piHistogram[i]; + curMode = i; + if (curAmp > firstAmp) + { + secondAmp = firstAmp; + secondMode = firstMode; + firstAmp = curAmp; + firstMode = curMode; + } + else + { + if (curAmp > secondAmp) + { + secondAmp = curAmp; + secondMode = curMode; + } + } + } + + cu.dimdChromaMode = firstMode; +#if JVET_AC0094_REF_SAMPLES_OPT + cu.dimdChromaModeSecond = secondMode; +#else + int dmMode = PU::getCoLocatedIntraLumaMode(*cu.firstPU); + if (dmMode == firstMode) + { + cu.dimdChromaMode = secondMode; + if (firstMode == secondMode) + { + cu.dimdChromaMode = DC_IDX; + } + } +#endif + +#if JVET_AH0136_CHROMA_REORDERING + if (CS::isDualITree(*cu.cs) && cu.cs->sps->getUseChromaReordering()) + { + int amp[DIMD_FUSION_NUM - 1] = { 0 }; + curAmp = 0; + int mode[DIMD_FUSION_NUM - 1] = { 0 }; + curMode = 0; + for (int i = 0; i < NUM_LUMA_MODE; i++) + { + curAmp = piHistogram[i]; + curMode = i; + for (int j = 0; j < DIMD_FUSION_NUM - 1; j++) + { + if (curAmp > amp[j]) + { + for (int k = DIMD_FUSION_NUM - 2; k > j; k--) + { + amp[k] = amp[k - 1]; + mode[k] = mode[k - 1]; + } + amp[j] = curAmp; + mode[j] = curMode; + break; + } + } + } + + for (int i = 0; i < 5; i++) + { + cu.dimdBlendModeChroma[i] = mode[i]; + } + } +#endif +} +#endif + +#if JVET_AH0136_CHROMA_REORDERING +void IntraPrediction::deriveNonCcpChromaModes(const CPelBuf &recoBufY, const CPelBuf &recoBufCb, const CPelBuf &recoBufCr, const CompArea &areaY, const CompArea &areaCb, const CompArea &areaCr, CodingUnit &cu, PredictionUnit &pu, InterPrediction *pcInterPred) +{ + if (!CS::isDualITree(*pu.cs) || !pu.cs->sps->getUseChromaReordering()) + { + return; + } + + // save original info + int intraDir = pu.intraDir[1]; + + // construct collocated luma area + UnitArea area(CHROMA_420, areaY); + CodingUnit lumaCU(area); + PredictionUnit lumaPU(area); + lumaPU.cu = &lumaCU; + lumaCU.firstPU = &lumaPU; + lumaCU.cs = cu.cs; + lumaPU.cs = pu.cs; + lumaCU.slice = cu.slice; + + // derive DBV info +#if JVET_AC0071_DBV + PU::deriveChromaBv(pu); +#endif + + // build input list + static_vector<uint8_t, NUM_CHROMA_LIST_MODE> uiModeList; + static_vector<Distortion, NUM_CHROMA_LIST_MODE> uiCostList; + uint8_t chromaList[NUM_CHROMA_LIST_MODE]; + int existNum = 0; + bool hasDBV = false; + buildChromaModeList(areaCb, cu, pu, chromaList, existNum, hasDBV); + + // prepare luma pred indfo + int width = areaY.width; + int height = areaY.height; + const UnitArea localUnitAreaLuma(CHROMA_420, Area(0, 0, width, height)); + PelBuf predY = m_tempBuffer[0].getBuf(localUnitAreaLuma.Y()); + DistParam cDistParamSatd; + m_timdSatdCost->setDistParam(cDistParamSatd, recoBufY, predY, pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, true); + cDistParamSatd.applyWeight = false; + cDistParamSatd.useMR = false; + + // prepare chroma pred info + int line = NUM_CHROMA_TM_LINES_IN_REORDERING; + const UnitArea localUnitAreaChroma(CHROMA_420, Area(0, 0, width + line * 2, height + line * 2)); + PelBuf predCb = m_tempBuffer[0].getBuf(localUnitAreaChroma.Cb()); + PelBuf predCr = m_tempBuffer[0].getBuf(localUnitAreaChroma.Cr()); + int iRefX = 0; + int iRefY = 0; + uint32_t uiRefWidth = 0; + uint32_t uiRefHeight = 0; + TemplateType eTplType = CU::deriveTimdRefType(areaCb.x, areaCb.y, areaCb.width, areaCb.height, line, line, iRefX, iRefY, uiRefWidth, uiRefHeight); + const Pel* piCb = recoBufCb.buf; + int iCbStride = recoBufCb.stride; + piCb += (iRefY - areaCb.y) * iCbStride + (iRefX - areaCb.x); + const Pel* piCr = recoBufCr.buf; + int iCrStride = recoBufCr.stride; + piCr += (iRefY - areaCr.y) * iCrStride + (iRefX - areaCr.x); + const int channelBitDepth = pu.cu->cs->sps->getBitDepth(toChannelType(COMPONENT_Cb)); + DistParam distParamSatd[2][2]; // above, left + distParamSatd[0][0].applyWeight = false; + distParamSatd[0][0].useMR = false; + distParamSatd[0][1].applyWeight = false; + distParamSatd[0][1].useMR = false; + distParamSatd[1][0].applyWeight = false; + distParamSatd[1][0].useMR = false; + distParamSatd[1][1].applyWeight = false; + distParamSatd[1][1].useMR = false; + if (eTplType == LEFT_ABOVE_NEIGHBOR) + { + m_timdSatdCost->setTimdDistParam(distParamSatd[0][0], piCb + line, predCb.buf + line, iCbStride, predCb.stride, channelBitDepth, COMPONENT_Cb, areaCb.width, line, 0, 1, false); + m_timdSatdCost->setTimdDistParam(distParamSatd[0][1], piCb + line * iCbStride, predCb.buf + line * predCb.stride, iCbStride, predCb.stride, channelBitDepth, COMPONENT_Cb, line, areaCb.height, 0, 1, false); + m_timdSatdCost->setTimdDistParam(distParamSatd[1][0], piCr + line, predCr.buf + line, iCrStride, predCr.stride, channelBitDepth, COMPONENT_Cr, areaCr.width, line, 0, 1, false); + m_timdSatdCost->setTimdDistParam(distParamSatd[1][1], piCr + line * iCrStride, predCr.buf + line * predCr.stride, iCrStride, predCr.stride, channelBitDepth, COMPONENT_Cr, line, areaCr.height, 0, 1, false); + } + else if (eTplType == LEFT_NEIGHBOR) + { + m_timdSatdCost->setTimdDistParam(distParamSatd[0][1], piCb, predCb.buf, iCbStride, predCb.stride, channelBitDepth, COMPONENT_Cb, line, areaCb.height, 0, 1, false); + m_timdSatdCost->setTimdDistParam(distParamSatd[1][1], piCr, predCr.buf, iCrStride, predCr.stride, channelBitDepth, COMPONENT_Cr, line, areaCr.height, 0, 1, false); + } + else if (eTplType == ABOVE_NEIGHBOR) + { + m_timdSatdCost->setTimdDistParam(distParamSatd[0][0], piCb, predCb.buf, iCbStride, predCb.stride, channelBitDepth, COMPONENT_Cb, areaCb.width, line, 0, 1, false); + m_timdSatdCost->setTimdDistParam(distParamSatd[1][0], piCr, predCr.buf, iCrStride, predCr.stride, channelBitDepth, COMPONENT_Cr, areaCr.width, line, 0, 1, false); + } + + // early termination based on the first two costs + Distortion costPre[2] = { 0 }; + int modePre[2] = { PLANAR_IDX }; + int logW = floorLog2(areaCb.width); + int logH = floorLog2(areaCb.height); + int logN = floorLog2(NUM_CHROMA_TM_LINES_IN_REORDERING); + + for (int i = 0; i < 2; i++) + { + int x = i; + if (hasDBV) + { + x = i == 0 ? 16 : 0; + } + + Distortion cost = 0; + Distortion costL = 0; + Distortion costCbA = 0; + Distortion costCbL = 0; + Distortion costCrA = 0; + Distortion costCrL = 0; + bool isBad = false; + + // pred co-located luma area + predCoLuma(areaY, recoBufY, lumaPU, chromaList[x], predY, pcInterPred, cu); + + if (PU::isDbvMode(chromaList[x])) + { + int idx = chromaList[x] - DBV_CHROMA_IDX; + if (cu.mvs[idx] == Mv()) + { + isBad = true; + } + } + costL += cDistParamSatd.distFunc(cDistParamSatd); + pu.intraDir[1] = chromaList[x]; + if (eTplType != NO_NEIGHBOR) + { + // pred chroma TM + predChromaTM(areaCb, areaCr, pu, chromaList[x], predCb, predCr, eTplType, pcInterPred); + if (eTplType == LEFT_ABOVE_NEIGHBOR) + { + costCbA += distParamSatd[0][0].distFunc(distParamSatd[0][0]); + costCbL += distParamSatd[0][1].distFunc(distParamSatd[0][1]); + costCrA += distParamSatd[1][0].distFunc(distParamSatd[1][0]); + costCrL += distParamSatd[1][1].distFunc(distParamSatd[1][1]); + cost = 8 * costL + ((costCbA + costCrA) << (logH + 2 - logN)) + ((costCbL + costCrL) << (logW + 2 - logN)); + } + else if (eTplType == LEFT_NEIGHBOR) + { + costCbL += distParamSatd[0][1].distFunc(distParamSatd[0][1]); + costCrL += distParamSatd[1][1].distFunc(distParamSatd[1][1]); + cost = 8 * costL + ((costCbL + costCrL) << (logW + 2 - logN)); + } + else if (eTplType == ABOVE_NEIGHBOR) + { + costCbA += distParamSatd[0][0].distFunc(distParamSatd[0][0]); + costCrA += distParamSatd[1][0].distFunc(distParamSatd[1][0]); + cost = 8 * costL + ((costCbA + costCrA) << (logH + 2 - logN)); + } + else + { + assert(0); + } + } + else + { + cost = costL; + } + + pu.intraDir[1] = intraDir; + + if (isBad) + { + cost = MAX_INT; + } + costPre[i] = cost; + modePre[i] = chromaList[x]; + } + if (costPre[0] < costPre[1]) + { +#if JVET_AC0071_DBV + if (hasDBV) + { + for (uint32_t i = existNum - 1; i > 0; i--) + { + chromaList[i] = chromaList[i - 1]; + } + chromaList[0] = DBV_CHROMA_IDX; + } +#endif + for (uint32_t i = 0; i < existNum; i++) + { + cu.chromaList[i] = chromaList[i]; + } + return; + } + + for (int x = 0; x < NUM_CHROMA_LIST_MODE; x++) + { + if (chromaList[x] > DM_CHROMA_IDX) + { + continue; + } + if (chromaList[x] == modePre[0] || chromaList[x] == modePre[1]) + { + updateCandList(chromaList[x], chromaList[x] == modePre[0] ? costPre[0] : costPre[1], uiModeList, uiCostList, existNum); + continue; + } + Distortion cost = 0; + + Distortion costL = 0; + Distortion costCbA = 0; + Distortion costCbL = 0; + Distortion costCrA = 0; + Distortion costCrL = 0; + bool isBad = false; + + // pred co-located luma area + predCoLuma(areaY, recoBufY, lumaPU, chromaList[x], predY, pcInterPred, cu); + +#if JVET_AC0071_DBV + if (PU::isDbvMode(chromaList[x])) + { + int idx = chromaList[x] - DBV_CHROMA_IDX; + if (cu.mvs[idx] == Mv()) + { + isBad = true; + } + } +#endif + + costL += cDistParamSatd.distFunc(cDistParamSatd); + + pu.intraDir[1] = chromaList[x]; + if (eTplType != NO_NEIGHBOR) + { + // pred chroma TM + predChromaTM(areaCb, areaCr, pu, chromaList[x], predCb, predCr, eTplType, pcInterPred); + + if (eTplType == LEFT_ABOVE_NEIGHBOR) + { + costCbA += distParamSatd[0][0].distFunc(distParamSatd[0][0]); + costCbL += distParamSatd[0][1].distFunc(distParamSatd[0][1]); + + costCrA += distParamSatd[1][0].distFunc(distParamSatd[1][0]); + costCrL += distParamSatd[1][1].distFunc(distParamSatd[1][1]); + cost = 8 * costL + ((costCbA + costCrA) << (logH + 2 - logN)) + ((costCbL + costCrL) << (logW + 2 - logN)); + } + else if (eTplType == LEFT_NEIGHBOR) + { + costCbL += distParamSatd[0][1].distFunc(distParamSatd[0][1]); + costCrL += distParamSatd[1][1].distFunc(distParamSatd[1][1]); + cost = 8 * costL + ((costCbL + costCrL) << (logW + 2 - logN)); + } + else if (eTplType == ABOVE_NEIGHBOR) + { + costCbA += distParamSatd[0][0].distFunc(distParamSatd[0][0]); + costCrA += distParamSatd[1][0].distFunc(distParamSatd[1][0]); + cost = 8 * costL + ((costCbA + costCrA) << (logH + 2 - logN)); + } + else + { + assert(0); + } + } + else + { + cost = costL; + } + + pu.intraDir[1] = intraDir; + + if (isBad) + { + cost = MAX_INT; + } + + updateCandList(chromaList[x], cost, uiModeList, uiCostList, existNum); + } + + for (uint32_t i = 0; i < existNum; i++) + { + cu.chromaList[i] = uiModeList[i]; + } + + // reste chroma mode + pu.intraDir[1] = intraDir; +} + +void IntraPrediction::buildChromaModeList(const CompArea &area, CodingUnit &cu, PredictionUnit &pu, uint8_t chromaList[NUM_CHROMA_LIST_MODE], int &existNum, bool &hasDBV) +{ + // initialization + for (int i = 0; i < NUM_CHROMA_LIST_MODE; i++) + { + chromaList[i] = 255; + } + + // get the orginal chroma mode list + int dmMode = PU::getCoLocatedIntraLumaMode(pu); + int startNum = 0; +#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD + if (cu.slice->getSPS()->getUseDimd()) + { + int dimdMode = cu.dimdChromaMode; + if (cu.dimdChromaMode == dmMode || cu.dimdChromaMode == HOR_IDX || cu.dimdChromaMode == VER_IDX) + { + int i = 1; + for (; i < 5; i++) + { + if (cu.dimdBlendModeChroma[i] == dmMode || cu.dimdBlendModeChroma[i] == HOR_IDX || cu.dimdBlendModeChroma[i] == VER_IDX) + { + continue; + } + break; + } + dimdMode = (i == 5) ? DC_IDX : cu.dimdBlendModeChroma[i]; + } + chromaList[0] = dmMode; + chromaList[1] = dimdMode; + chromaList[2] = PLANAR_IDX; + chromaList[3] = DC_IDX; + chromaList[4] = HOR_IDX; + chromaList[5] = VER_IDX; + existNum = 6; + startNum = 2; + } + else +#endif + { + chromaList[0] = dmMode; + chromaList[1] = PLANAR_IDX; + chromaList[2] = DC_IDX; + chromaList[3] = HOR_IDX; + chromaList[4] = VER_IDX; + existNum = 5; + startNum = 1; + } + bool hasMode[NUM_LUMA_MODE] = { false }; + for (int i = startNum; i < existNum; i++) + { + if (chromaList[i] == dmMode) + { + chromaList[i] = VDIA_IDX; + } + } + for (int i = 0; i < existNum; i++) + { + hasMode[chromaList[i]] = true; + } + + int addNum = 0; + // get co-located luma modes + CompArea lumaArea = CompArea(COMPONENT_Y, pu.chromaFormat, pu.Cb().lumaPos(), recalcSize(pu.chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, pu.Cb().size())); + lumaArea = clipArea(lumaArea, pu.cs->picture->block(COMPONENT_Y)); + + Position posList[5] = { lumaArea.center(), lumaArea.topLeft(), lumaArea.topRight(), lumaArea.bottomLeft(), lumaArea.bottomRight() }; + for (int n = 0; n < NUM_DBV_POSITION; n++) + { + const PredictionUnit *lumaPU = pu.cs->picture->cs->getPU(posList[n], CHANNEL_TYPE_LUMA); + int mode; + if (lumaPU->cu->timd || lumaPU->cu->tmrlFlag) + { + mode = MAP131TO67(PU::getIntraDirLuma(*lumaPU, 0)); + } + else + { + mode = PU::getIntraDirLuma(*lumaPU, 0); + } + if (hasMode[mode] == false) + { + chromaList[6 + addNum] = mode; + hasMode[mode] = true; + addNum++; + } + } + + // get neighboring modes + const Position posCand[5] = + { + pu.chromaPos().offset(-1, area.height - 1), + pu.chromaPos().offset(area.width - 1, -1), + pu.chromaPos().offset(-1, area.height), + pu.chromaPos().offset(area.width, -1), + pu.chromaPos().offset(-1, -1) + }; + + for (const Position &posLT : posCand) + { + const PredictionUnit* puRef = PU::getPUFromPos(pu, CHANNEL_TYPE_CHROMA, posLT); + if (puRef != nullptr && CU::isIntra(*puRef->cu) && !PU::isLMCMode(puRef->intraDir[1]) && !PU::isDbvMode(puRef->intraDir[1])) + { + int mode; + mode = puRef->intraDir[1]; + if (hasMode[mode] == false) + { + chromaList[6 + addNum] = mode; + hasMode[mode] = true; + addNum++; + } + } + } + +#if JVET_AC0071_DBV + if (PU::hasChromaBvFlag(pu)) + { + chromaList[16] = DBV_CHROMA_IDX; + existNum++; + hasDBV = true; + if (cu.mvsNum > 1) + { + for (int i = NUM_CHROMA_LIST_MODE - 9, j = 0; i < NUM_CHROMA_LIST_MODE && j < cu.mvsNum - 1; i++, j++) + { + chromaList[i] = DBV_CHROMA_IDX1 + j; + } + } + } +#endif +} + +void IntraPrediction::predCoLuma(const CompArea &area, const CPelBuf &recoBuf, PredictionUnit &pu, uint8_t predMode, PelBuf predBuf, InterPrediction *pcInterPred, CodingUnit &chromaCu) +{ + pu.intraDir[0] = predMode; + +#if JVET_AC0071_DBV + if (PU::isDbvMode(predMode)) + { + pu.intraDir[1] = predMode; + int idx = predMode - DBV_CHROMA_IDX; + pu.mv[0] = chromaCu.mvs[idx]; + pu.bv = chromaCu.bvs[idx]; + pu.cu->rribcFlipType = chromaCu.rribcTypes[idx]; + Mv mv = pu.mv[0]; + + bool isFracMv = pu.cs->sps->getIBCFracFlag() && mv.isFracMv<true>(pu.chromaFormat); + int xFrac = mv.hor & ((1 << MV_FRACTIONAL_BITS_INTERNAL) - 1); + int yFrac = mv.ver & ((1 << MV_FRACTIONAL_BITS_INTERNAL) - 1); + int xFilterTap = xFrac == 0 ? 0 : NTAPS_LUMA_IBC; + int yFilterTap = yFrac == 0 ? 0 : NTAPS_LUMA_IBC; + const uint32_t ctuSize = pu.cs->slice->getSPS()->getMaxCUWidth(); + const int ctuSizeLog2 = floorLog2(ctuSize); + const int picWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples(); + const int picHeight = pu.cs->slice->getPPS()->getPicHeightInLumaSamples(); + int xLumaBv = mv.hor >> MV_FRACTIONAL_BITS_INTERNAL; + int yLumaBv = mv.ver >> MV_FRACTIONAL_BITS_INTERNAL; + if (!PU::searchBv(pu, pu.blocks[COMPONENT_Y].x, pu.blocks[COMPONENT_Y].y, predBuf.width, predBuf.height, picWidth, picHeight, xLumaBv, yLumaBv, ctuSize, xFilterTap, yFilterTap, COMPONENT_Y)) + { + isFracMv = false; + } + if (isFracMv) + { + PelUnitBuf pcBuf(pu.chromaFormat, predBuf, PelBuf(), PelBuf()); + pcInterPred->getPredIBCBlk(pu, COMPONENT_Y, pu.cs->picture, mv, pcBuf); + } + else + { + const int bvShftHor = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleX(COMPONENT_Y, pu.chromaFormat); + const int bvShftVer = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleY(COMPONENT_Y, pu.chromaFormat); + int refx = pu.blocks[COMPONENT_Y].x + (mv.hor >> bvShftHor); + int refy = pu.blocks[COMPONENT_Y].y + (mv.ver >> bvShftVer); + int refStride = pu.cs->picture->getRecoBuf(COMPONENT_Y).stride; + Pel *ref = pu.cs->picture->getRecoBuf(COMPONENT_Y).buf; + Pel *refTarget = ref + refy * refStride + refx; + int iStride = predBuf.stride; + Pel *pred = predBuf.buf; + int iHeight = predBuf.height; + int iWidth = predBuf.width; + for (int uiY = 0; uiY < iHeight; uiY++) + { + for (int uiX = 0; uiX < iWidth; uiX++) + { + pred[uiX] = refTarget[uiX]; + } + refTarget += refStride; + pred += iStride; + } + + // padding + // left + if (refx < 0) + { + for (int j = 0; j < iHeight; j++) + { + for (int i = 0; i < -refx; i++) + { + pred[i + j * predBuf.stride] = pred[i - refx + j * predBuf.stride]; + } + } + CHECK(refx != -1, "WRONG"); + } + // above + if (refy < 0) + { + for (int j = 0; j < -refy; j++) + { + for (int i = 0; i < iWidth; i++) + { + pred[i + j * iStride] = pred[i + (j - refy) * iStride]; + } + } + CHECK(refy != -1, "WRONG"); + } + // bottom + bool isBottom = true; + if (refy + iHeight - 1 >= picHeight) + { + isBottom = false; + } + if (((refy + iHeight - 1) >> ctuSizeLog2) > (pu.blocks[COMPONENT_Y].y >> ctuSizeLog2)) // CTU + { + isBottom = false; + } + if ((((refx + iWidth - 1) >> ctuSizeLog2) > (pu.blocks[COMPONENT_Y].x >> ctuSizeLog2)) && (((refy + iHeight - 1) >> ctuSizeLog2) == (pu.blocks[COMPONENT_Y].y >> ctuSizeLog2))) + { + isBottom = false; + } + if (!isBottom) + { + for (int i = 0; i < iWidth; i++) + { + pred[i + (iHeight - 1) * predBuf.stride] = pred[i + (iHeight - 2) * predBuf.stride]; + } + } + // right + bool isRight = true; + if (refx + iWidth - 1 >= picWidth) + { + isRight = false; + } + if ((((refx + iWidth - 1) >> ctuSizeLog2) > (pu.blocks[COMPONENT_Y].x >> ctuSizeLog2)) && (((refy + iHeight - 1) >> ctuSizeLog2) == (pu.blocks[COMPONENT_Y].y >> ctuSizeLog2))) + { + isRight = false; + } + if (!isRight) + { + for (int j = 0; j < iHeight; j++) + { + pred[iWidth - 1 + j * iStride] = pred[iWidth - 2 + j * iStride]; + } + } + + } + if (pu.cu->rribcFlipType) + { + predBuf.flipSignal(pu.cu->rribcFlipType == 1); + } + + pu.bv.set(0, 0); + pu.mv[0].setZero(); + pu.cu->rribcFlipType = 0; + } + else +#endif + { + initPredIntraParams(pu, area, *pu.cs->sps, 0); + m_ipaParam.applyFusion = false; + m_leftRefLength = (area.height << 1); + m_topRefLength = (area.width << 1); + Pel *refBufUnfiltered = m_refBuffer[area.compID][PRED_BUF_UNFILTERED]; + Pel *refBufFiltered = m_refBuffer[area.compID][PRED_BUF_FILTERED]; + xFillReferenceSamplesForCoLuma(recoBuf, refBufUnfiltered, area, *pu.cu); + if (m_ipaParam.refFilterFlag) + { + xFilterReferenceSamples(refBufUnfiltered, refBufFiltered, area, *pu.cs->sps, 0); + } + predIntraAng(COMPONENT_Y, predBuf, pu, false); + } +} + +void IntraPrediction::predChromaTM(const CompArea &areaCb, const CompArea &areaCr, PredictionUnit &pu, uint8_t predMode, PelBuf predCb, PelBuf predCr, TemplateType eTplType, InterPrediction *pcInterPred) +{ + pu.intraDir[1] = predMode; + int line = NUM_CHROMA_TM_LINES_IN_REORDERING; +#if JVET_AC0071_DBV + if (PU::isDbvMode(predMode)) + { + int idx = predMode - DBV_CHROMA_IDX; + Mv mv = pu.cu->mvs[idx]; + pu.cu->rribcFlipType = pu.cu->rribcTypes[idx]; + const CodingStructure &cs = *pu.cs; + Position posRT = pu.blocks[COMPONENT_Cb].topRight(); + const PredictionUnit *puAbove = cs.getPURestricted(posRT.offset(0, -line), pu, CHANNEL_TYPE_CHROMA); + bool topCanUse = puAbove && pu.cu != puAbove->cu; + Position posLB = pu.blocks[COMPONENT_Cb].bottomLeft(); + const PredictionUnit *puLeft = cs.getPURestricted(posLB.offset(-line, 0), pu, CHANNEL_TYPE_CHROMA); + bool leftCanUse = puLeft && pu.cu != puLeft->cu; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + const int bvShiftHor = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleX(COMPONENT_Cb, pu.chromaFormat); + const int bvShiftVer = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleY(COMPONENT_Cb, pu.chromaFormat); +#else + const int shiftSampleHor = ::getComponentScaleX(compId, pu.chromaFormat); + const int shiftSampleVer = ::getComponentScaleY(compId, pu.chromaFormat); +#endif + + CHECK(topCanUse == false && leftCanUse == false, "wrong type"); + + int filterIdx = 0; + CompArea area = pu.blocks[COMPONENT_Cb]; + int uiHeight = area.height; + int uiWidth = area.width; + + Pel tempCb[MAX_CU_SIZE * 4]; + memset(tempCb, 0, MAX_CU_SIZE * 4 * sizeof(Pel)); + Pel tempCr[MAX_CU_SIZE * 4]; + memset(tempCr, 0, MAX_CU_SIZE * 4 * sizeof(Pel)); + int stride = MAX_CU_SIZE; + Pel *refPixCb = tempCb; + Pel *refPixCr = tempCr; + Pel *refPixTempCb; + Pel *refPixTempCr; + const CPelBuf recBufCb = pu.cs->picture->getRecoBuf(pu.cs->picture->blocks[COMPONENT_Cb]); + const CPelBuf recBufCr = pu.cs->picture->getRecoBuf(pu.cs->picture->blocks[COMPONENT_Cr]); + + Mv mvCurr = mv; + if (topCanUse) + { + Mv mvTop(0, -line); +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 2) + { + mvTop.setVer(uiHeight); + } +#endif +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + mvTop <<= bvShiftVer; +#endif + mvTop += mvCurr; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + if (!PU::checkIsChromaBvCandidateValidChromaTm(pu, mvTop, filterIdx, true, true)) + { +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 2) + { + mvTop.setVer(mvCurr.getVer() + ((uiHeight - line) << bvShiftVer)); + } + else +#endif + { + mvTop = mvCurr; + } + } +#else +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 2) + { + if (!PU::checkIsChromaBvCandidateValid(pu, mvTop, true, true)) + { + mvTop.setVer(mvCurr.getVer() + uiHeight - line); + } + } + else +#endif + if (!PU::checkIsChromaBvCandidateValid(pu, mvTop, true, true)) + { + mvTop = mvCurr; + } +#endif + +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + bool isFracMv = pu.cs->sps->getIBCFracFlag() && mvTop.isFracMv<false>(pu.chromaFormat); + if (isFracMv) + { + PelUnitBuf pcBuf(pu.chromaFormat, PelBuf(), PelBuf(refPixCb, uiWidth, line), PelBuf(refPixCr, uiWidth, line)); + pcInterPred->getPredIBCBlk(pu, COMPONENT_Cb, pu.cs->picture, mvTop, pcBuf, filterIdx == 1); + pcInterPred->getPredIBCBlk(pu, COMPONENT_Cr, pu.cs->picture, mvTop, pcBuf, filterIdx == 1); +#if JVET_AA0070_RRIBC + pcBuf.bufs[COMPONENT_Cb].flip(pu.cu->rribcFlipType); + pcBuf.bufs[COMPONENT_Cr].flip(pu.cu->rribcFlipType); +#endif + } + else + { +#endif + refPixTempCb = refPixCb; + refPixTempCr = refPixCr; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + const Pel *recCb = recBufCb.bufAt(pu.blocks[COMPONENT_Cb].pos().offset(mvTop.hor >> bvShiftHor, mvTop.ver >> bvShiftVer)); + const Pel *recCr = recBufCr.bufAt(pu.blocks[COMPONENT_Cr].pos().offset(mvTop.hor >> bvShiftHor, mvTop.ver >> bvShiftVer)); +#else + const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvTop.hor, mvTop.ver)); +#endif + for (int k = 0; k < uiWidth; k++) + { + for (int l = 0; l < line; l++) + { +#if JVET_AA0070_RRIBC + int recValCb; + int recValCr; + if (pu.cu->rribcFlipType == 0) + { + recValCb = recCb[k + l * recBufCb.stride]; + recValCr = recCr[k + l * recBufCr.stride]; + } + else if (pu.cu->rribcFlipType == 1) + { + recValCb = recCb[uiWidth - 1 - k + l * recBufCb.stride]; + recValCr = recCr[uiWidth - 1 - k + l * recBufCr.stride]; + } + else + { + recValCb = recCb[k + (line - 1 - l) * recBufCb.stride]; + recValCr = recCr[k + (line - 1 - l) * recBufCr.stride]; + } +#else + int recVal = rec[k + l * recBuf.stride]; +#endif + refPixTempCb[k + l * uiWidth] = recValCb; + refPixTempCr[k + l * uiWidth] = recValCr; + } + } +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + } +#endif + } + + if (leftCanUse) + { + Mv mvLeft(-line, 0); +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + mvLeft.setHor(uiWidth); + } +#endif +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + mvLeft <<= bvShiftHor; +#endif + mvLeft += mvCurr; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + if (!PU::checkIsChromaBvCandidateValidChromaTm(pu, mvLeft, filterIdx, true, false)) + { +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + mvLeft.setHor(mvCurr.getHor() + ((uiWidth - line) << bvShiftHor)); + } + else +#endif + { + mvLeft = mvCurr; + } + } +#else +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + if (!PU::checkIsChromaBvCandidateValid(pu, mvLeft, true, false)) + { + mvLeft.setHor(mvCurr.getHor() + uiWidth - DBV_TEMPLATE_SIZE); + } + } + else +#endif + if (!PU::checkIsChromaBvCandidateValid(pu, mvLeft, true, false)) + { + mvLeft = mvCurr; + } +#endif +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + bool isFracMv = pu.cs->sps->getIBCFracFlag() && mvLeft.isFracMv<false>(pu.chromaFormat); + if (isFracMv) + { + PelUnitBuf pcBuf(pu.chromaFormat, PelBuf(), PelBuf(refPixCb + 2 * stride, line, uiHeight), PelBuf(refPixCr + 2 * stride, line, uiHeight)); + pcInterPred->getPredIBCBlk(pu, COMPONENT_Cb, pu.cs->picture, mvLeft, pcBuf, filterIdx == 1); + pcInterPred->getPredIBCBlk(pu, COMPONENT_Cr, pu.cs->picture, mvLeft, pcBuf, filterIdx == 1); +#if JVET_AA0070_RRIBC + pcBuf.bufs[COMPONENT_Cb].flip(pu.cu->rribcFlipType); + pcBuf.bufs[COMPONENT_Cr].flip(pu.cu->rribcFlipType); +#endif + } + else + { +#endif + refPixTempCb = refPixCb + 2 * stride; + refPixTempCr = refPixCr + 2 * stride; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + const Pel *recCb = recBufCb.bufAt(pu.blocks[COMPONENT_Cb].pos().offset(mvLeft.hor >> bvShiftHor, mvLeft.ver >> bvShiftVer)); + const Pel *recCr = recBufCr.bufAt(pu.blocks[COMPONENT_Cr].pos().offset(mvLeft.hor >> bvShiftHor, mvLeft.ver >> bvShiftVer)); +#else + const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvLeft.hor, mvLeft.ver)); +#endif + for (int k = 0; k < uiHeight; k++) + { + for (int l = 0; l < line; l++) + { +#if JVET_AA0070_RRIBC + int recValCb; + int recValCr; + if (pu.cu->rribcFlipType == 0) + { + recValCb = recCb[recBufCb.stride * k + l]; + recValCr = recCr[recBufCr.stride * k + l]; + } + else if (pu.cu->rribcFlipType == 1) + { + recValCb = recCb[recBufCb.stride * k + line - 1 - l]; + recValCr = recCr[recBufCr.stride * k + line - 1 - l]; + } + else + { + recValCb = recCb[recBufCb.stride * (uiHeight - 1 - k) + l]; + recValCr = recCr[recBufCr.stride * (uiHeight - 1 - k) + l]; + } +#else + int recVal = rec[recBuf.stride * k + l]; #endif - const Pel *pRecoAboveLeftCb = pRecoCb - 2 - iStrideCb * 2; - const Pel *pRecoAboveLeftCr = pRecoCr - 2 - iStrideCr * 2; -#if !JVET_AC0094_REF_SAMPLES_OPT - buildHistogram(pRecoAboveLeftY, iStrideY, 2, 2, piHistogram, 3, uiWidthY, uiHeightY); + refPixTempCb[l + k * line] = recValCb; + refPixTempCr[l + k * line] = recValCr; + } + } +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + } #endif - buildHistogram(pRecoAboveLeftCb, iStrideCb, 2, 2, piHistogram, 3, uiWidthCb, uiHeightCb); - buildHistogram(pRecoAboveLeftCr, iStrideCr, 2, 2, piHistogram, 3, uiWidthCr, uiHeightCr); - } - - int firstAmp = 0, secondAmp = 0, curAmp = 0; - int firstMode = 0, secondMode = 0, curMode = 0; + } - for (int i = 0; i < NUM_LUMA_MODE; i++) - { - curAmp = piHistogram[i]; - curMode = i; - if (curAmp > firstAmp) + if (topCanUse && leftCanUse) { - secondAmp = firstAmp; - secondMode = firstMode; - firstAmp = curAmp; - firstMode = curMode; + for (int i = 0; i < uiWidth; i++) + { + predCb.at(line + i, 0) = tempCb[i]; + predCr.at(line + i, 0) = tempCr[i]; + } + for (int j = 0; j < uiHeight; j++) + { + predCb.at(0, line + j) = tempCb[2 * stride + j]; + predCr.at(0, line + j) = tempCr[2 * stride + j]; + } } - else + + if (topCanUse) { - if (curAmp > secondAmp) + //top + for (int i = 0; i < uiWidth; i++) { - secondAmp = curAmp; - secondMode = curMode; + predCb.at(i, 0) = tempCb[i]; + predCr.at(i, 0) = tempCr[i]; } } - } - - cu.dimdChromaMode = firstMode; -#if JVET_AC0094_REF_SAMPLES_OPT - cu.dimdChromaModeSecond = secondMode; -#else - int dmMode = PU::getCoLocatedIntraLumaMode(*cu.firstPU); - if (dmMode == firstMode) - { - cu.dimdChromaMode = secondMode; - if (firstMode == secondMode) + if (leftCanUse) { - cu.dimdChromaMode = DC_IDX; + for (int j = 0; j < uiHeight; j++) + { + predCb.at(0, j) = tempCb[2 * stride + j]; + predCr.at(0, j) = tempCr[2 * stride + j]; + } } } + else #endif + { + m_topRefLength = (areaCb.width + line) << 1; + m_leftRefLength = (areaCb.height + predMode) << 1; + xFillTimdReferenceSamples(pu.cs->picture->getRecoBuf(areaCb), m_refBuffer[COMPONENT_Cb][PRED_BUF_UNFILTERED], areaCb, *pu.cu, line, line); + initPredIntraParams(pu, areaCb, *(pu.cs->sps)); + predTimdIntraAng(COMPONENT_Cb, pu, predMode, predCb.buf, predCb.stride, areaCb.width + line, areaCb.height + line, eTplType, line, line); + + xFillTimdReferenceSamples(pu.cs->picture->getRecoBuf(areaCr), m_refBuffer[COMPONENT_Cr][PRED_BUF_UNFILTERED], areaCr, *pu.cu, line, line); + initPredIntraParams(pu, areaCr, *(pu.cs->sps)); + predTimdIntraAng(COMPONENT_Cr, pu, predMode, predCr.buf, predCr.stride, areaCr.width + line, areaCr.height + line, eTplType, line, line); + } } #endif @@ -21188,7 +22367,11 @@ void IntraPrediction::xCflmCreateLumaRef(const PredictionUnit& pu, const CompAre } } -bool IntraPrediction::xCflmCreateChromaPred(const PredictionUnit& pu, const ComponentID compId, PelBuf& piPred) +bool IntraPrediction::xCflmCreateChromaPred(const PredictionUnit& pu, const ComponentID compId, PelBuf& piPred +#if JVET_AH0136_CHROMA_REORDERING + , InterPrediction *pcInterPred +#endif +) { uint32_t iMode = PU::getFinalIntraMode(pu, CHANNEL_TYPE_CHROMA); @@ -21204,13 +22387,261 @@ bool IntraPrediction::xCflmCreateChromaPred(const PredictionUnit& pu, const Comp return false; } +#if JVET_AH0136_CHROMA_REORDERING + Pel* piRefPred = refChroma.bufAt(0, 0); +#endif + +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (PU::isDbvMode(iMode)) + { + Mv mv = refineChromaBv(compId, pu, pcInterPred); + + int tmpSize = 2; + const CodingStructure &cs = *pu.cs; + Position posRT = pu.blocks[compId].topRight(); + const PredictionUnit *puAbove = cs.getPURestricted(posRT.offset(0, -2), pu, pu.chType); + bool topCanUse = puAbove && pu.cu != puAbove->cu; + Position posLB = pu.blocks[compId].bottomLeft(); + const PredictionUnit *puLeft = cs.getPURestricted(posLB.offset(-2, 0), pu, pu.chType); + bool leftCanUse = puLeft && pu.cu != puLeft->cu; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + const int bvShiftHor = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleX(compId, pu.chromaFormat); + const int bvShiftVer = MV_FRACTIONAL_BITS_INTERNAL + ::getComponentScaleY(compId, pu.chromaFormat); +#else + const int shiftSampleHor = ::getComponentScaleX(compId, pu.chromaFormat); + const int shiftSampleVer = ::getComponentScaleY(compId, pu.chromaFormat); +#endif + CHECK(topCanUse == false && leftCanUse == false, "wrong type"); + + int filterIdx = 0; + CompArea area = pu.blocks[compId]; + int uiHeight = area.height; + int uiWidth = area.width; + + Pel temp[MAX_CU_SIZE * 4]; + memset(temp, 0, MAX_CU_SIZE * 4 * sizeof(Pel)); + int stride = MAX_CU_SIZE; + Pel *refPix = temp; + Pel *refPixTemp; + const CPelBuf recBuf = pu.cs->picture->getRecoBuf(pu.cs->picture->blocks[compId]); + + Mv mvCurr = mv; + if (topCanUse) + { + Mv mvTop(0, -tmpSize); +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 2) + { + mvTop.setVer(uiHeight); + } +#endif +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + mvTop <<= bvShiftVer; +#endif + mvTop += mvCurr; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + if (!PU::checkIsChromaBvCandidateValidChromaTm(pu, mvTop, filterIdx, true, true)) + { +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 2) + { + mvTop.setVer(mvCurr.getVer() + ((uiHeight - tmpSize) << bvShiftVer)); + } + else +#endif + { + mvTop = mvCurr; + } + } +#else +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 2) + { + if (!PU::checkIsChromaBvCandidateValid(pu, mvTop, true, true)) + { + mvTop.setVer(mvCurr.getVer() + uiHeight - tmpSize); + } + } + else +#endif + if (!PU::checkIsChromaBvCandidateValid(pu, mvTop, true, true)) + { + mvTop = mvCurr; + } +#endif + +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + bool isFracMv = pu.cs->sps->getIBCFracFlag() && mvTop.isFracMv<false>(pu.chromaFormat); + if (isFracMv) + { + PelUnitBuf pcBuf(pu.chromaFormat, PelBuf(), PelBuf(refPix, uiWidth, tmpSize), PelBuf(refPix, uiWidth, tmpSize)); + pcInterPred->getPredIBCBlk(pu, compId, pu.cs->picture, mvTop, pcBuf, filterIdx == 1); +#if JVET_AA0070_RRIBC + pcBuf.bufs[compId].flip(pu.cu->rribcFlipType); +#endif + } + else + { +#endif + refPixTemp = refPix; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvTop.hor >> bvShiftHor, mvTop.ver >> bvShiftVer)); +#else + const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvTop.hor, mvTop.ver)); +#endif + for (int k = 0; k < uiWidth; k++) + { + for (int l = 0; l < tmpSize; l++) + { +#if JVET_AA0070_RRIBC + int recVal; + if (pu.cu->rribcFlipType == 0) + { + recVal = rec[k + l * recBuf.stride]; + } + else if (pu.cu->rribcFlipType == 1) + { + recVal = rec[uiWidth - 1 - k + l * recBuf.stride]; + } + else + { + recVal = rec[k + (tmpSize - 1 - l) * recBuf.stride]; + } +#else + int recVal = rec[k + l * recBuf.stride]; +#endif + refPixTemp[k + l * uiWidth] = recVal; + } + } +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + } +#endif + } + + if (leftCanUse) + { + Mv mvLeft(-tmpSize, 0); +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + mvLeft.setHor(uiWidth); + } +#endif +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + mvLeft <<= bvShiftHor; +#endif + mvLeft += mvCurr; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + if (!PU::checkIsChromaBvCandidateValidChromaTm(pu, mvLeft, filterIdx, true, false)) + { +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + mvLeft.setHor(mvCurr.getHor() + ((uiWidth - tmpSize) << bvShiftHor)); + } + else +#endif + { + mvLeft = mvCurr; + } + } +#else +#if JVET_AA0070_RRIBC + if (pu.cu->rribcFlipType == 1) + { + if (!PU::checkIsChromaBvCandidateValid(pu, mvLeft, true, false)) + { + mvLeft.setHor(mvCurr.getHor() + uiWidth - DBV_TEMPLATE_SIZE); + } + } + else +#endif + if (!PU::checkIsChromaBvCandidateValid(pu, mvLeft, true, false)) + { + mvLeft = mvCurr; + } +#endif +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + bool isFracMv = pu.cs->sps->getIBCFracFlag() && mvLeft.isFracMv<false>(pu.chromaFormat); + if (isFracMv) + { + PelUnitBuf pcBuf(pu.chromaFormat, PelBuf(), PelBuf(refPix + 2 * stride, tmpSize, uiHeight), PelBuf(refPix + 2 * stride, tmpSize, uiHeight)); + pcInterPred->getPredIBCBlk(pu, compId, pu.cs->picture, mvLeft, pcBuf, filterIdx == 1); +#if JVET_AA0070_RRIBC + pcBuf.bufs[compId].flip(pu.cu->rribcFlipType); +#endif + } + else + { +#endif + refPixTemp = refPix + 2 * stride; +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvLeft.hor >> bvShiftHor, mvLeft.ver >> bvShiftVer)); +#else + const Pel *rec = recBuf.bufAt(pu.blocks[compId].pos().offset(mvLeft.hor, mvLeft.ver)); +#endif + for (int k = 0; k < uiHeight; k++) + { + for (int l = 0; l < tmpSize; l++) + { +#if JVET_AA0070_RRIBC + int recVal; + if (pu.cu->rribcFlipType == 0) + { + recVal = rec[recBuf.stride * k + l]; + } + else if (pu.cu->rribcFlipType == 1) + { + recVal = rec[recBuf.stride * k + tmpSize - 1 - l]; + } + else + { + recVal = rec[recBuf.stride * (uiHeight - 1 - k) + l]; + } +#else + int recVal = rec[recBuf.stride * k + l]; +#endif + refPixTemp[l + k * tmpSize] = recVal; + } + } +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + } +#endif + } + + if (topCanUse) + { + //top + for (int i = 0; i < uiWidth; i++) + { + refChroma.at(refSizeX + i, 0) = temp[i]; + refChroma.at(refSizeX + i, 1) = temp[uiWidth + i]; + } + } + if (leftCanUse) + { + //left + for (int j = 0; j < uiHeight; j++) + { + refChroma.at(0, refSizeY + j) = temp[2 * stride + j * 2]; + refChroma.at(1, refSizeY + j) = temp[2 * stride + j * 2 + 1]; + } + } + } + else + { +#endif m_topRefLength = areaWidth << 1; m_leftRefLength = areaHeight << 1; xFillTimdReferenceSamples(pu.cs->picture->getRecoBuf(area), m_refBuffer[compId][PRED_BUF_UNFILTERED], area, *pu.cu, refSizeX, refSizeY); - +#if !JVET_AH0136_CHROMA_REORDERING Pel* piRefPred = refChroma.bufAt(0, 0); +#endif initPredIntraParams(pu, area, *(pu.cs->sps)); predTimdIntraAng(compId, pu, iMode, piRefPred, refChroma.stride, areaWidth, areaHeight, eTplType, refSizeX, refSizeY); +#if JVET_AH0136_CHROMA_REORDERING + } +#endif // the PU reference areas PelBuf predChroma = xCflmGetPuBuf(pu, compId, area); @@ -21224,6 +22655,12 @@ bool IntraPrediction::xCflmCreateChromaPred(const PredictionUnit& pu, const Comp piPredBuf += piPred.stride; } +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (pu.cu->rribcFlipType != 0 && PU::isDbvMode(iMode)) + { + predChroma.flipSignal(pu.cu->rribcFlipType == 1); + } +#endif #if JVET_AB0174_CCCM_DIV_FREE int chromaOffset = 1 << (pu.cu->slice->getSPS()->getBitDepth(CHANNEL_TYPE_CHROMA) - 1); diff --git a/source/Lib/CommonLib/IntraPrediction.h b/source/Lib/CommonLib/IntraPrediction.h index d5549712cda3c7439c2b0adb958e91f6a8c7ab2b..2555acdfb1059bd102e131bd3fc09b5ec817e168 100644 --- a/source/Lib/CommonLib/IntraPrediction.h +++ b/source/Lib/CommonLib/IntraPrediction.h @@ -500,6 +500,9 @@ protected: #endif void xFillReferenceSamples ( const CPelBuf &recoBuf, Pel* refBufUnfiltered, const CompArea &area, const CodingUnit &cu ); +#if JVET_AH0136_CHROMA_REORDERING + void xFillReferenceSamplesForCoLuma(const CPelBuf &recoBuf, Pel* refBufUnfiltered, const CompArea &area, const CodingUnit &cu); +#endif void xFilterReferenceSamples(const Pel *refBufUnfiltered, Pel *refBufFiltered, const CompArea &area, const SPS &sps, int multiRefIdx ); @@ -664,7 +667,11 @@ public: void xCflmCalcModels(const PredictionUnit& pu, const ComponentID compId, const CompArea& chromaArea, CccmModel& cflmModel, int modelId, int modelThr); void xCflmApplyModel(const PredictionUnit& pu, const ComponentID compId, const CompArea& chromaArea, CccmModel& cflmModel, int modelId, int modelThr, PelBuf& piPred); void xCflmCreateLumaRef (const PredictionUnit& pu, const CompArea& chromaArea); - bool xCflmCreateChromaPred (const PredictionUnit& pu, const ComponentID compId, PelBuf& piPred); + bool xCflmCreateChromaPred (const PredictionUnit& pu, const ComponentID compId, PelBuf& piPred +#if JVET_AH0136_CHROMA_REORDERING + , InterPrediction *pcInterPred +#endif + ); PelBuf xCflmGetRefBuf (const PredictionUnit& pu, const ComponentID compId, const CompArea& chromaArea, int& areaWidth, int& areaHeight, int& refSizeX, int& refSizeY, int& refPosPicX, int& refPosPicY) const; PelBuf xCflmGetPuBuf (const PredictionUnit& pu, const ComponentID compId, const CompArea& chromaArea) const; int xCflmCalcRefAver (const PredictionUnit& pu, const CompArea& chromaArea); @@ -744,6 +751,12 @@ public: static void deriveDimdMode (const CPelBuf &recoBuf, const CompArea &area, CodingUnit &cu); #if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD static void deriveDimdChromaMode(const CPelBuf &recoBufY, const CPelBuf &recoBufCb, const CPelBuf &recoBufCr, const CompArea &areaY, const CompArea &areaCb, const CompArea &areaCr, CodingUnit &cu); +#if JVET_AH0136_CHROMA_REORDERING + void deriveNonCcpChromaModes(const CPelBuf &recoBufY, const CPelBuf &recoBufCb, const CPelBuf &recoBufCr, const CompArea &areaY, const CompArea &areaCb, const CompArea &areaCr, CodingUnit &cu, PredictionUnit &pu, InterPrediction *pcInterPred); + void buildChromaModeList(const CompArea &area, CodingUnit &cu, PredictionUnit &pu, uint8_t chromaList[NUM_CHROMA_LIST_MODE], int &existNum, bool &hasDBV); + void predCoLuma(const CompArea &area, const CPelBuf &recoBuf, PredictionUnit &pu, uint8_t predMode, PelBuf predBuf, InterPrediction *pcInterPred, CodingUnit &chromaCu); + void predChromaTM(const CompArea &areaCb, const CompArea &areaCr, PredictionUnit &pu, uint8_t predMode, PelBuf predCb, PelBuf predCr, TemplateType eTplType, InterPrediction *pcInterPred); +#endif #endif #if JVET_AB0067_MIP_DIMD_LFNST && ENABLE_DIMD static int deriveDimdMipMode(PelBuf& reducedPred, int width, int height, CodingUnit& cu); @@ -980,7 +993,11 @@ public: void geneIntrainterPred (const CodingUnit &cu, PelStorage& pred); #if JVET_Z0050_DIMD_CHROMA_FUSION #if JVET_AD0188_CCP_MERGE - void geneChromaFusionPred (const ComponentID compId, PelBuf &piPred, PredictionUnit &pu); + void geneChromaFusionPred (const ComponentID compId, PelBuf &piPred, PredictionUnit &pu +#if JVET_AH0136_CHROMA_REORDERING + , InterPrediction *pcInterPred = NULL +#endif + ); #else void geneChromaFusionPred (const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu); #endif diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index eb9c43a78b70fba84a9155a7f78a82e56ebe3ede..9b02bafe3dc73e111149c58e17994d7861f29a2e 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -3927,6 +3927,9 @@ SPS::SPS() #if JVET_AD0085_MPM_SORTING , m_mpmSorting ( false ) #endif +#if JVET_AH0136_CHROMA_REORDERING +, m_chromaReordering ( false ) +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING , m_cccm ( false ) #endif diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 5fcc7203fc153bb88ca8cc4bb071afddd0aae0df..b36f05e40bce68b13088e924546a26bff8dfb92a 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1807,6 +1807,9 @@ private: #if JVET_AD0085_MPM_SORTING bool m_mpmSorting; #endif +#if JVET_AH0136_CHROMA_REORDERING + bool m_chromaReordering; +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING int m_cccm; #endif @@ -2523,6 +2526,10 @@ void setCCALFEnabledFlag( bool b ) void setUseMpmSorting (bool b) { m_mpmSorting = b; } bool getUseMpmSorting () const { return m_mpmSorting; } #endif +#if JVET_AH0136_CHROMA_REORDERING + void setUseChromaReordering(bool b) { m_chromaReordering = b; } + bool getUseChromaReordering() const { return m_chromaReordering; } +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING void setUseCccm( int i ) { m_cccm = i; } int getUseCccm() const { return m_cccm; } diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp index 13900446a6880807d540afd2ac26ed81a3a8c116..4c0b9d24ab785eb8122608a378560cb99e8288ce 100644 --- a/source/Lib/CommonLib/TrQuant.cpp +++ b/source/Lib/CommonLib/TrQuant.cpp @@ -544,7 +544,11 @@ void TrQuant::xInvLfnst( const TransformUnit &tu, const ComponentID compID ) } #endif #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (compID != COMPONENT_Y && PU::isDbvMode(intraMode)) +#else if (compID != COMPONENT_Y && intraMode == DBV_CHROMA_IDX) +#endif { intraMode = PLANAR_IDX; } @@ -833,7 +837,11 @@ void TrQuant::xFwdLfnst( const TransformUnit &tu, const ComponentID compID, cons } #endif #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (compID != COMPONENT_Y && PU::isDbvMode(intraMode)) +#else if (compID != COMPONENT_Y && intraMode == DBV_CHROMA_IDX) +#endif { intraMode = PLANAR_IDX; } @@ -2735,7 +2743,11 @@ int TrQuant::getLfnstIdx(const TransformUnit &tu, ComponentID compID) } #endif #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (compID != COMPONENT_Y && PU::isDbvMode(intraMode)) +#else if (compID != COMPONENT_Y && intraMode == DBV_CHROMA_IDX) +#endif { intraMode = PLANAR_IDX; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index de802deee3193771e44595d59284a59788a3b90a..b821550a2a64b619a3bc46c6dc741fbbf49ec9a9 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -206,6 +206,7 @@ #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 +#define JVET_AH0136_CHROMA_REORDERING 1 // JVET-AH0136: Non-CCP intra chroma mode reordering //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 diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index a051d7c6593269d51b36610c5f7065c178c51376..d8f975f3430ab23582ea3caa79e0687475e93d6e 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -345,6 +345,23 @@ CodingUnit& CodingUnit::operator=( const CodingUnit& other ) } #endif #endif +#if JVET_AH0136_CHROMA_REORDERING + for (uint32_t i = 0; i < 7; i++) + { + chromaList[i] = other.chromaList[i]; + } + for (int i = 0; i < 5; i++) + { + dimdBlendModeChroma[i] = other.dimdBlendModeChroma[i]; + } + for (int i = 0; i < 10; i++) + { + mvs[i] = other.mvs[i]; + bvs[i] = other.bvs[i]; + rribcTypes[i] = other.rribcTypes[i]; + } + mvsNum = other.mvsNum; +#endif #if TMP_FAST_ENC #if JVET_AD0086_ENHANCED_INTRA_TMP #if (JVET_AG0146_DIMD_ITMP_IBC || JVET_AG0152_SGPM_ITMP_IBC || JVET_AG0151_INTRA_TMP_MERGE_MODE) @@ -602,6 +619,23 @@ void CodingUnit::initData() } #endif #endif +#if JVET_AH0136_CHROMA_REORDERING + for (uint32_t i = 0; i < 7; i++) + { + chromaList[i] = -1; + } + for (int i = 0; i < 5; i++) + { + dimdBlendModeChroma[i] = -1; + } + for (int i = 0; i < 10; i++) + { + mvs[i].setZero(); + bvs[i].setZero(); + rribcTypes[i] = 0; + } + mvsNum = 0; +#endif #if TMP_FAST_ENC #if JVET_AD0086_ENHANCED_INTRA_TMP #if (JVET_AG0146_DIMD_ITMP_IBC || JVET_AG0152_SGPM_ITMP_IBC || JVET_AG0151_INTRA_TMP_MERGE_MODE) diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index 769b3c2b2a78b4bb9bc6b1415f8a144b1d5b6123..fe9893ecbc3443d99650afd7c2df867d5781aa04 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -362,6 +362,14 @@ struct CodingUnit : public UnitArea int8_t dimdRelWeight[3]; // max number of predictions to blend #endif #endif +#if JVET_AH0136_CHROMA_REORDERING + int8_t dimdBlendModeChroma[DIMD_FUSION_NUM - 1]; + uint8_t chromaList[7]; + Mv mvs[10]; + Mv bvs[10]; + int rribcTypes[10]; + int mvsNum; +#endif #if TMP_FAST_ENC #if JVET_AD0086_ENHANCED_INTRA_TMP #if (JVET_AG0146_DIMD_ITMP_IBC || JVET_AG0152_SGPM_ITMP_IBC || JVET_AG0151_INTRA_TMP_MERGE_MODE) @@ -546,7 +554,7 @@ struct CodingUnit : public UnitArea struct IntraPredictionData { -#if ENABLE_DIMD || JVET_W0123_TIMD_FUSION +#if ENABLE_DIMD || JVET_W0123_TIMD_FUSION || JVET_AH0136_CHROMA_REORDERING bool parseLumaMode = false; int8_t candId = -1; bool parseChromaMode = false; diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 147f66589eaacacdee75b4bbcbfa33a46cda6fa6..7fbb092d8c3fcf92179d8ab86e0763b446644afc 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -3066,7 +3066,14 @@ bool PU::hasChromaFusionFlag(const PredictionUnit &pu, int intraMode) bool hasChromaFusionFlag = pu.cs->slice->getSliceType() == I_SLICE; #endif #if JVET_AC0071_DBV && JVET_AC0119_LM_CHROMA_FUSION - hasChromaFusionFlag &= intraMode != DBV_CHROMA_IDX; +#if JVET_AH0136_CHROMA_REORDERING + if (!pu.cs->sps->getUseChromaReordering()) + { +#endif + hasChromaFusionFlag &= intraMode != DBV_CHROMA_IDX; +#if JVET_AH0136_CHROMA_REORDERING + } +#endif #endif #if JVET_AC0119_LM_CHROMA_FUSION hasChromaFusionFlag &= PU::isLMCModeEnabled(pu, LM_CHROMA_IDX); @@ -4913,6 +4920,35 @@ uint32_t PU::getIntraDirLuma( const PredictionUnit &pu ) void PU::getIntraChromaCandModes(const PredictionUnit &pu, unsigned modeList[NUM_CHROMA_MODE]) { +#if JVET_AH0136_CHROMA_REORDERING + if (CS::isDualITree(*pu.cs) && pu.cs->sps->getUseChromaReordering()) + { + modeList[0] = LM_CHROMA_IDX; + modeList[1] = MDLM_L_IDX; + modeList[2] = MDLM_T_IDX; +#if MMLM + modeList[3] = MMLM_CHROMA_IDX; + modeList[4] = MMLM_L_IDX; + modeList[5] = MMLM_T_IDX; + modeList[6] = pu.cu->chromaList[0]; + modeList[7] = pu.cu->chromaList[1]; + modeList[8] = pu.cu->chromaList[2]; + modeList[9] = pu.cu->chromaList[3]; + modeList[10] = pu.cu->chromaList[4]; + modeList[11] = pu.cu->chromaList[5]; + modeList[12] = pu.cu->chromaList[6]; +#else + modeList[3] = pu.cu->chromaList[0]; + modeList[4] = pu.cu->chromaList[1]; + modeList[5] = pu.cu->chromaList[2]; + modeList[6] = pu.cu->chromaList[3]; + modeList[7] = pu.cu->chromaList[4]; + modeList[8] = pu.cu->chromaList[5]; + modeList[9] = pu.cu->chromaList[6]; +#endif + return; +} +#endif modeList[0] = PLANAR_IDX; modeList[1] = VER_IDX; modeList[2] = HOR_IDX; @@ -5100,7 +5136,11 @@ uint32_t PU::getFinalIntraMode( const PredictionUnit &pu, const ChannelType &chT } #endif #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if ((pu.cs->sps->getUseChromaReordering() && CS::isDualITree(*pu.cs) && (PU::isDbvMode(pu.intraDir[1]) && !isLuma(chType) && pu.cu->mvs[pu.intraDir[1] - DBV_CHROMA_IDX] == Mv())) || ((!CS::isDualITree(*pu.cs) || !pu.cs->sps->getUseChromaReordering()) && uiIntraMode == DBV_CHROMA_IDX && !isLuma(chType) && pu.bv == Mv())) +#else if (uiIntraMode == DBV_CHROMA_IDX && !isLuma(chType) && pu.bv == Mv()) +#endif { uiIntraMode = PLANAR_IDX; } @@ -5166,6 +5206,16 @@ uint32_t PU::getCoLocatedIntraLumaMode(const PredictionUnit &pu) #endif #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING +bool PU::isDbvMode(int mode) +{ + if (mode >= DBV_CHROMA_IDX && mode <= DBV_CHROMA_IDX9) + { + return true; + } + return false; +} +#endif bool PU::dbvModeAvail(const PredictionUnit &pu) { #if JVET_AF0066_ENABLE_DBV_4_SINGLE_TREE @@ -5200,6 +5250,12 @@ void PU::deriveChromaBv(PredictionUnit &pu) { return; } +#endif +#if JVET_AH0136_CHROMA_REORDERING + if (!pu.cs->sps->getUseIntraDBV()) + { + return; + } #endif pu.bv.set(0, 0); #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS @@ -5219,6 +5275,9 @@ void PU::deriveChromaBv(PredictionUnit &pu) lumaArea = clipArea(lumaArea, pu.cs->picture->block(COMPONENT_Y)); Position posList[5] = { lumaArea.center(), lumaArea.topLeft(), lumaArea.topRight(), lumaArea.bottomLeft(), lumaArea.bottomRight() }; +#if JVET_AH0136_CHROMA_REORDERING + int cnt = 0; +#endif for (int n = 0; n < NUM_DBV_POSITION; n++) { const PredictionUnit *lumaPU = pu.cs->picture->cs->getPU(posList[n], CHANNEL_TYPE_LUMA); @@ -5243,18 +5302,43 @@ void PU::deriveChromaBv(PredictionUnit &pu) if (PU::checkIsChromaBvCandidateValid(pu, chromaBv)) #endif { - pu.bv = lumaBv; +#if JVET_AH0136_CHROMA_REORDERING + if (pu.cs->sps->getUseChromaReordering()) + { + pu.cu->bvs[cnt] = lumaBv; + pu.cu->bvs[cnt].changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); + pu.cu->mvs[cnt] = lumaBv; + pu.cu->rribcTypes[cnt] = lumaPU->cu->rribcFlipType; + cnt++; + if (cnt - 1 > 0) + { + for (int i = 0; i < cnt - 1; i++) + { + if (pu.cu->mvs[i] == lumaBv) + { + cnt--; + } + } + } + } + else + { +#endif + pu.bv = lumaBv; #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS - pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); - pu.mv[0] = lumaBv; + pu.bv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); + pu.mv[0] = lumaBv; #endif #if JVET_AA0070_RRIBC - pu.cu->rribcFlipType = lumaPU->cu->rribcFlipType; + pu.cu->rribcFlipType = lumaPU->cu->rribcFlipType; #endif #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS - pu.intraDir[1] = bkIntraDir; + pu.intraDir[1] = bkIntraDir; +#endif + return; +#if JVET_AH0136_CHROMA_REORDERING + } #endif - return; } #if JVET_AE0169_BIPREDICTIVE_IBC if (CU::isIBC(*lumaPU->cu) && lumaPU->interDir == 3) @@ -5273,13 +5357,38 @@ void PU::deriveChromaBv(PredictionUnit &pu) if (PU::checkIsChromaBvCandidateValid(pu, chromaBv)) #endif { +#if JVET_AH0136_CHROMA_REORDERING + if (pu.cs->sps->getUseChromaReordering()) + { + pu.cu->bvs[cnt] = lumaBv; + pu.cu->bvs[cnt].changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); + pu.cu->mvs[cnt] = lumaBv; + pu.cu->rribcTypes[cnt] = lumaPU->cu->rribcFlipType; + cnt++; + if (cnt - 1 > 0) + { + for (int i = 0; i < cnt - 1; i++) + { + if (pu.cu->mvs[i] == lumaBv) + { + cnt--; + } + } + } + } + else + { +#endif #if JVET_AA0070_RRIBC - pu.cu->rribcFlipType = lumaPU->cu->rribcFlipType; + pu.cu->rribcFlipType = lumaPU->cu->rribcFlipType; #endif #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS - pu.intraDir[1] = bkIntraDir; + pu.intraDir[1] = bkIntraDir; +#endif + return; +#if JVET_AH0136_CHROMA_REORDERING + } #endif - return; } } #endif @@ -5288,6 +5397,9 @@ void PU::deriveChromaBv(PredictionUnit &pu) #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS pu.intraDir[1] = bkIntraDir; #endif +#if JVET_AH0136_CHROMA_REORDERING + pu.cu->mvsNum = cnt; +#endif } #if JVET_AA0070_RRIBC @@ -5399,6 +5511,44 @@ bool PU::checkIsChromaBvCandidateValid(const PredictionUnit &pu } #endif +#if JVET_AH0136_CHROMA_REORDERING +bool PU::checkIsChromaBvCandidateValidChromaTm(const PredictionUnit &pu, const Mv mv, int filterIdx, bool isRefTemplate, bool isRefAbove) +{ +#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS + int roiWidth = (isRefTemplate && !isRefAbove) ? 2 : pu.Cb().width; + int roiHeight = (isRefTemplate && isRefAbove) ? 2 : pu.Cb().height; + uint32_t validType = checkValidBv(pu, COMPONENT_Cb, roiWidth, roiHeight, mv, true, filterIdx); + return validType != IBC_BV_INVALID; +#else + const int cuPelX = pu.Cb().x; + const int cuPelY = pu.Cb().y; + int roiWidth = (isRefTemplate && !isRefAbove) ? DBV_TEMPLATE_SIZE : pu.Cb().width; + int roiHeight = (isRefTemplate && isRefAbove) ? DBV_TEMPLATE_SIZE : pu.Cb().height; + int xPred = chromaBv.getHor(); + int yPred = chromaBv.getVer(); + if ((xPred + roiWidth) > 0 && (yPred + roiHeight) > 0) + { + return false; + } + int refRightX = cuPelX + xPred + roiWidth - 1; + int refLeftX = cuPelX + xPred; + int refBottomY = cuPelY + yPred + roiHeight - 1; + int refTopY = cuPelY + yPred; + const Position refPosLT(refLeftX, refTopY); + const Position refPosBR(refRightX, refBottomY); + if (!pu.cs->isDecomp(refPosBR, pu.chType)) + { + return false; + } + if (!pu.cs->isDecomp(refPosLT, pu.chType)) + { + return false; + } + return true; +#endif +} +#endif + int PU::getWideAngle( const TransformUnit &tu, const uint32_t dirMode, const ComponentID compID ) { //This function returns a wide angle index taking into account that the values 0 and 1 are reserved @@ -8070,8 +8220,20 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS #if JVET_AC0071_DBV - const bool isDBV = (pu.cs->slice->getSliceType() == I_SLICE && CS::isDualITree(*pu.cs) && pu.cu->slice->getSPS()->getUseIntraDBV()) - && compID != COMPONENT_Y && pu.intraDir[1] == DBV_CHROMA_IDX; + const bool isDBV = (pu.cs->slice->getSliceType() == I_SLICE && CS::isDualITree(*pu.cs) && pu.cu->slice->getSPS()->getUseIntraDBV()) + && compID != COMPONENT_Y && +#if JVET_AH0136_CHROMA_REORDERING + PU::isDbvMode(pu.intraDir[1]); +#else + pu.intraDir[1] == DBV_CHROMA_IDX; +#endif +#endif +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + bool isLumaDbv = false; + if (pu.cs->sps->getUseChromaReordering() && compID == COMPONENT_Y && PU::isDbvMode(pu.intraDir[1]) && CS::isDualITree(*pu.cs)) + { + isLumaDbv = true; + } #endif const int szShiftHor = ::getComponentScaleX(compID, pu.chromaFormat); const int szShiftVer = ::getComponentScaleY(compID, pu.chromaFormat); @@ -8134,6 +8296,20 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h { return false; } +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (isLumaDbv) + { + if (refBottomY >> ctuSizeLog2 > yPos >> ctuSizeLog2) + { + return false; + } + if ((refRightX >> ctuSizeLog2 > xPos >> ctuSizeLog2) && (refBottomY >> ctuSizeLog2 == yPos >> ctuSizeLog2)) + { + return false; + } + return true; + } +#endif #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS if (refRightX >= xPos && refBottomY >= yPos) #else @@ -29349,7 +29525,13 @@ uint32_t PU::getFinalIntraModeForTransform( const TransformUnit &tu, const Compo } #endif #if JVET_AC0071_DBV - if (compID != COMPONENT_Y && intraMode == DBV_CHROMA_IDX) + if (compID != COMPONENT_Y +#if JVET_AH0136_CHROMA_REORDERING + && PU::isDbvMode(intraMode) +#else + && intraMode == DBV_CHROMA_IDX +#endif + ) { intraMode = PLANAR_IDX; } diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 7e0a4430109af9c8de4d2c1d310300bf9baa4aac..35cdbbcee34dcfe8f35cab6837ad0c2fd4a28a48 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -274,6 +274,9 @@ namespace PU uint32_t getCoLocatedIntraLumaMode (const PredictionUnit &pu); #endif #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + bool isDbvMode(int mode); +#endif bool dbvModeAvail(const PredictionUnit &pu); void deriveChromaBv(PredictionUnit &pu); #if JVET_AA0070_RRIBC @@ -292,6 +295,9 @@ namespace PU , const Mv chromaBv #endif , bool isRefTemplate = false, bool isRefAbove = false); +#endif +#if JVET_AH0136_CHROMA_REORDERING + bool checkIsChromaBvCandidateValidChromaTm(const PredictionUnit &pu, const Mv mv, int filterIdx = 0, bool isRefTemplate = false, bool isRefAbove = false); #endif int getWideAngle ( const TransformUnit &tu, const uint32_t dirMode, const ComponentID compID ); #if MULTI_PASS_DMVR || JVET_W0097_GPM_MMVD_TM diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 330d73b106c825e8dc08dbec5c50053e96bc6920..50eb0a7b98275837ebe8182d0cdb75ade821af36 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -2923,10 +2923,14 @@ void CABACReader::intra_chroma_pred_mode(PredictionUnit& pu) pu.intraDir[1] = DBV_CHROMA_IDX; if (PU::hasChromaFusionFlag(pu, pu.intraDir[1])) { +#if JVET_AH0136_CHROMA_REORDERING + intraChromaFusionMode(pu); +#else if (m_BinDecoder.decodeBin(Ctx::ChromaFusionMode()) == 1) { pu.isChromaFusion = true; } +#endif } DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) dir=%d\n", pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, pu.intraDir[CHANNEL_TYPE_CHROMA]); @@ -2998,7 +3002,10 @@ void CABACReader::intra_chroma_pred_mode(PredictionUnit& pu) #endif } #endif - +#if JVET_AH0136_CHROMA_REORDERING + pu.intraDir[1] = PLANAR_IDX; + pu.candId = candId; +#else unsigned chromaCandModes[NUM_CHROMA_MODE]; PU::getIntraChromaCandModes(pu, chromaCandModes); @@ -3013,6 +3020,7 @@ void CABACReader::intra_chroma_pred_mode(PredictionUnit& pu) #if ENABLE_DIMD || JVET_W0123_TIMD_FUSION pu.candId = candId; #endif +#endif } void CABACReader::cu_residual( CodingUnit& cu, Partitioner &partitioner, CUCtx& cuCtx ) diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index 13a54cf83a5252bc6c8371d97fed1165182a428b..0b081de080dcf24b1c63dc0081eb4366974daa87 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -469,7 +469,11 @@ void DecCu::decompressCtu( CodingStructure& cs, const UnitArea& ctuArea ) #endif } } +#if JVET_AH0136_CHROMA_REORDERING + if (currCU.firstPU->parseChromaMode && (!CS::isDualITree(cs) || !currCU.cs->sps->getUseChromaReordering())) +#else if (currCU.firstPU->parseChromaMode) +#endif { unsigned chromaCandModes[NUM_CHROMA_MODE]; PU::getIntraChromaCandModes(*currCU.firstPU, chromaCandModes); @@ -627,7 +631,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) #endif #if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD #if JVET_AG0059_CCP_MERGE_ENHANCEMENT +#if JVET_AH0136_CHROMA_REORDERING + if (((!PU::isLMCMode(pu.intraDir[1]) && compID == COMPONENT_Cb && !pu.cu->bdpcmModeChroma) && CS::isDualITree(cs) && pu.cs->sps->getUseChromaReordering()) || ((pu.intraDir[1] == DIMD_CHROMA_IDX || pu.ccpMergeFusionType == 1) && compID == COMPONENT_Cb)) +#else if ((pu.intraDir[1] == DIMD_CHROMA_IDX || pu.ccpMergeFusionType == 1) && compID == COMPONENT_Cb) +#endif #else if (pu.intraDir[1] == DIMD_CHROMA_IDX && compID == COMPONENT_Cb) #endif @@ -651,6 +659,57 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) #endif } #endif +#if JVET_AH0136_CHROMA_REORDERING + if ((!PU::isLMCMode(pu.intraDir[1]) && compID == COMPONENT_Cb && !pu.cu->bdpcmModeChroma) && CS::isDualITree(cs) && pu.cs->sps->getUseChromaReordering()) + { + CompArea areaCb = pu.Cb(); + CompArea areaCr = pu.Cr(); + CompArea lumaArea = CompArea(COMPONENT_Y, pu.chromaFormat, areaCb.lumaPos(), recalcSize(pu.chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, areaCb.size())); + m_pcIntraPred->deriveNonCcpChromaModes(cs.picture->getRecoBuf(lumaArea), cs.picture->getRecoBuf(areaCb), cs.picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, *pu.cu, pu, m_pcInterPred); + int chromaIdx = -1; +#if JVET_AC0071_DBV +#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD + if (cs.slice->getSPS()->getUseDimd()) + { + chromaIdx = pu.intraDir[1] == DBV_CHROMA_IDX ? 0 : (pu.intraDir[1] == DM_CHROMA_IDX ? 1 : (pu.intraDir[1] == DIMD_CHROMA_IDX ? 2 : pu.candId + 3)); + } + else + { + chromaIdx = pu.intraDir[1] == DBV_CHROMA_IDX ? 0 : (pu.intraDir[1] == DM_CHROMA_IDX ? 1 : pu.candId + 2); + } +#else + chromaIdx = pu.intraDir[1] == DBV_CHROMA_IDX ? 0 : (pu.intraDir[1] == DM_CHROMA_IDX ? 1 : pu.candId + 2); +#endif + if (!PU::hasChromaBvFlag(pu)) + { + chromaIdx--; + } +#else +#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD + if (cs.slice->getSPS()->getUseDimd()) + { + chromaIdx = pu.intraDir[1] == DM_CHROMA_IDX ? 0 : (pu.intraDir[1] == DIMD_CHROMA_IDX ? 1 : pu.candId + 2); + } + else + { + chromaIdx = pu.intraDir[1] == DM_CHROMA_IDX ? 0 : pu.candId + 1; + } +#else + chromaIdx = pu.intraDir[1] == DM_CHROMA_IDX ? 0 : pu.candId + 1; +#endif +#endif + pu.intraDir[1] = pu.cu->chromaList[chromaIdx]; +#if JVET_AC0071_DBV + if (PU::isDbvMode(pu.intraDir[1]) && CS::isDualITree(cs)) + { + pu.bv = pu.cu->bvs[pu.intraDir[1] - DBV_CHROMA_IDX]; + pu.mv[0] = pu.cu->mvs[pu.intraDir[1] - DBV_CHROMA_IDX]; + pu.cu->rribcFlipType = pu.cu->rribcTypes[pu.intraDir[1] - DBV_CHROMA_IDX]; + } +#endif + CHECK(pu.intraDir[1] < 0, "wrong intraDir"); + } +#endif #if JVET_AE0100_BVGCCCM if (pu.bvgCccmFlag && compID == COMPONENT_Cb) { @@ -660,7 +719,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) } #endif #if JVET_AC0071_DBV - if (pu.intraDir[1] == DBV_CHROMA_IDX && compID == COMPONENT_Cb) + if (pu.intraDir[1] == DBV_CHROMA_IDX && compID == COMPONENT_Cb +#if JVET_AH0136_CHROMA_REORDERING + && !pu.cs->sps->getUseChromaReordering() +#endif + ) { PU::deriveChromaBv(pu); } @@ -1120,7 +1183,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) } else #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (compID != COMPONENT_Y && PU::isDbvMode(uiChFinalMode)) +#else if (compID != COMPONENT_Y && uiChFinalMode == DBV_CHROMA_IDX) +#endif { m_pcIntraPred->predIntraDbv(compID, piPred, pu #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS @@ -1134,7 +1201,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) #if JVET_Z0050_DIMD_CHROMA_FUSION if (compID != COMPONENT_Y && pu.isChromaFusion) { - m_pcIntraPred->geneChromaFusionPred(compID, piPred, pu); + m_pcIntraPred->geneChromaFusionPred(compID, piPred, pu +#if JVET_AH0136_CHROMA_REORDERING + , m_pcInterPred +#endif + ); } #endif } @@ -1183,7 +1254,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) else { #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (PU::isDbvMode(uiChFinalMode)) +#else if (uiChFinalMode == DBV_CHROMA_IDX) +#endif { m_pcIntraPred->predIntraDbv(COMPONENT_Cr, piPredCr, pu #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS @@ -1197,7 +1272,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) #if JVET_Z0050_DIMD_CHROMA_FUSION if (pu.isChromaFusion) { - m_pcIntraPred->geneChromaFusionPred(COMPONENT_Cr, piPredCr, pu); + m_pcIntraPred->geneChromaFusionPred(COMPONENT_Cr, piPredCr, pu +#if JVET_AH0136_CHROMA_REORDERING + , m_pcInterPred +#endif + ); } #endif } @@ -1272,7 +1351,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) if( !tu.cu->ispMode || !isLuma( compID ) ) { #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS && JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (!(PU::isDbvMode(uiChFinalMode) && compID == COMPONENT_Cb)) +#else if (!(uiChFinalMode == DBV_CHROMA_IDX && compID == COMPONENT_Cb)) +#endif #endif cs.setDecomp( area ); } @@ -1320,7 +1403,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) pReco.copyFrom( piPred ); #endif #if JVET_AC0071_DBV && JVET_AA0070_RRIBC +#if JVET_AH0136_CHROMA_REORDERING + if (compID != COMPONENT_Y && PU::isDbvMode(uiChFinalMode) && tu.cu->rribcFlipType) +#else if (compID != COMPONENT_Y && uiChFinalMode == DBV_CHROMA_IDX && tu.cu->rribcFlipType) +#endif { pReco.flipSignal(tu.cu->rribcFlipType == 1); } diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index db2922cde01247c85f2add41f654c107327867a5..882575d6aae92ac71ad3b1a7269d9d8bbaee71aa 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -2709,6 +2709,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) #if JVET_AD0085_MPM_SORTING READ_FLAG(uiCode, "sps_mpm_sorting_enabled_flag"); pcSPS->setUseMpmSorting(uiCode != 0); #endif +#if JVET_AH0136_CHROMA_REORDERING + READ_FLAG(uiCode, "sps_chroma_reordering_enabled_flag"); pcSPS->setUseChromaReordering(uiCode != 0); +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING READ_UVLC(uiCode, "sps_cccm_cand"); pcSPS->setUseCccm(uiCode); #endif diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index edace200777cae4060b9cee266492d0073cdbe79..78a457150e1b43906c946973b0d7884e5b2945a9 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2573,16 +2573,33 @@ void CABACWriter::intra_chroma_pred_mode(const PredictionUnit& pu) } #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + bool hasDBV = false; +#endif if (PU::hasChromaBvFlag(pu)) { +#if JVET_AH0136_CHROMA_REORDERING + hasDBV = true; + bool isDbvChromaMode = intraDir == DBV_CHROMA_IDX; + if (CS::isDualITree(*pu.cs) && pu.cs->sps->getUseChromaReordering()) + { + int mode = PU::isDbvMode(pu.intraDir[1]) ? pu.intraDir[1] : PU::getFinalIntraMode(pu, CHANNEL_TYPE_CHROMA); + isDbvChromaMode = mode == pu.cu->chromaList[0]; + } +#else const bool isDbvChromaMode = intraDir == DBV_CHROMA_IDX; +#endif m_BinEncoder.encodeBin(isDbvChromaMode ? 0 : 1, Ctx::DbvChromaMode()); if (isDbvChromaMode) { if (PU::hasChromaFusionFlag(pu, pu.intraDir[1])) { +#if JVET_AH0136_CHROMA_REORDERING + intraChromaFusionMode(pu); +#else const bool isFusion = pu.isChromaFusion; m_BinEncoder.encodeBin(isFusion ? 1 : 0, Ctx::ChromaFusionMode()); +#endif } DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) dir=%d\n", pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, pu.intraDir[CHANNEL_TYPE_CHROMA]); @@ -2591,6 +2608,108 @@ void CABACWriter::intra_chroma_pred_mode(const PredictionUnit& pu) } #endif +#if JVET_AH0136_CHROMA_REORDERING + if (CS::isDualITree(*pu.cs) && pu.cs->sps->getUseChromaReordering()) + { + int chromaIdx = 0; + bool hasMode = false; + int mode = PU::isDbvMode(pu.intraDir[1]) ? pu.intraDir[1] : PU::getFinalIntraMode(pu, CHANNEL_TYPE_CHROMA); + int start = 0; + int end = 6; +#if JVET_AC0071_DBV + if (hasDBV) + { + start++; + end++; + } +#endif +#if ENABLE_DIMD && JVET_Z0050_DIMD_CHROMA_FUSION + if (!pu.cu->slice->getSPS()->getUseDimd()) + { + end--; + } +#endif + for (int i = start; i < end; i++) + { + if (mode == pu.cu->chromaList[i]) + { + chromaIdx = i; + hasMode = true; + break; + } + } + + if (hasDBV) + { + chromaIdx--; + } + CHECK(!hasMode, "wrong mode"); + const bool isDerivedMode = chromaIdx == 0; + m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0)); + if (isDerivedMode) + { +#if JVET_Z0050_DIMD_CHROMA_FUSION + if (PU::hasChromaFusionFlag(pu, pu.intraDir[1])) + { +#if JVET_AC0119_LM_CHROMA_FUSION + intraChromaFusionMode(pu); +#else + const bool isFusion = pu.isChromaFusion; + m_BinEncoder.encodeBin(isFusion ? 1 : 0, Ctx::ChromaFusionMode()); +#endif + } +#endif + DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) dir=%d\n", + pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, pu.intraDir[CHANNEL_TYPE_CHROMA]); + return; + } + +#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD + if (pu.cu->slice->getSPS()->getUseDimd()) + { + const bool isDimdChromaMode = chromaIdx == 1; + m_BinEncoder.encodeBin(isDimdChromaMode ? 0 : 1, Ctx::DimdChromaMode()); + if (isDimdChromaMode) + { + if (PU::hasChromaFusionFlag(pu, pu.intraDir[1])) + { +#if JVET_AC0119_LM_CHROMA_FUSION + intraChromaFusionMode(pu); +#else + const bool isFusion = pu.isChromaFusion; + m_BinEncoder.encodeBin(isFusion ? 1 : 0, Ctx::ChromaFusionMode()); +#endif + } + DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) dir=%d\n", + pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, pu.intraDir[CHANNEL_TYPE_CHROMA]); + return; + } + } + else + { + chromaIdx++; + } +#endif + + // chroma candidate index + { + m_BinEncoder.encodeBinsEP(chromaIdx - 2, 2); + DTRACE(g_trace_ctx, D_SYNTAX, "intra_chroma_pred_modes() pos=(%d,%d) cand_idx=%d\n", pu.blocks[CHANNEL_TYPE_CHROMA].x, pu.blocks[CHANNEL_TYPE_CHROMA].y, chromaIdx - 2); +#if JVET_Z0050_DIMD_CHROMA_FUSION + if (PU::hasChromaFusionFlag(pu, pu.intraDir[1])) + { +#if JVET_AC0119_LM_CHROMA_FUSION + intraChromaFusionMode(pu); +#else + const bool isFusion = pu.isChromaFusion; + m_BinEncoder.encodeBin(isFusion ? 1 : 0, Ctx::ChromaFusionMode()); +#endif + } +#endif + } + return; + } +#endif const bool isDerivedMode = intraDir == DM_CHROMA_IDX; m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0)); if (isDerivedMode) diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 17eafd18adb86fc9d773709221b8bcbdecd6bbf1..cb7aed7c7604e767f013ccdf5b027c16d354f573 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -509,6 +509,9 @@ protected: #if JVET_AD0085_MPM_SORTING bool m_mpmSorting; #endif +#if JVET_AH0136_CHROMA_REORDERING + bool m_chromaReordering; +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING int m_cccm; #endif @@ -1750,6 +1753,10 @@ public: void setUseMpmSorting (bool b) { m_mpmSorting = b; } bool getUseMpmSorting () const { return m_mpmSorting; } #endif +#if JVET_AH0136_CHROMA_REORDERING + void setUseChromaReordering (bool b) { m_chromaReordering = b; } + bool getUseChromaReordering () const { return m_chromaReordering; } +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING void setUseCccm (int i) { m_cccm = i; } int getUseCccm () const { return m_cccm; } diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index f9b563790a1832aa35c8a553e1a5a4a21fd4f60d..c4424a5b2245e8e62a58ddce458802cebfbd3e34 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -2594,6 +2594,10 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS int8_t dimdChromaMode = -1; int8_t dimdChromaModeSecond = -1; #endif +#if JVET_AH0136_CHROMA_REORDERING + int8_t dimdBlendModeChroma[DIMD_FUSION_NUM - 1] = { 0 }; + int chromaList[7] = { -1 }; +#endif #if JVET_AH0076_OBIC bool obicIsBlended = false; int obicMode[OBIC_FUSION_NUM] = { -1 }; @@ -2678,8 +2682,12 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS #endif #endif } -#if JVET_Z0050_DIMD_CHROMA_FUSION && (JVET_AC0094_REF_SAMPLES_OPT) +#if (JVET_Z0050_DIMD_CHROMA_FUSION && (JVET_AC0094_REF_SAMPLES_OPT)) || JVET_AH0136_CHROMA_REORDERING +#if JVET_AH0136_CHROMA_REORDERING + if (CS::isDualITree(*tempCS) ? isChroma(partitioner.chType) : false) +#else if (tempCS->slice->getSPS()->getUseDimd() && (CS::isDualITree(*tempCS) ? isChroma(partitioner.chType) : false)) +#endif { CodingUnit cu(tempCS->area); cu.cs = tempCS; @@ -2688,9 +2696,33 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS const CompArea areaCb = tempCS->area.Cb(); const CompArea areaCr = tempCS->area.Cr(); const CompArea lumaArea = CompArea(COMPONENT_Y, (tempCS->area).chromaFormat, areaCb.lumaPos(), recalcSize((tempCS->area).chromaFormat, CHANNEL_TYPE_CHROMA, CHANNEL_TYPE_LUMA, areaCb.size())); - IntraPrediction::deriveDimdChromaMode(bestCS->picture->getRecoBuf(lumaArea), bestCS->picture->getRecoBuf(areaCb), bestCS->picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, cu); - dimdChromaMode = cu.dimdChromaMode; - dimdChromaModeSecond = cu.dimdChromaModeSecond; +#if JVET_AH0136_CHROMA_REORDERING + if (tempCS->slice->getSPS()->getUseDimd()) + { +#endif + IntraPrediction::deriveDimdChromaMode(bestCS->picture->getRecoBuf(lumaArea), bestCS->picture->getRecoBuf(areaCb), bestCS->picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, cu); + dimdChromaMode = cu.dimdChromaMode; + dimdChromaModeSecond = cu.dimdChromaModeSecond; +#if JVET_AH0136_CHROMA_REORDERING + for (int i = 0; i < 5; i++) + { + dimdBlendModeChroma[i] = cu.dimdBlendModeChroma[i]; + } + } + if (tempCS->slice->getSPS()->getUseChromaReordering()) + { + PredictionUnit pu(tempCS->area); + pu.cu = &cu; + cu.firstPU = &pu; + pu.cs = bestCS; + cu.cs = bestCS; + m_pcIntraSearch->deriveNonCcpChromaModes(bestCS->picture->getRecoBuf(lumaArea), bestCS->picture->getRecoBuf(areaCb), bestCS->picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, cu, pu, m_pcInterSearch); + for (int i = 0; i < 7; i++) + { + chromaList[i] = cu.chromaList[i]; + } + } +#endif } #endif #elif SECONDARY_MPM @@ -2836,8 +2868,23 @@ bool EncCu::xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS { cu.dimdChromaMode = dimdChromaMode; cu.dimdChromaModeSecond = dimdChromaModeSecond; +#if JVET_AH0136_CHROMA_REORDERING + for (int i = 0; i < 5; i++) + { + cu.dimdBlendModeChroma[i] = dimdBlendModeChroma[i]; + } +#endif } #endif +#endif +#if JVET_AH0136_CHROMA_REORDERING + if (tempCS->slice->getSPS()->getUseChromaReordering() && (CS::isDualITree(*tempCS) ? isChroma(partitioner.chType) : false)) + { + for (int i = 0; i < 7; i++) + { + cu.chromaList[i] = chromaList[i]; + } + } #endif cu.lfnstIdx = lfnstIdx; cu.mtsFlag = mtsFlag; diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index fe0594c14f5ac281cc451c13462f4e4d79a1f1b8..5fecb2ed3530710aa484aa0575ac917885761acb 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1978,6 +1978,9 @@ void EncLib::xInitSPS( SPS& sps ) #if JVET_AD0085_MPM_SORTING sps.setUseMpmSorting ( m_mpmSorting ); #endif +#if JVET_AH0136_CHROMA_REORDERING + sps.setUseChromaReordering (m_chromaReordering); +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING sps.setUseCccm ( m_cccm ); #endif diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp index b4f9886a09dbd19b708a3988fb6de87a0f5ff9e0..bb138346e2ebcd79a0a802f0fcae34e3b3e731c5 100644 --- a/source/Lib/EncoderLib/IntraSearch.cpp +++ b/source/Lib/EncoderLib/IntraSearch.cpp @@ -3688,6 +3688,12 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner IntraPrediction::deriveDimdChromaMode(cs.picture->getRecoBuf(lumaArea), cs.picture->getRecoBuf(areaCb), cs.picture->getRecoBuf(areaCr), lumaArea, areaCb, areaCr, *pu.cu); #endif #endif +#if JVET_AH0136_CHROMA_REORDERING && ENABLE_DIMD && JVET_Z0050_DIMD_CHROMA_FUSION + if (!cu.slice->getSPS()->getUseDimd() && cu.cs->sps->getUseChromaReordering()) + { + uiMaxMode--; + } +#endif #if JVET_AC0071_DBV if (PU::hasChromaBvFlag(pu)) { @@ -3773,11 +3779,19 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner } #if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + bool modeIsEnable[NUM_INTRA_MODE + 3 + 9]; // use intra mode idx to check whether enable + for (int i = 0; i < NUM_INTRA_MODE + 3 + 9; i++) + { + modeIsEnable[i] = 1; + } +#else bool modeIsEnable[NUM_INTRA_MODE + 3]; // use intra mode idx to check whether enable for (int i = 0; i < NUM_INTRA_MODE + 3; i++) { modeIsEnable[i] = 1; } +#endif #else bool modeIsEnable[NUM_INTRA_MODE + 2]; // use intra mode idx to check whether enable for (int i = 0; i < NUM_INTRA_MODE + 2; i++) @@ -3946,17 +3960,51 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner { continue; } - if ((mode == LM_CHROMA_IDX) || (mode == PLANAR_IDX) || (mode == DM_CHROMA_IDX) -#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD - || (mode == DIMD_CHROMA_IDX) +#if JVET_AH0136_CHROMA_REORDERING + if (CS::isDualITree(*pu.cs) && cu.cs->sps->getUseChromaReordering()) + { + if ((mode == LM_CHROMA_IDX) || mode == pu.cu->chromaList[0] || mode == pu.cu->chromaList[1]) + { + continue; + } +#if ENABLE_DIMD && JVET_Z0050_DIMD_CHROMA_FUSION +#if JVET_AC0071_DBV + if ((cu.slice->getSPS()->getUseDimd() && (mode == pu.cu->chromaList[2] || (PU::hasChromaBvFlag(pu) && mode == pu.cu->chromaList[3]))) || (!cu.slice->getSPS()->getUseDimd() && (PU::hasChromaBvFlag(pu) && mode == pu.cu->chromaList[2]))) + { + continue; + } +#else + if ((cu.slice->getSPS()->getUseDimd() && mode == pu.cu->chromaList[2])) + { + continue; + } #endif +#else #if JVET_AC0071_DBV - || (mode == DBV_CHROMA_IDX) + if (PU::hasChromaBvFlag(pu) && mode == pu.cu->chromaList[2]) + { + continue; + } +#endif #endif - ) // only pre-check regular modes and MDLM modes, not including DM, DIMD, Planar, and LM + } + else { - continue; +#endif + if ((mode == LM_CHROMA_IDX) || (mode == PLANAR_IDX) || (mode == DM_CHROMA_IDX) +#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD + || (mode == DIMD_CHROMA_IDX) +#endif +#if JVET_AC0071_DBV + || (mode == DBV_CHROMA_IDX) +#endif + ) // only pre-check regular modes and MDLM modes, not including DM, DIMD, Planar, and LM + { + continue; + } +#if JVET_AH0136_CHROMA_REORDERING } +#endif pu.intraDir[1] = mode; // temporary assigned, for SATD checking. int64_t sad = 0; @@ -3982,8 +4030,29 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner } else { - initPredIntraParams(pu, pu.Cb(), *pu.cs->sps); - predIntraAng(COMPONENT_Cb, predCb, pu); +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (cu.cs->sps->getUseChromaReordering() && CS::isDualITree(cs) && PU::isDbvMode(mode)) + { + pu.bv = cu.bvs[mode - DBV_CHROMA_IDX]; + pu.mv[0] = cu.mvs[mode - DBV_CHROMA_IDX]; + pu.cu->rribcFlipType = cu.rribcTypes[mode - DBV_CHROMA_IDX]; + predIntraDbv(COMPONENT_Cb, predCb, pu, pcInterPred); + if (pu.cu->rribcFlipType) + { + predCb.flipSignal(pu.cu->rribcFlipType == 1); + } + pu.bv.setZero(); + pu.mv[0].setZero(); + pu.cu->rribcFlipType = 0; + } + else + { +#endif + initPredIntraParams(pu, pu.Cb(), *pu.cs->sps); + predIntraAng(COMPONENT_Cb, predCb, pu); +#if JVET_AH0136_CHROMA_REORDERING + } +#endif } sadCb = distParamSad.distFunc(distParamSad) * 2; satdCb = distParamSatd.distFunc(distParamSatd); @@ -4001,12 +4070,39 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner } else { - initPredIntraParams(pu, pu.Cr(), *pu.cs->sps); - predIntraAng(COMPONENT_Cr, predCr, pu); +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (cu.cs->sps->getUseChromaReordering() && CS::isDualITree(cs) && PU::isDbvMode(mode)) + { + pu.bv = cu.bvs[mode - DBV_CHROMA_IDX]; + pu.mv[0] = cu.mvs[mode - DBV_CHROMA_IDX]; + pu.cu->rribcFlipType = cu.rribcTypes[mode - DBV_CHROMA_IDX]; + predIntraDbv(COMPONENT_Cr, predCr, pu, pcInterPred); + if (pu.cu->rribcFlipType) + { + predCr.flipSignal(pu.cu->rribcFlipType == 1); + } + pu.bv.setZero(); + pu.mv[0].setZero(); + pu.cu->rribcFlipType = 0; + } + else + { +#endif + initPredIntraParams(pu, pu.Cr(), *pu.cs->sps); + predIntraAng(COMPONENT_Cr, predCr, pu); +#if JVET_AH0136_CHROMA_REORDERING + } +#endif } sadCr = distParamSad.distFunc(distParamSad) * 2; satdCr = distParamSatd.distFunc(distParamSatd); sad += std::min(sadCr, satdCr); +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (cu.cs->sps->getUseChromaReordering() && CS::isDualITree(*pu.cs) && PU::isDbvMode(mode) && cu.mvs[mode - DBV_CHROMA_IDX] == Mv()) + { + sad = INT64_MAX; + } +#endif satdSortedCost[idx] = sad; #if JVET_AD0120_LBCCP && MMLM if(mode == MMLM_CHROMA_IDX) @@ -4873,7 +4969,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner if (uiMode < 0) { cu.bdpcmModeChroma = -uiMode; +#if JVET_AH0136_CHROMA_REORDERING + chromaIntraMode = cu.bdpcmModeChroma == 2 ? VER_IDX : HOR_IDX; +#else chromaIntraMode = cu.bdpcmModeChroma == 2 ? chromaCandModes[1] : chromaCandModes[2]; +#endif } else { @@ -4895,7 +4995,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner } #endif #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (PU::isDbvMode(chromaIntraMode) && !PU::hasChromaBvFlag(pu)) +#else if (chromaIntraMode == DBV_CHROMA_IDX && !PU::hasChromaBvFlag(pu)) +#endif { continue; } @@ -5119,6 +5223,9 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner #endif #if JVET_Z0050_DIMD_CHROMA_FUSION +#if JVET_AH0136_CHROMA_REORDERING + cs.setDecomp(pu.Cb(), false); +#endif #if JVET_AC0119_LM_CHROMA_FUSION uint32_t uiFusionModeNum = 2; #if MMLM @@ -5167,8 +5274,25 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner if (PU::hasChromaFusionFlag(pu, chromaIntraMode)) { pu.intraDir[1] = chromaIntraMode; - if (!xCflmCreateChromaPred(pu, COMPONENT_Cb, predStorage[uiMode].Cb()) || - !xCflmCreateChromaPred(pu, COMPONENT_Cr, predStorage[uiMode].Cr())) +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (cu.cs->sps->getUseChromaReordering() && PU::isDbvMode(pu.intraDir[1]) && CS::isDualITree(cs)) + { + pu.bv = cu.bvs[pu.intraDir[1] - DBV_CHROMA_IDX]; + pu.mv[0] = cu.mvs[pu.intraDir[1] - DBV_CHROMA_IDX]; + pu.cu->rribcFlipType = cu.rribcTypes[pu.intraDir[1] - DBV_CHROMA_IDX]; + } +#endif + if (!xCflmCreateChromaPred(pu, COMPONENT_Cb, predStorage[uiMode].Cb() +#if JVET_AH0136_CHROMA_REORDERING + , pcInterPred +#endif + ) || + !xCflmCreateChromaPred(pu, COMPONENT_Cr, predStorage[uiMode].Cr() +#if JVET_AH0136_CHROMA_REORDERING + , pcInterPred +#endif + )) + { break; } @@ -5184,8 +5308,17 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner fusionStorage[idx].Cb().copyFrom( predStorage[uiMode].Cb() ); fusionStorage[idx].Cr().copyFrom( predStorage[uiMode].Cr() ); - geneChromaFusionPred(COMPONENT_Cb, fusionStorage[idx].Cb(), pu); - geneChromaFusionPred(COMPONENT_Cr, fusionStorage[idx].Cr(), pu); + + geneChromaFusionPred(COMPONENT_Cb, fusionStorage[idx].Cb(), pu +#if JVET_AH0136_CHROMA_REORDERING + , pcInterPred +#endif + ); + geneChromaFusionPred(COMPONENT_Cr, fusionStorage[idx].Cr(), pu +#if JVET_AH0136_CHROMA_REORDERING + , pcInterPred +#endif + ); distParamSadCb.cur = fusionStorage[idx].Cb(); distParamSatdCb.cur = fusionStorage[idx].Cb(); @@ -5337,6 +5470,9 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner pu.curCand = {}; #endif #endif +#if JVET_AH0136_CHROMA_REORDERING + cs.setDecomp(pu.Cb(), false); +#endif #if JVET_Z0050_CCLM_SLOPE #if MMLM @@ -5436,6 +5572,10 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner #endif #if JVET_AD0188_CCP_MERGE ccpModelBest = pu.curCand; +#endif + isChromaFusion = pu.isChromaFusion; +#if JVET_AA0126_GLM + bestGlmIdc = pu.glmIdc; #endif } } @@ -8226,6 +8366,9 @@ void IntraSearch::xEncIntraHeader( CodingStructure &cs, Partitioner &partitioner if( isFirst ) { m_CABACEstimator->bdpcm_mode( cu, ComponentID(CHANNEL_TYPE_CHROMA) ); +#if JVET_AH0136_CHROMA_REORDERING + if (!cu.bdpcmModeChroma) +#endif m_CABACEstimator->intra_chroma_pred_mode( pu ); } } @@ -9318,7 +9461,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp } } #if JVET_AC0071_DBV && JVET_AA0070_RRIBC +#if JVET_AH0136_CHROMA_REORDERING + if (compID != COMPONENT_Y && PU::isDbvMode(uiChFinalMode) && pu.cu->rribcFlipType) +#else if (compID != COMPONENT_Y && uiChFinalMode == DBV_CHROMA_IDX && pu.cu->rribcFlipType) +#endif { cs.getRecoBuf(area).flipSignal(pu.cu->rribcFlipType == 1); if (jointCbCr) @@ -11533,12 +11680,23 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio // Do predictions here to avoid repeating the "default0Save1Load2" stuff int predMode = pu.cu->bdpcmModeChroma ? BDPCM_IDX : PU::getFinalIntraMode(pu, CHANNEL_TYPE_CHROMA); #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS && JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (!PU::isDbvMode(predMode) || pu.isChromaFusion > 0) +#else if (predMode != DBV_CHROMA_IDX) +#endif { cs.setDecomp(currArea.Cb(), true); // set in advance (required for Cb2/Cr2 in 4:2:2 video) } #endif - +#if JVET_AH0136_CHROMA_REORDERING && JVET_AC0071_DBV + if (pu.cs->sps->getUseChromaReordering() && PU::isDbvMode(predMode) && CS::isDualITree(cs)) + { + pu.bv = pu.cu->bvs[predMode - DBV_CHROMA_IDX]; + pu.mv[0] = pu.cu->mvs[predMode - DBV_CHROMA_IDX]; + pu.cu->rribcFlipType = pu.cu->rribcTypes[predMode - DBV_CHROMA_IDX]; + } +#endif PelBuf piPredCb = cs.getPredBuf(cbArea); PelBuf piPredCr = cs.getPredBuf(crArea); @@ -11669,7 +11827,11 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio { #endif #if JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (PU::isDbvMode(predMode)) +#else if (predMode == DBV_CHROMA_IDX) +#endif { predIntraDbv(COMPONENT_Cb, piPredCb, pu #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS @@ -11682,6 +11844,9 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio #endif ); #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS && JVET_AC0071_DBV +#if JVET_AH0136_CHROMA_REORDERING + if (pu.isChromaFusion == 0) +#endif cs.setDecomp(currArea.Cb(), true); // set in advance (required for Cb2/Cr2 in 4:2:2 video) #endif } @@ -11696,8 +11861,16 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio #if JVET_Z0050_DIMD_CHROMA_FUSION if (pu.isChromaFusion) { - geneChromaFusionPred(COMPONENT_Cb, piPredCb, pu); - geneChromaFusionPred(COMPONENT_Cr, piPredCr, pu); + geneChromaFusionPred(COMPONENT_Cb, piPredCb, pu +#if JVET_AH0136_CHROMA_REORDERING + , pcInterPred +#endif + ); + geneChromaFusionPred(COMPONENT_Cr, piPredCr, pu +#if JVET_AH0136_CHROMA_REORDERING + , pcInterPred +#endif + ); } #endif #if JVET_AC0119_LM_CHROMA_FUSION @@ -11710,7 +11883,11 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio PelBuf resiCb = cs.getResiBuf(cbArea); PelBuf resiCr = cs.getResiBuf(crArea); #if JVET_AC0071_DBV && JVET_AA0070_RRIBC +#if JVET_AH0136_CHROMA_REORDERING + if (PU::isDbvMode(predMode) && currTU.cu->rribcFlipType) +#else if (predMode == DBV_CHROMA_IDX && currTU.cu->rribcFlipType) +#endif { resiCb.copyFrom(cs.getOrgBuf(cbArea)); resiCr.copyFrom(cs.getOrgBuf(crArea)); diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 16f386e9256b350281f51a5b3f3cf25cdaa94da6..56dcc142ef9dd781ceb6fc98f38f84acea4b8cf7 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1741,6 +1741,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) #if JVET_AD0085_MPM_SORTING WRITE_FLAG(pcSPS->getUseMpmSorting() ? 1 : 0, "sps_mpm_sorting_enabled_flag"); #endif +#if JVET_AH0136_CHROMA_REORDERING + WRITE_FLAG(pcSPS->getUseChromaReordering() ? 1 : 0, "sps_chroma_reordering_enabled_flag"); +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING WRITE_UVLC(pcSPS->getUseCccm() , "sps_cccm_cand"); #endif