[x265] [PATCH RFC] 1. Bug fix - improved quality drop for low resolution videos in ABR by 5%

Sumalatha Polureddy sumalatha at multicorewareinc.com
Fri Sep 13 13:57:05 CEST 2013


 since changed commit message - sending it as new patch. ignore the
previous mail


On Fri, Sep 13, 2013 at 4:51 PM, Sumalatha Polureddy <
sumalatha at multicorewareinc.com> wrote:

> modified according to comments in this thread
>
>
>
> # HG changeset patch
> # User sumalatha polureddy
> # Date 1379070966 -19800
> # Node ID 540be38baa71ba76e8502dbae8b8f4a4024cdb8d
> # Parent  64cde4a0b1759e2033d99bec709db6acfbe0f07a
> ratecontrol: Tweak to better handle short term compensation
> Increase the coefficient cplxrSum is adjusted by so that short term
> compensation does not suffer as much.
>
> Also, clip the QP for the first frame.
>
> Overall improvement is about 5%.
>
> diff -r 64cde4a0b175 -r 540be38baa71 source/encoder/ratecontrol.cpp
> --- a/source/encoder/ratecontrol.cpp Fri Sep 13 16:40:56 2013 +0530
> +++ b/source/encoder/ratecontrol.cpp Fri Sep 13 16:46:06 2013 +0530
> @@ -72,11 +72,12 @@
>      shortTermCplxCount = 0;
>      if (rateControlMode == X265_RC_ABR)
>      {
> -        //TODO : confirm this value. obtained it from x264 when crf is
> disabled , abr enabled.
> -        //h->param.rc.i_rc_method == X264_RC_CRF ?
> h->param.rc.f_rf_constant : 24  -- can be tweaked for x265.
> -#define ABR_INIT_QP (24  + QP_BD_OFFSET)
> +
> +        //introduced to margin QP for first frame to an optimum level in
> order to stabilize the quality.
> +#define ABR_INIT_QP_MIN (24 + QP_BD_OFFSET)
> +#define ABR_INIT_QP_MAX (38 + QP_BD_OFFSET)
>          accumPNorm = .01;
> -        accumPQp = (ABR_INIT_QP)*accumPNorm;
> +        accumPQp = (ABR_INIT_QP_MIN) * accumPNorm;
>          /* estimated ratio that produces a reasonable QP for the first
> I-frame  */
>          cplxrSum = .01 * pow(7.0e5, qCompress) * pow(2 *ncu, 0.5);
>          wantedBitsWindow = bitrate * frameDuration;
> @@ -86,7 +87,7 @@
>      pbOffset = 6.0 * (float)(X265_LOG2(param->rc.pbFactor));
>      for (int i = 0; i < 3; i++)
>      {
> -        lastQScaleFor[i] = qp2qScale(ABR_INIT_QP);
> +        lastQScaleFor[i] = qp2qScale(ABR_INIT_QP_MIN);
>          lmin[i] = qp2qScale(MIN_QP);
>          lmax[i] = qp2qScale(MAX_QP);
>      }
> @@ -111,15 +112,15 @@
>      switch (rateControlMode)
>      {
>      case X265_RC_ABR:
> -        {
> -            lastSatd = l->getEstimatedPictureCost(pic);
> -            double q = qScale2qp(rateEstimateQscale(rce));
> -            qp = Clip3(MIN_QP, MAX_QP, (int)(q + 0.5));
> -            rce->qpaRc = qpm = q;
> -            rce->newQp = qp;
> -            accumPQpUpdate();
> -            break;
> -        }
> +    {
> +        lastSatd = l->getEstimatedPictureCost(pic);
> +        double q = qScale2qp(rateEstimateQscale(rce));
> +        qp = Clip3(MIN_QP, MAX_QP, (int)(q + 0.5));
> +        rce->qpaRc = qpm = q;
> +        rce->newQp = qp;
> +        accumPQpUpdate();
> +        break;
> +    }
>
>      case X265_RC_CQP:
>          qp = qpConstant[frameType];
> @@ -160,16 +161,19 @@
>      {
>          /* B-frames don't have independent rate control, but rather get
> the
>           * average QP of the two adjacent P-frames + an offset */
> +        TComSlice* prevRefSlice = curFrame->getRefPic(REF_PIC_LIST_0,
> 0)->getSlice();
> +        TComSlice* nextRefSlice = curFrame->getRefPic(REF_PIC_LIST_1,
> 0)->getSlice();
> +        bool i0 = prevRefSlice->getSliceType() == I_SLICE;
> +        bool i1 = nextRefSlice->getSliceType() == I_SLICE;
> +        int dt0 = abs(curFrame->getPOC() - prevRefSlice->getPOC());
> +        int dt1 = abs(curFrame->getPOC() - nextRefSlice->getPOC());
> +        double q0 = prevRefSlice->getSliceQp();
> +        double q1 = nextRefSlice->getSliceQp();
>
> -        int i0 = curFrame->getRefPic(REF_PIC_LIST_0,
> 0)->getSlice()->getSliceType() == I_SLICE;
> -        int i1 = curFrame->getRefPic(REF_PIC_LIST_1,
> 0)->getSlice()->getSliceType() == I_SLICE;
> -        int dt0 = abs(curFrame->getPOC() -
> curFrame->getRefPic(REF_PIC_LIST_0, 0)->getPOC());
> -        int dt1 = abs(curFrame->getPOC() -
> curFrame->getRefPic(REF_PIC_LIST_1, 0)->getPOC());
> -
> -        //TODO:need to figure out this
> -        double q0 = curFrame->getRefPic(REF_PIC_LIST_0,
> 0)->getSlice()->getSliceQp();
> -        double q1 = curFrame->getRefPic(REF_PIC_LIST_1,
> 0)->getSlice()->getSliceQp();
> -
> +        if (prevRefSlice->getSliceType() == B_SLICE &&
> prevRefSlice->isReferenced())
> +            q0 -= pbOffset / 2;
> +        if (nextRefSlice->getSliceType() == B_SLICE &&
> nextRefSlice->isReferenced())
> +            q1 -= pbOffset / 2;
>          if (i0 && i1)
>              q = (q0 + q1) / 2 + ipOffset;
>          else if (i0)
> @@ -183,12 +187,8 @@
>              q += pbOffset / 2;
>          else
>              q += pbOffset;
> -
> -        double qScale = qp2qScale(q);
>
> -        lastQScaleFor[P_SLICE] = lastQScale = qScale/pbFactor;
> -
> -        return qScale;
> +        return qp2qScale(q);
>      }
>      else
>      {
> @@ -242,21 +242,32 @@
>              q = qp2qScale(accumPQp / accumPNorm);
>              q /= fabs(ipFactor);
>          }
> -        else if (curFrame->getPOC() > 0)
> +        if (rateControlMode != X265_RC_CRF)
>          {
> -            if (rateControlMode != X265_RC_CRF)
> +            double lqmin = 0, lqmax = 0;
> +
> +            /* Clip the qp of 1st frame to ensure it doesnt detoriate the
> quality */
> +            if (curFrame->getPOC() == 0)
>              {
> -                /* Asymmetric clipping, because symmetric would prevent
> -                 * overflow control in areas of rapidly oscillating
> complexity */
> -                double lqmin = lastQScaleFor[pictType] / lstep;
> -                double lqmax = lastQScaleFor[pictType] * lstep;
> -                if (overflow > 1.1 && curFrame->getPOC() > 3)
> -                    lqmax *= lstep;
> -                else if (overflow < 0.9)
> -                    lqmin /= lstep;
> +                lqmin = qp2qScale(ABR_INIT_QP_MIN) / lstep;
> +                lqmax = qp2qScale(ABR_INIT_QP_MAX) * lstep;
> +                double l1 = qScale2qp(lqmin);
> +                double l2 = qScale2qp(lqmax);
> +                    l1=l2;
> +            }
> +            /* Asymmetric clipping, because symmetric would prevent
> +             * overflow control in areas of rapidly oscillating
> complexity */
> +            else if (curFrame->getPOC() > 0)
> +            {
> +                lqmin = lastQScaleFor[pictType] / lstep;
> +                lqmax = lastQScaleFor[pictType] * lstep;
> +            }
> +            if (overflow > 1.1 && curFrame->getPOC() > 3)
> +                lqmax *= lstep;
> +            else if (overflow < 0.9)
> +                lqmin /= lstep;
>
> -                q = Clip3(lqmin, lqmax, q);
> -            }
> +            q = Clip3(lqmin, lqmax, q);
>          }
>
>          //FIXME use get_diff_limited_q() ?
> @@ -300,16 +311,18 @@
>      if (rateControlMode == X265_RC_ABR)
>      {
>          if (frameType != B_SLICE)
> -            cplxrSum +=  1.1 *bits * qp2qScale(rce->qpaRc) /
> rce->lastRceq;
> +            /* The factor 1.5 is to tune up the actual bits, otherwise
> the cplxrSum is scaled too low
> +             * to improve short term compensation for next frame. */
> +            cplxrSum += 1.5 *bits * qp2qScale(rce->qpaRc) / rce->lastRceq;
>          else
>          {
>              /* Depends on the fact that B-frame's QP is an offset from
> the following P-frame's.
>               * Not perfectly accurate with B-refs, but good enough. */
> -            cplxrSum += bits * qp2qScale(rce->qpaRc) / (rce->lastRceq *
> fabs(0.5 * pbFactor));
> +            cplxrSum += bits * qp2qScale(rce->qpaRc) / (rce->lastRceq *
> fabs(pbFactor));
>          }
>          cplxrSum *= cbrDecay;
>          wantedBitsWindow += frameDuration * bitrate;
> -        wantedBitsWindow *= cbrDecay;
> +        wantedBitsWindow *= cbrDecay;
>          rce = NULL;
>      }
>      totalBits += bits;
>
>
>
> On Fri, Sep 13, 2013 at 4:23 PM, Derek Buitenhuis <
> derek.buitenhuis at gmail.com> wrote:
>
>> On 9/13/2013 11:50 AM, Aarthi Priya Thirumalai wrote:
>> >  The qscale values are clipped(for P frames)  depending on the
>> lastQScaleFor[] at the end to ensure qps dont increase too high/low. they
>> are updated in rateEstimateQScale for non B frames. The above change was
>> introduced so that qp for P frames can adapt based on the qp of  preceding
>> B frames  too -  to see if its improves RateControl. Since it didnt give
>> any big improvements, removing the change.
>>
>> Ah, OK then.
>>
>> - Derek
>> _______________________________________________
>> 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/20130913/79ec7ffa/attachment-0001.html>


More information about the x265-devel mailing list