[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