[x265-commits] [x265] quant: scale psy-rdoq by lambda

Steve Borho steve at borho.org
Sat Aug 16 18:34:32 CEST 2014


details:   http://hg.videolan.org/x265/rev/810151a75aed
branches:  
changeset: 7799:810151a75aed
user:      Steve Borho <steve at borho.org>
date:      Fri Aug 15 00:17:15 2014 -0500
description:
quant: scale psy-rdoq by lambda

Using L1 lambda in RDO is unorthodox, but we already do the same thing with
psy-rd energy and it seems to work decently well here weighting the
reconstructed DCT coeff against the RD cost in psy-rdoq.

The goal is for psy-rdoq 1 to be a safe and sane default
Subject: [x265] rdcost: add arbitray scale to make --psy-rd 0..2 range give acceptable quality

details:   http://hg.videolan.org/x265/rev/8d48e5e726cd
branches:  
changeset: 7800:8d48e5e726cd
user:      Steve Borho <steve at borho.org>
date:      Fri Aug 15 15:42:25 2014 -0500
description:
rdcost: add arbitray scale to make --psy-rd 0..2 range give acceptable quality
Subject: [x265] param: re-enable psy-rdoq range check for [0..10], print with two digits

details:   http://hg.videolan.org/x265/rev/1710b46949f2
branches:  
changeset: 7801:1710b46949f2
user:      Steve Borho <steve at borho.org>
date:      Fri Aug 15 16:27:47 2014 -0500
description:
param: re-enable psy-rdoq range check for [0..10], print with two digits
Subject: [x265] quant: set lambdas at the same time quant QP is configured

details:   http://hg.videolan.org/x265/rev/eb23702aacd8
branches:  
changeset: 7802:eb23702aacd8
user:      Steve Borho <steve at borho.org>
date:      Sat Aug 16 10:49:38 2014 -0500
description:
quant: set lambdas at the same time quant QP is configured
Subject: [x265] analysis: nits

details:   http://hg.videolan.org/x265/rev/6b14a488d586
branches:  
changeset: 7803:6b14a488d586
user:      Steve Borho <steve at borho.org>
date:      Sat Aug 16 10:49:53 2014 -0500
description:
analysis: nits

diffstat:

 source/common/param.cpp         |   6 +++---
 source/common/quant.cpp         |  21 ++++++++-------------
 source/common/quant.h           |   6 ++++--
 source/encoder/analysis.cpp     |   4 +++-
 source/encoder/cturow.cpp       |   1 +
 source/encoder/frameencoder.cpp |   8 +++-----
 source/encoder/rdcost.h         |   2 +-
 7 files changed, 23 insertions(+), 25 deletions(-)

diffs (193 lines):

diff -r 4c09d2ef5f1b -r 6b14a488d586 source/common/param.cpp
--- a/source/common/param.cpp	Thu Aug 14 20:45:39 2014 -0500
+++ b/source/common/param.cpp	Sat Aug 16 10:49:53 2014 -0500
@@ -947,7 +947,7 @@ int x265_check_params(x265_param *param)
     CHECK(param->rc.aqStrength < 0 || param->rc.aqStrength > 3,
           "Aq-Strength is out of range");
     CHECK(param->psyRd < 0 || 2.0 < param->psyRd, "Psy-rd strength must be between 0 and 2.0");
-    // CHECK(param->psyRdoq < 0 || 2.0 < param->psyRdoq, "Psy-rdoq strength must be between 0 and 2.0");
+    CHECK(param->psyRdoq < 0 || 10.0 < param->psyRdoq, "Psy-rdoq strength must be between 0 and 10.0");
     CHECK(param->bEnableWavefront < 0, "WaveFrontSynchro cannot be negative");
     CHECK((param->vui.aspectRatioIdc < 0
            || param->vui.aspectRatioIdc > 16)
@@ -1151,9 +1151,9 @@ void x265_print_params(x265_param *param
     TOOLOPT(param->bEnableEarlySkip, "esd");
     fprintf(stderr, "rd=%d ", param->rdLevel);
     if (param->psyRd > 0.)
-        fprintf(stderr, "psy-rd=%.1lf ", param->psyRd);
+        fprintf(stderr, "psy-rd=%.2lf ", param->psyRd);
     if (param->psyRdoq > 0.)
-        fprintf(stderr, "psy-rdoq=%.1lf ", param->psyRdoq);
+        fprintf(stderr, "psy-rdoq=%.2lf ", param->psyRdoq);
     if (param->noiseReduction)
         fprintf(stderr, "nr=%d ", param->noiseReduction);
 
diff -r 4c09d2ef5f1b -r 6b14a488d586 source/common/quant.cpp
--- a/source/common/quant.cpp	Thu Aug 14 20:45:39 2014 -0500
+++ b/source/common/quant.cpp	Sat Aug 16 10:49:53 2014 -0500
@@ -199,13 +199,6 @@ void Quant::setChromaQP(int qpin, TextTy
     m_qpParam[ttype].setQpParam(qp + QP_BD_OFFSET);
 }
 
-void Quant::setLambdas(double lambdaY, double lambdaCb, double lambdaCr)
-{
-    m_lambda2[0] = (int64_t)(lambdaY * 256. + 0.5);
-    m_lambda2[1] = (int64_t)(lambdaCb * 256. + 0.5);
-    m_lambda2[2] = (int64_t)(lambdaCr * 256. + 0.5);
-}
-
 /* To minimize the distortion only. No rate is considered */
 uint32_t Quant::signBitHidingHDQ(coeff_t* coeff, int32_t* deltaU, uint32_t numSig, const TUEntropyCodingParameters &codeParams)
 {
@@ -491,19 +484,21 @@ uint32_t Quant::rdoQuant(TComDataCU* cu,
         return 0;
 
     uint32_t trSize = 1 << log2TrSize;
+    int64_t lambda2 = m_qpParam[ttype].lambda2;
+    int64_t lambda  = m_qpParam[ttype].lambda;
 
     /* unquant constants for measuring distortion. Scaling list quant coefficients have a (1 << 4)
      * scale applied that must be removed during unquant. Note that in real dequant there is clipping
-     * at several stages. We skip the clipping when measuring RD cost */
-#define UNQUANT(lvl) (((lvl) * (unquantScale[blkPos] << per) + unquantRound) >> unquantShift)
+     * at several stages. We skip the clipping for simplicity when measuring RD cost */
     int32_t *unquantScale = m_scalingList->m_dequantCoef[log2TrSize - 2][scalingListType][rem];
     int unquantShift = QUANT_IQUANT_SHIFT - QUANT_SHIFT - transformShift + (m_scalingList->m_bEnabled ? 4 : 0);
     int unquantRound = (unquantShift > per) ? 1 << (unquantShift - per - 1) : 0;
+    int scaleBits = SCALE_BITS - 2 * transformShift;
 
+#define UNQUANT(lvl)    (((lvl) * (unquantScale[blkPos] << per) + unquantRound) >> unquantShift)
 #define SIGCOST(bits)   ((lambda2 * (bits)) >> 8)
 #define RDCOST(d, bits) ((((int64_t)d * d) << scaleBits) + ((lambda2 * (bits)) >> 8))
-    int64_t lambda2 = m_lambda2[ttype];
-    int scaleBits = SCALE_BITS - 2 * transformShift;
+#define PSYVALUE(rec)   ((m_psyRdoqScale * lambda * (rec)) >> (16 - scaleBits))
 
     int64_t costCoeff[32 * 32];   /* d*d + lambda * bits */
     int64_t costUncoded[32 * 32]; /* d*d + lambda * 0    */
@@ -573,7 +568,7 @@ uint32_t Quant::rdoQuant(TComDataCU* cu,
             costUncoded[scanPos] = (int64_t)(signCoef * signCoef) << scaleBits;
             if (usePsy && blkPos)
                 /* when no residual coefficient is coded, predicted coef == recon coef */
-                costUncoded[scanPos] -= (((m_psyRdoqScale * predictedCoef) << scaleBits) >> 8);
+                costUncoded[scanPos] -= PSYVALUE(predictedCoef);
 
             totalUncodedCost += costUncoded[scanPos];
 
@@ -644,7 +639,7 @@ uint32_t Quant::rdoQuant(TComDataCU* cu,
                         if (usePsy && blkPos)
                         {
                             int reconCoef = abs(unquantAbsLevel + SIGN(predictedCoef, signCoef));
-                            curCost -= (int)(((m_psyRdoqScale * reconCoef) << scaleBits) >> 8);
+                            curCost -= PSYVALUE(reconCoef);
                         }
 
                         if (curCost < costCoeff[scanPos])
diff -r 4c09d2ef5f1b -r 6b14a488d586 source/common/quant.h
--- a/source/common/quant.h	Thu Aug 14 20:45:39 2014 -0500
+++ b/source/common/quant.h	Sat Aug 16 10:49:53 2014 -0500
@@ -41,6 +41,8 @@ struct QpParam
     int rem;
     int per;
     int qp;
+    int64_t lambda2; /* FIX8 */
+    int64_t lambda;  /* FIX8 */
 
     QpParam() : qp(MAX_INT) {}
 
@@ -51,6 +53,8 @@ struct QpParam
             rem = qpScaled % 6;
             per = qpScaled / 6;
             qp  = qpScaled;
+            lambda2 = (int64_t)(x265_lambda2_tab[qp - QP_BD_OFFSET] * 256. + 0.5);
+            lambda  = (int64_t)(x265_lambda_tab[qp - QP_BD_OFFSET] * 256. + 0.5);
         }
     }
 };
@@ -67,7 +71,6 @@ protected:
     const ScalingList* m_scalingList;
 
     QpParam            m_qpParam[3];
-    int64_t            m_lambda2[3]; /* FIX8 lambda2 values per plane */
 
     bool               m_useRDOQ;
     int64_t            m_psyRdoqScale;
@@ -87,7 +90,6 @@ public:
 
     /* CU setup */
     void setQPforQuant(TComDataCU* cu);
-    void setLambdas(double lambdaY, double lambdaCb, double lambdaCr);
 
     uint32_t transformNxN(TComDataCU* cu, pixel *fenc, uint32_t fencstride, int16_t* residual, uint32_t stride, coeff_t* coeff,
                           uint32_t log2TrSize, TextType ttype, uint32_t absPartIdx, bool useTransformSkip);
diff -r 4c09d2ef5f1b -r 6b14a488d586 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp	Thu Aug 14 20:45:39 2014 -0500
+++ b/source/encoder/analysis.cpp	Sat Aug 16 10:49:53 2014 -0500
@@ -247,6 +247,7 @@ void Analysis::compressCU(TComDataCU* cu
     if (m_bestCU[0]->m_slice->m_sliceType == I_SLICE)
     {
         compressIntraCU(m_bestCU[0], m_tempCU[0], 0, false);
+
         if (m_param->bLogCuStats || m_param->rc.bStatWrite)
         {
             uint32_t i = 0, part;
@@ -278,11 +279,12 @@ void Analysis::compressCU(TComDataCU* cu
             TComDataCU* outBestCU = NULL;
 
             /* At the start of analysis, the best CU is a null pointer
-            On return, it points to the CU encode with best chosen mode*/
+             * On return, it points to the CU encode with best chosen mode */
             compressInterCU_rd0_4(outBestCU, m_tempCU[0], cu, 0, false, 0, 4);
         }
         else
             compressInterCU_rd5_6(m_bestCU[0], m_tempCU[0], 0, false);
+
         if (m_param->bLogCuStats || m_param->rc.bStatWrite)
         {
             uint32_t i = 0, part;
diff -r 4c09d2ef5f1b -r 6b14a488d586 source/encoder/cturow.cpp
--- a/source/encoder/cturow.cpp	Thu Aug 14 20:45:39 2014 -0500
+++ b/source/encoder/cturow.cpp	Sat Aug 16 10:49:53 2014 -0500
@@ -51,6 +51,7 @@ void CTURow::processCU(TComDataCU *cu, E
     tld.m_cuCoder.m_entropyCoder = &m_entropyCoder;
     tld.m_cuCoder.m_rdEntropyCoders = m_rdEntropyCoders;
     tld.m_cuCoder.m_quant.m_entropyCoder = &m_entropyCoder;
+    tld.m_cuCoder.m_quant.setQPforQuant(cu);
 
     tld.m_cuCoder.compressCU(cu); // Does all the CU analysis
 
diff -r 4c09d2ef5f1b -r 6b14a488d586 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Thu Aug 14 20:45:39 2014 -0500
+++ b/source/encoder/frameencoder.cpp	Sat Aug 16 10:49:53 2014 -0500
@@ -871,16 +871,14 @@ void FrameEncoder::setLambda(int qp, Thr
     int qpCb = Clip3(0, MAX_MAX_QP, qp + slice->m_pps->chromaCbQpOffset);
     int qpCr = Clip3(0, MAX_MAX_QP, qp + slice->m_pps->chromaCrQpOffset);
     qp = Clip3(0, MAX_MAX_QP, qp);
-    double lambda2 = x265_lambda2_tab[qp];
-    double lambdaCb = x265_lambda2_tab[qpCb];
-    double lambdaCr = x265_lambda2_tab[qpCr];
 
     tld.m_cuCoder.m_me.setQP(qp);
-    tld.m_cuCoder.m_quant.setLambdas(lambda2, lambdaCb, lambdaCr);
-    tld.m_cuCoder.m_rdCost.setLambda(lambda2, x265_lambda_tab[qp]);
+    tld.m_cuCoder.m_rdCost.setLambda(x265_lambda2_tab[qp], x265_lambda_tab[qp]);
+
     int chroma_offset_idx = X265_MIN(qp - qpCb + 12, MAX_CHROMA_LAMBDA_OFFSET);
     uint16_t lambdaOffset = tld.m_cuCoder.m_rdCost.m_psyRd ? x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256;
     tld.m_cuCoder.m_rdCost.setCbDistortionWeight(lambdaOffset);
+
     chroma_offset_idx = X265_MIN(qp - qpCr + 12, MAX_CHROMA_LAMBDA_OFFSET);
     lambdaOffset = tld.m_cuCoder.m_rdCost.m_psyRd ? x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256;
     tld.m_cuCoder.m_rdCost.setCrDistortionWeight(lambdaOffset);
diff -r 4c09d2ef5f1b -r 6b14a488d586 source/encoder/rdcost.h
--- a/source/encoder/rdcost.h	Thu Aug 14 20:45:39 2014 -0500
+++ b/source/encoder/rdcost.h	Sat Aug 16 10:49:53 2014 -0500
@@ -40,7 +40,7 @@ public:
     uint64_t  m_crDistortionWeight;
     uint32_t  m_psyRd;
 
-    void setPsyRdScale(double scale)                { m_psyRd = (uint32_t)floor(256.0 * scale); }
+    void setPsyRdScale(double scale)                { m_psyRd = (uint32_t)floor(256.0 * scale * 0.33); }
     void setCbDistortionWeight(uint16_t weightFix8) { m_cbDistortionWeight = weightFix8; }
     void setCrDistortionWeight(uint16_t weightFix8) { m_crDistortionWeight = weightFix8; }
 


More information about the x265-commits mailing list