<div dir="ltr"><div dir="ltr">On Thu, Dec 20, 2018 at 1:52 PM Kalyan Goswami <<a href="mailto:kalyan@multicorewareinc.com">kalyan@multicorewareinc.com</a>> wrote:<br></div><div class="gmail_quote"><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">Pushed <div><br clear="all"><div><div dir="ltr" class="gmail-m_5902244584152672835gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div>Thanks,</div><div dir="ltr"><span></span><span></span>Kalyan Goswami, PhD</div><div dir="ltr"><span style="font-size:12.8px">Video Architect @ MulticoreWare</span></div><div dir="ltr"><div><a href="http://www.multicorewareinc.com/" target="_blank">http:</a><a href="http://www.multicorewareinc.com/" style="font-size:12.8px" target="_blank">//www.multicorewareinc.com</a></div><div><span style="font-size:12.8px">+91 9884989331</span><br></div><div></div></div></div></div></div></div></div></div></div></div></div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Dec 18, 2018 at 2:48 PM Aruna Matheswaran <<a href="mailto:aruna@multicorewareinc.com" target="_blank">aruna@multicorewareinc.com</a>> wrote:<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 dir="ltr"><div># HG changeset patch</div><div># User Aruna Matheswaran <<a href="mailto:aruna@multicorewareinc.com" target="_blank">aruna@multicorewareinc.com</a>></div><div># Date 1545045548 -19800</div><div>#      Mon Dec 17 16:49:08 2018 +0530</div><div># Node ID e6b3e3747035b503aa982b1cbeb2bb6a7bffa9b3</div><div># Parent  81373aab81dfe2e31a5ef353b1073d8bf1e22502</div><div>Introduce CTU distortion refinement in analysis-save/load</div><div><br></div><div>diff -r 81373aab81df -r e6b3e3747035 doc/reST/cli.rst</div><div>--- a/doc/reST/cli.rst<span style="white-space:pre-wrap">       </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/doc/reST/cli.rst<span style="white-space:pre-wrap">     </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -930,6 +930,14 @@</div><div> <span style="white-space:pre-wrap">      </span>Reuse MV information received through API call. Currently receives information for AVC size and the accepted </div><div> <span style="white-space:pre-wrap"> </span>string input is "avc". Default is disabled.</div><div> </div><div>+.. option:: --refine-ctu-distortion <0/1></div><div>+</div><div>+    Store/normalize ctu distortion in analysis-save/load.</div><div>+    0 - Disabled.</div><div>+    1 - Save ctu distortion to the analysis file specified during analysis-save.</div><div>+        Load CTU distortion from the analysis file and normalize it across every frame during analysis-load.</div><div>+    Default 0.</div><div>+</div><div> .. option:: --scale-factor</div><div> </div><div> <span style="white-space:pre-wrap">      </span>Factor by which input video is scaled down for analysis save mode.</div><div>diff -r 81373aab81df -r e6b3e3747035 source/CMakeLists.txt</div><div>--- a/source/CMakeLists.txt<span style="white-space:pre-wrap">   </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/source/CMakeLists.txt<span style="white-space:pre-wrap">        </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -29,7 +29,7 @@</div><div> option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)</div><div> mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)</div><div> # X265_BUILD must be incremented each time the public API is changed</div><div>-set(X265_BUILD 168)</div><div>+set(X265_BUILD 169)</div><div> configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265.def.in" target="_blank">x265.def.in</a>"</div><div>                "${PROJECT_BINARY_DIR}/x265.def")</div><div> configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265_config.h.in" target="_blank">x265_config.h.in</a>"</div><div>diff -r 81373aab81df -r e6b3e3747035 source/common/param.cpp</div><div>--- a/source/common/param.cpp<span style="white-space:pre-wrap">     </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/source/common/param.cpp<span style="white-space:pre-wrap">      </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -297,6 +297,7 @@</div><div>     param->interRefine = 0;</div><div>     param->bDynamicRefine = 0;</div><div>     param->mvRefine = 0;</div><div>+    param->ctuDistortionRefine = 0;</div><div>     param->bUseAnalysisFile = 1;</div><div>     param->csvfpt = NULL;</div><div>     param->forceFlush = 0;</div><div>@@ -1061,6 +1062,7 @@</div><div>                 bError = true;</div><div>         }</div><div>         OPT("hrd-concat") p->bEnableHRDConcatFlag = atobool(value);</div><div>+        OPT("refine-ctu-distortion") p->ctuDistortionRefine = atoi(value);</div><div>         else</div><div>             return X265_PARAM_BAD_NAME;</div><div>     }</div><div>@@ -1416,6 +1418,8 @@</div><div>         "Invalid refine-inter value, refine-inter levels 0 to 3 supported");</div><div>     CHECK(param->intraRefine > 4 || param->intraRefine < 0,</div><div>         "Invalid refine-intra value, refine-intra levels 0 to 3 supported");</div><div>+    CHECK(param->ctuDistortionRefine < 0 || param->ctuDistortionRefine > 1,</div><div>+        "Invalid refine-ctu-distortion value, must be either 0 or 1");</div><div>     CHECK(param->maxAUSizeFactor < 0.5 || param->maxAUSizeFactor > 1.0,</div><div>         "Supported factor for controlling max AU size is from 0.5 to 1");</div><div>     CHECK((param->dolbyProfile != 0) && (param->dolbyProfile != 50),</div><div>@@ -1818,6 +1822,7 @@</div><div>     s += sprintf(s, " refine-intra=%d", p->intraRefine);</div><div>     s += sprintf(s, " refine-inter=%d", p->interRefine);</div><div>     s += sprintf(s, " refine-mv=%d", p->mvRefine);</div><div>+    s += sprintf(s, " refine-ctu-distortion=%d", p->ctuDistortionRefine);</div><div>     BOOL(p->bLimitSAO, "limit-sao");</div><div>     s += sprintf(s, " ctu-info=%d", p->bCTUInfo);</div><div>     BOOL(p->bLowPassDct, "lowpass-dct");</div><div>diff -r 81373aab81df -r e6b3e3747035 source/encoder/analysis.cpp</div><div>--- a/source/encoder/analysis.cpp<span style="white-space:pre-wrap">  </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/source/encoder/analysis.cpp<span style="white-space:pre-wrap">  </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -3560,7 +3560,7 @@</div><div>     FrameData& curEncData = *m_frame->m_encData;</div><div>     double qp = baseQp >= 0 ? baseQp : curEncData.m_cuStat[ctu.m_cuAddr].baseQp;</div><div> </div><div>-    if (m_param->analysisMultiPassDistortion && m_param->rc.bStatRead)</div><div>+    if ((m_param->analysisMultiPassDistortion && m_param->rc.bStatRead) || (m_param->ctuDistortionRefine && m_param->analysisLoad))</div><div>     {</div><div>         x265_analysis_distortion_data* distortionData = m_frame->m_analysisData.distortionData;</div><div>         if ((distortionData->threshold[ctu.m_cuAddr] < 0.9 || distortionData->threshold[ctu.m_cuAddr] > 1.1)</div><div>diff -r 81373aab81df -r e6b3e3747035 source/encoder/api.cpp</div><div>--- a/source/encoder/api.cpp<span style="white-space:pre-wrap">     </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/source/encoder/api.cpp<span style="white-space:pre-wrap">       </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -408,6 +408,7 @@</div><div>     x265_analysis_inter_data *interData = analysis->interData = NULL;</div><div>     x265_analysis_intra_data *intraData = analysis->intraData = NULL;</div><div>     x265_analysis_distortion_data *distortionData = analysis->distortionData = NULL;</div><div>+</div><div>     bool isVbv = param->rc.vbvMaxBitrate > 0 && param->rc.vbvBufferSize > 0;</div><div>     int numDir = 2; //irrespective of P or B slices set direction as 2</div><div>     uint32_t numPlanes = param->internalCsp == X265_CSP_I400 ? 1 : 3;</div><div>@@ -419,18 +420,19 @@</div><div> #else</div><div>     uint32_t numCUs_sse_t = analysis->numCUsInFrame;</div><div> #endif</div><div>-</div><div>-    //Allocate memory for distortionData pointer</div><div>-    CHECKED_MALLOC_ZERO(distortionData, x265_analysis_distortion_data, 1);</div><div>-    CHECKED_MALLOC_ZERO(distortionData->distortion, sse_t, analysis->numPartitions * numCUs_sse_t);</div><div>-    if (param->rc.bStatRead)</div><div>+    if (param->analysisMultiPassRefine || param->analysisMultiPassDistortion || param->ctuDistortionRefine)</div><div>     {</div><div>-        CHECKED_MALLOC_ZERO(distortionData->ctuDistortion, sse_t, numCUs_sse_t);</div><div>-        CHECKED_MALLOC_ZERO(distortionData->scaledDistortion, double, analysis->numCUsInFrame);</div><div>-        CHECKED_MALLOC_ZERO(distortionData->offset, double, analysis->numCUsInFrame);</div><div>-        CHECKED_MALLOC_ZERO(distortionData->threshold, double, analysis->numCUsInFrame);</div><div>+        //Allocate memory for distortionData pointer</div><div>+        CHECKED_MALLOC_ZERO(distortionData, x265_analysis_distortion_data, 1);</div><div>+        CHECKED_MALLOC_ZERO(distortionData->ctuDistortion, sse_t, analysis->numPartitions * numCUs_sse_t);</div><div>+        if (param->analysisLoad || param->rc.bStatRead)</div><div>+        {</div><div>+            CHECKED_MALLOC_ZERO(distortionData->scaledDistortion, double, analysis->numCUsInFrame);</div><div>+            CHECKED_MALLOC_ZERO(distortionData->offset, double, analysis->numCUsInFrame);</div><div>+            CHECKED_MALLOC_ZERO(distortionData->threshold, double, analysis->numCUsInFrame);</div><div>+        }</div><div>+        analysis->distortionData = distortionData;</div><div>     }</div><div>-    analysis->distortionData = distortionData;</div><div> </div><div>     if (param->bDisableLookahead && isVbv)</div><div>     {</div><div>@@ -516,10 +518,9 @@</div><div>     //Free memory for distortionData pointers</div><div>     if (analysis->distortionData)</div><div>     {</div><div>-        X265_FREE((analysis->distortionData)->distortion);</div><div>-        if (param->rc.bStatRead)</div><div>+        X265_FREE((analysis->distortionData)->ctuDistortion);</div><div>+        if (param->rc.bStatRead || param->analysisLoad)</div><div>         {</div><div>-            X265_FREE((analysis->distortionData)->ctuDistortion);</div><div>             X265_FREE((analysis->distortionData)->scaledDistortion);</div><div>             X265_FREE((analysis->distortionData)->offset);</div><div>             X265_FREE((analysis->distortionData)->threshold);</div><div>diff -r 81373aab81df -r e6b3e3747035 source/encoder/encoder.cpp</div><div>--- a/source/encoder/encoder.cpp<span style="white-space:pre-wrap">    </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/source/encoder/encoder.cpp<span style="white-space:pre-wrap">   </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -1266,9 +1266,9 @@</div><div>                     pic_out->analysisData.wt = outFrame->m_analysisData.wt;</div><div>                     pic_out->analysisData.interData = outFrame->m_analysisData.interData;</div><div>                     pic_out->analysisData.intraData = outFrame->m_analysisData.intraData;</div><div>+                    pic_out->analysisData.distortionData = outFrame->m_analysisData.distortionData;</div><div>                     pic_out->analysisData.modeFlag[0] = outFrame->m_analysisData.modeFlag[0];</div><div>                     pic_out->analysisData.modeFlag[1] = outFrame->m_analysisData.modeFlag[1];</div><div>-                    pic_out->analysisData.distortionData = outFrame->m_analysisData.distortionData;</div><div>                     if (m_param->bDisableLookahead)</div><div>                     {</div><div>                         int factor = 1;</div><div>@@ -2839,6 +2839,20 @@</div><div>         }</div><div>     }</div><div> </div><div>+    if (p->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)</div><div>+    {</div><div>+        if (!p->analysisLoad && !p->analysisSave)</div><div>+        {</div><div>+            x265_log(p, X265_LOG_WARNING, "refine-ctu-distortion 1 requires analysis save/load. Disabling refine-ctu-distortion\n");</div><div>+            p->ctuDistortionRefine = 0;</div><div>+        }</div><div>+        if (p->scaleFactor && p->analysisLoad)</div><div>+        {</div><div>+            x265_log(p, X265_LOG_WARNING, "refine-ctu-distortion 1 cannot be enabled along with multi resolution analysis refinement. Disabling refine-ctu-distortion\n");</div><div>+            p->ctuDistortionRefine = 0;</div><div>+        }</div><div>+    }</div><div>+</div><div>     if ((p->analysisMultiPassRefine || p->analysisMultiPassDistortion) && (p->bDistributeModeAnalysis || p->bDistributeMotionEstimation))</div><div>     {</div><div>         x265_log(p, X265_LOG_WARNING, "multi-pass-opt-analysis/multi-pass-opt-distortion incompatible with pmode/pme, Disabling pmode/pme\n");</div><div>@@ -3237,6 +3251,7 @@</div><div>     const x265_analysis_data *picData = &(picIn->analysisData);</div><div>     x265_analysis_intra_data *intraPic = picData->intraData;</div><div>     x265_analysis_inter_data *interPic = picData->interData;</div><div>+    x265_analysis_distortion_data *picDistortion = picData->distortionData;</div><div> </div><div>     int poc; uint32_t frameRecordSize;</div><div>     X265_FREAD(&frameRecordSize, sizeof(uint32_t), 1, m_analysisFileIn, &(picData->frameRecordSize));</div><div>@@ -3272,6 +3287,7 @@</div><div>     X265_FREAD(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFileIn, &(picData->satdCost));</div><div>     X265_FREAD(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFileIn, &(picData->numCUsInFrame));</div><div>     X265_FREAD(&analysis->numPartitions, sizeof(int), 1, m_analysisFileIn, &(picData->numPartitions));</div><div>+</div><div>     if (m_param->bDisableLookahead)</div><div>     {</div><div>         X265_FREAD(&analysis->numCuInHeight, sizeof(uint32_t), 1, m_analysisFileIn, &(picData->numCuInHeight));</div><div>@@ -3284,6 +3300,12 @@</div><div>         analysis->numPartitions *= factor;</div><div>     /* Memory is allocated for inter and intra analysis data based on the slicetype */</div><div>     x265_alloc_analysis_data(m_param, analysis);</div><div>+</div><div>+    if (m_param->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)</div><div>+    {</div><div>+        X265_FREAD((analysis->distortionData)->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileIn, picDistortion);</div><div>+        computeDistortionOffset(analysis);</div><div>+    }</div><div>     if (m_param->bDisableLookahead && m_rateControl->m_isVbv)</div><div>     {</div><div>         size_t vbvCount = m_param->lookaheadDepth + m_param->bframes + 2;</div><div>@@ -3532,6 +3554,7 @@</div><div>     const x265_analysis_data *picData = &(picIn->analysisData);</div><div>     x265_analysis_intra_data *intraPic = picData->intraData;</div><div>     x265_analysis_inter_data *interPic = picData->interData;</div><div>+    x265_analysis_distortion_data *picDistortion = picData->distortionData;</div><div> </div><div>     int poc; uint32_t frameRecordSize;</div><div>     X265_FREAD(&frameRecordSize, sizeof(uint32_t), 1, m_analysisFileIn, &(picData->frameRecordSize));</div><div>@@ -3567,6 +3590,7 @@</div><div>     X265_FREAD(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFileIn, &(picData->satdCost));</div><div>     X265_FREAD(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFileIn, &(picData->numCUsInFrame));</div><div>     X265_FREAD(&analysis->numPartitions, sizeof(int), 1, m_analysisFileIn, &(picData->numPartitions));</div><div>+    </div><div>     if (m_param->bDisableLookahead)</div><div>     {</div><div>         X265_FREAD(&analysis->numCuInHeight, sizeof(uint32_t), 1, m_analysisFileIn, &(picData->numCuInHeight));</div><div>@@ -3586,6 +3610,12 @@</div><div>     /* Memory is allocated for inter and intra analysis data based on the slicetype */</div><div>     x265_alloc_analysis_data(m_param, analysis);</div><div> </div><div>+    if (m_param->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)</div><div>+    {</div><div>+        X265_FREAD((analysis->distortionData)->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileIn, picDistortion);</div><div>+        computeDistortionOffset(analysis);</div><div>+    }</div><div>+</div><div>     analysis->numPartitions = numPartitions * factor;</div><div>     analysis->numCUsInFrame = numCUsInFrame;</div><div>     analysis->numCuInHeight = numCuInHeight;</div><div>@@ -3956,6 +3986,7 @@</div><div>     X265_PARAM_VALIDATE(saveParam->chunkStart, sizeof(int), 1, &m_param->chunkStart, chunk-start);</div><div>     X265_PARAM_VALIDATE(saveParam->chunkEnd, sizeof(int), 1, &m_param->chunkEnd, chunk-end);</div><div>     X265_PARAM_VALIDATE(saveParam->cuTree,sizeof(int),1,&m_param->rc.cuTree, cutree - offset);</div><div>+    X265_PARAM_VALIDATE(saveParam->ctuDistortionRefine, sizeof(int), 1, &m_param->ctuDistortionRefine, ctu - distortion);</div><div> </div><div>     int sourceHeight, sourceWidth;</div><div>     if (writeFlag)</div><div>@@ -4107,7 +4138,31 @@</div><div>     }</div><div>     return SIZE_2Nx2N;</div><div> }</div><div>-</div><div>+void Encoder::computeDistortionOffset(x265_analysis_data* analysis)</div><div>+{</div><div>+    x265_analysis_distortion_data *distortionData = analysis->distortionData;</div><div>+</div><div>+    double sum = 0.0, sqrSum = 0.0;</div><div>+    for (uint32_t i = 0; i < analysis->numCUsInFrame; ++i)</div><div>+    {</div><div>+        distortionData->scaledDistortion[i] = X265_LOG2(X265_MAX(distortionData->ctuDistortion[i], 1));</div><div>+        sum += distortionData->scaledDistortion[i];</div><div>+        sqrSum += distortionData->scaledDistortion[i] * distortionData->scaledDistortion[i];</div><div>+    }</div><div>+    double avg = sum / analysis->numCUsInFrame;</div><div>+    distortionData->sdDistortion = pow(((sqrSum / analysis->numCUsInFrame) - (avg * avg)), 0.5);</div><div>+    distortionData->averageDistortion = avg;</div><div>+    distortionData->highDistortionCtuCount = distortionData->lowDistortionCtuCount = 0;</div><div>+    for (uint32_t i = 0; i < analysis->numCUsInFrame; ++i)</div><div>+    {</div><div>+        distortionData->threshold[i] = distortionData->scaledDistortion[i] / distortionData->averageDistortion;</div><div>+        distortionData->offset[i] = (distortionData->averageDistortion - distortionData->scaledDistortion[i]) / distortionData->sdDistortion;</div><div>+        if (distortionData->threshold[i] < 0.9 && distortionData->offset[i] >= 1)</div><div>+            distortionData->lowDistortionCtuCount++;</div><div>+        else if (distortionData->threshold[i] > 1.1 && distortionData->offset[i] <= -1)</div><div>+            distortionData->highDistortionCtuCount++;</div><div>+    }</div><div>+}</div><div> void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, int sliceType)</div><div> {</div><div> </div><div>@@ -4135,21 +4190,16 @@</div><div>     /* Now arrived at the right frame, read the record */</div><div>     analysis->frameRecordSize = frameRecordSize;</div><div>     uint8_t* tempBuf = NULL, *depthBuf = NULL;</div><div>-    sse_t *tempdistBuf = NULL, *distortionBuf = NULL;</div><div>+    X265_FREAD((analysis->distortionData)->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileIn);</div><div>     tempBuf = X265_MALLOC(uint8_t, depthBytes);</div><div>     X265_FREAD(tempBuf, sizeof(uint8_t), depthBytes, m_analysisFileIn);</div><div>-    tempdistBuf = X265_MALLOC(sse_t, depthBytes);</div><div>-    X265_FREAD(tempdistBuf, sizeof(sse_t), depthBytes, m_analysisFileIn);</div><div>     depthBuf = tempBuf;</div><div>-    distortionBuf = tempdistBuf;</div><div>     x265_analysis_data *analysisData = (x265_analysis_data*)analysis;</div><div>     x265_analysis_intra_data *intraData = analysisData->intraData;</div><div>     x265_analysis_inter_data *interData = analysisData->interData;</div><div>-    x265_analysis_distortion_data *distortionData = analysisData->distortionData;</div><div>-</div><div>+</div><div>+    computeDistortionOffset(analysis);</div><div>     size_t count = 0;</div><div>-    uint32_t ctuCount = 0;</div><div>-    double sum = 0, sqrSum = 0;</div><div>     for (uint32_t d = 0; d < depthBytes; d++)</div><div>     {</div><div>         int bytes = analysis->numPartitions >> (depthBuf[d] * 2);</div><div>@@ -4157,30 +4207,10 @@</div><div>             memset(&intraData->depth[count], depthBuf[d], bytes);</div><div>         else</div><div>             memset(&interData->depth[count], depthBuf[d], bytes);</div><div>-        distortionData->distortion[count] = distortionBuf[d];</div><div>-        distortionData->ctuDistortion[ctuCount] += distortionData->distortion[count];</div><div>         count += bytes;</div><div>-        if ((count % (unsigned)analysis->numPartitions) == 0)</div><div>-        {</div><div>-            distortionData->scaledDistortion[ctuCount] = X265_LOG2(X265_MAX(distortionData->ctuDistortion[ctuCount], 1));</div><div>-            sum += distortionData->scaledDistortion[ctuCount];</div><div>-            sqrSum += distortionData->scaledDistortion[ctuCount] * distortionData->scaledDistortion[ctuCount];</div><div>-            ctuCount++;</div><div>-        }</div><div>     }</div><div>-    double avg = sum / analysis->numCUsInFrame;</div><div>-    distortionData->sdDistortion = pow(((sqrSum / analysis->numCUsInFrame) - (avg * avg)), 0.5);</div><div>-    distortionData->averageDistortion = avg;</div><div>-    distortionData->highDistortionCtuCount = distortionData->lowDistortionCtuCount = 0;</div><div>-    for (uint32_t i = 0; i < analysis->numCUsInFrame; ++i)</div><div>-    {</div><div>-        distortionData->threshold[i] = distortionData->scaledDistortion[i] / distortionData->averageDistortion;</div><div>-        distortionData->offset[i] = (distortionData->averageDistortion - distortionData->scaledDistortion[i]) / distortionData->sdDistortion;</div><div>-        if (distortionData->threshold[i] < 0.9 && distortionData->offset[i] >= 1)</div><div>-            distortionData->lowDistortionCtuCount++;</div><div>-        else if (distortionData->threshold[i] > 1.1 && distortionData->offset[i] <= -1)</div><div>-            distortionData->highDistortionCtuCount++;</div><div>-    }</div><div>+</div><div>+</div><div>     if (!IS_X265_TYPE_I(sliceType))</div><div>     {</div><div>         MV *tempMVBuf[2], *MVBuf[2];</div><div>@@ -4233,11 +4263,27 @@</div><div>         X265_FREE(tempModeBuf);</div><div>     }</div><div>     X265_FREE(tempBuf);</div><div>-    X265_FREE(tempdistBuf);</div><div> </div><div> #undef X265_FREAD</div><div> }</div><div> </div><div>+void Encoder::copyDistortionData(x265_analysis_data* analysis, FrameData &curEncData)</div><div>+{</div><div>+    for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)</div><div>+    {</div><div>+        uint8_t depth = 0;</div><div>+        CUData* ctu = curEncData.getPicCTU(cuAddr);</div><div>+        x265_analysis_distortion_data *distortionData = (x265_analysis_distortion_data *)analysis->distortionData;</div><div>+        distortionData->ctuDistortion[cuAddr] = 0;</div><div>+        for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions;)</div><div>+        {</div><div>+            depth = ctu->m_cuDepth[absPartIdx];</div><div>+            distortionData->ctuDistortion[cuAddr] += ctu->m_distortion[absPartIdx];</div><div>+            absPartIdx += ctu->m_numPartitions >> (depth * 2);</div><div>+        }</div><div>+    }</div><div>+}</div><div>+</div><div> void Encoder::writeAnalysisFile(x265_analysis_data* analysis, FrameData &curEncData)</div><div> {</div><div> </div><div>@@ -4273,8 +4319,15 @@</div><div>         analysis->frameRecordSize += sizeof(WeightParam) * numPlanes * numDir;</div><div>     }</div><div> </div><div>+    if (m_param->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)</div><div>+    {</div><div>+        copyDistortionData(analysis, curEncData);</div><div>+        analysis->frameRecordSize += analysis->numCUsInFrame * sizeof(sse_t);</div><div>+    }</div><div>+</div><div>     if (m_param->analysisReuseLevel > 1)</div><div>     {</div><div>+</div><div>         if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType == X265_TYPE_I)</div><div>         {</div><div>             for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)</div><div>@@ -4406,6 +4459,8 @@</div><div>     X265_FWRITE(&analysis->satdCost, sizeof(int64_t), 1, m_analysisFileOut);</div><div>     X265_FWRITE(&analysis->numCUsInFrame, sizeof(int), 1, m_analysisFileOut);</div><div>     X265_FWRITE(&analysis->numPartitions, sizeof(int), 1, m_analysisFileOut);</div><div>+    if (m_param->ctuDistortionRefine == CTU_DISTORTION_INTERNAL)</div><div>+        X265_FWRITE((analysis->distortionData)->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileOut);</div><div>     if (analysis->sliceType > X265_TYPE_I)</div><div>         X265_FWRITE((WeightParam*)analysis->wt, sizeof(WeightParam), numPlanes * numDir, m_analysisFileOut);</div><div> </div><div>@@ -4469,25 +4524,24 @@</div><div>     x265_analysis_inter_data *interData = analysisData->interData;</div><div>     x265_analysis_distortion_data *distortionData = analysisData->distortionData;</div><div> </div><div>-    for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)</div><div>+    copyDistortionData(analysis, curEncData);</div><div>+</div><div>+    if (curEncData.m_slice->m_sliceType == I_SLICE)</div><div>     {</div><div>-        uint8_t depth = 0;</div><div>-</div><div>-        CUData* ctu = curEncData.getPicCTU(cuAddr);</div><div>-</div><div>-        for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)</div><div>+        for (uint32_t cuAddr = 0; cuAddr < analysis->numCUsInFrame; cuAddr++)</div><div>         {</div><div>-            depth = ctu->m_cuDepth[absPartIdx];</div><div>-            if (curEncData.m_slice->m_sliceType == I_SLICE)</div><div>+            uint8_t depth = 0;</div><div>+            CUData* ctu = curEncData.getPicCTU(cuAddr);</div><div>+            for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)</div><div>+            {</div><div>+                depth = ctu->m_cuDepth[absPartIdx];</div><div>                 intraData->depth[depthBytes] = depth;</div><div>-            else</div><div>-                interData->depth[depthBytes] = depth;</div><div>-            distortionData->distortion[depthBytes] = ctu->m_distortion[absPartIdx];</div><div>-            absPartIdx += ctu->m_numPartitions >> (depth * 2);</div><div>+                absPartIdx += ctu->m_numPartitions >> (depth * 2);</div><div>+            }</div><div>         }</div><div>     }</div><div> </div><div>-    if (curEncData.m_slice->m_sliceType != I_SLICE)</div><div>+    else</div><div>     {</div><div>         int32_t* ref[2];</div><div>         ref[0] = (analysis->interData)->ref;</div><div>@@ -4502,6 +4556,7 @@</div><div>             for (uint32_t absPartIdx = 0; absPartIdx < ctu->m_numPartitions; depthBytes++)</div><div>             {</div><div>                 depth = ctu->m_cuDepth[absPartIdx];</div><div>+                interData->depth[depthBytes] = depth;</div><div>                 interData->mv[0][depthBytes].word = ctu->m_mv[0][absPartIdx].word;</div><div>                 interData->mvpIdx[0][depthBytes] = ctu->m_mvpIdx[0][absPartIdx];</div><div>                 ref[0][depthBytes] = ctu->m_refIdx[0][absPartIdx];</div><div>@@ -4523,7 +4578,7 @@</div><div>     /* calculate frameRecordSize */</div><div>     analysis->frameRecordSize = sizeof(analysis->frameRecordSize) + sizeof(depthBytes) + sizeof(analysis->poc);</div><div>     analysis->frameRecordSize += depthBytes * sizeof(uint8_t);</div><div>-    analysis->frameRecordSize += depthBytes * sizeof(sse_t);</div><div>+    analysis->frameRecordSize += analysis->numCUsInFrame * sizeof(sse_t);</div><div>     if (curEncData.m_slice->m_sliceType != I_SLICE)</div><div>     {</div><div>         int numDir = (curEncData.m_slice->m_sliceType == P_SLICE) ? 1 : 2;</div><div>@@ -4535,6 +4590,7 @@</div><div>     X265_FWRITE(&analysis->frameRecordSize, sizeof(uint32_t), 1, m_analysisFileOut);</div><div>     X265_FWRITE(&depthBytes, sizeof(uint32_t), 1, m_analysisFileOut);</div><div>     X265_FWRITE(&analysis->poc, sizeof(uint32_t), 1, m_analysisFileOut);</div><div>+    X265_FWRITE(distortionData->ctuDistortion, sizeof(sse_t), analysis->numCUsInFrame, m_analysisFileOut);</div><div>     if (curEncData.m_slice->m_sliceType == I_SLICE)</div><div>     {</div><div>         X265_FWRITE((analysis->intraData)->depth, sizeof(uint8_t), depthBytes, m_analysisFileOut);</div><div>@@ -4543,7 +4599,6 @@</div><div>     {</div><div>         X265_FWRITE((analysis->interData)->depth, sizeof(uint8_t), depthBytes, m_analysisFileOut);</div><div>     }</div><div>-    X265_FWRITE(distortionData->distortion, sizeof(sse_t), depthBytes, m_analysisFileOut);</div><div>     if (curEncData.m_slice->m_sliceType != I_SLICE)</div><div>     {</div><div>         int numDir = curEncData.m_slice->m_sliceType == P_SLICE ? 1 : 2;</div><div>diff -r 81373aab81df -r e6b3e3747035 source/encoder/encoder.h</div><div>--- a/source/encoder/encoder.h<span style="white-space:pre-wrap">       </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/source/encoder/encoder.h<span style="white-space:pre-wrap">     </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -194,6 +194,8 @@</div><div>     bool               m_reconfigure;      // Encoder reconfigure in progress</div><div>     bool               m_reconfigureRc;</div><div> </div><div>+    int               m_saveCtuDistortionLevel;</div><div>+</div><div>     /* Begin intra refresh when one not in progress or else begin one as soon as the current </div><div>      * one is done. Requires bIntraRefresh to be set.*/</div><div>     int                m_bQueuedIntraRefresh;</div><div>@@ -281,6 +283,8 @@</div><div> </div><div>     void readAnalysisFile(x265_analysis_data* analysis, int poc, const x265_picture* picIn, int paramBytes, cuLocation cuLoc);</div><div> </div><div>+    void computeDistortionOffset(x265_analysis_data* analysis);</div><div>+</div><div>     int getCUIndex(cuLocation* cuLoc, uint32_t* count, int bytes, int flag);</div><div> </div><div>     int getPuShape(puOrientation* puOrient, int partSize, int numCTU);</div><div>@@ -289,6 +293,8 @@</div><div> </div><div>     void writeAnalysisFileRefine(x265_analysis_data* analysis, FrameData &curEncData);</div><div> </div><div>+    void copyDistortionData(x265_analysis_data* analysis, FrameData &curEncData);</div><div>+</div><div>     void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, x265_frame_stats* frameStats, int inPoc);</div><div> </div><div>     int validateAnalysisData(x265_analysis_data* analysis, int readWriteFlag);</div><div>diff -r 81373aab81df -r e6b3e3747035 source/x265.h</div><div>--- a/source/x265.h<span style="white-space:pre-wrap">      </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/source/x265.h<span style="white-space:pre-wrap">        </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -131,6 +131,7 @@</div><div>     int     chunkStart;</div><div>     int     chunkEnd;</div><div>     int     cuTree;</div><div>+    int     ctuDistortionRefine;</div><div> }x265_analysis_validate;</div><div> </div><div> /* Stores intra analysis data for a single frame. This struct needs better packing */</div><div>@@ -182,9 +183,12 @@</div><div> typedef uint64_t sse_t;</div><div> #endif</div><div> </div><div>+#define CTU_DISTORTION_OFF 0</div><div>+#define CTU_DISTORTION_INTERNAL 1</div><div>+#define CTU_DISTORTION_EXTERNAL 2</div><div>+</div></div></div></blockquote></div></blockquote><div><br></div><div>I don't see the need to export these in x265.h as these are only utilized inside the library.</div><div> <div class="gmail_quote"><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 dir="ltr"><div> typedef struct x265_analysis_distortion_data</div><div> {</div><div>-    sse_t*        distortion;</div><div>     sse_t*        ctuDistortion;</div><div>     double*       scaledDistortion;</div><div>     double        averageDistortion;</div><div>@@ -193,6 +197,7 @@</div><div>     uint32_t      lowDistortionCtuCount;</div><div>     double*       offset;</div><div>     double*       threshold;</div><div>+</div><div> }x265_analysis_distortion_data;</div></div></div></blockquote></div></div><div><br></div><div>Objects of this struct are only every accessed through objects of x265_analysis_data_t. If that is the case, can we fold these fields into the x265_analysis_data_t struct and remove this struct?</div><div>Nested structs aren't a great idea as it makes backwards compatibility a pain!</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail_quote"><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 dir="ltr"><div> </div><div> /* Stores all analysis data for a single frame */</div><div>@@ -1736,6 +1741,11 @@</div><div>     /* Set concantenation flag for the first keyframe in the HRD buffering period SEI. */</div><div>     int bEnableHRDConcatFlag;</div><div> </div><div>+</div><div>+    /* Store/normalize ctu distortion in analysis-save/load. Ranges from 0 - 1.</div><div>+    *  0 - Disabled. 1 - Save/Load ctu distortion to/from the file specified </div><div>+    * analysis-save/load. Default 0. */</div><div>+    int       ctuDistortionRefine;</div><div> } x265_param;</div><div> /* x265_param_alloc:</div><div>  *  Allocates an x265_param instance. The returned param structure is not</div><div>diff -r 81373aab81df -r e6b3e3747035 source/x265cli.h</div><div>--- a/source/x265cli.h<span style="white-space:pre-wrap">   </span>Thu Dec 13 10:55:15 2018 +0530</div><div>+++ b/source/x265cli.h<span style="white-space:pre-wrap">     </span>Mon Dec 17 16:49:08 2018 +0530</div><div>@@ -291,6 +291,7 @@</div><div>     { "dolby-vision-profile",  required_argument, NULL, 0 },</div><div>     { "refine-mv",            no_argument, NULL, 0 },</div><div>     { "no-refine-mv",         no_argument, NULL, 0 },</div><div>+    { "refine-ctu-distortion", required_argument, NULL, 0 },</div><div>     { "force-flush",    required_argument, NULL, 0 },</div><div>     { "splitrd-skip",         no_argument, NULL, 0 },</div><div>     { "no-splitrd-skip",      no_argument, NULL, 0 },</div><div>@@ -514,6 +515,10 @@</div><div>         "                                Default:%d\n", param->interRefine);</div><div>     H0("   --[no-]dynamic-refine         Dynamically changes refine-inter level for each CU. Default %s\n", OPT(param->bDynamicRefine));</div><div>     H0("   --[no-]refine-mv              Enable mv refinement for load mode. Default %s\n", OPT(param->mvRefine));</div><div>+    H0("   --refine-ctu-distortion       Store/normalize ctu distortion in analysis-save/load.\n"</div><div>+        "                                    - 0 : Disabled.\n"</div><div>+        "                                    - 1 : Store/Load ctu distortion to/from the file specified in analysis-save/load.\n"</div><div>+        "                                Default 0 - Disabled\n");</div><div>     H0("   --aq-mode <integer>           Mode for Adaptive Quantization - 0:none 1:uniform AQ 2:auto variance 3:auto variance with bias to dark scenes. Default %d\n", param->rc.aqMode);</div><div>     H0("   --aq-strength <float>         Reduces blocking and blurring in flat and textured areas (0 to 3.0). Default %.2f\n", param->rc.aqStrength);</div><div>     H0("   --[no-]aq-motion              Adaptive Quantization based on the relative motion of each CU w.r.t., frame. Default %s\n", OPT(param->bOptCUDeltaQP));</div><div><br></div></div></div>
_______________________________________________<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/listinfo/x265-devel</a><br>
</blockquote></div>
_______________________________________________<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/listinfo/x265-devel</a><br>
</blockquote></div></div>