[x265] [PATCH] rd: determine CU complexity to skip analysis of higher depths

Kavitha Sampath kavitha at multicorewareinc.com
Mon Jun 13 13:14:02 CEST 2016


# HG changeset patch
# User Kavitha Sampath <kavitha at multicorewareinc.com>
# Date 1465814710 -19800
#      Mon Jun 13 16:15:10 2016 +0530
# Node ID d9a7d21cb17918f869f0ff3407dec764880827d4
# Parent  106a5a7dc4b337121c11484bc3bc4900b8a0d9a4
rd: determine CU complexity to skip analysis of higher depths

Complexity check is performed for RD level 2 of 4K videos

diff -r 106a5a7dc4b3 -r d9a7d21cb179 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp Thu Jun 09 13:34:55 2016 -0500
+++ b/source/encoder/analysis.cpp Mon Jun 13 16:15:10 2016 +0530
@@ -74,6 +74,7 @@
 {
     m_reuseInterDataCTU = NULL;
     m_reuseRef = NULL;
+    m_is4k = false;
 }
 bool Analysis::create(ThreadLocalData *tld)
 {
@@ -105,6 +106,8 @@
             md.pred[j].fencYuv = &md.fencYuv;
         }
     }
+    if (m_param->sourceWidth >= 3840)
+        m_is4k = true;

     return ok;
 }
@@ -944,8 +947,13 @@
     if (md.bestMode && m_param->bEnableRecursionSkip)
     {
         skipRecursion = md.bestMode->cu.isSkipped(0);
-        if (mightSplit && depth && depth >= minDepth && !skipRecursion)
-            skipRecursion = recursionDepthCheck(parentCTU, cuGeom,
*md.bestMode);
+        if (mightSplit && depth >= minDepth && !skipRecursion)
+        {
+            if (depth)
+                skipRecursion = recursionDepthCheck(parentCTU, cuGeom,
*md.bestMode);
+            if (m_is4k && !skipRecursion && m_param->rdLevel == 2 &&
md.fencYuv.m_size != MAX_CU_SIZE)
+                skipRecursion = complexityCheckCU(*md.bestMode);
+        }
     }

     /* Step 2. Evaluate each of the 4 split sub-blocks in series */
@@ -2593,6 +2601,30 @@
     return false;
 }

+bool Analysis::complexityCheckCU(const Mode& bestMode)
+{
+    uint32_t mean = 0;
+    uint32_t homo = 0;
+    uint32_t cuSize = bestMode.fencYuv->m_size;
+    for (uint32_t y = 0; y < cuSize; y++) {
+        for (uint32_t x = 0; x < cuSize; x++) {
+            mean += (bestMode.fencYuv->m_buf[0][y * cuSize + x]);
+        }
+    }
+    mean = mean / (cuSize * cuSize);
+    for (uint32_t y = 0 ; y < cuSize; y++){
+        for (uint32_t x = 0 ; x < cuSize; x++){
+            homo += abs(int(bestMode.fencYuv->m_buf[0][y * cuSize + x] -
mean));
+        }
+    }
+    homo = homo / (cuSize * cuSize);
+
+    if (homo < (.1 * mean))
+        return true;
+
+    return false;
+}
+
 int Analysis::calculateQpforCuSize(const CUData& ctu, const CUGeom&
cuGeom, double baseQp)
 {
     FrameData& curEncData = *m_frame->m_encData;
diff -r 106a5a7dc4b3 -r d9a7d21cb179 source/encoder/analysis.h
--- a/source/encoder/analysis.h Thu Jun 09 13:34:55 2016 -0500
+++ b/source/encoder/analysis.h Mon Jun 13 16:15:10 2016 +0530
@@ -108,6 +108,7 @@
     ModeDepth m_modeDepth[NUM_CU_DEPTH];
     bool      m_bTryLossless;
     bool      m_bChromaSa8d;
+    bool      m_is4k;

     Analysis();

@@ -160,6 +161,7 @@
     /* work-avoidance heuristics for RD levels < 5 */
     uint32_t topSkipMinDepth(const CUData& parentCTU, const CUGeom&
cuGeom);
     bool recursionDepthCheck(const CUData& parentCTU, const CUGeom&
cuGeom, const Mode& bestMode);
+    bool complexityCheckCU(const Mode& bestMode);

     /* generate residual and recon pixels for an entire CTU recursively
(RD0) */
     void encodeResidue(const CUData& parentCTU, const CUGeom& cuGeom);


On Mon, Jun 13, 2016 at 3:50 PM, Kavitha Sampath <
kavitha at multicorewareinc.com> wrote:

> yes I can make that a member of Analysis
> I will make the change and send the updated patch
>
> On Mon, Jun 13, 2016 at 12:28 PM, Deepthi Nandakumar <
> deepthi at multicorewareinc.com> wrote:
>
>> Kavitha,
>>
>> Is there a need to introduce another global variable - can't we just keep
>> a local one here, or one in Analysis?
>>
>> Deepthi
>>
>> On Thu, Jun 9, 2016 at 12:07 PM, <kavitha at multicorewareinc.com> wrote:
>>
>>> # HG changeset patch
>>> # User Kavitha Sampath <kavitha at multicorewareinc.com>
>>> # Date 1463588688 25200
>>> #      Wed May 18 09:24:48 2016 -0700
>>> # Node ID 4baa78c17dca00c3d2f8a1c4d5e0ae87d7463f05
>>> # Parent  0af296185f7ae3e05493ecf164046ddfec085bb3
>>> rd: determine CU complexity to skip analysis of higher depths
>>>
>>> Complexity check is performed for RD level 2 of 4K videos
>>>
>>> diff -r 0af296185f7a -r 4baa78c17dca source/common/constants.cpp
>>> --- a/source/common/constants.cpp       Tue Jun 07 09:20:11 2016 +0530
>>> +++ b/source/common/constants.cpp       Wed May 18 09:24:48 2016 -0700
>>> @@ -161,6 +161,7 @@
>>>      65535
>>>  };
>>>
>>> +bool     g_is4k = false;
>>>  int      g_ctuSizeConfigured = 0;
>>>  uint32_t g_maxLog2CUSize = MAX_LOG2_CU_SIZE;
>>>  uint32_t g_maxCUSize     = MAX_CU_SIZE;
>>> diff -r 0af296185f7a -r 4baa78c17dca source/common/constants.h
>>> --- a/source/common/constants.h Tue Jun 07 09:20:11 2016 +0530
>>> +++ b/source/common/constants.h Wed May 18 09:24:48 2016 -0700
>>> @@ -31,6 +31,7 @@
>>>  // private namespace
>>>
>>>  extern int g_ctuSizeConfigured;
>>> +extern bool g_is4k;
>>>
>>>  void initZscanToRaster(uint32_t maxFullDepth, uint32_t depth, uint32_t
>>> startVal, uint32_t*& curIdx);
>>>  void initRasterToZscan(uint32_t maxFullDepth);
>>> diff -r 0af296185f7a -r 4baa78c17dca source/common/param.cpp
>>> --- a/source/common/param.cpp   Tue Jun 07 09:20:11 2016 +0530
>>> +++ b/source/common/param.cpp   Wed May 18 09:24:48 2016 -0700
>>> @@ -1265,6 +1265,9 @@
>>>          initZscanToRaster(g_unitSizeDepth, 1, 0, tmp);
>>>          initRasterToZscan(g_unitSizeDepth);
>>>      }
>>> +    if (param->sourceWidth >= 3840)
>>> +        g_is4k = true;
>>> +
>>>      return 0;
>>>  }
>>>
>>> diff -r 0af296185f7a -r 4baa78c17dca source/encoder/analysis.cpp
>>> --- a/source/encoder/analysis.cpp       Tue Jun 07 09:20:11 2016 +0530
>>> +++ b/source/encoder/analysis.cpp       Wed May 18 09:24:48 2016 -0700
>>> @@ -944,8 +944,13 @@
>>>      if (md.bestMode && m_param->bEnableRecursionSkip)
>>>      {
>>>          skipRecursion = md.bestMode->cu.isSkipped(0);
>>> -        if (mightSplit && depth && depth >= minDepth && !skipRecursion)
>>> -            skipRecursion = recursionDepthCheck(parentCTU, cuGeom,
>>> *md.bestMode);
>>> +        if (mightSplit && depth >= minDepth && !skipRecursion)
>>> +        {
>>> +            if (depth)
>>> +                skipRecursion = recursionDepthCheck(parentCTU, cuGeom,
>>> *md.bestMode);
>>> +            if (g_is4k && !skipRecursion && m_param->rdLevel == 2 &&
>>> md.fencYuv.m_size != MAX_CU_SIZE)
>>> +                skipRecursion = complexityCheckCU(*md.bestMode);
>>> +        }
>>>      }
>>>
>>>      /* Step 2. Evaluate each of the 4 split sub-blocks in series */
>>> @@ -2593,6 +2598,30 @@
>>>      return false;
>>>  }
>>>
>>> +bool Analysis::complexityCheckCU(const Mode& bestMode)
>>> +{
>>> +    uint32_t mean = 0;
>>> +    uint32_t homo = 0;
>>> +    uint32_t cuSize = bestMode.fencYuv->m_size;
>>> +    for (uint32_t y = 0; y < cuSize; y++) {
>>> +        for (uint32_t x = 0; x < cuSize; x++) {
>>> +            mean += (bestMode.fencYuv->m_buf[0][y * cuSize + x]);
>>> +        }
>>> +    }
>>> +    mean = mean / (cuSize * cuSize);
>>> +    for (uint32_t y = 0 ; y < cuSize; y++){
>>> +        for (uint32_t x = 0 ; x < cuSize; x++){
>>> +            homo += abs(int(bestMode.fencYuv->m_buf[0][y * cuSize + x]
>>> - mean));
>>> +        }
>>> +    }
>>> +    homo = homo / (cuSize * cuSize);
>>> +
>>> +    if (homo < (.1 * mean))
>>> +        return true;
>>> +
>>> +    return false;
>>> +}
>>> +
>>>  int Analysis::calculateQpforCuSize(const CUData& ctu, const CUGeom&
>>> cuGeom, double baseQp)
>>>  {
>>>      FrameData& curEncData = *m_frame->m_encData;
>>> diff -r 0af296185f7a -r 4baa78c17dca source/encoder/analysis.h
>>> --- a/source/encoder/analysis.h Tue Jun 07 09:20:11 2016 +0530
>>> +++ b/source/encoder/analysis.h Wed May 18 09:24:48 2016 -0700
>>> @@ -160,6 +160,7 @@
>>>      /* work-avoidance heuristics for RD levels < 5 */
>>>      uint32_t topSkipMinDepth(const CUData& parentCTU, const CUGeom&
>>> cuGeom);
>>>      bool recursionDepthCheck(const CUData& parentCTU, const CUGeom&
>>> cuGeom, const Mode& bestMode);
>>> +    bool complexityCheckCU(const Mode& bestMode);
>>>
>>>      /* generate residual and recon pixels for an entire CTU recursively
>>> (RD0) */
>>>      void encodeResidue(const CUData& parentCTU, const CUGeom& cuGeom);
>>> _______________________________________________
>>> x265-devel mailing list
>>> x265-devel at videolan.org
>>> https://mailman.videolan.org/listinfo/x265-devel
>>>
>>
>>
>>
>> --
>> Deepthi Nandakumar
>> Engineering Manager, x265
>> Multicoreware, Inc
>>
>> _______________________________________________
>> x265-devel mailing list
>> x265-devel at videolan.org
>> https://mailman.videolan.org/listinfo/x265-devel
>>
>>
>
>
> --
> Regards,
> Kavitha
>



-- 
Regards,
Kavitha
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20160613/b966a4d2/attachment-0001.html>


More information about the x265-devel mailing list