[x265] [PATCH] vbv: lookahead

Steve Borho steve at borho.org
Wed Feb 12 08:46:34 CET 2014


On Wed, Feb 12, 2014 at 1:33 AM, <santhoshini at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Santhoshini Sekar <santhoshini at multicorewareinc.com>
> # Date 1392189204 -19800
> #      Wed Feb 12 12:43:24 2014 +0530
> # Node ID e83af58ed0f3a9308dacf64f79b9ddad47cd0170
> # Parent  699f2aa335e9995e32a07181eb70bd1ed1dfb7e9
> vbv: lookahead
>
> diff -r 699f2aa335e9 -r e83af58ed0f3 source/common/lowres.h
> --- a/source/common/lowres.h    Tue Feb 11 13:06:43 2014 +0530
> +++ b/source/common/lowres.h    Wed Feb 12 12:43:24 2014 +0530
> @@ -121,6 +121,8 @@
>      uint16_t(*lowresCosts[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]);
>      int32_t*  lowresMvCosts[2][X265_BFRAME_MAX + 1];
>      MV*       lowresMvs[2][X265_BFRAME_MAX + 1];
> +    int       plannedType[X265_LOOKAHEAD_MAX+1];
> +    int64_t   plannedSatd[X265_LOOKAHEAD_MAX+1];
>
>      /* rate control / adaptive quant data */
>      double*   qpAqOffset;      // qp Aq offset values for each Cu
> diff -r 699f2aa335e9 -r e83af58ed0f3 source/encoder/ratecontrol.cpp
> --- a/source/encoder/ratecontrol.cpp    Tue Feb 11 13:06:43 2014 +0530
> +++ b/source/encoder/ratecontrol.cpp    Wed Feb 12 12:43:24 2014 +0530
> @@ -384,7 +384,7 @@
>      {
>          lastSatd = l->getEstimatedPictureCost(pic);
>          rce->lastSatd = lastSatd;
> -        double q = qScale2qp(rateEstimateQscale(rce));
> +        double q = qScale2qp(rateEstimateQscale(pic, rce));
>          qp = Clip3(MIN_QP, MAX_MAX_QP, (int)(q + 0.5));
>          rce->qpaRc = q;
>          /* copy value of lastRceq into thread local rce struct *to be
> used in RateControlEnd() */
> @@ -416,7 +416,7 @@
>          accumPQp += qp;
>  }
>
> -double RateControl::rateEstimateQscale(RateControlEntry *rce)
> +double RateControl::rateEstimateQscale(TComPic* pic, RateControlEntry
> *rce)
>  {
>      double q;
>
> @@ -558,7 +558,7 @@
>          double lmax1 = lmax[sliceType];
>          q = Clip3(lmin1, lmax1, q);
>
> -        q = clipQscale(q);
> +        q = clipQscale(pic, q);
>
>          lastQScaleFor[sliceType] = q;
>
> @@ -614,7 +614,7 @@
>      return (p->coeff * var + p->offset) / (q * p->count);
>  }
>
> -double RateControl::clipQscale(double q)
> +double RateControl::clipQscale(TComPic* pic, double q)
>  {
>      double lmin1 = lmin[sliceType];
>      double lmax1 = lmax[sliceType];
> @@ -624,8 +624,55 @@
>      // since they are controlled by the P-frames' QPs.
>      if (isVbv && lastSatd > 0)
>      {
> -        //if (lookahead){} //for lookahead
> -        //else
> +       if (cfg->param.lookaheadDepth)
>

white-space


> +        {
> +            int terminate = 0;
> +
> +            /* Avoid an infinite loop. */
> +            for (int iterations = 0; iterations < 1000 && terminate != 3;
> iterations++)
> +            {
> +                double frameQ[3];
> +                double curBits = predictSize(&pred[sliceType], q,
> (double)lastSatd);
> +                double bufferFillCur = bufferFill - curBits;
> +                double targetFill;
> +                double totalDuration = 0;
> +                frameQ[0] = sliceType == I_SLICE ? q *
> cfg->param.rc.ipFactor : q;
> +                frameQ[1] = frameQ[0] * cfg->param.rc.pbFactor;
> +                frameQ[2] = frameQ[0] / cfg->param.rc.ipFactor;
> +
> +                /* Loop over the planned future frames. */
> +                for (int j = 0; bufferFillCur >= 0 && bufferFillCur <=
> bufferSize; j++)
> +                {
> +                    totalDuration += frameDuration;
> +                    bufferFillCur += vbvMaxRate * frameDuration;
> +                    int type = pic->m_lowres.plannedType[j];
> +                    int64_t satd = pic->m_lowres.plannedSatd[j];
> +                    if (type == X265_TYPE_AUTO)
> +                        break;
> +                    type = IS_X265_TYPE_I(type) ? I_SLICE :
> IS_X265_TYPE_B(type) ? B_SLICE : P_SLICE;
> +                    curBits = predictSize(&pred[type], frameQ[type],
> (double)satd);
> +                    bufferFillCur -= curBits;
> +                }
> +                /* Try to get the buffer at least 50% filled, but don't
> set an impossible goal. */
> +                targetFill = X265_MIN(bufferFill + totalDuration *
> vbvMaxRate * 0.5, bufferSize * 0.5);
> +                if (bufferFillCur < targetFill)
> +                {
> +                    q *= 1.01;
> +                    terminate |= 1;
> +                    continue;
> +                }
> +                /* Try to get the buffer no more than 80% filled, but
> don't set an impossible goal. */
> +                targetFill = Clip3(bufferFill - totalDuration *
> vbvMaxRate * 0.5, bufferSize * 0.8, bufferSize);
> +                if (vbvMinRate && bufferFillCur > targetFill)
> +                {
> +                    q /= 1.01;
> +                    terminate |= 2;
> +                    continue;
> +                }
> +                break;
> +            }
> +        }
> +        else
>          {
>              if ((sliceType == P_SLICE ||
>                   (sliceType == I_SLICE && lastNonBPictType == I_SLICE)) &&
> diff -r 699f2aa335e9 -r e83af58ed0f3 source/encoder/ratecontrol.h
> --- a/source/encoder/ratecontrol.h      Tue Feb 11 13:06:43 2014 +0530
> +++ b/source/encoder/ratecontrol.h      Wed Feb 12 12:43:24 2014 +0530
> @@ -129,13 +129,13 @@
>  protected:
>
>      double getQScale(RateControlEntry *rce, double rateFactor);
> -    double rateEstimateQscale(RateControlEntry *rce); // main logic for
> calculating QP based on ABR
> +    double rateEstimateQscale(TComPic* pic, RateControlEntry *rce); //
> main logic for calculating QP based on ABR
>      void accumPQpUpdate();
>      uint32_t acEnergyCu(TComPic* pic, uint32_t block_x, uint32_t block_y);
>
>      void updateVbv(int64_t bits, RateControlEntry* rce);
>      void updatePredictor(Predictor *p, double q, double var, double bits);
> -    double clipQscale(double q);
> +    double clipQscale(TComPic* pic, double q);
>      void updateVbvPlan(Encoder* enc);
>      double predictSize(Predictor *p, double q, double var);
>      void checkAndResetABR(RateControlEntry* rce);
> diff -r 699f2aa335e9 -r e83af58ed0f3 source/encoder/slicetype.cpp
> --- a/source/encoder/slicetype.cpp      Tue Feb 11 13:06:43 2014 +0530
> +++ b/source/encoder/slicetype.cpp      Wed Feb 12 12:43:24 2014 +0530
> @@ -373,13 +373,57 @@
>      }
>  }
>
> +void Lookahead::vbvLookahead(Lowres **frames, int numFrames, int keyframe)
> +{
> +    int prevNonB = 0, curNonB = 1, idx = 0;
> +    while (curNonB < numFrames && frames[curNonB]->sliceType ==
> X265_TYPE_B)
> +        curNonB++;
> +    int nextNonB = keyframe ? prevNonB : curNonB;
> +
> +    while (curNonB < numFrames)
> +    {
> +        /* P/I cost: This shouldn't include the cost of nextNonB */
> +        if (nextNonB != curNonB)
> +        {
> +            int p0 = IS_X265_TYPE_I(frames[curNonB]->sliceType) ? curNonB
> : prevNonB;
> +            frames[nextNonB]->plannedSatd[idx] = vbvFrameCost(frames, p0,
> curNonB, curNonB);
> +            frames[nextNonB]->plannedType[idx] =
> frames[curNonB]->sliceType;
> +            idx++;
> +        }
> +        /* Handle the B-frames: coded order */
> +        for (int i = prevNonB+1; i < curNonB; i++, idx++)
> +        {
> +            frames[nextNonB]->plannedSatd[idx] = vbvFrameCost(frames,
> prevNonB, curNonB, i);
> +            frames[nextNonB]->plannedType[idx] = X265_TYPE_B;
> +        }
> +        prevNonB = curNonB;
> +        curNonB++;
> +        while (curNonB <= numFrames && frames[curNonB]->sliceType ==
> X265_TYPE_B)
> +            curNonB++;
> +    }
> +    frames[nextNonB]->plannedType[idx] = X265_TYPE_AUTO;
> +}
> +
> +int64_t Lookahead::vbvFrameCost(Lowres **frames, int p0, int p1, int b)
> +{
> +    int64_t cost = est.estimateFrameCost(frames, p0, p1, b, 0);
> +    if (cfg->param.rc.aqMode)
> +    {
> +        if (cfg->param.rc.cuTree)
> +            return frameCostRecalculate(frames, p0, p1, b);
> +        else
> +            return frames[b]->costEstAq[b-p0][p1-b];
> +    }
> +    return cost;
> +}
> +
>  void Lookahead::slicetypeAnalyse(Lowres **frames, bool bKeyframe)
>  {
>      int numFrames, origNumFrames, keyintLimit, framecnt;
>      int maxSearch = X265_MIN(cfg->param.lookaheadDepth,
> X265_LOOKAHEAD_MAX);
>      int cuCount = NUM_CUS;
>      int resetStart;
> -
> +    int isVbvLookahead = cfg->param.rc.vbvBufferSize &&
> cfg->param.lookaheadDepth;
>

we generally use bools for this:

bool bIsVbvLookahead


>      if (!lastNonB)
>          return;
>
> @@ -403,7 +447,9 @@
>      keyintLimit = cfg->param.keyframeMax - frames[0]->frameNum +
> lastKeyframe - 1;
>      origNumFrames = numFrames = X265_MIN(framecnt, keyintLimit);
>
> -    if (cfg->param.bOpenGOP && numFrames < framecnt)
> +    if (isVbvLookahead)
> +        numFrames = framecnt;
> +    else if (cfg->param.bOpenGOP && numFrames < framecnt)
>          numFrames++;
>      else if (numFrames == 0)
>      {
> @@ -538,6 +584,9 @@
>          resetStart = X265_MIN(resetStart, j + 1);
>      }
>
> +        if (isVbvLookahead)
>

white-space


> +        vbvLookahead(frames, numFrames, bKeyframe);
> +
>      /* Restore frametypes for all frames that haven't actually been
> decided yet. */
>      for (int j = resetStart; j <= numFrames; j++)
>      {
> diff -r 699f2aa335e9 -r e83af58ed0f3 source/encoder/slicetype.h
> --- a/source/encoder/slicetype.h        Tue Feb 11 13:06:43 2014 +0530
> +++ b/source/encoder/slicetype.h        Wed Feb 12 12:43:24 2014 +0530
> @@ -151,6 +151,8 @@
>      bool    scenecutInternal(Lowres **frames, int p0, int p1, bool
> bRealScenecut);
>      void    slicetypePath(Lowres **frames, int length,
> char(*best_paths)[X265_LOOKAHEAD_MAX + 1]);
>      int64_t slicetypePathCost(Lowres **frames, char *path, int64_t
> threshold);
> +    int64_t vbvFrameCost(Lowres **frames, int p0, int p1, int b);
> +    void vbvLookahead(Lowres **frames, int numFrames, int keyframes);
>

line-up the function names


>
>      /* called by slicetypeAnalyse() to effect cuTree adjustments to
> adaptive
>       * quant offsets */
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>



-- 
Steve Borho
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20140212/725fc8a9/attachment-0001.html>


More information about the x265-devel mailing list