<div dir="ltr">Thanks - very nicely done!<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 8, 2015 at 5:24 AM, Min Chen <span dir="ltr"><<a href="mailto:chenm003@163.com" target="_blank">chenm003@163.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Min Chen <<a href="mailto:chenm003@163.com">chenm003@163.com</a>><br>
# Date 1449511560 21600<br>
# Node ID c68eec7fb242748363ec985937b20ed1aff73f02<br>
# Parent  3542d3abd018491d6ad67a79b0e6d05b604d3818<br>
move SAO into class ParallelFilter and modify it to row based<br>
---<br>
 source/common/common.h          |    1 +<br>
 source/encoder/frameencoder.cpp |   36 +++++++-------<br>
 source/encoder/framefilter.cpp  |   95 +++++++++++++++++++++++++-------------<br>
 source/encoder/framefilter.h    |   14 +++---<br>
 source/encoder/sao.cpp          |   81 ++++++++++++++++++++++++---------<br>
 source/encoder/sao.h            |    7 ++-<br>
 6 files changed, 151 insertions(+), 83 deletions(-)<br>
<br>
diff -r 3542d3abd018 -r c68eec7fb242 source/common/common.h<br>
--- a/source/common/common.h    Mon Dec 07 12:05:57 2015 -0600<br>
+++ b/source/common/common.h    Mon Dec 07 12:06:00 2015 -0600<br>
@@ -215,6 +215,7 @@<br>
<br>
 #define X265_MALLOC(type, count)    (type*)x265_malloc(sizeof(type) * (count))<br>
 #define X265_FREE(ptr)              x265_free(ptr)<br>
+#define X265_FREE_ZERO(ptr)         x265_free(ptr); (ptr) = NULL<br>
 #define CHECKED_MALLOC(var, type, count) \<br>
     { \<br>
         var = (type*)x265_malloc(sizeof(type) * (count)); \<br>
diff -r 3542d3abd018 -r c68eec7fb242 source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp   Mon Dec 07 12:05:57 2015 -0600<br>
+++ b/source/encoder/frameencoder.cpp   Mon Dec 07 12:06:00 2015 -0600<br>
@@ -1093,7 +1093,7 @@<br>
<br>
         /* SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas */<br>
         if (m_param->bEnableSAO && m_param->bSaoNonDeblocked)<br>
-            m_frameFilter.m_sao.calcSaoStatsCu_BeforeDblk(m_frame, col, row);<br>
+            m_frameFilter.m_parallelFilter[row].m_sao.calcSaoStatsCu_BeforeDblk(m_frame, col, row);<br>
<br>
         /* Deblock with idle threading */<br>
         if (m_param->bEnableLoopFilter)<br>
@@ -1103,24 +1103,24 @@<br>
             if (row > 0)<br>
             {<br>
                 // Waitting last threading finish<br>
-                m_frameFilter.m_pdeblock[row - 1].waitForExit();<br>
+                m_frameFilter.m_parallelFilter[row - 1].waitForExit();<br>
<br>
                 // Processing new group<br>
-                const int allowCol = ((row >= 2) ? X265_MIN(m_frameFilter.m_pdeblock[row - 2].m_lastCol.get(), (int)col) : col);<br>
-                m_frameFilter.m_pdeblock[row - 1].m_allowedCol.set(allowCol);<br>
-                m_frameFilter.m_pdeblock[row - 1].tryBondPeers(*this, 1);<br>
+                const int allowCol = ((row >= 2) ? X265_MIN(m_frameFilter.m_parallelFilter[row - 2].m_lastCol.get(), (int)col) : col);<br>
+                m_frameFilter.m_parallelFilter[row - 1].m_allowedCol.set(allowCol);<br>
+                m_frameFilter.m_parallelFilter[row - 1].tryBondPeers(*this, 1);<br>
             }<br>
<br>
             // Last Row may start early<br>
             if (row == m_numRows - 1)<br>
             {<br>
                 // Waitting last threading finish<br>
-                m_frameFilter.m_pdeblock[row].waitForExit();<br>
+                m_frameFilter.m_parallelFilter[row].waitForExit();<br>
<br>
                 // Processing last row<br>
-                const int allowCol = ((row >= 2) ? X265_MIN(m_frameFilter.m_pdeblock[row - 1].m_lastCol.get(), (int)col) : col);<br>
-                m_frameFilter.m_pdeblock[row].m_allowedCol.set(allowCol);<br>
-                m_frameFilter.m_pdeblock[row].tryBondPeers(*this, 1);<br>
+                const int allowCol = ((row >= 2) ? X265_MIN(m_frameFilter.m_parallelFilter[row - 1].m_lastCol.get(), (int)col) : col);<br>
+                m_frameFilter.m_parallelFilter[row].m_allowedCol.set(allowCol);<br>
+                m_frameFilter.m_parallelFilter[row].tryBondPeers(*this, 1);<br>
             }<br>
         }<br>
<br>
@@ -1188,17 +1188,17 @@<br>
         if (m_param->bEnableLoopFilter & (row > 0))<br>
         {<br>
             /* TODO: Multiple Threading */<br>
-            m_frameFilter.m_pdeblock[row - 1].waitForExit();<br>
+            m_frameFilter.m_parallelFilter[row - 1].waitForExit();<br>
<br>
             /* Check to avoid previous row process slower than current row */<br>
             if (row >= 2)<br>
             {<br>
-                int prevCol = m_frameFilter.m_pdeblock[row - 2].m_lastCol.get();<br>
+                int prevCol = m_frameFilter.m_parallelFilter[row - 2].m_lastCol.get();<br>
                 while(prevCol != (int)numCols)<br>
-                    prevCol = m_frameFilter.m_pdeblock[row - 2].m_lastCol.waitForChange(prevCol);<br>
+                    prevCol = m_frameFilter.m_parallelFilter[row - 2].m_lastCol.waitForChange(prevCol);<br>
             }<br>
-            m_frameFilter.m_pdeblock[row - 1].m_allowedCol.set(numCols);<br>
-            m_frameFilter.m_pdeblock[row - 1].processTasks(-1);<br>
+            m_frameFilter.m_parallelFilter[row - 1].m_allowedCol.set(numCols);<br>
+            m_frameFilter.m_parallelFilter[row - 1].processTasks(-1);<br>
         }<br>
<br>
         /* trigger row-wise loop filters */<br>
@@ -1217,12 +1217,12 @@<br>
             /* TODO: Early start last row */<br>
             if (m_param->bEnableLoopFilter)<br>
             {<br>
-                X265_CHECK(m_frameFilter.m_pdeblock[row - 1].m_allowedCol.get() == (int)numCols, "Deblock m_EncodedCol check failed");<br>
+                X265_CHECK(m_frameFilter.m_parallelFilter[row - 1].m_allowedCol.get() == (int)numCols, "Deblock m_EncodedCol check failed");<br>
<br>
                 /* NOTE: Last Row not execute before, so didn't need wait */<br>
-                m_frameFilter.m_pdeblock[row].waitForExit();<br>
-                m_frameFilter.m_pdeblock[row].m_allowedCol.set(numCols);<br>
-                m_frameFilter.m_pdeblock[row].processTasks(-1);<br>
+                m_frameFilter.m_parallelFilter[row].waitForExit();<br>
+                m_frameFilter.m_parallelFilter[row].m_allowedCol.set(numCols);<br>
+                m_frameFilter.m_parallelFilter[row].processTasks(-1);<br>
             }<br>
<br>
             for (uint32_t i = m_numRows - m_filterRowDelay; i < m_numRows; i++)<br>
diff -r 3542d3abd018 -r c68eec7fb242 source/encoder/framefilter.cpp<br>
--- a/source/encoder/framefilter.cpp    Mon Dec 07 12:05:57 2015 -0600<br>
+++ b/source/encoder/framefilter.cpp    Mon Dec 07 12:06:00 2015 -0600<br>
@@ -35,19 +35,22 @@<br>
 static uint64_t computeSSD(pixel *fenc, pixel *rec, intptr_t stride, uint32_t width, uint32_t height);<br>
 static float calculateSSIM(pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2, uint32_t width, uint32_t height, void *buf, uint32_t& cnt);<br>
<br>
-uint32_t FrameFilter::ParallelDeblock::numCols = 0;<br>
+uint32_t FrameFilter::ParallelFilter::numCols = 0;<br>
<br>
 void FrameFilter::destroy()<br>
 {<br>
-    if (m_param->bEnableSAO)<br>
-        m_sao.destroy();<br>
-<br>
     X265_FREE(m_ssimBuf);<br>
<br>
-    if (m_pdeblock)<br>
+    if (m_parallelFilter)<br>
     {<br>
-        delete[] m_pdeblock;<br>
-        m_pdeblock = NULL;<br>
+        if (m_param->bEnableSAO)<br>
+        {<br>
+            for(int row = 0; row < m_numRows; row++)<br>
+                m_parallelFilter[row].m_sao.destroy((row == 0 ? 1 : 0));<br>
+        }<br>
+<br>
+        delete[] m_parallelFilter;<br>
+        m_parallelFilter = NULL;<br>
     }<br>
 }<br>
<br>
@@ -63,50 +66,65 @@<br>
     m_saoRowDelay = m_param->bEnableLoopFilter ? 1 : 0;<br>
     m_lastHeight = m_param->sourceHeight % g_maxCUSize ? m_param->sourceHeight % g_maxCUSize : g_maxCUSize;<br>
<br>
-    if (m_param->bEnableSAO)<br>
-        if (!m_sao.create(m_param))<br>
-            m_param->bEnableSAO = 0;<br>
-<br>
     if (m_param->bEnableSsim)<br>
         m_ssimBuf = X265_MALLOC(int, 8 * (m_param->sourceWidth / 4 + 3));<br>
<br>
     if (m_param->bEnableLoopFilter)<br>
-        m_pdeblock = new ParallelDeblock[numRows];<br>
+        m_parallelFilter = new ParallelFilter[numRows];<br>
<br>
-    if (m_pdeblock)<br>
+    if (m_parallelFilter)<br>
     {<br>
+        if (m_param->bEnableSAO)<br>
+        {<br>
+            for(int row = 0; row < numRows; row++)<br>
+            {<br>
+                if (!m_parallelFilter[row].m_sao.create(m_param, (row == 0 ? 1 : 0)))<br>
+                    m_param->bEnableSAO = 0;<br>
+                else<br>
+                {<br>
+                    if (row != 0)<br>
+                        m_parallelFilter[row].m_sao.createFromRootNode(&m_parallelFilter[0].m_sao);<br>
+                }<br>
+<br>
+            }<br>
+        }<br>
+<br>
         for(int row = 0; row < numRows; row++)<br>
         {<br>
-            m_pdeblock[row].m_rowAddr = row * numCols;<br>
-            m_pdeblock[row].m_frameEncoder = m_frameEncoder;<br>
+            m_parallelFilter[row].m_rowAddr = row * numCols;<br>
+            m_parallelFilter[row].m_frameEncoder = m_frameEncoder;<br>
         }<br>
     }<br>
<br>
     // Setting maximum columns<br>
-    ParallelDeblock::numCols = numCols;<br>
+    ParallelFilter::numCols = numCols;<br>
 }<br>
<br>
 void FrameFilter::start(Frame *frame, Entropy& initState, int qp)<br>
 {<br>
     m_frame = frame;<br>
<br>
-    if (m_param->bEnableSAO)<br>
-        m_sao.startSlice(frame, initState, qp);<br>
-<br>
-    // Reset Deblock Data Struct<br>
-    if (m_pdeblock)<br>
+    // Reset Filter Data Struct<br>
+    if (m_parallelFilter)<br>
     {<br>
         for(int row = 0; row < m_numRows; row++)<br>
         {<br>
-            m_pdeblock[row].m_lastCol.set(0);<br>
-            m_pdeblock[row].m_allowedCol.set(0);<br>
-            m_pdeblock[row].m_encData = frame->m_encData;<br>
+            if (m_param->bEnableSAO)<br>
+                m_parallelFilter[row].m_sao.startSlice(frame, initState, qp);<br>
+<br>
+            m_parallelFilter[row].m_lastCol.set(0);<br>
+            m_parallelFilter[row].m_allowedCol.set(0);<br>
+            m_parallelFilter[row].m_encData = frame->m_encData;<br>
         }<br>
+<br>
+        // Reset SAO global/common statistics<br>
+        if (m_param->bEnableSAO)<br>
+            m_parallelFilter[0].m_sao.resetStats();<br>
     }<br>
 }<br>
<br>
 // NOTE: Single Threading only<br>
-void FrameFilter::ParallelDeblock::processTasks(int /*workerThreadId*/)<br>
+void FrameFilter::ParallelFilter::processTasks(int /*workerThreadId*/)<br>
 {<br>
     const CUGeom* cuGeoms = m_frameEncoder->m_cuGeoms;<br>
     const uint32_t* ctuGeomMap = m_frameEncoder->m_ctuGeomMap;<br>
@@ -160,11 +178,11 @@<br>
     SAOParam* saoParam = encData.m_saoParam;<br>
     if (m_param->bEnableSAO)<br>
     {<br>
-        m_sao.m_entropyCoder.load(m_frameEncoder->m_initSliceContext);<br>
-        m_sao.m_rdContexts.next.load(m_frameEncoder->m_initSliceContext);<br>
-        m_sao.m_rdContexts.cur.load(m_frameEncoder->m_initSliceContext);<br>
+        m_parallelFilter[row].m_sao.m_entropyCoder.load(m_frameEncoder->m_initSliceContext);<br>
+        m_parallelFilter[row].m_sao.m_rdContexts.next.load(m_frameEncoder->m_initSliceContext);<br>
+        m_parallelFilter[row].m_sao.m_rdContexts.cur.load(m_frameEncoder->m_initSliceContext);<br>
<br>
-        m_sao.rdoSaoUnitRow(saoParam, row);<br>
+        m_parallelFilter[row].m_sao.rdoSaoUnitRow(saoParam, row);<br>
<br>
         // NOTE: Delay a row because SAO decide need top row pixels at next row, is it HM's bug?<br>
         if (row >= m_saoRowDelay)<br>
@@ -180,7 +198,7 @@<br>
     {<br>
         if (m_param->bEnableSAO)<br>
         {<br>
-            m_sao.rdoSaoUnitRowEnd(saoParam, encData.m_slice->m_sps->numCUsInFrame);<br>
+            m_parallelFilter[row].m_sao.rdoSaoUnitRowEnd(saoParam, encData.m_slice->m_sps->numCUsInFrame);<br>
<br>
             for (int i = m_numRows - m_saoRowDelay; i < m_numRows; i++)<br>
                 processSao(i);<br>
@@ -489,12 +507,23 @@<br>
     SAOParam* saoParam = encData.m_saoParam;<br>
<br>
     if (saoParam->bSaoFlag[0])<br>
-        m_sao.processSaoUnitRow(saoParam->ctuParam[0], row, 0);<br>
+    {<br>
+        m_parallelFilter[row].m_sao.processSaoUnitRow(saoParam->ctuParam[0], row, 0);<br>
+        if (row != m_numRows - 1)<br>
+        {<br>
+            memcpy(m_parallelFilter[row + 1].m_sao.m_tmpU1[0], m_parallelFilter[row].m_sao.m_tmpU1[0], sizeof(pixel) * m_param->sourceWidth);<br>
+        }<br>
+    }<br>
<br>
     if (saoParam->bSaoFlag[1])<br>
     {<br>
-        m_sao.processSaoUnitRow(saoParam->ctuParam[1], row, 1);<br>
-        m_sao.processSaoUnitRow(saoParam->ctuParam[2], row, 2);<br>
+        m_parallelFilter[row].m_sao.processSaoUnitRow(saoParam->ctuParam[1], row, 1);<br>
+        m_parallelFilter[row].m_sao.processSaoUnitRow(saoParam->ctuParam[2], row, 2);<br>
+        if (row != m_numRows - 1)<br>
+        {<br>
+            memcpy(m_parallelFilter[row + 1].m_sao.m_tmpU1[1], m_parallelFilter[row].m_sao.m_tmpU1[1], sizeof(pixel) * m_param->sourceWidth);<br>
+            memcpy(m_parallelFilter[row + 1].m_sao.m_tmpU1[2], m_parallelFilter[row].m_sao.m_tmpU1[2], sizeof(pixel) * m_param->sourceWidth);<br>
+        }<br>
     }<br>
<br>
     if (encData.m_slice->m_pps->bTransquantBypassEnabled)<br>
diff -r 3542d3abd018 -r c68eec7fb242 source/encoder/framefilter.h<br>
--- a/source/encoder/framefilter.h      Mon Dec 07 12:05:57 2015 -0600<br>
+++ b/source/encoder/framefilter.h      Mon Dec 07 12:06:00 2015 -0600<br>
@@ -51,7 +51,6 @@<br>
     int           m_vChromaShift;<br>
     int           m_pad[2];<br>
<br>
-    SAO           m_sao;<br>
     int           m_numRows;<br>
     int           m_saoRowDelay;<br>
     int           m_lastHeight;<br>
@@ -59,41 +58,42 @@<br>
     void*         m_ssimBuf; /* Temp storage for ssim computation */<br>
<br>
 #define MAX_PFILTER_CUS     (4) /* maximum CUs for every thread */<br>
-    class ParallelDeblock : public BondedTaskGroup, public Deblock<br>
+    class ParallelFilter : public BondedTaskGroup, public Deblock<br>
     {<br>
     public:<br>
         static uint32_t     numCols;<br>
         uint32_t            m_rowAddr;<br>
         FrameEncoder*       m_frameEncoder;<br>
         FrameData*          m_encData;<br>
+        SAO                 m_sao;<br>
         ThreadSafeInteger   m_lastCol;          /* The column that next to process */<br>
         ThreadSafeInteger   m_allowedCol;       /* The column that processed from Encode pipeline */<br>
<br>
-        ParallelDeblock()<br>
+        ParallelFilter()<br>
             : m_rowAddr(0)<br>
             , m_frameEncoder(NULL)<br>
             , m_encData(NULL)<br>
         {<br>
         }<br>
<br>
-        ~ParallelDeblock()<br>
+        ~ParallelFilter()<br>
         { }<br>
<br>
         void processTasks(int workerThreadId);<br>
<br>
     protected:<br>
<br>
-        ParallelDeblock operator=(const ParallelDeblock&);<br>
+        ParallelFilter operator=(const ParallelFilter&);<br>
     };<br>
<br>
-    ParallelDeblock*    m_pdeblock;<br>
+    ParallelFilter*     m_parallelFilter;<br>
<br>
     FrameFilter()<br>
         : m_param(NULL)<br>
         , m_frame(NULL)<br>
         , m_frameEncoder(NULL)<br>
         , m_ssimBuf(NULL)<br>
-        , m_pdeblock(NULL)<br>
+        , m_parallelFilter(NULL)<br>
     {<br>
     }<br>
<br>
diff -r 3542d3abd018 -r c68eec7fb242 source/encoder/sao.cpp<br>
--- a/source/encoder/sao.cpp    Mon Dec 07 12:05:57 2015 -0600<br>
+++ b/source/encoder/sao.cpp    Mon Dec 07 12:06:00 2015 -0600<br>
@@ -103,7 +103,7 @@<br>
     m_depthSaoRate[1][3] = 0;<br>
 }<br>
<br>
-bool SAO::create(x265_param* param)<br>
+bool SAO::create(x265_param* param, int initCommon)<br>
 {<br>
     m_param = param;<br>
     m_chromaFormat = param->internalCsp;<br>
@@ -131,12 +131,24 @@<br>
         m_tmpU2[i] += 1;<br>
     }<br>
<br>
-    CHECKED_MALLOC(m_count, PerClass, NUM_PLANE);<br>
-    CHECKED_MALLOC(m_offset, PerClass, NUM_PLANE);<br>
-    CHECKED_MALLOC(m_offsetOrg, PerClass, NUM_PLANE);<br>
+    if (initCommon)<br>
+    {<br>
+        CHECKED_MALLOC(m_count, PerClass, NUM_PLANE);<br>
+        CHECKED_MALLOC(m_offset, PerClass, NUM_PLANE);<br>
+        CHECKED_MALLOC(m_offsetOrg, PerClass, NUM_PLANE);<br>
<br>
-    CHECKED_MALLOC(m_countPreDblk, PerPlane, numCtu);<br>
-    CHECKED_MALLOC(m_offsetOrgPreDblk, PerPlane, numCtu);<br>
+        CHECKED_MALLOC(m_countPreDblk, PerPlane, numCtu);<br>
+        CHECKED_MALLOC(m_offsetOrgPreDblk, PerPlane, numCtu);<br>
+    }<br>
+    else<br>
+    {<br>
+        // must initialize these common pointer outside of function<br>
+        m_count = NULL;<br>
+        m_offset = NULL;<br>
+        m_offsetOrg = NULL;<br>
+        m_countPreDblk = NULL;<br>
+        m_offsetOrgPreDblk = NULL;<br>
+    }<br>
<br>
     m_clipTable = &(m_clipTableBase[rangeExt]);<br>
<br>
@@ -155,24 +167,50 @@<br>
     return false;<br>
 }<br>
<br>
-void SAO::destroy()<br>
+void SAO::createFromRootNode(SAO* root)<br>
 {<br>
-    X265_FREE(m_clipTableBase);<br>
+    X265_CHECK(m_count == NULL, "duplicate initialize on m_count");<br>
+    X265_CHECK(m_offset == NULL, "duplicate initialize on m_offset");<br>
+    X265_CHECK(m_offsetOrg == NULL, "duplicate initialize on m_offsetOrg");<br>
+    X265_CHECK(m_countPreDblk == NULL, "duplicate initialize on m_countPreDblk");<br>
+    X265_CHECK(m_offsetOrgPreDblk == NULL, "duplicate initialize on m_offsetOrgPreDblk");<br>
<br>
-    X265_FREE(m_tmpL1);<br>
-    X265_FREE(m_tmpL2);<br>
+    m_count = root->m_count;<br>
+    m_offset = root->m_offset;<br>
+    m_offsetOrg = root->m_offsetOrg;<br>
+    m_countPreDblk = root->m_countPreDblk;<br>
+    m_offsetOrgPreDblk = root->m_offsetOrgPreDblk;<br>
+}<br>
+<br>
+void SAO::destroy(int destoryCommon)<br>
+{<br>
+    X265_FREE_ZERO(m_clipTableBase);<br>
+<br>
+    X265_FREE_ZERO(m_tmpL1);<br>
+    X265_FREE_ZERO(m_tmpL2);<br>
<br>
     for (int i = 0; i < 3; i++)<br>
     {<br>
-        if (m_tmpU1[i]) X265_FREE(m_tmpU1[i] - 1);<br>
-        if (m_tmpU2[i]) X265_FREE(m_tmpU2[i] - 1);<br>
+        if (m_tmpU1[i])<br>
+        {<br>
+            X265_FREE(m_tmpU1[i] - 1);<br>
+            m_tmpU1[i] = NULL;<br>
+        }<br>
+        if (m_tmpU2[i])<br>
+        {<br>
+            X265_FREE(m_tmpU2[i] - 1);<br>
+            m_tmpU2[i] = NULL;<br>
+        }<br>
     }<br>
<br>
-    X265_FREE(m_count);<br>
-    X265_FREE(m_offset);<br>
-    X265_FREE(m_offsetOrg);<br>
-    X265_FREE(m_countPreDblk);<br>
-    X265_FREE(m_offsetOrgPreDblk);<br>
+    if (destoryCommon)<br>
+    {<br>
+        X265_FREE(m_count);<br>
+        X265_FREE(m_offset);<br>
+        X265_FREE(m_offsetOrg);<br>
+        X265_FREE(m_countPreDblk);<br>
+        X265_FREE(m_offsetOrgPreDblk);<br>
+    }<br>
 }<br>
<br>
 /* allocate memory for SAO parameters */<br>
@@ -210,8 +248,6 @@<br>
         break;<br>
     }<br>
<br>
-    resetStats();<br>
-<br>
     m_entropyCoder.load(initState);<br>
     m_rdContexts.next.load(initState);<br>
     m_rdContexts.cur.load(initState);<br>
@@ -586,15 +622,14 @@<br>
         ctuHeight >>= m_vChromaShift;<br>
     }<br>
<br>
+    int addr = idxY * m_numCuInWidth;<br>
+    pixel* rec = reconPic->getPlaneAddr(plane, addr);<br>
+<br>
     if (!idxY)<br>
     {<br>
-        pixel* rec = reconPic->m_picOrg[plane];<br>
         memcpy(m_tmpU1[plane], rec, sizeof(pixel) * picWidth);<br>
     }<br>
<br>
-    int addr = idxY * m_numCuInWidth;<br>
-    pixel* rec = plane ? reconPic->getChromaAddr(plane, addr) : reconPic->getLumaAddr(addr);<br>
-<br>
     for (int i = 0; i < ctuHeight + 1; i++)<br>
     {<br>
         m_tmpL1[i] = rec[0];<br>
diff -r 3542d3abd018 -r c68eec7fb242 source/encoder/sao.h<br>
--- a/source/encoder/sao.h      Mon Dec 07 12:05:57 2015 -0600<br>
+++ b/source/encoder/sao.h      Mon Dec 07 12:06:00 2015 -0600<br>
@@ -120,8 +120,9 @@<br>
<br>
     SAO();<br>
<br>
-    bool create(x265_param* param);<br>
-    void destroy();<br>
+    bool create(x265_param* param, int initCommon);<br>
+    void createFromRootNode(SAO *root);<br>
+    void destroy(int destoryCommon);<br>
<br>
     void allocSaoParam(SAOParam* saoParam) const;<br>
<br>
@@ -147,6 +148,8 @@<br>
<br>
     void rdoSaoUnitRowEnd(const SAOParam* saoParam, int numctus);<br>
     void rdoSaoUnitRow(SAOParam* saoParam, int idxY);<br>
+<br>
+    friend class FrameFilter;<br>
 };<br>
<br>
 }<br>
<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature"><div dir="ltr"><div><div>Deepthi Nandakumar<br></div>Engineering Manager, x265<br></div>Multicoreware, Inc<br></div></div>
</div>