[x265] [PATCH] rc: change row diagonal vbv algorithm
Divya Manivannan
divya at multicorewareinc.com
Thu May 19 14:04:03 CEST 2016
# HG changeset patch
# User Divya Manivannan <divya at multicorewareinc.com>
# Date 1462450702 -19800
# Thu May 05 17:48:22 2016 +0530
# Node ID eadc0a1e233adb60326030825cab2ff71782ef9d
# Parent 7241944b3893cc7ee6df67ebceec06fa0916319a
rc: change row diagonal vbv algorithm
diff -r 7241944b3893 -r eadc0a1e233a source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Wed May 18 19:25:34 2016 +0000
+++ b/source/encoder/ratecontrol.cpp Thu May 05 17:48:22 2016 +0530
@@ -2243,22 +2243,27 @@
double qpMax = X265_MIN(prevRowQp + m_param->rc.qpStep, qpAbsoluteMax);
double qpMin = X265_MAX(prevRowQp - m_param->rc.qpStep, qpAbsoluteMin);
double stepSize = 0.5;
- double bufferLeftPlanned = rce->bufferFill - rce->frameSizePlanned;
const SPS& sps = *curEncData.m_slice->m_sps;
- double maxFrameError = X265_MAX(0.05, 1.0 / sps.numCuInHeight);
+ double maxFrameError = x265_clip3(0.05, 0.25, 1.0 / sps.numCuInHeight);
+ double maxFrameSize = rce->frameSizeMaximum - rce->frameSizeMaximum * maxFrameError;
+ maxFrameSize = X265_MIN(maxFrameSize, rce->bufferFill - rce->bufferRate * maxFrameError);
if (row < sps.numCuInHeight - 1)
{
+ double bufferLeftPlanned = rce->bufferFill - rce->frameSizePlanned;
+ bufferLeftPlanned = X265_MAX(bufferLeftPlanned, 0.f);
+
/* More threads means we have to be more cautious in letting ratecontrol use up extra bits. */
double rcTol = bufferLeftPlanned / m_param->frameNumThreads * m_rateTolerance;
int32_t encodedBitsSoFar = 0;
double accFrameBits = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar);
+ double trustCoeff = x265_clip3(0.0, 1.0, encodedBitsSoFar / rce->frameSizePlanned);
/* * 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
* frame was measured inaccurately. */
- if (encodedBitsSoFar < 0.05f * rce->frameSizePlanned)
+ if (trustCoeff < 0.05f)
qpMax = qpAbsoluteMax = prevRowQp;
if (rce->sliceType != I_SLICE || (m_param->rc.bStrictCbr && rce->poc > 0))
@@ -2274,7 +2279,7 @@
while (qpVbv < qpMax
&& (((accFrameBits > rce->frameSizePlanned + rcTol) ||
- (rce->bufferFill - accFrameBits < bufferLeftPlanned * 0.5) ||
+ (accFrameBits > rce->bufferFill - bufferLeftPlanned * 0.5) ||
(accFrameBits > rce->frameSizePlanned && qpVbv < rce->qpNoVbv))
&& (!m_param->rc.bStrictCbr ? 1 : abrOvershoot > 0.1)))
{
@@ -2283,16 +2288,22 @@
abrOvershoot = (accFrameBits + m_totalBits - m_wantedBitsWindow) / totalBitsNeeded;
}
- while (qpVbv > qpMin
+ double accFrameBitsMax = accFrameBits + ((rce->bufferFill - m_bufferSize + m_bufferRate) * 0.90 - accFrameBits) * trustCoeff;
+ qpVbv -= stepSize;
+ double accFrameBitsTemp = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar);
+ while (qpVbv > qpMin && qpVbv < prevRowQp
&& (qpVbv > curEncData.m_rowStat[0].diagQp || m_singleFrameVbv)
- && (((accFrameBits < rce->frameSizePlanned * 0.8f && qpVbv <= prevRowQp)
- || accFrameBits < (rce->bufferFill - m_bufferSize + m_bufferRate) * 1.1)
+ && (accFrameBitsTemp < maxFrameSize)
+ && (((accFrameBitsTemp < rce->frameSizePlanned * 0.8f)
+ || (accFrameBitsTemp < accFrameBitsMax))
&& (!m_param->rc.bStrictCbr ? 1 : abrOvershoot < 0)))
{
+ accFrameBits = accFrameBitsTemp;
qpVbv -= stepSize;
- accFrameBits = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar);
+ accFrameBitsTemp = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar);
abrOvershoot = (accFrameBits + m_totalBits - m_wantedBitsWindow) / totalBitsNeeded;
}
+ qpVbv += stepSize;
if (m_param->rc.bStrictCbr && m_param->totalFrames)
{
@@ -2313,9 +2324,7 @@
}
/* avoid VBV underflow or MinCr violation */
- while ((qpVbv < qpAbsoluteMax)
- && ((rce->bufferFill - accFrameBits < m_bufferRate * maxFrameError) ||
- (rce->frameSizeMaximum - accFrameBits < rce->frameSizeMaximum * maxFrameError)))
+ while (qpVbv < qpAbsoluteMax && (accFrameBits > maxFrameSize))
{
qpVbv += stepSize;
accFrameBits = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar);
@@ -2343,12 +2352,14 @@
else
{
int32_t encodedBitsSoFar = 0;
- rce->frameSizeEstimated = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar);
+ for (uint32_t row = 0; row < sps.numCuInHeight; row++)
+ encodedBitsSoFar += curEncData.m_rowStat[row].encodedBits;
+
+ rce->frameSizeEstimated = encodedBitsSoFar;
/* Last-ditch attempt: if the last row of the frame underflowed the VBV,
* try again. */
- if ((rce->frameSizeEstimated > (rce->bufferFill - m_bufferRate * maxFrameError) &&
- qpVbv < qpMax && canReencodeRow))
+ if (qpVbv < qpMax && canReencodeRow && (rce->frameSizeEstimated > X265_MIN(rce->frameSizeMaximum, rce->bufferFill)))
{
qpVbv = qpMax;
return -1;
More information about the x265-devel
mailing list