<div dir="ltr">From 6990541ee2e5b63c818b813a0b766192dbd21f53 Mon Sep 17 00:00:00 2001<br>From: AnusuyaKumarasamy <<a href="mailto:anusuya.kumarasamy@multicorewareinc.com" target="_blank">anusuya.kumarasamy@multicorewareinc.com</a>><br>Date: Mon, 15 Jul 2024 23:11:51 +0530<br>Subject: [PATCH] Decouple mv-hevc code from alpha and latest-tip<br><br>---<br> source/abrEncApp.cpp            |  5 +++--<br> source/abrEncApp.h              |  1 +<br> source/common/cudata.cpp        |  5 +++--<br> source/common/param.cpp         |  5 ++++-<br> source/common/slice.h           |  7 ++-----<br> source/encoder/dpb.cpp          |  8 ++++++--<br> source/encoder/encoder.cpp      | 30 +++++++++++++++++-------------<br> source/encoder/entropy.cpp      | 14 ++++----------<br> source/encoder/frameencoder.cpp |  4 +++-<br> source/x265.h                   |  2 ++<br> source/x265cli.cpp              |  2 +-<br> 11 files changed, 46 insertions(+), 37 deletions(-)<br><br>diff --git a/source/abrEncApp.cpp b/source/abrEncApp.cpp<br>index 3460dfe78..0ae7e5800 100644<br>--- a/source/abrEncApp.cpp<br>+++ b/source/abrEncApp.cpp<br>@@ -63,6 +63,7 @@ namespace X265_NS {<br>             m_passEnc[i]->init(ret);<br>         }<br> <br>+        m_numInputViews = m_passEnc[0]->m_param->numViews;<br>         if (!allocBuffers())<br>         {<br>             x265_log(NULL, X265_LOG_ERROR, "Unable to allocate memory for buffers\n");<br>@@ -96,7 +97,7 @@ namespace X265_NS {<br> #if ENABLE_MULTIVIEW<br>         if (m_passEnc[0]->m_param->numViews > 1)<br>         {<br>-            for (uint8_t pass = 0; pass < m_passEnc[0]->m_param->numViews; pass++)<br>+            for (uint8_t pass = 0; pass < m_numInputViews; pass++)<br>             {<br>                 m_inputPicBuffer[pass] = X265_MALLOC(x265_picture*, m_queueSize);<br>                 for (uint32_t idx = 0; idx < m_queueSize; idx++)<br>@@ -144,7 +145,7 @@ namespace X265_NS {<br>     {<br>         x265_cleanup(); /* Free library singletons */<br> #if ENABLE_MULTIVIEW<br>-        for (uint8_t pass = 0; pass < MAX_VIEWS; pass++)<br>+        for (uint8_t pass = 0; pass < m_numInputViews; pass++)<br>         {<br>             for (uint32_t index = 0; index < m_queueSize; index++)<br>             {<br>diff --git a/source/abrEncApp.h b/source/abrEncApp.h<br>index 43b202cc5..fab694656 100644<br>--- a/source/abrEncApp.h<br>+++ b/source/abrEncApp.h<br>@@ -42,6 +42,7 @@ namespace X265_NS {<br>     {<br>     public:<br>         uint8_t           m_numEncodes;<br>+        uint8_t           m_numInputViews; // Number of inputs for multiview-extension<br>         PassEncoder        **m_passEnc;<br>         uint32_t           m_queueSize;<br>         ThreadSafeInteger  m_numActiveEncodes;<br>diff --git a/source/common/cudata.cpp b/source/common/cudata.cpp<br>index baa9be476..c0d68bc5f 100644<br>--- a/source/common/cudata.cpp<br>+++ b/source/common/cudata.cpp<br>@@ -2053,11 +2053,12 @@ bool CUData::getIndirectPMV(MV& outMV, InterNeighbourMV *neighbours, uint32_t pi<br>                     outMV = mvp;<br>                 if (!(curRefPOC == curPOC))<br>                     outMV = scaleMvByPOCDist(mvp, curPOC, curRefPOC, neibPOC, neibRefPOC);<br>+                return true;<br>+            }<br> #else<br>             outMV = scaleMvByPOCDist(mvp, curPOC, curRefPOC, neibPOC, neibRefPOC);<br>-#endif<br>             return true;<br>-            }<br>+#endif<br>         }<br>     }<br>     return false;<br>diff --git a/source/common/param.cpp b/source/common/param.cpp<br>index c310a7b4c..084743ee9 100755<br>--- a/source/common/param.cpp<br>+++ b/source/common/param.cpp<br>@@ -406,7 +406,7 @@ void x265_param_default(x265_param* param)<br> <br>     /* Multi-View Encoding*/<br>     param->numViews = 1;<br>-    param->format = 1;<br>+    param->format = 0;<br> <br>     param->numLayers = 1;<br> }<br>@@ -1461,6 +1461,7 @@ int x265_param_parse(x265_param* p, const char* name, const char* value)<br>             {<br>                 p->bEnableAlpha = 1;<br>                 p->numScalableLayers = 2;<br>+                p->numLayers = 2;<br>             }<br>         }<br> #endif<br>@@ -1952,6 +1953,8 @@ int x265_check_params(x265_param* param)<br> #endif<br> #if ENABLE_MULTIVIEW<br>     CHECK((param->numViews > 2), "Multi-View Encoding currently support only 2 views");<br>+    CHECK((param->numViews > 1) && (param->internalBitDepth != 8), "BitDepthConstraint must be 8 for Multiview main profile");<br>+    CHECK((param->numViews > 1 && param->rc.rateControlMode != X265_RC_CQP), "Multiview encode supported only with CQP mode");<br> #endif<br>     return check_failed;<br> }<br>diff --git a/source/common/slice.h b/source/common/slice.h<br>index 90009ae7f..0d6807952 100644<br>--- a/source/common/slice.h<br>+++ b/source/common/slice.h<br>@@ -164,6 +164,7 @@ struct VPS<br>     uint32_t         maxLatencyIncrease[MAX_T_LAYERS];<br>     int              m_numLayers;<br>     int              m_numViews;<br>+    bool             vps_extension_flag;<br> <br> #if (ENABLE_ALPHA || ENABLE_MULTIVIEW)<br>     bool             splitting_flag;<br>@@ -176,7 +177,6 @@ struct VPS<br>     uint8_t          m_layerIdInVps[MAX_VPS_LAYER_ID_PLUS1];<br>     int              m_viewIdLen;<br>     int              m_vpsNumLayerSetsMinus1;<br>-    bool             vps_extension_flag;<br> #endif<br> <br> #if ENABLE_MULTIVIEW<br>@@ -276,9 +276,9 @@ struct SPS<br> <br>     Window   conformanceWindow;<br>     VUI      vuiParameters;<br>+    bool     sps_extension_flag;<br> <br> #if ENABLE_MULTIVIEW<br>-    bool     sps_extension_flag;<br>     int      setSpsExtOrMaxSubLayersMinus1;<br>     int      maxViews;<br>     bool     vui_parameters_present_flag;<br>@@ -322,11 +322,8 @@ struct PPS<br>     int      numRefIdxDefault[2];<br>     bool     pps_slice_chroma_qp_offsets_present_flag;<br> <br>-#if ENABLE_MULTIVIEW<br>     bool     pps_extension_flag;<br>     int      maxViews;<br>-#endif<br>-<br> };<br> <br> struct WeightParam<br>diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp<br>index a187e6657..eafc9c91e 100644<br>--- a/source/encoder/dpb.cpp<br>+++ b/source/encoder/dpb.cpp<br>@@ -95,10 +95,12 @@ 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>+#if ENABLE_MULTIVIEW<br>+            if (curFrame->m_param->numViews > 1 && !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>+#endif<br>             iterFrame = m_picList.first();<br> <br>             m_freeList.pushBack(*curFrame);<br>@@ -271,8 +273,10 @@ void DPB::prepareEncode(Frame *newFrame)<br>         }<br>     }<br> <br>+#if ENABLE_MULTIVIEW<br>     if (newFrame->m_viewId)<br>         slice->createInterLayerReferencePictureSet(m_picList, newFrame->refPicSetInterLayer0, newFrame->refPicSetInterLayer1);<br>+#endif<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>     else<br>@@ -349,7 +353,7 @@ void DPB::computeRPS(int curPoc, int tempId, bool isRAP, RPS * rps, unsigned int<br>             if ((!m_bTemporalSublayer || (iterPic->m_tempLayer <= tempId)) && ((m_lastIDR >= curPoc) || (m_lastIDR <= iterPic->m_poc)))<br>             {<br> #if ENABLE_MULTIVIEW<br>-                    if (layer && numNeg == iterPic->m_param->maxNumReferences - 1 && (iterPic->m_poc - curPoc) < 0)<br>+                    if (iterPic->m_param->numViews > 1 && layer && numNeg == iterPic->m_param->maxNumReferences - 1 && (iterPic->m_poc - curPoc) < 0)<br>                     {<br>                         iterPic = iterPic->m_next;<br>                         continue;<br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index 5fb822c8a..ff8f53883 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -1595,12 +1595,13 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<br>                 inFrame[layer] = new Frame;<br>                 inFrame[layer]->m_encodeStartTime = x265_mdate();<br> #if ENABLE_MULTIVIEW<br>-                inFrame[layer]->m_viewId = layer;<br>-#else<br>-                inFrame[layer]->m_sLayerId = layer;<br>+                inFrame[layer]->m_viewId = m_param->numViews > 1 ? layer : 0;<br>+#endif<br>+#if ENABLE_ALPHA<br>+                inFrame[layer]->m_sLayerId = m_param->numScalableLayers > 1 ? layer : 0;<br> #endif<br>                 inFrame[layer]->m_valid = false;<br>-                if (inFrame[layer]->create(p, inputPic[layer]->quantOffsets))<br>+                if (inFrame[layer]->create(p, inputPic[!m_param->format ? (m_param->numScalableLayers > 1) ? 0 : layer : 0]->quantOffsets))<br>                 {<br>                     /* the first PicYuv created is asked to generate the CU and block unit offset<br>                      * arrays which are then shared with all subsequent PicYuv (orig and recon)<br>@@ -1663,9 +1664,10 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<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>+                inFrame[layer]->m_viewId = m_param->numViews > 1 ? layer : 0;<br>+#endif<br>+#if ENABLE_ALPHA<br>+                inFrame[layer]->m_sLayerId = m_param->numScalableLayers > 1 ? layer : 0;<br> #endif<br>                 inFrame[layer]->m_valid = false;<br>                 inFrame[layer]->m_lowres.bKeyframe = false;<br>@@ -1701,7 +1703,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<br>             }<br> <br>             /* Copy input picture into a Frame and PicYuv, send to lookahead */<br>-            inFrame[layer]->m_fencPic->copyFromPicture(*inputPic[!m_param->format ? layer : 0], *m_param, m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset, !layer);<br>+            inFrame[layer]->m_fencPic->copyFromPicture(*inputPic[!m_param->format ? (m_param->numScalableLayers > 1) ? 0 : layer : 0], *m_param, m_sps.conformanceWindow.rightOffset, m_sps.conformanceWindow.bottomOffset, !layer);<br> <br>             inFrame[layer]->m_poc = (!layer) ? (++m_pocLast) : m_pocLast;<br>             inFrame[layer]->m_userData = inputPic[0]->userData;<br>@@ -2211,12 +2213,11 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture** pic_out)<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>+                if (m_param->numScalableLayers > 1)<br>+                    frameEnc[layer]->m_lowres.sliceType = baseViewType;<br>+                else if(m_param->numViews > 1)<br>+                    frameEnc[layer]->m_lowres.sliceType = IS_X265_TYPE_I(baseViewType) ? X265_TYPE_P : baseViewType;<br>             }<br> #endif<br> <br>@@ -3644,6 +3645,7 @@ void Encoder::initSPS(SPS *sps)<br> <br>     vui.timingInfo.numUnitsInTick = m_param->fpsDenom;<br>     vui.timingInfo.timeScale = m_param->fpsNum;<br>+    sps->sps_extension_flag = false;<br> <br> #if ENABLE_MULTIVIEW<br>     if (m_param->numViews > 1)<br>@@ -3698,6 +3700,8 @@ void Encoder::initPPS(PPS *pps)<br> <br>     pps->numRefIdxDefault[0] = 1;<br>     pps->numRefIdxDefault[1] = 1;<br>+    pps->pps_extension_flag = false;<br>+    pps->maxViews = 1;<br> <br> #if ENABLE_MULTIVIEW<br>     if (m_param->numViews > 1)<br>diff --git a/source/encoder/entropy.cpp b/source/encoder/entropy.cpp<br>index 1fe3d5895..0e45b4976 100644<br>--- a/source/encoder/entropy.cpp<br>+++ b/source/encoder/entropy.cpp<br>@@ -487,11 +487,13 @@ void Entropy::codeVPS(const VPS& vps, const SPS& sps)<br> void Entropy::codeSPS(const SPS& sps, const ScalingList& scalingList, const ProfileTierLevel& ptl, int layer)<br> {<br>     WRITE_CODE(0, 4, "sps_video_parameter_set_id");<br>-    WRITE_CODE(!layer ? sps.maxTempSubLayers - 1 : sps.setSpsExtOrMaxSubLayersMinus1, 3, "sps_ext_or_max_sub_layers_minus1");<br> #if ENABLE_MULTIVIEW<br>+    if(layer != 0 && sps.setSpsExtOrMaxSubLayersMinus1 == 7)<br>+        WRITE_CODE(sps.setSpsExtOrMaxSubLayersMinus1, 3, "sps_ext_or_max_sub_layers_minus1");<br>     if (!(layer != 0 && sps.setSpsExtOrMaxSubLayersMinus1 == 7))<br> #endif<br>     {<br>+        WRITE_CODE(sps.maxTempSubLayers - 1, 3, "sps_max_sub_layers_minus1");<br>         WRITE_FLAG(sps.maxTempSubLayers == 1, "sps_temporal_id_nesting_flag");<br>         codeProfileTier(ptl, sps.maxTempSubLayers, layer);<br>     }<br>@@ -924,21 +926,13 @@ void Entropy::codeSliceHeader(const Slice& slice, FrameData& encData, uint32_t s<br> <br>     WRITE_UVLC(slice.m_sliceType, "slice_type");<br> <br>-    if (layer > 0 || !slice.getIdrPicFlag())<br>+    if ((slice.m_param->numViews > 1 && layer > 0) || !slice.getIdrPicFlag())<br>     {<br>         int picOrderCntLSB = (slice.m_poc - slice.m_lastIDR + (1 << slice.m_sps->log2MaxPocLsb)) % (1 << slice.m_sps->log2MaxPocLsb);<br>         WRITE_CODE(picOrderCntLSB, slice.m_sps->log2MaxPocLsb, "pic_order_cnt_lsb");<br>     }<br>     if (!slice.getIdrPicFlag())<br>     {<br>-#if ENABLE_MULTIVIEW<br>-        if (!(slice.m_param->numViews > 1))<br>-#endif<br>-        {<br>-            int picOrderCntLSB = (slice.m_poc - slice.m_lastIDR + (1 << slice.m_sps->log2MaxPocLsb)) % (1 << slice.m_sps->log2MaxPocLsb);<br>-            WRITE_CODE(picOrderCntLSB, slice.m_sps->log2MaxPocLsb, "pic_order_cnt_lsb");<br>-        }<br>-<br> #if _DEBUG || CHECKED_BUILD<br>         // check for bitstream restriction stating that:<br>         // If the current picture is a BLA or CRA picture, the value of NumPocTotalCurr shall be equal to 0.<br>diff --git a/source/encoder/frameencoder.cpp b/source/encoder/frameencoder.cpp<br>index 19d61ec35..c5175f538 100644<br>--- a/source/encoder/frameencoder.cpp<br>+++ b/source/encoder/frameencoder.cpp<br>@@ -1159,8 +1159,10 @@ void FrameEncoder::compressFrame(int layer)<br>     /* rateControlEnd may also block for earlier frames to call rateControlUpdateStats */<br>     if (!layer && m_top->m_rateControl->rateControlEnd(m_frame[layer], m_accessUnitBits[layer], &m_rce, &filler) < 0)<br>         m_top->m_aborted = true;<br>-    if (!layer)<br>+#if ENABLE_ALPHA || ENABLE_MULTIVIEW<br>+    if (!layer && m_frame[layer+1])<br>         m_frame[1]->m_encData->m_avgQpAq = m_frame[layer]->m_encData->m_avgQpAq;<br>+#endif<br> <br>     if (filler > 0)<br>     {<br>diff --git a/source/x265.h b/source/x265.h<br>index fb06372af..7b5144ec2 100644<br>--- a/source/x265.h<br>+++ b/source/x265.h<br>@@ -650,6 +650,8 @@ typedef enum<br> <br> #if ENABLE_ALPHA || ENABLE_MULTIVIEW<br> #define MAX_LAYERS              2<br>+#else<br>+#define MAX_LAYERS              1<br> #endif<br> <br> #define X265_IPRATIO_STRENGTH   1.43<br>diff --git a/source/x265cli.cpp b/source/x265cli.cpp<br>index c0c70b78b..a4ce6d272 100755<br>--- a/source/x265cli.cpp<br>+++ b/source/x265cli.cpp<br>@@ -983,7 +983,7 @@ namespace X265_NS {<br>                 }<br>             }<br> #endif<br>-            for (int i = 0; i < param->numLayers - !!param->format; i++)<br>+            for (int i = 0; i < param->numLayers; i++)<br>             {<br>                 this->recon[i] = ReconFile::open(reconfn[i], param->sourceWidth, param->sourceHeight, reconFileBitDepth,<br>                     param->fpsNum, param->fpsDenom, param->internalCsp, param->sourceBitDepth);<br>-- <br>2.36.0.windows.1<br><br></div>