diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp index cdd826d76c95822b277d94ee9d469bcf4ab68ab9..1a7f7aab297c3d747d237f2c9091f10e2dbc8701 100644 --- a/source/Lib/CommonLib/CodingStructure.cpp +++ b/source/Lib/CommonLib/CodingStructure.cpp @@ -207,7 +207,12 @@ const int CodingStructure::signalModeCons( const PartSplit split, Partitioner &p minLumaArea = minLumaArea >> 1; } int minChromaBlock = minLumaArea >> (getChannelTypeScaleX(CHANNEL_TYPE_CHROMA, partitioner.currArea().chromaFormat) + getChannelTypeScaleY(CHANNEL_TYPE_CHROMA, partitioner.currArea().chromaFormat)); +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + bool is2xNChroma = (partitioner.currArea().chromaSize().width == 4 && split == CU_VERT_SPLIT) || (partitioner.currArea().chromaSize().width == 8 && split == CU_TRIV_SPLIT); + return minChromaBlock >= 16 && !is2xNChroma ? LDT_MODE_TYPE_INHERIT : ((minLumaArea < 32) || slice->isIntra()) ? LDT_MODE_TYPE_INFER : LDT_MODE_TYPE_SIGNAL; +#else return minChromaBlock >= 16 ? LDT_MODE_TYPE_INHERIT : ((minLumaArea < 32) || slice->isIntra()) ? LDT_MODE_TYPE_INFER : LDT_MODE_TYPE_SIGNAL; +#endif #else int width = partitioner.currArea().lwidth(); int height = partitioner.currArea().lheight(); @@ -219,13 +224,20 @@ const int CodingStructure::signalModeCons( const PartSplit split, Partitioner &p else // bt return slice->isIntra() ? LDT_MODE_TYPE_INFER : LDT_MODE_TYPE_SIGNAL; } - else if( width * height == 128 ) +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + else if (((width * height == 128) && (split == CU_TRIH_SPLIT || split == CU_TRIV_SPLIT)) || (width == 8 && split == CU_VERT_SPLIT) || (width == 16 && split == CU_TRIV_SPLIT)) + { + return slice->isIntra() ? LDT_MODE_TYPE_INFER : LDT_MODE_TYPE_SIGNAL; + } +#else + else if (width * height == 128) { - if( split == CU_TRIH_SPLIT || split == CU_TRIV_SPLIT ) // tt + if (split == CU_TRIH_SPLIT || split == CU_TRIV_SPLIT) // tt return slice->isIntra() ? LDT_MODE_TYPE_INFER : LDT_MODE_TYPE_SIGNAL; else // bt return LDT_MODE_TYPE_INHERIT; } +#endif else { return LDT_MODE_TYPE_INHERIT; diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index 01295fa4e31ca594aec6b52a1800ac349a7e5c75..263b138ca48d1ef1b2ba5f6d42baac4caa95bb93 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -265,6 +265,9 @@ void IntraPrediction::predIntraAng( const ComponentID compId, PelBuf &piPred, co const ChannelType channelType = toChannelType( compID ); const int iWidth = piPred.width; const int iHeight = piPred.height; +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + CHECK(iWidth == 2, "Width of 2 is not supported"); +#endif const uint32_t uiDirMode = isLuma( compId ) && pu.cu->bdpcmMode ? BDPCM_IDX : PU::getFinalIntraMode( pu, channelType ); CHECK( floorLog2(iWidth) < 2 && pu.cs->pcv->noChroma2x2, "Size not allowed" ); @@ -740,6 +743,9 @@ bool IntraPrediction::useDPCMForFirstPassIntraEstimation(const PredictionUnit &p void IntraPrediction::geneWeightedPred(const ComponentID compId, PelBuf &pred, const PredictionUnit &pu, Pel *srcBuf) { const int width = pred.width; +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + CHECK(width == 2, "Width of 2 is not supported"); +#endif const int height = pred.height; const int srcStride = width; const int dstStride = pred.stride; @@ -801,15 +807,24 @@ void IntraPrediction::geneIntrainterPred(const CodingUnit &cu) initIntraPatternChType(cu, pu->Y()); predIntraAng(COMPONENT_Y, cu.cs->getPredBuf(*pu).Y(), *pu); +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + if (pu->chromaSize().width > 2) + { +#endif + initIntraPatternChType(cu, pu->Cb()); + predIntraAng(COMPONENT_Cb, cu.cs->getPredBuf(*pu).Cb(), *pu); - initIntraPatternChType(cu, pu->Cb()); - predIntraAng(COMPONENT_Cb, cu.cs->getPredBuf(*pu).Cb(), *pu); - - initIntraPatternChType(cu, pu->Cr()); - predIntraAng(COMPONENT_Cr, cu.cs->getPredBuf(*pu).Cr(), *pu); - + initIntraPatternChType(cu, pu->Cr()); + predIntraAng(COMPONENT_Cr, cu.cs->getPredBuf(*pu).Cr(), *pu); +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + } +#endif for (int currCompID = 0; currCompID < 3; currCompID++) { +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + if (pu->chromaSize().width <= 2 && currCompID > 0) + continue; +#endif ComponentID currCompID2 = (ComponentID)currCompID; PelBuf tmpBuf = currCompID == 0 ? cu.cs->getPredBuf(*pu).Y() : (currCompID == 1 ? cu.cs->getPredBuf(*pu).Cb() : cu.cs->getPredBuf(*pu).Cr()); switchBuffer(*pu, currCompID2, tmpBuf, getPredictorPtr2(currCompID2, 0)); @@ -824,6 +839,9 @@ inline int isBelowLeftAvailable ( const CodingUnit &cu, const ChannelType &chT void IntraPrediction::initIntraPatternChType(const CodingUnit &cu, const CompArea &area, const bool forceRefFilterFlag) { +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + CHECK(area.width == 2, "Width of 2 is not supported"); +#endif const CodingStructure& cs = *cu.cs; if (!forceRefFilterFlag) diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index e77565e139e99e6010b485ee6160203043cb6465..579b04df078b99fd9214e84a2ae3e8c90e2b9e85 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_P0641_REMOVE_2xN_CHROMA_INTRA 1 // JVET-P0641: removing 2xN chroma intra blocks + #define JVET_P0206_TMVP_flags 1 // JVET-P0206: Signalling TMVP usage (remove pps TMVP idc and constraint when RPR is used) #define JVET_P0599_INTRA_SMOOTHING_INTERP_FILT 1 // JVET-P0599: Cleanup of interpolation filtering for intra prediction diff --git a/source/Lib/CommonLib/UnitPartitioner.cpp b/source/Lib/CommonLib/UnitPartitioner.cpp index 362ba8e22d1465a60e781bc1dc8f23ea307048aa..68bf1fda14047ca3eaafba5c5bbc86b51da5f2e5 100644 --- a/source/Lib/CommonLib/UnitPartitioner.cpp +++ b/source/Lib/CommonLib/UnitPartitioner.cpp @@ -395,7 +395,9 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca canBh = implicitSplit == CU_HORZ_SPLIT; canBv = implicitSplit == CU_VERT_SPLIT; - +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + if (chType == CHANNEL_TYPE_CHROMA && areaC.width == 4) canBv = false; +#endif return; } @@ -434,7 +436,11 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca if( chType == CHANNEL_TYPE_CHROMA && areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE ) canBh = false; if( area.width <= minBtSize ) canBv = false; if( area.width <= MAX_TB_SIZEY && area.height > MAX_TB_SIZEY ) canBv = false; +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + if (chType == CHANNEL_TYPE_CHROMA && (areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE || areaC.width == 4)) canBv = false; +#else if( chType == CHANNEL_TYPE_CHROMA && areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE ) canBv = false; +#endif #if JVET_P0063_LDT_SPLIT_FIX if( modeType == MODE_TYPE_INTER && area.width * area.height == 32 ) canBv = canBh = false; #endif @@ -445,7 +451,11 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca if( area.width <= 2 * minTtSize || area.width > maxTtSize || area.height > maxTtSize ) canTv = false; if( area.width > MAX_TB_SIZEY || area.height > MAX_TB_SIZEY ) canTv = false; +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + if (chType == CHANNEL_TYPE_CHROMA && (areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE * 2 || areaC.width == 8)) canTv = false; +#else if( chType == CHANNEL_TYPE_CHROMA && areaC.width * areaC.height <= MIN_DUALTREE_CHROMA_SIZE*2 ) canTv = false; +#endif #if JVET_P0063_LDT_SPLIT_FIX if( modeType == MODE_TYPE_INTER && area.width * area.height == 64 ) canTv = canTh = false; #endif diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index 32db51ed89858f27fb5167a470861ac3a050b3e2..13ae6e5be9330fef0fdde60bd9f7236bfc2337d1 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -574,8 +574,15 @@ void DecCu::xReconInter(CodingUnit &cu) cu.cs->getPredBuf(*cu.firstPU).Y().rspSignal(m_pcReshape->getFwdLUT()); } m_pcIntraPred->geneWeightedPred(COMPONENT_Y, cu.cs->getPredBuf(*cu.firstPU).Y(), *cu.firstPU, m_pcIntraPred->getPredictorPtr2(COMPONENT_Y, 0)); - m_pcIntraPred->geneWeightedPred(COMPONENT_Cb, cu.cs->getPredBuf(*cu.firstPU).Cb(), *cu.firstPU, m_pcIntraPred->getPredictorPtr2(COMPONENT_Cb, 0)); - m_pcIntraPred->geneWeightedPred(COMPONENT_Cr, cu.cs->getPredBuf(*cu.firstPU).Cr(), *cu.firstPU, m_pcIntraPred->getPredictorPtr2(COMPONENT_Cr, 0)); +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + if (cu.chromaSize().width > 2) + { +#endif + m_pcIntraPred->geneWeightedPred(COMPONENT_Cb, cu.cs->getPredBuf(*cu.firstPU).Cb(), *cu.firstPU, m_pcIntraPred->getPredictorPtr2(COMPONENT_Cb, 0)); + m_pcIntraPred->geneWeightedPred(COMPONENT_Cr, cu.cs->getPredBuf(*cu.firstPU).Cr(), *cu.firstPU, m_pcIntraPred->getPredictorPtr2(COMPONENT_Cr, 0)); +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + } +#endif } DTRACE ( g_trace_ctx, D_TMP, "pred " ); diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index 5788126d7cb38d387640999f02417e23b7daed78..4a2c2e88a7586e1d2fb16a10785eab9348c0cf90 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -2575,6 +2575,10 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& { pu.intraDir[0] = PLANAR_IDX; pu.intraDir[1] = DM_CHROMA_IDX; +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + if (pu.chromaSize().width == 2) + continue; +#endif uint32_t bufIdx = 0; m_pcIntraSearch->initIntraPatternChType(*pu.cu, pu.Cb()); m_pcIntraSearch->predIntraAng(COMPONENT_Cb, pu.cs->getPredBuf(pu).Cb(), pu); @@ -2713,12 +2717,26 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *& tmpBuf.rspSignal(m_pcReshape->getFwdLUT()); } m_pcIntraSearch->geneWeightedPred(COMPONENT_Y, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Y, bufIdx)); +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + if (pu.chromaSize().width > 2) + { +#endif tmpBuf = tempCS->getPredBuf(pu).Cb(); tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cb()); m_pcIntraSearch->geneWeightedPred(COMPONENT_Cb, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Cb, bufIdx)); tmpBuf = tempCS->getPredBuf(pu).Cr(); tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cr()); m_pcIntraSearch->geneWeightedPred(COMPONENT_Cr, tmpBuf, pu, m_pcIntraSearch->getPredictorPtr2(COMPONENT_Cr, bufIdx)); +#if JVET_P0641_REMOVE_2xN_CHROMA_INTRA + } + else + { + tmpBuf = tempCS->getPredBuf(pu).Cb(); + tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cb()); + tmpBuf = tempCS->getPredBuf(pu).Cr(); + tmpBuf.copyFrom(acMergeTmpBuffer[uiMergeCand].Cr()); + } +#endif } else {