[x265] [PATCH] Fix VBV Lookahead in analysis load to achieve target bitrate

Ashok Kumar Mishra ashok at multicorewareinc.com
Thu May 17 17:35:58 CEST 2018


On Thu, May 17, 2018 at 6:22 PM, <mahesh at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Mahesh Pittala
> # Date 1526553420 -19800
> #      Thu May 17 16:07:00 2018 +0530
> # Branch stable
> # Node ID d3d9943b60cf058c1b22ab7afb5c0f79b98b9769
> # Parent  3cef29225ef431c820c8e5593b00c3c225bfffdc
> Fix VBV Lookahead in analysis load to achieve target bitrate
>
> Details:
> If save and the load encodes have the same max CU size then number of CTU
> rows
> will be doubled and total number of CTU's are 4 times compared to
> analysis save encode so copying one CTU's vbv cost to 4 CTU's in load and
> one
> vbv row's satdcost to 2 consecutive rows(cost is multiplied by 2 here)
>
> diff -r 3cef29225ef4 -r d3d9943b60cf source/encoder/encoder.cpp
> --- a/source/encoder/encoder.cpp        Thu May 17 12:18:34 2018 +0530
> +++ b/source/encoder/encoder.cpp        Thu May 17 16:07:00 2018 +0530
> @@ -1233,26 +1233,27 @@
>                              int vbvCount = m_param->lookaheadDepth +
> m_param->bframes + 2;
>                              for (int index = 0; index < vbvCount; index++)
>                              {
> -                                pic_out->analysisData.lookahead.plannedSatd[index]
> = outFrame->m_lowres.plannedSatd[index] * factor;
> +                                pic_out->analysisData.lookahead.plannedSatd[index]
> = outFrame->m_lowres.plannedSatd[index];
>                                  pic_out->analysisData.lookahead.plannedType[index]
> = outFrame->m_lowres.plannedType[index];
>                              }
>                              for (uint32_t index = 0; index <
> pic_out->analysisData.numCuInHeight; index++)
>                              {
> -                                outFrame->m_analysisData.
> lookahead.intraSatdForVbv[index] = outFrame->m_encData->m_rowStat[index].intraSatdForVbv
> * factor;
> -                                outFrame->m_analysisData.lookahead.satdForVbv[index]
> = outFrame->m_encData->m_rowStat[index].satdForVbv * factor;
> +                                outFrame->m_analysisData.
> lookahead.intraSatdForVbv[index] = outFrame->m_encData->m_rowStat[index].
> intraSatdForVbv;
> +                                outFrame->m_analysisData.lookahead.satdForVbv[index]
> = outFrame->m_encData->m_rowStat[index].satdForVbv;
>                              }
>                              pic_out->analysisData.lookahead.intraSatdForVbv
> = outFrame->m_analysisData.lookahead.intraSatdForVbv;
>                              pic_out->analysisData.lookahead.satdForVbv =
> outFrame->m_analysisData.lookahead.satdForVbv;
>                              for (uint32_t index = 0; index <
> pic_out->analysisData.numCUsInFrame; index++)
>                              {
> -                                outFrame->m_analysisData.lookahead.intraVbvCost[index]
> = outFrame->m_encData->m_cuStat[index].intraVbvCost * factor;
> -                                outFrame->m_analysisData.lookahead.vbvCost[index]
> = outFrame->m_encData->m_cuStat[index].vbvCost * factor;
> +                                outFrame->m_analysisData.lookahead.intraVbvCost[index]
> = outFrame->m_encData->m_cuStat[index].intraVbvCost;
> +                                outFrame->m_analysisData.lookahead.vbvCost[index]
> = outFrame->m_encData->m_cuStat[index].vbvCost;
>                              }
>                              pic_out->analysisData.lookahead.intraVbvCost
> = outFrame->m_analysisData.lookahead.intraVbvCost;
>                              pic_out->analysisData.lookahead.vbvCost =
> outFrame->m_analysisData.lookahead.vbvCost;
>                          }
>                      }
>                      writeAnalysisFile(&pic_out->analysisData,
> *outFrame->m_encData);
> +                    pic_out->analysisData.saveParam =
> pic_out->analysisData.saveParam;
>                      if (m_param->bUseAnalysisFile)
>                          freeAnalysis(&pic_out->analysisData);
>                  }
> @@ -3411,6 +3412,21 @@
>          X265_FREAD(analysis->lookahead.vbvCost, sizeof(uint32_t),
> analysis->numCUsInFrame, m_analysisFileIn, picData->lookahead.vbvCost);
>          X265_FREAD(analysis->lookahead.satdForVbv, sizeof(uint32_t),
> analysis->numCuInHeight, m_analysisFileIn, picData->lookahead.satdForVbv);
>          X265_FREAD(analysis->lookahead.intraSatdForVbv,
> sizeof(uint32_t), analysis->numCuInHeight, m_analysisFileIn,
> picData->lookahead.intraSatdForVbv);
> +
> +        int vbvCount = m_param->lookaheadDepth + m_param->bframes + 2;
> +        for (int index = 0; index < vbvCount; index++)
> +            analysis->lookahead.plannedSatd[index] = picData->lookahead.plannedSatd[index]
> * (2 * m_param->scaleFactor);
> +
> +        for (uint32_t i = 0; i < analysis->numCuInHeight; i++)
> +        {
> +            analysis->lookahead.satdForVbv[i] = analysis->lookahead.satdForVbv[i]
> * (2* m_param->scaleFactor);
> +            analysis->lookahead.intraSatdForVbv[i] = analysis->lookahead.intraSatdForVbv[i]
> * (2 * m_param->scaleFactor);
> +        }
> +        for (uint32_t i = 0; i < analysis->numCUsInFrame; i++)
> +        {
> +            analysis->lookahead.vbvCost[i] =
> analysis->lookahead.vbvCost[i] * (2 * m_param->scaleFactor);
> +            analysis->lookahead.intraVbvCost[i] = analysis->lookahead.intraVbvCost[i]
> * (2 * m_param->scaleFactor);
> +        }
>      }
>      if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType ==
> X265_TYPE_I)
>      {
> @@ -3663,21 +3679,71 @@
>
>      int numPartitions = analysis->numPartitions;
>      int numCUsInFrame = analysis->numCUsInFrame;
> +    int numCuInHeight = analysis->numCuInHeight;
>      /* Allocate memory for scaled resoultion's numPartitions and
> numCUsInFrame*/
>      analysis->numPartitions = m_param->num4x4Partitions;
>      analysis->numCUsInFrame = cuLoc.heightInCU * cuLoc.widthInCU;
> +    analysis->numCuInHeight = cuLoc.heightInCU;
>
>      /* Memory is allocated for inter and intra analysis data based on the
> slicetype */
>      allocAnalysis(analysis);
>
>      analysis->numPartitions = numPartitions * factor;
>      analysis->numCUsInFrame = numCUsInFrame;
> +    analysis->numCuInHeight = numCuInHeight;
>      if (m_param->bDisableLookahead && m_rateControl->m_isVbv)
>      {
> -        X265_FREAD(analysis->lookahead.intraVbvCost, sizeof(uint32_t),
> analysis->numCUsInFrame, m_analysisFileIn, picData->lookahead.
> intraVbvCost);
> -        X265_FREAD(analysis->lookahead.vbvCost, sizeof(uint32_t),
> analysis->numCUsInFrame, m_analysisFileIn, picData->lookahead.vbvCost);
> -        X265_FREAD(analysis->lookahead.satdForVbv, sizeof(uint32_t),
> analysis->numCuInHeight, m_analysisFileIn, picData->lookahead.satdForVbv);
> -        X265_FREAD(analysis->lookahead.intraSatdForVbv,
> sizeof(uint32_t), analysis->numCuInHeight, m_analysisFileIn,
> picData->lookahead.intraSatdForVbv);
> +        uint32_t width = analysis->numCUsInFrame /
> analysis->numCuInHeight;
> +        bool skipLastRow = (analysis->numCuInHeight * 2) >
> cuLoc.heightInCU;
> +        bool skipLastCol = (width * 2) > cuLoc.widthInCU;
> +        uint32_t *intraVbvCostBuf = NULL, *vbvCostBuf = NULL,
> *satdForVbvBuf = NULL, *intraSatdForVbvBuf = NULL;
> +        intraVbvCostBuf = X265_MALLOC(uint32_t, analysis->numCUsInFrame);
> +        vbvCostBuf = X265_MALLOC(uint32_t, analysis->numCUsInFrame);
> +        satdForVbvBuf = X265_MALLOC(uint32_t, analysis->numCuInHeight);
> +        intraSatdForVbvBuf = X265_MALLOC(uint32_t,
> analysis->numCuInHeight);
> +
> +        X265_FREAD(intraVbvCostBuf, sizeof(uint32_t),
> analysis->numCUsInFrame, m_analysisFileIn, picData->lookahead.
> intraVbvCost);
> +        X265_FREAD(vbvCostBuf, sizeof(uint32_t), analysis->numCUsInFrame,
> m_analysisFileIn, picData->lookahead.vbvCost);
> +        X265_FREAD(satdForVbvBuf, sizeof(uint32_t),
> analysis->numCuInHeight, m_analysisFileIn, picData->lookahead.satdForVbv);
> +        X265_FREAD(intraSatdForVbvBuf, sizeof(uint32_t),
> analysis->numCuInHeight, m_analysisFileIn, picData->lookahead.
> intraSatdForVbv);
> +
> +        int k = 0;
> +        for (uint32_t i = 0; i < analysis->numCuInHeight; i++)
> +        {
> +            analysis->lookahead.satdForVbv[m_param->scaleFactor * i] =
> satdForVbvBuf[i] * m_param->scaleFactor;
> +            analysis->lookahead.intraSatdForVbv[m_param->scaleFactor *
> i] = intraSatdForVbvBuf[i] * m_param->scaleFactor;
> +            if (!(i == (analysis->numCuInHeight - 1) && skipLastRow))
> +            {
> +                analysis->lookahead.satdForVbv[(m_param->scaleFactor *
> i) + 1] = satdForVbvBuf[i] * m_param->scaleFactor;
> +                analysis->lookahead.intraSatdForVbv[(m_param->scaleFactor
> * i) + 1] = intraSatdForVbvBuf[i] * m_param->scaleFactor;
> +            }
> +
> +            for (uint32_t j = 0; j < width; j++, k++)
> +            {
> +                analysis->lookahead.vbvCost[(i * m_param->scaleFactor *
> cuLoc.widthInCU) + (j * m_param->scaleFactor)] = vbvCostBuf[k];
> +                analysis->lookahead.intraVbvCost[(i *
> m_param->scaleFactor * cuLoc.widthInCU) + (j * m_param->scaleFactor)] =
> intraVbvCostBuf[k];
> +
> +                if (!(j == (width - 1) && skipLastCol))
> +                {
> +                    analysis->lookahead.vbvCost[(i * m_param->scaleFactor
> * cuLoc.widthInCU) + (j * m_param->scaleFactor) + 1] = vbvCostBuf[k];
> +                    analysis->lookahead.intraVbvCost[(i *
> m_param->scaleFactor * cuLoc.widthInCU) + (j * m_param->scaleFactor) + 1] =
> intraVbvCostBuf[k];
> +                }
> +                if (!(i == (analysis->numCuInHeight - 1) && skipLastRow))
> +                {
> +                    analysis->lookahead.vbvCost[(i * m_param->scaleFactor
> * cuLoc.widthInCU) + cuLoc.widthInCU + (j * m_param->scaleFactor)] =
> vbvCostBuf[k];
> +                    analysis->lookahead.intraVbvCost[(i *
> m_param->scaleFactor * cuLoc.widthInCU) + cuLoc.widthInCU + (j *
> m_param->scaleFactor)] = intraVbvCostBuf[k];
> +                    if (!(j == (width - 1) && skipLastCol))
> +                    {
> +                        analysis->lookahead.vbvCost[(i *
> m_param->scaleFactor * cuLoc.widthInCU) + cuLoc.widthInCU + (j *
> m_param->scaleFactor) + 1] = vbvCostBuf[k];
> +                        analysis->lookahead.intraVbvCost[(i *
> m_param->scaleFactor * cuLoc.widthInCU) + cuLoc.widthInCU + (j *
> m_param->scaleFactor) + 1] = intraVbvCostBuf[k];
> +                    }
> +                }
> +            }
> +        }
> +        X265_FREE(satdForVbvBuf);
> +        X265_FREE(intraSatdForVbvBuf);
> +        X265_FREE(intraVbvCostBuf);
> +        X265_FREE(vbvCostBuf);
>      }
>
>      if (analysis->sliceType == X265_TYPE_IDR || analysis->sliceType ==
> X265_TYPE_I)
> @@ -3912,6 +3978,7 @@
>      /* Restore to the current encode's numPartitions and numCUsInFrame */
>      analysis->numPartitions = m_param->num4x4Partitions;
>      analysis->numCUsInFrame = cuLoc.heightInCU * cuLoc.widthInCU;
> +    analysis->numCuInHeight = cuLoc.heightInCU;
>  #undef X265_FREAD
>  }
>
> @@ -3944,23 +4011,23 @@
>      }\
>      count++;\
>
> -    x265_analysis_validate saveParam = analysis->saveParam;
> +    x265_analysis_validate *saveParam = &analysis->saveParam;
>      FILE*     fileOffset = NULL;
>      int       readValue = 0;
>      int       count = 0;
>
> -    X265_PARAM_VALIDATE(saveParam.maxNumReferences, sizeof(int), 1,
> &m_param->maxNumReferences);
> -    X265_PARAM_VALIDATE(saveParam.analysisReuseLevel, sizeof(int), 1,
> &m_param->analysisReuseLevel);
> -    X265_PARAM_VALIDATE(saveParam.scaleFactor, sizeof(int), 1,
> &m_param->scaleFactor);
> -    X265_PARAM_VALIDATE(saveParam.keyframeMax, sizeof(int), 1,
> &m_param->keyframeMax);
> -    X265_PARAM_VALIDATE(saveParam.keyframeMin, sizeof(int), 1,
> &m_param->keyframeMin);
> -    X265_PARAM_VALIDATE(saveParam.openGOP, sizeof(int), 1,
> &m_param->bOpenGOP);
> -    X265_PARAM_VALIDATE(saveParam.bframes, sizeof(int), 1,
> &m_param->bframes);
> -    X265_PARAM_VALIDATE(saveParam.bPyramid, sizeof(int), 1,
> &m_param->bBPyramid);
> +    X265_PARAM_VALIDATE(saveParam->maxNumReferences, sizeof(int), 1,
> &m_param->maxNumReferences);
> +    X265_PARAM_VALIDATE(saveParam->analysisReuseLevel, sizeof(int), 1,
> &m_param->analysisReuseLevel);
> +    X265_PARAM_VALIDATE(saveParam->scaleFactor, sizeof(int), 1,
> &m_param->scaleFactor);
> +    X265_PARAM_VALIDATE(saveParam->keyframeMax, sizeof(int), 1,
> &m_param->keyframeMax);
> +    X265_PARAM_VALIDATE(saveParam->keyframeMin, sizeof(int), 1,
> &m_param->keyframeMin);
> +    X265_PARAM_VALIDATE(saveParam->openGOP, sizeof(int), 1,
> &m_param->bOpenGOP);
> +    X265_PARAM_VALIDATE(saveParam->bframes, sizeof(int), 1,
> &m_param->bframes);
> +    X265_PARAM_VALIDATE(saveParam->bPyramid, sizeof(int), 1,
> &m_param->bBPyramid);
>      /* Enable m_saveCTUSize if the save and load encodes have the same
> maxCU size */
>      if (writeFlag)
>      {
> -        X265_PARAM_VALIDATE(saveParam.maxCUSize, sizeof(int), 1,
> &m_param->maxCUSize);
> +        X265_PARAM_VALIDATE(saveParam->maxCUSize, sizeof(int), 1,
> &m_param->maxCUSize);
>      }
>      else
>      {
> @@ -3971,7 +4038,7 @@
>              m_aborted = true;
>          }
>          else if (!m_param->bUseAnalysisFile)
> -            readValue = saveParam.maxCUSize;
> +            readValue = saveParam->maxCUSize;
>
>          m_saveCTUSize = 0;
>          if (m_param->scaleFactor && g_log2Size[m_param->maxCUSize] ==
> g_log2Size[readValue])
> @@ -3983,10 +4050,10 @@
>          }
>          count++;
>      }
> -    X265_PARAM_VALIDATE(saveParam.minCUSize, sizeof(int), 1,
> &m_param->minCUSize);
> -    X265_PARAM_VALIDATE(saveParam.radl, sizeof(int), 1, &m_param->radl);
> -    X265_PARAM_VALIDATE(saveParam.lookaheadDepth, sizeof(int), 1,
> &m_param->lookaheadDepth);
> -    X265_PARAM_VALIDATE(saveParam.gopLookahead, sizeof(int), 1,
> &m_param->gopLookahead);
> +    X265_PARAM_VALIDATE(saveParam->minCUSize, sizeof(int), 1,
> &m_param->minCUSize);
> +    X265_PARAM_VALIDATE(saveParam->radl, sizeof(int), 1, &m_param->radl);
> +    X265_PARAM_VALIDATE(saveParam->lookaheadDepth, sizeof(int), 1,
> &m_param->lookaheadDepth);
> +    X265_PARAM_VALIDATE(saveParam->gopLookahead, sizeof(int), 1,
> &m_param->gopLookahead);
>      return (count * sizeof(int));
>  #undef X265_PARAM_VALIDATE
>  }
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
>
Pushed.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20180517/54cef637/attachment-0001.html>


More information about the x265-devel mailing list