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