since changed commit message - sending it as new patch. ignore the previous mail
On Fri, Sep 13, 2013 at 4:51 PM, Sumalatha Polureddy < [email protected]> 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 < > [email protected]> 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 >> [email protected] >> https://mailman.videolan.org/listinfo/x265-devel >> > >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
