<div dir="ltr">From c18284bea36b70ff59a075594f984a328f6b003c Mon Sep 17 00:00:00 2001<br>From: Kirithika <<a href="mailto:kirithika@multicorewareinc.com">kirithika@multicorewareinc.com</a>><br>Date: Mon, 6 May 2024 18:36:56 +0530<br>Subject: [PATCH] This commit does the following<br><br>1.Modify the method of pushing/accessing scalable layer frames to/from DPB<br>2.Access current frame from DPB based on scalable layer Id<br>---<br> source/common/piclist.cpp  | 43 ++++++++++++++++++++++++++++++++++----<br> source/common/piclist.h    |  7 +++++--<br> source/common/slice.cpp    |  6 +++---<br> source/common/slice.h      |  2 +-<br> source/encoder/api.cpp     |  2 +-<br> source/encoder/dpb.cpp     | 12 +++++------<br> source/encoder/dpb.h       | 14 ++++++-------<br> source/encoder/encoder.cpp | 26 +++++++++++------------<br> source/encoder/encoder.h   |  2 +-<br> 9 files changed, 75 insertions(+), 39 deletions(-)<br><br>diff --git a/source/common/piclist.cpp b/source/common/piclist.cpp<br>index 275617f6f..4408d2355 100644<br>--- a/source/common/piclist.cpp<br>+++ b/source/common/piclist.cpp<br>@@ -123,10 +123,10 @@ Frame *PicList::popFront()<br>         return NULL;<br> }<br> <br>-Frame* PicList::getPOC(int poc)<br>+Frame* PicList::getPOC(int poc, int sLayerId)<br> {<br>     Frame *curFrame = m_start;<br>-    while (curFrame && curFrame->m_poc != poc)<br>+    while (curFrame && (curFrame->m_poc != poc || curFrame->m_sLayerId != sLayerId))<br>         curFrame = curFrame->m_next;<br>     return curFrame;<br> }<br>@@ -185,10 +185,10 @@ Frame *PicList::popBackMCSTF()<br>         return NULL;<br> }<br> <br>-Frame* PicList::getCurFrame(void)<br>+Frame* PicList::getCurFrame(int sLayer)<br> {<br>     Frame *curFrame = m_start;<br>-    if (curFrame != NULL)<br>+    if (curFrame->m_sLayerId == sLayer && curFrame != NULL)<br>         return curFrame;<br>     else<br>         return NULL;<br>@@ -227,6 +227,41 @@ void PicList::remove(Frame& curFrame)<br>     curFrame.m_next = curFrame.m_prev = NULL;<br> }<br> <br>+<br>+Frame* PicList::removeFrame(Frame& curFrame)<br>+{<br>+#if _DEBUG<br>+    Frame* tmp = m_start;<br>+    while (tmp && tmp != &curFrame)<br>+    {<br>+        tmp = tmp->m_next;<br>+    }<br>+<br>+    X265_CHECK(tmp == &curFrame, "piclist: pic being removed was not in list\n"); // verify pic is in this list<br>+#endif<br>+<br>+    m_count--;<br>+    if (m_count)<br>+    {<br>+        if (m_start == &curFrame)<br>+            m_start = curFrame.m_next;<br>+        if (m_end == &curFrame)<br>+            m_end = curFrame.m_prev;<br>+<br>+        if (curFrame.m_next)<br>+            curFrame.m_next->m_prev = curFrame.m_prev;<br>+        if (curFrame.m_prev)<br>+            curFrame.m_prev->m_next = curFrame.m_next;<br>+    }<br>+    else<br>+    {<br>+        m_start = m_end = NULL;<br>+    }<br>+<br>+    curFrame.m_next = curFrame.m_prev = NULL;<br>+    return tmp;<br>+}<br>+<br> void PicList::removeMCSTF(Frame& curFrame)<br> {<br> #if _DEBUG<br>diff --git a/source/common/piclist.h b/source/common/piclist.h<br>index 45023c93b..3c392f0cb 100644<br>--- a/source/common/piclist.h<br>+++ b/source/common/piclist.h<br>@@ -63,15 +63,18 @@ public:<br>     Frame* popFront();<br> <br>     /** Find frame with specified POC */<br>-    Frame* getPOC(int poc);<br>+    Frame* getPOC(int poc, int sLayerId);<br>     /* Find next MCSTF frame with specified POC */<br>     Frame* getPOCMCSTF(int poc);<br> <br>     /** Get the current Frame from the list **/<br>-    Frame* getCurFrame(void);<br>+    Frame* getCurFrame(int sLayer);<br> <br>     /** Remove picture from list */<br>     void remove(Frame& pic);<br>+<br>+    /** Remove picture from list */<br>+    Frame* removeFrame(Frame& pic);<br>     /* Remove MCSTF picture from list */<br>     void removeMCSTF(Frame& pic);<br> <br>diff --git a/source/common/slice.cpp b/source/common/slice.cpp<br>index 3d57ee121..dd257b48d 100644<br>--- a/source/common/slice.cpp<br>+++ b/source/common/slice.cpp<br>@@ -29,7 +29,7 @@<br> <br> using namespace X265_NS;<br> <br>-void Slice::setRefPicList(PicList& picList)<br>+void Slice::setRefPicList(PicList& picList, int sLayerId)<br> {<br>     if (m_sliceType == I_SLICE)<br>     {<br>@@ -53,7 +53,7 @@ void Slice::setRefPicList(PicList& picList)<br>     {<br>         if (m_rps.bUsed[i])<br>         {<br>-            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i]);<br>+            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i], m_rps.deltaPOC[i] ? sLayerId : 0);<br>             refPicSetStCurr0[numPocStCurr0] = refPic;<br>             numPocStCurr0++;<br>         }<br>@@ -63,7 +63,7 @@ void Slice::setRefPicList(PicList& picList)<br>     {<br>         if (m_rps.bUsed[i])<br>         {<br>-            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i]);<br>+            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i], m_rps.deltaPOC[i] ? sLayerId : 0);<br>             refPicSetStCurr1[numPocStCurr1] = refPic;<br>             numPocStCurr1++;<br>         }<br>diff --git a/source/common/slice.h b/source/common/slice.h<br>index f6718ee95..83f4c488f 100644<br>--- a/source/common/slice.h<br>+++ b/source/common/slice.h<br>@@ -384,7 +384,7 @@ public:<br> <br>     void disableWeights();<br> <br>-    void setRefPicList(PicList& picList);<br>+    void setRefPicList(PicList& picList, int sLayerId);<br> <br>     bool getRapPicFlag() const<br>     {<br>diff --git a/source/encoder/api.cpp b/source/encoder/api.cpp<br>index 15b898a3c..33e98a066 100644<br>--- a/source/encoder/api.cpp<br>+++ b/source/encoder/api.cpp<br>@@ -744,7 +744,7 @@ int x265_get_slicetype_poc_and_scenecut(x265_encoder *enc, int *slicetype, int *<br>     if (!enc)<br>         return -1;<br>     Encoder *encoder = static_cast<Encoder*>(enc);<br>-    if (!encoder->copySlicetypePocAndSceneCut(slicetype, poc, sceneCut))<br>+    if (!encoder->copySlicetypePocAndSceneCut(slicetype, poc, sceneCut, 0))<br>         return 0;<br>     return -1;<br> }<br>diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp<br>index eeb2a5cb8..95ad41523 100644<br>--- a/source/encoder/dpb.cpp<br>+++ b/source/encoder/dpb.cpp<br>@@ -175,9 +175,7 @@ void DPB::prepareEncode(Frame *newFrame)<br>         newFrame->m_encData->m_bHasReferences = true;<br>     }<br> <br>-    //Non base view pictures are already present in the list<br>-    if(newFrame->m_sLayerId == 0)<br>-        m_picList.pushFront(*newFrame);<br>+    m_picList.pushFront(*newFrame);<br> <br>     if (m_bTemporalSublayer && getTemporalLayerNonReferenceFlag(newFrame->m_sLayerId))<br>     {<br>@@ -212,9 +210,9 @@ void DPB::prepareEncode(Frame *newFrame)<br>             || slice->m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL_R)<br>         )<br>     {<br>-        if (isTemporalLayerSwitchingPoint(pocCurr, newFrame->m_tempLayer) || (slice->m_sps->maxTempSubLayers == 1))<br>+        if (isTemporalLayerSwitchingPoint(pocCurr, newFrame->m_tempLayer, newFrame->m_sLayerId) || (slice->m_sps->maxTempSubLayers == 1))<br>         {<br>-            if (getTemporalLayerNonReferenceFlag())<br>+            if (getTemporalLayerNonReferenceFlag(newFrame->m_sLayerId))<br>             {<br>                 slice->m_nalUnitType = NAL_UNIT_CODED_SLICE_TSA_N;<br>             }<br>@@ -273,7 +271,7 @@ void DPB::prepareEncode(Frame *newFrame)<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[1] = X265_MIN(newFrame->m_param->bBPyramid ? 2 : 1, slice->m_rps.numberOfPositivePictures);<br>-    slice->setRefPicList(m_picList);<br>+    slice->setRefPicList(m_picList, newFrame->m_sLayerId);<br> <br>     X265_CHECK(slice->m_sliceType != B_SLICE || slice->m_numRefIdx[1], "B slice without L1 references (non-fatal)\n");<br> <br>@@ -486,7 +484,7 @@ bool DPB::isStepwiseTemporalLayerSwitchingPoint(RPS *rps, int curPoc, int tempId<br> }<br> <br> /* deciding the nal_unit_type */<br>-NalUnitType DPB::getNalUnitType(int curPOC, bool bIsKeyFrame, int viewId)<br>+NalUnitType DPB::getNalUnitType(int curPOC, bool bIsKeyFrame)<br> {<br>     if (!curPOC)<br>         return NAL_UNIT_CODED_SLICE_IDR_N_LP;<br>diff --git a/source/encoder/dpb.h b/source/encoder/dpb.h<br>index fcb19a203..0638d0c16 100644<br>--- a/source/encoder/dpb.h<br>+++ b/source/encoder/dpb.h<br>@@ -79,15 +79,15 @@ public:<br> <br> protected:<br> <br>-    void computeRPS(int curPoc,int tempId, bool isRAP, RPS * rps, unsigned int maxDecPicBuffer, int viewId);<br>+    void computeRPS(int curPoc,int tempId, bool isRAP, RPS * rps, unsigned int maxDecPicBuffer, int sLayerId);<br> <br>-    void applyReferencePictureSet(RPS *rps, int curPoc, int tempId, bool isTSAPicture, int viewId);<br>-    bool getTemporalLayerNonReferenceFlag(int viewId);<br>-    void decodingRefreshMarking(int pocCurr, NalUnitType nalUnitType, int viewId);<br>-    bool isTemporalLayerSwitchingPoint(int curPoc, int tempId, int viewId);<br>-    bool isStepwiseTemporalLayerSwitchingPoint(RPS *rps, int curPoc, int tempId, int viewId);<br>+    void applyReferencePictureSet(RPS *rps, int curPoc, int tempId, bool isTSAPicture, int sLayerId);<br>+    bool getTemporalLayerNonReferenceFlag(int sLayerId);<br>+    void decodingRefreshMarking(int pocCurr, NalUnitType nalUnitType, int sLayerId);<br>+    bool isTemporalLayerSwitchingPoint(int curPoc, int tempId, int sLayerId);<br>+    bool isStepwiseTemporalLayerSwitchingPoint(RPS *rps, int curPoc, int tempId, int sLayerId);<br> <br>-    NalUnitType getNalUnitType(int curPoc, bool bIsKeyFrame, int viewId);<br>+    NalUnitType getNalUnitType(int curPoc, bool bIsKeyFrame);<br> };<br> }<br> <br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index e62823ef6..e61db1ebc 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -597,9 +597,9 @@ void Encoder::stopJobs()<br>     }<br> }<br> <br>-int Encoder::copySlicetypePocAndSceneCut(int *slicetype, int *poc, int *sceneCut)<br>+int Encoder::copySlicetypePocAndSceneCut(int *slicetype, int *poc, int *sceneCut, int sLayer)<br> {<br>-    Frame *FramePtr = m_dpb->m_picList.getCurFrame();<br>+    Frame *FramePtr = m_dpb->m_picList.getCurFrame(sLayer);<br>     if (FramePtr != NULL)<br>     {<br>         *slicetype = FramePtr->m_lowres.sliceType;<br>@@ -618,7 +618,7 @@ int Encoder::getRefFrameList(PicYuv** l0, PicYuv** l1, int sliceType, int poc, i<br> {<br>     if (!(IS_X265_TYPE_I(sliceType)))<br>     {<br>-        Frame *framePtr = m_dpb->m_picList.getPOC(poc);<br>+        Frame *framePtr = m_dpb->m_picList.getPOC(poc, 0);<br>         if (framePtr != NULL)<br>         {<br>             for (int j = 0; j < framePtr->m_encData->m_slice->m_numRefIdx[0]; j++)    // check only for --ref=n number of frames.<br>@@ -627,7 +627,7 @@ int Encoder::getRefFrameList(PicYuv** l0, PicYuv** l1, int sliceType, int poc, i<br>                 {<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);<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>                     l0[j] = l0Fp->m_reconPic;<br>@@ -639,7 +639,7 @@ int Encoder::getRefFrameList(PicYuv** l0, PicYuv** l1, int sliceType, int poc, i<br>                 {<br>                     int l1POC = framePtr->m_encData->m_slice->m_refFrameList[1][j]->m_poc;<br>                     pocL1[j] = l1POC;<br>-                    Frame* l1Fp = m_dpb->m_picList.getPOC(l1POC);<br>+                    Frame* l1Fp = m_dpb->m_picList.getPOC(l1POC, 0);<br>                     while (l1Fp->m_reconRowFlag[l1Fp->m_numRows - 1].get() == 0)<br>                         l1Fp->m_reconRowFlag[l1Fp->m_numRows - 1].waitForChange(0); /* If recon is not ready, current frame encoder has to wait. */<br>                     l1[j] = l1Fp->m_reconPic;<br>@@ -762,7 +762,7 @@ int Encoder::setAnalysisData(x265_analysis_data *analysis_data, int poc, uint32_<br>     uint32_t widthInCU = (m_param->sourceWidth + m_param->maxCUSize - 1) >> m_param->maxLog2CUSize;<br>     uint32_t heightInCU = (m_param->sourceHeight + m_param->maxCUSize - 1) >> m_param->maxLog2CUSize;<br> <br>-    Frame* curFrame = m_dpb->m_picList.getPOC(poc);<br>+    Frame* curFrame = m_dpb->m_picList.getPOC(poc, 0);<br>     if (curFrame != NULL)<br>     {<br>         curFrame->m_analysisData = (*analysis_data);<br>@@ -1667,7 +1667,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)<br>                     for (int i = 1; i <= backwardWindow; i++)<br>                     {<br>                         int frameNum = inFrame[layer]->m_poc - i;<br>-                        Frame* frame = m_lookahead->m_inputQueue.getPOC(frameNum);<br>+                        Frame* frame = m_lookahead->m_inputQueue.getPOC(frameNum, 0);<br>                         if (frame)<br>                             frame->m_isInsideWindow = BACKWARD_WINDOW;<br>                     }<br>@@ -2142,7 +2142,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)<br>         if (frameEnc[0] && !pass && (!m_param->chunkEnd || (m_encodedFrameNum < m_param->chunkEnd)))<br>         {<br>             //Pop non base view pictures from DPB piclist<br>-            frameEnc[1] = m_dpb->m_picList.getPOC(frameEnc[0]->m_poc);<br>+            frameEnc[1] = m_dpb->m_picList.getPOC(frameEnc[0]->m_poc, 1);<br>             m_dpb->m_picList.remove(*frameEnc[1]);<br>             frameEnc[1]->m_lowres.sliceType = frameEnc[0]->m_lowres.sliceType;<br> <br>@@ -2441,7 +2441,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)<br>                 {<br>                     TemporalFilterRefPicInfo *ref = &curEncoder->m_mcstfRefList[i];<br>                     ref->slicetype = m_lookahead->findSliceType(frameEnc[0]->m_poc + ref->origOffset);<br>-                    Frame* dpbframePtr = m_dpb->m_picList.getPOC(frameEnc[0]->m_poc + ref->origOffset);<br>+                    Frame* dpbframePtr = m_dpb->m_picList.getPOC(frameEnc[0]->m_poc + ref->origOffset, 0);<br>                     if (dpbframePtr != NULL)<br>                     {<br>                         if (dpbframePtr->m_encData->m_slice->m_sliceType == B_SLICE)<br>@@ -2561,15 +2561,15 @@ void Encoder::copyCtuInfo(x265_ctu_info_t** frameCtuInfo, int poc)<br>     bool copied = false;<br>     do<br>     {<br>-        curFrame = m_lookahead->m_inputQueue.getPOC(poc);<br>+        curFrame = m_lookahead->m_inputQueue.getPOC(poc, 0);<br>         if (!curFrame)<br>-            curFrame = m_lookahead->m_outputQueue.getPOC(poc);<br>+            curFrame = m_lookahead->m_outputQueue.getPOC(poc, 0);<br> <br>         if (poc > 0)<br>         {<br>-            prevFrame = m_lookahead->m_inputQueue.getPOC(poc - 1);<br>+            prevFrame = m_lookahead->m_inputQueue.getPOC(poc - 1, 0);<br>             if (!prevFrame)<br>-                prevFrame = m_lookahead->m_outputQueue.getPOC(poc - 1);<br>+                prevFrame = m_lookahead->m_outputQueue.getPOC(poc - 1, 0);<br>             if (!prevFrame)<br>             {<br>                 FrameEncoder* prevEncoder;<br>diff --git a/source/encoder/encoder.h b/source/encoder/encoder.h<br>index 06a01e21c..77e32fe42 100644<br>--- a/source/encoder/encoder.h<br>+++ b/source/encoder/encoder.h<br>@@ -308,7 +308,7 @@ public:<br> <br>     void copyCtuInfo(x265_ctu_info_t** frameCtuInfo, int poc);<br> <br>-    int copySlicetypePocAndSceneCut(int *slicetype, int *poc, int *sceneCut);<br>+    int copySlicetypePocAndSceneCut(int *slicetype, int *poc, int *sceneCut, int sLayer);<br> <br>     int getRefFrameList(PicYuv** l0, PicYuv** l1, int sliceType, int poc, int* pocL0, int* pocL1);<br> <br>-- <br>2.36.0.windows.1<br><br></div>