[x265] [PATCH 2 of 2] vbv: bug fixes - move row Predictors, frameSizeEstimated to Frame Encoder scope
aarthi at multicorewareinc.com
aarthi at multicorewareinc.com
Mon Mar 10 20:36:36 CET 2014
# HG changeset patch
# User Aarthi Thirumalai
# Date 1394480150 -19800
# Tue Mar 11 01:05:50 2014 +0530
# Node ID f103a68c678c88c9072f6ea286582ec9427a2241
# Parent 489ec5db168c83c61836b77503eb9280fd5b5164
vbv: bug fixes - move row Predictors, frameSizeEstimated to Frame Encoder scope.
Improves quality and controls buffer underflow when Frame parallelism is enabled.
diff -r 489ec5db168c -r f103a68c678c source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Tue Mar 11 00:17:53 2014 +0530
+++ b/source/encoder/encoder.cpp Tue Mar 11 01:05:50 2014 +0530
@@ -216,7 +216,12 @@
FrameEncoder *encoder = &m_frameEncoder[encIdx];
double bits;
bits = encoder->m_rce.frameSizePlanned;
- bits = X265_MAX(bits, m_rateControl->frameSizeEstimated);
+ if (!encoder->m_rce.isActive)
+ {
+ encIdx = (encIdx + 1) % param->frameNumThreads;
+ continue;
+ }
+ bits = X265_MAX(bits,encoder->m_rce.frameSizeEstimated);
rc->bufferFill -= bits;
rc->bufferFill = X265_MAX(rc->bufferFill, 0);
rc->bufferFill += encoder->m_rce.bufferRate;
diff -r 489ec5db168c -r f103a68c678c source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Tue Mar 11 00:17:53 2014 +0530
+++ b/source/encoder/ratecontrol.cpp Tue Mar 11 01:05:50 2014 +0530
@@ -252,7 +252,6 @@
lastNonBPictType = I_SLICE;
isAbrReset = false;
lastAbrResetPoc = -1;
- frameSizeEstimated = 0;
// vbv initialization
param->rc.vbvBufferSize = Clip3(0, 2000000, param->rc.vbvBufferSize);
param->rc.vbvMaxBitrate = Clip3(0, 2000000, param->rc.vbvMaxBitrate);
@@ -374,13 +373,7 @@
pred[i].decay = 0.5;
pred[i].offset = 0.0;
}
- for (int i = 0; i < 4; i++)
- {
- rowPreds[i].coeff = 0.25;
- rowPreds[i].count = 1.0;
- rowPreds[i].decay = 0.5;
- rowPreds[i].offset = 0.0;
- }
+
predBfromP = pred[0];
}
@@ -390,7 +383,7 @@
curSlice = pic->getSlice();
sliceType = curSlice->getSliceType();
rce->sliceType = sliceType;
-
+ rce->isActive = true;
if (sliceType == B_SLICE)
rce->bframes = bframes;
else
@@ -401,8 +394,21 @@
rce->poc = curSlice->getPOC();
if (isVbv)
{
- rowPred[0] = &rowPreds[sliceType];
- rowPred[1] = &rowPreds[3];
+ if (rce->rowPreds[0][0].count == 0)
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ for(int j = 0; j < 2; j++)
+ {
+ rce->rowPreds[i][j].coeff = 0.25;
+ rce->rowPreds[i][j].count = 1.0;
+ rce->rowPreds[i][j].decay = 0.5;
+ rce->rowPreds[i][j].offset = 0.0;
+ }
+ }
+ }
+ rce->rowPred[0] = &rce->rowPreds[sliceType][0];
+ rce->rowPred[1] = &rce->rowPreds[sliceType][1];
updateVbvPlan(enc);
rce->bufferFill = bufferFill;
}
@@ -497,7 +503,7 @@
qpNoVbv = q;
double qScale = qp2qScale(qpNoVbv);
rce->frameSizePlanned = predictSize(&predBfromP, qScale, (double)leadingNoBSatd);
- frameSizeEstimated = rce->frameSizePlanned;
+ rce->frameSizeEstimated = rce->frameSizePlanned;
return qScale;
}
else
@@ -616,7 +622,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 && !isFrameDone)
+ if (underflow < 0.9 && !isFrameDone)
{
reInit();
shortTermCplxSum = rce->lastSatd / (CLIP_DURATION(frameDuration) / BASE_FRAME_DURATION);
@@ -765,7 +771,7 @@
return Clip3(lmin1, lmax1, q);
}
-double RateControl::predictRowsSizeSum(TComPic* pic, double qpVbv, int32_t & encodedBitsSoFar)
+double RateControl::predictRowsSizeSum(TComPic* pic, RateControlEntry* rce, double qpVbv, int32_t & encodedBitsSoFar)
{
uint32_t rowSatdCostSoFar = 0, totalSatdBits = 0;
@@ -781,7 +787,7 @@
uint32_t satdCostForPendingCus = pic->m_rowSatdForVbv[row] - rowSatdCostSoFar;
if (satdCostForPendingCus > 0)
{
- double pred_s = predictSize(rowPred[0], qScale, satdCostForPendingCus);
+ double pred_s = predictSize(rce->rowPred[0], qScale, satdCostForPendingCus);
uint32_t refRowSatdCost = 0, refRowBits = 0, intraCost = 0;
double refQScale = 0;
@@ -818,7 +824,7 @@
else
{
/* Our QP is lower than the reference! */
- double pred_intra = predictSize(rowPred[1], qScale, intraCost);
+ double pred_intra = predictSize(rce->rowPred[1], qScale, intraCost);
/* Sum: better to overestimate than underestimate by using only one of the two predictors. */
totalSatdBits += int32_t(pred_intra + pred_s);
}
@@ -841,16 +847,16 @@
rowSatdCost += pic->m_rowDiagSatd[0];
encodedBits += pic->m_rowEncodedBits[0];
}
- updatePredictor(rowPred[0], qScaleVbv, rowSatdCost, encodedBits);
+ updatePredictor(rce->rowPred[0], qScaleVbv, rowSatdCost, encodedBits);
if (pic->getSlice()->getSliceType() == P_SLICE)
{
TComPic* refSlice = pic->getSlice()->getRefPic(REF_PIC_LIST_0, 0);
if (qpVbv < refSlice->m_rowDiagQp[row])
{
if (row == 1)
- updatePredictor(rowPred[1], qScaleVbv, pic->m_rowDiagIntraSatd[row] + pic->m_rowDiagIntraSatd[0], pic->m_rowEncodedBits[row] + pic->m_rowEncodedBits[0]);
+ updatePredictor(rce->rowPred[1], qScaleVbv, pic->m_rowDiagIntraSatd[row] + pic->m_rowDiagIntraSatd[0], pic->m_rowEncodedBits[row] + pic->m_rowEncodedBits[0]);
else
- updatePredictor(rowPred[1], qScaleVbv, pic->m_rowDiagIntraSatd[row], pic->m_rowEncodedBits[row]);
+ updatePredictor(rce->rowPred[1], qScaleVbv, pic->m_rowDiagIntraSatd[row], pic->m_rowEncodedBits[row]);
}
}
@@ -880,7 +886,7 @@
/* More threads means we have to be more cautious in letting ratecontrol use up extra bits. */
double rcTol = bufferLeftPlanned / param->frameNumThreads * param->rc.rateTolerance;
int32_t encodedBitsSoFar = 0;
- double accFrameBits = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+ double accFrameBits = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
/* * Don't increase the row QPs until a sufficent amount of the bits of
* the frame have been processed, in case a flat area at the top of the
@@ -900,7 +906,7 @@
(accFrameBits > rce->frameSizePlanned && qpVbv < rce->qpNoVbv)))
{
qpVbv += stepSize;
- accFrameBits = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+ accFrameBits = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
}
while (qpVbv > qpMin
@@ -909,7 +915,7 @@
|| accFrameBits < (rce->bufferFill - bufferSize + bufferRate) * 1.1))
{
qpVbv -= stepSize;
- accFrameBits = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+ accFrameBits = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
}
/* avoid VBV underflow */
@@ -917,10 +923,10 @@
&& (rce->bufferFill - accFrameBits < bufferRate * maxFrameError))
{
qpVbv += stepSize;
- accFrameBits = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+ accFrameBits = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
}
- frameSizeEstimated = accFrameBits;
+ rce->frameSizeEstimated = accFrameBits;
/* If the current row was large enough to cause a large QP jump, try re-encoding it. */
if (qpVbv > qpMax && prevRowQp < qpMax && canReencodeRow)
@@ -933,11 +939,11 @@
else
{
int32_t encodedBitsSoFar = 0;
- frameSizeEstimated = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);
+ rce->frameSizeEstimated = predictRowsSizeSum(pic, rce, qpVbv, encodedBitsSoFar);
/* Last-ditch attempt: if the last row of the frame underflowed the VBV,
* try again. */
- if ((frameSizeEstimated > (rce->bufferFill - bufferRate * maxFrameError) &&
+ if ((rce->frameSizeEstimated > (rce->bufferFill - bufferRate * maxFrameError) &&
qpVbv < qpMax && canReencodeRow))
{
qpVbv = qpMax;
@@ -1069,6 +1075,7 @@
}
}
updateVbv(bits, rce);
+ rce->isActive = false;
}
return 0;
}
diff -r 489ec5db168c -r f103a68c678c source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Tue Mar 11 00:17:53 2014 +0530
+++ b/source/encoder/ratecontrol.h Tue Mar 11 01:05:50 2014 +0530
@@ -43,6 +43,14 @@
#define CLIP_DURATION(f) Clip3(MIN_FRAME_DURATION, MAX_FRAME_DURATION, f)
+struct Predictor
+{
+ double coeff;
+ double count;
+ double decay;
+ double offset;
+};
+
struct RateControlEntry
{
int64_t texBits; /* Required in 2-pass rate control */
@@ -57,19 +65,15 @@
double blurredComplexity;
double qpaRc;
double qRceq;
- double frameSizePlanned;
+ double frameSizePlanned; /* frame Size decided by RateCotrol before encoding the frame */
double bufferRate;
double movingAvgSum;
double qpNoVbv;
double bufferFill;
-};
-
-struct Predictor
-{
- double coeff;
- double count;
- double decay;
- double offset;
+ Predictor rowPreds[3][2];
+ Predictor* rowPred[2];
+ double frameSizeEstimated; /* hold frameSize, updated from cu level vbv rc */
+ bool isActive;
};
struct RateControl
@@ -96,8 +100,6 @@
bool isVbv;
Predictor pred[5];
Predictor predBfromP;
- Predictor rowPreds[4];
- Predictor *rowPred[2];
int bframes;
int bframeBits;
bool isAbrReset;
@@ -123,7 +125,6 @@
int framesDone; /* framesDone keeps track of # of frames passed through RateCotrol already */
double qCompress;
double qpNoVbv; /* QP for the current frame if 1-pass VBV was disabled. */
- double frameSizeEstimated; /* hold synched frameSize, updated from cu level vbv rc */
RateControl(Encoder * _cfg);
// to be called for each frame to process RateControl and set QP
@@ -146,7 +147,7 @@
void updateVbvPlan(Encoder* enc);
double predictSize(Predictor *p, double q, double var);
void checkAndResetABR(RateControlEntry* rce, bool isFrameDone);
- double predictRowsSizeSum(TComPic* pic, double qpm, int32_t& encodedBits);
+ double predictRowsSizeSum(TComPic* pic, RateControlEntry* rce, double qpm, int32_t& encodedBits);
};
}
#endif // ifndef X265_RATECONTROL_H
More information about the x265-devel
mailing list