[x265] [PATCH] Add consistent VBV support for --tune grain

aruna at multicorewareinc.com aruna at multicorewareinc.com
Fri Jun 23 09:25:24 CEST 2017


# HG changeset patch
# User Aruna Matheswaran <aruna at multicorewareinc.com>
# Date 1496833155 -19800
#      Wed Jun 07 16:29:15 2017 +0530
# Branch stable
# Node ID 5e516bd4316c535d7f67b3542cfc2acafb4fa4a9
# Parent  dccf02340c7538e81a940ca53322762d5d284654
Add consistent VBV support for --tune grain

diff -r dccf02340c75 -r 5e516bd4316c doc/reST/cli.rst
--- a/doc/reST/cli.rst	Thu May 25 10:31:58 2017 +0530
+++ b/doc/reST/cli.rst	Wed Jun 07 16:29:15 2017 +0530
@@ -1573,6 +1573,11 @@
    that this option is used through the tune grain feature where a combination 
    of param options are used to improve visual quality.
    
+ .. option:: --const-vbv, --no-const-vbv
+
+   Enables VBV algorithm to be consistent across runs. Default disabled. 
+   Enabled when :option:'--tune' grain is applied.
+   
 .. option:: --qblur <float>
 
 	Temporally blur quants. Default 0.5
diff -r dccf02340c75 -r 5e516bd4316c source/common/param.cpp
--- a/source/common/param.cpp	Thu May 25 10:31:58 2017 +0530
+++ b/source/common/param.cpp	Wed Jun 07 16:29:15 2017 +0530
@@ -236,6 +236,7 @@
     param->rc.bEnableGrain = 0;
     param->rc.qpMin = 0;
     param->rc.qpMax = QP_MAX_MAX;
+    param->rc.bEnableConstVbv = 0;
 
     /* Video Usability Information (VUI) */
     param->vui.aspectRatioIdc = 0;
@@ -494,6 +495,7 @@
             param->psyRd = 4.0;
             param->psyRdoq = 10.0;
             param->bEnableSAO = 0;
+            param->rc.bEnableConstVbv = 1;
         }
         else
             return -1;
@@ -954,6 +956,7 @@
         OPT("limit-sao") p->bLimitSAO = atobool(value);
         OPT("dhdr10-info") p->toneMapFile = strdup(value);
         OPT("dhdr10-opt") p->bDhdr10opt = atobool(value);
+        OPT("const-vbv") p->rc.bEnableConstVbv = atobool(value);
         else
             return X265_PARAM_BAD_NAME;
     }
@@ -1630,6 +1633,7 @@
     s += sprintf(s, " qg-size=%d", p->rc.qgSize);
     BOOL(p->rc.bEnableGrain, "rc-grain");
     s += sprintf(s, " qpmax=%d qpmin=%d", p->rc.qpMax, p->rc.qpMin);
+    BOOL(p->rc.bEnableConstVbv, "const-vbv");
     s += sprintf(s, " sar=%d", p->vui.aspectRatioIdc);
     if (p->vui.aspectRatioIdc == X265_EXTENDED_SAR)
         s += sprintf(s, " sar-width : sar-height=%d:%d", p->vui.sarWidth, p->vui.sarHeight);
diff -r dccf02340c75 -r 5e516bd4316c source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Thu May 25 10:31:58 2017 +0530
+++ b/source/encoder/encoder.cpp	Wed Jun 07 16:29:15 2017 +0530
@@ -518,7 +518,7 @@
         FrameEncoder *encoder = m_frameEncoder[i];
         if (encoder->m_rce.isActive && encoder->m_rce.poc != rc->m_curSlice->m_poc)
         {
-            int64_t bits = (int64_t) X265_MAX(encoder->m_rce.frameSizeEstimated, encoder->m_rce.frameSizePlanned);
+            int64_t bits = m_param->rc.bEnableConstVbv ? (int64_t)encoder->m_rce.frameSizePlanned : (int64_t)X265_MAX(encoder->m_rce.frameSizeEstimated, encoder->m_rce.frameSizePlanned);
             rc->m_bufferFill -= bits;
             rc->m_bufferFill = X265_MAX(rc->m_bufferFill, 0);
             rc->m_bufferFill += encoder->m_rce.bufferRate;
diff -r dccf02340c75 -r 5e516bd4316c source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Thu May 25 10:31:58 2017 +0530
+++ b/source/encoder/frameencoder.cpp	Wed Jun 07 16:29:15 2017 +0530
@@ -1510,14 +1510,17 @@
         x265_emms();
 
         if (bIsVbv)
-        {
-            // Update encoded bits, satdCost, baseQP for each CU
-            curEncData.m_rowStat[row].rowSatd      += curEncData.m_cuStat[cuAddr].vbvCost;
-            curEncData.m_rowStat[row].rowIntraSatd += curEncData.m_cuStat[cuAddr].intraVbvCost;
-            curEncData.m_rowStat[row].encodedBits   += curEncData.m_cuStat[cuAddr].totalBits;
-            curEncData.m_rowStat[row].sumQpRc       += curEncData.m_cuStat[cuAddr].baseQp;
-            curEncData.m_rowStat[row].numEncodedCUs = cuAddr;
-
+        {   
+            // Update encoded bits, satdCost, baseQP for each CU if tune grain is disabled
+            if ((m_param->bEnableWavefront && (!cuAddr || !m_param->rc.bEnableConstVbv)) || !m_param->bEnableWavefront)
+            {
+                curEncData.m_rowStat[row].rowSatd += curEncData.m_cuStat[cuAddr].vbvCost;
+                curEncData.m_rowStat[row].rowIntraSatd += curEncData.m_cuStat[cuAddr].intraVbvCost;
+                curEncData.m_rowStat[row].encodedBits += curEncData.m_cuStat[cuAddr].totalBits;
+                curEncData.m_rowStat[row].sumQpRc += curEncData.m_cuStat[cuAddr].baseQp;
+                curEncData.m_rowStat[row].numEncodedCUs = cuAddr;
+            }
+            
             // If current block is at row end checkpoint, call vbv ratecontrol.
 
             if (!m_param->bEnableWavefront && col == numCols - 1)
@@ -1553,6 +1556,24 @@
 
             else if (m_param->bEnableWavefront && row == col && row)
             {
+                if (m_param->rc.bEnableConstVbv)
+                {
+                    int32_t startCuAddr = numCols * row;
+                    int32_t EndCuAddr = startCuAddr + col;
+                    for (int32_t r = row; r >= 0; r--)
+                    {
+                        for (int32_t c = startCuAddr; c <= EndCuAddr && c <= (int32_t)numCols * (r + 1) - 1; c++)
+                        {
+                            curEncData.m_rowStat[r].rowSatd += curEncData.m_cuStat[c].vbvCost;
+                            curEncData.m_rowStat[r].rowIntraSatd += curEncData.m_cuStat[c].intraVbvCost;
+                            curEncData.m_rowStat[r].encodedBits += curEncData.m_cuStat[c].totalBits;
+                            curEncData.m_rowStat[r].sumQpRc += curEncData.m_cuStat[c].baseQp;
+                            curEncData.m_rowStat[r].numEncodedCUs = c;
+                        }
+                        startCuAddr = EndCuAddr - numCols;
+                        EndCuAddr = startCuAddr + 1;
+                    }
+                }
                 double qpBase = curEncData.m_cuStat[cuAddr].baseQp;
                 int reEncode = m_top->m_rateControl->rowVbvRateControl(m_frame, row, &m_rce, qpBase);
                 qpBase = x265_clip3((double)m_param->rc.qpMin, (double)m_param->rc.qpMax, qpBase);
@@ -1648,6 +1669,23 @@
     }
 
     /** this row of CTUs has been compressed **/
+    if (m_param->bEnableWavefront && m_param->rc.bEnableConstVbv)
+    {
+        if (row == m_numRows - 1)
+        {
+            for (int32_t r = 0; r < (int32_t)m_numRows; r++)
+            {
+                for (int32_t c = curEncData.m_rowStat[r].numEncodedCUs + 1; c < (int32_t)numCols * (r + 1); c++)
+                {
+                    curEncData.m_rowStat[r].rowSatd += curEncData.m_cuStat[c].vbvCost;
+                    curEncData.m_rowStat[r].rowIntraSatd += curEncData.m_cuStat[c].intraVbvCost;
+                    curEncData.m_rowStat[r].encodedBits += curEncData.m_cuStat[c].totalBits;
+                    curEncData.m_rowStat[r].sumQpRc += curEncData.m_cuStat[c].baseQp;
+                    curEncData.m_rowStat[r].numEncodedCUs = c;
+                }
+            }
+        }
+    }
 
     /* If encoding with ABR, update update bits and complexity in rate control
      * after a number of rows so the next frame's rateControlStart has more
diff -r dccf02340c75 -r 5e516bd4316c source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Thu May 25 10:31:58 2017 +0530
+++ b/source/encoder/ratecontrol.cpp	Wed Jun 07 16:29:15 2017 +0530
@@ -2301,7 +2301,8 @@
                     && refFrame 
                     && refFrame->m_encData->m_slice->m_sliceType == picType
                     && refQScale > 0
-                    && refRowSatdCost > 0)
+                    && refRowBits > 0
+                    && !m_param->rc.bEnableConstVbv)
                 {
                     if (abs((int32_t)(refRowSatdCost - satdCostForPendingCus)) < (int32_t)satdCostForPendingCus / 2)
                     {
diff -r dccf02340c75 -r 5e516bd4316c source/x265.h
--- a/source/x265.h	Thu May 25 10:31:58 2017 +0530
+++ b/source/x265.h	Wed Jun 07 16:29:15 2017 +0530
@@ -1194,6 +1194,9 @@
 
         /* sets a hard lower limit on QP */
         int      qpMin;
+
+        /* internally enable if tune grain is set */
+        int      bEnableConstVbv;
     } rc;
 
     /*== Video Usability Information ==*/
diff -r dccf02340c75 -r 5e516bd4316c source/x265cli.h
--- a/source/x265cli.h	Thu May 25 10:31:58 2017 +0530
+++ b/source/x265cli.h	Wed Jun 07 16:29:15 2017 +0530
@@ -158,6 +158,8 @@
     { "qpstep",         required_argument, NULL, 0 },
     { "qpmin",          required_argument, NULL, 0 },
     { "qpmax",          required_argument, NULL, 0 },
+    { "const-vbv",            no_argument, NULL, 0 },
+    { "no-const-vbv",         no_argument, NULL, 0 },
     { "ratetol",        required_argument, NULL, 0 },
     { "cplxblur",       required_argument, NULL, 0 },
     { "qblur",          required_argument, NULL, 0 },
@@ -446,6 +448,7 @@
     H1("   --qpstep <integer>            The maximum single adjustment in QP allowed to rate control. Default %d\n", param->rc.qpStep);
     H1("   --qpmin <integer>             sets a hard lower limit on QP allowed to ratecontrol. Default %d\n", param->rc.qpMin);
     H1("   --qpmax <integer>             sets a hard upper limit on QP allowed to ratecontrol. Default %d\n", param->rc.qpMax);
+    H0("   --[no-]const-vbv              Enable consistent vbv. turned on with tune grain. Default %s\n", OPT(param->rc.bEnableConstVbv));
     H1("   --cbqpoffs <integer>          Chroma Cb QP Offset [-12..12]. Default %d\n", param->cbQpOffset);
     H1("   --crqpoffs <integer>          Chroma Cr QP Offset [-12..12]. Default %d\n", param->crQpOffset);
     H1("   --scaling-list <string>       Specify a file containing HM style quant scaling lists or 'default' or 'off'. Default: off\n");


More information about the x265-devel mailing list