<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, May 9, 2017 at 2:14 PM,  <span dir="ltr"><<a href="mailto:vignesh@multicorewareinc.com" target="_blank">vignesh@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 Santhoshini Sekar<br>
# Date 1493009037 -19800<br>
#      Mon Apr 24 10:13:57 2017 +0530<br>
# Node ID b5f7b13bf089d09bba8c121e11bdfc<wbr>e824f42e64<br>
# Parent  7ecd263f6d43966df308d53029a67c<wbr>fda03bb185<br>
Add API to read CTU Information<br>
<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 doc/reST/api.rst<br>
--- a/doc/reST/api.rst  Tue May 09 12:43:04 2017 +0530<br>
+++ b/doc/reST/api.rst  Mon Apr 24 10:13:57 2017 +0530<br>
@@ -193,6 +193,13 @@<br>
         *      parameters to take this into account. */<br>
        int x265_encoder_reconfig(x265_<wbr>encoder *, x265_param *);<br>
<br>
+**x265_encoder_ctu_info**<br>
+       /* x265_encoder_ctu_info:<br>
+        *    Copy CTU information such as ctu address and ctu partition structure of all<br>
+        *    CTUs in each frame. The function is invoked only if "--ctu-info" is enabled and<br>
+        *    the encoder will wait for this copy to complete if enabled.<br>
+        */<br>
+<br>
 Pictures<br>
 ========<br>
<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/common/frame.cpp<br>
--- a/source/common/frame.cpp   Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/common/frame.cpp   Mon Apr 24 10:13:57 2017 +0530<br>
@@ -48,6 +48,8 @@<br>
     m_rcData = NULL;<br>
     m_encodeStartTime = 0;<br>
     m_reconfigureRc = false;<br>
+    m_ctuInfo = NULL;<br>
+    m_prevCtuInfoChange = NULL;<br>
 }<br>
<br>
 bool Frame::create(x265_param *param, float* quantOffsets)<br>
@@ -166,6 +168,23 @@<br>
         delete[] m_userSEI.payloads;<br>
     }<br>
<br>
+    if (m_ctuInfo)<br>
+    {<br>
+        uint32_t widthInCU = (m_param->sourceWidth + g_maxCUSize - 1) >> g_maxLog2CUSize;<br>
+        uint32_t heightInCU = (m_param->sourceHeight + g_maxCUSize - 1) >> g_maxLog2CUSize;<br>
+        uint32_t numCUsInFrame = widthInCU * heightInCU;<br>
+        for (uint32_t i = 0; i < numCUsInFrame; i++)<br>
+        {<br>
+            X265_FREE((*m_ctuInfo + i)->ctuInfo);<br>
+            (*m_ctuInfo + i)->ctuInfo = NULL;<br>
+        }<br>
+        X265_FREE(*m_ctuInfo);<br>
+        *m_ctuInfo = NULL;<br>
+        X265_FREE(m_ctuInfo);<br>
+        m_ctuInfo = NULL;<br>
+        X265_FREE(m_prevCtuInfoChange)<wbr>;<br>
+        m_prevCtuInfoChange = NULL;<br>
+    }<br>
     m_lowres.destroy();<br>
     X265_FREE(m_rcData);<br>
 }<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/common/frame.h<br>
--- a/source/common/frame.h     Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/common/frame.h     Mon Apr 24 10:13:57 2017 +0530<br>
@@ -107,6 +107,9 @@<br>
     x265_analysis_data     m_analysisData;<br>
     x265_analysis_2Pass    m_analysis2Pass;<br>
     RcStats*               m_rcData;<br>
+    x265_ctu_info_t**      m_ctuInfo;<br>
+    Event                  m_copied;<br>
+    int*                   m_prevCtuInfoChange;<br>
<br>
     int64_t                m_encodeStartTime;<br>
     Frame();<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/common/param.cpp<br>
--- a/source/common/param.cpp   Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/common/param.cpp   Mon Apr 24 10:13:57 2017 +0530<br>
@@ -275,6 +275,7 @@<br>
<br>
     param->toneMapFile = NULL;<br>
     param->bDhdr10opt = 0;<br>
+    param->bCTUInfo = 0;<br>
 }<br>
<br>
 int x265_param_default_preset(<wbr>x265_param* param, const char* preset, const char* tune)<br>
@@ -954,6 +955,7 @@<br>
         OPT("limit-sao") p->bLimitSAO = atobool(value);<br>
         OPT("dhdr10-info") p->toneMapFile = strdup(value);<br>
         OPT("dhdr10-opt") p->bDhdr10opt = atobool(value);<br>
+        OPT("ctu-info") p->bCTUInfo = atoi(value);<br>
         else<br>
             return X265_PARAM_BAD_NAME;<br>
     }<br>
@@ -1457,6 +1459,7 @@<br>
     TOOLOPT(param-><wbr>bEnableStrongIntraSmoothing, "strong-intra-smoothing");<br>
     TOOLVAL(param-><wbr>lookaheadSlices, "lslices=%d");<br>
     TOOLVAL(param-><wbr>lookaheadThreads, "lthreads=%d")<br>
+    TOOLVAL(param->bCTUInfo, "ctu-info=%d");<br>
     if (param->maxSlices > 1)<br>
         TOOLVAL(param->maxSlices, "slices=%d");<br>
     if (param->bEnableLoopFilter)<br>
@@ -1670,6 +1673,7 @@<br>
     BOOL(p->bDhdr10opt, "dhdr10-opt");<br>
     s += sprintf(s, " refine-level=%d", p->analysisRefineLevel);<br>
     BOOL(p->bLimitSAO, "limit-sao");<br>
+    s += sprintf(s, " ctu-info=%d", p->bCTUInfo);<br>
 #undef BOOL<br>
     return buf;<br>
 }<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/api.cpp<br>
--- a/source/encoder/api.cpp    Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/encoder/api.cpp    Mon Apr 24 10:13:57 2017 +0530<br>
@@ -296,6 +296,15 @@<br>
     return 0;<br>
 }<br>
<br>
+int x265_encoder_ctu_info(x265_<wbr>encoder *enc, int poc, x265_ctu_info_t** ctu)<br>
+{<br>
+    if (!ctu || !enc)<br>
+        return -1;<br>
+    Encoder* encoder = static_cast<Encoder*>(enc);<br>
+    encoder->copyCtuInfo(ctu, poc);<br>
+    return 0;<br>
+}<br>
+<br>
 void x265_cleanup(void)<br>
 {<br>
     if (!g_ctuSizeConfigured)<br>
@@ -372,6 +381,7 @@<br>
<br>
     sizeof(x265_frame_stats),<br>
     &x265_encoder_intra_refresh,<br>
+    &x265_encoder_ctu_info,<br>
 };<br>
<br></blockquote><div><br></div><div>Since api is now changing, the BUILD_NUMBER in CMakeLists.txt should be incremented.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
 typedef const x265_api* (*api_get_func)(int bitDepth);<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/dpb.cpp<br>
--- a/source/encoder/dpb.cpp    Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/encoder/dpb.cpp    Mon Apr 24 10:13:57 2017 +0530<br>
@@ -105,6 +105,23 @@<br>
                 }<br>
             }<br>
<br>
+            if (curFrame->m_ctuInfo != NULL)<br>
+            {<br>
+                uint32_t widthInCU = (curFrame->m_param-><wbr>sourceWidth + g_maxCUSize - 1) >> g_maxLog2CUSize;<br>
+                uint32_t heightInCU = (curFrame->m_param-><wbr>sourceHeight + g_maxCUSize - 1) >> g_maxLog2CUSize;<br>
+                uint32_t numCUsInFrame = widthInCU * heightInCU;<br>
+                for (uint32_t i = 0; i < numCUsInFrame; i++)<br>
+                {<br>
+                    X265_FREE((*curFrame->m_<wbr>ctuInfo + i)->ctuInfo);<br>
+                    (*curFrame->m_ctuInfo + i)->ctuInfo = NULL;<br>
+                }<br>
+                X265_FREE(*curFrame->m_<wbr>ctuInfo);<br>
+                *(curFrame->m_ctuInfo) = NULL;<br>
+                X265_FREE(curFrame->m_ctuInfo)<wbr>;<br>
+                curFrame->m_ctuInfo = NULL;<br>
+                X265_FREE(curFrame->m_<wbr>prevCtuInfoChange);<br>
+                curFrame->m_prevCtuInfoChange = NULL;<br>
+            }<br>
             curFrame->m_encData = NULL;<br>
             curFrame->m_reconPic = NULL;<br>
         }<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp        Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/encoder/encoder.cpp        Mon Apr 24 10:13:57 2017 +0530<br>
@@ -1157,6 +1157,120 @@<br>
     return x265_check_params(encParam);<br>
 }<br>
<br>
+void Encoder::copyCtuInfo(x265_ctu_<wbr>info_t** frameCtuInfo, int poc)<br>
+{<br>
+    uint32_t widthInCU = (m_param->sourceWidth + g_maxCUSize - 1) >> g_maxLog2CUSize;<br>
+    uint32_t heightInCU = (m_param->sourceHeight + g_maxCUSize - 1) >> g_maxLog2CUSize;<br>
+    Frame* curFrame;<br>
+    Frame* prevFrame = NULL;<br>
+    int32_t* frameCTU;<br>
+    uint32_t numCUsInFrame = widthInCU * heightInCU;<br>
+    uint32_t maxNum8x8Partitions = 64;<br>
+    bool copied = false;<br>
+    do<br>
+    {<br>
+        curFrame = m_lookahead->m_inputQueue.<wbr>getPOC(poc);<br>
+        if (!curFrame)<br>
+            curFrame = m_lookahead->m_outputQueue.<wbr>getPOC(poc);<br>
+<br>
+        if (poc > 0)<br>
+        {<br>
+            prevFrame = m_lookahead->m_inputQueue.<wbr>getPOC(poc - 1);<br>
+            if (!prevFrame)<br>
+                prevFrame = m_lookahead->m_outputQueue.<wbr>getPOC(poc - 1);<br>
+            if (!prevFrame)<br>
+            {<br>
+                FrameEncoder* prevEncoder;<br>
+                for (int i = 0; i < m_param->frameNumThreads; i++)<br>
+                {<br>
+                    prevEncoder = m_frameEncoder[i];<br>
+                    prevFrame = prevEncoder->m_frame;<br>
+                    if (prevFrame && (prevEncoder->m_frame->m_poc == poc - 1))<br>
+                    {<br>
+                        prevFrame = prevEncoder->m_frame;<br>
+                        break;<br>
+                    }<br>
+                }<br>
+            }<br>
+        }<br>
+        x265_ctu_info_t* ctuTemp, *prevCtuTemp;<br>
+        if (curFrame)<br>
+        {<br>
+            if (!curFrame->m_ctuInfo)<br>
+                CHECKED_MALLOC(curFrame->m_<wbr>ctuInfo, x265_ctu_info_t*, 1);<br>
+            CHECKED_MALLOC(*curFrame->m_<wbr>ctuInfo, x265_ctu_info_t, numCUsInFrame);<br>
+            CHECKED_MALLOC_ZERO(curFrame-><wbr>m_prevCtuInfoChange, int, numCUsInFrame * maxNum8x8Partitions);<br>
+            for (uint32_t i = 0; i < numCUsInFrame; i++)<br>
+            {<br>
+                ctuTemp = *curFrame->m_ctuInfo + i;<br>
+                CHECKED_MALLOC(frameCTU, int32_t, maxNum8x8Partitions);<br>
+                ctuTemp->ctuInfo = (int32_t*)frameCTU;<br>
+                ctuTemp->ctuAddress = frameCtuInfo[i]->ctuAddress;<br>
+                memcpy(ctuTemp->ctuPartitions, frameCtuInfo[i]-><wbr>ctuPartitions, sizeof(int32_t) * maxNum8x8Partitions);<br>
+                memcpy(ctuTemp->ctuInfo, frameCtuInfo[i]->ctuInfo, sizeof(int32_t) * maxNum8x8Partitions);<br>
+                if (prevFrame && curFrame->m_poc > 1)<br>
+                {<br>
+                    prevCtuTemp = *prevFrame->m_ctuInfo + i;<br>
+                    for (uint32_t j = 0; j < maxNum8x8Partitions; j++)<br>
+                        curFrame->m_prevCtuInfoChange[<wbr>i * maxNum8x8Partitions + j] = (*((int32_t *)prevCtuTemp->ctuInfo + j) == 2) ? (poc - 1) : prevFrame->m_<wbr>prevCtuInfoChange[i * maxNum8x8Partitions + j];<br>
+                }<br>
+            }<br>
+            copied = true;<br>
+            curFrame->m_copied.trigger();<br>
+        }<br>
+        else<br>
+        {<br>
+            FrameEncoder* curEncoder;<br>
+            for (int i = 0; i < m_param->frameNumThreads; i++)<br>
+            {<br>
+                curEncoder = m_frameEncoder[i];<br>
+                curFrame = curEncoder->m_frame;<br>
+                if (curFrame)<br>
+                {<br>
+                    if (poc == curFrame->m_poc)<br>
+                    {<br>
+                        if (!curFrame->m_ctuInfo)<br>
+                            CHECKED_MALLOC(curFrame->m_<wbr>ctuInfo, x265_ctu_info_t*, 1);<br>
+                        CHECKED_MALLOC(*curFrame->m_<wbr>ctuInfo, x265_ctu_info_t, numCUsInFrame);<br>
+                        CHECKED_MALLOC_ZERO(curFrame-><wbr>m_prevCtuInfoChange, int, numCUsInFrame * maxNum8x8Partitions);<br>
+                        for (uint32_t l = 0; l < numCUsInFrame; l++)<br>
+                        {<br>
+                            ctuTemp = *curFrame->m_ctuInfo + l;<br>
+                            CHECKED_MALLOC(frameCTU, int32_t, maxNum8x8Partitions);<br>
+                            ctuTemp->ctuInfo = (int32_t*)frameCTU;<br>
+                            ctuTemp->ctuAddress = frameCtuInfo[l]->ctuAddress;<br>
+                            memcpy(ctuTemp->ctuPartitions, frameCtuInfo[l]-><wbr>ctuPartitions, sizeof(int32_t) * maxNum8x8Partitions);<br>
+                            memcpy(ctuTemp->ctuInfo, frameCtuInfo[l]->ctuInfo, sizeof(int32_t) * maxNum8x8Partitions);<br>
+                            if (prevFrame && curFrame->m_poc > 1)<br>
+                            {<br>
+                                prevCtuTemp = *prevFrame->m_ctuInfo + l;<br>
+                                for (uint32_t j = 0; j < maxNum8x8Partitions; j++)<br>
+                                    curFrame->m_prevCtuInfoChange[<wbr>l * maxNum8x8Partitions + j] = (*((int32_t *)prevCtuTemp->ctuInfo + j) == CTU_INFO_CHANGE) ? (poc - 1) : prevFrame->m_<wbr>prevCtuInfoChange[l * maxNum8x8Partitions + j];<br>
+                            }<br>
+                        }<br>
+                        copied = true;<br>
+                        curFrame->m_copied.trigger();<br>
+                        break;<br>
+                    }<br>
+                }<br>
+            }<br>
+        }<br>
+    } while (!copied);<br>
+    return;<br>
+fail:<br>
+    for (uint32_t i = 0; i < numCUsInFrame; i++)<br>
+    {<br>
+        X265_FREE((*curFrame->m_<wbr>ctuInfo + i)->ctuInfo);<br>
+        (*curFrame->m_ctuInfo + i)->ctuInfo = NULL;<br>
+    }<br>
+    X265_FREE(*curFrame->m_<wbr>ctuInfo);<br>
+    *(curFrame->m_ctuInfo) = NULL;<br>
+    X265_FREE(curFrame->m_ctuInfo)<wbr>;<br>
+    curFrame->m_ctuInfo = NULL;<br>
+    X265_FREE(curFrame->m_<wbr>prevCtuInfoChange);<br>
+    curFrame->m_prevCtuInfoChange = NULL;<br>
+}<br>
+<br>
 void EncStats::addPsnr(double psnrY, double psnrU, double psnrV)<br>
 {<br>
     m_psnrSumY += psnrY;<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/encoder.h<br>
--- a/source/encoder/encoder.h  Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/encoder/encoder.h  Mon Apr 24 10:13:57 2017 +0530<br>
@@ -199,6 +199,8 @@<br>
<br>
     int reconfigureParam(x265_param* encParam, x265_param* param);<br>
<br>
+    void copyCtuInfo(x265_ctu_info_t** frameCtuInfo, int poc);<br>
+<br>
     void getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs);<br>
<br>
     void fetchStats(x265_stats* stats, size_t statsSizeBytes);<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/encoder/frameencoder.<wbr>cpp<br>
--- a/source/encoder/frameencoder.<wbr>cpp   Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/encoder/frameencoder.<wbr>cpp   Mon Apr 24 10:13:57 2017 +0530<br>
@@ -295,6 +295,11 @@<br>
<br>
     while (m_threadActive)<br>
     {<br>
+        if (m_param->bCTUInfo)<br>
+        {<br>
+            while (!m_frame->m_ctuInfo)<br>
+                m_frame->m_copied.wait();<br>
+        }<br>
         compressFrame();<br>
         m_done.trigger(); /* FrameEncoder::<wbr>getEncodedPicture() blocks for this event */<br>
         m_enable.wait();<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/x265.h<br>
--- a/source/x265.h     Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/x265.h     Mon Apr 24 10:13:57 2017 +0530<br>
@@ -161,6 +161,21 @@<br>
     double           totalFrameTime;<br>
 } x265_frame_stats;<br>
<br>
+typedef struct x265_ctu_info_t<br>
+{<br>
+    int32_t ctuAddress;<br>
+    int32_t ctuPartitions[64];<br>
+    void*    ctuInfo;<br>
+} x265_ctu_info_t;<br>
+<br>
+typedef enum<br>
+{<br>
+    NO_CTU_INFO = 0,<br>
+    HAS_CTU_INFO = 1,<br>
+    CTU_INFO_CHANGE = 2,<br>
+}CTUInfo;<br>
+<br>
+<br>
 /* Arbitrary User SEI<br>
  * Payload size is in bytes and the payload pointer must be non-NULL.<br>
  * Payload types and syntax can be found in Annex D of the H.265 Specification.<br>
@@ -1391,6 +1406,9 @@<br>
     /* Insert tone mapping information only for IDR frames and when the<br>
      * tone mapping information changes. */<br>
     int       bDhdr10opt;<br>
+<br>
+    /* Determine how x265 react to the content information recieved through the API */<br>
+    int       bCTUInfo;<br>
 } x265_param;<br>
 /* x265_param_alloc:<br>
  *  Allocates an x265_param instance. The returned param structure is not<br>
@@ -1580,6 +1598,12 @@<br>
  *      Should not be called during an x265_encoder_encode. */<br>
<br>
 int x265_encoder_intra_refresh(<wbr>x265_encoder *);<br>
+/* x265_encoder_ctu_info:<br>
+ *    Copy CTU information such as ctu address and ctu partition structure of all<br>
+ *    CTUs in each frame. The function is invoked only if "--ctu-info" is enabled and<br>
+ *    the encoder will wait for this copy to complete if enabled.<br>
+ */<br>
+int x265_encoder_ctu_info(x265_<wbr>encoder *, int poc, x265_ctu_info_t** ctu);<br>
<br>
 /* x265_cleanup:<br>
  *       release library static allocations, reset configured CTU size */<br>
@@ -1629,6 +1653,7 @@<br>
<br>
     int           sizeof_frame_stats;   /* sizeof(x265_frame_stats) */<br>
     int           (*encoder_intra_refresh)(x265_<wbr>encoder*);<br>
+    int           (*encoder_ctu_info)(x265_<wbr>encoder*, int, x265_ctu_info_t**);<br>
     /* add new pointers to the end, or increment X265_MAJOR_VERSION */<br>
 } x265_api;<br>
<br>
diff -r 7ecd263f6d43 -r b5f7b13bf089 source/x265cli.h<br>
--- a/source/x265cli.h  Tue May 09 12:43:04 2017 +0530<br>
+++ b/source/x265cli.h  Mon Apr 24 10:13:57 2017 +0530<br>
@@ -122,6 +122,7 @@<br>
     { "scenecut",       required_argument, NULL, 0 },<br>
     { "no-scenecut",          no_argument, NULL, 0 },<br>
     { "scenecut-bias",  required_argument, NULL, 0 },<br>
+    { "ctu-info",       required_argument, NULL, 0 },<br>
     { "intra-refresh",        no_argument, NULL, 0 },<br>
     { "rc-lookahead",   required_argument, NULL, 0 },<br>
     { "lookahead-slices", required_argument, NULL, 0 },<br>
@@ -367,6 +368,7 @@<br>
     H1("   --[no-]tskip-fast             Enable fast intra transform skipping. Default %s\n", OPT(param->bEnableTSkipFast));<br>
     H1("   --nr-intra <integer>          An integer value in range of 0 to 2000, which denotes strength of noise reduction in intra CUs. Default 0\n");<br>
     H1("   --nr-inter <integer>          An integer value in range of 0 to 2000, which denotes strength of noise reduction in inter CUs. Default 0\n");<br>
+    H0("   --ctu-info <integer>          Enable receiving ctu information asynchronously and determine reaction to the ctu information. Default 0\n");<br></blockquote><div><br></div><div>Need a description of what the various values of ctu-info mean. Should also add this information to cli.rst so that online docs are up-to-date.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
     H0("\nCoding tools:\n");<br>
     H0("-w/--[no-]weightp                Enable weighted prediction in P slices. Default %s\n", OPT(param-><wbr>bEnableWeightedPred));<br>
     H0("   --[no-]weightb                Enable weighted prediction in B slices. Default %s\n", OPT(param-><wbr>bEnableWeightedBiPred));<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>
</blockquote></div><br></div></div>