Imported Upstream version 1.4+222+hg5f9f7194267b
[deb_x265.git] / source / encoder / ratecontrol.cpp
index f54b1015c4c01af94d7cd30732e1c33d71bb27da..4f31fe18d31e1dd2ff250524a610f207edf8bf11 100644 (file)
@@ -40,8 +40,7 @@
 using namespace x265;
 
 /* Amortize the partial cost of I frames over the next N frames */
-const double RateControl::s_amortizeFraction = 0.85;
-const int RateControl::s_amortizeFrames = 75;
+
 const int RateControl::s_slidingWindowFrames = 20;
 const char *RateControl::s_defaultStatFileName = "x265_2pass.log";
 
@@ -173,8 +172,8 @@ static inline uint32_t acEnergyPlane(Frame *curFrame, pixel* src, intptr_t srcSt
 /* Find the total AC energy of each block in all planes */
 uint32_t RateControl::acEnergyCu(Frame* curFrame, uint32_t block_x, uint32_t block_y)
 {
-    intptr_t stride = curFrame->m_origPicYuv->m_stride;
-    intptr_t cStride = curFrame->m_origPicYuv->m_strideC;
+    intptr_t stride = curFrame->m_fencPic->m_stride;
+    intptr_t cStride = curFrame->m_fencPic->m_strideC;
     intptr_t blockOffsetLuma = block_x + (block_y * stride);
     int colorFormat = m_param->internalCsp;
     int hShift = CHROMA_H_SHIFT(colorFormat);
@@ -183,9 +182,9 @@ uint32_t RateControl::acEnergyCu(Frame* curFrame, uint32_t block_x, uint32_t blo
 
     uint32_t var;
 
-    var  = acEnergyPlane(curFrame, curFrame->m_origPicYuv->m_picOrg[0] + blockOffsetLuma, stride, 0, colorFormat);
-    var += acEnergyPlane(curFrame, curFrame->m_origPicYuv->m_picOrg[1] + blockOffsetChroma, cStride, 1, colorFormat);
-    var += acEnergyPlane(curFrame, curFrame->m_origPicYuv->m_picOrg[2] + blockOffsetChroma, cStride, 2, colorFormat);
+    var  = acEnergyPlane(curFrame, curFrame->m_fencPic->m_picOrg[0] + blockOffsetLuma, stride, 0, colorFormat);
+    var += acEnergyPlane(curFrame, curFrame->m_fencPic->m_picOrg[1] + blockOffsetChroma, cStride, 1, colorFormat);
+    var += acEnergyPlane(curFrame, curFrame->m_fencPic->m_picOrg[2] + blockOffsetChroma, cStride, 2, colorFormat);
     x265_emms();
     return var;
 }
@@ -193,8 +192,8 @@ uint32_t RateControl::acEnergyCu(Frame* curFrame, uint32_t block_x, uint32_t blo
 void RateControl::calcAdaptiveQuantFrame(Frame *curFrame)
 {
     /* Actual adaptive quantization */
-    int maxCol = curFrame->m_origPicYuv->m_picWidth;
-    int maxRow = curFrame->m_origPicYuv->m_picHeight;
+    int maxCol = curFrame->m_fencPic->m_picWidth;
+    int maxRow = curFrame->m_fencPic->m_picHeight;
 
     for (int y = 0; y < 3; y++)
     {
@@ -323,6 +322,12 @@ RateControl::RateControl(x265_param *p)
     m_bTerminated = false;
     m_finalFrameCount = 0;
     m_numEntries = 0;
+    m_amortizeFraction = 0.85;
+    m_amortizeFrames = 75;
+    if (m_param->totalFrames <= 2 * m_fps)
+    {
+        m_amortizeFraction = m_amortizeFrames = 0;
+    }
     if (m_param->rc.rateControlMode == X265_RC_CRF)
     {
         m_param->rc.qp = (int)m_param->rc.rfConstant;
@@ -494,12 +499,12 @@ bool RateControl::init(const SPS *sps)
     /* Frame Predictors and Row predictors used in vbv */
     for (int i = 0; i < 5; i++)
     {
-        m_pred[i].coeff = 2.0;
+        m_pred[i].coeff = 1.5;
         m_pred[i].count = 1.0;
         m_pred[i].decay = 0.5;
         m_pred[i].offset = 0.0;
     }
-    m_predBfromP = m_pred[0];
+    m_pred[0].coeff = 1.0;
     if (!m_statFileOut && (m_param->rc.bStatWrite || m_param->rc.bStatRead))
     {
         /* If the user hasn't defined the stat filename, use the default value */
@@ -1157,7 +1162,7 @@ int RateControl::rateControlStart(Frame* curFrame, RateControlEntry* rce, Encode
     rce->leadingNoBSatd = m_leadingNoBSatd;
     if (curFrame->m_forceqp)
     {
-        m_qp = int32_t(curFrame->m_forceqp + 0.5) - 1;
+        m_qp = (int32_t)(curFrame->m_forceqp + 0.5) - 1;
         m_qp = Clip3(QP_MIN, QP_MAX_MAX, m_qp);
         rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = m_qp;
     }
@@ -1343,6 +1348,25 @@ fail:
     return false;
 }
 
+double RateControl::tuneAbrQScaleFromFeedback(double qScale)
+{
+    double abrBuffer = 2 * m_param->rc.rateTolerance * m_bitrate;
+    if (m_currentSatd)
+    {
+        /* use framesDone instead of POC as poc count is not serial with bframes enabled */
+        double overflow = 1.0;
+        double timeDone = (double)(m_framesDone - m_param->frameNumThreads + 1) * m_frameDuration;
+        double wantedBits = timeDone * m_bitrate;
+        if (wantedBits > 0 && m_totalBits > 0 && !m_partialResidualFrames)
+        {
+            abrBuffer *= X265_MAX(1, sqrt(timeDone));
+            overflow = Clip3(.5, 2.0, 1.0 + (m_totalBits - wantedBits) / abrBuffer);
+            qScale *= overflow;
+        }
+    }
+    return qScale;
+}
+
 double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
 {
     double q;
@@ -1415,17 +1439,25 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
             q += m_pbOffset / 2;
         else
             q += m_pbOffset;
-        rce->qpNoVbv = q;
-        double qScale = x265_qp2qScale(q);
 
-        if (!m_2pass && m_isVbv)
+        double qScale = x265_qp2qScale(q);
+        if (m_isCbr)
         {
-            if (m_leadingBframes > 5)
+            qScale = tuneAbrQScaleFromFeedback(qScale);
+            if (!m_isAbrReset)
             {
-                qScale = clipQscale(curFrame, rce, qScale);
-                m_lastQScaleFor[m_sliceType] = qScale;
+                double lmin = m_lastQScaleFor[P_SLICE] / m_lstep;
+                double lmax = m_lastQScaleFor[P_SLICE] * m_lstep;
+                qScale = Clip3(lmin, lmax, qScale);
             }
-            rce->frameSizePlanned = predictSize(&m_predBfromP, qScale, (double)m_leadingNoBSatd);
+            q = x265_qScale2qp(qScale);
+        }
+        rce->qpNoVbv = q;
+        if (!m_2pass && m_isVbv)
+        {
+            qScale = clipQscale(curFrame, rce, qScale);
+            m_lastQScaleFor[m_sliceType] = qScale;
+            rce->frameSizePlanned = predictSize(&m_pred[m_sliceType], qScale, (double)m_currentSatd);
         }
         else if (m_2pass && m_isVbv)
         {
@@ -1508,7 +1540,7 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
              * tradeoff between quality and bitrate precision. But at large
              * tolerances, the bit distribution approaches that of 2pass. */
 
-            double wantedBits, overflow = 1;
+            double overflow = 1;
 
             m_shortTermCplxSum *= 0.5;
             m_shortTermCplxCount *= 0.5;
@@ -1528,25 +1560,10 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
             {
                 if (!m_param->rc.bStatRead)
                     checkAndResetABR(rce, false);
-                q = getQScale(rce, m_wantedBitsWindow / m_cplxrSum);
-
-                /* ABR code can potentially be counterproductive in CBR, so just
-                 * don't bother.  Don't run it if the frame complexity is zero
-                 * either. */
-                if (!m_isCbr && m_currentSatd)
-                {
-                    /* use framesDone instead of POC as poc count is not serial with bframes enabled */
-                    double timeDone = (double)(m_framesDone - m_param->frameNumThreads + 1) * m_frameDuration;
-                    wantedBits = timeDone * m_bitrate;
-                    if (wantedBits > 0 && m_totalBits > 0 && !m_partialResidualFrames)
-                    {
-                        abrBuffer *= X265_MAX(1, sqrt(timeDone));
-                        overflow = Clip3(.5, 2.0, 1.0 + (m_totalBits - wantedBits) / abrBuffer);
-                        q *= overflow;
-                    }
-                }
+                double initialQScale = getQScale(rce, m_wantedBitsWindow / m_cplxrSum);
+                q = tuneAbrQScaleFromFeedback(initialQScale);
+                overflow = q / initialQScale;
             }
-
             if (m_sliceType == I_SLICE && m_param->keyframeMax > 1
                 && m_lastNonBPictType != I_SLICE && !m_isAbrReset)
             {
@@ -1574,7 +1591,7 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
             {
                 q = x265_qp2qScale(CRF_INIT_QP) / fabs(m_param->rc.ipFactor);
             }
-            else if (m_framesDone == 0 && !m_isVbv)
+            else if (m_framesDone == 0 && !m_isVbv && m_param->rc.rateControlMode == X265_RC_ABR)
             {
                 /* for ABR alone, clip the first I frame qp */
                 double lqmax = x265_qp2qScale(ABR_INIT_QP_MAX) * m_lstep;
@@ -1615,8 +1632,8 @@ void RateControl::rateControlUpdateStats(RateControlEntry* rce)
             if (m_partialResidualFrames)
                 rce->rowTotalBits += m_partialResidualCost * m_partialResidualFrames;
 
-            m_partialResidualFrames = X265_MIN(s_amortizeFrames, m_param->keyframeMax);
-            m_partialResidualCost = (int)((rce->rowTotalBits * s_amortizeFraction) /m_partialResidualFrames);
+            m_partialResidualFrames = X265_MIN(m_amortizeFrames, m_param->keyframeMax);
+            m_partialResidualCost = (int)((rce->rowTotalBits * m_amortizeFraction) /m_partialResidualFrames);
             rce->rowTotalBits -= m_partialResidualCost * m_partialResidualFrames;
         }
         else if (m_partialResidualFrames)
@@ -1725,13 +1742,11 @@ double RateControl::clipQscale(Frame* curFrame, RateControlEntry* rce, double q)
             {
                 double frameQ[3];
                 double curBits;
-                if (m_sliceType == B_SLICE)
-                    curBits = predictSize(&m_predBfromP, q, (double)m_currentSatd);
-                else
-                    curBits = predictSize(&m_pred[m_sliceType], q, (double)m_currentSatd);
+                curBits = predictSize(&m_pred[m_sliceType], q, (double)m_currentSatd);
                 double bufferFillCur = m_bufferFill - curBits;
                 double targetFill;
-                double totalDuration = 0;
+                double totalDuration = m_frameDuration;
+                bool isIFramePresent = m_sliceType == I_SLICE ? true : false;
                 frameQ[P_SLICE] = m_sliceType == I_SLICE ? q * m_param->rc.ipFactor : (m_sliceType == B_SLICE ? q / m_param->rc.pbFactor : q);
                 frameQ[B_SLICE] = frameQ[P_SLICE] * m_param->rc.pbFactor;
                 frameQ[I_SLICE] = frameQ[P_SLICE] / m_param->rc.ipFactor;
@@ -1747,20 +1762,23 @@ double RateControl::clipQscale(Frame* curFrame, RateControlEntry* rce, double q)
                         bufferFillCur += wantedFrameSize;
                     int64_t satd = curFrame->m_lowres.plannedSatd[j] >> (X265_DEPTH - 8);
                     type = IS_X265_TYPE_I(type) ? I_SLICE : IS_X265_TYPE_B(type) ? B_SLICE : P_SLICE;
+                    if (type == I_SLICE) 
+                        isIFramePresent = true;
                     curBits = predictSize(&m_pred[type], frameQ[type], (double)satd);
                     bufferFillCur -= curBits;
                 }
 
-                /* Try to get the buffer at least 50% filled, but don't set an impossible goal. */
-                targetFill = X265_MIN(m_bufferFill + totalDuration * m_vbvMaxRate * 0.5, m_bufferSize * 0.5);
+                /* Try to get the buffer no more than 80% filled, but don't set an impossible goal. */
+                double tol = isIFramePresent ? 1 / totalDuration : totalDuration < 0.5 ? 2 : 1;
+                targetFill = X265_MIN(m_bufferFill + totalDuration * m_vbvMaxRate * 0.5 , m_bufferSize * (1 - 0.8 * totalDuration * tol));
                 if (bufferFillCur < targetFill)
                 {
                     q *= 1.01;
                     loopTerminate |= 1;
                     continue;
                 }
-                /* Try to get the buffer no more than 80% filled, but don't set an impossible goal. */
-                targetFill = Clip3(m_bufferSize * 0.8, m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5);
+                /* Try to get the buffer atleast 50% filled, but don't set an impossible goal. */
+                targetFill = Clip3(m_bufferSize - (m_bufferSize * totalDuration * 0.5), m_bufferSize, m_bufferFill - totalDuration * m_vbvMaxRate * 0.5);
                 if (m_isCbr && bufferFillCur > targetFill)
                 {
                     q /= 1.01;
@@ -1810,25 +1828,6 @@ double RateControl::clipQscale(Frame* curFrame, RateControlEntry* rce, double q)
         if (pbits > rce->frameSizeMaximum)
             q *= pbits / rce->frameSizeMaximum;
 
-        // Check B-frame complexity, and use up any bits that would
-        // overflow before the next P-frame.
-        if (m_leadingBframes <= 5 && m_sliceType == P_SLICE && !m_singleFrameVbv)
-        {
-            int nb = m_leadingBframes;
-            double bits = predictSize(&m_pred[m_sliceType], q, (double)m_currentSatd);
-            double bbits = predictSize(&m_predBfromP, q * m_param->rc.pbFactor, (double)m_currentSatd);
-            double space;
-            if (bbits > m_bufferRate)
-                nb = 0;
-            double pbbits = nb * bbits;
-
-            space = m_bufferFill + (1 + nb) * m_bufferRate - m_bufferSize;
-            if (pbbits < space)
-                q *= X265_MAX(pbbits / space, bits / (0.5 * m_bufferSize));
-
-            q = X265_MAX(q0 / 2, q);
-        }
-
         if (!m_isCbr || (m_isAbr && m_currentSatd >= rce->movingAvgSum && q <= q0 / 2))
             q = X265_MAX(q0, q);
 
@@ -1899,22 +1898,24 @@ double RateControl::predictRowsSizeSum(Frame* curFrame, RateControlEntry* rce, d
                     && refQScale > 0
                     && refRowSatdCost > 0)
                 {
-                    if (abs(int32_t(refRowSatdCost - satdCostForPendingCus)) < (int32_t)satdCostForPendingCus / 2)
+                    if (abs((int32_t)(refRowSatdCost - satdCostForPendingCus)) < (int32_t)satdCostForPendingCus / 2)
                     {
                         double predTotal = refRowBits * satdCostForPendingCus / refRowSatdCost * refQScale / qScale;
-                        totalSatdBits += int32_t((pred_s + predTotal) * 0.5);
+                        totalSatdBits += (int32_t)((pred_s + predTotal) * 0.5);
                         continue;
                     }
                 }
-                totalSatdBits += int32_t(pred_s);
+                totalSatdBits += (int32_t)pred_s;
             }
-            else
+            else if (picType == P_SLICE)
             {
                 /* Our QP is lower than the reference! */
                 double pred_intra = predictSize(rce->rowPred[1], qScale, intraCost);
                 /* Sum: better to overestimate than underestimate by using only one of the two predictors. */
-                totalSatdBits += int32_t(pred_intra + pred_s);
+                totalSatdBits += (int32_t)(pred_intra + pred_s);
             }
+            else
+                totalSatdBits += (int32_t)pred_s;
         }
     }
 
@@ -1969,16 +1970,8 @@ int RateControl::rowDiagonalVbvRateControl(Frame* curFrame, uint32_t row, RateCo
 
     if (row < sps.numCuInHeight - 1)
     {
-        /* B-frames shouldn't use lower QP than their reference frames. */
-        if (rce->sliceType == B_SLICE)
-        {
-            Frame* refSlice1 = curEncData.m_slice->m_refPicList[0][0];
-            Frame* refSlice2 = curEncData.m_slice->m_refPicList[1][0];
-            qpMin = X265_MAX(qpMin, X265_MAX(refSlice1->m_encData->m_rowStat[row].diagQp, refSlice2->m_encData->m_rowStat[row].diagQp));
-            qpVbv = X265_MAX(qpVbv, qpMin);
-        }
         /* More threads means we have to be more cautious in letting ratecontrol use up extra bits. */
-        double rcTol = bufferLeftPlanned / m_param->frameNumThreads * m_param->rc.rateTolerance;
+        double rcTol = (bufferLeftPlanned * 0.2) / m_param->frameNumThreads * m_param->rc.rateTolerance;
         int32_t encodedBitsSoFar = 0;
         double accFrameBits = predictRowsSizeSum(curFrame, rce, qpVbv, encodedBitsSoFar);
 
@@ -1996,7 +1989,7 @@ int RateControl::rowDiagonalVbvRateControl(Frame* curFrame, uint32_t row, RateCo
 
         while (qpVbv < qpMax
                && ((accFrameBits > rce->frameSizePlanned + rcTol) ||
-                   (rce->bufferFill - accFrameBits < bufferLeftPlanned * 0.5) ||
+                   (rce->bufferFill - accFrameBits < bufferLeftPlanned * 0.2) ||
                    (accFrameBits > rce->frameSizePlanned && qpVbv < rce->qpNoVbv)))
         {
             qpVbv += stepSize;
@@ -2085,7 +2078,7 @@ void RateControl::updatePredictor(Predictor *p, double q, double var, double bit
 {
     if (var < 10)
         return;
-    const double range = 1.5;
+    const double range = 2;
     double old_coeff = p->coeff / p->count;
     double new_coeff = bits * q / var;
     double new_coeff_clipped = Clip3(old_coeff / range, old_coeff * range, new_coeff);
@@ -2220,8 +2213,8 @@ int RateControl::rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry*
                 /* previous I still had a residual; roll it into the new loan */
                 if (m_residualFrames)
                     bits += m_residualCost * m_residualFrames;
-                m_residualFrames = X265_MIN(s_amortizeFrames, m_param->keyframeMax);
-                m_residualCost = (int)((bits * s_amortizeFraction) / m_residualFrames);
+                m_residualFrames = X265_MIN(m_amortizeFrames, m_param->keyframeMax);
+                m_residualCost = (int)((bits * m_amortizeFraction) / m_residualFrames);
                 bits -= m_residualCost * m_residualFrames;
             }
             else if (m_residualFrames)
@@ -2257,16 +2250,6 @@ int RateControl::rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry*
 
     if (m_isVbv)
     {
-        if (rce->sliceType == B_SLICE)
-        {
-            m_bframeBits += actualBits;
-            if (rce->bLastMiniGopBFrame)
-            {
-                if (rce->bframes != 0)
-                    updatePredictor(&m_predBfromP, x265_qp2qScale(rce->qpaRc), (double)rce->leadingNoBSatd, (double)m_bframeBits / rce->bframes);
-                m_bframeBits = 0;
-            }
-        }
         updateVbv(actualBits, rce);
 
         if (m_param->bEmitHRDSEI)