[x265-commits] [x265] vbv: bug fix in clipQScale
Aarthi at videolan.org
Aarthi at videolan.org
Mon Feb 24 22:45:59 CET 2014
details: http://hg.videolan.org/x265/rev/80caa9f00d7c
branches:
changeset: 6268:80caa9f00d7c
user: Aarthi Thirumalai
date: Sun Feb 23 21:25:22 2014 +0530
description:
vbv: bug fix in clipQScale
Subject: [x265] tcomrom: remove unused g_sigLastScan8x8 and g_sigLastScanCG32x32 variables
details: http://hg.videolan.org/x265/rev/57ce7f0f4f4c
branches:
changeset: 6269:57ce7f0f4f4c
user: Gopu Govindaswamy
date: Thu Feb 20 16:01:28 2014 -0800
description:
tcomrom: remove unused g_sigLastScan8x8 and g_sigLastScanCG32x32 variables
Subject: [x265] rc: bug fix - clip qp before setting into TComPic:m_avgQpRc.
details: http://hg.videolan.org/x265/rev/acaed9dbaae2
branches:
changeset: 6270:acaed9dbaae2
user: Aarthi Thirumalai
date: Mon Feb 24 23:01:32 2014 +0530
description:
rc: bug fix - clip qp before setting into TComPic:m_avgQpRc.
This fix resolves Encoder crash caused due to invalid qp being used in each
CU.
Subject: [x265] vbv: refactor, implement row wise qp updates only if vbv is enabled.
details: http://hg.videolan.org/x265/rev/d0aea0cfd263
branches:
changeset: 6271:d0aea0cfd263
user: Aarthi Thirumalai
date: Mon Feb 24 17:50:55 2014 +0530
description:
vbv: refactor, implement row wise qp updates only if vbv is enabled.
Subject: [x265] rc: implement abr reset for single pass ABR + VBV
details: http://hg.videolan.org/x265/rev/ebaa34c8f651
branches:
changeset: 6272:ebaa34c8f651
user: Aarthi Thirumalai
date: Mon Feb 24 18:55:00 2014 +0530
description:
rc: implement abr reset for single pass ABR + VBV
diffstat:
source/Lib/TLibCommon/TComRom.cpp | 18 -------
source/Lib/TLibCommon/TComRom.h | 9 ---
source/encoder/frameencoder.cpp | 7 +-
source/encoder/ratecontrol.cpp | 90 +++++++++++++++++++-------------------
source/encoder/ratecontrol.h | 3 +-
5 files changed, 50 insertions(+), 77 deletions(-)
diffs (truncated from 301 to 300 lines):
diff -r d1cd52bb3461 -r ebaa34c8f651 source/Lib/TLibCommon/TComRom.cpp
--- a/source/Lib/TLibCommon/TComRom.cpp Sat Feb 22 19:00:07 2014 -0600
+++ b/source/Lib/TLibCommon/TComRom.cpp Mon Feb 24 18:55:00 2014 +0530
@@ -443,24 +443,6 @@ uint64_t g_nSymbolCounter = 0;
// Scanning order & context model mapping
// ====================================================================================================================
-const uint32_t g_sigLastScan8x8[3][4] =
-{
- { 0, 2, 1, 3 },
- { 0, 1, 2, 3 },
- { 0, 2, 1, 3 }
-};
-const uint32_t g_sigLastScanCG32x32[64] =
-{
- 0, 8, 1, 16, 9, 2, 24, 17,
- 10, 3, 32, 25, 18, 11, 4, 40,
- 33, 26, 19, 12, 5, 48, 41, 34,
- 27, 20, 13, 6, 56, 49, 42, 35,
- 28, 21, 14, 7, 57, 50, 43, 36,
- 29, 22, 15, 58, 51, 44, 37, 30,
- 23, 59, 52, 45, 38, 31, 60, 53,
- 46, 39, 61, 54, 47, 62, 55, 63
-};
-
const uint32_t g_minInGroup[10] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24 };
const uint32_t g_groupIdx[32] = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9 };
diff -r d1cd52bb3461 -r ebaa34c8f651 source/Lib/TLibCommon/TComRom.h
--- a/source/Lib/TLibCommon/TComRom.h Sat Feb 22 19:00:07 2014 -0600
+++ b/source/Lib/TLibCommon/TComRom.h Mon Feb 24 18:55:00 2014 +0530
@@ -137,15 +137,6 @@ extern const uint32_t g_minInGroup[10];
extern const uint32_t g_goRiceRange[5]; //!< maximum value coded with Rice codes
extern const uint32_t g_goRicePrefixLen[5]; //!< prefix length for each maximum value
-extern const uint32_t g_sigLastScan8x8[3][4]; //!< coefficient group scan order for 8x8 TUs
-extern const uint32_t g_sigLastScanCG32x32[64];
-
-// ====================================================================================================================
-// ADI table
-// ====================================================================================================================
-
-extern const UChar g_intraModeNumFast[7];
-
// ====================================================================================================================
// Bit-depth
// ====================================================================================================================
diff -r d1cd52bb3461 -r ebaa34c8f651 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Sat Feb 22 19:00:07 2014 -0600
+++ b/source/encoder/frameencoder.cpp Mon Feb 24 18:55:00 2014 +0530
@@ -1058,6 +1058,7 @@ void FrameEncoder::processRowEncoder(int
const uint32_t numCols = m_pic->getPicSym()->getFrameWidthInCU();
const uint32_t lineStartCUAddr = row * numCols;
double qpBase = m_pic->m_avgQpRc;
+ bool isVbv = m_cfg->param.rc.vbvBufferSize > 0 && m_cfg->param.rc.vbvMaxBitrate > 0;
for (uint32_t col = curRow.m_completed; col < numCols; col++)
{
const uint32_t cuAddr = lineStartCUAddr + col;
@@ -1068,10 +1069,10 @@ void FrameEncoder::processRowEncoder(int
codeRow.m_entropyCoder.resetEntropy();
TEncSbac *bufSbac = (m_cfg->param.bEnableWavefront && col == 0 && row > 0) ? &m_rows[row - 1].m_bufferSbacCoder : NULL;
- if ((uint32_t)row >= col && (row != 0))
+ if ((uint32_t)row >= col && (row != 0) && isVbv)
qpBase = m_pic->getCU(cuAddr - numCols + 1)->m_baseQp;
- if (m_cfg->param.rc.aqMode || (m_cfg->param.rc.vbvBufferSize > 0 && m_cfg->param.rc.vbvMaxBitrate > 0))
+ if (m_cfg->param.rc.aqMode || isVbv)
{
int qp = calcQpForCu(m_pic, cuAddr, qpBase);
setLambda(qp, row);
@@ -1080,7 +1081,7 @@ void FrameEncoder::processRowEncoder(int
cu->m_baseQp = qpBase;
}
codeRow.processCU(cu, m_pic->getSlice(), bufSbac, m_cfg->param.bEnableWavefront && col == 1);
- if (m_cfg->param.rc.vbvBufferSize && m_cfg->param.rc.vbvMaxBitrate)
+ if (isVbv)
{
// Update encoded bits, satdCost, baseQP for each CU
m_pic->m_rowDiagSatd[row] += m_pic->m_cuCostsForVbv[cuAddr];
diff -r d1cd52bb3461 -r ebaa34c8f651 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Sat Feb 22 19:00:07 2014 -0600
+++ b/source/encoder/ratecontrol.cpp Mon Feb 24 18:55:00 2014 +0530
@@ -245,15 +245,12 @@ RateControl::RateControl(TEncCfg * _cfg)
}
isAbr = cfg->param.rc.rateControlMode != X265_RC_CQP; // later add 2pass option
-
bitrate = cfg->param.rc.bitrate * 1000;
frameDuration = (double)cfg->param.fpsDenom / cfg->param.fpsNum;
qp = cfg->param.rc.qp;
lastRceq = 1; /* handles the cmplxrsum when the previous frame cost is zero */
- totalBits = 0;
shortTermCplxSum = 0;
shortTermCplxCount = 0;
- framesDone = 0;
lastNonBPictType = I_SLICE;
isAbrReset = false;
lastAbrResetPoc = -1;
@@ -325,43 +322,20 @@ RateControl::RateControl(TEncCfg * _cfg)
&& cfg->param.rc.vbvMaxBitrate <= cfg->param.rc.bitrate;
}
- for (int i = 0; i < 5; i++)
- {
- pred[i].coeff = 2.0;
- pred[i].count = 1.0;
- 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];
bframes = cfg->param.bframes;
bframeBits = 0;
leadingNoBSatd = 0;
- accumPNorm = .01;
- /* estimated ratio that produces a reasonable QP for the first I-frame */
- cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5);
- wantedBitsWindow = bitrate * frameDuration;
-
if (cfg->param.rc.rateControlMode == X265_RC_ABR)
{
/* Adjust the first frame in order to stabilize the quality level compared to the rest */
#define ABR_INIT_QP_MIN (24 + QP_BD_OFFSET)
#define ABR_INIT_QP_MAX (34 + QP_BD_OFFSET)
- accumPQp = (ABR_INIT_QP_MIN)*accumPNorm;
}
else if (cfg->param.rc.rateControlMode == X265_RC_CRF)
{
#define ABR_INIT_QP ((int)cfg->param.rc.rfConstant + QP_BD_OFFSET)
- accumPQp = ABR_INIT_QP * accumPNorm;
}
+ reInit();
ipOffset = 6.0 * X265_LOG2(cfg->param.rc.ipFactor);
pbOffset = 6.0 * X265_LOG2(cfg->param.rc.pbFactor);
@@ -383,6 +357,36 @@ RateControl::RateControl(TEncCfg * _cfg)
lstep = pow(2, cfg->param.rc.qpStep / 6.0);
}
+void RateControl::reInit()
+{
+ totalBits = 0;
+ framesDone = 0;
+
+ /* estimated ratio that produces a reasonable QP for the first I-frame */
+ cplxrSum = .01 * pow(7.0e5, qCompress) * pow(ncu, 0.5);
+ wantedBitsWindow = bitrate * frameDuration;
+ accumPNorm = .01;
+ accumPQp = (cfg->param.rc.rateControlMode == X265_RC_CRF ? ABR_INIT_QP : ABR_INIT_QP_MIN) * accumPNorm;
+
+ /* Frame Predictors and Row predictors used in vbv */
+ for (int i = 0; i < 5; i++)
+ {
+ pred[i].coeff = 2.0;
+ pred[i].count = 1.0;
+ 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];
+}
+
+
void RateControl::rateControlStart(TComPic* pic, Lookahead *l, RateControlEntry* rce, Encoder* enc)
{
curSlice = pic->getSlice();
@@ -409,7 +413,8 @@ void RateControl::rateControlStart(TComP
/* Update rce for use in rate control VBV later */
rce->lastSatd = currentSatd;
double q = qScale2qp(rateEstimateQscale(pic, rce));
- qp = Clip3(MIN_QP, MAX_MAX_QP, (int)(q + 0.5));
+ q = Clip3((double)MIN_QP, (double)MAX_MAX_QP, q);
+ qp = int(q + 0.5);
rce->qpaRc = pic->m_avgQpRc = q;
/* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */
rce->qRceq = lastRceq;
@@ -464,7 +469,7 @@ double RateControl::rateEstimateQscale(T
int dt1 = abs(curSlice->getPOC() - nextRefSlice->getPOC());
// Skip taking a reference frame before the Scenecut if ABR has been reset.
- if (lastAbrResetPoc >= 0 && !isVbv)
+ if (lastAbrResetPoc >= 0)
{
if (prevRefSlice->getSliceType() == P_SLICE && prevRefSlice->getPOC() < lastAbrResetPoc)
{
@@ -530,10 +535,8 @@ double RateControl::rateEstimateQscale(T
}
else
{
- if (!isVbv)
- {
- checkAndResetABR(pic, rce);
- }
+
+ checkAndResetABR(rce, false);
q = getQScale(rce, wantedBitsWindow / cplxrSum);
/* ABR code can potentially be counterproductive in CBR, so just
@@ -569,7 +572,7 @@ double RateControl::rateEstimateQscale(T
lqmax = qp2qScale(ABR_INIT_QP_MAX) * lstep;
q = Clip3(lqmin, lqmax, q);
}
- else if (totalBits > 0 || (isVbv && rce->poc > 0))
+ else if (totalBits > 0 || (isVbv && framesDone > 0))
{
lqmin = lastQScaleFor[sliceType] / lstep;
lqmax = lastQScaleFor[sliceType] * lstep;
@@ -585,10 +588,10 @@ double RateControl::rateEstimateQscale(T
if (qCompress != 1 && framesDone == 0)
q = qp2qScale(ABR_INIT_QP) / fabs(cfg->param.rc.ipFactor);
}
- qpNoVbv = qScale2qp(q);
double lmin1 = lmin[sliceType];
double lmax1 = lmax[sliceType];
q = Clip3(lmin1, lmax1, q);
+ qpNoVbv = qScale2qp(q);
q = clipQscale(pic, q);
@@ -603,7 +606,7 @@ double RateControl::rateEstimateQscale(T
}
}
-void RateControl::checkAndResetABR(TComPic* pic, RateControlEntry* rce)
+void RateControl::checkAndResetABR(RateControlEntry* rce, bool isFrameDone)
{
double abrBuffer = 2 * cfg->param.rc.rateTolerance * bitrate;
@@ -614,14 +617,9 @@ void RateControl::checkAndResetABR(TComP
{
// 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 && pic->m_avgQpRc == 0)
+ if (underflow < 1 && !isFrameDone)
{
- 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;
+ reInit();
shortTermCplxSum = rce->lastSatd / (CLIP_DURATION(frameDuration) / BASE_FRAME_DURATION);
shortTermCplxCount = 1;
isAbrReset = true;
@@ -756,7 +754,7 @@ double RateControl::clipQscale(TComPic*
{
q *= X265_MAX(pbbits / space, bits / (0.5 * bufferSize));
}
- q = X265_MAX(q0 - 5, q);
+ q = X265_MAX(q0 / 2, q);
}
if (!vbvMinRate)
q = X265_MAX(q0, q);
@@ -1009,9 +1007,9 @@ int RateControl::rateControlEnd(TComPic*
{
if (isAbr)
{
- if (!isVbv && cfg->param.rc.rateControlMode == X265_RC_ABR)
+ if (cfg->param.rc.rateControlMode == X265_RC_ABR)
{
- checkAndResetABR(pic, rce);
+ checkAndResetABR(rce, true);
}
if (!isAbrReset)
{
diff -r d1cd52bb3461 -r ebaa34c8f651 source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Sat Feb 22 19:00:07 2014 -0600
+++ b/source/encoder/ratecontrol.h Mon Feb 24 18:55:00 2014 +0530
@@ -134,6 +134,7 @@ struct RateControl
protected:
+ void reInit();
double getQScale(RateControlEntry *rce, double rateFactor);
double rateEstimateQscale(TComPic* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR
void accumPQpUpdate();
@@ -144,7 +145,7 @@ protected:
double clipQscale(TComPic* pic, double q);
void updateVbvPlan(Encoder* enc);
double predictSize(Predictor *p, double q, double var);
- void checkAndResetABR(TComPic* pic, RateControlEntry* rce);
+ void checkAndResetABR(RateControlEntry* rce, bool isFrameDone);
double predictRowsSizeSum(TComPic* pic, double qpm, int32_t& encodedBits);
};
More information about the x265-commits
mailing list