<div dir="ltr">From 19d4c3239c543b429dc05a9b80cba46eec5c8a5a Mon Sep 17 00:00:00 2001<br>From: Kirithika <<a href="mailto:kirithika@multicorewareinc.com" target="_blank">kirithika@multicorewareinc.com</a>><br>Date: Fri, 12 Jul 2024 17:45:05 +0530<br>Subject: [PATCH] Add support for MV-HEVC in DPB and Sub DPB<br><br>---<br> source/common/frame.cpp    | 34 +++++++++++++++<br> source/common/frame.h      |  7 ++++<br> source/common/piclist.cpp  | 86 +++++++++++++++++++++++++++++++++++++-<br> source/common/piclist.h    | 10 +++++<br> source/encoder/dpb.cpp     | 50 ++++++++++++++--------<br> source/encoder/encoder.cpp | 20 ++++++++-<br> 6 files changed, 185 insertions(+), 22 deletions(-)<br><br>diff --git a/source/common/frame.cpp b/source/common/frame.cpp<br>index 79474333f..c40093dba 100644<br>--- a/source/common/frame.cpp<br>+++ b/source/common/frame.cpp<br>@@ -75,6 +75,11 @@ Frame::Frame()<br> <br>     m_tempLayer = 0;<br>     m_sameLayerRefPic = false;<br>+<br>+    m_viewId = 0;<br>+    m_valid = 0;<br>+    m_nextSubDPB = NULL;<br>+    m_prevSubDPB = NULL;<br> }<br> <br> bool Frame::create(x265_param *param, float* quantOffsets)<br>@@ -244,6 +249,35 @@ void Frame::destroy()<br>         m_encData = NULL;<br>     }<br> <br>+#if ENABLE_MULTIVIEW<br>+    //Destroy interlayer References<br>+    if (refPicSetInterLayer0.size())<br>+    {<br>+        Frame* iterFrame = refPicSetInterLayer0.first();<br>+<br>+        while (iterFrame)<br>+        {<br>+            Frame* curFrame = iterFrame;<br>+            iterFrame = iterFrame->m_nextSubDPB;<br>+            refPicSetInterLayer0.removeSubDPB(*curFrame);<br>+            iterFrame = refPicSetInterLayer0.first();<br>+        }<br>+    }<br>+<br>+    if (refPicSetInterLayer1.size())<br>+    {<br>+        Frame* iterFrame = refPicSetInterLayer1.first();<br>+<br>+        while (iterFrame)<br>+        {<br>+            Frame* curFrame = iterFrame;<br>+            iterFrame = iterFrame->m_nextSubDPB;<br>+            refPicSetInterLayer1.removeSubDPB(*curFrame);<br>+            iterFrame = refPicSetInterLayer1.first();<br>+        }<br>+    }<br>+#endif<br>+<br>     if (m_fencPic)<br>     {<br>         if (m_param->bCopyPicToFrame)<br>diff --git a/source/common/frame.h b/source/common/frame.h<br>index 97094ad73..4ddd8bd46 100644<br>--- a/source/common/frame.h<br>+++ b/source/common/frame.h<br>@@ -88,6 +88,9 @@ public:<br>     PicYuv*                m_fencPicSubsampled2;<br>     PicYuv*                m_fencPicSubsampled4;<br> <br>+    PicList                refPicSetInterLayer0;<br>+    PicList                refPicSetInterLayer1;<br>+<br>     int                    m_poc;<br>     int                    m_encodeOrder;<br>     int                    m_gopOffset;<br>@@ -164,6 +167,10 @@ public:<br>     int                    m_sLayerId;<br>     bool                   m_valid;<br> <br>+    int                    m_viewId;<br>+    Frame*                 m_nextSubDPB;           // PicList doubly linked list pointers<br>+    Frame*                 m_prevSubDPB;<br>+<br>     Frame();<br> <br>     bool create(x265_param *param, float* quantOffsets);<br>diff --git a/source/common/piclist.cpp b/source/common/piclist.cpp<br>index 345fd02c9..9c1bea7e8 100644<br>--- a/source/common/piclist.cpp<br>+++ b/source/common/piclist.cpp<br>@@ -82,6 +82,82 @@ void PicList::pushBack(Frame& curFrame)<br>     m_count++;<br> }<br> <br>+#if ENABLE_MULTIVIEW<br>+Frame* PicList::popFrontSubDPB()<br>+{<br>+    if (m_start)<br>+    {<br>+        Frame* temp = m_start;<br>+        m_count--;<br>+<br>+        if (m_count)<br>+        {<br>+            m_start = m_start->m_nextSubDPB;<br>+            m_start->m_prevSubDPB = NULL;<br>+        }<br>+        else<br>+        {<br>+            m_start = m_end = NULL;<br>+        }<br>+        temp->m_next = temp->m_prev = NULL;<br>+        return temp;<br>+    }<br>+    else<br>+        return NULL;<br>+}<br>+<br>+void PicList::pushBackSubDPB(Frame& curFrame)<br>+{<br>+    X265_CHECK(!curFrame.m_nextSubDPB && !curFrame.m_prevSubDPB, "piclist: picture already in Sub DPB list\n"); // ensure frame is not in a list<br>+    curFrame.m_nextSubDPB = NULL;<br>+    curFrame.m_prevSubDPB = m_end;<br>+<br>+    if (m_count)<br>+    {<br>+        m_end->m_nextSubDPB = &curFrame;<br>+        m_end = &curFrame;<br>+    }<br>+    else<br>+    {<br>+        m_start = m_end = &curFrame;<br>+    }<br>+    m_count++;<br>+}<br>+<br>+void PicList::removeSubDPB(Frame& curFrame)<br>+{<br>+#if _DEBUG<br>+    Frame* tmp = m_start;<br>+    while (tmp && tmp != &curFrame)<br>+    {<br>+        tmp = tmp->m_nextSubDPB;<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_nextSubDPB;<br>+        if (m_end == &curFrame)<br>+            m_end = curFrame.m_prevSubDPB;<br>+<br>+        if (curFrame.m_nextSubDPB)<br>+            curFrame.m_nextSubDPB->m_prevSubDPB = curFrame.m_prevSubDPB;<br>+        if (curFrame.m_prevSubDPB)<br>+            curFrame.m_prevSubDPB->m_nextSubDPB = curFrame.m_nextSubDPB;<br>+    }<br>+    else<br>+    {<br>+        m_start = m_end = NULL;<br>+    }<br>+<br>+    curFrame.m_nextSubDPB = curFrame.m_prevSubDPB = NULL;<br>+}<br>+#endif<br>+<br> void PicList::pushBackMCSTF(Frame& curFrame)<br> {<br>     X265_CHECK(!curFrame.m_nextMCSTF && !curFrame.m_prevMCSTF, "piclist: picture already in OPB list\n"); // ensure frame is not in a list<br>@@ -126,8 +202,13 @@ Frame *PicList::popFront()<br> Frame* PicList::getPOC(int poc, int sLayerId)<br> {<br>     Frame *curFrame = m_start;<br>-    while (curFrame && (curFrame->m_poc != poc || curFrame->m_sLayerId != sLayerId))<br>+    int layer = curFrame->m_param->numViews > 1 ? curFrame->m_viewId : (curFrame->m_param->numScalableLayers > 1) ? curFrame->m_sLayerId : 0;<br>+    while (curFrame && (curFrame->m_poc != poc || layer != sLayerId))<br>+    {<br>         curFrame = curFrame->m_next;<br>+        if(curFrame)<br>+            layer = curFrame->m_param->numViews > 1 ? curFrame->m_viewId : (curFrame->m_param->numScalableLayers > 1) ? curFrame->m_sLayerId : 0;<br>+    }<br>     return curFrame;<br> }<br> <br>@@ -188,7 +269,8 @@ Frame *PicList::popBackMCSTF()<br> Frame* PicList::getCurFrame(int sLayer)<br> {<br>     Frame *curFrame = m_start;<br>-    if (curFrame->m_sLayerId == sLayer && curFrame != NULL)<br>+    int layer = curFrame->m_param->numViews > 1 ? curFrame->m_viewId : (curFrame->m_param->numScalableLayers > 1) ? curFrame->m_sLayerId : 0;<br>+    if (layer == sLayer && curFrame != NULL)<br>         return curFrame;<br>     else<br>         return NULL;<br>diff --git a/source/common/piclist.h b/source/common/piclist.h<br>index 3c392f0cb..d270d0aec 100644<br>--- a/source/common/piclist.h<br>+++ b/source/common/piclist.h<br>@@ -50,10 +50,16 @@ public:<br>     /** Push picture to end of the list */<br>     void pushBack(Frame& pic);<br>     void pushBackMCSTF(Frame& pic);<br>+#if ENABLE_MULTIVIEW<br>+    void pushBackSubDPB(Frame& pic);<br>+#endif<br> <br>     /** Push picture to beginning of the list */<br>     void pushFront(Frame& pic);<br>     void pushFrontMCSTF(Frame& pic);<br>+#if ENABLE_MULTIVIEW<br>+    Frame* popFrontSubDPB();<br>+#endif<br> <br>     /** Pop picture from end of the list */<br>     Frame* popBack();<br>@@ -77,6 +83,10 @@ public:<br>     Frame* removeFrame(Frame& pic);<br>     /* Remove MCSTF picture from list */<br>     void removeMCSTF(Frame& pic);<br>+#if ENABLE_MULTIVIEW<br>+    /** Remove picture from Sub list */<br>+    void removeSubDPB(Frame& pic);<br>+#endif<br> <br>     Frame* first()        { return m_start;   }<br> <br>diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp<br>index 95ad41523..bce49b500 100644<br>--- a/source/encoder/dpb.cpp<br>+++ b/source/encoder/dpb.cpp<br>@@ -95,6 +95,10 @@ void DPB::recycleUnreferenced()<br> <br>             // iterator is invalidated by remove, restart scan<br>             m_picList.remove(*curFrame);<br>+            if (!curFrame->m_viewId && m_picList.getPOC(curFrame->m_poc, 1) && curFrame == m_picList.getPOC(curFrame->m_poc, 1)->refPicSetInterLayer0.getPOC(curFrame->m_poc, curFrame->m_viewId))<br>+            {<br>+                m_picList.getPOC(curFrame->m_poc, 1)->refPicSetInterLayer0.removeSubDPB(*curFrame);<br>+            }<br>             iterFrame = m_picList.first();<br> <br>             m_freeList.pushBack(*curFrame);<br>@@ -177,7 +181,8 @@ void DPB::prepareEncode(Frame *newFrame)<br> <br>     m_picList.pushFront(*newFrame);<br> <br>-    if (m_bTemporalSublayer && getTemporalLayerNonReferenceFlag(newFrame->m_sLayerId))<br>+    int layer = slice->m_param->numViews > 1 ? newFrame->m_viewId : (slice->m_param->numScalableLayers > 1) ? newFrame->m_sLayerId : 0;<br>+    if (m_bTemporalSublayer && getTemporalLayerNonReferenceFlag(layer))<br>     {<br>         switch (slice->m_nalUnitType)<br>         {<br>@@ -195,12 +200,12 @@ void DPB::prepareEncode(Frame *newFrame)<br>         }<br>     }<br>     // Do decoding refresh marking if any<br>-    decodingRefreshMarking(pocCurr, slice->m_nalUnitType, newFrame->m_sLayerId);<br>+    decodingRefreshMarking(pocCurr, slice->m_nalUnitType, layer);<br> <br>-    computeRPS(pocCurr, newFrame->m_tempLayer, slice->isIRAP(), &slice->m_rps, slice->m_sps->maxDecPicBuffering[newFrame->m_tempLayer], newFrame->m_sLayerId);<br>+    computeRPS(pocCurr, newFrame->m_tempLayer, slice->isIRAP(), &slice->m_rps, slice->m_sps->maxDecPicBuffering[newFrame->m_tempLayer], layer);<br>     bool isTSAPic = ((slice->m_nalUnitType == 2) || (slice->m_nalUnitType == 3)) ? true : false;<br>     // Mark pictures in m_piclist as unreferenced if they are not included in RPS<br>-    applyReferencePictureSet(&slice->m_rps, pocCurr, newFrame->m_tempLayer, isTSAPic, newFrame->m_sLayerId);<br>+    applyReferencePictureSet(&slice->m_rps, pocCurr, newFrame->m_tempLayer, isTSAPic, layer);<br> <br> <br>     if (m_bTemporalSublayer && newFrame->m_tempLayer > 0<br>@@ -210,9 +215,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, newFrame->m_sLayerId) || (slice->m_sps->maxTempSubLayers == 1))<br>+        if (isTemporalLayerSwitchingPoint(pocCurr, newFrame->m_tempLayer, layer) || (slice->m_sps->maxTempSubLayers == 1))<br>         {<br>-            if (getTemporalLayerNonReferenceFlag(newFrame->m_sLayerId))<br>+            if (getTemporalLayerNonReferenceFlag(layer))<br>             {<br>                 slice->m_nalUnitType = NAL_UNIT_CODED_SLICE_TSA_N;<br>             }<br>@@ -221,7 +226,7 @@ void DPB::prepareEncode(Frame *newFrame)<br>                 slice->m_nalUnitType = NAL_UNIT_CODED_SLICE_TSA_R;<br>             }<br>         }<br>-        else if (isStepwiseTemporalLayerSwitchingPoint(&slice->m_rps, pocCurr, newFrame->m_tempLayer, newFrame->m_sLayerId))<br>+        else if (isStepwiseTemporalLayerSwitchingPoint(&slice->m_rps, pocCurr, newFrame->m_tempLayer, layer))<br>         {<br>             bool isSTSA = true;<br>             int id = newFrame->m_gopOffset % x265_gop_ra_length[newFrame->m_gopId];<br>@@ -254,7 +259,7 @@ void DPB::prepareEncode(Frame *newFrame)<br>             }<br>             if (isSTSA == true)<br>             {<br>-                if (getTemporalLayerNonReferenceFlag(newFrame->m_sLayerId))<br>+                if (getTemporalLayerNonReferenceFlag(layer))<br>                 {<br>                     slice->m_nalUnitType = NAL_UNIT_CODED_SLICE_STSA_N;<br>                 }<br>@@ -266,12 +271,14 @@ void DPB::prepareEncode(Frame *newFrame)<br>         }<br>     }<br> <br>+    if (newFrame->m_viewId)<br>+        slice->createInterLayerReferencePictureSet(m_picList, newFrame->refPicSetInterLayer0, newFrame->refPicSetInterLayer1);<br>     if (slice->m_sliceType != I_SLICE)<br>-        slice->m_numRefIdx[0] = x265_clip3(1, newFrame->m_param->maxNumReferences, slice->m_rps.numberOfNegativePictures);<br>+        slice->m_numRefIdx[0] = x265_clip3(1, newFrame->m_param->maxNumReferences, slice->m_rps.numberOfNegativePictures + 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[1] = X265_MIN(newFrame->m_param->bBPyramid ? 2 : 1, slice->m_rps.numberOfPositivePictures);<br>-    slice->setRefPicList(m_picList, newFrame->m_sLayerId);<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>     X265_CHECK(slice->m_sliceType != B_SLICE || slice->m_numRefIdx[1], "B slice without L1 references (non-fatal)\n");<br> <br>@@ -316,7 +323,8 @@ void DPB::computeRPS(int curPoc, int tempId, bool isRAP, RPS * rps, unsigned int<br> <br>     while (iterPic && (poci < maxDecPicBuffer - 1))<br>     {<br>-        if (iterPic->m_valid && (iterPic->m_poc != curPoc) && iterPic->m_encData->m_bHasReferences && iterPic->m_sLayerId == scalableLayerId)<br>+        int layer = iterPic->m_param->numViews > 1 ? iterPic->m_viewId : (iterPic->m_param->numScalableLayers > 1) ? iterPic->m_sLayerId : 0;<br>+        if (iterPic->m_valid && (iterPic->m_poc != curPoc) && iterPic->m_encData->m_bHasReferences && layer == scalableLayerId)<br>         {<br>             if ((!m_bTemporalSublayer || (iterPic->m_tempLayer <= tempId)) && ((m_lastIDR >= curPoc) || (m_lastIDR <= iterPic->m_poc)))<br>             {<br>@@ -340,7 +348,8 @@ void DPB::computeRPS(int curPoc, int tempId, bool isRAP, RPS * rps, unsigned int<br> bool DPB::getTemporalLayerNonReferenceFlag(int scalableLayerId)<br> {<br>     Frame* curFrame = m_picList.first();<br>-    if (curFrame->m_valid && curFrame->m_encData->m_bHasReferences && curFrame->m_sLayerId == scalableLayerId)<br>+    int layer = curFrame->m_param->numViews > 1 ? curFrame->m_viewId : (curFrame->m_param->numScalableLayers > 1) ? curFrame->m_sLayerId : 0;<br>+    if (curFrame->m_valid && curFrame->m_encData->m_bHasReferences && layer == scalableLayerId)<br>     {<br>         curFrame->m_sameLayerRefPic = true;<br>         return false;<br>@@ -359,7 +368,8 @@ void DPB::decodingRefreshMarking(int pocCurr, NalUnitType nalUnitType, int scala<br>         Frame* iterFrame = m_picList.first();<br>         while (iterFrame)<br>         {<br>-            if (iterFrame->m_valid && iterFrame->m_poc != pocCurr && iterFrame->m_sLayerId == scalableLayerId)<br>+            int layer = iterFrame->m_param->numViews > 1 ? iterFrame->m_viewId : (iterFrame->m_param->numScalableLayers > 1) ? iterFrame->m_sLayerId : 0;<br>+            if (iterFrame->m_valid && iterFrame->m_poc != pocCurr && layer == scalableLayerId)<br>                 iterFrame->m_encData->m_bHasReferences = false;<br>             iterFrame = iterFrame->m_next;<br>         }<br>@@ -376,7 +386,8 @@ void DPB::decodingRefreshMarking(int pocCurr, NalUnitType nalUnitType, int scala<br>             Frame* iterFrame = m_picList.first();<br>             while (iterFrame)<br>             {<br>-                if (iterFrame->m_valid && iterFrame->m_poc != pocCurr && iterFrame->m_poc != m_pocCRA && iterFrame->m_sLayerId == scalableLayerId)<br>+                int layer = iterFrame->m_param->numViews > 1 ? iterFrame->m_viewId : (iterFrame->m_param->numScalableLayers > 1) ? iterFrame->m_sLayerId : 0;<br>+                if (iterFrame->m_valid && iterFrame->m_poc != pocCurr && iterFrame->m_poc != m_pocCRA && layer == scalableLayerId)<br>                     iterFrame->m_encData->m_bHasReferences = false;<br>                 iterFrame = iterFrame->m_next;<br>             }<br>@@ -404,7 +415,8 @@ void DPB::applyReferencePictureSet(RPS *rps, int curPoc, int tempId, bool isTSAP<br>     Frame* iterFrame = m_picList.first();<br>     while (iterFrame)<br>     {<br>-        if (iterFrame->m_valid && iterFrame->m_poc != curPoc && iterFrame->m_encData->m_bHasReferences && iterFrame->m_sLayerId == scalableLayerId)<br>+        int layer = iterFrame->m_param->numViews > 1 ? iterFrame->m_viewId : (iterFrame->m_param->numScalableLayers > 1) ? iterFrame->m_sLayerId : 0;<br>+        if (iterFrame->m_valid && iterFrame->m_poc != curPoc && iterFrame->m_encData->m_bHasReferences && layer == scalableLayerId)<br>         {<br>             // loop through all pictures in the Reference Picture Set<br>             // to see if the picture should be kept as reference picture<br>@@ -447,7 +459,8 @@ bool DPB::isTemporalLayerSwitchingPoint(int curPoc, int tempId, int scalableLaye<br>     Frame* iterFrame = m_picList.first();<br>     while (iterFrame)<br>     {<br>-        if (iterFrame->m_valid && iterFrame->m_poc != curPoc && iterFrame->m_encData->m_bHasReferences && iterFrame->m_sLayerId == scalableLayerId)<br>+        int layer = iterFrame->m_param->numViews > 1 ? iterFrame->m_viewId : (iterFrame->m_param->numScalableLayers > 1) ? iterFrame->m_sLayerId : 0;<br>+        if (iterFrame->m_valid && iterFrame->m_poc != curPoc && iterFrame->m_encData->m_bHasReferences && layer == scalableLayerId)<br>         {<br>             if (iterFrame->m_tempLayer >= tempId)<br>             {<br>@@ -465,7 +478,8 @@ bool DPB::isStepwiseTemporalLayerSwitchingPoint(RPS *rps, int curPoc, int tempId<br>     Frame* iterFrame = m_picList.first();<br>     while (iterFrame)<br>     {<br>-        if (iterFrame->m_valid && iterFrame->m_poc != curPoc && iterFrame->m_encData->m_bHasReferences && iterFrame->m_sLayerId == scalableLayerId)<br>+        int layer = iterFrame->m_param->numViews > 1 ? iterFrame->m_viewId : (iterFrame->m_param->numScalableLayers > 1) ? iterFrame->m_sLayerId : 0;<br>+        if (iterFrame->m_valid && iterFrame->m_poc != curPoc && iterFrame->m_encData->m_bHasReferences && layer == scalableLayerId)<br>         {<br>             for (int i = 0; i < rps->numberOfPositivePictures + rps->numberOfNegativePictures; i++)<br>             {<br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index a79ad6dab..ef152f2ae 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -1663,7 +1663,11 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<br>                 inFrame[layer]->m_isInsideWindow = 0;<br>                 inFrame[layer]->m_tempLayer = 0;<br>                 inFrame[layer]->m_sameLayerRefPic = 0;<br>+#if ENABLE_MULTIVIEW<br>+                inFrame[layer]->m_viewId = layer;<br>+#else<br>                 inFrame[layer]->m_sLayerId = layer;<br>+#endif<br>                 inFrame[layer]->m_valid = false;<br>                 inFrame[layer]->m_lowres.bKeyframe = false;<br>             }<br>@@ -1893,6 +1897,12 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<br>         if(m_param->numScalableLayers > 1)<br>             m_dpb->m_picList.pushBack(*inFrame[1]); /* Add enhancement layer to DPB to be used later in frameencoder*/<br> #endif<br>+<br>+#if ENABLE_MULTIVIEW<br>+        for (int view = 1; view < m_param->numViews; view++)<br>+            m_dpb->m_picList.pushBack(*inFrame[view]);<br>+#endif<br>+<br>         m_numDelayedPic++;<br>     }<br>     else if (m_latestParam->forceFlush == 2)<br>@@ -2166,13 +2176,19 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<br>             frameEnc[0] = m_lookahead->getDecidedPicture();<br>         if (frameEnc[0] && !pass && (!m_param->chunkEnd || (m_encodedFrameNum < m_param->chunkEnd)))<br>         {<br>-#if ENABLE_ALPHA<br>+#if ENABLE_ALPHA || ENABLE_MULTIVIEW<br>             //Pop non base view pictures from DPB piclist<br>-            for (int layer = 1; layer < m_param->numScalableLayers; layer++)<br>+            int numLayers = m_param->numViews > 1 ? m_param->numViews : (m_param->numScalableLayers > 1) ? m_param->numScalableLayers : 1;<br>+            for (int layer = 1; layer < numLayers; layer++)<br>             {<br>                 Frame* currentFrame = m_dpb->m_picList.getPOC(frameEnc[0]->m_poc, layer);<br>                 frameEnc[layer] = m_dpb->m_picList.removeFrame(*currentFrame);<br>+#if ENABLE_ALPHA<br>                 frameEnc[layer]->m_lowres.sliceType = frameEnc[0]->m_lowres.sliceType;<br>+#else<br>+                int baseViewType = frameEnc[0]->m_lowres.sliceType;<br>+                frameEnc[layer]->m_lowres.sliceType = IS_X265_TYPE_I(baseViewType) ? X265_TYPE_P : baseViewType;<br>+#endif<br>             }<br> #endif<br> <br>-- <br>2.36.0.windows.1<br><br></div>