[x265] [PATCH] lambda: [CHANGES OUTPUT] Change the distortion weights applied to chroma

deepthi at multicorewareinc.com deepthi at multicorewareinc.com
Wed Jun 18 11:29:33 CEST 2014


# HG changeset patch
# User Deepthi Nandakumar <deepthi at multicorewareinc.com>
# Date 1403083757 -19800
#      Wed Jun 18 14:59:17 2014 +0530
# Node ID da3d728616c0f5eb5caf41062ab4f9a05ddd078f
# Parent  a43a223a12944ef4e3d83318d51ce8bbcbb855d4
lambda: [CHANGES OUTPUT] Change the distortion weights applied to chroma.

Inside R-D, a single lambda is applied for both luma and chroma. To account for the different QPs,
(as defined by the standard) the chroma distortion was weighted by a factor proportional to the
difference in QPs. This patch eliminates the extra weighting given to the chroma distortion
(since it is visually less perceptible).

diff -r a43a223a1294 -r da3d728616c0 source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp	Wed Jun 18 00:04:09 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp	Wed Jun 18 14:59:17 2014 +0530
@@ -143,15 +143,17 @@
     return false;
 }
 
-void TEncSearch::setQP(int qp, double cbWeight, double crWeight)
+void TEncSearch::setQP(int qp, int qpCb, int qpCr)
 {
     double lambda2 = x265_lambda2_tab[qp];
+    double lambdaCb = x265_lambda2_tab[qpCb];
+    double lambdaCr = x265_lambda2_tab[qpCr];
 
     m_me.setQP(qp);
-    m_trQuant->setLambdas(lambda2, lambda2 / cbWeight, lambda2 / crWeight);
+    m_trQuant->setLambdas(lambda2, lambdaCb, lambdaCr);
     m_rdCost->setLambda(lambda2, x265_lambda_tab[qp]);
-    m_rdCost->setCbDistortionWeight(cbWeight);
-    m_rdCost->setCrDistortionWeight(crWeight);
+    m_rdCost->setCbDistortionWeight(1.0);
+    m_rdCost->setCrDistortionWeight(1.0);
 }
 
 void TEncSearch::xEncSubdivCbfQT(TComDataCU* cu, uint32_t trDepth, uint32_t absPartIdx, uint32_t absPartIdxStep, uint32_t width, uint32_t height, bool bLuma, bool bChroma)
diff -r a43a223a1294 -r da3d728616c0 source/Lib/TLibEncoder/TEncSearch.h
--- a/source/Lib/TLibEncoder/TEncSearch.h	Wed Jun 18 00:04:09 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.h	Wed Jun 18 14:59:17 2014 +0530
@@ -140,7 +140,7 @@
 
     void setRDGoOnSbacCoder(TEncSbac* rdGoOnSbacCoder) { m_rdGoOnSbacCoder = rdGoOnSbacCoder; }
 
-    void setQP(int QP, double cbWeight, double crWeight);
+    void setQP(int qp, int qpCb, int qpCr);
 
     TEncSearch();
     virtual ~TEncSearch();
diff -r a43a223a1294 -r da3d728616c0 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Wed Jun 18 00:04:09 2014 -0500
+++ b/source/encoder/frameencoder.cpp	Wed Jun 18 14:59:17 2014 +0530
@@ -364,20 +364,14 @@
 void FrameEncoder::setLambda(int qp, int row)
 {
     TComSlice*  slice = m_pic->getSlice();
-    int         chFmt = slice->getSPS()->getChromaFormatIdc();
-
-    // for RDO
-    // 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, MAX_MAX_QP, qp + chromaQPOffset);
-    double cbWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset
-
+    int qpCb = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
+    
     chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
-    qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
-    double crWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset
-
-    m_rows[row].m_search.setQP(qp, cbWeight, crWeight);
+    int qpCr = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
+    
+    m_rows[row].m_search.setQP(qp, qpCb, qpCr);
 }
 
 void FrameEncoder::compressFrame()
@@ -386,7 +380,6 @@
     int64_t      startCompressTime = x265_mdate();
     TEncEntropy* entropyCoder      = getEntropyCoder(0);
     TComSlice*   slice             = m_pic->getSlice();
-    int          chFmt             = slice->getSPS()->getChromaFormatIdc();
     int          totalCoded        = (int)m_top->m_encodedFrameNum - 1;
 
     m_nalCount = 0;
@@ -512,20 +505,15 @@
 
     int qp = slice->getSliceQp();
 
-    // for RDO
-    // in RdCost there is only one lambda because the luma and chroma bits are not separated,
-    // instead we weight the distortion of chroma.
-    int qpc;
     int chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
-    qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
-    double cbWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset
-
+    int qpCb = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
+    
     chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
-    qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
-    double crWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset
-
+    int qpCr = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
+    
     double lambda = x265_lambda2_tab[qp];
-    double chromaLambda = lambda / crWeight;
+    /* Assuming qpCb and qpCr are the same, since SAO takes only a single chroma lambda. TODO: Check why */
+    double chromaLambda = x265_lambda2_tab[qpCb];
 
     // NOTE: set SAO lambda every Frame
     m_frameFilter.m_sao.lumaLambda = lambda;
@@ -535,7 +523,7 @@
     for (int i = 0; i < m_numRows; i++)
     {
         m_rows[i].m_search.m_me.setSourcePlane(fenc->getLumaAddr(), fenc->getStride());
-        m_rows[i].m_search.setQP(qp, cbWeight, crWeight);
+        m_rows[i].m_search.setQP(qp, qpCb, qpCr);
     }
 
     // Clip qps back to 0-51 range before encoding


More information about the x265-devel mailing list