[x265] [PATCH] Introduce CTU distortion refinement in analysis-save/load

Aruna Matheswaran aruna at multicorewareinc.com
Mon Dec 24 10:13:58 CET 2018


On Thu, Dec 20, 2018 at 10:18 PM Pradeep Ramachandran <
pradeep at multicorewareinc.com> wrote:

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

yes, this patch uses these macros only inside the library. I'll send a
delta patch to remove them from x265.h

>
>
>>  typedef struct x265_analysis_distortion_data
>>  {
>> -    sse_t*        distortion;
>>      sse_t*        ctuDistortion;
>>      double*       scaledDistortion;
>>      double        averageDistortion;
>> @@ -193,6 +197,7 @@
>>      uint32_t      lowDistortionCtuCount;
>>      double*       offset;
>>      double*       threshold;
>> +
>>  }x265_analysis_distortion_data;
>>
>
> 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?
>
Nested structs aren't a great idea as it makes backwards compatibility a
> pain!
>

okay, I'll fold the members of  x265_analysis_distortion_data into
x265_analysis_data_t and remove the struct.

>
>
>>
>>>  /* Stores all analysis data for a single frame */
>>> @@ -1736,6 +1741,11 @@
>>>      /* Set concantenation flag for the first keyframe in the HRD
>>> buffering period SEI. */
>>>      int bEnableHRDConcatFlag;
>>>
>>> +
>>> +    /* Store/normalize ctu distortion in analysis-save/load. Ranges
>>> from 0 - 1.
>>> +    *  0 - Disabled. 1 - Save/Load ctu distortion to/from the file
>>> specified
>>> +    * analysis-save/load. Default 0. */
>>> +    int       ctuDistortionRefine;
>>>  } x265_param;
>>>  /* x265_param_alloc:
>>>   *  Allocates an x265_param instance. The returned param structure is
>>> not
>>> diff -r 81373aab81df -r e6b3e3747035 source/x265cli.h
>>> --- a/source/x265cli.h Thu Dec 13 10:55:15 2018 +0530
>>> +++ b/source/x265cli.h Mon Dec 17 16:49:08 2018 +0530
>>> @@ -291,6 +291,7 @@
>>>      { "dolby-vision-profile",  required_argument, NULL, 0 },
>>>      { "refine-mv",            no_argument, NULL, 0 },
>>>      { "no-refine-mv",         no_argument, NULL, 0 },
>>> +    { "refine-ctu-distortion", required_argument, NULL, 0 },
>>>      { "force-flush",    required_argument, NULL, 0 },
>>>      { "splitrd-skip",         no_argument, NULL, 0 },
>>>      { "no-splitrd-skip",      no_argument, NULL, 0 },
>>> @@ -514,6 +515,10 @@
>>>          "                                Default:%d\n",
>>> param->interRefine);
>>>      H0("   --[no-]dynamic-refine         Dynamically changes
>>> refine-inter level for each CU. Default %s\n", OPT(param->bDynamicRefine));
>>>      H0("   --[no-]refine-mv              Enable mv refinement for load
>>> mode. Default %s\n", OPT(param->mvRefine));
>>> +    H0("   --refine-ctu-distortion       Store/normalize ctu distortion
>>> in analysis-save/load.\n"
>>> +        "                                    - 0 : Disabled.\n"
>>> +        "                                    - 1 : Store/Load ctu
>>> distortion to/from the file specified in analysis-save/load.\n"
>>> +        "                                Default 0 - Disabled\n");
>>>      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);
>>>      H0("   --aq-strength <float>         Reduces blocking and blurring
>>> in flat and textured areas (0 to 3.0). Default %.2f\n",
>>> param->rc.aqStrength);
>>>      H0("   --[no-]aq-motion              Adaptive Quantization based on
>>> the relative motion of each CU w.r.t., frame. Default %s\n",
>>> OPT(param->bOptCUDeltaQP));
>>>
>>> _______________________________________________
>>> x265-devel mailing list
>>> x265-devel at videolan.org
>>> https://mailman.videolan.org/listinfo/x265-devel
>>>
>> _______________________________________________
>> x265-devel mailing list
>> x265-devel at videolan.org
>> https://mailman.videolan.org/listinfo/x265-devel
>>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20181224/21c50c23/attachment-0001.html>


More information about the x265-devel mailing list