[x265] [PATCH 2 of 5] Influence depth decisions based on CTUInfo recieved through API

vignesh at multicorewareinc.com vignesh at multicorewareinc.com
Tue May 9 10:44:13 CEST 2017


# HG changeset patch
# User Vignesh Vijayakumar
# Date 1491887898 -19800
#      Tue Apr 11 10:48:18 2017 +0530
# Node ID cf414fc0a459dea19015ca07d130e1234890541a
# Parent  b5f7b13bf089d09bba8c121e11bdfce824f42e64
Influence depth decisions based on CTUInfo recieved through API

diff -r b5f7b13bf089 -r cf414fc0a459 source/common/frame.cpp
--- a/source/common/frame.cpp	Mon Apr 24 10:13:57 2017 +0530
+++ b/source/common/frame.cpp	Tue Apr 11 10:48:18 2017 +0530
@@ -50,6 +50,8 @@
     m_reconfigureRc = false;
     m_ctuInfo = NULL;
     m_prevCtuInfoChange = NULL;
+    m_addOnDepth = NULL;
+    m_addOnCtuInfo = NULL;
 }
 
 bool Frame::create(x265_param *param, float* quantOffsets)
@@ -58,6 +60,20 @@
     m_param = param;
     CHECKED_MALLOC_ZERO(m_rcData, RcStats, 1);
 
+    if (param->bCTUInfo)
+    {
+        uint32_t widthInCTU = (m_param->sourceWidth + g_maxCUSize - 1) >> g_maxLog2CUSize;
+        uint32_t heightInCTU = (m_param->sourceHeight + g_maxCUSize - 1) >> g_maxLog2CUSize;
+        uint32_t numCTUsInFrame = widthInCTU * heightInCTU;
+        CHECKED_MALLOC_ZERO(m_addOnDepth, uint8_t *, numCTUsInFrame);
+        CHECKED_MALLOC_ZERO(m_addOnCtuInfo, uint8_t *, numCTUsInFrame);
+        for (uint32_t i = 0; i < numCTUsInFrame; i++)
+        {
+            CHECKED_MALLOC_ZERO(m_addOnDepth[i], uint8_t, uint32_t(NUM_4x4_PARTITIONS));
+            CHECKED_MALLOC_ZERO(m_addOnCtuInfo[i], uint8_t, uint32_t(NUM_4x4_PARTITIONS));
+        }
+    }
+
     if (m_fencPic->create(param->sourceWidth, param->sourceHeight, param->internalCsp) &&
         m_lowres.create(m_fencPic, param->bframes, !!param->rc.aqMode || !!param->bAQMotion, param->rc.qgSize))
     {
@@ -177,6 +193,10 @@
         {
             X265_FREE((*m_ctuInfo + i)->ctuInfo);
             (*m_ctuInfo + i)->ctuInfo = NULL;
+            X265_FREE(m_addOnDepth[i]);
+            m_addOnDepth[i] = NULL;
+            X265_FREE(m_addOnCtuInfo[i]);
+            m_addOnCtuInfo[i] = NULL;
         }
         X265_FREE(*m_ctuInfo);
         *m_ctuInfo = NULL;
@@ -184,6 +204,11 @@
         m_ctuInfo = NULL;
         X265_FREE(m_prevCtuInfoChange);
         m_prevCtuInfoChange = NULL;
+        X265_FREE(m_addOnDepth);
+        m_addOnDepth = NULL;
+        X265_FREE(m_addOnCtuInfo);
+        m_addOnCtuInfo = NULL;
+
     }
     m_lowres.destroy();
     X265_FREE(m_rcData);
diff -r b5f7b13bf089 -r cf414fc0a459 source/common/frame.h
--- a/source/common/frame.h	Mon Apr 24 10:13:57 2017 +0530
+++ b/source/common/frame.h	Tue Apr 11 10:48:18 2017 +0530
@@ -112,6 +112,9 @@
     int*                   m_prevCtuInfoChange;
 
     int64_t                m_encodeStartTime;
+
+    uint8_t**              m_addOnDepth;
+    uint8_t**              m_addOnCtuInfo;
     Frame();
 
     bool create(x265_param *param, float* quantOffsets);
diff -r b5f7b13bf089 -r cf414fc0a459 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp	Mon Apr 24 10:13:57 2017 +0530
+++ b/source/encoder/analysis.cpp	Tue Apr 11 10:48:18 2017 +0530
@@ -150,6 +150,33 @@
         calculateNormFactor(ctu, qp);
 
     uint32_t numPartition = ctu.m_numPartitions;
+    if (m_param->bCTUInfo && (*m_frame->m_ctuInfo + ctu.m_cuAddr))
+    {
+        x265_ctu_info_t* ctuTemp = *m_frame->m_ctuInfo + ctu.m_cuAddr;
+        if (ctuTemp->ctuPartitions)
+        {
+            int32_t depthIdx = 0;
+            uint8_t* depthInfoPtr = m_frame->m_addOnDepth[ctu.m_cuAddr];
+            uint8_t* contentInfoPtr = m_frame->m_addOnCtuInfo[ctu.m_cuAddr];
+            do
+            {
+                uint8_t depth = (uint8_t)ctuTemp->ctuPartitions[depthIdx];
+                uint8_t content = (uint8_t)(*((int32_t *)ctuTemp->ctuInfo + depthIdx));
+                memset(depthInfoPtr, depth, sizeof(uint8_t) * numPartition >> 2 * depth);
+                memset(contentInfoPtr, content, sizeof(uint8_t) * numPartition >> 2 * depth);
+                depthInfoPtr += ctu.m_numPartitions >> 2 * depth;
+                contentInfoPtr += ctu.m_numPartitions >> 2 * depth;
+                depthIdx++;
+            } while (ctuTemp->ctuPartitions[depthIdx] != 0);
+
+            m_additionalCtuInfo = m_frame->m_addOnCtuInfo[ctu.m_cuAddr];
+            memcpy(ctu.m_cuDepth, m_frame->m_addOnDepth[ctu.m_cuAddr], sizeof(uint8_t) * numPartition);
+            //Calculate log2CUSize from depth
+            for (uint32_t i = 0; i < cuGeom.numPartitions; i++)
+                ctu.m_log2CUSize[i] = (uint8_t)g_maxLog2CUSize - ctu.m_cuDepth[i];
+        }
+    }
+
     if (m_param->analysisMultiPassRefine && m_param->rc.bStatRead)
     {
         m_multipassAnalysis = (analysis2PassFrameData*)m_frame->m_analysis2Pass.analysisFramedata;
@@ -1017,11 +1044,13 @@
     bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
     bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
     uint32_t minDepth = topSkipMinDepth(parentCTU, cuGeom);
+    bool bDecidedDepth = parentCTU.m_cuDepth[cuGeom.absPartIdx] == depth;
     bool skipModes = false; /* Skip any remaining mode analyses at current depth */
     bool skipRecursion = false; /* Skip recursion */
     bool splitIntra = true;
     bool skipRectAmp = false;
     bool chooseMerge = false;
+    bool bCtuInfoCheck = false;
 
     if ((m_limitTU & X265_TU_LIMIT_NEIGH) && cuGeom.log2CUSize >= 4)
         m_maxTUDepth = loadTUDepth(cuGeom, parentCTU);
@@ -1040,6 +1069,26 @@
         md.pred[PRED_2Nx2N].sa8dCost = 0;
     }
 
+    if (m_param->bCTUInfo && depth <= parentCTU.m_cuDepth[cuGeom.absPartIdx])
+    {
+        if (depth < parentCTU.m_cuDepth[cuGeom.absPartIdx])
+        {
+            mightNotSplit &= bDecidedDepth;
+            bCtuInfoCheck = skipRecursion = false;
+            skipModes = true;
+        }
+        else if (mightNotSplit && bDecidedDepth)
+        {
+            if (m_additionalCtuInfo[cuGeom.absPartIdx])
+                bCtuInfoCheck = skipRecursion = true;
+            mightSplit &= !bDecidedDepth;
+            md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
+            md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
+            checkMerge2Nx2N_rd0_4(md.pred[PRED_SKIP], md.pred[PRED_MERGE], cuGeom);
+            if (m_param->rdLevel)
+                skipModes = m_param->bEnableEarlySkip && md.bestMode && md.bestMode->cu.isSkipped(0);
+        }
+    }
     if (m_param->analysisMode == X265_ANALYSIS_LOAD && m_param->analysisRefineLevel > 1)
     {
         if (mightNotSplit && depth == m_reuseDepth[cuGeom.absPartIdx])
@@ -1082,7 +1131,7 @@
     }
 
     /* Step 1. Evaluate Merge/Skip candidates for likely early-outs, if skip mode was not set above */
-    if (mightNotSplit && depth >= minDepth && !md.bestMode) /* TODO: Re-evaluate if analysis load/save still works */
+    if (mightNotSplit && depth >= minDepth && !md.bestMode && !bCtuInfoCheck) /* TODO: Re-evaluate if analysis load/save still works */
     {
         /* Compute Merge Cost */
         md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
@@ -1092,7 +1141,7 @@
             skipModes = m_param->bEnableEarlySkip && md.bestMode && md.bestMode->cu.isSkipped(0); // TODO: sa8d threshold per depth
     }
 
-    if (md.bestMode && m_param->bEnableRecursionSkip)
+    if (md.bestMode && m_param->bEnableRecursionSkip && !bCtuInfoCheck)
     {
         skipRecursion = md.bestMode->cu.isSkipped(0);
         if (mightSplit && depth >= minDepth && !skipRecursion)
@@ -1584,10 +1633,12 @@
 
     bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);
     bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);
+    bool bDecidedDepth = parentCTU.m_cuDepth[cuGeom.absPartIdx] == depth;
     bool skipRecursion = false;
     bool skipModes = false;
     bool splitIntra = true;
     bool skipRectAmp = false;
+    bool bCtuInfoCheck = false;
 
     // avoid uninitialize value in below reference
     if (m_param->limitModes)
@@ -1607,6 +1658,29 @@
     splitData[3].initSplitCUData();
     uint32_t allSplitRefs = splitData[0].splitRefs | splitData[1].splitRefs | splitData[2].splitRefs | splitData[3].splitRefs;
     uint32_t refMasks[2];
+    if (m_param->bCTUInfo && depth <= parentCTU.m_cuDepth[cuGeom.absPartIdx])
+    {
+        if (depth < parentCTU.m_cuDepth[cuGeom.absPartIdx])
+        {
+            mightNotSplit &= bDecidedDepth;
+            bCtuInfoCheck = skipRecursion = false;
+            skipModes = true;
+        }
+        else if (mightNotSplit && bDecidedDepth)
+        {
+            if (m_additionalCtuInfo[cuGeom.absPartIdx])
+                bCtuInfoCheck = skipRecursion = true;
+            mightSplit &= !bDecidedDepth;
+            md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
+            md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
+            checkMerge2Nx2N_rd5_6(md.pred[PRED_SKIP], md.pred[PRED_MERGE], cuGeom);
+            skipModes = !!m_param->bEnableEarlySkip && md.bestMode;
+            refMasks[0] = allSplitRefs;
+            md.pred[PRED_2Nx2N].cu.initSubCU(parentCTU, cuGeom, qp);
+            checkInter_rd5_6(md.pred[PRED_2Nx2N], cuGeom, SIZE_2Nx2N, refMasks);
+            checkBestMode(md.pred[PRED_2Nx2N], cuGeom.depth);
+        }
+    }
     if (m_param->analysisMode == X265_ANALYSIS_LOAD && m_param->analysisRefineLevel > 1)
     {
         if (mightNotSplit && depth == m_reuseDepth[cuGeom.absPartIdx])
@@ -1653,7 +1727,7 @@
     }
 
     /* Step 1. Evaluate Merge/Skip candidates for likely early-outs */
-    if (mightNotSplit && !md.bestMode)
+    if (mightNotSplit && !md.bestMode && !bCtuInfoCheck)
     {
         md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
         md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
diff -r b5f7b13bf089 -r cf414fc0a459 source/encoder/analysis.h
--- a/source/encoder/analysis.h	Mon Apr 24 10:13:57 2017 +0530
+++ b/source/encoder/analysis.h	Tue Apr 11 10:48:18 2017 +0530
@@ -137,6 +137,8 @@
     int*                    m_multipassMvpIdx[2];
     int32_t*                m_multipassRef[2];
     uint8_t*                m_multipassModes;
+
+    uint8_t*                m_additionalCtuInfo;
     /* refine RD based on QP for rd-levels 5 and 6 */
     void qprdRefine(const CUData& parentCTU, const CUGeom& cuGeom, int32_t qp, int32_t lqp);
 


More information about the x265-devel mailing list