[x265] [PATCH SCC 03/09] Modify reference picture list for IntrablockCopy mode

patoo34 at free.fr patoo34 at free.fr
Wed Aug 7 20:58:29 UTC 2024


STOP STOP STOP STOP STOP
don't send me anything anymore


----- Mail original -----
> 
> 
> From 21c8be0de09076b700db5eeb6336b95c2587e848 Mon Sep 17 00:00:00
> 2001
> From: Kirithika < kirithika at multicorewareinc.com >
> Date: Thu, 18 Jul 2024 21:15:11 +0530
> Subject: [PATCH 3/9] Modify reference picture list for IntrablockCopy
> mode
> 
> ---
> source/common/cudata.cpp | 7 +++++--
> source/common/piclist.h | 2 +-
> source/common/slice.cpp | 27 +++++++++++++++++++++++++--
> source/common/slice.h | 1 +
> source/encoder/analysis.cpp | 7 +++++--
> source/encoder/dpb.cpp | 9 ++++++---
> source/encoder/encoder.cpp | 9 ++++++---
> source/encoder/entropy.cpp | 6 ++++++
> source/encoder/frameencoder.cpp | 8 ++++++++
> source/encoder/ratecontrol.cpp | 2 +-
> source/encoder/search.cpp | 23 ++++++++++++++++++-----
> source/encoder/search.h | 2 ++
> source/encoder/slicetype.cpp | 2 +-
> source/encoder/weightPrediction.cpp | 6 +++++-
> 14 files changed, 90 insertions(+), 21 deletions(-)
> 
> diff --git a/source/common/cudata.cpp b/source/common/cudata.cpp
> index c0d68bc5f..ddee2b52b 100644
> --- a/source/common/cudata.cpp
> +++ b/source/common/cudata.cpp
> @@ -1681,10 +1681,13 @@ uint32_t
> CUData::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx,
> MV
> }
> }
> }
> - int numRefIdx = (isInterB) ? X265_MIN(m_slice->m_numRefIdx[0],
> m_slice->m_numRefIdx[1]) : m_slice->m_numRefIdx[0];
> + int numRefIdx0 = m_slice->m_numRefIdx[0];
> + if (m_slice->m_param->bEnableSCC)
> + numRefIdx0--;
> + int numRefIdx = (isInterB) ? X265_MIN(numRefIdx0,
> m_slice->m_numRefIdx[1]) : numRefIdx0;
> int r = 0;
> int refcnt = 0;
> - while (count < maxNumMergeCand)
> + while (numRefIdx && (count < maxNumMergeCand))
> {
> candDir[count] = 1;
> candMvField[count][0].mv.word = 0;
> diff --git a/source/common/piclist.h b/source/common/piclist.h
> index d270d0aec..dae253d8b 100644
> --- a/source/common/piclist.h
> +++ b/source/common/piclist.h
> @@ -69,7 +69,7 @@ public:
> Frame* popFront();
> 
> /** Find frame with specified POC */
> - Frame* getPOC(int poc, int sLayerId);
> + Frame* getPOC(int poc, int sLayerId = 0);
> /* Find next MCSTF frame with specified POC */
> Frame* getPOCMCSTF(int poc);
> 
> diff --git a/source/common/slice.cpp b/source/common/slice.cpp
> index 7f62695ee..badcb7671 100644
> --- a/source/common/slice.cpp
> +++ b/source/common/slice.cpp
> @@ -64,6 +64,15 @@ void Slice::setRefPicList(PicList& picList,
> PicList& refPicSetInterLayer0, PicLi
> return;
> }
> 
> + /*Reset the number of references for I-slice marked as P-slice*/
> + if (m_param->bEnableSCC && m_sliceType != m_origSliceType)
> + {
> + memset(m_refFrameList, 0, sizeof(m_refFrameList));
> + memset(m_refReconPicList, 0, sizeof(m_refReconPicList));
> + memset(m_refPOCList, 0, sizeof(m_refPOCList));
> + m_numRefIdx[0] = 1;
> + }
> +
> Frame* refPic = NULL;
> Frame* refPicSetStCurr0[MAX_NUM_REF];
> Frame* refPicSetStCurr1[MAX_NUM_REF];
> @@ -75,7 +84,7 @@ void Slice::setRefPicList(PicList& picList,
> PicList& refPicSetInterLayer0, PicLi
> 
> for (i = 0; i < m_rps.numberOfNegativePictures; i++)
> {
> - if (m_rps.bUsed[i])
> + if (m_rps.bUsed[i] && m_origSliceType != I_SLICE)
> {
> refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i], m_rps.deltaPOC[i]
> ? sLayerId : 0);
> refPicSetStCurr0[numPocStCurr0] = refPic;
> @@ -85,7 +94,7 @@ void Slice::setRefPicList(PicList& picList,
> PicList& refPicSetInterLayer0, PicLi
> 
> for (; i < m_rps.numberOfNegativePictures +
> m_rps.numberOfPositivePictures; i++)
> {
> - if (m_rps.bUsed[i])
> + if (m_rps.bUsed[i] && m_origSliceType != I_SLICE)
> {
> refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i], m_rps.deltaPOC[i]
> ? sLayerId : 0);
> refPicSetStCurr1[numPocStCurr1] = refPic;
> @@ -105,6 +114,9 @@ void Slice::setRefPicList(PicList& picList,
> PicList& refPicSetInterLayer0, PicLi
> int numPocTotalCurr = numPocStCurr0 + numPocStCurr1 + numPocLtCurr;
> #endif
> 
> + if (m_param->bEnableSCC)
> + numPocTotalCurr++;
> +
> int cIdx = 0;
> for (i = 0; i < numPocStCurr0; i++, cIdx++)
> rpsCurrList0[cIdx] = refPicSetStCurr0[i];
> @@ -127,6 +139,9 @@ void Slice::setRefPicList(PicList& picList,
> PicList& refPicSetInterLayer0, PicLi
> rpsCurrList0[cIdx] = refPicSetInterLayer1.getPOC(m_poc, 0);
> #endif
> 
> + if (m_param->bEnableSCC)
> + rpsCurrList0[cIdx++] = picList.getPOC(m_poc);
> +
> X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n");
> 
> if (m_sliceType == B_SLICE)
> @@ -153,6 +168,9 @@ void Slice::setRefPicList(PicList& picList,
> PicList& refPicSetInterLayer0, PicLi
> rpsCurrList1[cIdx] = refPicSetInterLayer0.getPOC(m_poc, 0);
> #endif
> 
> + if (m_param->bEnableSCC)
> + rpsCurrList1[cIdx++] = picList.getPOC(m_poc);
> +
> X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n");
> }
> 
> @@ -166,6 +184,11 @@ void Slice::setRefPicList(PicList& picList,
> PicList& refPicSetInterLayer0, PicLi
> #endif
> }
> 
> + if (m_param->bEnableSCC && numPocTotalCurr > m_numRefIdx[0])
> + {
> + m_refFrameList[0][m_numRefIdx[0] - 1] = picList.getPOC(m_poc);
> + }
> +
> if (m_sliceType != B_SLICE)
> {
> m_numRefIdx[1] = 0;
> diff --git a/source/common/slice.h b/source/common/slice.h
> index add5948f8..f03508660 100644
> --- a/source/common/slice.h
> +++ b/source/common/slice.h
> @@ -376,6 +376,7 @@ public:
> 
> NalUnitType m_nalUnitType;
> SliceType m_sliceType;
> + SliceType m_origSliceType;
> int m_sliceQp;
> int m_chromaQpOffset[2];
> int m_poc;
> diff --git a/source/encoder/analysis.cpp
> b/source/encoder/analysis.cpp
> index 1f1984707..33bf9d9a9 100644
> --- a/source/encoder/analysis.cpp
> +++ b/source/encoder/analysis.cpp
> @@ -223,7 +223,7 @@ Mode& Analysis::compressCTU(CUData& ctu, Frame&
> frame, const CUGeom& cuGeom, con
> }
> ProfileCUScope(ctu, totalCTUTime, totalCTUs);
> 
> - if (m_slice->m_sliceType == I_SLICE)
> + if (m_slice->m_sliceType == I_SLICE || (m_param->bEnableSCC &&
> (m_slice->m_numRefIdx[0] == 1) && m_slice->m_refPOCList[0][0] ==
> m_slice->m_poc))
> {
> x265_analysis_intra_data* intraDataCTU =
> m_frame->m_analysisData.intraData;
> if (m_param->analysisLoadReuseLevel > 1)
> @@ -3434,7 +3434,8 @@ uint32_t Analysis::topSkipMinDepth(const
> CUData& parentCTU, const CUGeom& cuGeom
> uint32_t minDepth0 = 4, minDepth1 = 4;
> uint32_t sum = 0;
> int numRefs = 0;
> - if (m_slice->m_numRefIdx[0])
> + int refPresent = (!m_slice->m_param->bEnableSCC &&
> m_slice->m_numRefIdx[0]) || ((!m_slice->m_param->bEnableSCC &&
> (m_slice->m_numRefIdx[0] - 1)));
> + if (refPresent)
> {
> numRefs++;
> const CUData& cu =
> *m_slice->m_refFrameList[0][0]->m_encData->getPicCTU(parentCTU.m_cuAddr);
> @@ -3781,6 +3782,8 @@ int Analysis::findSameContentRefCount(const
> CUData& parentCTU, const CUGeom& cuG
> for (int i = 0; i < m_frame->m_encData->m_slice->m_numRefIdx[list];
> i++)
> {
> int refPoc =
> m_frame->m_encData->m_slice->m_refFrameList[list][i]->m_poc;
> + if (refPoc == m_curPoc)
> + continue;
> int refPrevChange =
> m_frame->m_encData->m_slice->m_refFrameList[list][i]->m_addOnPrevChange[parentCTU.m_cuAddr][cuGeom.absPartIdx];
> if ((refPoc < prevChange && refPoc < m_curPoc) || (refPoc > m_curPoc
> && prevChange < m_curPoc && refPrevChange > m_curPoc) || ((refPoc ==
> prevChange) && (m_additionalCtuInfo[cuGeom.absPartIdx] ==
> CTU_INFO_CHANGE)))
> sameContentRef++; /* Content changed */
> diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp
> index eafc9c91e..e488cebb8 100644
> --- a/source/encoder/dpb.cpp
> +++ b/source/encoder/dpb.cpp
> @@ -150,7 +150,9 @@ void DPB::prepareEncode(Frame *newFrame)
> if (slice->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
> slice->m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP)
> m_lastIDR = pocCurr;
> slice->m_lastIDR = m_lastIDR;
> - slice->m_sliceType = IS_X265_TYPE_B(type) ? B_SLICE : (type ==
> X265_TYPE_P) ? P_SLICE : I_SLICE;
> + slice->m_origSliceType = slice->m_sliceType = IS_X265_TYPE_B(type)
> ? B_SLICE : (type == X265_TYPE_P) ? P_SLICE : I_SLICE;
> + if (slice->m_param->bEnableSCC && IS_X265_TYPE_I(type))
> + slice->m_sliceType = P_SLICE;
> 
> if (type == X265_TYPE_B)
> {
> @@ -277,10 +279,11 @@ void DPB::prepareEncode(Frame *newFrame)
> if (newFrame->m_viewId)
> slice->createInterLayerReferencePictureSet(m_picList,
> newFrame->refPicSetInterLayer0, newFrame->refPicSetInterLayer1);
> #endif
> + int numRef = slice->m_param->bEnableSCC ?
> slice->m_rps.numberOfNegativePictures + 1 :
> slice->m_rps.numberOfNegativePictures;
> if (slice->m_sliceType != I_SLICE)
> - slice->m_numRefIdx[0] = x265_clip3(1,
> newFrame->m_param->maxNumReferences,
> slice->m_rps.numberOfNegativePictures +
> newFrame->refPicSetInterLayer0.size() +
> newFrame->refPicSetInterLayer1.size());
> + slice->m_numRefIdx[0] = x265_clip3(1,
> newFrame->m_param->maxNumReferences, numRef +
> newFrame->refPicSetInterLayer0.size() +
> newFrame->refPicSetInterLayer1.size());
> else
> - slice->m_numRefIdx[0] =
> X265_MIN(newFrame->m_param->maxNumReferences,
> slice->m_rps.numberOfNegativePictures); // Ensuring L0 contains just
> the -ve POC
> + slice->m_numRefIdx[0] =
> X265_MIN(newFrame->m_param->maxNumReferences, numRef); // Ensuring
> L0 contains just the -ve POC
> slice->m_numRefIdx[1] = X265_MIN(newFrame->m_param->bBPyramid ? 3 :
> 2, slice->m_rps.numberOfPositivePictures +
> newFrame->refPicSetInterLayer0.size() +
> newFrame->refPicSetInterLayer1.size());
> slice->setRefPicList(m_picList, newFrame->refPicSetInterLayer0,
> newFrame->refPicSetInterLayer1, layer);
> 
> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
> index 095009200..f4782f55d 100644
> --- a/source/encoder/encoder.cpp
> +++ b/source/encoder/encoder.cpp
> @@ -629,8 +629,11 @@ int Encoder::getRefFrameList(PicYuv** l0,
> PicYuv** l1, int sliceType, int poc, i
> int l0POC =
> framePtr->m_encData->m_slice->m_refFrameList[0][j]->m_poc;
> pocL0[j] = l0POC;
> Frame* l0Fp = m_dpb->m_picList.getPOC(l0POC, 0);
> - while (l0Fp->m_reconRowFlag[l0Fp->m_numRows - 1].get() == 0)
> - l0Fp->m_reconRowFlag[l0Fp->m_numRows - 1].waitForChange(0); /* If
> recon is not ready, current frame encoder has to wait. */
> + if (l0POC != poc)
> + {
> + while (l0Fp->m_reconRowFlag[l0Fp->m_numRows - 1].get() == 0)
> + l0Fp->m_reconRowFlag[l0Fp->m_numRows - 1].waitForChange(0); /* If
> recon is not ready, current frame encoder has to wait. */
> + }
> l0[j] = l0Fp->m_reconPic;
> }
> }
> @@ -3700,7 +3703,7 @@ void Encoder::initPPS(PPS *pps)
> 
> pps->bEntropyCodingSyncEnabled = m_param->bEnableWavefront;
> 
> - pps->numRefIdxDefault[0] = 1;
> + pps->numRefIdxDefault[0] = 1 + !!m_param->bEnableSCC;;
> pps->numRefIdxDefault[1] = 1;
> pps->pps_extension_flag = false;
> pps->maxViews = 1;
> diff --git a/source/encoder/entropy.cpp b/source/encoder/entropy.cpp
> index 400a7dd8e..c79c3ea0d 100644
> --- a/source/encoder/entropy.cpp
> +++ b/source/encoder/entropy.cpp
> @@ -1726,6 +1726,8 @@ void Entropy::codePredWeightTable(const Slice&
> slice)
> {
> for (int ref = 0; ref < slice.m_numRefIdx[list]; ref++)
> {
> + if (slice.m_poc == slice.m_refPOCList[list][ref])
> + continue;
> wp = slice.m_weightPredTable[list][ref];
> if (!bDenomCoded)
> {
> @@ -1746,6 +1748,8 @@ void Entropy::codePredWeightTable(const Slice&
> slice)
> {
> for (int ref = 0; ref < slice.m_numRefIdx[list]; ref++)
> {
> + if (slice.m_poc == slice.m_refPOCList[list][ref])
> + continue;
> wp = slice.m_weightPredTable[list][ref];
> WRITE_FLAG(!!wp[1].wtPresent, "chroma_weight_lX_flag");
> totalSignalledWeightFlags += 2 * wp[1].wtPresent;
> @@ -1754,6 +1758,8 @@ void Entropy::codePredWeightTable(const Slice&
> slice)
> 
> for (int ref = 0; ref < slice.m_numRefIdx[list]; ref++)
> {
> + if (slice.m_poc == slice.m_refPOCList[list][ref])
> + continue;
> wp = slice.m_weightPredTable[list][ref];
> if (wp[0].wtPresent)
> {
> diff --git a/source/encoder/frameencoder.cpp
> b/source/encoder/frameencoder.cpp
> index c5175f538..0ee3e9a2e 100644
> --- a/source/encoder/frameencoder.cpp
> +++ b/source/encoder/frameencoder.cpp
> @@ -911,6 +911,10 @@ void FrameEncoder::compressFrame(int layer)
> {
> Frame *refpic = slice->m_refFrameList[l][ref];
> 
> + /*Exempt the current pic as reference*/
> + if (m_param->bEnableSCC && refpic->m_poc == m_frame[layer]->m_poc)
> + continue;
> +
> // NOTE: we unnecessary wait row that beyond current slice boundary
> const int rowIdx = X265_MIN(sliceEndRow, (row + m_refLagRows));
> 
> @@ -953,6 +957,10 @@ void FrameEncoder::compressFrame(int layer)
> {
> Frame *refpic = slice->m_refFrameList[list][ref];
> 
> + /*Exempt the current pic as reference*/
> + if (m_param->bEnableSCC && refpic->m_poc == m_frame[layer]->m_poc)
> + continue;
> +
> const int rowIdx = X265_MIN(m_numRows - 1, (i + m_refLagRows));
> while (refpic->m_reconRowFlag[rowIdx].get() == 0)
> refpic->m_reconRowFlag[rowIdx].waitForChange(0);
> diff --git a/source/encoder/ratecontrol.cpp
> b/source/encoder/ratecontrol.cpp
> index d46fb9a1e..25cb7318e 100644
> --- a/source/encoder/ratecontrol.cpp
> +++ b/source/encoder/ratecontrol.cpp
> @@ -1348,7 +1348,7 @@ int RateControl::rateControlStart(Frame*
> curFrame, RateControlEntry* rce, Encode
> 
> FrameData& curEncData = *curFrame->m_encData;
> m_curSlice = curEncData.m_slice;
> - m_sliceType = m_curSlice->m_sliceType;
> + m_sliceType = m_curSlice->m_origSliceType;
> rce->sliceType = m_sliceType;
> if (!m_2pass)
> rce->keptAsRef = IS_REFERENCED(curFrame);
> diff --git a/source/encoder/search.cpp b/source/encoder/search.cpp
> index 954ec54d2..79af0b350 100644
> --- a/source/encoder/search.cpp
> +++ b/source/encoder/search.cpp
> @@ -76,6 +76,7 @@ bool Search::initSearch(const x265_param& param,
> ScalingList& scalingList)
> m_param = ¶m;
> m_bFrameParallel = param.frameNumThreads > 1;
> m_numLayers = g_log2Size[param.maxCUSize] - 2;
> + m_ibcEnabled = param.bEnableSCC;
> 
> m_rdCost.setPsyRdScale(param.psyRd);
> m_rdCost.setSsimRd(param.bSsimRd);
> @@ -2086,7 +2087,10 @@ void Search::processPME(PME& pme, Search&
> slave)
> void Search::singleMotionEstimation(Search& master, Mode& interMode,
> const PredictionUnit& pu, int part, int list, int ref)
> {
> uint32_t bits = master.m_listSelBits[list] + MVP_IDX_BITS;
> - bits += getTUBits(ref, m_slice->m_numRefIdx[list]);
> + int numIdx = m_slice->m_numRefIdx[list];
> + if (!list && m_ibcEnabled)
> + numIdx--;
> + bits += getTUBits(ref, numIdx);
> 
> MotionData* bestME = interMode.bestME[part];
> 
> @@ -2246,7 +2250,10 @@ void Search::predInterSearch(Mode& interMode,
> const CUGeom& cuGeom, bool bChroma
> continue;
> }
> uint32_t bits = m_listSelBits[list] + MVP_IDX_BITS;
> - bits += getTUBits(ref, numRefIdx[list]);
> + int numIdx = m_slice->m_numRefIdx[list];
> + if (!list && m_ibcEnabled)
> + numIdx--;
> + bits += getTUBits(ref, numIdx);
> 
> int numMvc = cu.getPMV(interMode.interNeighbours, list, ref,
> interMode.amvpCand[list][ref], mvc, puIdx, pu.puAbsPartIdx);
> const MV* amvp = interMode.amvpCand[list][ref];
> @@ -2354,7 +2361,10 @@ void Search::predInterSearch(Mode& interMode,
> const CUGeom& cuGeom, bool bChroma
> for (int list = 0; list < numPredDir; list++)
> {
> int idx = 0;
> - for (int ref = 0; ref < numRefIdx[list]; ref++)
> + int numIdx = numRefIdx[list];
> + if (!list && m_ibcEnabled)
> + numIdx--;
> + for (int ref = 0; ref < numIdx; ref++)
> {
> if (!(refMask & (1 << ref)))
> continue;
> @@ -2393,7 +2403,10 @@ void Search::predInterSearch(Mode& interMode,
> const CUGeom& cuGeom, bool bChroma
> 
> for (int list = 0; list < numPredDir; list++)
> {
> - for (int ref = 0; ref < numRefIdx[list]; ref++)
> + int numIdx = numRefIdx[list];
> + if (!list && m_ibcEnabled)
> + numIdx--;
> + for (int ref = 0; ref < numIdx; ref++)
> {
> ProfileCounter(interMode.cu, totalMotionReferences[cuGeom.depth]);
> 
> @@ -2404,7 +2417,7 @@ void Search::predInterSearch(Mode& interMode,
> const CUGeom& cuGeom, bool bChroma
> }
> 
> uint32_t bits = m_listSelBits[list] + MVP_IDX_BITS;
> - bits += getTUBits(ref, numRefIdx[list]);
> + bits += getTUBits(ref, numIdx);
> 
> int numMvc = cu.getPMV(interMode.interNeighbours, list, ref,
> interMode.amvpCand[list][ref], mvc, puIdx, pu.puAbsPartIdx);
> 
> diff --git a/source/encoder/search.h b/source/encoder/search.h
> index ea3fae02f..e90964619 100644
> --- a/source/encoder/search.h
> +++ b/source/encoder/search.h
> @@ -288,6 +288,8 @@ public:
> 
> bool m_vertRestriction;
> 
> + int m_ibcEnabled;
> +
> #if DETAILED_CU_STATS
> /* Accumulate CU statistics separately for each frame encoder */
> CUStats m_stats[X265_MAX_FRAME_THREADS];
> diff --git a/source/encoder/slicetype.cpp
> b/source/encoder/slicetype.cpp
> index 46c6dd4d5..8bbac8244 100644
> --- a/source/encoder/slicetype.cpp
> +++ b/source/encoder/slicetype.cpp
> @@ -1324,7 +1324,7 @@ void Lookahead::getEstimatedPictureCost(Frame
> *curFrame)
> int l0poc = slice->m_rps.numberOfNegativePictures ?
> slice->m_refPOCList[0][0] : -1;
> int l1poc = slice->m_refPOCList[1][0];
> 
> - switch (slice->m_sliceType)
> + switch (slice->m_origSliceType)
> {
> case I_SLICE:
> frames[p0] = &curFrame->m_lowres;
> diff --git a/source/encoder/weightPrediction.cpp
> b/source/encoder/weightPrediction.cpp
> index 9568afb12..724757429 100644
> --- a/source/encoder/weightPrediction.cpp
> +++ b/source/encoder/weightPrediction.cpp
> @@ -491,8 +491,12 @@ void weightAnalyse(Slice& slice, Frame& frame,
> x265_param& param)
> lumaDenom = weights[0].log2WeightDenom;
> chromaDenom = weights[1].log2WeightDenom;
> 
> + int numIdx = slice.m_numRefIdx[list];
> + if (!list && param.bEnableSCC)
> + numIdx--;
> +
> /* reset weight states */
> - for (int ref = 1; ref < slice.m_numRefIdx[list]; ref++)
> + for (int ref = 1; ref < numIdx; ref++)
> {
> SET_WEIGHT(wp[list][ref][0], false, 1 << lumaDenom, lumaDenom, 0);
> SET_WEIGHT(wp[list][ref][1], false, 1 << chromaDenom, chromaDenom,
> 0);
> --
> 2.36.0.windows.1
> 
> 
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
> 


More information about the x265-devel mailing list