[x265] [PATCH 2 of 2] rc: implement ratecontrol upto MAX_MAX_QP

Aarthi Thirumalai aarthi at multicorewareinc.com
Fri Dec 13 09:54:23 CET 2013


# HG changeset patch
# User Aarthi Thirumalai
# Date 1386876827 -19800
#      Fri Dec 13 01:03:47 2013 +0530
# Node ID 30192892976f2aa3c0f9ef915496f72f43a87030
# Parent  0b9c8b0dd9b33acb8b0a93818e4232e0a60689f8
rc: implement ratecontrol upto  MAX_MAX_QP.

For RateControl .virtual qps are used from 0 till 69. Howevr,Before encoding the frame,
the qps are clipped back to 51

diff -r 0b9c8b0dd9b3 -r 30192892976f source/Lib/TLibCommon/TComSlice.cpp
--- a/source/Lib/TLibCommon/TComSlice.cpp	Fri Dec 13 00:36:35 2013 +0530
+++ b/source/Lib/TLibCommon/TComSlice.cpp	Fri Dec 13 01:03:47 2013 +0530
@@ -64,6 +64,7 @@
     , m_sliceQpDeltaCb(0)
     , m_sliceQpDeltaCr(0)
     , m_bReferenced(false)
+    ,m_avgQpRc(0)
     , m_sps(NULL)
     , m_pps(NULL)
     , m_pic(NULL)
diff -r 0b9c8b0dd9b3 -r 30192892976f source/Lib/TLibCommon/TComSlice.h
--- a/source/Lib/TLibCommon/TComSlice.h	Fri Dec 13 00:36:35 2013 +0530
+++ b/source/Lib/TLibCommon/TComSlice.h	Fri Dec 13 01:03:47 2013 +0530
@@ -1356,6 +1356,7 @@
 
     wpScalingParam  m_weightPredTable[2][MAX_NUM_REF][3]; // [REF_PIC_LIST_0 or REF_PIC_LIST_1][refIdx][0:Y, 1:U, 2:V]
     int             m_numWPRefs;                          // number of references for which unidirectional weighted prediction is used
+    int             m_avgQpRc;
 
     TComSlice();
     virtual ~TComSlice();
diff -r 0b9c8b0dd9b3 -r 30192892976f source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Fri Dec 13 00:36:35 2013 +0530
+++ b/source/encoder/frameencoder.cpp	Fri Dec 13 01:03:47 2013 +0530
@@ -329,11 +329,11 @@
     // in RdCost there is only one lambda because the luma and chroma bits are not separated,
     // instead we weight the distortion of chroma.
     int chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
-    int qpc = Clip3(0, 57, qp + chromaQPOffset);
+    int qpc = Clip3(0, 70, qp + chromaQPOffset);
     double cbWeight = pow(2.0, (qp - g_chromaScale[qpc])); // takes into account of the chroma qp mapping and chroma qp Offset
 
     chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
-    qpc = Clip3(0, 57, qp + chromaQPOffset);
+    qpc = Clip3(0, 70, qp + chromaQPOffset);
     double crWeight = pow(2.0, (qp - g_chromaScale[qpc])); // takes into account of the chroma qp mapping and chroma qp Offset
     double chromaLambda = lambda / crWeight;
 
@@ -370,10 +370,10 @@
     // instead we weight the distortion of chroma.
     int qpc;
     int chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
-    qpc = Clip3(0, 57, qp + chromaQPOffset);
+    qpc = Clip3(0, 70, qp + chromaQPOffset);
     double cbWeight = pow(2.0, (qp - g_chromaScale[qpc])); // takes into account of the chroma qp mapping and chroma qp Offset
     chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
-    qpc = Clip3(0, 57, qp + chromaQPOffset);
+    qpc = Clip3(0, 70, qp + chromaQPOffset);
     double crWeight = pow(2.0, (qp - g_chromaScale[qpc])); // takes into account of the chroma qp mapping and chroma qp Offset
     double chromaLambda = lambda / crWeight;
 
@@ -389,7 +389,7 @@
 
     m_frameFilter.m_sao.lumaLambda = lambda;
     m_frameFilter.m_sao.chromaLambda = chromaLambda;
-
+    
     switch (slice->getSliceType())
     {
     case I_SLICE:
@@ -402,7 +402,13 @@
         m_frameFilter.m_sao.depth = 2 + !slice->isReferenced();
         break;
     }
-
+    /* Clip qps back to 0-51 range before encoding */
+    if(qp > MAX_QP)
+    {
+        qp = MAX_QP;
+        slice->setSliceQp(qp);
+        slice->setSliceQpBase(qp);
+    }
     slice->setSliceQpDelta(0);
     slice->setSliceQpDeltaCb(0);
     slice->setSliceQpDeltaCr(0);
@@ -1045,8 +1051,11 @@
         if (m_cfg->param.rc.aqMode)
         {
             int qp = calcQpForCu(m_pic, cuAddr);
+            setLambda(qp, row);
+            if (qp > MAX_QP)
+                qp = MAX_QP;
             cu->setQP(0, (char)qp);
-            setLambda(qp, row);
+
         }
         codeRow.processCU(cu, m_pic->getSlice(), bufSbac, m_cfg->param.bEnableWavefront && col == 1);
 
@@ -1102,7 +1111,7 @@
 int FrameEncoder::calcQpForCu(TComPic *pic, uint32_t cuAddr)
 {
     x265_emms();
-    double qp = pic->getSlice()->getSliceQp();
+    double qp = pic->getSlice()->m_avgQpRc;
     if (m_cfg->param.rc.aqMode)
     {
         /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */
@@ -1127,7 +1136,7 @@
         qp_offset /= cnt;
         qp += qp_offset;
     }
-    return Clip3(MIN_QP, MAX_QP, (int)(qp + 0.5));
+    return Clip3(MIN_QP, MAX_MAX_QP, (int)(qp + 0.5));
 }
 
 TComPic *FrameEncoder::getEncodedPicture(NALUnitEBSP **nalunits)
diff -r 0b9c8b0dd9b3 -r 30192892976f source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Fri Dec 13 00:36:35 2013 +0530
+++ b/source/encoder/ratecontrol.cpp	Fri Dec 13 01:03:47 2013 +0530
@@ -273,14 +273,14 @@
     {
         lastQScaleFor[i] = qp2qScale(cfg->param.rc.rateControlMode == X265_RC_CRF ? ABR_INIT_QP : ABR_INIT_QP_MIN);
         lmin[i] = qp2qScale(MIN_QP);
-        lmax[i] = qp2qScale(MAX_QP);
+        lmax[i] = qp2qScale(MAX_MAX_QP);
     }
 
     if (cfg->param.rc.rateControlMode == X265_RC_CQP)
     {
         qpConstant[P_SLICE] = baseQp;
-        qpConstant[I_SLICE] = Clip3(0, MAX_QP, (int)(baseQp - ipOffset + 0.5));
-        qpConstant[B_SLICE] = Clip3(0, MAX_QP, (int)(baseQp + pbOffset + 0.5));
+        qpConstant[I_SLICE] = Clip3(0, MAX_MAX_QP, (int)(baseQp - ipOffset + 0.5));
+        qpConstant[B_SLICE] = Clip3(0, MAX_MAX_QP, (int)(baseQp + pbOffset + 0.5));
     }
 
     /* qstep - value set as encoder specific */
@@ -309,7 +309,7 @@
     {
         lastSatd = l->getEstimatedPictureCost(pic);
         double q = qScale2qp(rateEstimateQscale(rce));
-        qp = Clip3(MIN_QP, MAX_QP, (int)(q + 0.5));
+        qp = Clip3(MIN_QP, MAX_MAX_QP, (int)(q + 0.5));
         rce->qpaRc = q;
         /* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */
         rce->qRceq = lastRceq;
@@ -327,6 +327,7 @@
     /* set the final QP to slice structure */
     curSlice->setSliceQp(qp);
     curSlice->setSliceQpBase(qp);
+    curSlice->m_avgQpRc = qp;
 }
 
 void RateControl::accumPQpUpdate()
@@ -354,8 +355,8 @@
         bool i1 = nextRefSlice->getSliceType() == I_SLICE;
         int dt0 = abs(curSlice->getPOC() - prevRefSlice->getPOC());
         int dt1 = abs(curSlice->getPOC() - nextRefSlice->getPOC());
-        double q0 = prevRefSlice->getSliceQp();
-        double q1 = nextRefSlice->getSliceQp();
+        double q0 = prevRefSlice->m_avgQpRc;
+        double q1 = nextRefSlice->m_avgQpRc;
 
         if (prevRefSlice->getSliceType() == B_SLICE && prevRefSlice->isReferenced())
             q0 -= pbOffset / 2;


More information about the x265-devel mailing list