<div dir="ltr">Please ignore this patch, I will resend it with some changes. </div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><br>Thanks,<br><br>Bhavna Hariharan<br></div></div></div></div></div></div></div>
<br><div class="gmail_quote">On Tue, May 22, 2018 at 2:14 PM,  <span dir="ltr"><<a href="mailto:bhavna@multicorewareinc.com" target="_blank">bhavna@multicorewareinc.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 Bhavna Hariharan <<a href="mailto:bhavna@multicorewareinc.com">bhavna@multicorewareinc.com</a>><br>
# Date 1526964471 -19800<br>
#      Tue May 22 10:17:51 2018 +0530<br>
# Node ID 5587d9a25248075edadf94e1a78f6e<wbr>11d091f651<br>
# Parent  cc2c5e46f3c87d27e3602af30b06ba<wbr>6a0fbe2704<br>
Clean up dynamic refinement<br>
<br>
This patch does the following:<br>
1) Earlier, locks were used to avoid the possibility of race conditions while<br>
copying data from CTU level to frame level. Now, the data is collected for each<br>
row and when the entire frame completes analysis the row data is copied to the<br>
frame. This method eliminates the possibility of a race condition without<br>
having to employ locks.<br>
2) Allocate memory for the CTU infromation from the data pool, this will avoid<br>
fragmentation of data.<br>
<br>
diff -r cc2c5e46f3c8 -r 5587d9a25248 source/common/common.h<br>
--- a/source/common/common.h    Mon May 21 18:42:29 2018 +0530<br>
+++ b/source/common/common.h    Tue May 22 10:17:51 2018 +0530<br>
@@ -332,6 +332,8 @@<br>
 #define START_CODE_OVERHEAD 3 <br>
 #define FILLER_OVERHEAD (NAL_TYPE_OVERHEAD + START_CODE_OVERHEAD + 1)<br>
<br>
+#define MAX_NUM_DYN_REFINE          ((NUM_CU_DEPTH - 1) * X265_REFINE_INTER_LEVELS)<br>
+<br>
 namespace X265_NS {<br>
<br>
 enum { SAO_NUM_OFFSET = 4 };<br>
diff -r cc2c5e46f3c8 -r 5587d9a25248 source/common/cudata.cpp<br>
--- a/source/common/cudata.cpp  Mon May 21 18:42:29 2018 +0530<br>
+++ b/source/common/cudata.cpp  Tue May 22 10:17:51 2018 +0530<br>
@@ -274,6 +274,9 @@<br>
         for (int i = 0; i < 3; i++)<br>
             m_fAc_den[i] = m_fDc_den[i] = 0;<br>
     }<br>
+    m_collectCURd = dataPool.dynRefineRdBlock + (instance * MAX_NUM_DYN_REFINE);<br>
+    m_collectCUVariance = dataPool.dynRefVarBlock + (instance * MAX_NUM_DYN_REFINE);<br>
+    m_collectCUCount = dataPool.dynRefCntBlock + (instance * MAX_NUM_DYN_REFINE);<br>
 }<br>
<br>
 void CUData::initCTU(const Frame& frame, uint32_t cuAddr, int qp, uint32_t firstRowInSlice, uint32_t lastRowInSlice, uint32_t lastCuInSlice)<br>
@@ -318,15 +321,9 @@<br>
     m_cuAboveRight = (m_cuAbove && ((m_cuAddr % widthInCU) < (widthInCU - 1))) ? m_encData->getPicCTU(m_cuAddr - widthInCU + 1) : NULL;<br>
     memset(m_distortion, 0, m_numPartitions * sizeof(sse_t));<br>
<br>
-    if (m_encData->m_param-><wbr>bDynamicRefine)<br>
-    {<br>
-        int size = m_encData->m_param->maxCUDepth * X265_REFINE_INTER_LEVELS;<br>
-        CHECKED_MALLOC_ZERO(m_<wbr>collectCURd, uint64_t, size);<br>
-        CHECKED_MALLOC_ZERO(m_<wbr>collectCUVariance, uint32_t, size);<br>
-        CHECKED_MALLOC_ZERO(m_<wbr>collectCUCount, uint32_t, size);<br>
-    }<br>
-fail:<br>
-    return;<br>
+    memset(m_collectCURd, 0, MAX_NUM_DYN_REFINE * sizeof(uint64_t));<br>
+    memset(m_collectCUVariance, 0, MAX_NUM_DYN_REFINE * sizeof(uint32_t));<br>
+    memset(m_collectCUCount, 0, MAX_NUM_DYN_REFINE * sizeof(uint32_t));<br>
 }<br>
<br>
 // initialize Sub partition<br>
diff -r cc2c5e46f3c8 -r 5587d9a25248 source/common/cudata.h<br>
--- a/source/common/cudata.h    Mon May 21 18:42:29 2018 +0530<br>
+++ b/source/common/cudata.h    Tue May 22 10:17:51 2018 +0530<br>
@@ -353,8 +353,12 @@<br>
     coeff_t* trCoeffMemBlock;<br>
     MV*      mvMemBlock;<br>
     sse_t*   distortionMemBlock;<br>
+    uint64_t* dynRefineRdBlock;<br>
+    uint32_t* dynRefCntBlock;<br>
+    uint32_t* dynRefVarBlock;<br>
<br>
-    CUDataMemPool() { charMemBlock = NULL; trCoeffMemBlock = NULL; mvMemBlock = NULL; distortionMemBlock = NULL; }<br>
+    CUDataMemPool() { charMemBlock = NULL; trCoeffMemBlock = NULL; mvMemBlock = NULL; distortionMemBlock = NULL; <br>
+                      dynRefineRdBlock = NULL; dynRefCntBlock = NULL; dynRefVarBlock = NULL;}<br>
<br>
     bool create(uint32_t depth, uint32_t csp, uint32_t numInstances, const x265_param& param)<br>
     {<br>
@@ -373,6 +377,9 @@<br>
         CHECKED_MALLOC(charMemBlock, uint8_t, numPartition * numInstances * CUData::BytesPerPartition);<br>
         CHECKED_MALLOC_ZERO(<wbr>mvMemBlock, MV, numPartition * 4 * numInstances);<br>
         CHECKED_MALLOC(<wbr>distortionMemBlock, sse_t, numPartition * numInstances);<br>
+        CHECKED_MALLOC_ZERO(<wbr>dynRefineRdBlock, uint64_t, MAX_NUM_DYN_REFINE * numInstances);<br>
+        CHECKED_MALLOC_ZERO(<wbr>dynRefCntBlock, uint32_t, MAX_NUM_DYN_REFINE * numInstances);<br>
+        CHECKED_MALLOC_ZERO(<wbr>dynRefVarBlock, uint32_t, MAX_NUM_DYN_REFINE * numInstances);<br>
         return true;<br>
     fail:<br>
         return false;<br>
@@ -384,6 +391,9 @@<br>
         X265_FREE(mvMemBlock);<br>
         X265_FREE(charMemBlock);<br>
         X265_FREE(distortionMemBlock);<br>
+        X265_FREE(dynRefineRdBlock);<br>
+        X265_FREE(dynRefCntBlock);<br>
+        X265_FREE(dynRefVarBlock);<br>
     }<br>
 };<br>
 }<br>
diff -r cc2c5e46f3c8 -r 5587d9a25248 source/common/framedata.h<br>
--- a/source/common/framedata.h Mon May 21 18:42:29 2018 +0530<br>
+++ b/source/common/framedata.h Tue May 22 10:17:51 2018 +0530<br>
@@ -88,6 +88,11 @@<br>
     uint64_t    cntInterPu[NUM_CU_DEPTH][<wbr>INTER_MODES - 1];<br>
     uint64_t    cntMergePu[NUM_CU_DEPTH][<wbr>INTER_MODES - 1];<br>
<br>
+    /* Feature values per row for dynamic refinement */<br>
+    uint64_t       rowRdDyn[MAX_NUM_DYN_REFINE];<br>
+    uint32_t       rowVarDyn[MAX_NUM_DYN_REFINE];<br>
+    uint32_t       rowCntDyn[MAX_NUM_DYN_REFINE];<br>
+<br>
     FrameStats()<br>
     {<br>
         memset(this, 0, sizeof(FrameStats));<br>
diff -r cc2c5e46f3c8 -r 5587d9a25248 source/encoder/frameencoder.<wbr>cpp<br>
--- a/source/encoder/frameencoder.<wbr>cpp   Mon May 21 18:42:29 2018 +0530<br>
+++ b/source/encoder/frameencoder.<wbr>cpp   Tue May 22 10:17:51 2018 +0530<br>
@@ -956,6 +956,9 @@<br>
         }  <br>
     } // end of (m_param->maxSlices > 1)<br>
<br>
+    if (m_param->bDynamicRefine && m_top->m_startPoint <= m_frame->m_encodeOrder) //Avoid collecting data that will not be used by future frames.<br>
+        collectDynDataFrame();<br>
+<br>
     if (m_param->rc.bStatWrite)<br>
     {<br>
         int totalI = 0, totalP = 0, totalSkip = 0;<br>
@@ -1494,31 +1497,12 @@<br>
<br>
         // Does all the CU analysis, returns best top level mode decision<br>
         Mode& best = tld.analysis.compressCTU(*ctu, *m_frame, m_cuGeoms[m_ctuGeomMap[cuAddr]<wbr>], rowCoder);<br>
-        if (m_param->bDynamicRefine)<br>
-        {<br>
-            if (m_top->m_startPoint <= m_frame->m_encodeOrder) // Avoid collecting data that will not be used by future frames.<br>
-            {<br>
-                ScopedLock dynLock(m_top->m_<wbr>dynamicRefineLock);<br>
-                for (uint32_t i = 0; i < X265_REFINE_INTER_LEVELS; i++)<br>
-                {<br>
-                    for (uint32_t depth = 0; depth < m_param->maxCUDepth; depth++)<br>
-                    {<br>
-                        int offset = (depth * X265_REFINE_INTER_LEVELS) + i;<br>
-                        int curFrameIndex = m_frame->m_encodeOrder - m_top->m_startPoint;<br>
-                        int index = (curFrameIndex * X265_REFINE_INTER_LEVELS * m_param->maxCUDepth) + offset;<br>
-                        if (ctu->m_collectCUCount[offset]<wbr>)<br>
-                        {<br>
-                            m_top->m_variance[index] += ctu->m_collectCUVariance[<wbr>offset];<br>
-                            m_top->m_rdCost[index] += ctu->m_collectCURd[offset];<br>
-                            m_top->m_trainingCount[index] += ctu->m_collectCUCount[offset];<br>
-                        }<br>
-                    }<br>
-                }<br>
-            }<br>
-            X265_FREE_ZERO(ctu->m_<wbr>collectCUVariance);<br>
-            X265_FREE_ZERO(ctu->m_<wbr>collectCURd);<br>
-            X265_FREE_ZERO(ctu->m_<wbr>collectCUCount);<br>
-        }<br>
+<br>
+        /* startPoint > encodeOrder is true when the start point changes for<br>
+        a new GOP but few frames from the previous GOP is still incomplete.<br>
+        The data of frames in this interval will not be used by any future frames. */<br>
+        if (m_param->bDynamicRefine && m_top->m_startPoint <= m_frame->m_encodeOrder)<br>
+            collectDynDataRow(*ctu, &curRow.rowStats);<br>
<br>
         // take a sample of the current active worker count<br>
         ATOMIC_ADD(&m_<wbr>totalActiveWorkerCount, m_activeWorkerCount);<br>
@@ -1901,6 +1885,46 @@<br>
     if (ATOMIC_INC(&m_<wbr>completionCount) == 2 * (int)m_numRows)<br>
         m_completionEvent.trigger();<br>
 }<br>
+<br>
+void FrameEncoder::<wbr>collectDynDataRow(CUData& ctu, FrameStats* rowStats)<br>
+{<br>
+    for (uint32_t i = 0; i < X265_REFINE_INTER_LEVELS; i++)<br>
+    {<br>
+        for (uint32_t depth = 0; depth < m_param->maxCUDepth; depth++)<br>
+        {<br>
+            int offset = (depth * X265_REFINE_INTER_LEVELS) + i;<br>
+            if (ctu.m_collectCUCount[offset])<br>
+            {<br>
+                rowStats->rowVarDyn[offset] += ctu.m_collectCUVariance[<wbr>offset];<br>
+                rowStats->rowRdDyn[offset] += ctu.m_collectCURd[offset];<br>
+                rowStats->rowCntDyn[offset] += ctu.m_collectCUCount[offset];<br>
+            }<br>
+        }<br>
+    }<br>
+}<br>
+<br>
+void FrameEncoder::<wbr>collectDynDataFrame()<br>
+{<br>
+    for (uint32_t row = 0; row < m_numRows; row++)<br>
+    {<br>
+        for (uint32_t refLevel = 0; refLevel < X265_REFINE_INTER_LEVELS; refLevel++)<br>
+        {<br>
+            for (uint32_t depth = 0; depth < m_param->maxCUDepth; depth++)<br>
+            {<br>
+                int offset = (depth * X265_REFINE_INTER_LEVELS) + refLevel;<br>
+                int curFrameIndex = m_frame->m_encodeOrder - m_top->m_startPoint;<br>
+                int index = (curFrameIndex * X265_REFINE_INTER_LEVELS * m_param->maxCUDepth) + offset;<br>
+                if (m_rows[row].rowStats.<wbr>rowCntDyn[offset])<br>
+                {<br>
+                    m_top->m_variance[index] += m_rows[row].rowStats.<wbr>rowVarDyn[offset];<br>
+                    m_top->m_rdCost[index] += m_rows[row].rowStats.rowRdDyn[<wbr>offset];<br>
+                    m_top->m_trainingCount[index] += m_rows[row].rowStats.<wbr>rowCntDyn[offset];<br>
+                }<br>
+            }<br>
+        }<br>
+    }<br>
+}<br>
+<br>
 void FrameEncoder::<wbr>computeAvgTrainingData()<br>
 {<br>
     if (m_frame->m_lowres.bScenecut || m_frame->m_lowres.bKeyframe)<br>
diff -r cc2c5e46f3c8 -r 5587d9a25248 source/encoder/frameencoder.h<br>
--- a/source/encoder/frameencoder.<wbr>h     Mon May 21 18:42:29 2018 +0530<br>
+++ b/source/encoder/frameencoder.<wbr>h     Tue May 22 10:17:51 2018 +0530<br>
@@ -243,6 +243,8 @@<br>
 #if ENABLE_LIBVMAF<br>
     void vmafFrameLevelScore();<br>
 #endif<br>
+    void collectDynDataRow(CUData& ctu, FrameStats* rowStats);<br>
+    void collectDynDataFrame();<br>
 };<br>
 }<br>
<br>
</blockquote></div><br></div>