[x265] [PATCH 2 of 4] rc: fix sliceType of 2nd pass from prev pass stats

aarthi at multicorewareinc.com aarthi at multicorewareinc.com
Mon Jul 21 09:32:47 CEST 2014


# HG changeset patch
# User Aarthi Thirumalai
# Date 1405684344 -19800
#      Fri Jul 18 17:22:24 2014 +0530
# Node ID 382e20845179925356c178c0ff738410f2d0648e
# Parent  d9296f2aad7210305efd49cb949407a23ef8ded3
rc: fix sliceType of 2nd pass from prev pass stats

avoid doing sliceAnalyse in lookahead for 2nd pass

diff -r d9296f2aad72 -r 382e20845179 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Fri Jul 18 17:19:20 2014 +0530
+++ b/source/encoder/encoder.cpp	Fri Jul 18 17:22:24 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 d9296f2aad72 -r 382e20845179 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Fri Jul 18 17:19:20 2014 +0530
+++ b/source/encoder/ratecontrol.cpp	Fri Jul 18 17:22:24 2014 +0530
@@ -583,9 +583,10 @@
                        &picType, &rce->frameDuration, &qpRc, &qpAq, &rce->coeffBits,
                        &rce->mvBits, &rce->miscBits, &rce->iCuCount, &rce->pCuCount,
                        &rce->skipCuCount);
-
-                if (picType != 'b' || picType != 'p')
-                    rce->keptAsRef = true;
+                rce->clippedDuration = CLIP_DURATION(rce->frameDuration)/BASE_FRAME_DURATION;
+                rce->keptAsRef = true;
+                if (picType == 'b' || picType == 'p')
+                    rce->keptAsRef = false;
                 if (picType == 'I' || picType == 'i')
                     rce->sliceType = I_SLICE;
                 else if (picType == 'P' || picType == 'p')
@@ -998,6 +999,46 @@
     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)
 {
     int orderValue = m_startEndOrder.get();
@@ -1016,10 +1057,11 @@
     m_curSlice = pic->m_picSym->m_slice;
     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)
@@ -1029,7 +1071,6 @@
 
     rce->bLastMiniGopBFrame = pic->m_lowres.bLastMiniGopBFrame;
     rce->bufferRate = m_bufferRate;
-    rce->poc = m_curSlice->m_poc;
     rce->rowCplxrSum = 0.0;
     rce->rowTotalBits = 0;
     if (m_isVbv)
@@ -1053,11 +1094,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);
@@ -1066,6 +1110,7 @@
         rce->qRceq = m_lastRceq;
         accumPQpUpdate();
     }
+
     else //CQP
     {
         if (m_sliceType == B_SLICE && m_curSlice->m_bReferenced)
@@ -2167,6 +2212,7 @@
     if (m_cutreeStatFileIn)
         fclose(m_cutreeStatFileIn);
 
+    X265_FREE(m_rce2Pass);
     for (int i = 0; i < 2; i++)
         X265_FREE(m_cuTreeStats.qpBuffer[i]);
 }
diff -r d9296f2aad72 -r 382e20845179 source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h	Fri Jul 18 17:19:20 2014 +0530
+++ b/source/encoder/ratecontrol.h	Fri Jul 18 17:22:24 2014 +0530
@@ -205,6 +205,7 @@
     void hrdFullness(SEIBufferingPeriod* sei);
     bool init(const SPS* sps);
     void initHRD(SPS* sps);
+    int rateControlSliceType(int frameNum);
 protected:
 
     static const double s_amortizeFraction;
diff -r d9296f2aad72 -r 382e20845179 source/encoder/slicetype.cpp
--- a/source/encoder/slicetype.cpp	Fri Jul 18 17:19:20 2014 +0530
+++ b/source/encoder/slicetype.cpp	Fri Jul 18 17:22:24 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;
@@ -241,7 +242,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);
@@ -300,7 +301,7 @@
 
     memset(frames, 0, sizeof(frames));
     memset(list, 0, sizeof(list));
-
+    int numFrames = 0;
     {
         Frame *pic = m_inputQueue.first();
         int j;
@@ -310,6 +311,7 @@
             list[j] = pic;
             pic = pic->m_next;
         }
+        numFrames = j;
 
         pic = m_inputQueue.first();
         frames[0] = m_lastNonB;
@@ -328,7 +330,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 < numFrames; i++)
+            list[i]->m_lowres.sliceType =
+            m_top->m_rateControl->rateControlSliceType(list[i]->getPOC());
+    }
+
+    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 d9296f2aad72 -r 382e20845179 source/encoder/slicetype.h
--- a/source/encoder/slicetype.h	Fri Jul 18 17:19:20 2014 +0530
+++ b/source/encoder/slicetype.h	Fri Jul 18 17:22:24 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