[x265] [PATCH] aq: Add AQ_AUTO_VARIANCE feature for performing adaptive quantization

Aarthi Thirumalai aarthi at multicorewareinc.com
Tue Dec 24 13:15:40 CET 2013


# HG changeset patch
# User Aarthi Thirumalai
# Date 1387887324 -19800
#      Tue Dec 24 17:45:24 2013 +0530
# Node ID 7a9c4e1a83ab2846c4242e794156f5c2876da405
# Parent  d74f2e0856b443d05ccffd87f86fc942b58a2588
aq: Add AQ_AUTO_VARIANCE feature for performing adaptive quantization.

diff -r d74f2e0856b4 -r 7a9c4e1a83ab source/common/common.cpp
--- a/source/common/common.cpp	Tue Dec 24 08:29:01 2013 +0530
+++ b/source/common/common.cpp	Tue Dec 24 17:45:24 2013 +0530
@@ -494,7 +494,7 @@
           "max consecutive bframe count must be 16 or smaller");
     CHECK(param->lookaheadDepth > X265_LOOKAHEAD_MAX,
           "Lookahead depth must be less than 256");
-    CHECK(param->rc.aqMode < X265_AQ_NONE || param->rc.aqMode > X265_AQ_VARIANCE,
+    CHECK(param->rc.aqMode < X265_AQ_NONE || param->rc.aqMode > X265_AQ_AUTO_VARIANCE,
           "Aq-Mode is out of range");
     CHECK(param->rc.aqStrength < 0 || param->rc.aqStrength > 3,
           "Aq-Strength is out of range");
diff -r d74f2e0856b4 -r 7a9c4e1a83ab source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Tue Dec 24 08:29:01 2013 +0530
+++ b/source/encoder/ratecontrol.cpp	Tue Dec 24 17:45:24 2013 +0530
@@ -69,7 +69,7 @@
 }
 
 /* Find the total AC energy of each block in all planes */
-double RateControl::acEnergyCu(TComPic* pic, uint32_t block_x, uint32_t block_y)
+uint32_t RateControl::acEnergyCu(TComPic* pic, uint32_t block_x, uint32_t block_y)
 {
     int stride = pic->getPicYuvOrg()->getStride();
     int cStride = pic->getPicYuvOrg()->getCStride();
@@ -82,8 +82,7 @@
     var += acEnergyPlane(pic, pic->getPicYuvOrg()->getCbAddr() + blockOffsetChroma, cStride, 1);
     var += acEnergyPlane(pic, pic->getPicYuvOrg()->getCrAddr() + blockOffsetChroma, cStride, 2);
     x265_emms();
-    double strength = cfg->param.rc.aqStrength * 1.0397f;
-    return strength * (X265_LOG2(X265_MAX(var, 1)) - 14.427f);
+    return var;
 }
 
 void RateControl::calcAdaptiveQuantFrame(TComPic *pic)
@@ -101,10 +100,10 @@
     /* Calculate Qp offset for each 16x16 block in the frame */
     int block_xy = 0;
     int block_x = 0, block_y = 0;
-
+    double strength = 0.f;
     if (cfg->param.rc.aqMode == X265_AQ_NONE || cfg->param.rc.aqStrength == 0)
     {
-        /* Need to init it anyways for MB tree */
+        /* Need to init it anyways for CU tree */
         int cuWidth = ((maxCol / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
         int cuHeight = ((maxRow / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
         int cuCount = cuWidth * cuHeight;
@@ -112,7 +111,7 @@
         if(cfg->param.rc.aqMode && cfg->param.rc.aqStrength == 0 )
         {
             memset(pic->m_lowres.qpOffset, 0, cuCount * sizeof(double));
-            memset(pic->m_lowres.qpAqOffset, 0, cuCount * sizeof(double) );
+            memset(pic->m_lowres.qpAqOffset, 0, cuCount * sizeof(double));
             for (int cuxy = 0; cuxy < cuCount; cuxy++ )
                 pic->m_lowres.invQscaleFactor[cuxy] = 256;
         }
@@ -128,20 +127,51 @@
     }
     else
     {
-        for (block_y = 0; block_y < maxRow; block_y += 16)
+        block_xy = 0;
+        double avg_adj_pow2 = 0, avg_adj = 0, qp_adj = 0;
+        if (cfg->param.rc.aqMode == X265_AQ_AUTO_VARIANCE)
         {
-            for (block_x = 0; block_x < maxCol; block_x += 16)
+            double bit_depth_correction = pow (1 << (g_bitDepth - 8), 0.5);
+            for (block_y = 0; block_y < maxRow; block_y += 16)
             {
-                double qp_adj = acEnergyCu(pic, block_x, block_y);
-                if (cfg->param.rc.aqMode)
+                for (block_x = 0; block_x < maxCol; block_x += 16)
                 {
+                    uint32_t energy = acEnergyCu(pic, block_x, block_y);
+                    qp_adj = pow (energy + 1, 0.125);
+                    pic->m_lowres.qpOffset[block_xy] = qp_adj;
+                    avg_adj += qp_adj;
+                    avg_adj_pow2 += qp_adj * qp_adj;
+                    block_xy++;
+                }
+            }
+            avg_adj /= ncu;
+            avg_adj_pow2 /= ncu;
+            strength = cfg->param.rc.aqStrength * avg_adj / bit_depth_correction;
+            avg_adj = avg_adj - 0.5f * (avg_adj_pow2 - (14.f * bit_depth_correction)) / avg_adj;
+        }
+        else
+            strength = cfg->param.rc.aqStrength * 1.0397f;
+            block_xy = 0; 
+            for (block_y = 0; block_y < maxRow; block_y += 16)
+            {
+                for (block_x = 0; block_x < maxCol; block_x += 16)
+                {
+                    if(cfg->param.rc.aqMode == X265_AQ_AUTO_VARIANCE)
+                    {
+                        qp_adj =pic->m_lowres.qpOffset[block_xy];
+                        qp_adj = strength * (qp_adj - avg_adj);
+                    }
+                    else
+                    {
+                        uint32_t energy = acEnergyCu(pic, block_x, block_y);
+                        qp_adj = strength * (X265_LOG2(X265_MAX(energy, 1)) - (14.427f + 2*(g_bitDepth-8)));
+                    }
                     pic->m_lowres.qpAqOffset[block_xy] = qp_adj;
                     pic->m_lowres.qpOffset[block_xy] = qp_adj;
                     pic->m_lowres.invQscaleFactor[block_xy] = x265_exp2fix8(qp_adj);
                     block_xy++;
                 }
             }
-        }
     }
 
     if (cfg->param.bEnableWeightedPred)
diff -r d74f2e0856b4 -r 7a9c4e1a83ab source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h	Tue Dec 24 08:29:01 2013 +0530
+++ b/source/encoder/ratecontrol.h	Tue Dec 24 17:45:24 2013 +0530
@@ -128,7 +128,7 @@
     double getQScale(RateControlEntry *rce, double rateFactor);
     double rateEstimateQscale(RateControlEntry *rce); // main logic for calculating QP based on ABR
     void accumPQpUpdate();
-    double acEnergyCu(TComPic* pic, uint32_t block_x, uint32_t block_y);
+    uint32_t acEnergyCu(TComPic* pic, uint32_t block_x, uint32_t block_y);
 
     void updateVbv(int64_t bits, RateControlEntry* rce);
     void updatePredictor(Predictor *p, double q, double var, double bits);
diff -r d74f2e0856b4 -r 7a9c4e1a83ab source/x265.h
--- a/source/x265.h	Tue Dec 24 08:29:01 2013 +0530
+++ b/source/x265.h	Tue Dec 24 17:45:24 2013 +0530
@@ -162,6 +162,7 @@
 #define X265_TYPE_KEYFRAME      0x0006  /* IDR or I depending on b_open_gop option */
 #define X265_AQ_NONE                 0
 #define X265_AQ_VARIANCE             1
+#define X265_AQ_AUTO_VARIANCE        2
 #define IS_X265_TYPE_I(x) ((x) == X265_TYPE_I || (x) == X265_TYPE_IDR)
 #define IS_X265_TYPE_B(x) ((x) == X265_TYPE_B || (x) == X265_TYPE_BREF)
 


More information about the x265-devel mailing list