<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 20, 2017 at 11:01 AM, Pradeep Ramachandran <span dir="ltr"><<a href="mailto:pradeep@multicorewareinc.com" target="_blank">pradeep@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote"><span class="gmail-">On Fri, Nov 17, 2017 at 7:23 PM,  <span dir="ltr"><<a href="mailto:praveen@multicorewareinc.com" target="_blank">praveen@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># HG changeset patch<br>
# User Praveen Tiwari <<a href="mailto:praveen@multicorewareinc.com" target="_blank">praveen@multicorewareinc.com</a>><br>
# Date 1510926794 -19800<br>
#      Fri Nov 17 19:23:14 2017 +0530<br>
# Node ID 6b248ccb14169d2b0d5b84d50d94a1<wbr>53bd8f3b4f<br>
# Parent  9723e8812e63ce51e38ede41f7d5ed<wbr>f73cad0849<br>
analysis: use AVC CU analysis-info for HEVC mode analysis<br></blockquote><div><br></div></span><div>Pushed to default. Thanks!</div><div><div class="gmail-h5"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
This patch work implements the functionality for anlysis-reuselevel 7, here we want<br>
to use AVC analysis-info for HEVC mode decision and use the depth from offload<br>
for AVC sizes<br>
<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/common/cudata.cpp<br>
--- a/source/common/cudata.cpp  Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/common/cudata.cpp  Fri Nov 17 19:23:14 2017 +0530<br>
@@ -201,6 +201,8 @@<br>
         m_cuDepth            = charBuf; charBuf += m_numPartitions;<br>
         m_predMode           = charBuf; charBuf += m_numPartitions; /* the order up to here is important in initCTU() and initSubCU() */<br>
         m_partSize           = charBuf; charBuf += m_numPartitions;<br>
+        m_skipFlag[0]        = charBuf; charBuf += m_numPartitions;<br>
+        m_skipFlag[1]        = charBuf; charBuf += m_numPartitions;<br>
         m_mergeFlag          = charBuf; charBuf += m_numPartitions;<br>
         m_interDir           = charBuf; charBuf += m_numPartitions;<br>
         m_mvpIdx[0]          = charBuf; charBuf += m_numPartitions;<br>
@@ -239,6 +241,8 @@<br>
         m_cuDepth            = charBuf; charBuf += m_numPartitions;<br>
         m_predMode           = charBuf; charBuf += m_numPartitions; /* the order up to here is important in initCTU() and initSubCU() */<br>
         m_partSize           = charBuf; charBuf += m_numPartitions;<br>
+        m_skipFlag[0]        = charBuf; charBuf += m_numPartitions;<br>
+        m_skipFlag[1]        = charBuf; charBuf += m_numPartitions;<br>
         m_mergeFlag          = charBuf; charBuf += m_numPartitions;<br>
         m_interDir           = charBuf; charBuf += m_numPartitions;<br>
         m_mvpIdx[0]          = charBuf; charBuf += m_numPartitions;<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/common/cudata.h<br>
--- a/source/common/cudata.h    Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/common/cudata.h    Fri Nov 17 19:23:14 2017 +0530<br>
@@ -199,13 +199,14 @@<br>
     uint8_t*      m_predMode;         // array of prediction modes<br>
     uint8_t*      m_partSize;         // array of partition sizes<br>
     uint8_t*      m_mergeFlag;        // array of merge flags<br>
+    uint8_t*      m_skipFlag[2];<br>
     uint8_t*      m_interDir;         // array of inter directions<br>
     uint8_t*      m_mvpIdx[2];        // array of motion vector predictor candidates or merge candidate indices [0]<br>
     uint8_t*      m_tuDepth;          // array of transform indices<br>
     uint8_t*      m_transformSkip[3]; // array of transform skipping flags per plane<br>
     uint8_t*      m_cbf[3];           // array of coded block flags (CBF) per plane<br>
     uint8_t*      m_chromaIntraDir;   // array of intra directions (chroma)<br>
-    enum { BytesPerPartition = 21 };  // combined sizeof() of all per-part data<br>
+    enum { BytesPerPartition = 23 };  // combined sizeof() of all per-part data<br>
<br>
     sse_t*        m_distortion;<br>
     coeff_t*      m_trCoeff[3];       // transformed coefficient buffer per plane<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/common/framedata.h<br>
--- a/source/common/framedata.h Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/common/framedata.h Fri Nov 17 19:23:14 2017 +0530<br>
@@ -195,6 +195,7 @@<br>
     uint8_t*    mvpIdx[2];<br>
     int8_t*     refIdx[2];<br>
     MV*         mv[2];<br>
+   int64_t*     sadCost;<br>
 };<br>
<br>
 struct analysis2PassFrameData<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/encoder/analysis.cpp<br>
--- a/source/encoder/analysis.cpp       Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/encoder/analysis.cpp       Fri Nov 17 19:23:14 2017 +0530<br>
@@ -75,6 +75,10 @@<br>
     m_reuseInterDataCTU = NULL;<br>
     m_reuseRef = NULL;<br>
     m_bHD = false;<br>
+    m_modeFlag[0] = false;<br>
+    m_modeFlag[1] = false;<br>
+    m_checkMergeAndSkipOnly[0] = false;<br>
+    m_checkMergeAndSkipOnly[1] = false;<br>
     m_evaluateInter = 0;<br>
 }<br>
<br>
@@ -247,6 +251,9 @@<br>
             memcpy(ctu.m_cuDepth, &interDataCTU->depth[posCTU], sizeof(uint8_t) * numPartition);<br>
             memcpy(ctu.m_predMode, &interDataCTU->modes[posCTU], sizeof(uint8_t) * numPartition);<br>
             memcpy(ctu.m_partSize, &interDataCTU->partSize[posCTU<wbr>], sizeof(uint8_t) * numPartition);<br>
+            for (int list = 0; list < m_slice->isInterB() + 1; list++)<br>
+                memcpy(ctu.m_skipFlag[list], &m_frame->m_analysisData.modeF<wbr>lag[list][posCTU], sizeof(uint8_t) * numPartition);<br>
+<br>
             if ((m_slice->m_sliceType == P_SLICE || m_param->bIntraInBFrames) && !m_param->bMVType)<br>
             {<br>
                 analysis_intra_data* intraDataCTU = (analysis_intra_data*)m_frame-<wbr>>m_analysisData.intraData;<br>
@@ -1162,7 +1169,11 @@<br>
     PicYuv& reconPic = *m_frame->m_reconPic;<br>
     SplitData splitCUData;<br>
<br>
-    if ((m_param->bMVType && cuGeom.numPartitions > 16) || !m_param->bMVType)<br>
+    bool bHEVCBlockAnalysis = (m_param->bMVType && cuGeom.numPartitions > 16);<br>
+    bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));<br>
+    bool bNooffloading = !m_param->bMVType;<br>
+<br>
+    if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)<br>
     {<br>
         md.bestMode = NULL;<br>
         bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);<br>
@@ -1296,7 +1307,7 @@<br>
         }<br>
<br>
         /* Step 1. Evaluate Merge/Skip candidates for likely early-outs, if skip mode was not set above */<br>
-        if (mightNotSplit && depth >= minDepth && !md.bestMode && !bCtuInfoCheck) /* TODO: Re-evaluate if analysis load/save still works */<br>
+        if ((mightNotSplit && depth >= minDepth && !md.bestMode && !bCtuInfoCheck) || (m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1]))) /* TODO: Re-evaluate if analysis load/save still works */<br>
         {<br>
             /* Compute Merge Cost */<br>
             md.pred[PRED_MERGE].cu.initSu<wbr>bCU(parentCTU, cuGeom, qp);<br>
@@ -1307,7 +1318,7 @@<br>
                 && md.bestMode && md.bestMode->cu.isSkipped(0); // TODO: sa8d threshold per depth<br>
         }<br>
<br>
-        if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck)<br>
+        if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck && !(m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1])))<br>
         {<br>
             skipRecursion = md.bestMode->cu.isSkipped(0);<br>
             if (mightSplit && depth >= minDepth && !skipRecursion)<br>
@@ -1319,6 +1330,9 @@<br>
             }<br>
         }<br>
<br>
+        if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <= 16)<br>
+            skipRecursion = true;<br>
+<br>
         /* Step 2. Evaluate each of the 4 split sub-blocks in series */<br>
         if (mightSplit && !skipRecursion)<br>
         {<br>
@@ -1374,6 +1388,10 @@<br>
                 splitPred->sa8dCost = m_rdCost.calcRdSADCost((uint32<wbr>_t)splitPred->distortion, splitPred->sa8dBits);<br>
         }<br>
<br>
+        /* If analysis mode is simple do not Evaluate other modes */<br>
+        if ((m_param->bMVType && cuGeom.numPartitions <= 16) && (m_slice->m_sliceType == P_SLICE || m_slice->m_sliceType == B_SLICE))<br>
+            mightNotSplit = !(m_checkMergeAndSkipOnly[0] || (m_checkMergeAndSkipOnly[0] && m_checkMergeAndSkipOnly[1]));<br>
+<br>
         /* Split CUs<br>
          *   0  1<br>
          *   2  3 */<br>
@@ -1838,7 +1856,12 @@<br>
     }<br>
<br></blockquote></div></div></div></div></div></blockquote><div>It is better to write a separate function when bMVType is enabled. When numPartitions > 16, call compressInterCU_rd5_6(), else write code specific to</div><div>your requirement. It will be much cleaner and readable, so that the base code will not be disturbed. </div><div><br></div><div>Same is applied for the case of compressInterCU_rd0_4().</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="gmail-h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
     SplitData splitCUData;<br>
-    if ((m_param->bMVType && cuGeom.numPartitions > 16) || !m_param->bMVType)<br>
+<br>
+    bool bHEVCBlockAnalysis = (m_param->bMVType && cuGeom.numPartitions > 16);<br>
+    bool bRefineAVCAnalysis = (m_param->analysisReuseLevel == 7 && (m_modeFlag[0] || m_modeFlag[1]));<br>
+    bool bNooffloading = !m_param->bMVType;<br>
+<br>
+    if (bHEVCBlockAnalysis || bRefineAVCAnalysis || bNooffloading)<br>
     {<br>
         bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);<br>
         bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);<br>
@@ -1977,7 +2000,7 @@<br>
         }<br>
<br>
         /* Step 1. Evaluate Merge/Skip candidates for likely early-outs */<br>
-        if (mightNotSplit && !md.bestMode && !bCtuInfoCheck)<br>
+        if (mightNotSplit && !md.bestMode && !bCtuInfoCheck || (m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1])))<br>
         {<br>
             md.pred[PRED_SKIP].cu.initSub<wbr>CU(parentCTU, cuGeom, qp);<br>
             md.pred[PRED_MERGE].cu.initSu<wbr>bCU(parentCTU, cuGeom, qp);<br>
@@ -1993,6 +2016,9 @@<br>
                 skipRecursion = md.bestMode && !md.bestMode->cu.getQtRootCbf(<wbr>0);<br>
         }<br>
<br>
+        if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <= 16)<br>
+            skipRecursion = true;<br>
+<br>
         // estimate split cost<br>
         /* Step 2. Evaluate each of the 4 split sub-blocks in series */<br>
         if (mightSplit && !skipRecursion)<br>
@@ -2045,6 +2071,10 @@<br>
             checkDQPForSplitPred(*splitPr<wbr>ed, cuGeom);<br>
         }<br>
<br>
+        /* If analysis mode is simple do not Evaluate other modes */<br>
+        if ((m_param->bMVType && cuGeom.numPartitions <= 16) && (m_slice->m_sliceType == P_SLICE || m_slice->m_sliceType == B_SLICE))<br>
+            mightNotSplit = !(m_checkMergeAndSkipOnly[0] || (m_checkMergeAndSkipOnly[0] && m_checkMergeAndSkipOnly[1]));<br>
+<br>
         /* Split CUs<br>
          *   0  1<br>
          *   2  3 */<br>
@@ -2479,6 +2509,22 @@<br>
                 checkDQPForSplitPred(*md.best<wbr>Mode, cuGeom);<br>
         }<br>
<br>
+        if (m_param->bMVType && m_param->analysisReuseLevel == 7)<br>
+        {<br>
+            for (int list = 0; list < m_slice->isInterB() + 1; list++)<br>
+            {<br>
+                m_modeFlag[list] = true;<br>
+                if (parentCTU.m_skipFlag[list][cu<wbr>Geom.absPartIdx] == 1 && cuGeom.numPartitions <= 16)<br>
+                    m_checkMergeAndSkipOnly[list] = true;<br>
+            }<br>
+            m_param->rdLevel > 4 ? compressInterCU_rd5_6(parentCT<wbr>U, cuGeom, qp) : compressInterCU_rd0_4(parentCT<wbr>U, cuGeom, qp);<br>
+            for (int list = 0; list < m_slice->isInterB() + 1; list++)<br>
+            {<br>
+                m_modeFlag[list] = false;<br>
+                m_checkMergeAndSkipOnly[list] = false;<br>
+            }<br>
+        }<br>
+<br>
         if (m_param->interRefine > 1 || (m_param->interRefine && parentCTU.m_predMode[cuGeom.ab<wbr>sPartIdx] == MODE_SKIP  && !mode.cu.isSkipped(0)))<br>
         {<br>
             m_evaluateInter = 1;<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/encoder/analysis.h<br>
--- a/source/encoder/analysis.h Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/encoder/analysis.h Fri Nov 17 19:23:14 2017 +0530<br>
@@ -110,6 +110,9 @@<br>
     bool      m_bChromaSa8d;<br>
     bool      m_bHD;<br>
<br>
+    bool      m_modeFlag[2];<br>
+    bool      m_checkMergeAndSkipOnly[2];<br>
+<br>
     Analysis();<br>
<br>
     bool create(ThreadLocalData* tld);<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp        Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/encoder/encoder.cpp        Fri Nov 17 19:23:14 2017 +0530<br>
@@ -48,6 +48,12 @@<br>
 const char g_sliceTypeToChar[] = {'B', 'P', 'I'};<br>
 }<br>
<br>
+/* Threshold for motion vection, based on expermental result.<br>
+ * TODO: come up an algorithm for adoptive threshold */<br>
+<br>
+#define MVTHRESHOLD 10<br>
+#define PU_2Nx2N 1<br>
+<br>
 static const char* defaultAnalysisFileName = "x265_analysis.dat";<br>
<br>
 using namespace X265_NS;<br>
@@ -565,6 +571,14 @@<br>
                             (interData)->mvpIdx[k][cuPos + cuOffset] = (srcInterData)->mvpIdx[k][(mbI<wbr>ndex * 16) + cuOffset];<br>
                             (interData)->refIdx[k][cuPos + cuOffset] = (srcInterData)->refIdx[k][(mbI<wbr>ndex * 16) + cuOffset];<br>
                             memcpy(&(interData)->mv[k][cu<wbr>Pos + cuOffset], &(srcInterData)->mv[k][(mbInde<wbr>x * 16) + cuOffset], sizeof(MV));<br>
+                            if (m_param->analysisReuseLevel == 7)<br>
+                            {<br>
+                                int mv_x = ((analysis_inter_data *)curFrame->m_analysisData.int<wbr>erData)->mv[k][(mbIndex * 16) + cuOffset].x;<br>
+                                int mv_y = ((analysis_inter_data *)curFrame->m_analysisData.int<wbr>erData)->mv[k][(mbIndex * 16) + cuOffset].y;<br>
+                                double mv = sqrt(mv_x*mv_x + mv_y*mv_y);<br>
+                                if (numPU == PU_2Nx2N && ((srcInterData)->depth[cuPos + cuOffset] == (m_param->maxCUSize >> 5)) && mv <= MVTHRESHOLD)<br>
+                                    memset(&curFrame->m_analysisDa<wbr>ta.modeFlag[k][cuPos + cuOffset], 1, bytes);<br>
+                            }<br>
                         }<br>
                     }<br>
                 }<br>
@@ -624,6 +638,7 @@<br>
                     int bytes = curFrame->m_analysisData.numPa<wbr>rtitions >> ((interData)->depth[d] * 2);<br>
                     memset(&(currInterData)->dept<wbr>h[count], (interData)->depth[d], bytes);<br>
                     memset(&(currInterData)->mode<wbr>s[count], (interData)->modes[d], bytes);<br>
+                    memcpy(&(currInterData)->sadCo<wbr>st[count], &((analysis_inter_data*)analys<wbr>is_data->interData)->sadCost[<wbr>d], bytes);<br>
                     if (m_param->analysisReuseLevel > 4)<br>
                     {<br>
                         memset(&(currInterData)->part<wbr>Size[count], (interData)->partSize[d], bytes);<br>
@@ -639,6 +654,14 @@<br>
                                     (currInterData)->mvpIdx[i][co<wbr>unt + pu] = (interData)->mvpIdx[i][d];<br>
                                     (currInterData)->refIdx[i][co<wbr>unt + pu] = (interData)->refIdx[i][d];<br>
                                     memcpy(&(currInterData)->mv[<wbr>i][count + pu], &(interData)->mv[i][d], sizeof(MV));<br>
+                                    if (m_param->analysisReuseLevel == 7)<br>
+                                    {<br>
+                                        int mv_x = ((analysis_inter_data *)curFrame->m_analysisData.int<wbr>erData)->mv[i][count + pu].x;<br>
+                                        int mv_y = ((analysis_inter_data *)curFrame->m_analysisData.int<wbr>erData)->mv[i][count + pu].y;<br>
+                                        double mv = sqrt(mv_x*mv_x + mv_y*mv_y);<br>
+                                        if (numPU == PU_2Nx2N && m_param->num4x4Partitions <= 16 && mv <= MVTHRESHOLD)<br>
+                                            memset(&curFrame->m_analysisDa<wbr>ta.modeFlag[i][count + pu], 1, bytes);<br>
+                                    }<br>
                                 }<br>
                             }<br>
                         }<br>
@@ -3116,12 +3139,14 @@<br>
             if (m_param->analysisReuseLevel >= 7)<br>
             {<br>
                 X265_FREE(((analysis_inter_da<wbr>ta*)analysis->interData)->inte<wbr>rDir);<br>
+                X265_FREE(((analysis_inter_dat<wbr>a*)analysis->interData)->sadCo<wbr>st);<br>
                 int numDir = analysis->sliceType == X265_TYPE_P ? 1 : 2;<br>
                 for (int dir = 0; dir < numDir; dir++)<br>
                 {<br>
                     X265_FREE(((analysis_inter_da<wbr>ta*)analysis->interData)->mvpI<wbr>dx[dir]);<br>
                     X265_FREE(((analysis_inter_da<wbr>ta*)analysis->interData)->refI<wbr>dx[dir]);<br>
                     X265_FREE(((analysis_inter_da<wbr>ta*)analysis->interData)->mv[<wbr>dir]);<br>
+                    X265_FREE(analysis->modeFlag[d<wbr>ir]);<br>
                 }<br>
             }<br>
             else<br>
diff -r 9723e8812e63 -r 6b248ccb1416 source/x265.h<br>
--- a/source/x265.h     Fri Nov 17 14:16:31 2017 +0530<br>
+++ b/source/x265.h     Fri Nov 17 19:23:14 2017 +0530<br>
@@ -123,6 +123,7 @@<br>
     void*            intraData;<br>
     uint32_t         numCuInHeight;<br>
     x265_lookahead_data lookahead;<br>
+    uint8_t*         modeFlag[2];<br>
 } x265_analysis_data;<br>
<br>
 /* cu statistics */<br>
______________________________<wbr>_________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/l<wbr>istinfo/x265-devel</a><br>
</blockquote></div></div></div><br></div></div>
<br>______________________________<wbr>_________________<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/<wbr>listinfo/x265-devel</a><br>
<br></blockquote></div><br></div></div>