<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 22, 2014 at 4:59 PM,  <span dir="ltr"><<a href="mailto:gopu@multicorewareinc.com" target="_blank">gopu@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 Gopu Govindaswamy <<a href="mailto:gopu@multicorewareinc.com">gopu@multicorewareinc.com</a>><br>
# Date 1419247700 -19800<br>
#      Mon Dec 22 16:58:20 2014 +0530<br>
# Node ID 8606c4019f6b962bec47398ac8f876642ecab747<br>
# Parent  8d2f418829c894c25da79daa861f16c61e5060d7<br>
analysis: dump the best depth and re-use it for analysis-mode=load<br>
<br>
For inter frame currently dump the best ref and re-using it, in addition to that<br>
share the best depth and re-use it for analysis mode=load, the best depth can be<br>
shared only the mode is MODE_SKIP, otherwise ignored it<br>
<br>
diff -r 8d2f418829c8 -r 8606c4019f6b source/encoder/analysis.cpp<br>
--- a/source/encoder/analysis.cpp       Sat Dec 20 21:27:14 2014 +0900<br>
+++ b/source/encoder/analysis.cpp       Mon Dec 22 16:58:20 2014 +0530<br>
@@ -138,9 +138,9 @@<br>
         m_reuseInterDataCTU = (analysis_inter_data *)m_frame->m_analysisData.interData + ctu.m_cuAddr * X265_MAX_PRED_MODE_PER_CTU * numPredDir;<br>
     }<br>
<br>
+    uint32_t zOrder = 0;<br>
     if (m_slice->m_sliceType == I_SLICE)<br>
     {<br>
-        uint32_t zOrder = 0;<br>
         compressIntraCU(ctu, cuGeom, m_reuseIntraDataCTU, zOrder);<br>
         if (m_param->analysisMode == X265_ANALYSIS_SAVE && m_frame->m_analysisData.intraData)<br>
         {<br>
@@ -158,7 +158,7 @@<br>
             * they are available for intra predictions */<br>
             m_modeDepth[0].fencYuv.copyToPicYuv(*m_frame->m_reconPic, ctu.m_cuAddr, 0);<br>
<br>
-            compressInterCU_rd0_4(ctu, cuGeom);<br>
+            compressInterCU_rd0_4(ctu, cuGeom, m_reuseIntraDataCTU, zOrder);<br>
<br>
             /* generate residual for entire CTU at once and copy to reconPic */<br>
             encodeResidue(ctu, cuGeom);<br>
@@ -166,9 +166,17 @@<br>
         else if (m_param->bDistributeModeAnalysis && m_param->rdLevel >= 2)<br>
             compressInterCU_dist(ctu, cuGeom);<br>
         else if (m_param->rdLevel <= 4)<br>
-            compressInterCU_rd0_4(ctu, cuGeom);<br>
+            compressInterCU_rd0_4(ctu, cuGeom, m_reuseIntraDataCTU, zOrder);<br>
         else<br>
-            compressInterCU_rd5_6(ctu, cuGeom);<br>
+        {<br>
+            compressInterCU_rd5_6(ctu, cuGeom, m_reuseIntraDataCTU, zOrder);<br></blockquote><div><br></div><div>This is clearly inter-data, why are we saving/loading it using intraData?<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+            if (m_param->analysisMode == X265_ANALYSIS_SAVE && m_frame->m_analysisData.intraData)<br>
+            {<br>
+                CUData *bestCU = &m_modeDepth[0].bestMode->cu;<br>
+                memcpy(&m_reuseIntraDataCTU->depth[ctu.m_cuAddr * numPartition], bestCU->m_cuDepth, sizeof(uint8_t) * numPartition);<br>
+                memcpy(&m_reuseIntraDataCTU->modes[ctu.m_cuAddr * numPartition], bestCU->m_predMode, sizeof(uint8_t) * numPartition);<br>
+            }<br>
+        }<br>
     }<br>
<br>
     return *m_modeDepth[0].bestMode;<br>
@@ -748,7 +756,7 @@<br>
         md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic, cuAddr, cuGeom.encodeIdx);<br>
 }<br>
<br></blockquote><div>Lets leave this out until force-skip is added at rd 0, 4 also. <br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-void Analysis::compressInterCU_rd0_4(const CUData& parentCTU, const CUGeom& cuGeom)<br>
+void Analysis::compressInterCU_rd0_4(const CUData& parentCTU, const CUGeom& cuGeom, analysis_intra_data* reuseIntraData, uint32_t& zOrder)<br>
 {<br>
     uint32_t depth = cuGeom.depth;<br>
     uint32_t cuAddr = parentCTU.m_cuAddr;<br>
@@ -982,7 +990,7 @@<br>
             {<br>
                 m_modeDepth[0].fencYuv.copyPartToYuv(nd.fencYuv, childGeom.encodeIdx);<br>
                 m_rqt[nextDepth].cur.load(*nextContext);<br>
-                compressInterCU_rd0_4(parentCTU, childGeom);<br>
+                compressInterCU_rd0_4(parentCTU, childGeom, reuseIntraData, zOrder);<br>
<br>
                 // Save best CU and pred data for this sub CU<br>
                 splitCU->copyPartFrom(nd.bestMode->cu, childGeom, subPartIdx);<br>
@@ -1033,7 +1041,7 @@<br>
         md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic, cuAddr, cuGeom.encodeIdx);<br>
 }<br>
<br>
-void Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom& cuGeom)<br></blockquote><div><br></div><div>m_reuseIntraData is a member field of Analysis, it might be better to store an incrementing counter as each depth/mode is read.<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+void Analysis::compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom& cuGeom, analysis_intra_data* reuseIntraData, uint32_t& zOrder)<br>
 {<br>
     uint32_t depth = cuGeom.depth;<br>
     ModeDepth& md = m_modeDepth[depth];<br>
@@ -1042,6 +1050,50 @@<br>
     bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);<br>
     bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);<br>
<br>
+    if (m_param->analysisMode == X265_ANALYSIS_LOAD)<br>
+    {<br>
+        uint8_t* reuseDepth  = &reuseIntraData->depth[parentCTU.m_cuAddr * parentCTU.m_numPartitions];<br>
+        uint8_t* reuseModes  = &reuseIntraData->modes[parentCTU.m_cuAddr * parentCTU.m_numPartitions];<br>
+        if (mightNotSplit && depth == reuseDepth[zOrder] && zOrder == cuGeom.encodeIdx && reuseModes[zOrder] == MODE_SKIP)<br>
+        {<br>
+            md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);<br>
+            md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom);<br>
+            checkMerge2Nx2N_rd5_6(md.pred[PRED_SKIP], md.pred[PRED_MERGE], cuGeom);<br>
+<br>
+            if ((m_slice->m_sliceType != B_SLICE || m_param->bIntraInBFrames) &&<br>
+                (!m_param->bEnableCbfFastMode || md.bestMode->cu.getQtRootCbf(0)))<br>
+            {<br>
+                md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);<br>
+                checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL);<br>
+                checkBestMode(md.pred[PRED_INTRA], depth);<br>
+<br>
+                if (depth == g_maxCUDepth && cuGeom.log2CUSize > m_slice->m_sps->quadtreeTULog2MinSize)<br>
+                {<br>
+                    md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);<br>
+                    checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, &reuseModes[zOrder]);<br>
+                    checkBestMode(md.pred[PRED_INTRA_NxN], depth);<br>
+                }<br>
+            }<br>
+<br>
+            if (m_bTryLossless)<br>
+                tryLossless(cuGeom);<br>
+<br>
+            if (mightSplit)<br>
+                addSplitFlagCost(*md.bestMode, cuGeom.depth);<br>
+<br>
+            mightSplit = false;<br>
+            mightNotSplit = false;<br>
+<br>
+            // increment zOrder offset to point to next best depth in sharedDepth buffer<br>
+            zOrder += g_depthInc[g_maxCUDepth - 1][reuseDepth[zOrder]];<br>
+<br>
+            int numPredDir = m_slice->isInterP() ? 1 : 2;<br>
+            for (int i = 0; i < md.bestMode->cu.getNumPartInter(); i++)<br>
+                for (int l = 0; l < numPredDir; l++)<br>
+                    m_reuseInterDataCTU++;<br>
+        }<br>
+    }<br>
+<br>
     if (mightNotSplit)<br>
     {<br>
         md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom);<br>
@@ -1173,7 +1225,7 @@<br>
             {<br>
                 m_modeDepth[0].fencYuv.copyPartToYuv(nd.fencYuv, childGeom.encodeIdx);<br>
                 m_rqt[nextDepth].cur.load(*nextContext);<br>
-                compressInterCU_rd5_6(parentCTU, childGeom);<br>
+                compressInterCU_rd5_6(parentCTU, childGeom, reuseIntraData, zOrder);<br>
<br>
                 // Save best CU and pred data for this sub CU<br>
                 splitCU->copyPartFrom(nd.bestMode->cu, childGeom, subPartIdx);<br>
@@ -1182,7 +1234,10 @@<br>
                 nextContext = &nd.bestMode->contexts;<br>
             }<br>
             else<br>
+            {<br>
                 splitCU->setEmptyPart(childGeom, subPartIdx);<br>
+                zOrder += g_depthInc[g_maxCUDepth - 1][nextDepth];<br>
+            }<br>
         }<br>
         nextContext->store(splitPred->contexts);<br>
         if (mightNotSplit)<br>
diff -r 8d2f418829c8 -r 8606c4019f6b source/encoder/analysis.h<br>
--- a/source/encoder/analysis.h Sat Dec 20 21:27:14 2014 +0900<br>
+++ b/source/encoder/analysis.h Mon Dec 22 16:58:20 2014 +0530<br>
@@ -99,8 +99,8 @@<br>
<br>
     /* full analysis for a P or B slice CU */<br>
     void compressInterCU_dist(const CUData& parentCTU, const CUGeom& cuGeom);<br>
-    void compressInterCU_rd0_4(const CUData& parentCTU, const CUGeom& cuGeom);<br>
-    void compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom& cuGeom);<br>
+    void compressInterCU_rd0_4(const CUData& parentCTU, const CUGeom& cuGeom, analysis_intra_data* sdata, uint32_t &zOrder);<br>
+    void compressInterCU_rd5_6(const CUData& parentCTU, const CUGeom& cuGeom, analysis_intra_data* sdata, uint32_t &zOrder);<br>
<br>
     /* measure merge and skip */<br>
     void checkMerge2Nx2N_rd0_4(Mode& skip, Mode& merge, const CUGeom& cuGeom);<br>
diff -r 8d2f418829c8 -r 8606c4019f6b source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp        Sat Dec 20 21:27:14 2014 +0900<br>
+++ b/source/encoder/encoder.cpp        Mon Dec 22 16:58:20 2014 +0530<br>
@@ -1639,12 +1639,16 @@<br>
     else if (analysis->sliceType == X265_TYPE_P)<br>
     {<br>
         X265_FREAD(analysis->interData, sizeof(analysis_inter_data), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU, m_analysisFile);<br>
+        X265_FREAD(((analysis_intra_data *)analysis->intraData)->depth, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);<br>
+        X265_FREAD(((analysis_intra_data *)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);<br>
         consumedBytes += frameRecordSize;<br>
         totalConsumedBytes = consumedBytes;<br>
     }<br>
     else<br>
     {<br>
         X265_FREAD(analysis->interData, sizeof(analysis_inter_data), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * 2, m_analysisFile);<br>
+        X265_FREAD(((analysis_intra_data *)analysis->intraData)->depth, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);<br>
+        X265_FREAD(((analysis_intra_data *)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);<br>
         consumedBytes += frameRecordSize;<br>
     }<br>
 #undef X265_FREAD<br>
@@ -1668,9 +1672,15 @@<br>
     if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)<br>
         analysis->frameRecordSize += sizeof(uint8_t) * analysis->numCUsInFrame * analysis->numPartitions * 3;<br>
     else if (analysis->sliceType == X265_TYPE_P)<br>
+    {<br>
         analysis->frameRecordSize += sizeof(analysis_inter_data) * analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU;<br>
+        analysis->frameRecordSize += sizeof(uint8_t) * analysis->numCUsInFrame * analysis->numPartitions * 2;<br>
+    }<br>
     else<br>
+    {<br>
         analysis->frameRecordSize += sizeof(analysis_inter_data) * analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * 2;<br>
+        analysis->frameRecordSize += sizeof(uint8_t) * analysis->numCUsInFrame * analysis->numPartitions * 2;<br>
+    }<br>
<br>
     X265_FWRITE(&analysis->frameRecordSize, sizeof(uint32_t), 1, m_analysisFile);<br>
     X265_FWRITE(&analysis->poc, sizeof(int), 1, m_analysisFile);<br>
@@ -1687,10 +1697,14 @@<br>
     else if (analysis->sliceType == X265_TYPE_P)<br>
     {<br>
         X265_FWRITE(analysis->interData, sizeof(analysis_inter_data), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU, m_analysisFile);<br>
+        X265_FWRITE(((analysis_intra_data*)analysis->intraData)->depth, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);<br>
+        X265_FWRITE(((analysis_intra_data*)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);<br>
     }<br>
     else<br>
     {<br>
         X265_FWRITE(analysis->interData, sizeof(analysis_inter_data), analysis->numCUsInFrame * X265_MAX_PRED_MODE_PER_CTU * 2, m_analysisFile);<br>
+        X265_FWRITE(((analysis_intra_data*)analysis->intraData)->depth, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);<br>
+        X265_FWRITE(((analysis_intra_data*)analysis->intraData)->modes, sizeof(uint8_t), analysis->numCUsInFrame * analysis->numPartitions, m_analysisFile);<br>
     }<br>
 #undef X265_FWRITE<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" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div><br></div></div>