[x265] [PATCH] fix bugs in analysis-reuse-level=7 and refine-mv-type=AVC

Ashok Kumar Mishra ashok at multicorewareinc.com
Thu Dec 21 07:57:05 CET 2017


On Thu, Dec 21, 2017 at 12:24 PM, Santhoshini Sekar <
santhoshini at multicorewareinc.com> wrote:

>
>
> On Thu, Dec 21, 2017 at 12:03 PM, Ashok Kumar Mishra <
> ashok at multicorewareinc.com> wrote:
>
>>
>>
>> On Thu, Dec 21, 2017 at 9:03 AM, <santhoshini at multicorewareinc.com>
>> wrote:
>>
>>> # HG changeset patch
>>> # User Santhoshini Sekar <santhoshini at multicorewareinc.com>
>>> # Date 1513677810 -19800
>>> #      Tue Dec 19 15:33:30 2017 +0530
>>> # Node ID 32a2cd5926ed3bc64fc5665f3ecc20e9b371cee2
>>> # Parent  57eaef9abfd8204b568498d4a37a23391e790d44
>>> fix bugs in analysis-reuse-level=7 and refine-mv-type=AVC
>>>
>>> diff --git a/source/encoder/analysis.cpp b/source/encoder/analysis.cpp
>>> --- a/source/encoder/analysis.cpp
>>> +++ b/source/encoder/analysis.cpp
>>> @@ -280,7 +280,7 @@
>>>              /* generate residual for entire CTU at once and copy to
>>> reconPic */
>>>              encodeResidue(ctu, cuGeom);
>>>          }
>>> -        else if ((m_param->analysisReuseMode == X265_ANALYSIS_LOAD &&
>>> m_param->analysisReuseLevel == 10) || ((m_param->bMVType == AVC_INFO) &&
>>> m_param->analysisReuseLevel >= 7))
>>> +        else if ((m_param->analysisReuseMode == X265_ANALYSIS_LOAD &&
>>> m_param->analysisReuseLevel == 10) || ((m_param->bMVType == AVC_INFO) &&
>>> m_param->analysisReuseLevel >= 7 && ctu.m_numPartitions <= 16))
>>>          {
>>>              analysis_inter_data* interDataCTU =
>>> (analysis_inter_data*)m_frame->m_analysisData.interData;
>>>              int posCTU = ctu.m_cuAddr * numPartition;
>>> @@ -461,7 +461,7 @@
>>>      int lambdaQP = lqp;
>>>
>>>      bool doQPRefine = (bDecidedDepth && depth <=
>>> m_slice->m_pps->maxCuDQPDepth) || (!bDecidedDepth && depth ==
>>> m_slice->m_pps->maxCuDQPDepth);
>>> -    if (m_param->analysisReuseLevel == 10)
>>> +    if (m_param->analysisReuseLevel >= 7)
>>>          doQPRefine = false;
>>>
>>>      if (doQPRefine)
>>> @@ -1307,7 +1307,7 @@
>>>          }
>>>
>>>          /* Step 1. Evaluate Merge/Skip candidates for likely
>>> early-outs, if skip mode was not set above */
>>> -        if ((mightNotSplit && depth >= minDepth && !md.bestMode &&
>>> !bCtuInfoCheck) || (m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1])))
>>> /* TODO: Re-evaluate if analysis load/save still works */
>>> +        if ((mightNotSplit && depth >= minDepth && !md.bestMode &&
>>> !bCtuInfoCheck) || (m_param->bMVType && m_param->analysisReuseLevel == 7 &&
>>> (m_modeFlag[0] || m_modeFlag[1]))) /* TODO: Re-evaluate if analysis
>>> load/save still works */
>>>          {
>>>              /* Compute Merge Cost */
>>>              md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
>>> @@ -1318,7 +1318,7 @@
>>>                  && md.bestMode && md.bestMode->cu.isSkipped(0); //
>>> TODO: sa8d threshold per depth
>>>          }
>>>
>>> -        if (md.bestMode && m_param->bEnableRecursionSkip &&
>>> !bCtuInfoCheck && !(m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1])))
>>> +        if (md.bestMode && m_param->bEnableRecursionSkip &&
>>> !bCtuInfoCheck && !(m_param->bMVType && m_param->analysisReuseLevel == 7 &&
>>> (m_modeFlag[0] || m_modeFlag[1])))
>>>          {
>>>              skipRecursion = md.bestMode->cu.isSkipped(0);
>>>              if (mightSplit && depth >= minDepth && !skipRecursion)
>>> @@ -1330,7 +1330,7 @@
>>>              }
>>>          }
>>>
>>> -        if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <=
>>> 16)
>>> +        if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <=
>>> 16 && m_param->analysisReuseLevel == 7)
>>>              skipRecursion = true;
>>>
>>>          /* Step 2. Evaluate each of the 4 split sub-blocks in series */
>>> @@ -1389,8 +1389,19 @@
>>>          }
>>>
>>>          /* If analysis mode is simple do not Evaluate other modes */
>>> -        if ((m_param->bMVType && cuGeom.numPartitions <= 16) &&
>>> (m_slice->m_sliceType == P_SLICE || m_slice->m_sliceType == B_SLICE))
>>> -            mightNotSplit = !(m_checkMergeAndSkipOnly[0] ||
>>> (m_checkMergeAndSkipOnly[0] && m_checkMergeAndSkipOnly[1]));
>>> +        if (m_param->bMVType && m_param->analysisReuseLevel == 7)
>>> +        {
>>> +            if (m_slice->m_sliceType == P_SLICE)
>>> +            {
>>> +                if (m_checkMergeAndSkipOnly[0])
>>> +                    skipModes = true;
>>> +            }
>>> +            else
>>> +            {
>>> +                if (m_checkMergeAndSkipOnly[0] &&
>>> m_checkMergeAndSkipOnly[1])
>>> +                    skipModes = true;
>>> +            }
>>> +        }
>>>
>>>          /* Split CUs
>>>           *   0  1
>>> @@ -2001,7 +2012,7 @@
>>>
>>>          /* Step 1. Evaluate Merge/Skip candidates for likely early-outs
>>> */
>>>          if ((mightNotSplit && !md.bestMode && !bCtuInfoCheck) ||
>>> -            (m_param->bMVType && (m_modeFlag[0] || m_modeFlag[1])))
>>> +            (m_param->bMVType && m_param->analysisReuseLevel == 7 &&
>>> (m_modeFlag[0] || m_modeFlag[1])))
>>>          {
>>>              md.pred[PRED_SKIP].cu.initSubCU(parentCTU, cuGeom, qp);
>>>              md.pred[PRED_MERGE].cu.initSubCU(parentCTU, cuGeom, qp);
>>> @@ -2017,7 +2028,7 @@
>>>                  skipRecursion = md.bestMode &&
>>> !md.bestMode->cu.getQtRootCbf(0);
>>>          }
>>>
>>> -        if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <=
>>> 16)
>>> +        if (m_param->bMVType && md.bestMode && cuGeom.numPartitions <=
>>> 16 && m_param->analysisReuseLevel == 7)
>>>              skipRecursion = true;
>>>
>>>          // estimate split cost
>>> @@ -2073,8 +2084,19 @@
>>>          }
>>>
>>>          /* If analysis mode is simple do not Evaluate other modes */
>>> -        if ((m_param->bMVType && cuGeom.numPartitions <= 16) &&
>>> (m_slice->m_sliceType == P_SLICE || m_slice->m_sliceType == B_SLICE))
>>> -            mightNotSplit = !(m_checkMergeAndSkipOnly[0] ||
>>> (m_checkMergeAndSkipOnly[0] && m_checkMergeAndSkipOnly[1]));
>>> +        if (m_param->bMVType && m_param->analysisReuseLevel == 7)
>>> +        {
>>> +            if (m_slice->m_sliceType == P_SLICE)
>>> +            {
>>> +                if (m_checkMergeAndSkipOnly[0])
>>> +                    skipModes = true;
>>> +            }
>>> +            else
>>> +            {
>>> +                if (m_checkMergeAndSkipOnly[0] &&
>>> m_checkMergeAndSkipOnly[1])
>>> +                    skipModes = true;
>>> +            }
>>> +        }
>>>
>>>          /* Split CUs
>>>           *   0  1
>>> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
>>> --- a/source/encoder/encoder.cpp
>>> +++ b/source/encoder/encoder.cpp
>>> @@ -562,7 +562,7 @@
>>>                      {
>>>                          int cuOffset = cuI * bytes + pu;
>>>                          (interData)->mergeFlag[cuPos + cuOffset] =
>>> (srcInterData)->mergeFlag[(mbIndex * 16) + cuOffset];
>>> -
>>> +                        (interData)->sadCost[cuPos + cuOffset] =
>>> (srcInterData)->sadCost[(mbIndex * 16) + cuOffset];
>>>                          (interData)->interDir[cuPos + cuOffset] =
>>> (srcInterData)->interDir[(mbIndex * 16) + cuOffset];
>>>                          for (uint32_t k = 0; k < numDir; k++)
>>>                          {
>>> @@ -570,10 +570,10 @@
>>>                              (interData)->refIdx[k][cuPos + cuOffset] =
>>> (srcInterData)->refIdx[k][(mbIndex * 16) + cuOffset];
>>>                              memcpy(&(interData)->mv[k][cuPos +
>>> cuOffset], &(srcInterData)->mv[k][(mbIndex * 16) + cuOffset],
>>> sizeof(MV));
>>>                              if (m_param->analysisReuseLevel == 7 &&
>>> numPU == PU_2Nx2N &&
>>> -                                ((srcInterData)->depth[cuPos +
>>> cuOffset] == (m_param->maxCUSize >> 5)))
>>> +                                ((interData)->depth[cuPos + cuOffset]
>>> == (m_param->maxCUSize >> 5)))
>>>                              {
>>> -                                int mv_x = ((analysis_inter_data
>>> *)curFrame->m_analysisData.interData)->mv[k][(mbIndex * 16) +
>>> cuOffset].x;
>>> -                                int mv_y = ((analysis_inter_data
>>> *)curFrame->m_analysisData.interData)->mv[k][(mbIndex * 16) +
>>> cuOffset].y;
>>> +                                int mv_x = ((analysis_inter_data
>>> *)curFrame->m_analysisData.interData)->mv[k][cuPos + cuOffset].x;
>>> +                                int mv_y = ((analysis_inter_data
>>> *)curFrame->m_analysisData.interData)->mv[k][cuPos + cuOffset].y;
>>>
>>
>> Always use local pointer analysis_inter_data * interData above.
>>
> ok, I'll change this everywhere.
>
>>
>>
>>>                                  if ((mv_x*mv_x + mv_y*mv_y) <=
>>> MVTHRESHOLD)
>>>                                      memset(&curFrame->m_analysisData.modeFlag[k][cuPos
>>> + cuOffset], 1, bytes);
>>>                              }
>>> @@ -640,9 +640,10 @@
>>>                      if (m_param->analysisReuseLevel > 4)
>>>                      {
>>>                          memset(&(currInterData)->partSize[count],
>>> (interData)->partSize[d], bytes);
>>> -                        int numPU = nbPartsTable[(currInterData)->
>>> partSize[d]];
>>> -                        for (int pu = 0; pu < numPU; pu++, d++)
>>> +                        int numPU = nbPartsTable[(interData)->part
>>> Size[d]];
>>> +                        for (int pu = 0; pu < numPU; pu++)
>>>                          {
>>> +                            if (pu) d++;
>>>
>>
>> Can be written as
>> for (int pu = 0; pu < numPU; pu++, d++)
>>
> this is logically wrong because 'd' should be incremented only when pu is
> non-zero. But incrementing 'd' in the for loop always increments d.
>
Agreed. I didn't see you are using the d in outer for loop.

>
>>
>>
>>>                              (currInterData)->mergeFlag[count + pu] =
>>> (interData)->mergeFlag[d];
>>>                              if (m_param->analysisReuseLevel >= 7)
>>>                              {
>>> @@ -3061,12 +3062,13 @@
>>>          if (m_param->analysisReuseLevel >= 7)
>>>          {
>>>              CHECKED_MALLOC(interData->interDir, uint8_t,
>>> analysis->numPartitions * analysis->numCUsInFrame);
>>> +            CHECKED_MALLOC(interData->sadCost, int64_t,
>>> analysis->numPartitions * analysis->numCUsInFrame);
>>>              for (int dir = 0; dir < numDir; dir++)
>>>              {
>>>                  CHECKED_MALLOC(interData->mvpIdx[dir], uint8_t,
>>> analysis->numPartitions * analysis->numCUsInFrame);
>>>                  CHECKED_MALLOC(interData->refIdx[dir], int8_t,
>>> analysis->numPartitions * analysis->numCUsInFrame);
>>>                  CHECKED_MALLOC(interData->mv[dir], MV,
>>> analysis->numPartitions * analysis->numCUsInFrame);
>>> -                CHECKED_MALLOC(analysis->modeFlag[dir], uint8_t,
>>> analysis->numPartitions * analysis->numCUsInFrame);
>>> +                CHECKED_MALLOC_ZERO(analysis->modeFlag[dir], uint8_t,
>>> analysis->numPartitions * analysis->numCUsInFrame);
>>>              }
>>>
>>>              /* Allocate intra in inter */
>>>
>>> _______________________________________________
>>> 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/20171221/447f4b2e/attachment-0001.html>


More information about the x265-devel mailing list