diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 5b3e2cc93a99e9e86906865cccec4b993e0b0cbd..c3eef79afcc3beb3fe5a7dc1c62f35d1dedd514e 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -311,9 +311,15 @@ static const int MLS_CG_SIZE = 4; ///< Coef static const int RVM_VCEGAM10_M = 4; +#if JVET_Y0116_EXTENDED_MRL_LIST +static const int MAX_REF_LINE_IDX = 13; //highest refLine offset in the list +static const int MRL_NUM_REF_LINES = 6; //number of candidates in the array +static const int MULTI_REF_LINE_IDX[6] = { 0, 1, 3, 5, 7, 12 }; +#else static const int MAX_REF_LINE_IDX = 3; //highest refLine offset in the list static const int MRL_NUM_REF_LINES = 3; //number of candidates in the array static const int MULTI_REF_LINE_IDX[4] = { 0, 1, 2, 0 }; +#endif static const int PRED_REG_MIN_WIDTH = 4; // Minimum prediction region width for ISP subblocks diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp index 17f56ea8806f6d9e7ded42317cbd6a49543bca6c..c9cfad6ff350a5fcbfcdf9664c2925e4152c675f 100644 --- a/source/Lib/CommonLib/Contexts.cpp +++ b/source/Lib/CommonLib/Contexts.cpp @@ -942,6 +942,23 @@ const CtxSet ContextSetCfg::PredMode = ContextSetCfg::addCtxSet const CtxSet ContextSetCfg::MultiRefLineIdx = ContextSetCfg::addCtxSet ({ +#if JVET_Y0116_EXTENDED_MRL_LIST +#if JVET_W0123_TIMD_FUSION + { 25, 59, 59, 59, 59, 25, 59}, + { 25, 58, 58, 58, 58, 25, 58}, + { 25, 60, 60, 60, 60, 25, 60}, + { 6, 5, 5, 5, 5, 6, 5 }, + { 6, 5, 5, 5, 5, 6, 5 }, + { 6, 8, 8, 8, 8, 6, 8 } +#else + { 25, 59, 59, 59, 59}, + { 25, 58, 58, 58, 58}, + { 25, 60, 60, 60, 60}, + { 6, 5, 5, 5, 5 }, + { 6, 5, 5, 5, 5 }, + { 6, 8, 8, 8, 8 } +#endif +#else #if JVET_W0123_TIMD_FUSION { 25, 59, 25, 59 }, { 25, 58, 25, 58 }, @@ -957,6 +974,7 @@ const CtxSet ContextSetCfg::MultiRefLineIdx = ContextSetCfg::addCtxSet { 6, 5 }, { 6, 8 } #endif +#endif }); const CtxSet ContextSetCfg::IntraLumaMpmFlag = ContextSetCfg::addCtxSet @@ -2172,6 +2190,19 @@ const CtxSet ContextSetCfg::PredMode = ContextSetCfg::addCtxSet const CtxSet ContextSetCfg::MultiRefLineIdx = ContextSetCfg::addCtxSet ({ +#if JVET_Y0116_EXTENDED_MRL_LIST +#if JVET_W0123_TIMD_FUSION + { 25, 59, 59, 59, 59, 25, 59}, + { 25, 58, 58, 58, 58, 25, 58}, + { 25, 60, 60, 60, 60, 25, 60}, + { 5, 8, 8, 8, 8, 5, 8 }, +#else + { 25, 59, 59, 59, 59}, + { 25, 58, 58, 58, 58}, + { 25, 60, 60, 60, 60}, + { 5, 8, 8, 8, 8 }, +#endif +#else #if JVET_W0123_TIMD_FUSION { 25, 59, 25, 59, }, { 25, 58, 25, 58, }, @@ -2183,6 +2214,7 @@ const CtxSet ContextSetCfg::MultiRefLineIdx = ContextSetCfg::addCtxSet { 25, 60, }, { 5, 8, }, #endif +#endif }); const CtxSet ContextSetCfg::IntraLumaMpmFlag = ContextSetCfg::addCtxSet diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index 7c17c8b3298dfc62b6eac79c23886110be42ab72..698b6b63660891a68fb6dcfa6340262b00f7cb12 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -2125,9 +2125,18 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf 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())); + #if JVET_Y0116_EXTENDED_MRL_LIST + int leftMrlUnitNum = multiRefIdx / unitHeight; + int aboveMrlUnitNum = multiRefIdx / unitWidth; +#endif + const int totalAboveUnits = (predSize + (unitWidth - 1)) / unitWidth; const int totalLeftUnits = (predHSize + (unitHeight - 1)) / unitHeight; +#if JVET_Y0116_EXTENDED_MRL_LIST + const int totalUnits = totalAboveUnits + totalLeftUnits + 1 + leftMrlUnitNum + aboveMrlUnitNum; //+1 for top-left +#else const int totalUnits = totalAboveUnits + totalLeftUnits + 1; //+1 for top-left +#endif const int numAboveUnits = std::max<int>( tuWidth / unitWidth, 1 ); const int numLeftUnits = std::max<int>( tuHeight / unitHeight, 1 ); const int numAboveRightUnits = totalAboveUnits - numAboveUnits; @@ -2140,17 +2149,33 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf const Position posRT = area.topRight(); const Position posLB = area.bottomLeft(); +#if JVET_Y0116_EXTENDED_MRL_LIST + bool neighborFlags[4 * MAX_NUM_PART_IDXS_IN_CTU_WIDTH + MAX_REF_LINE_IDX + 1]; +#else bool neighborFlags[4 * MAX_NUM_PART_IDXS_IN_CTU_WIDTH + 1]; +#endif int numIntraNeighbor = 0; memset( neighborFlags, 0, totalUnits ); +#if JVET_Y0116_EXTENDED_MRL_LIST + neighborFlags[totalLeftUnits+leftMrlUnitNum] = isAboveLeftAvailable( cu, chType, posLT.offset(-multiRefIdx, -multiRefIdx) ); + numIntraNeighbor += neighborFlags[totalLeftUnits+leftMrlUnitNum] ? 1 : 0; + numIntraNeighbor += isAboveAvailable ( cu, chType, posLT.offset(-aboveMrlUnitNum*unitWidth, -multiRefIdx), aboveMrlUnitNum, unitWidth, (neighborFlags + totalLeftUnits + 1 + leftMrlUnitNum) ); + numIntraNeighbor += isLeftAvailable ( cu, chType, posLT.offset(-multiRefIdx, -leftMrlUnitNum*unitHeight), leftMrlUnitNum, unitHeight, (neighborFlags + totalLeftUnits - 1 + leftMrlUnitNum) ); + numIntraNeighbor += isAboveAvailable ( cu, chType, posLT.offset(0, -multiRefIdx), numAboveUnits, unitWidth, (neighborFlags + totalLeftUnits + 1 + leftMrlUnitNum + aboveMrlUnitNum) ); + numIntraNeighbor += isAboveRightAvailable( cu, chType, posRT.offset(0, -multiRefIdx), numAboveRightUnits, unitWidth, (neighborFlags + totalLeftUnits + 1 + leftMrlUnitNum + aboveMrlUnitNum + numAboveUnits) ); + numIntraNeighbor += isLeftAvailable ( cu, chType, posLT.offset(-multiRefIdx, 0), numLeftUnits, unitHeight, (neighborFlags + totalLeftUnits - 1) ); + numIntraNeighbor += isBelowLeftAvailable ( cu, chType, posLB.offset(-multiRefIdx, 0), numLeftBelowUnits, unitHeight, (neighborFlags + totalLeftUnits - 1 - numLeftUnits) ); + +#else neighborFlags[totalLeftUnits] = isAboveLeftAvailable( cu, chType, posLT ); numIntraNeighbor += neighborFlags[totalLeftUnits] ? 1 : 0; numIntraNeighbor += isAboveAvailable ( cu, chType, posLT, numAboveUnits, unitWidth, (neighborFlags + totalLeftUnits + 1) ); numIntraNeighbor += isAboveRightAvailable( cu, chType, posRT, numAboveRightUnits, unitWidth, (neighborFlags + totalLeftUnits + 1 + numAboveUnits) ); numIntraNeighbor += isLeftAvailable ( cu, chType, posLT, numLeftUnits, unitHeight, (neighborFlags + totalLeftUnits - 1) ); numIntraNeighbor += isBelowLeftAvailable ( cu, chType, posLB, numLeftBelowUnits, unitHeight, (neighborFlags + totalLeftUnits - 1 - numLeftUnits) ); +#endif // ----- Step 2: fill reference samples (depending on neighborhood) ----- @@ -2189,11 +2214,19 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf // Fill top-left sample(s) if available ptrSrc = srcBuf - (1 + multiRefIdx) * srcStride - (1 + multiRefIdx); ptrDst = refBufUnfiltered; +#if JVET_Y0116_EXTENDED_MRL_LIST + if (neighborFlags[totalLeftUnits+leftMrlUnitNum]) +#else if (neighborFlags[totalLeftUnits]) +#endif { ptrDst[0] = ptrSrc[0]; ptrDst[predStride] = ptrSrc[0]; +#if JVET_Y0116_EXTENDED_MRL_LIST + for (int i = 1; i <= multiRefIdx-leftMrlUnitNum*unitHeight; i++) +#else for (int i = 1; i <= multiRefIdx; i++) +#endif { ptrDst[i] = ptrSrc[i]; ptrDst[i + predStride] = ptrSrc[i * srcStride]; @@ -2201,9 +2234,18 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf } // Fill left & below-left samples if available (downwards) +#if JVET_Y0116_EXTENDED_MRL_LIST + ptrSrc += (1 + multiRefIdx-leftMrlUnitNum*unitHeight) * srcStride; + ptrDst += (1 + multiRefIdx-leftMrlUnitNum*unitHeight) + predStride; +#else ptrSrc += (1 + multiRefIdx) * srcStride; ptrDst += (1 + multiRefIdx) + predStride; +#endif +#if JVET_Y0116_EXTENDED_MRL_LIST + for (int unitIdx = totalLeftUnits + leftMrlUnitNum - 1; unitIdx > 0; unitIdx--) +#else for (int unitIdx = totalLeftUnits - 1; unitIdx > 0; unitIdx--) +#endif { if (neighborFlags[unitIdx]) { @@ -2226,9 +2268,18 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf } // Fill above & above-right samples if available (left-to-right) +#if JVET_Y0116_EXTENDED_MRL_LIST + ptrSrc = srcBuf - srcStride * (1 + multiRefIdx ) - aboveMrlUnitNum*unitWidth; + ptrDst = refBufUnfiltered + 1 + multiRefIdx - aboveMrlUnitNum*unitWidth; +#else ptrSrc = srcBuf - srcStride * (1 + multiRefIdx); ptrDst = refBufUnfiltered + 1 + multiRefIdx; +#endif +#if JVET_Y0116_EXTENDED_MRL_LIST + for (int unitIdx = totalLeftUnits + leftMrlUnitNum + 1; unitIdx < totalUnits - 1; unitIdx++) +#else for (int unitIdx = totalLeftUnits + 1; unitIdx < totalUnits - 1; unitIdx++) +#endif { if (neighborFlags[unitIdx]) { @@ -2264,6 +2315,21 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf // first available sample int firstAvailRow = -1; int firstAvailCol = 0; + +#if JVET_Y0116_EXTENDED_MRL_LIST + if (firstAvailUnit < totalLeftUnits + leftMrlUnitNum) + { + firstAvailRow = (totalLeftUnits + leftMrlUnitNum - firstAvailUnit) * unitHeight + multiRefIdx - leftMrlUnitNum * unitHeight; + } + else if (firstAvailUnit == totalLeftUnits + leftMrlUnitNum) + { + firstAvailRow = multiRefIdx - leftMrlUnitNum * unitHeight; + } + else + { + firstAvailCol = (firstAvailUnit - totalLeftUnits - leftMrlUnitNum - 1) * unitWidth + 1 + multiRefIdx - aboveMrlUnitNum * unitWidth; + } +#else if (firstAvailUnit < totalLeftUnits) { firstAvailRow = (totalLeftUnits - firstAvailUnit) * unitHeight + multiRefIdx; @@ -2276,6 +2342,7 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf { firstAvailCol = (firstAvailUnit - totalLeftUnits - 1) * unitWidth + 1 + multiRefIdx; } +#endif const Pel firstAvailSample = ptrDst[firstAvailRow < 0 ? firstAvailCol : firstAvailRow + predStride]; // last sample below-left (n.a.) @@ -2306,6 +2373,20 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf // last available sample int lastAvailRow = -1; int lastAvailCol = 0; +#if JVET_Y0116_EXTENDED_MRL_LIST + if (lastAvailUnit < totalLeftUnits + leftMrlUnitNum) + { + lastAvailRow = (totalLeftUnits + leftMrlUnitNum - lastAvailUnit - 1) * unitHeight + multiRefIdx - leftMrlUnitNum * unitHeight + 1; + } + else if (lastAvailUnit == totalLeftUnits + leftMrlUnitNum) + { + lastAvailCol = multiRefIdx- leftMrlUnitNum * unitHeight; + } + else + { + lastAvailCol = (lastAvailUnit - totalLeftUnits - leftMrlUnitNum) * unitWidth + multiRefIdx - aboveMrlUnitNum * unitWidth; + } +#else if (lastAvailUnit < totalLeftUnits) { lastAvailRow = (totalLeftUnits - lastAvailUnit - 1) * unitHeight + multiRefIdx + 1; @@ -2318,9 +2399,38 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf { lastAvailCol = (lastAvailUnit - totalLeftUnits) * unitWidth + multiRefIdx; } +#endif const Pel lastAvailSample = ptrDst[lastAvailRow < 0 ? lastAvailCol : lastAvailRow + predStride]; // fill current unit with last available sample +#if JVET_Y0116_EXTENDED_MRL_LIST + if (currUnit < totalLeftUnits + leftMrlUnitNum) + { + for (int i = lastAvailRow - 1; i >= lastAvailRow - unitHeight; i--) + { + ptrDst[i + predStride] = lastAvailSample; + } + } + else if (currUnit == totalLeftUnits + leftMrlUnitNum) + { + for (int i = 0; i < multiRefIdx - leftMrlUnitNum * unitHeight + 1; i++) + { + ptrDst[i + predStride] = lastAvailSample; + } + for (int j = 0; j < multiRefIdx - aboveMrlUnitNum * unitWidth + 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; + } + } +#else if (currUnit < totalLeftUnits) { for (int i = lastAvailRow - 1; i >= lastAvailRow - unitHeight; i--) @@ -2347,6 +2457,7 @@ void IntraPrediction::xFillReferenceSamples( const CPelBuf &recoBuf, Pel* refBuf ptrDst[j] = lastAvailSample; } } +#endif } lastAvailUnit = currUnit; currUnit++; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 4a3e90208f596ed875eff52d0ca73dedddbf132c..b8934415c17900d10fbb71b0033c739a00de5f67 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -125,6 +125,8 @@ #define JVET_X0149_TIMD_DIMD_LUT 1 // JVET-X0149: LUT-based derivation of DIMD and TIMD #endif +#define JVET_Y0116_EXTENDED_MRL_LIST 1 // JVET-Y0116: Extended MRL Candidate List + // Inter #define CIIP_PDPC 1 // apply pdpc to megre prediction as a new CIIP mode (CIIP_PDPC) additional to CIIP mode #define JVET_X0090_CIIP_FIX 1 // JVET-X0090: combination of CIIP, OBMC and LMCS diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 9451ae55ce2de770d9e4a68adbd275cc81fd7a75..7f12033f2f86ebd62dca59ae3208687a0fbcc2fb 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -1813,6 +1813,40 @@ void CABACReader::extend_ref_line(CodingUnit& cu) } int multiRefIdx = 0; +#if JVET_Y0116_EXTENDED_MRL_LIST + if (MRL_NUM_REF_LINES > 1) + { +#if JVET_W0123_TIMD_FUSION + multiRefIdx = m_BinDecoder.decodeBin(cu.timd ? Ctx::MultiRefLineIdx(5) : Ctx::MultiRefLineIdx(0)) == 1 ? MULTI_REF_LINE_IDX[1] : MULTI_REF_LINE_IDX[0]; +#else + multiRefIdx = m_BinDecoder.decodeBin(Ctx::MultiRefLineIdx(0)) == 1 ? MULTI_REF_LINE_IDX[1] : MULTI_REF_LINE_IDX[0]; +#endif + if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0]) + { +#if JVET_W0123_TIMD_FUSION + multiRefIdx = m_BinDecoder.decodeBin(cu.timd ? Ctx::MultiRefLineIdx(6) : Ctx::MultiRefLineIdx(1)) == 1 ? MULTI_REF_LINE_IDX[2] : MULTI_REF_LINE_IDX[1]; +#else + multiRefIdx = m_BinDecoder.decodeBin(Ctx::MultiRefLineIdx(1)) == 1 ? MULTI_REF_LINE_IDX[2] : MULTI_REF_LINE_IDX[1]; +#endif + if (MRL_NUM_REF_LINES > 3 && multiRefIdx != MULTI_REF_LINE_IDX[1] +#if JVET_W0123_TIMD_FUSION + && !cu.timd +#endif + ) + { + multiRefIdx = m_BinDecoder.decodeBin(Ctx::MultiRefLineIdx(2)) == 1 ? MULTI_REF_LINE_IDX[3] : MULTI_REF_LINE_IDX[2]; + if (MRL_NUM_REF_LINES > 4 && multiRefIdx != MULTI_REF_LINE_IDX[2]) + { + multiRefIdx = m_BinDecoder.decodeBin(Ctx::MultiRefLineIdx(3)) == 1 ? MULTI_REF_LINE_IDX[4] : MULTI_REF_LINE_IDX[3]; + if (MRL_NUM_REF_LINES > 5 && multiRefIdx != MULTI_REF_LINE_IDX[3]) + { + multiRefIdx = m_BinDecoder.decodeBin(Ctx::MultiRefLineIdx(4)) == 1 ? MULTI_REF_LINE_IDX[5] : MULTI_REF_LINE_IDX[4]; + } + } + } + } + } +#else if (MRL_NUM_REF_LINES > 1) { #if JVET_W0123_TIMD_FUSION @@ -1830,6 +1864,7 @@ void CABACReader::extend_ref_line(CodingUnit& cu) } } +#endif pu->multiRefIdx = multiRefIdx; pu = pu->next; } diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 49e941741fd0441763d4b31d42aff4f5a883e5cd..024d94405fcaca1194b9e8caca34dab3278893e1 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -1267,6 +1267,40 @@ void CABACWriter::extend_ref_line(const PredictionUnit& pu) return; } int multiRefIdx = pu.multiRefIdx; +#if JVET_Y0116_EXTENDED_MRL_LIST + if (MRL_NUM_REF_LINES > 1) + { +#if JVET_W0123_TIMD_FUSION + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], cu.timd ? Ctx::MultiRefLineIdx(5) : Ctx::MultiRefLineIdx(0)); +#else + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0)); +#endif + if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0]) + { +#if JVET_W0123_TIMD_FUSION + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], cu.timd ? Ctx::MultiRefLineIdx(6) : Ctx::MultiRefLineIdx(1)); +#else + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1)); +#endif + if (MRL_NUM_REF_LINES > 3 && multiRefIdx != MULTI_REF_LINE_IDX[1] +#if JVET_W0123_TIMD_FUSION + && !cu.timd +#endif + ) + { + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[2], Ctx::MultiRefLineIdx(2)); + if (MRL_NUM_REF_LINES > 4 && multiRefIdx != MULTI_REF_LINE_IDX[2]) + { + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[3], Ctx::MultiRefLineIdx(3)); + if (MRL_NUM_REF_LINES > 5 && multiRefIdx != MULTI_REF_LINE_IDX[3]) + { + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[4], Ctx::MultiRefLineIdx(4)); + } + } + } + } + } +#else if (MRL_NUM_REF_LINES > 1) { #if JVET_W0123_TIMD_FUSION @@ -1283,6 +1317,7 @@ void CABACWriter::extend_ref_line(const PredictionUnit& pu) #endif } } +#endif } void CABACWriter::extend_ref_line(const CodingUnit& cu) @@ -1312,6 +1347,40 @@ void CABACWriter::extend_ref_line(const CodingUnit& cu) return; } int multiRefIdx = pu->multiRefIdx; +#if JVET_Y0116_EXTENDED_MRL_LIST + if (MRL_NUM_REF_LINES > 1) + { +#if JVET_W0123_TIMD_FUSION + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], cu.timd ? Ctx::MultiRefLineIdx(5) : Ctx::MultiRefLineIdx(0)); +#else + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0)); +#endif + if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0]) + { +#if JVET_W0123_TIMD_FUSION + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], cu.timd ? Ctx::MultiRefLineIdx(6) : Ctx::MultiRefLineIdx(1)); +#else + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1)); +#endif + if (MRL_NUM_REF_LINES > 3 && multiRefIdx != MULTI_REF_LINE_IDX[1] +#if JVET_W0123_TIMD_FUSION + && !cu.timd +#endif + ) + { + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[2], Ctx::MultiRefLineIdx(2)); + if (MRL_NUM_REF_LINES > 4 && multiRefIdx != MULTI_REF_LINE_IDX[2]) + { + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[3], Ctx::MultiRefLineIdx(3)); + if (MRL_NUM_REF_LINES > 5 && multiRefIdx != MULTI_REF_LINE_IDX[3]) + { + m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[4], Ctx::MultiRefLineIdx(4)); + } + } + } + } + } +#else if (MRL_NUM_REF_LINES > 1) { #if JVET_W0123_TIMD_FUSION @@ -1329,6 +1398,7 @@ void CABACWriter::extend_ref_line(const CodingUnit& cu) } } +#endif pu = pu->next; } } diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp index 4112d72d053c3793d578c18a6f657e082626e3ce..a643c5249ccccab84bc25de7132ceaa309fbdec8 100644 --- a/source/Lib/EncoderLib/IntraSearch.cpp +++ b/source/Lib/EncoderLib/IntraSearch.cpp @@ -595,7 +595,41 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c // this should always be true CHECK(!pu.Y().valid(), "PU is not valid"); bool isFirstLineOfCtu = (((pu.block(COMPONENT_Y).y) & ((pu.cs->sps)->getMaxCUWidth() - 1)) == 0); +#if JVET_Y0116_EXTENDED_MRL_LIST + int numOfPassesExtendRef = MRL_NUM_REF_LINES; + if (!sps.getUseMRL() || isFirstLineOfCtu) + { + numOfPassesExtendRef = 1; + } + else + { + bool checkLineOutsideCtu[MRL_NUM_REF_LINES - 1]; + for (int mrlIdx = 1; mrlIdx < MRL_NUM_REF_LINES; mrlIdx++) + { + bool isLineOutsideCtu = + ((cu.block(COMPONENT_Y).y) % ((cu.cs->sps)->getMaxCUWidth()) <= MULTI_REF_LINE_IDX[mrlIdx]) ? true + : false; + checkLineOutsideCtu[mrlIdx-1] = isLineOutsideCtu; + } + if (checkLineOutsideCtu[0]) + { + numOfPassesExtendRef = 1; + } + else + { + for (int mrlIdx = MRL_NUM_REF_LINES - 2; mrlIdx > 0; mrlIdx--) + { + if (checkLineOutsideCtu[mrlIdx] && !checkLineOutsideCtu[mrlIdx - 1]) + { + numOfPassesExtendRef = mrlIdx + 1; + break; + } + } + } + } +#else int numOfPassesExtendRef = ((!sps.getUseMRL() || isFirstLineOfCtu) ? 1 : MRL_NUM_REF_LINES); +#endif pu.multiRefIdx = 0; if (numModesForFullRD != numModesAvailable) @@ -1238,7 +1272,37 @@ bool IntraSearch::estIntraPredLumaQT(CodingUnit &cu, Partitioner &partitioner, c if (lfnstIdx == 0 && !cu.mtsFlag) { bool isFirstLineOfCtu = (((pu.block(COMPONENT_Y).y) & ((pu.cs->sps)->getMaxCUWidth() - 1)) == 0); +#if JVET_Y0116_EXTENDED_MRL_LIST + int numOfPassesExtendRef = 3; + if (!sps.getUseMRL() || isFirstLineOfCtu) + { + numOfPassesExtendRef = 1; + } + else + { + bool checkLineOutsideCtu[2]; + for (int mrlIdx = 1; mrlIdx < 3; mrlIdx++) + { + bool isLineOutsideCtu = + ((cu.block(COMPONENT_Y).y) % ((cu.cs->sps)->getMaxCUWidth()) <= MULTI_REF_LINE_IDX[mrlIdx]) ? true + : false; + checkLineOutsideCtu[mrlIdx-1] = isLineOutsideCtu; + } + if (checkLineOutsideCtu[0]) + { + numOfPassesExtendRef = 1; + } + else + { + if (checkLineOutsideCtu[1] && !checkLineOutsideCtu[0]) + { + numOfPassesExtendRef = 2; + } + } + } +#else int numOfPassesExtendRef = ((!sps.getUseMRL() || isFirstLineOfCtu) ? 1 : MRL_NUM_REF_LINES); +#endif for (int mRefNum = 1; mRefNum < numOfPassesExtendRef; mRefNum++) { int multiRefIdx = MULTI_REF_LINE_IDX[mRefNum];