[x265] [PATCH 4 of 6] vbv: fix bugs in vbv flow with single pass ABR
aarthi at multicorewareinc.com
aarthi at multicorewareinc.com
Thu Feb 20 14:25:46 CET 2014
# HG changeset patch
# User Aarthi Thirumalai
# Date 1392899993 -19800
# Thu Feb 20 18:09:53 2014 +0530
# Node ID c5c07a3ee7fcf0f331f06f83b7b3bc0b1bcc1668
# Parent ebc23ec5ac1c5f8e2abe0d0b88414fabd2fdf1bb
vbv: fix bugs in vbv flow with single pass ABR
diff -r ebc23ec5ac1c -r c5c07a3ee7fc source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Thu Feb 20 17:47:53 2014 +0530
+++ b/source/encoder/encoder.cpp Thu Feb 20 18:09:53 2014 +0530
@@ -367,7 +367,7 @@
// Allow this frame to be recycled if no frame encoders are using it for reference
ATOMIC_DEC(&out->m_countRefEncoders);
- m_rateControl->rateControlEnd(bits, &(curEncoder->m_rce));
+ m_rateControl->rateControlEnd(out, bits, &(curEncoder->m_rce));
m_dpb->recycleUnreferenced(m_freeList);
diff -r ebc23ec5ac1c -r c5c07a3ee7fc source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Thu Feb 20 17:47:53 2014 +0530
+++ b/source/encoder/ratecontrol.cpp Thu Feb 20 18:09:53 2014 +0530
@@ -207,7 +207,9 @@
RateControl::RateControl(TEncCfg * _cfg)
{
this->cfg = _cfg;
- ncu = (int)((cfg->param.sourceHeight * cfg->param.sourceWidth) / pow((int)16, 2.0));
+ int lowresCuWidth = ((cfg->param.sourceWidth/2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
+ int lowresCuHeight = ((cfg->param.sourceHeight/2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
+ ncu = lowresCuWidth * lowresCuHeight;
if (cfg->param.rc.cuTree)
{
@@ -445,12 +447,12 @@
* average QP of the two adjacent P-frames + an offset */
TComSlice* prevRefSlice = curSlice->getRefPic(REF_PIC_LIST_0, 0)->getSlice();
TComSlice* nextRefSlice = curSlice->getRefPic(REF_PIC_LIST_1, 0)->getSlice();
+ double q0 = curSlice->getRefPic(REF_PIC_LIST_0, 0)->m_avgQpRc;
+ double q1 = curSlice->getRefPic(REF_PIC_LIST_1, 0)->m_avgQpRc;
bool i0 = prevRefSlice->getSliceType() == I_SLICE;
bool i1 = nextRefSlice->getSliceType() == I_SLICE;
int dt0 = abs(curSlice->getPOC() - prevRefSlice->getPOC());
int dt1 = abs(curSlice->getPOC() - nextRefSlice->getPOC());
- double q0 = prevRefSlice->m_avgQpRc;
- double q1 = nextRefSlice->m_avgQpRc;
// Skip taking a reference frame before the Scenecut if ABR has been reset.
if (lastAbrResetPoc >= 0 && !isVbv)
@@ -522,7 +524,7 @@
{
if (!isVbv)
{
- checkAndResetABR(rce);
+ checkAndResetABR(pic, rce);
}
q = getQScale(rce, wantedBitsWindow / cplxrSum);
@@ -552,23 +554,22 @@
if (cfg->param.rc.rateControlMode != X265_RC_CRF)
{
double lqmin = 0, lqmax = 0;
- if (totalBits == 0)
+ if (totalBits == 0 && !isVbv)
{
lqmin = qp2qScale(ABR_INIT_QP_MIN) / lstep;
lqmax = qp2qScale(ABR_INIT_QP_MAX) * lstep;
+ q = Clip3(lqmin, lqmax, q);
}
- else
+ else if(totalBits > 0 || (isVbv && rce->poc > 0 ))
{
lqmin = lastQScaleFor[sliceType] / lstep;
lqmax = lastQScaleFor[sliceType] * lstep;
+ if (overflow > 1.1 && framesDone > 3)
+ lqmax *= lstep;
+ else if (overflow < 0.9)
+ lqmin /= lstep;
+ q = Clip3(lqmin, lqmax, q);
}
-
- if (overflow > 1.1 && framesDone > 3)
- lqmax *= lstep;
- else if (overflow < 0.9)
- lqmin /= lstep;
-
- q = Clip3(lqmin, lqmax, q);
}
else
{
@@ -593,7 +594,7 @@
}
}
-void RateControl::checkAndResetABR(RateControlEntry* rce)
+void RateControl::checkAndResetABR(TComPic* pic, RateControlEntry* rce)
{
double abrBuffer = 2 * cfg->param.rc.rateTolerance * bitrate;
@@ -604,7 +605,7 @@
{
// 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)
+ if (underflow < 1 && pic->m_avgQpRc == 0)
{
totalBits = 0;
framesDone = 0;
@@ -659,9 +660,9 @@
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;
+ frameQ[P_SLICE] = sliceType == I_SLICE ? q * cfg->param.rc.ipFactor : q;
+ frameQ[B_SLICE] = frameQ[P_SLICE] * cfg->param.rc.pbFactor;
+ frameQ[I_SLICE] = frameQ[P_SLICE] / cfg->param.rc.ipFactor;
/* Loop over the planned future frames. */
for (int j = 0; bufferFillCur >= 0 && bufferFillCur <= bufferSize; j++)
@@ -807,9 +808,8 @@
void RateControl::updateVbv(int64_t bits, RateControlEntry* rce)
{
- int mbCount = (int)((cfg->param.sourceHeight * cfg->param.sourceWidth) / pow((int)16, 2.0));
- if (rce->lastSatd >= mbCount)
+ if (rce->lastSatd >= ncu)
updatePredictor(&pred[rce->sliceType], qp2qScale(rce->qpaRc), (double)rce->lastSatd, (double)bits);
if (!isVbv)
@@ -826,17 +826,27 @@
}
/* After encoding one frame, update rate control state */
-int RateControl::rateControlEnd(int64_t bits, RateControlEntry* rce)
+int RateControl::rateControlEnd(TComPic* pic, int64_t bits, RateControlEntry* rce)
{
if (isAbr)
{
if (!isVbv && cfg->param.rc.rateControlMode == X265_RC_ABR)
{
- checkAndResetABR(rce);
+ checkAndResetABR(pic, rce);
}
if (!isAbrReset)
{
+ if (pic->m_qpaRc)
+ {
+ for (uint32_t i = 0; i < pic->getFrameHeightInCU(); i++)
+ {
+ pic->m_avgQpRc += pic->m_qpaRc[i];
+ }
+ pic->m_avgQpRc /= (pic->getFrameHeightInCU() * pic->getFrameWidthInCU());
+ rce->qpaRc = pic->m_avgQpRc;
+ }
+
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. */
diff -r ebc23ec5ac1c -r c5c07a3ee7fc source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Thu Feb 20 17:47:53 2014 +0530
+++ b/source/encoder/ratecontrol.h Thu Feb 20 18:09:53 2014 +0530
@@ -128,7 +128,7 @@
// to be called for each frame to process RateControl and set QP
void rateControlStart(TComPic* pic, Lookahead *, RateControlEntry* rce, Encoder* enc);
void calcAdaptiveQuantFrame(TComPic *pic);
- int rateControlEnd(int64_t bits, RateControlEntry* rce);
+ int rateControlEnd(TComPic* pic, int64_t bits, RateControlEntry* rce);
protected:
@@ -142,7 +142,7 @@
double clipQscale(TComPic* pic, double q);
void updateVbvPlan(Encoder* enc);
double predictSize(Predictor *p, double q, double var);
- void checkAndResetABR(RateControlEntry* rce);
+ void checkAndResetABR(TComPic* pic, RateControlEntry* rce);
};
}
More information about the x265-devel
mailing list