[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