[x265] [PATCH] rc: fix sliceType of 2nd pass from prev pass stats
aarthi at multicorewareinc.com
aarthi at multicorewareinc.com
Fri Jul 18 06:50:24 CEST 2014
# HG changeset patch
# User Aarthi Thirumalai
# Date 1405601922 -19800
# Thu Jul 17 18:28:42 2014 +0530
# Node ID fb653ec12832e487fdd4d00f80ff85a302e7cf69
# Parent 8772e37e101af0d727932edc0025bc590a6da12b
rc: fix sliceType of 2nd pass from prev pass stats
avoid doing sliceAnalyse in lookahead for 2nd pass
diff -r 8772e37e101a -r fb653ec12832 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Thu Jul 17 16:33:40 2014 +0530
+++ b/source/encoder/encoder.cpp Thu Jul 17 18:28:42 2014 +0530
@@ -107,7 +107,7 @@
else
m_aborted = true;
- m_lookahead = new Lookahead(m_param, m_threadPool);
+ m_lookahead = new Lookahead(m_param, m_threadPool, this);
m_dpb = new DPB(m_param);
m_rateControl = new RateControl(m_param);
diff -r 8772e37e101a -r fb653ec12832 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Thu Jul 17 16:33:40 2014 +0530
+++ b/source/encoder/ratecontrol.cpp Thu Jul 17 18:28:42 2014 +0530
@@ -994,15 +994,56 @@
return false;
}
+/* In 2pass, force the same frame types as in the 1st pass */
+int RateControl::rateControlSliceType(int frameNum)
+{
+ if (m_param->rc.bStatRead)
+ {
+ if (frameNum >= m_numEntries)
+ {
+ /* We could try to initialize everything required for ABR and
+ * adaptive B-frames, but that would be complicated.
+ * So just calculate the average QP used so far. */
+ m_param->rc.qp = (m_accumPQp < 1) ? ABR_INIT_QP_MAX : (int)(m_accumPQp + 0.5);
+ m_qpConstant[P_SLICE] = Clip3(0, MAX_MAX_QP, m_param->rc.qp);
+ m_qpConstant[I_SLICE] = Clip3(0, MAX_MAX_QP, (int)(m_param->rc.qp - m_ipOffset + 0.5));
+ m_qpConstant[B_SLICE] = Clip3(0, MAX_MAX_QP, (int)(m_param->rc.qp + m_pbOffset + 0.5 ));
+
+ x265_log(m_param, X265_LOG_ERROR, "2nd pass has more frames than 1st pass (%d)\n", m_numEntries);
+ x265_log(m_param, X265_LOG_ERROR, "continuing anyway, at constant QP=%d\n", m_param->rc.qp);
+ if (m_param->bFrameAdaptive)
+ x265_log(m_param, X265_LOG_ERROR, "disabling adaptive B-frames\n");
+
+ m_isAbr = 0;
+ m_2pass= 0;
+ m_param->rc.rateControlMode = X265_RC_CQP;
+ m_param->rc.bStatRead = 0;
+ m_param->bFrameAdaptive = 0;
+ m_param->scenecutThreshold = 0;
+ m_param->rc.cuTree = 0;
+ if (m_param->bframes > 1)
+ m_param->bframes = 1;
+ return X265_TYPE_AUTO;
+ }
+ int frameType = m_rce2Pass[frameNum].sliceType == I_SLICE ? (m_rce2Pass[frameNum].poc == 0 ? X265_TYPE_I : X265_TYPE_IDR)
+ : m_rce2Pass[frameNum].sliceType == P_SLICE ? X265_TYPE_P
+ : (m_rce2Pass[frameNum].sliceType == B_SLICE && m_rce2Pass[frameNum].keptAsRef? X265_TYPE_BREF : X265_TYPE_B);
+ return frameType;
+ }
+ else
+ return X265_TYPE_AUTO;
+}
+
void RateControl::rateControlStart(Frame* pic, Lookahead *l, RateControlEntry* rce, Encoder* enc)
{
m_curSlice = pic->getSlice();
m_sliceType = m_curSlice->m_sliceType;
rce->sliceType = m_sliceType;
+ rce->poc = m_curSlice->m_poc;
if (m_param->rc.bStatRead)
{
- assert(rce->encodeOrder >= 0 && rce->encodeOrder < m_numEntries);
- copyRceData(rce, &m_rce2Pass[rce->encodeOrder]);
+ assert(rce->poc >= 0 && rce->poc < m_numEntries);
+ copyRceData(rce, &m_rce2Pass[rce->poc]);
}
rce->isActive = true;
if (m_sliceType == B_SLICE)
@@ -1012,7 +1053,6 @@
rce->bLastMiniGopBFrame = pic->m_lowres.bLastMiniGopBFrame;
rce->bufferRate = m_bufferRate;
- rce->poc = m_curSlice->m_poc;
if (m_isVbv)
{
if (rce->rowPreds[0][0].count == 0)
@@ -1034,11 +1074,14 @@
updateVbvPlan(enc);
rce->bufferFill = m_bufferFill;
}
- if (m_isAbr) //ABR,CRF
+ if (m_isAbr || m_2pass) //ABR,CRF
{
- m_currentSatd = l->getEstimatedPictureCost(pic) >> (X265_DEPTH - 8);
- /* Update rce for use in rate control VBV later */
- rce->lastSatd = m_currentSatd;
+ if (m_isAbr || m_isVbv)
+ {
+ m_currentSatd = l->getEstimatedPictureCost(pic) >> (X265_DEPTH - 8);
+ /* Update rce for use in rate control VBV later */
+ rce->lastSatd = m_currentSatd;
+ }
double q = x265_qScale2qp(rateEstimateQscale(pic, rce));
q = Clip3((double)MIN_QP, (double)MAX_MAX_QP, q);
m_qp = int(q + 0.5);
@@ -1047,6 +1090,7 @@
rce->qRceq = m_lastRceq;
accumPQpUpdate();
}
+
else //CQP
{
if (m_sliceType == B_SLICE && m_curSlice->m_bReferenced)
diff -r 8772e37e101a -r fb653ec12832 source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Thu Jul 17 16:33:40 2014 +0530
+++ b/source/encoder/ratecontrol.h Thu Jul 17 18:28:42 2014 +0530
@@ -180,6 +180,7 @@
void hrdFullness(SEIBufferingPeriod* sei);
bool init(const TComSPS* sps);
void initHRD(TComSPS* sps);
+ int rateControlSliceType(int frameNum);
protected:
static const double s_amortizeFraction;
diff -r 8772e37e101a -r fb653ec12832 source/encoder/slicetype.cpp
--- a/source/encoder/slicetype.cpp Thu Jul 17 16:33:40 2014 +0530
+++ b/source/encoder/slicetype.cpp Thu Jul 17 18:28:42 2014 +0530
@@ -55,12 +55,13 @@
dst.y = median(a.y, b.y, c.y);
}
-Lookahead::Lookahead(x265_param *param, ThreadPool* pool)
+Lookahead::Lookahead(x265_param *param, ThreadPool* pool, Encoder* enc)
: JobProvider(pool)
, m_est(pool)
{
m_bReady = 0;
m_param = param;
+ m_top = enc;
m_lastKeyframe = -m_param->keyframeMax;
m_lastNonB = NULL;
m_bFilling = true;
@@ -240,7 +241,7 @@
return 0;
}
- if (m_param->rc.cuTree)
+ if (m_param->rc.cuTree && !m_param->rc.bStatRead)
{
/* update row satds based on cutree offsets */
pic->m_lowres.satdCost = frameCostRecalculate(frames, p0, p1, b);
@@ -327,7 +328,15 @@
if (!m_est.m_rows && list[0])
m_est.init(m_param, list[0]);
- if (m_lastNonB &&
+ if (m_param->rc.bStatRead)
+ {
+ /* Use the frame types from the first pass */
+ for (int i = 0; i < maxSearch; i++)
+ list[i]->m_lowres.sliceType =
+ m_top->m_rateControl->rateControlSliceType(list[i]->m_lowres.frameNum);
+ }
+
+ else if (m_lastNonB &&
((m_param->bFrameAdaptive && m_param->bframes) ||
m_param->rc.cuTree || m_param->scenecutThreshold ||
(m_param->lookaheadDepth && m_param->rc.vbvBufferSize)))
diff -r 8772e37e101a -r fb653ec12832 source/encoder/slicetype.h
--- a/source/encoder/slicetype.h Thu Jul 17 16:33:40 2014 +0530
+++ b/source/encoder/slicetype.h Thu Jul 17 18:28:42 2014 +0530
@@ -125,7 +125,7 @@
{
public:
- Lookahead(x265_param *param, ThreadPool *pool);
+ Lookahead(x265_param *param, ThreadPool *pool, Encoder* enc);
~Lookahead();
void init();
void destroy();
@@ -158,7 +158,7 @@
volatile int m_bReady;
volatile bool m_bFilling;
volatile bool m_bFlushed;
-
+ Encoder *m_top;
bool findJob(int);
/* called by addPicture() or flush() to trigger slice decisions */
More information about the x265-devel
mailing list