[x265] [PATCH RFC] ratecontrol: amortize I frame cost over first few P frames

Steve Borho steve at borho.org
Mon May 12 14:58:35 CEST 2014


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1399899495 18000
#      Mon May 12 07:58:15 2014 -0500
# Node ID b4571ceca12b0ca8b7fa55091e64de3255850c2e
# Parent  3cf70d49bf00b3ef9cb56dd9c3c797a84fd53ecf
ratecontrol: amortize I frame cost over first few P frames

Try to prevent ABR over-compensation after I frames by amortizing the cost over
the next few frames; this patch demonstrates the basic idea. It needs lots of
testing and tuning of the two parameters.

diff -r 3cf70d49bf00 -r b4571ceca12b source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Mon May 12 06:51:16 2014 -0500
+++ b/source/encoder/ratecontrol.cpp	Mon May 12 07:58:15 2014 -0500
@@ -30,6 +30,10 @@
 
 using namespace x265;
 
+/* Amortize the partial cost of I frames over the next N frames */
+const double RateControl::amortizeFraction = 0.5;
+const int RateControl::amortizeFrames = 5;
+
 /* Compute variance to derive AC energy of each block */
 static inline uint32_t acEnergyVar(TComPic *pic, uint64_t sum_ssd, int shift, int i)
 {
@@ -204,6 +208,8 @@
         qCompress = param->rc.qCompress;
 
     // validate for param->rc, maybe it is need to add a function like x265_parameters_valiate()
+    residualFrames = 0;
+    residualCost = 0;
     param->rc.rfConstant = Clip3((double)-QP_BD_OFFSET, (double)51, param->rc.rfConstant);
     param->rc.rfConstantMax = Clip3((double)-QP_BD_OFFSET, (double)51, param->rc.rfConstantMax);
     rateFactorMaxIncrement = 0;
@@ -1082,6 +1088,22 @@
                 }
             }
 
+            if (rce->sliceType == I_SLICE)
+            {
+                /* previous I still had a residual; roll it into the new loan */
+                if (residualFrames)
+                    bits += residualCost * residualFrames;
+
+                residualFrames = amortizeFrames;
+                residualCost = (bits * amortizeFraction) / residualFrames;
+                bits -= residualCost * residualFrames;
+            }
+            else if (residualFrames)
+            {
+                bits += residualCost;
+                residualFrames--;
+            }
+
             if (rce->sliceType != B_SLICE)
                 /* The factor 1.5 is to tune up the actual bits, otherwise the cplxrSum is scaled too low
                  * to improve short term compensation for next frame. */
diff -r 3cf70d49bf00 -r b4571ceca12b source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h	Mon May 12 06:51:16 2014 -0500
+++ b/source/encoder/ratecontrol.h	Mon May 12 07:58:15 2014 -0500
@@ -132,6 +132,12 @@
 
 protected:
 
+    static const double amortizeFraction;
+    static const int amortizeFrames;
+
+    int residualFrames;
+    int residualCost;
+
     void init();
     double getQScale(RateControlEntry *rce, double rateFactor);
     double rateEstimateQscale(TComPic* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR


More information about the x265-devel mailing list