[x265] [PATCH] SAO: consider chroma distortion when chroma sao is disabled

ashok at multicorewareinc.com ashok at multicorewareinc.com
Wed May 4 16:09:05 CEST 2016


# HG changeset patch
# User Ashok Kumar Mishra<ashok at multicorewareinc.com>
# Date 1461571794 -19800
#      Mon Apr 25 13:39:54 2016 +0530
# Node ID 9f27620a948b67498056246b97db72bebac99218
# Parent  00ea3784bd36c164c5f799c998d7a09f2cb244bf
SAO: consider chroma distortion when chroma sao is disabled
It is a valid modification which I missed in my last patch.
Note that output may change where chroma sao is disabled.

diff -r 00ea3784bd36 -r 9f27620a948b source/encoder/sao.cpp
--- a/source/encoder/sao.cpp	Thu Apr 28 09:59:30 2016 +0200
+++ b/source/encoder/sao.cpp	Mon Apr 25 13:39:54 2016 +0530
@@ -1238,7 +1238,7 @@
         calcSaoStatsCu(addr, 2);
     }
 
-    saoStatsInitialOffset(chroma);
+    saoStatsInitialOffset(planes);
 
     // SAO distortion calculation
     m_entropyCoder.load(m_rdContexts.cur);
@@ -1249,13 +1249,13 @@
         m_entropyCoder.codeSaoMerge(0);
     m_entropyCoder.store(m_rdContexts.temp);
 
-    double mergeDist[NUM_MERGE_MODE] = { 0.0 };
+    // Estimate distortion and cost of new SAO params
     double bestCost = 0.0;
-
+    double rateDist = 0.0;
     // Estimate distortion and cost of new SAO params
-    saoLumaComponentParamDist(saoParam, addr, mergeDist, lambda, bestCost);
-    if (chroma && saoParam->bSaoFlag[1])
-        saoChromaComponentParamDist(saoParam, addr, mergeDist, lambda, bestCost);
+    saoLumaComponentParamDist(saoParam, addr, rateDist, lambda, bestCost);
+    if (chroma)
+        saoChromaComponentParamDist(saoParam, addr, rateDist, lambda, bestCost);
 
     if (saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1])
     {
@@ -1265,7 +1265,8 @@
             if (!allowMerge[mergeIdx])
                 continue;
 
-            for (int plane = 0; plane < 3; plane++)
+            double mergeDist = 0; 
+            for (int plane = 0; plane < planes; plane++)
             {
                 int64_t estDist = 0;
                 SaoCtuParam* mergeSrcParam = &(saoParam->ctuParam[plane][addrMerge[mergeIdx]]);
@@ -1279,8 +1280,7 @@
                         estDist += estSaoDist(m_count[plane][typeIdx][classIdx + bandPos], mergeOffset, m_offsetOrg[plane][typeIdx][classIdx + bandPos]);
                     }
                 }
-
-                mergeDist[mergeIdx + 1] += ((double)estDist / lambda[!!plane]);
+                mergeDist += ((double)estDist / lambda[!!plane]);
             }
 
             m_entropyCoder.load(m_rdContexts.cur);
@@ -1290,8 +1290,8 @@
             if (allowMerge[1] && (mergeIdx == 1))
                 m_entropyCoder.codeSaoMerge(1);
 
-            int32_t rate = m_entropyCoder.getNumberOfWrittenBits();
-            double mergeCost = mergeDist[mergeIdx + 1] + (double)rate;
+            int32_t estRate = m_entropyCoder.getNumberOfWrittenBits();
+            double mergeCost = mergeDist + (double)estRate;
             if (mergeCost < bestCost)
             {
                 SaoMergeMode mergeMode = mergeIdx ? SAO_MERGE_UP : SAO_MERGE_LEFT;
@@ -1326,9 +1326,8 @@
 
 // Rounds the division of initial offsets by the number of samples in
 // each of the statistics table entries.
-void SAO::saoStatsInitialOffset(bool chroma)
+void SAO::saoStatsInitialOffset(int planes)
 {
-    int planes = chroma ? 3 : 1;
     memset(m_offset, 0, sizeof(m_offset));
 
     // EO
@@ -1405,7 +1404,7 @@
     offset = bestOffset;
 }
 
-void SAO::saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda, double &bestCost)
+void SAO::saoLumaComponentParamDist(SAOParam* saoParam, int addr, double& rateDist, double* lambda, double &bestCost)
 {
     int64_t bestDist = 0;
     int bestTypeIdx = -1;
@@ -1513,16 +1512,19 @@
             lclCtuParam->offset[classIdx] = (int)m_offset[0][SAO_BO][classIdx + bestClassBO];
     }
 
-    mergeDist[0] = ((double)bestDist / lambda[0]);
+    rateDist = ((double)bestDist / lambda[0]);
     m_entropyCoder.load(m_rdContexts.temp);
     m_entropyCoder.codeSaoOffset(*lclCtuParam, 0);
     m_entropyCoder.store(m_rdContexts.temp);
 
-    uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
-    bestCost = mergeDist[0] + (double)rate;
+    if (m_param->internalCsp == X265_CSP_I400)
+    {
+        uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
+        bestCost = rateDist + (double)rate;
+    }
 }
 
-void SAO::saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda, double &bestCost)
+void SAO::saoChromaComponentParamDist(SAOParam* saoParam, int addr, double& rateDist, double* lambda, double &bestCost)
 {
     int64_t bestDist = 0;
     int bestTypeIdx = -1;
@@ -1645,15 +1647,23 @@
         }
     }
 
-    mergeDist[0] += ((double)bestDist / lambda[1]);
+    rateDist += ((double)bestDist / lambda[1]);
     m_entropyCoder.load(m_rdContexts.temp);
 
-    m_entropyCoder.codeSaoOffset(*lclCtuParam[0], 1);
-    m_entropyCoder.codeSaoOffset(*lclCtuParam[1], 2);
-    m_entropyCoder.store(m_rdContexts.temp);
+    if (saoParam->bSaoFlag[1])
+    {
+        m_entropyCoder.codeSaoOffset(*lclCtuParam[0], 1);
+        m_entropyCoder.codeSaoOffset(*lclCtuParam[1], 2);
+        m_entropyCoder.store(m_rdContexts.temp);
 
-    uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
-    bestCost = mergeDist[0] + (double)rate;
+        uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
+        bestCost = rateDist + (double)rate;
+    }
+    else
+    {
+        uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
+        bestCost = rateDist + (double)rate;
+    }
 }
 
 // NOTE: must put in namespace X265_NS since we need class SAO
diff -r 00ea3784bd36 -r 9f27620a948b source/encoder/sao.h
--- a/source/encoder/sao.h	Thu Apr 28 09:59:30 2016 +0200
+++ b/source/encoder/sao.h	Mon Apr 25 13:39:54 2016 +0530
@@ -54,7 +54,6 @@
     enum { OFFSET_THRESH = 1 << X265_MIN(X265_DEPTH - 5, 5) };
     enum { NUM_EDGETYPE = 5 };
     enum { NUM_PLANE = 3 };
-    enum { NUM_MERGE_MODE = 3 };
     enum { SAO_DEPTHRATE_SIZE = 4 };
 
     static const uint32_t s_eoTable[NUM_EDGETYPE];
@@ -127,14 +126,14 @@
     void calcSaoStatsCu(int addr, int plane);
     void calcSaoStatsCu_BeforeDblk(Frame* pic, int idxX, int idxY);
 
-    void saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda, double &bestCost);
-    void saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda, double &bestCost);
+    void saoLumaComponentParamDist(SAOParam* saoParam, int addr, double& rateDist, double* lambda, double &bestCost);
+    void saoChromaComponentParamDist(SAOParam* saoParam, int addr, double& rateDist, double* lambda, double &bestCost);
 
     void estIterOffset(int typeIdx, double lambda, int32_t count, int32_t offsetOrg, int& offset, int& distClasses, double& costClasses);
     void rdoSaoUnitRowEnd(const SAOParam* saoParam, int numctus);
     void rdoSaoUnitCu(SAOParam* saoParam, int rowBaseAddr, int idxX, int addr);
 
-    void saoStatsInitialOffset(bool chroma);
+    void saoStatsInitialOffset(int planes);
 
     friend class FrameFilter;
 };


More information about the x265-devel mailing list