[x265] [PATCH] abr: reset ABR to prevent high bitrate peaks in single pass ABR
Steve Borho
steve at borho.org
Sun Feb 2 19:38:34 CET 2014
On Sun, Feb 2, 2014 at 6:37 AM, Aarthi Priya Thirumalai <
aarthi at multicorewareinc.com> wrote:
> # HG changeset patch
> # User Aarthi Thirumalai
> # Date 1391343895 -19800
> # Sun Feb 02 17:54:55 2014 +0530
> # Node ID bf00f495951eb882e34225740c43540311bf51cb
> # Parent bb33ab0f4ef933315cedf388d70443bc97fefeea
> abr: reset ABR to prevent high bitrate peaks in single pass ABR .
>
> Long series of blank frames in video followed by detailed content causes
> heavy ABR underflow and overall bitrates surges high for a long while.
> patch detects this condition in Single pass ABR mode and resets ABR - to
> not consider history from blank frames and continue from following
> scene-cut.
>
The patch behavior seems reasonable, given what was documented in another
email, however lots of coding style nits.
>
> diff -r bb33ab0f4ef9 -r bf00f495951e source/encoder/ratecontrol.cpp
> --- a/source/encoder/ratecontrol.cpp Sat Feb 01 16:39:12 2014 -0600
> +++ b/source/encoder/ratecontrol.cpp Sun Feb 02 17:54:55 2014 +0530
> @@ -240,7 +240,7 @@
> shortTermCplxCount = 0;
> framesDone = 0;
> lastNonBPictType = I_SLICE;
> -
> + isAbrReset = false;
> // vbv initialization
> cfg->param.rc.vbvBufferSize = Clip3(0, 2000000,
> cfg->param.rc.vbvBufferSize);
> cfg->param.rc.vbvMaxBitrate = Clip3(0, 2000000,
> cfg->param.rc.vbvMaxBitrate);
> @@ -375,12 +375,12 @@
> if (isAbr) //ABR,CRF
> {
> lastSatd = l->getEstimatedPictureCost(pic);
> + rce->lastSatd = lastSatd;
> double q = qScale2qp(rateEstimateQscale(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() */
> rce->qRceq = lastRceq;
> - rce->lastSatd = lastSatd;
> accumPQpUpdate();
> }
> else //CQP
> @@ -464,6 +464,7 @@
> * tolerances, the bit distribution approaches that of 2pass. */
>
> double wantedBits, overflow = 1;
> + rce->movingAvgSum = shortTermCplxSum;
> shortTermCplxSum *= 0.5;
> shortTermCplxCount *= 0.5;
> shortTermCplxSum += lastSatd / (CLIP_DURATION(frameDuration) /
> BASE_FRAME_DURATION);
> @@ -479,6 +480,8 @@
> }
> else
> {
> + if (!isVbv)
> + checkAndResetABR(rce);
> q = getQScale(rce, wantedBitsWindow / cplxrSum);
>
> /* ABR code can potentially be counterproductive in CBR, so
> just don't bother.
> @@ -498,7 +501,7 @@
> }
>
> if (sliceType == I_SLICE && cfg->param.keyframeMax > 1
> - && lastNonBPictType != I_SLICE)
> + && lastNonBPictType != I_SLICE && !isAbrReset)
> {
> q = qp2qScale(accumPQp / accumPNorm);
> q /= fabs(cfg->param.rc.ipFactor);
> @@ -539,7 +542,7 @@
>
> lastQScaleFor[sliceType] = q;
>
> - if (curSlice->getPOC() == 0)
> + if (curSlice->getPOC() == 0 || (isAbrReset && sliceType ==
> I_SLICE))
> lastQScaleFor[P_SLICE] = q * fabs(cfg->param.rc.ipFactor);
>
> rce->frameSizePlanned = predictSize(&pred[sliceType], q,
> (double)lastSatd);
> @@ -548,6 +551,35 @@
> }
> }
>
> +void RateControl::checkAndResetABR( RateControlEntry* rce )
>
white-space
> +{
> + double abrBuffer = 2 * cfg->param.rc.rateTolerance * bitrate;
> + // Check if current SLice is a scene cut that follow low
> detailed/blank frames
>
'slice' can be all lower case, `follow` should be follows
> + if (rce->lastSatd > 4 * rce->movingAvgSum)
> + {
> + if (!isAbrReset && rce->movingAvgSum > 0 )
>
ws
> + {
> + // Reset ABR if prev frames are blank to prevent further
> sudden overflows/ high bit rate spikes.
> + double underflow = 1.0 + (totalBits - wantedBitsWindow) /
> abrBuffer;
> + if (underflow < 1 && curSlice->m_avgQpRc==0)
>
ws
> + {
> + totalBits = 0;
> + framesDone = 0;
> + cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5);
> + wantedBitsWindow = bitrate * frameDuration;
> + accumPNorm = .01;
> + accumPQp = (ABR_INIT_QP_MIN)*accumPNorm;
> + isAbrReset = true;
> + }
> + }
> + // Clear flag to reset ABR and continue as usual.
>
we generally place else comments within the else braces
> + else
> + {
> + isAbrReset = false;
> + }
> + }
> +}
> +
> void RateControl::updateVbvPlan(Encoder* enc)
> {
> bufferFill = bufferFillFinal;
> @@ -706,19 +738,25 @@
> {
> if (isAbr)
> {
> - if (rce->sliceType != B_SLICE)
> - /* 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 += bits * qp2qScale(rce->qpaRc) / rce->qRceq;
> - else
> + if (!isVbv)
> + checkAndResetABR(rce);
> +
> + if(!isAbrReset)
>
ws
> {
> - /* 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->qRceq *
> fabs(cfg->param.rc.pbFactor));
> + if (rce->sliceType != B_SLICE)
> + /* 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 += bits * qp2qScale(rce->qpaRc) / rce->qRceq;
> + 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->qRceq *
> fabs(cfg->param.rc.pbFactor));
> + }
> + wantedBitsWindow += frameDuration * bitrate;
> + totalBits += bits;
> }
> - wantedBitsWindow += frameDuration * bitrate;
> }
> - totalBits += bits;
>
> if (isVbv)
> {
> @@ -732,8 +770,9 @@
> bframeBits = 0;
> }
> }
> + updateVbv(bits, rce);
> }
>
> - updateVbv(bits, rce);
> +
> return 0;
> }
> diff -r bb33ab0f4ef9 -r bf00f495951e source/encoder/ratecontrol.h
> --- a/source/encoder/ratecontrol.h Sat Feb 01 16:39:12 2014 -0600
> +++ b/source/encoder/ratecontrol.h Sun Feb 02 17:54:55 2014 +0530
> @@ -60,6 +60,7 @@
> double qRceq;
> double frameSizePlanned;
> double bufferRate;
> + double movingAvgSum;
> };
>
> struct Predictor
> @@ -97,7 +98,7 @@
> int bframes;
> int bframeBits;
> double leadingNoBSatd;
> -
> + bool isAbrReset;
> int64_t lastSatd;
> int qpConstant[3];
> double cplxrSum; /* sum of bits*qscale/rceq */
> @@ -136,6 +137,7 @@
> double clipQscale(double q);
> void updateVbvPlan(Encoder* enc);
> double predictSize(Predictor *p, double q, double var);
> + void checkAndResetABR( RateControlEntry* rce );
>
ws
> };
> }
>
>
>
> _______________________________________________
> 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/20140202/bece86b0/attachment-0001.html>
More information about the x265-devel
mailing list