[x265] [PATCH] SAO: removed unnecessary copy of sao type and offsets in offset rdo calculation

ashok at multicorewareinc.com ashok at multicorewareinc.com
Mon Jan 18 16:51:10 CET 2016


# HG changeset patch
# User Ashok Kumar Mishra<ashok at multicorewareinc.com>
# Date 1453132257 -19800
#      Mon Jan 18 21:20:57 2016 +0530
# Node ID add820b8cde0fc82a643fd32717def5a3e2f3888
# Parent  e7768afed62fad78a193ea0d54137c4f5d8d2db3
SAO: removed unnecessary copy of sao type and offsets in offset rdo calculation

diff -r e7768afed62f -r add820b8cde0 source/encoder/entropy.cpp
--- a/source/encoder/entropy.cpp	Mon Jan 18 21:20:27 2016 +0530
+++ b/source/encoder/entropy.cpp	Mon Jan 18 21:20:57 2016 +0530
@@ -1026,6 +1026,44 @@
     }
 }
 
+void Entropy::codeSaoOffsetEO(int *offset, int typeIdx, int plane)
+{
+    if (plane != 2)
+    {
+        encodeBin(1, m_contextState[OFF_SAO_TYPE_IDX_CTX]);
+        encodeBinEP(1);
+    }
+
+    enum { OFFSET_THRESH = 1 << X265_MIN(X265_DEPTH - 5, 5) };
+
+    codeSaoMaxUvlc(offset[0], OFFSET_THRESH - 1);
+    codeSaoMaxUvlc(offset[1], OFFSET_THRESH - 1);
+    codeSaoMaxUvlc(-offset[2], OFFSET_THRESH - 1);
+    codeSaoMaxUvlc(-offset[3], OFFSET_THRESH - 1);
+    if (plane != 2)
+        encodeBinsEP((uint32_t)(typeIdx), 2);
+}
+
+void Entropy::codeSaoOffsetBO(int *offset, int bandPos, int plane)
+{
+    if (plane != 2)
+    {
+        encodeBin(1, m_contextState[OFF_SAO_TYPE_IDX_CTX]);
+        encodeBinEP(0);
+    }
+
+    enum { OFFSET_THRESH = 1 << X265_MIN(X265_DEPTH - 5, 5) };
+
+    for (int i = 0; i < SAO_BO_LEN; i++)
+        codeSaoMaxUvlc(abs(offset[i]), OFFSET_THRESH - 1);
+
+    for (int i = 0; i < SAO_BO_LEN; i++)
+        if (offset[i] != 0)
+            encodeBinEP(offset[i] < 0);
+
+    encodeBinsEP(bandPos, 5);
+}
+
 /** initialize context model with respect to QP and initialization value */
 uint8_t sbacInit(int qp, int initValue)
 {
diff -r e7768afed62f -r add820b8cde0 source/encoder/entropy.h
--- a/source/encoder/entropy.h	Mon Jan 18 21:20:27 2016 +0530
+++ b/source/encoder/entropy.h	Mon Jan 18 21:20:57 2016 +0530
@@ -169,6 +169,7 @@
     void codeCoeffNxN(const CUData& cu, const coeff_t* coef, uint32_t absPartIdx, uint32_t log2TrSize, TextType ttype);
 
     inline void codeSaoMerge(uint32_t code)                          { encodeBin(code, m_contextState[OFF_SAO_MERGE_FLAG_CTX]); }
+    inline void codeSaoType(uint32_t code)                           { encodeBin(code, m_contextState[OFF_SAO_TYPE_IDX_CTX]); }
     inline void codeMVPIdx(uint32_t symbol)                          { encodeBin(symbol, m_contextState[OFF_MVP_IDX_CTX]); }
     inline void codeMergeFlag(const CUData& cu, uint32_t absPartIdx) { encodeBin(cu.m_mergeFlag[absPartIdx], m_contextState[OFF_MERGE_FLAG_EXT_CTX]); }
     inline void codeSkipFlag(const CUData& cu, uint32_t absPartIdx)  { encodeBin(cu.isSkipped(absPartIdx), m_contextState[OFF_SKIP_FLAG_CTX + cu.getCtxSkipFlag(absPartIdx)]); }
@@ -182,6 +183,8 @@
     inline void codeTransformSkipFlags(uint32_t transformSkip, TextType ttype) { encodeBin(transformSkip, m_contextState[OFF_TRANSFORMSKIP_FLAG_CTX + (ttype ? NUM_TRANSFORMSKIP_FLAG_CTX : 0)]); }
     void codeDeltaQP(const CUData& cu, uint32_t absPartIdx);
     void codeSaoOffset(const SaoCtuParam& ctuParam, int plane);
+    void codeSaoOffsetEO(int *offset, int typeIdx, int plane);
+    void codeSaoOffsetBO(int *offset, int bandPos, int plane);
 
     /* RDO functions */
     void estBit(EstBitsSbac& estBitsSbac, uint32_t log2TrSize, bool bIsLuma) const;
diff -r e7768afed62f -r add820b8cde0 source/encoder/sao.cpp
--- a/source/encoder/sao.cpp	Mon Jan 18 21:20:27 2016 +0530
+++ b/source/encoder/sao.cpp	Mon Jan 18 21:20:57 2016 +0530
@@ -1598,17 +1598,17 @@
 void SAO::saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist)
 {
     int64_t bestDist = 0;
+    int bestTypeIdx = -1;
 
     SaoCtuParam* lclCtuParam = &saoParam->ctuParam[0][addr];
 
-    double bestRDCostTableBo = MAX_DOUBLE;
-    int    bestClassTableBo  = 0;
     int    currentDistortionTableBo[MAX_NUM_SAO_CLASS];
     double currentRdCostTableBo[MAX_NUM_SAO_CLASS];
 
     m_entropyCoder.load(m_rdContexts.temp);
     m_entropyCoder.resetBits();
-    m_entropyCoder.codeSaoOffset(*lclCtuParam, 0);
+    m_entropyCoder.codeSaoType(0);
+
     double dCostPartBest = m_entropyCoder.getNumberOfWrittenBits() * m_lumaLambda;
 
     //EO distortion calculation
@@ -1633,16 +1633,9 @@
             estDist += estSaoDist(count, (int)offsetOut << SAO_BIT_INC, offsetOrg);
         }
 
-        SaoCtuParam  ctuParamRdo;
-        ctuParamRdo.mergeMode = SAO_MERGE_NONE;
-        ctuParamRdo.typeIdx   = typeIdx;
-        ctuParamRdo.bandPos   = 0;
-        for (int classIdx = 0; classIdx < SAO_NUM_OFFSET; classIdx++)
-            ctuParamRdo.offset[classIdx] = (int)m_offset[0][typeIdx][classIdx + 1];
-
         m_entropyCoder.load(m_rdContexts.temp);
         m_entropyCoder.resetBits();
-        m_entropyCoder.codeSaoOffset(ctuParamRdo, 0);
+        m_entropyCoder.codeSaoOffsetEO(m_offset[0][typeIdx] + 1, typeIdx, 0);
 
         uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();
         double cost = (double)estDist + m_lumaLambda * (double)estRate;
@@ -1650,12 +1643,21 @@
         if (cost < dCostPartBest)
         {
             dCostPartBest = cost;
-            copySaoUnit(lclCtuParam, &ctuParamRdo);
             bestDist = estDist;
+            bestTypeIdx = typeIdx;
         }
     }
 
-    //BO distortion calculation
+    if (bestTypeIdx != -1)
+    {
+        lclCtuParam->mergeMode = SAO_MERGE_NONE;
+        lclCtuParam->typeIdx = bestTypeIdx;
+        lclCtuParam->bandPos = 0;
+        for (int classIdx = 0; classIdx < SAO_NUM_OFFSET; classIdx++)
+            lclCtuParam->offset[classIdx] = (int)m_offset[0][bestTypeIdx][classIdx + 1];
+    }
+
+    //BO RDO
     int64_t estDist = 0;
     for (int classIdx = 1; classIdx < SAO_NUM_BO_CLASSES + 1; classIdx++)
     {
@@ -1678,6 +1680,9 @@
     }
 
     // Estimate Best Position
+    double bestRDCostTableBo = MAX_DOUBLE;
+    int    bestClassTableBo  = 0;
+
     for (int i = 0; i < SAO_NUM_BO_CLASSES - SAO_BO_LEN + 1; i++)
     {
         double currentRDCost = 0.0;
@@ -1695,16 +1700,9 @@
     for (int classIdx = bestClassTableBo; classIdx < bestClassTableBo + SAO_BO_LEN; classIdx++)
         estDist += currentDistortionTableBo[classIdx];
 
-    SaoCtuParam  ctuParamRdo;
-    ctuParamRdo.mergeMode = SAO_MERGE_NONE;
-    ctuParamRdo.typeIdx = SAO_BO;
-    ctuParamRdo.bandPos = bestClassTableBo;
-    for (int classIdx = 0; classIdx < SAO_NUM_OFFSET; classIdx++)
-        ctuParamRdo.offset[classIdx] = (int)m_offset[0][SAO_BO][classIdx + ctuParamRdo.bandPos + 1];
-
     m_entropyCoder.load(m_rdContexts.temp);
     m_entropyCoder.resetBits();
-    m_entropyCoder.codeSaoOffset(ctuParamRdo, 0);
+    m_entropyCoder.codeSaoOffsetBO(m_offset[0][SAO_BO] + (bestClassTableBo + 1), bestClassTableBo, 0);
 
     uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();
     double cost = (double)estDist + m_lumaLambda * (double)estRate;
@@ -1712,8 +1710,13 @@
     if (cost < dCostPartBest)
     {
         dCostPartBest = cost;
-        copySaoUnit(lclCtuParam, &ctuParamRdo);
         bestDist = estDist;
+
+        lclCtuParam->mergeMode = SAO_MERGE_NONE;
+        lclCtuParam->typeIdx = SAO_BO;
+        lclCtuParam->bandPos = bestClassTableBo;
+        for (int classIdx = 0; classIdx < SAO_NUM_OFFSET; classIdx++)
+            lclCtuParam->offset[classIdx] = (int)m_offset[0][SAO_BO][classIdx + bestClassTableBo + 1];
     }
 
     mergeDist[0] = ((double)bestDist / m_lumaLambda);
@@ -1725,21 +1728,21 @@
 void SAO::saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist)
 {
     int64_t bestDist = 0;
+    int bestTypeIdx = -1;
 
     SaoCtuParam* lclCtuParam[2] = { &saoParam->ctuParam[1][addr], &saoParam->ctuParam[2][addr] };
 
     double currentRdCostTableBo[MAX_NUM_SAO_CLASS];
+    int    currentDistortionTableBo[MAX_NUM_SAO_CLASS];
     int    bestClassTableBo[2] = { 0, 0 };
-    int    currentDistortionTableBo[MAX_NUM_SAO_CLASS];
 
     m_entropyCoder.load(m_rdContexts.temp);
     m_entropyCoder.resetBits();
-    m_entropyCoder.codeSaoOffset(*lclCtuParam[0], 1);
-    m_entropyCoder.codeSaoOffset(*lclCtuParam[1], 2);
+    m_entropyCoder.codeSaoType(0);
 
     double costPartBest = m_entropyCoder.getNumberOfWrittenBits() * m_chromaLambda;
 
-    //EO distortion calculation
+    //EO RDO
     for (int typeIdx = 0; typeIdx < MAX_NUM_SAO_TYPE - 1; typeIdx++)
     {
         int64_t estDist[2] = {0, 0};
@@ -1760,24 +1763,17 @@
                     offsetOrg = 0;
                     offsetOut = 0;
                 }
-                if (typeIdx != SAO_BO)
-                    estDist[compIdx - 1] += estSaoDist(count, (int)offsetOut << SAO_BIT_INC, offsetOrg);
+
+                estDist[compIdx - 1] += estSaoDist(count, (int)offsetOut << SAO_BIT_INC, offsetOrg);
             }
         }
 
         m_entropyCoder.load(m_rdContexts.temp);
         m_entropyCoder.resetBits();
 
-        SaoCtuParam  ctuParamRdo[2];
         for (int compIdx = 0; compIdx < 2; compIdx++)
         {
-            ctuParamRdo[compIdx].mergeMode = SAO_MERGE_NONE;
-            ctuParamRdo[compIdx].typeIdx = typeIdx;
-            ctuParamRdo[compIdx].bandPos = 0;
-            for (int classIdx = 0; classIdx < SAO_NUM_OFFSET; classIdx++)
-                ctuParamRdo[compIdx].offset[classIdx] = (int)m_offset[compIdx + 1][typeIdx][classIdx + 1];
-
-            m_entropyCoder.codeSaoOffset(ctuParamRdo[compIdx], compIdx + 1);
+            m_entropyCoder.codeSaoOffsetEO(m_offset[compIdx + 1][typeIdx] + 1, typeIdx, compIdx + 1);
         }
 
         uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();
@@ -1786,13 +1782,24 @@
         if (cost < costPartBest)
         {
             costPartBest = cost;
-            copySaoUnit(lclCtuParam[0], &ctuParamRdo[0]);
-            copySaoUnit(lclCtuParam[1], &ctuParamRdo[1]);
             bestDist = (estDist[0] + estDist[1]);
+            bestTypeIdx = typeIdx;
         }
     }
 
-    // BO distortion calculation
+    if (bestTypeIdx != -1)
+    {
+        for (int compIdx = 0; compIdx < 2; compIdx++)
+        {
+            lclCtuParam[compIdx]->mergeMode = SAO_MERGE_NONE;
+            lclCtuParam[compIdx]->typeIdx = bestTypeIdx;
+            lclCtuParam[compIdx]->bandPos = 0;
+            for (int classIdx = 0; classIdx < SAO_NUM_OFFSET; classIdx++)
+                lclCtuParam[compIdx]->offset[classIdx] = (int)m_offset[compIdx + 1][bestTypeIdx][classIdx + 1];
+        }
+    }
+
+    // BO RDO
     int64_t estDist[2];
 
     // Estimate Best Position
@@ -1841,16 +1848,9 @@
     m_entropyCoder.load(m_rdContexts.temp);
     m_entropyCoder.resetBits();
 
-    SaoCtuParam  ctuParamRdo[2];
     for (int compIdx = 0; compIdx < 2; compIdx++)
     {
-        ctuParamRdo[compIdx].mergeMode = SAO_MERGE_NONE;
-        ctuParamRdo[compIdx].typeIdx = SAO_BO;
-        ctuParamRdo[compIdx].bandPos = bestClassTableBo[compIdx];
-        for (int classIdx = 0; classIdx < SAO_NUM_OFFSET; classIdx++)
-            ctuParamRdo[compIdx].offset[classIdx] = (int)m_offset[compIdx + 1][SAO_BO][classIdx + ctuParamRdo[compIdx].bandPos + 1];
-
-        m_entropyCoder.codeSaoOffset(ctuParamRdo[compIdx], compIdx + 1);
+        m_entropyCoder.codeSaoOffsetBO(m_offset[compIdx + 1][SAO_BO] + (bestClassTableBo[compIdx] + 1), bestClassTableBo[compIdx], compIdx + 1);
     }
 
     uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();
@@ -1859,9 +1859,16 @@
     if (cost < costPartBest)
     {
         costPartBest = cost;
-        copySaoUnit(lclCtuParam[0], &ctuParamRdo[0]);
-        copySaoUnit(lclCtuParam[1], &ctuParamRdo[1]);
         bestDist = (estDist[0] + estDist[1]);
+
+        for (int compIdx = 0; compIdx < 2; compIdx++)
+        {
+            lclCtuParam[compIdx]->mergeMode = SAO_MERGE_NONE;
+            lclCtuParam[compIdx]->typeIdx = SAO_BO;
+            lclCtuParam[compIdx]->bandPos = bestClassTableBo[compIdx];
+            for (int classIdx = 0; classIdx < SAO_NUM_OFFSET; classIdx++)
+                lclCtuParam[compIdx]->offset[classIdx] = (int)m_offset[compIdx + 1][SAO_BO][classIdx + bestClassTableBo[compIdx] + 1];
+        }
     }
 
     mergeDist[0] += ((double)bestDist / m_chromaLambda);
diff -r e7768afed62f -r add820b8cde0 source/encoder/sao.h
--- a/source/encoder/sao.h	Mon Jan 18 21:20:27 2016 +0530
+++ b/source/encoder/sao.h	Mon Jan 18 21:20:57 2016 +0530
@@ -150,7 +150,7 @@
     void rdoSaoUnitRow(SAOParam* saoParam, int idxY);
     void rdoSaoUnitCu(SAOParam* saoParam, int rowBaseAddr, int idxX, int addr);
 
-    void saoStatisticInitOffset(int plane);
+    void saoStatsInitialOffset(int plane);
 
     friend class FrameFilter;
 };


More information about the x265-devel mailing list