[x265] [PATCH 2 of 3] lambda: change chroma lambda distortion weighting to resemble x264

deepthi at multicorewareinc.com deepthi at multicorewareinc.com
Mon Jun 16 13:19:40 CEST 2014


# HG changeset patch
# User Deepthi Nandakumar <deepthi at multicorewareinc.com>
# Date 1402916716 -19800
#      Mon Jun 16 16:35:16 2014 +0530
# Node ID 4d76a9c8b5abbf143e5869d55cf80a8816d99a68
# Parent  ff3a85f715d43e2c21aec295426ae9dbe7c03d75
lambda: change chroma lambda distortion weighting to resemble x264.

1. x264 scales the chroma distortion by a factor derived from a lambda offset table
when psyRd is enabled.

2. This patch also removes the separate Cb and Cr distortion weights that were carried over from HM,
and replaces it with 256 when psy-rd is disabled, and the above-mentioned lambda offset when it is enabled.

diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp	Mon Jun 16 16:12:00 2014 +0530
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp	Mon Jun 16 16:35:16 2014 +0530
@@ -143,16 +143,22 @@
     return false;
 }
 
-void TEncSearch::setQP(int qp, double crWeight, double cbWeight)
+void TEncSearch::setQP(int qp)
 {
-    double lambda2 = x265_lambda2_tab[qp];
-    double chromaLambda = lambda2 / crWeight;
+    double lambda2 = x265_lambda2_tab[qp];   
+
+#define SPEC_QP(x) X265_MIN(x, QP_MAX_SPEC)
+    int effective_chroma_qp = chroma_qp_table[SPEC_QP(qp)] + X265_MAX(qp - QP_MAX_SPEC, 0);
+    double chromaLambda = x265_lambda2_tab[effective_chroma_qp];
+    int chroma_offset_idx = X265_MIN (qp - effective_chroma_qp + 12, MAX_CHROMA_LAMBDA_OFFSET);
+    uint64_t chromaWeight = m_rdCost->psyRdEnabled() ? x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256;
+#undef SPEC_QP
 
     m_me.setQP(qp);
     m_trQuant->setLambda(lambda2, chromaLambda);
     m_rdCost->setLambda(lambda2, x265_lambda_tab[qp]);
-    m_rdCost->setCbDistortionWeight(cbWeight);
-    m_rdCost->setCrDistortionWeight(crWeight);
+    m_rdCost->setCbDistortionWeight(chromaWeight);
+    m_rdCost->setCrDistortionWeight(chromaWeight);
 }
 
 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 ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.h
--- a/source/Lib/TLibEncoder/TEncSearch.h	Mon Jun 16 16:12:00 2014 +0530
+++ b/source/Lib/TLibEncoder/TEncSearch.h	Mon Jun 16 16:35:16 2014 +0530
@@ -142,7 +142,7 @@
 
     void setRDGoOnSbacCoder(TEncSbac* rdGoOnSbacCoder) { m_rdGoOnSbacCoder = rdGoOnSbacCoder; }
 
-    void setQP(int QP, double crWeight, double cbWeight);
+    void setQP(int QP);
 
     TEncSearch();
     virtual ~TEncSearch();
diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Mon Jun 16 16:12:00 2014 +0530
+++ b/source/encoder/frameencoder.cpp	Mon Jun 16 16:35:16 2014 +0530
@@ -363,22 +363,8 @@
 }
 
 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
-
-    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, crWeight, cbWeight);
+{  
+    m_rows[row].m_search.setQP(qp);
 }
 
 void FrameEncoder::compressFrame()
@@ -387,7 +373,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;
@@ -515,21 +500,13 @@
     }
 
     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
-
-    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
-
+     
     double lambda = x265_lambda2_tab[qp];
-    double chromaLambda = lambda / crWeight;
+
+#define SPEC_QP(x) X265_MIN(x, QP_MAX_SPEC)
+    int effective_chroma_qp = chroma_qp_table[SPEC_QP(qp)] + X265_MAX(qp - QP_MAX_SPEC, 0);
+    double chromaLambda = x265_lambda2_tab[effective_chroma_qp];    
+#undef SPEC_QP
 
     // NOTE: set SAO lambda every Frame
     m_frameFilter.m_sao.lumaLambda = lambda;
@@ -539,7 +516,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, crWeight, cbWeight);
+        m_rows[i].m_search.setQP(qp);
     }
 
     // Clip qps back to 0-51 range before encoding
diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/encoder/rdcost.h
--- a/source/encoder/rdcost.h	Mon Jun 16 16:12:00 2014 +0530
+++ b/source/encoder/rdcost.h	Mon Jun 16 16:35:16 2014 +0530
@@ -53,14 +53,14 @@
         m_lambdaSAD = (uint64_t)floor(256.0 * lambda);
     }
 
-    void setCbDistortionWeight(double cbDistortionWeight)
+    void setCbDistortionWeight(uint64_t cbDistortionWeight)
     {
-        m_cbDistortionWeight = (uint64_t)floor(256.0 * cbDistortionWeight);
+        m_cbDistortionWeight = cbDistortionWeight;
     }
 
-    void setCrDistortionWeight(double crDistortionWeight)
+    void setCrDistortionWeight(uint64_t crDistortionWeight)
     {
-        m_crDistortionWeight = (uint64_t)floor(256.0 * crDistortionWeight);
+        m_crDistortionWeight = crDistortionWeight;
     }
 
     void setPsyRdScale(double scale)


More information about the x265-devel mailing list