[x265] [PATCH] rc: compute average of qpaRc, qpAq per frame even in 2 pass

aarthi at multicorewareinc.com aarthi at multicorewareinc.com
Wed Jul 23 21:10:03 CEST 2014


# HG changeset patch
# User Aarthi Thirumalai
# Date 1406142435 -19800
#      Thu Jul 24 00:37:15 2014 +0530
# Node ID 6920d5d634dc0f4bf3312b0127ecd700f7e6b550
# Parent  db6b7046d4f0d75bdd6b513f5ad578b3df3b6f17
rc: compute average of qpaRc, qpAq per frame even in 2 pass

diff -r db6b7046d4f0 -r 6920d5d634dc source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Wed Jul 23 14:42:10 2014 +0530
+++ b/source/encoder/ratecontrol.cpp	Thu Jul 24 00:37:15 2014 +0530
@@ -2063,100 +2063,104 @@
                     x265_qp2qScale(int(pic->m_avgQpRc + 0.5) + mbtree_offset);
             }
         }
-        if (!m_isAbrReset)
+    }
+    if (!m_isAbrReset)
+    {
+        if (m_param->rc.aqMode || m_isVbv)
         {
-            if (m_param->rc.aqMode || m_isVbv)
+            if (pic->m_qpaRc)
             {
-                if (pic->m_qpaRc)
+                for (uint32_t i = 0; i < pic->getFrameHeightInCU(); i++)
                 {
-                    for (uint32_t i = 0; i < pic->getFrameHeightInCU(); i++)
-                    {
-                        pic->m_avgQpRc += pic->m_qpaRc[i];
-                    }
-
-                    pic->m_avgQpRc /= (pic->getFrameHeightInCU() * pic->getFrameWidthInCU());
-                    rce->qpaRc = pic->m_avgQpRc;
-                    // copy avg RC qp to m_avgQpAq. To print out the correct qp when aq/cutree is disabled.
-                    pic->m_avgQpAq = pic->m_avgQpRc;
+                    pic->m_avgQpRc += pic->m_qpaRc[i];
                 }
 
-                if (pic->m_qpaAq)
+                pic->m_avgQpRc /= (pic->getFrameHeightInCU() * pic->getFrameWidthInCU());
+                rce->qpaRc = pic->m_avgQpRc;
+                // copy avg RC qp to m_avgQpAq. To print out the correct qp when aq/cutree is disabled.
+                pic->m_avgQpAq = pic->m_avgQpRc;
+            }
+
+            if (pic->m_qpaAq)
+            {
+                for (uint32_t i = 0; i < pic->getFrameHeightInCU(); i++)
                 {
-                    for (uint32_t i = 0; i < pic->getFrameHeightInCU(); i++)
-                    {
-                        pic->m_avgQpAq += pic->m_qpaAq[i];
-                    }
+                    pic->m_avgQpAq += pic->m_qpaAq[i];
+                }
 
-                    pic->m_avgQpAq /= (pic->getFrameHeightInCU() * pic->getFrameWidthInCU());
-                }
+                pic->m_avgQpAq /= (pic->getFrameHeightInCU() * pic->getFrameWidthInCU());
             }
-            // Write frame stats into the stats file if 2 pass is enabled.
-            if (m_param->rc.bStatWrite)
-            {
-                char cType = rce->sliceType == I_SLICE ? (rce->poc == 0 ? 'I' : 'i')
-                    : rce->sliceType == P_SLICE ? (pic->m_picSym->m_slice->m_bReferenced ? 'P' : 'p')
-                    : pic->m_picSym->m_slice->m_bReferenced ? 'B' : 'b';
-                if (fprintf(m_statFileOut,
-                         "in:%d out:%d type:%c dur:%.3f q:%.2f q-aq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ",
-                         rce->poc, rce->encodeOrder,
-                         cType, m_frameDuration,
-                         pic->m_avgQpRc, pic->m_avgQpAq,
-                         stats->coeffBits,
-                         stats->mvBits,
-                         stats->miscBits,
-                         stats->cuCount_i * m_ncu,
-                         stats->cuCount_p * m_ncu,
-                         stats->cuCount_skip * m_ncu) < 0)
-                    goto writeFailure;
-                if (fprintf(m_statFileOut, ";\n") < 0)
-                    goto writeFailure;
-                /* Don't re-write the data in multi-pass mode. */
-                if (m_param->rc.cuTree && pic->m_picSym->m_slice->m_bReferenced && !m_param->rc.bStatRead)
-                {
-                    uint8_t sliceType = (uint8_t)rce->sliceType;
-                    for (int i = 0; i < m_ncu; i++)
-                         m_cuTreeStats.qpBuffer[0][i] = (uint16_t)(pic->m_lowres.qpCuTreeOffset[i] * 256.0);
-                    if (fwrite(&sliceType, 1, 1, m_cutreeStatFileOut) < 1)
-                        goto writeFailure;
-                    if (fwrite(m_cuTreeStats.qpBuffer[0], sizeof(uint16_t), m_ncu, m_cutreeStatFileOut) < (size_t)m_ncu)
-                        goto writeFailure;
-                }
-            }
-            /* amortize part of each I slice over the next several frames, up to
-             * keyint-max, to avoid over-compensating for the large I slice cost */
-            if (!m_param->rc.bStatWrite && !m_param->rc.bStatRead)
-            {
-                if (rce->sliceType == I_SLICE)
-                {
-                    /* 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);
-                    bits -= m_residualCost * m_residualFrames;
-                }
-                else if (m_residualFrames)
-                {
-                    bits += m_residualCost;
-                    m_residualFrames--;
-                }
-            }
-            if (rce->sliceType != B_SLICE)
-            {
-                /* The factor 1.5 is to tune up the actual bits, otherwise the cplxrSum is scaled too low
-                 * to improve short term compensation for next frame. */
-                m_cplxrSum += (bits * x265_qp2qScale(rce->qpaRc) / rce->qRceq) - (rce->rowCplxrSum);
-            }
-            else
-            {
-                /* Depends on the fact that B-frame's QP is an offset from the following P-frame's.
-                 * Not perfectly accurate with B-refs, but good enough. */
-                m_cplxrSum += (bits * x265_qp2qScale(rce->qpaRc) / (rce->qRceq * fabs(m_param->rc.pbFactor))) - (rce->rowCplxrSum);
-            }
-            m_wantedBitsWindow += m_frameDuration * m_bitrate;
-            m_totalBits += bits - rce->rowTotalBits;
         }
     }
+    // Write frame stats into the stats file if 2 pass is enabled.
+    if (m_param->rc.bStatWrite)
+    {
+        char cType = rce->sliceType == I_SLICE ? (rce->poc == 0 ? 'I' : 'i')
+            : rce->sliceType == P_SLICE ? (pic->m_picSym->m_slice->m_bReferenced ? 'P' : 'p')
+            : pic->m_picSym->m_slice->m_bReferenced ? 'B' : 'b';
+        if (fprintf(m_statFileOut,
+                    "in:%d out:%d type:%c dur:%.3f q:%.2f q-aq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ",
+                    rce->poc, rce->encodeOrder,
+                    cType, m_frameDuration,
+                    pic->m_avgQpRc, pic->m_avgQpAq,
+                    stats->coeffBits,
+                    stats->mvBits,
+                    stats->miscBits,
+                    stats->cuCount_i * m_ncu,
+                    stats->cuCount_p * m_ncu,
+                    stats->cuCount_skip * m_ncu) < 0)
+            goto writeFailure;
+        if (fprintf(m_statFileOut, ";\n") < 0)
+            goto writeFailure;
+        /* Don't re-write the data in multi-pass mode. */
+        if (m_param->rc.cuTree && pic->m_picSym->m_slice->m_bReferenced && !m_param->rc.bStatRead)
+        {
+            uint8_t sliceType = (uint8_t)rce->sliceType;
+            for (int i = 0; i < m_ncu; i++)
+                    m_cuTreeStats.qpBuffer[0][i] = (uint16_t)(pic->m_lowres.qpCuTreeOffset[i] * 256.0);
+            if (fwrite(&sliceType, 1, 1, m_cutreeStatFileOut) < 1)
+                goto writeFailure;
+            if (fwrite(m_cuTreeStats.qpBuffer[0], sizeof(uint16_t), m_ncu, m_cutreeStatFileOut) < (size_t)m_ncu)
+                goto writeFailure;
+        }
+    }
+    if (m_isAbr && !m_isAbrReset)
+    {
+        /* amortize part of each I slice over the next several frames, up to
+         * keyint-max, to avoid over-compensating for the large I slice cost */
+        if (!m_param->rc.bStatWrite && !m_param->rc.bStatRead)
+        {
+            if (rce->sliceType == I_SLICE)
+            {
+                /* 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);
+                bits -= m_residualCost * m_residualFrames;
+            }
+            else if (m_residualFrames)
+            {
+                bits += m_residualCost;
+                m_residualFrames--;
+            }
+        }
+        if (rce->sliceType != B_SLICE)
+        {
+            /* The factor 1.5 is to tune up the actual bits, otherwise the cplxrSum is scaled too low
+                * to improve short term compensation for next frame. */
+            m_cplxrSum += (bits * x265_qp2qScale(rce->qpaRc) / rce->qRceq) - (rce->rowCplxrSum);
+        }
+        else
+        {
+            /* Depends on the fact that B-frame's QP is an offset from the following P-frame's.
+                * Not perfectly accurate with B-refs, but good enough. */
+            m_cplxrSum += (bits * x265_qp2qScale(rce->qpaRc) / (rce->qRceq * fabs(m_param->rc.pbFactor))) - (rce->rowCplxrSum);
+        }
+        m_wantedBitsWindow += m_frameDuration * m_bitrate;
+        m_totalBits += bits - rce->rowTotalBits;
+    }
+
     if (m_2pass)
     {
         m_expectedBitsSum += qScale2bits(rce, x265_qp2qScale(rce->newQp));


More information about the x265-devel mailing list