<div dir="ltr">From f6b409512b165e2cb397bfad5ec8c5f883129e28 Mon Sep 17 00:00:00 2001<br>From: AnusuyaKumarasamy <<a href="mailto:anusuya.kumarasamy@multicorewareinc.com">anusuya.kumarasamy@multicorewareinc.com</a>><br>Date: Wed, 21 Aug 2024 09:40:23 +0530<br>Subject: [PATCH 3/7] Add rateontrol support<br><br>---<br> source/common/param.cpp         |  3 --<br> source/encoder/frameencoder.cpp | 50 ++++++++++++++++++++++++++-------<br> 2 files changed, 40 insertions(+), 13 deletions(-)<br><br>diff --git a/source/common/param.cpp b/source/common/param.cpp<br>index aad31b515..72561a9cf 100755<br>--- a/source/common/param.cpp<br>+++ b/source/common/param.cpp<br>@@ -1959,14 +1959,11 @@ int x265_check_params(x265_param* param)<br>     if (param->bEnableAlpha)<br>     {<br>         CHECK((param->internalCsp != X265_CSP_I420), "Alpha encode supported only with i420a colorspace");<br>-        CHECK((param->rc.rateControlMode != X265_RC_CQP), "Alpha encode supported only with CQP mode");<br>     }<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 && param->rc.rateControlMode !=  X265_RC_ABR),<br>-        "Multiview encode supported only with CQP and ABR modes");<br> #endif<br> #if ENABLE_SCC_EXT<br>     CHECK(!!param->bEnableSCC&& param->rdLevel != 6, "Enabling scc extension in x265 requires rdlevel of 6 ");<br>diff --git a/source/encoder/frameencoder.cpp b/source/encoder/frameencoder.cpp<br>index 296ca4581..09ed0b9f7 100644<br>--- a/source/encoder/frameencoder.cpp<br>+++ b/source/encoder/frameencoder.cpp<br>@@ -621,10 +621,18 @@ void FrameEncoder::compressFrame(int layer)<br>             ncu = m_top->m_rateControl->m_ncu * 4;<br>         else<br>             ncu = m_top->m_rateControl->m_ncu;<br>-        for (int i = 0; i < ncu; i++)<br>+        if (m_param->numViews > 1)<br>         {<br>-            m_frame[layer]->m_lowres.qpCuTreeOffset[i] = m_frame[0]->m_lowres.qpCuTreeOffset[i];<br>-            m_frame[layer]->m_lowres.qpAqOffset[i] = m_frame[0]->m_lowres.qpAqOffset[i];<br>+            for (int i = 0; i < ncu; i++)<br>+            {<br>+                m_frame[layer]->m_lowres.qpCuTreeOffset[i] = m_frame[0]->m_lowres.qpCuTreeOffset[i];<br>+                m_frame[layer]->m_lowres.qpAqOffset[i] = m_frame[0]->m_lowres.qpAqOffset[i];<br>+            }<br>+        }<br>+        else if (m_param->numScalableLayers > 1)<br>+        {<br>+            memset(m_frame[layer]->m_lowres.qpCuTreeOffset, 0, sizeof(double)*ncu);<br>+            memset(m_frame[layer]->m_lowres.qpAqOffset, 0, sizeof(double)* ncu);<br>         }<br> <br>         m_frame[layer]->m_encData->m_avgQpAq = m_frame[0]->m_encData->m_avgQpAq;<br>@@ -645,14 +653,24 @@ void FrameEncoder::compressFrame(int layer)<br>                 double* pcCuTree0 = pcAQLayer0->dCuTreeOffset;<br>                 double* pcQP1 = pcAQLayer1->dQpOffset;<br>                 double* pcCuTree1 = pcAQLayer1->dCuTreeOffset;<br>-                for (uint32_t y = 0; y < m_frame[0]->m_fencPic->m_picHeight; y += aqPartHeight)<br>+                if (m_param->numViews > 1)<br>                 {<br>-                    for (uint32_t x = 0; x < m_frame[0]->m_fencPic->m_picWidth; x += aqPartWidth, pcQP0++, pcCuTree0++, pcQP1++, pcCuTree1++)<br>+                    for (uint32_t y = 0; y < m_frame[0]->m_fencPic->m_picHeight; y += aqPartHeight)<br>                     {<br>-                        *pcQP1 = *pcQP0;<br>-                        *pcCuTree1 = *pcCuTree0;<br>+                        for (uint32_t x = 0; x < m_frame[0]->m_fencPic->m_picWidth; x += aqPartWidth, pcQP0++, pcCuTree0++, pcQP1++, pcCuTree1++)<br>+                        {<br>+                            *pcQP1 = *pcQP0;<br>+                            *pcCuTree1 = *pcCuTree0;<br>+                        }<br>                     }<br>                 }<br>+                else if (m_param->numScalableLayers > 1)<br>+                {<br>+                    int numAQPartInWidth = (m_frame[0]->m_fencPic->m_picWidth + aqPartWidth - 1) / aqPartWidth;<br>+                    int numAQPartInHeight = (m_frame[0]->m_fencPic->m_picHeight + aqPartHeight - 1) / aqPartHeight;<br>+                    memset(m_frame[layer]->m_lowres.pAQLayer[d].dQpOffset, 0.0, sizeof(double)*numAQPartInWidth* numAQPartInHeight);<br>+                    memset(m_frame[layer]->m_lowres.pAQLayer[d].dCuTreeOffset, 0.0, sizeof(double)* numAQPartInWidth* numAQPartInHeight);<br>+                }<br>             }<br>         }<br>     }<br>@@ -1213,9 +1231,21 @@ 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 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>+<br>+#if ENABLE_ALPHA<br>+    if (layer && m_param->numScalableLayers > 1)<br>+        m_frame[layer]->m_encData->m_avgQpAq = m_frame[layer]->m_encData->m_avgQpRc;<br>+#endif<br>+#if ENABLE_MULTIVIEW<br>+    if (layer && m_param->numViews > 1)<br>+    {<br>+        double avgQpAq = 0;<br>+        for (uint32_t i = 0; i < slice->m_sps->numCuInHeight; i++)<br>+            avgQpAq += m_frame[layer]->m_encData->m_rowStat[i].sumQpAq;<br>+<br>+        avgQpAq /= (slice->m_sps->numCUsInFrame * m_param->num4x4Partitions);<br>+        m_frame[layer]->m_encData->m_avgQpAq = avgQpAq;<br>+    }<br> #endif<br> <br>     if (filler > 0)<br>-- <br>2.36.0.windows.1<br><br></div>