[x265] [PATCH] rc: fix to avoid false abr restarts

aarthi at multicorewareinc.com aarthi at multicorewareinc.com
Thu Feb 26 11:18:16 CET 2015


# HG changeset patch
# User Aarthi Thirumalai
# Date 1423638042 -19800
#      Wed Feb 11 12:30:42 2015 +0530
# Node ID bd5a4f539fbc82298877b0ec3cc3bcf2794fbcd3
# Parent  0e89af0781ee95453846340cdbc61d2b21672798
rc: fix to avoid false abr restarts

diff -r 0e89af0781ee -r bd5a4f539fbc source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Wed Feb 25 18:32:04 2015 -0800
+++ b/source/encoder/ratecontrol.cpp	Wed Feb 11 12:30:42 2015 +0530
@@ -219,6 +219,7 @@
     m_statFileOut = NULL;
     m_cutreeStatFileOut = m_cutreeStatFileIn = NULL;
     m_rce2Pass = NULL;
+    m_lastBsliceSatdCost = 0;
 
     // vbv initialization
     m_param->rc.vbvBufferSize = x265_clip3(0, 2000000, m_param->rc.vbvBufferSize);
@@ -357,6 +358,8 @@
         m_encodedBitsWindow[i] = 0;
     }
     m_sliderPos = 0;
+    m_isPatternPresent = false;
+    m_numBframesInPattern = 0;
 
     /* 720p videos seem to be a good cutoff for cplxrSum */
     double tuneCplxFactor = (m_param->rc.cuTree && m_ncu > 3600) ? 2.5 : 1;
@@ -1009,6 +1012,26 @@
             /* Update rce for use in rate control VBV later */
             rce->lastSatd = m_currentSatd;
             X265_CHECK(rce->lastSatd, "satdcost cannot be zero\n");
+            /* Detect a pattern for B frames with same SATDcost to identify a series of static frames
+             * and the P frame at the end of the series marks a possible case for ABR reset logic */
+            if (m_param->bframes)
+            {
+                if (m_sliceType != B_SLICE && m_numBframesInPattern > m_param->bframes)
+                {
+                    m_isPatternPresent = true;
+                }
+                else if (m_sliceType == B_SLICE && !IS_REFERENCED(curFrame))
+                {
+                    if (m_currentSatd != m_lastBsliceSatdCost && !rce->bLastMiniGopBFrame)
+                    {
+                        m_isPatternPresent = false;
+                        m_lastBsliceSatdCost = m_currentSatd;
+                        m_numBframesInPattern = 0;
+                    }
+                    else if (m_currentSatd == m_lastBsliceSatdCost)
+                        m_numBframesInPattern++;
+                }
+            }
         }
         double q = x265_qScale2qp(rateEstimateQscale(curFrame, rce));
         q = x265_clip3((double)QP_MIN, (double)QP_MAX_MAX, q);
@@ -1288,7 +1311,7 @@
                 slidingWindowCplxSum *= 0.5;
                 if (!m_satdCostWindow[pos])
                     break;
-                slidingWindowCplxSum += m_satdCostWindow[pos] / (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION);
+                slidingWindowCplxSum += m_satdCostWindow[pos];
             }
             rce->movingAvgSum = slidingWindowCplxSum;
             m_satdCostWindow[m_sliderPos % s_slidingWindowFrames] = rce->lastSatd;
@@ -1563,9 +1586,11 @@
     // Check if current Slice is a scene cut that follows low detailed/blank frames
     if (rce->lastSatd > 4 * rce->movingAvgSum)
     {
-        if (!m_isAbrReset && rce->movingAvgSum > 0)
+        if (!m_isAbrReset && rce->movingAvgSum > 0
+            && (m_isPatternPresent || !m_param->bframes))
         {
-            int64_t shrtTermWantedBits = (int64_t) (X265_MIN(m_sliderPos, s_slidingWindowFrames) * m_bitrate * m_frameDuration);
+            int pos = X265_MAX(m_sliderPos - m_param->frameNumThreads, 0);
+            int64_t shrtTermWantedBits = (int64_t) (X265_MIN(pos, s_slidingWindowFrames) * m_bitrate * m_frameDuration);
             int64_t shrtTermTotalBitsSum = 0;
             // Reset ABR if prev frames are blank to prevent further sudden overflows/ high bit rate spikes.
             for (int i = 0; i < s_slidingWindowFrames ; i++)
@@ -1581,7 +1606,7 @@
                 m_lastAbrResetPoc = rce->poc;
             }
         }
-        else
+        else if (m_isAbrReset && isFrameDone)
         {
             // Clear flag to reset ABR and continue as usual.
             m_isAbrReset = false;
diff -r 0e89af0781ee -r bd5a4f539fbc source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h	Wed Feb 25 18:32:04 2015 -0800
+++ b/source/encoder/ratecontrol.h	Wed Feb 11 12:30:42 2015 +0530
@@ -181,6 +181,11 @@
     int64_t  m_satdCostWindow[50];
     int      m_sliderPos;
     int64_t  m_encodedBitsWindow[50];
+    /* To detect a pattern of low detailed static frames in single pass ABR using satdcosts */
+    bool m_isPatternPresent;
+    int64_t m_lastBsliceSatdCost;
+    int m_numBframesInPattern;
+
     /* a common variable on which rateControlStart, rateControlEnd and rateControUpdateStats waits to
      * sync the calls to these functions. For example
      * -F2:


More information about the x265-devel mailing list