[x265] [PATCH Alpha 06/10] Access DPB using scalable layer Id

Anusuya Kumarasamy anusuya.kumarasamy at multicorewareinc.com
Mon Aug 5 10:59:53 UTC 2024


>From c18284bea36b70ff59a075594f984a328f6b003c Mon Sep 17 00:00:00 2001
From: Kirithika <kirithika at multicorewareinc.com>
Date: Mon, 6 May 2024 18:36:56 +0530
Subject: [PATCH] This commit does the following

1.Modify the method of pushing/accessing scalable layer frames to/from DPB
2.Access current frame from DPB based on scalable layer Id
---
 source/common/piclist.cpp  | 43 ++++++++++++++++++++++++++++++++++----
 source/common/piclist.h    |  7 +++++--
 source/common/slice.cpp    |  6 +++---
 source/common/slice.h      |  2 +-
 source/encoder/api.cpp     |  2 +-
 source/encoder/dpb.cpp     | 12 +++++------
 source/encoder/dpb.h       | 14 ++++++-------
 source/encoder/encoder.cpp | 26 +++++++++++------------
 source/encoder/encoder.h   |  2 +-
 9 files changed, 75 insertions(+), 39 deletions(-)

diff --git a/source/common/piclist.cpp b/source/common/piclist.cpp
index 275617f6f..4408d2355 100644
--- a/source/common/piclist.cpp
+++ b/source/common/piclist.cpp
@@ -123,10 +123,10 @@ Frame *PicList::popFront()
         return NULL;
 }

-Frame* PicList::getPOC(int poc)
+Frame* PicList::getPOC(int poc, int sLayerId)
 {
     Frame *curFrame = m_start;
-    while (curFrame && curFrame->m_poc != poc)
+    while (curFrame && (curFrame->m_poc != poc || curFrame->m_sLayerId !=
sLayerId))
         curFrame = curFrame->m_next;
     return curFrame;
 }
@@ -185,10 +185,10 @@ Frame *PicList::popBackMCSTF()
         return NULL;
 }

-Frame* PicList::getCurFrame(void)
+Frame* PicList::getCurFrame(int sLayer)
 {
     Frame *curFrame = m_start;
-    if (curFrame != NULL)
+    if (curFrame->m_sLayerId == sLayer && curFrame != NULL)
         return curFrame;
     else
         return NULL;
@@ -227,6 +227,41 @@ void PicList::remove(Frame& curFrame)
     curFrame.m_next = curFrame.m_prev = NULL;
 }

+
+Frame* PicList::removeFrame(Frame& curFrame)
+{
+#if _DEBUG
+    Frame* tmp = m_start;
+    while (tmp && tmp != &curFrame)
+    {
+        tmp = tmp->m_next;
+    }
+
+    X265_CHECK(tmp == &curFrame, "piclist: pic being removed was not in
list\n"); // verify pic is in this list
+#endif
+
+    m_count--;
+    if (m_count)
+    {
+        if (m_start == &curFrame)
+            m_start = curFrame.m_next;
+        if (m_end == &curFrame)
+            m_end = curFrame.m_prev;
+
+        if (curFrame.m_next)
+            curFrame.m_next->m_prev = curFrame.m_prev;
+        if (curFrame.m_prev)
+            curFrame.m_prev->m_next = curFrame.m_next;
+    }
+    else
+    {
+        m_start = m_end = NULL;
+    }
+
+    curFrame.m_next = curFrame.m_prev = NULL;
+    return tmp;
+}
+
 void PicList::removeMCSTF(Frame& curFrame)
 {
 #if _DEBUG
diff --git a/source/common/piclist.h b/source/common/piclist.h
index 45023c93b..3c392f0cb 100644
--- a/source/common/piclist.h
+++ b/source/common/piclist.h
@@ -63,15 +63,18 @@ public:
     Frame* popFront();

     /** Find frame with specified POC */
-    Frame* getPOC(int poc);
+    Frame* getPOC(int poc, int sLayerId);
     /* Find next MCSTF frame with specified POC */
     Frame* getPOCMCSTF(int poc);

     /** Get the current Frame from the list **/
-    Frame* getCurFrame(void);
+    Frame* getCurFrame(int sLayer);

     /** Remove picture from list */
     void remove(Frame& pic);
+
+    /** Remove picture from list */
+    Frame* removeFrame(Frame& pic);
     /* Remove MCSTF picture from list */
     void removeMCSTF(Frame& pic);

diff --git a/source/common/slice.cpp b/source/common/slice.cpp
index 3d57ee121..dd257b48d 100644
--- a/source/common/slice.cpp
+++ b/source/common/slice.cpp
@@ -29,7 +29,7 @@

 using namespace X265_NS;

-void Slice::setRefPicList(PicList& picList)
+void Slice::setRefPicList(PicList& picList, int sLayerId)
 {
     if (m_sliceType == I_SLICE)
     {
@@ -53,7 +53,7 @@ void Slice::setRefPicList(PicList& picList)
     {
         if (m_rps.bUsed[i])
         {
-            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i]);
+            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i],
m_rps.deltaPOC[i] ? sLayerId : 0);
             refPicSetStCurr0[numPocStCurr0] = refPic;
             numPocStCurr0++;
         }
@@ -63,7 +63,7 @@ void Slice::setRefPicList(PicList& picList)
     {
         if (m_rps.bUsed[i])
         {
-            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i]);
+            refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i],
m_rps.deltaPOC[i] ? sLayerId : 0);
             refPicSetStCurr1[numPocStCurr1] = refPic;
             numPocStCurr1++;
         }
diff --git a/source/common/slice.h b/source/common/slice.h
index f6718ee95..83f4c488f 100644
--- a/source/common/slice.h
+++ b/source/common/slice.h
@@ -384,7 +384,7 @@ public:

     void disableWeights();

-    void setRefPicList(PicList& picList);
+    void setRefPicList(PicList& picList, int sLayerId);

     bool getRapPicFlag() const
     {
diff --git a/source/encoder/api.cpp b/source/encoder/api.cpp
index 15b898a3c..33e98a066 100644
--- a/source/encoder/api.cpp
+++ b/source/encoder/api.cpp
@@ -744,7 +744,7 @@ int x265_get_slicetype_poc_and_scenecut(x265_encoder
*enc, int *slicetype, int *
     if (!enc)
         return -1;
     Encoder *encoder = static_cast<Encoder*>(enc);
-    if (!encoder->copySlicetypePocAndSceneCut(slicetype, poc, sceneCut))
+    if (!encoder->copySlicetypePocAndSceneCut(slicetype, poc, sceneCut, 0))
         return 0;
     return -1;
 }
diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp
index eeb2a5cb8..95ad41523 100644
--- a/source/encoder/dpb.cpp
+++ b/source/encoder/dpb.cpp
@@ -175,9 +175,7 @@ void DPB::prepareEncode(Frame *newFrame)
         newFrame->m_encData->m_bHasReferences = true;
     }

-    //Non base view pictures are already present in the list
-    if(newFrame->m_sLayerId == 0)
-        m_picList.pushFront(*newFrame);
+    m_picList.pushFront(*newFrame);

     if (m_bTemporalSublayer &&
getTemporalLayerNonReferenceFlag(newFrame->m_sLayerId))
     {
@@ -212,9 +210,9 @@ void DPB::prepareEncode(Frame *newFrame)
             || slice->m_nalUnitType == NAL_UNIT_CODED_SLICE_RASL_R)
         )
     {
-        if (isTemporalLayerSwitchingPoint(pocCurr, newFrame->m_tempLayer)
|| (slice->m_sps->maxTempSubLayers == 1))
+        if (isTemporalLayerSwitchingPoint(pocCurr, newFrame->m_tempLayer,
newFrame->m_sLayerId) || (slice->m_sps->maxTempSubLayers == 1))
         {
-            if (getTemporalLayerNonReferenceFlag())
+            if (getTemporalLayerNonReferenceFlag(newFrame->m_sLayerId))
             {
                 slice->m_nalUnitType = NAL_UNIT_CODED_SLICE_TSA_N;
             }
@@ -273,7 +271,7 @@ void DPB::prepareEncode(Frame *newFrame)
     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[1] = X265_MIN(newFrame->m_param->bBPyramid ? 2 : 1,
slice->m_rps.numberOfPositivePictures);
-    slice->setRefPicList(m_picList);
+    slice->setRefPicList(m_picList, newFrame->m_sLayerId);

     X265_CHECK(slice->m_sliceType != B_SLICE || slice->m_numRefIdx[1], "B
slice without L1 references (non-fatal)\n");

@@ -486,7 +484,7 @@ bool DPB::isStepwiseTemporalLayerSwitchingPoint(RPS
*rps, int curPoc, int tempId
 }

 /* deciding the nal_unit_type */
-NalUnitType DPB::getNalUnitType(int curPOC, bool bIsKeyFrame, int viewId)
+NalUnitType DPB::getNalUnitType(int curPOC, bool bIsKeyFrame)
 {
     if (!curPOC)
         return NAL_UNIT_CODED_SLICE_IDR_N_LP;
diff --git a/source/encoder/dpb.h b/source/encoder/dpb.h
index fcb19a203..0638d0c16 100644
--- a/source/encoder/dpb.h
+++ b/source/encoder/dpb.h
@@ -79,15 +79,15 @@ public:

 protected:

-    void computeRPS(int curPoc,int tempId, bool isRAP, RPS * rps, unsigned
int maxDecPicBuffer, int viewId);
+    void computeRPS(int curPoc,int tempId, bool isRAP, RPS * rps, unsigned
int maxDecPicBuffer, int sLayerId);

-    void applyReferencePictureSet(RPS *rps, int curPoc, int tempId, bool
isTSAPicture, int viewId);
-    bool getTemporalLayerNonReferenceFlag(int viewId);
-    void decodingRefreshMarking(int pocCurr, NalUnitType nalUnitType, int
viewId);
-    bool isTemporalLayerSwitchingPoint(int curPoc, int tempId, int viewId);
-    bool isStepwiseTemporalLayerSwitchingPoint(RPS *rps, int curPoc, int
tempId, int viewId);
+    void applyReferencePictureSet(RPS *rps, int curPoc, int tempId, bool
isTSAPicture, int sLayerId);
+    bool getTemporalLayerNonReferenceFlag(int sLayerId);
+    void decodingRefreshMarking(int pocCurr, NalUnitType nalUnitType, int
sLayerId);
+    bool isTemporalLayerSwitchingPoint(int curPoc, int tempId, int
sLayerId);
+    bool isStepwiseTemporalLayerSwitchingPoint(RPS *rps, int curPoc, int
tempId, int sLayerId);

-    NalUnitType getNalUnitType(int curPoc, bool bIsKeyFrame, int viewId);
+    NalUnitType getNalUnitType(int curPoc, bool bIsKeyFrame);
 };
 }

diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index e62823ef6..e61db1ebc 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -597,9 +597,9 @@ void Encoder::stopJobs()
     }
 }

-int Encoder::copySlicetypePocAndSceneCut(int *slicetype, int *poc, int
*sceneCut)
+int Encoder::copySlicetypePocAndSceneCut(int *slicetype, int *poc, int
*sceneCut, int sLayer)
 {
-    Frame *FramePtr = m_dpb->m_picList.getCurFrame();
+    Frame *FramePtr = m_dpb->m_picList.getCurFrame(sLayer);
     if (FramePtr != NULL)
     {
         *slicetype = FramePtr->m_lowres.sliceType;
@@ -618,7 +618,7 @@ int Encoder::getRefFrameList(PicYuv** l0, PicYuv** l1,
int sliceType, int poc, i
 {
     if (!(IS_X265_TYPE_I(sliceType)))
     {
-        Frame *framePtr = m_dpb->m_picList.getPOC(poc);
+        Frame *framePtr = m_dpb->m_picList.getPOC(poc, 0);
         if (framePtr != NULL)
         {
             for (int j = 0; j <
framePtr->m_encData->m_slice->m_numRefIdx[0]; j++)    // check only for
--ref=n number of frames.
@@ -627,7 +627,7 @@ 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);
+                    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. */
                     l0[j] = l0Fp->m_reconPic;
@@ -639,7 +639,7 @@ int Encoder::getRefFrameList(PicYuv** l0, PicYuv** l1,
int sliceType, int poc, i
                 {
                     int l1POC =
framePtr->m_encData->m_slice->m_refFrameList[1][j]->m_poc;
                     pocL1[j] = l1POC;
-                    Frame* l1Fp = m_dpb->m_picList.getPOC(l1POC);
+                    Frame* l1Fp = m_dpb->m_picList.getPOC(l1POC, 0);
                     while (l1Fp->m_reconRowFlag[l1Fp->m_numRows - 1].get()
== 0)
                         l1Fp->m_reconRowFlag[l1Fp->m_numRows -
1].waitForChange(0); /* If recon is not ready, current frame encoder has to
wait. */
                     l1[j] = l1Fp->m_reconPic;
@@ -762,7 +762,7 @@ int Encoder::setAnalysisData(x265_analysis_data
*analysis_data, int poc, uint32_
     uint32_t widthInCU = (m_param->sourceWidth + m_param->maxCUSize - 1)
>> m_param->maxLog2CUSize;
     uint32_t heightInCU = (m_param->sourceHeight + m_param->maxCUSize - 1)
>> m_param->maxLog2CUSize;

-    Frame* curFrame = m_dpb->m_picList.getPOC(poc);
+    Frame* curFrame = m_dpb->m_picList.getPOC(poc, 0);
     if (curFrame != NULL)
     {
         curFrame->m_analysisData = (*analysis_data);
@@ -1667,7 +1667,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
                     for (int i = 1; i <= backwardWindow; i++)
                     {
                         int frameNum = inFrame[layer]->m_poc - i;
-                        Frame* frame =
m_lookahead->m_inputQueue.getPOC(frameNum);
+                        Frame* frame =
m_lookahead->m_inputQueue.getPOC(frameNum, 0);
                         if (frame)
                             frame->m_isInsideWindow = BACKWARD_WINDOW;
                     }
@@ -2142,7 +2142,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
         if (frameEnc[0] && !pass && (!m_param->chunkEnd ||
(m_encodedFrameNum < m_param->chunkEnd)))
         {
             //Pop non base view pictures from DPB piclist
-            frameEnc[1] = m_dpb->m_picList.getPOC(frameEnc[0]->m_poc);
+            frameEnc[1] = m_dpb->m_picList.getPOC(frameEnc[0]->m_poc, 1);
             m_dpb->m_picList.remove(*frameEnc[1]);
             frameEnc[1]->m_lowres.sliceType =
frameEnc[0]->m_lowres.sliceType;

@@ -2441,7 +2441,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
                 {
                     TemporalFilterRefPicInfo *ref =
&curEncoder->m_mcstfRefList[i];
                     ref->slicetype =
m_lookahead->findSliceType(frameEnc[0]->m_poc + ref->origOffset);
-                    Frame* dpbframePtr =
m_dpb->m_picList.getPOC(frameEnc[0]->m_poc + ref->origOffset);
+                    Frame* dpbframePtr =
m_dpb->m_picList.getPOC(frameEnc[0]->m_poc + ref->origOffset, 0);
                     if (dpbframePtr != NULL)
                     {
                         if (dpbframePtr->m_encData->m_slice->m_sliceType
== B_SLICE)
@@ -2561,15 +2561,15 @@ void Encoder::copyCtuInfo(x265_ctu_info_t**
frameCtuInfo, int poc)
     bool copied = false;
     do
     {
-        curFrame = m_lookahead->m_inputQueue.getPOC(poc);
+        curFrame = m_lookahead->m_inputQueue.getPOC(poc, 0);
         if (!curFrame)
-            curFrame = m_lookahead->m_outputQueue.getPOC(poc);
+            curFrame = m_lookahead->m_outputQueue.getPOC(poc, 0);

         if (poc > 0)
         {
-            prevFrame = m_lookahead->m_inputQueue.getPOC(poc - 1);
+            prevFrame = m_lookahead->m_inputQueue.getPOC(poc - 1, 0);
             if (!prevFrame)
-                prevFrame = m_lookahead->m_outputQueue.getPOC(poc - 1);
+                prevFrame = m_lookahead->m_outputQueue.getPOC(poc - 1, 0);
             if (!prevFrame)
             {
                 FrameEncoder* prevEncoder;
diff --git a/source/encoder/encoder.h b/source/encoder/encoder.h
index 06a01e21c..77e32fe42 100644
--- a/source/encoder/encoder.h
+++ b/source/encoder/encoder.h
@@ -308,7 +308,7 @@ public:

     void copyCtuInfo(x265_ctu_info_t** frameCtuInfo, int poc);

-    int copySlicetypePocAndSceneCut(int *slicetype, int *poc, int
*sceneCut);
+    int copySlicetypePocAndSceneCut(int *slicetype, int *poc, int
*sceneCut, int sLayer);

     int getRefFrameList(PicYuv** l0, PicYuv** l1, int sliceType, int poc,
int* pocL0, int* pocL1);

-- 
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240805/03f543cb/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0006-This-commit-does-the-following.patch
Type: application/octet-stream
Size: 14928 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240805/03f543cb/attachment-0001.obj>


More information about the x265-devel mailing list