[x265] [PATCH] rc: fix GOP reencode logic for cappedvbr
Divya Manivannan
divya at multicorewareinc.com
Mon Feb 15 14:10:47 CET 2016
# HG changeset patch
# User Divya Manivannan <divya at multicorewareinc.com>
# Date 1455185954 -19800
# Thu Feb 11 15:49:14 2016 +0530
# Node ID 2ac100d55ce744f833dcfc292746f549334469cb
# Parent 75589d57421019695b525befecc897b8087e3d5c
rc: fix GOP reencode logic for cappedvbr
diff -r 75589d574210 -r 2ac100d55ce7 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Fri Feb 05 19:43:20 2016 +0530
+++ b/source/encoder/ratecontrol.cpp Thu Feb 11 15:49:14 2016 +0530
@@ -225,6 +225,7 @@
m_statFileOut = NULL;
m_cutreeStatFileOut = m_cutreeStatFileIn = NULL;
m_rce2Pass = NULL;
+ m_encOrder = NULL;
m_lastBsliceSatdCost = 0;
m_movingAvgSum = 0.0;
@@ -571,6 +572,8 @@
X265_FREE(statsBuf);
if (m_param->rc.rateControlMode != X265_RC_CQP)
{
+ m_start = 0;
+ m_isQpModified = true;
if (!initPass2())
return false;
} /* else we're using constant quant, so no need to run the bitrate allocation */
@@ -831,13 +834,12 @@
uint64_t allConstBits = 0, allCodedBits = 0;
uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * m_numEntries * m_frameDuration);
int startIndex, framesCount, endIndex;
- int fps = (int)(m_fps + 0.5);
+ int fps = X265_MIN(m_param->keyframeMax, (int)(m_fps + 0.5));
startIndex = endIndex = framesCount = 0;
- bool isQpModified = true;
int diffQp = 0;
double targetBits = 0;
double expectedBits = 0;
- for (startIndex = 0, endIndex = 0; endIndex < m_numEntries; endIndex++)
+ for (startIndex = m_start, endIndex = m_start; endIndex < m_numEntries; endIndex++)
{
allConstBits += m_rce2Pass[endIndex].miscBits;
allCodedBits += m_rce2Pass[endIndex].coeffBits + m_rce2Pass[endIndex].mvBits;
@@ -851,11 +853,16 @@
{
if (diffQp >= 1)
{
- if (!isQpModified && endIndex > fps)
+ if (!m_isQpModified && endIndex > fps)
{
double factor = 2;
double step = 0;
- for (int start = endIndex; start <= endIndex + fps - 1 && start < m_numEntries; start++)
+ if (endIndex + fps >= m_numEntries)
+ {
+ m_start = endIndex - fps + 1;
+ return true;
+ }
+ for (int start = endIndex + 1; start <= endIndex + fps && start < m_numEntries; start++)
{
RateControlEntry *rce = &m_rce2Pass[start];
targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));
@@ -863,12 +870,13 @@
}
if (expectedBits < 0.95 * targetBits)
{
- isQpModified = true;
+ m_isQpModified = true;
+ m_isGopReEncoded = true;
while (endIndex + fps < m_numEntries)
{
step = pow(2, factor / 6.0);
expectedBits = 0;
- for (int start = endIndex; start <= endIndex + fps - 1; start++)
+ for (int start = endIndex + 1; start <= endIndex + fps; start++)
{
RateControlEntry *rce = &m_rce2Pass[start];
rce->newQScale = rce->qScale / step;
@@ -883,13 +891,13 @@
}
if (m_isVbv && endIndex + fps < m_numEntries)
- if (!vbv2Pass((uint64_t)targetBits, endIndex + fps - 1, endIndex))
+ if (!vbv2Pass((uint64_t)targetBits, endIndex + fps, endIndex + 1))
return false;
targetBits = 0;
expectedBits = 0;
- for (int start = endIndex - fps; start <= endIndex - 1; start++)
+ for (int start = endIndex - fps + 1; start <= endIndex; start++)
{
RateControlEntry *rce = &m_rce2Pass[start];
targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));
@@ -898,7 +906,7 @@
{
step = pow(2, factor / 6.0);
expectedBits = 0;
- for (int start = endIndex - fps; start <= endIndex - 1; start++)
+ for (int start = endIndex - fps + 1; start <= endIndex; start++)
{
RateControlEntry *rce = &m_rce2Pass[start];
rce->newQScale = rce->qScale * step;
@@ -912,10 +920,13 @@
break;
}
if (m_isVbv)
- if (!vbv2Pass((uint64_t)targetBits, endIndex - 1, endIndex - fps))
+ if (!vbv2Pass((uint64_t)targetBits, endIndex, endIndex - fps + 1))
return false;
diffQp = 0;
+ m_reencode = endIndex - fps + 1;
+ endIndex = endIndex + fps;
startIndex = endIndex + 1;
+ m_start = startIndex;
targetBits = expectedBits = 0;
}
else
@@ -923,7 +934,7 @@
}
}
else
- isQpModified = false;
+ m_isQpModified = false;
}
}
}
@@ -939,6 +950,9 @@
if (!analyseABR2Pass(0, m_numEntries - 1, allAvailableBits))
return false;
}
+
+ m_start = X265_MAX(m_start, endIndex - fps);
+
return true;
}
@@ -2582,6 +2596,7 @@
fclose(m_cutreeStatFileIn);
X265_FREE(m_rce2Pass);
+ X265_FREE(m_encOrder);
for (int i = 0; i < 2; i++)
X265_FREE(m_cuTreeStats.qpBuffer[i]);
diff -r 75589d574210 -r 2ac100d55ce7 source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Fri Feb 05 19:43:20 2016 +0530
+++ b/source/encoder/ratecontrol.h Thu Feb 11 15:49:14 2016 +0530
@@ -202,7 +202,11 @@
/* 2 pass */
bool m_2pass;
+ bool m_isGopReEncoded;
+ bool m_isQpModified;
int m_numEntries;
+ int m_start;
+ int m_reencode;
FILE* m_statFileOut;
FILE* m_cutreeStatFileOut;
FILE* m_cutreeStatFileIn;
@@ -235,6 +239,8 @@
bool cuTreeReadFor2Pass(Frame* curFrame);
void hrdFullness(SEIBufferingPeriod* sei);
int writeRateControlFrameStats(Frame* curFrame, RateControlEntry* rce);
+ bool initPass2();
+
protected:
static const int s_slidingWindowFrames;
@@ -261,7 +267,6 @@
double predictSize(Predictor *p, double q, double var);
void checkAndResetABR(RateControlEntry* rce, bool isFrameDone);
double predictRowsSizeSum(Frame* pic, RateControlEntry* rce, double qpm, int32_t& encodedBits);
- bool initPass2();
bool analyseABR2Pass(int startPoc, int endPoc, uint64_t allAvailableBits);
void initFramePredictors();
double getDiffLimitedQScale(RateControlEntry *rce, double q);
More information about the x265-devel
mailing list