[x265] [PATCH] ABR tuning for MV-HEVC

Gopi Satykrishna Akisetty gopi.satykrishna at multicorewareinc.com
Thu Aug 15 04:44:43 UTC 2024


>From d3127dca7b3028e158ca73edaec803ee92facb94 Mon Sep 17 00:00:00 2001
From: gopi satykrishna akisetty <gopi.satykrishna at multicorewareinc.com>
Date: Thu, 8 Aug 2024 22:06:12 +0530
Subject: [PATCH] ABR tuning for MV-HEVC

---
 source/common/param.cpp         |  3 ++-
 source/encoder/frameencoder.cpp | 48 ++++++++++++++++++++++++++++++---
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/source/common/param.cpp b/source/common/param.cpp
index 5288bf453..aad31b515 100755
--- a/source/common/param.cpp
+++ b/source/common/param.cpp
@@ -1965,7 +1965,8 @@ int x265_check_params(x265_param* param)
 #if ENABLE_MULTIVIEW
     CHECK((param->numViews > 2), "Multi-View Encoding currently support
only 2 views");
     CHECK((param->numViews > 1) && (param->internalBitDepth != 8),
"BitDepthConstraint must be 8 for Multiview main profile");
-    CHECK((param->numViews > 1 && param->rc.rateControlMode !=
X265_RC_CQP), "Multiview encode supported only with CQP mode");
+    CHECK((param->numViews > 1) && (param->rc.rateControlMode !=
X265_RC_CQP && param->rc.rateControlMode !=  X265_RC_ABR),
+        "Multiview encode supported only with CQP and ABR modes");
 #endif
 #if ENABLE_SCC_EXT
     CHECK(!!param->bEnableSCC&& param->rdLevel != 6, "Enabling scc
extension in x265 requires rdlevel of 6 ");
diff --git a/source/encoder/frameencoder.cpp
b/source/encoder/frameencoder.cpp
index 7d02d0d96..0faa16713 100644
--- a/source/encoder/frameencoder.cpp
+++ b/source/encoder/frameencoder.cpp
@@ -613,7 +613,49 @@ void FrameEncoder::compressFrame(int layer)
     int qp = (layer == 0) ?
m_top->m_rateControl->rateControlStart(m_frame[layer], &m_rce, m_top) :
(int)m_rce.newQp;

     m_rce.newQp = qp;
+
+    if (!!layer && m_top->m_lookahead->m_bAdaptiveQuant)
+    {
+        int ncu;
+        if (m_param->rc.qgSize == 8)
+            ncu = m_top->m_rateControl->m_ncu * 4;
+        else
+            ncu = m_top->m_rateControl->m_ncu;
+        for (int i = 0; i < ncu; i++)
+        {
+            m_frame[layer]->m_lowres.qpCuTreeOffset[i] =
m_frame[0]->m_lowres.qpCuTreeOffset[i];
+            m_frame[layer]->m_lowres.qpAqOffset[i] =
m_frame[0]->m_lowres.qpAqOffset[i];
+        }

+        m_frame[layer]->m_encData->m_avgQpAq =
m_frame[0]->m_encData->m_avgQpAq;
+        m_frame[layer]->m_encData->m_avgQpRc =
m_frame[0]->m_encData->m_avgQpRc;
+        if (!!m_param->rc.hevcAq)
+        {
+            for (uint32_t d = 0; d < 4; d++)
+            {
+                int ctuSizeIdx = 6 - g_log2Size[m_param->maxCUSize];
+                int aqDepth = g_log2Size[m_param->maxCUSize] -
g_log2Size[m_param->rc.qgSize];
+                if (!aqLayerDepth[ctuSizeIdx][aqDepth][d])
+                    continue;
+                PicQPAdaptationLayer* pcAQLayer0 =
&m_frame[0]->m_lowres.pAQLayer[d];
+                PicQPAdaptationLayer* pcAQLayer1 =
&m_frame[layer]->m_lowres.pAQLayer[d];
+                const uint32_t aqPartWidth =
m_frame[0]->m_lowres.pAQLayer[d].aqPartWidth;
+                const uint32_t aqPartHeight =
m_frame[0]->m_lowres.pAQLayer[d].aqPartHeight;
+                double* pcQP0 = pcAQLayer0->dQpOffset;
+                double* pcCuTree0 = pcAQLayer0->dCuTreeOffset;
+                double* pcQP1 = pcAQLayer1->dQpOffset;
+                double* pcCuTree1 = pcAQLayer1->dCuTreeOffset;
+                for (uint32_t y = 0; y <
m_frame[0]->m_fencPic->m_picHeight; y += aqPartHeight)
+                {
+                    for (uint32_t x = 0; x <
m_frame[0]->m_fencPic->m_picWidth; x += aqPartWidth, pcQP0++, pcCuTree0++,
pcQP1++, pcCuTree1++)
+                    {
+                        *pcQP1 = *pcQP0;
+                        *pcCuTree1 = *pcCuTree0;
+                    }
+                }
+            }
+        }
+    }
     if (m_param->bEnableTemporalFilter)
     {
         m_frameEncTF->m_QP = qp;
@@ -1551,7 +1593,7 @@ void FrameEncoder::processRowEncoder(int intRow,
ThreadLocalData& tld, int layer
         const uint32_t bLastCuInSlice = (bLastRowInSlice & (col == numCols
- 1)) ? 1 : 0;
         ctu->initCTU(*m_frame[layer], cuAddr, slice->m_sliceQp,
bFirstRowInSlice, bLastRowInSlice, bLastCuInSlice);

-        if (bIsVbv)
+        if (!layer && bIsVbv)
         {
             if (col == 0 && !m_param->bEnableWavefront)
             {
@@ -1719,7 +1761,7 @@ void FrameEncoder::processRowEncoder(int intRow,
ThreadLocalData& tld, int layer
         curEncData.m_cuStat[cuAddr].totalBits = best.totalBits;
         x265_emms();

-        if (bIsVbv)
+        if (!layer && bIsVbv)
         {
             // Update encoded bits, satdCost, baseQP for each CU if tune
grain is disabled
             FrameData::RCStatCU& cuStat = curEncData.m_cuStat[cuAddr];
@@ -1904,7 +1946,7 @@ void FrameEncoder::processRowEncoder(int intRow,
ThreadLocalData& tld, int layer
      * after half the frame is encoded, but after this initial period we
update
      * after refLagRows (the number of rows reference frames must have
completed
      * before referencees may begin encoding) */
-    if (m_param->rc.rateControlMode == X265_RC_ABR || bIsVbv)
+    if ((!layer) && (m_param->rc.rateControlMode == X265_RC_ABR || bIsVbv))
     {
         uint32_t rowCount = 0;
         uint32_t maxRows = m_sliceBaseRow[sliceId + 1] -
m_sliceBaseRow[sliceId];
-- 
2.34.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240815/bb9cb212/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-ABR-tuning-for-MV-HEVC.patch
Type: application/octet-stream
Size: 5328 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240815/bb9cb212/attachment-0001.obj>


More information about the x265-devel mailing list