<div dir="ltr">pls ignore the previous patch. It has a few bugs while merging.<div>here is the fixed one :</div><div><br></div><div><br></div><div><div># HG changeset patch</div><div># User Divya Manivannan <<a href="mailto:divya@multicorewareinc.com">divya@multicorewareinc.com</a>></div><div># Date 1448267770 -19800</div><div>#      Mon Nov 23 14:06:10 2015 +0530</div><div># Branch stable</div><div># Node ID 0c49c9cc75e4c1ef9534a28b49b97b9107636f5d</div><div># Parent  6b308775b6f065ea5002a76a40aa6f5d81e8ee50</div><div>rc: implement 2 pass CRF, when vbv is enabled.</div><div><br></div><div>Allow CRF with VBV in 2nd pass to increase the quality of capped CRF in the first pass.</div><div><br></div><div>diff -r 6b308775b6f0 -r 0c49c9cc75e4 source/common/param.cpp</div><div>--- a/source/common/param.cpp<span class="" style="white-space:pre">     </span>Mon Nov 23 12:26:45 2015 +0530</div><div>+++ b/source/common/param.cpp<span class="" style="white-space:pre">        </span>Mon Nov 23 14:06:10 2015 +0530</div><div>@@ -1170,7 +1170,7 @@</div><div>         CHECK(0 > param->noiseReductionIntra || param->noiseReductionIntra > 2000, "Valid noise reduction range 0 - 2000");</div><div>     if (param->noiseReductionInter)</div><div>         CHECK(0 > param->noiseReductionInter || param->noiseReductionInter > 2000, "Valid noise reduction range 0 - 2000");</div><div>-    CHECK(param->rc.rateControlMode == X265_RC_CRF && param->rc.bStatRead,</div><div>+    CHECK(param->rc.rateControlMode == X265_RC_CRF && param->rc.bStatRead && param->rc.vbvMaxBitrate == 0,</div><div>           "Constant rate-factor is incompatible with 2pass");</div><div>     CHECK(param->rc.rateControlMode == X265_RC_CQP && param->rc.bStatRead,</div><div>           "Constant QP is incompatible with 2pass");</div><div>diff -r 6b308775b6f0 -r 0c49c9cc75e4 source/encoder/ratecontrol.cpp</div><div>--- a/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre">   </span>Mon Nov 23 12:26:45 2015 +0530</div><div>+++ b/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre"> </span>Mon Nov 23 14:06:10 2015 +0530</div><div>@@ -142,6 +142,8 @@</div><div>     rce->expectedVbv = rce2Pass->expectedVbv;</div><div>     rce->blurredComplexity = rce2Pass->blurredComplexity;</div><div>     rce->sliceType = rce2Pass->sliceType;</div><div>+    rce->qpNoVbv = rce2Pass->qpNoVbv;</div><div>+    rce->newQp = rce2Pass->newQp;</div><div> }</div><div> </div><div> }  // end anonymous namespace</div><div>@@ -205,7 +207,7 @@</div><div>             m_rateFactorMaxDecrement = m_param->rc.rfConstant - m_param->rc.rfConstantMin;</div><div>     }</div><div>     m_isAbr = m_param->rc.rateControlMode != X265_RC_CQP && !m_param->rc.bStatRead;</div><div>-    m_2pass = m_param->rc.rateControlMode == X265_RC_ABR && m_param->rc.bStatRead;</div><div>+    m_2pass = (m_param->rc.rateControlMode == X265_RC_ABR || m_param->rc.vbvMaxBitrate > 0) && m_param->rc.bStatRead;</div><div>     m_bitrate = m_param->rc.bitrate * 1000;</div><div>     m_frameDuration = (double)m_param->fpsDenom / m_param->fpsNum;</div><div>     m_qp = m_param->rc.qp;</div><div>@@ -488,6 +490,12 @@</div><div>                  x265_log(m_param, X265_LOG_ERROR, "Rce Entries for 2 pass cannot be allocated\n");</div><div>                  return false;</div><div>             }</div><div>+            m_encOrder = X265_MALLOC(int, m_numEntries);</div><div>+            if (!m_encOrder)</div><div>+            {</div><div>+                x265_log(m_param, X265_LOG_ERROR, "Encode order for 2 pass cannot be allocated\n");</div><div>+                return false;</div><div>+            }</div><div>             /* init all to skipped p frames */</div><div>             for (int i = 0; i < m_numEntries; i++)</div><div>             {</div><div>@@ -504,6 +512,7 @@</div><div>             {</div><div>                 RateControlEntry *rce;</div><div>                 int frameNumber;</div><div>+                int encodeOrder;</div><div>                 char picType;</div><div>                 int e;</div><div>                 char *next;</div><div>@@ -511,13 +520,14 @@</div><div>                 next = strstr(p, ";");</div><div>                 if (next)</div><div>                     *next++ = 0;</div><div>-                e = sscanf(p, " in:%d ", &frameNumber);</div><div>+                e = sscanf(p, " in:%d out:%d", &frameNumber, &encodeOrder);</div><div>                 if (frameNumber < 0 || frameNumber >= m_numEntries)</div><div>                 {</div><div>                     x265_log(m_param, X265_LOG_ERROR, "bad frame number (%d) at stats line %d\n", frameNumber, i);</div><div>                     return false;</div><div>                 }</div><div>-                rce = &m_rce2Pass[frameNumber];</div><div>+                rce = &m_rce2Pass[encodeOrder];</div><div>+                m_encOrder[frameNumber] = encodeOrder;</div><div>                 e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf q-noVbv:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf",</div><div>                        &picType, &qpRc, &qpAq, &qNoVbv, &rce->coeffBits,</div><div>                        &rce->mvBits, &rce->miscBits, &rce->iCuCount, &rce->pCuCount,</div><div>@@ -538,7 +548,7 @@</div><div>                     x265_log(m_param, X265_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e);</div><div>                     return false;</div><div>                 }</div><div>-                rce->qScale = x265_qp2qScale(qpRc);</div><div>+                rce->qScale = rce->newQScale = x265_qp2qScale(qpRc);</div><div>                 totalQpAq += qpAq;</div><div>                 rce->qpNoVbv = qNoVbv;</div><div>                 rce->qpaRc = qpRc;</div><div>@@ -546,8 +556,7 @@</div><div>                 p = next;</div><div>             }</div><div>             X265_FREE(statsBuf);</div><div>-</div><div>-            if (m_param->rc.rateControlMode == X265_RC_ABR)</div><div>+            if (m_param->rc.rateControlMode == X265_RC_ABR || m_param->rc.vbvMaxBitrate > 0)</div><div>             {</div><div>                 if (!initPass2())</div><div>                     return false;</div><div>@@ -630,11 +639,8 @@</div><div> </div><div>     #undef MAX_DURATION</div><div> }</div><div>-</div><div>-bool RateControl::initPass2()</div><div>+bool RateControl::analyseABR2Pass(int startIndex, int endIndex, uint64_t allAvailableBits)</div><div> {</div><div>-    uint64_t allConstBits = 0;</div><div>-    uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * m_numEntries * m_frameDuration);</div><div>     double rateFactor, stepMult;</div><div>     double qBlur = m_param->rc.qblur;</div><div>     double cplxBlur = m_param->rc.complexityBlur;</div><div>@@ -643,30 +649,19 @@</div><div>     double *qScale, *blurredQscale;</div><div>     double baseCplx = m_ncu * (m_param->bframes ? 120 : 80);</div><div>     double clippedDuration = CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION;</div><div>-</div><div>-    /* find total/average complexity & const_bits */</div><div>-    for (int i = 0; i < m_numEntries; i++)</div><div>-        allConstBits += m_rce2Pass[i].miscBits;</div><div>-</div><div>-    if (allAvailableBits < allConstBits)</div><div>-    {</div><div>-        x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too low. estimated minimum is %d kbps\n",</div><div>-                 (int)(allConstBits * m_fps / m_numEntries * 1000.));</div><div>-        return false;</div><div>-    }</div><div>-</div><div>+    int framesCount = endIndex - startIndex + 1;</div><div>     /* Blur complexities, to reduce local fluctuation of QP.</div><div>      * We don't blur the QPs directly, because then one very simple frame</div><div>      * could drag down the QP of a nearby complex frame and give it more</div><div>      * bits than intended. */</div><div>-    for (int i = 0; i < m_numEntries; i++)</div><div>+    for (int i = startIndex; i <= endIndex; i++)</div><div>     {</div><div>         double weightSum = 0;</div><div>         double cplxSum = 0;</div><div>         double weight = 1.0;</div><div>         double gaussianWeight;</div><div>         /* weighted average of cplx of future frames */</div><div>-        for (int j = 1; j < cplxBlur * 2 && j < m_numEntries - i; j++)</div><div>+        for (int j = 1; j < cplxBlur * 2 && j <= endIndex - i; j++)</div><div>         {</div><div>             RateControlEntry *rcj = &m_rce2Pass[i + j];</div><div>             weight *= 1 - pow(rcj->iCuCount / m_ncu, 2);</div><div>@@ -690,11 +685,10 @@</div><div>         }</div><div>         m_rce2Pass[i].blurredComplexity = cplxSum / weightSum;</div><div>     }</div><div>-</div><div>-    CHECKED_MALLOC(qScale, double, m_numEntries);</div><div>+    CHECKED_MALLOC(qScale, double, framesCount);</div><div>     if (filterSize > 1)</div><div>     {</div><div>-        CHECKED_MALLOC(blurredQscale, double, m_numEntries);</div><div>+        CHECKED_MALLOC(blurredQscale, double, framesCount);</div><div>     }</div><div>     else</div><div>         blurredQscale = qScale;</div><div>@@ -705,9 +699,8 @@</div><div>      * because qscale2bits is not invertible, but we can start with the simple</div><div>      * approximation of scaling the 1st pass by the ratio of bitrates.</div><div>      * The search range is probably overkill, but speed doesn't matter here. */</div><div>-</div><div>     expectedBits = 1;</div><div>-    for (int i = 0; i < m_numEntries; i++)</div><div>+    for (int i = startIndex; i <= endIndex; i++)</div><div>     {</div><div>         RateControlEntry* rce = &m_rce2Pass[i];</div><div>         double q = getQScale(rce, 1.0);</div><div>@@ -784,12 +777,10 @@</div><div>     X265_FREE(qScale);</div><div>     if (filterSize > 1)</div><div>         X265_FREE(blurredQscale);</div><div>-</div><div>     if (m_isVbv)</div><div>-        if (!vbv2Pass(allAvailableBits))</div><div>+    if (!vbv2Pass(allAvailableBits, endIndex, startIndex))</div><div>             return false;</div><div>-    expectedBits = countExpectedBits();</div><div>-</div><div>+    expectedBits = countExpectedBits(startIndex, endIndex);</div><div>     if (fabs(expectedBits / allAvailableBits - 1.0) > 0.01)</div><div>     {</div><div>         double avgq = 0;</div><div>@@ -822,7 +813,125 @@</div><div>     return false;</div><div> }</div><div> </div><div>-bool RateControl::vbv2Pass(uint64_t allAvailableBits)</div><div>+bool RateControl::initPass2()</div><div>+{</div><div>+    uint64_t allConstBits = 0, allCodedBits = 0;</div><div>+    uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * m_numEntries * m_frameDuration);</div><div>+    int startIndex, framesCount, endIndex, cnt;</div><div>+    int fps = (int)(m_fps + 0.5);</div><div>+    startIndex = endIndex = framesCount = 0;</div><div>+    allAvailableBits = uint64_t(m_param->rc.vbvMaxBitrate * 1000. * m_numEntries * m_frameDuration);</div><div>+    bool isQpModified = true;</div><div>+    int diffQp = 0;</div><div>+    int64_t targetBits = 0;</div><div>+    int64_t expectedBits = 0;</div><div>+    for (startIndex = 0, endIndex = 0; endIndex < m_numEntries; endIndex++)</div><div>+    {</div><div>+        allConstBits += m_rce2Pass[endIndex].miscBits;</div><div>+        allCodedBits += m_rce2Pass[endIndex].coeffBits + m_rce2Pass[endIndex].mvBits;</div><div>+        if (m_param->rc.rateControlMode == X265_RC_CRF)</div><div>+        {</div><div>+            framesCount = endIndex - startIndex + 1;</div><div>+            diffQp += int (m_rce2Pass[endIndex].qpaRc - m_rce2Pass[endIndex].qpNoVbv);</div><div>+            if (framesCount > fps)</div><div>+                diffQp -= int (m_rce2Pass[endIndex - fps].qpaRc - m_rce2Pass[endIndex - fps].qpNoVbv);</div><div>+            if (framesCount >= fps)</div><div>+            {</div><div>+                if (diffQp >= 1)</div><div>+                {</div><div>+                    if (!isQpModified && endIndex > fps)</div><div>+                    {</div><div>+                        double factor = 2;</div><div>+                        double step = 0;</div><div>+                        for (int start = endIndex; start <= endIndex + fps - 1 && start < m_numEntries; start++)</div><div>+                        {</div><div>+                            RateControlEntry *rce = &m_rce2Pass[start];</div><div>+                            targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));</div><div>+                            expectedBits += qScale2bits(rce, rce->qScale);</div><div>+                        }</div><div>+                        if (expectedBits < 0.95 * targetBits)</div><div>+                        {</div><div>+                            isQpModified = true;</div><div>+                            while (endIndex + fps < m_numEntries)</div><div>+                            {</div><div>+                                step = pow(2, factor / 6.0);</div><div>+                                expectedBits = 0;</div><div>+                                for (int start = endIndex; start <= endIndex + fps - 1; start++)</div><div>+                                {</div><div>+                                    RateControlEntry *rce = &m_rce2Pass[start];</div><div>+                                    rce->newQScale = rce->qScale / step;</div><div>+                                    X265_CHECK(rce->newQScale >= 0, "new Qscale is negative\n");</div><div>+                                    expectedBits += qScale2bits(rce, rce->newQScale);</div><div>+                                    rce->newQp = x265_qScale2qp(rce->newQScale);</div><div>+                                }</div><div>+                                if (expectedBits >= targetBits && step > 1)</div><div>+                                    factor *= 0.90;</div><div>+                                else</div><div>+                                    break;</div><div>+                            }</div><div>+</div><div>+                            if (m_isVbv && endIndex + fps < m_numEntries)</div><div>+                                if (!vbv2Pass(targetBits, endIndex + fps - 1, endIndex))</div><div>+                                    return false;</div><div>+</div><div>+                            double prevFactor = factor;</div><div>+                            targetBits = 0;</div><div>+                            expectedBits = 0;</div><div>+</div><div>+                            for (int start = endIndex - fps; start <= endIndex - 1; start++)</div><div>+                            {</div><div>+                                RateControlEntry *rce = &m_rce2Pass[start];</div><div>+                                targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));</div><div>+                            }</div><div>+                            while (1)</div><div>+                            {</div><div>+                                step = pow(2, factor / 6.0);</div><div>+                                expectedBits = 0;</div><div>+                                for (int start = endIndex - fps; start <= endIndex - 1; start++)</div><div>+                                {</div><div>+                                    RateControlEntry *rce = &m_rce2Pass[start];</div><div>+                                    rce->newQScale = rce->qScale * step;</div><div>+                                    X265_CHECK(rce->newQScale >= 0, "new Qscale is negative\n");</div><div>+                                    expectedBits += qScale2bits(rce, rce->newQScale);</div><div>+                                    rce->newQp = x265_qScale2qp(rce->newQScale);</div><div>+                                }</div><div>+                                if (expectedBits > targetBits && step > 1)</div><div>+                                    factor *= 1.1;</div><div>+                                else</div><div>+                                     break;</div><div>+                            }</div><div>+                            if (m_isVbv)</div><div>+                            if (!vbv2Pass(targetBits, endIndex - 1, endIndex - fps))</div><div>+                                    return false;</div><div>+                            diffQp = 0;</div><div>+                            startIndex = endIndex + 1;</div><div>+                            targetBits = expectedBits = 0;</div><div>+                        }</div><div>+                        else</div><div>+                            targetBits = expectedBits = 0;</div><div>+                    }</div><div>+                }</div><div>+                else</div><div>+                    isQpModified = false;</div><div>+            }</div><div>+        }</div><div>+    }</div><div>+</div><div>+    if (m_param->rc.rateControlMode == X265_RC_ABR)</div><div>+    {</div><div>+        if (allAvailableBits < allConstBits)</div><div>+        {</div><div>+            x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too low. estimated minimum is %d kbps\n",</div><div>+                     (int)(allConstBits * m_fps / framesCount * 1000.));</div><div>+            return false;</div><div>+        }</div><div>+        if (!analyseABR2Pass(0, m_numEntries - 1, allAvailableBits))</div><div>+            return false;</div><div>+    }</div><div>+    return true;</div><div>+}</div><div>+</div><div>+bool RateControl::vbv2Pass(uint64_t allAvailableBits, int endPos, int startPos)</div><div> {</div><div>     /* for each interval of bufferFull .. underflow, uniformly increase the qp of all</div><div>      * frames in the interval until either buffer is full at some intermediate frame or the</div><div>@@ -848,10 +957,10 @@</div><div>         {   /* not first iteration */</div><div>             adjustment = X265_MAX(X265_MIN(expectedBits / allAvailableBits, 0.999), 0.9);</div><div>             fills[-1] = m_bufferSize * m_param->rc.vbvBufferInit;</div><div>-            t0 = 0;</div><div>+            t0 = startPos;</div><div>             /* fix overflows */</div><div>             adjMin = 1;</div><div>-            while (adjMin && findUnderflow(fills, &t0, &t1, 1))</div><div>+            while (adjMin && findUnderflow(fills, &t0, &t1, 1, endPos))</div><div>             {</div><div>                 adjMin = fixUnderflow(t0, t1, adjustment, MIN_QPSCALE, MAX_MAX_QPSCALE);</div><div>                 t0 = t1;</div><div>@@ -862,20 +971,16 @@</div><div>         t0 = 0;</div><div>         /* fix underflows -- should be done after overflow, as we'd better undersize target than underflowing VBV */</div><div>         adjMax = 1;</div><div>-        while (adjMax && findUnderflow(fills, &t0, &t1, 0))</div><div>+        while (adjMax && findUnderflow(fills, &t0, &t1, 0, endPos))</div><div>             adjMax = fixUnderflow(t0, t1, 1.001, MIN_QPSCALE, MAX_MAX_QPSCALE );</div><div>-</div><div>-        expectedBits = countExpectedBits();</div><div>+        expectedBits = countExpectedBits(startPos, endPos);</div><div>     }</div><div>-    while ((expectedBits < .995 * allAvailableBits) && ((int64_t)(expectedBits+.5) > (int64_t)(prevBits+.5)));</div><div>-</div><div>+    while ((expectedBits < .995 * allAvailableBits) && ((int64_t)(expectedBits+.5) > (int64_t)(prevBits+.5)) && !(m_param->rc.rateControlMode == X265_RC_CRF));</div><div>     if (!adjMax)</div><div>         x265_log(m_param, X265_LOG_WARNING, "vbv-maxrate issue, qpmax or vbv-maxrate too low\n");</div><div>-</div><div>     /* store expected vbv filling values for tracking when encoding */</div><div>-    for (int i = 0; i < m_numEntries; i++)</div><div>+    for (int i = startPos; i <= endPos; i++)</div><div>         m_rce2Pass[i].expectedVbv = m_bufferSize - fills[i];</div><div>-</div><div>     X265_FREE(fills - 1);</div><div>     return true;</div><div> </div><div>@@ -915,9 +1020,10 @@</div><div>                 m_param->bframes = 1;</div><div>             return X265_TYPE_AUTO;</div><div>         }</div><div>-        int frameType = m_rce2Pass[frameNum].sliceType == I_SLICE ? (frameNum > 0 && m_param->bOpenGOP ? X265_TYPE_I : X265_TYPE_IDR)</div><div>-                            : m_rce2Pass[frameNum].sliceType == P_SLICE ? X265_TYPE_P</div><div>-                            : (m_rce2Pass[frameNum].sliceType == B_SLICE && m_rce2Pass[frameNum].keptAsRef? X265_TYPE_BREF : X265_TYPE_B);</div><div>+        int index = m_encOrder[frameNum];</div><div>+        int frameType = m_rce2Pass[index].sliceType == I_SLICE ? (frameNum > 0 && m_param->bOpenGOP ? X265_TYPE_I : X265_TYPE_IDR)</div><div>+                        : m_rce2Pass[index].sliceType == P_SLICE ? X265_TYPE_P</div><div>+                        : (m_rce2Pass[index].sliceType == B_SLICE && m_rce2Pass[index].keptAsRef ? X265_TYPE_BREF : X265_TYPE_B);</div><div>         return frameType;</div><div>     }</div><div>     else</div><div>@@ -968,7 +1074,8 @@</div><div>     if (m_param->rc.bStatRead)</div><div>     {</div><div>         X265_CHECK(rce->poc >= 0 && rce->poc < m_numEntries, "bad encode ordinal\n");</div><div>-        copyRceData(rce, &m_rce2Pass[rce->poc]);</div><div>+        int index = m_encOrder[rce->poc];</div><div>+        copyRceData(rce, &m_rce2Pass[index]);</div><div>     }</div><div>     rce->isActive = true;</div><div>     bool isRefFrameScenecut = m_sliceType!= I_SLICE && m_curSlice->m_refPicList[0][0]->m_lowres.bScenecut == 1;</div><div>@@ -1032,6 +1139,16 @@</div><div>             }</div><div>         }</div><div>     }</div><div>+    if (!m_isAbr && m_2pass && m_param->rc.rateControlMode == X265_RC_CRF)</div><div>+    {</div><div>+        rce->qScale = rce->newQScale;</div><div>+        rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = x265_qScale2qp(rce->newQScale);</div><div>+        m_qp = int(rce->qpaRc + 0.5);</div><div>+        rce->frameSizePlanned = qScale2bits(rce, rce->qScale);</div><div>+        m_framesDone++;</div><div>+        return m_qp;</div><div>+    }</div><div>+</div><div>     if (m_isAbr || m_2pass) // ABR,CRF</div><div>     {</div><div>         if (m_isAbr || m_isVbv)</div><div>@@ -1203,11 +1320,10 @@</div><div>     }</div><div>     return q;</div><div> }</div><div>-</div><div>-double RateControl::countExpectedBits()</div><div>+double RateControl::countExpectedBits(int startPos, int endPos)</div><div> {</div><div>     double expectedBits = 0;</div><div>-    for( int i = 0; i < m_numEntries; i++ )</div><div>+    for (int i = startPos; i <= endPos; i++)</div><div>     {</div><div>         RateControlEntry *rce = &m_rce2Pass[i];</div><div>         rce->expectedBits = (uint64_t)expectedBits;</div><div>@@ -1215,8 +1331,7 @@</div><div>     }</div><div>     return expectedBits;</div><div> }</div><div>-</div><div>-bool RateControl::findUnderflow(double *fills, int *t0, int *t1, int over)</div><div>+bool RateControl::findUnderflow(double *fills, int *t0, int *t1, int over, int endPos)</div><div> {</div><div>     /* find an interval ending on an overflow or underflow (depending on whether</div><div>      * we're adding or removing bits), and starting on the earliest frame that</div><div>@@ -1226,7 +1341,7 @@</div><div>     double fill = fills[*t0 - 1];</div><div>     double parity = over ? 1. : -1.;</div><div>     int start = -1, end = -1;</div><div>-    for (int i = *t0; i < m_numEntries; i++)</div><div>+    for (int i = *t0; i <= endPos; i++)</div><div>     {</div><div>         fill += (m_frameDuration * m_vbvMaxRate -</div><div>                  qScale2bits(&m_rce2Pass[i], m_rce2Pass[i].newQScale)) * parity;</div><div>@@ -1263,12 +1378,11 @@</div><div>     }</div><div>     return adjusted;</div><div> }</div><div>-</div><div> bool RateControl::cuTreeReadFor2Pass(Frame* frame)</div><div> {</div><div>-    uint8_t sliceTypeActual = (uint8_t)m_rce2Pass[frame->m_poc].sliceType;</div><div>-</div><div>-    if (m_rce2Pass[frame->m_poc].keptAsRef)</div><div>+    int index = m_encOrder[frame->m_poc];</div><div>+    uint8_t sliceTypeActual = (uint8_t)m_rce2Pass[index].sliceType;</div><div>+    if (m_rce2Pass[index].keptAsRef)</div><div>     {</div><div>         /* TODO: We don't need pre-lookahead to measure AQ offsets, but there is currently</div><div>          * no way to signal this */</div><div>@@ -1948,6 +2062,8 @@</div><div> </div><div> int RateControl::rowDiagonalVbvRateControl(Frame* curFrame, uint32_t row, RateControlEntry* rce, double& qpVbv)</div><div> {</div><div>+    if (m_param->rc.bStatRead && m_param->rc.rateControlMode == X265_RC_CRF)</div><div>+        return 0;</div><div>     FrameData& curEncData = *curFrame->m_encData;</div><div>     double qScaleVbv = x265_qp2qScale(qpVbv);</div><div>     uint64_t rowSatdCost = curEncData.m_rowStat[row].diagSatd;</div><div>@@ -2195,7 +2311,7 @@</div><div> </div><div>     if (m_param->rc.aqMode || m_isVbv)</div><div>     {</div><div>-        if (m_isVbv)</div><div>+        if (m_isVbv && !(m_2pass && m_param->rc.rateControlMode == X265_RC_CRF))</div><div>         {</div><div>             /* determine avg QP decided by VBV rate control */</div><div>             for (uint32_t i = 0; i < slice->m_sps->numCuInHeight; i++)</div><div>diff -r 6b308775b6f0 -r 0c49c9cc75e4 source/encoder/ratecontrol.h</div><div>--- a/source/encoder/ratecontrol.h<span class="" style="white-space:pre">    </span>Mon Nov 23 12:26:45 2015 +0530</div><div>+++ b/source/encoder/ratecontrol.h<span class="" style="white-space:pre">   </span>Mon Nov 23 14:06:10 2015 +0530</div><div>@@ -205,8 +205,8 @@</div><div>     double  m_lastAccumPNorm;</div><div>     double  m_expectedBitsSum;   /* sum of qscale2bits after rceq, ratefactor, and overflow, only includes finished frames */</div><div>     int64_t m_predictedBits;</div><div>+    int     *m_encOrder;</div><div>     RateControlEntry* m_rce2Pass;</div><div>-</div><div>     struct</div><div>     {</div><div>         uint16_t *qpBuffer[2]; /* Global buffers for converting MB-tree quantizer data. */</div><div>@@ -258,11 +258,12 @@</div><div>     void   checkAndResetABR(RateControlEntry* rce, bool isFrameDone);</div><div>     double predictRowsSizeSum(Frame* pic, RateControlEntry* rce, double qpm, int32_t& encodedBits);</div><div>     bool   initPass2();</div><div>+    bool   analyseABR2Pass(int startPoc, int endPoc, uint64_t allAvailableBits);</div><div>     void   initFramePredictors();</div><div>     double getDiffLimitedQScale(RateControlEntry *rce, double q);</div><div>-    double countExpectedBits();</div><div>-    bool   vbv2Pass(uint64_t allAvailableBits);</div><div>-    bool   findUnderflow(double *fills, int *t0, int *t1, int over);</div><div>+    double countExpectedBits(int startPos, int framesCount);</div><div>+    bool   vbv2Pass(uint64_t allAvailableBits, int frameCount, int startPos);</div><div>+    bool   findUnderflow(double *fills, int *t0, int *t1, int over, int framesCount);</div><div>     bool   fixUnderflow(int t0, int t1, double adjustment, double qscaleMin, double qscaleMax);</div><div> };</div><div> }</div></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 23, 2015 at 2:16 PM,  <span dir="ltr"><<a href="mailto:aarthi@multicorewareinc.com" target="_blank">aarthi@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Divya Manivannan <<a href="mailto:divya@multicorewareinc.com">divya@multicorewareinc.com</a>><br>
# Date 1448267770 -19800<br>
#      Mon Nov 23 14:06:10 2015 +0530<br>
# Branch stable<br>
# Node ID ffb0111298cdfcf6fe77d143089144c23b644b2d<br>
# Parent  6b308775b6f065ea5002a76a40aa6f5d81e8ee50<br>
rc: implement 2 pass CRF, when vbv is enabled.<br>
<br>
Allow CRF with VBV in 2nd pass to increase the quality of capped CRF in the first pass.<br>
<br>
diff -r 6b308775b6f0 -r ffb0111298cd source/common/param.cpp<br>
--- a/source/common/param.cpp   Mon Nov 23 12:26:45 2015 +0530<br>
+++ b/source/common/param.cpp   Mon Nov 23 14:06:10 2015 +0530<br>
@@ -1170,7 +1170,7 @@<br>
         CHECK(0 > param->noiseReductionIntra || param->noiseReductionIntra > 2000, "Valid noise reduction range 0 - 2000");<br>
     if (param->noiseReductionInter)<br>
         CHECK(0 > param->noiseReductionInter || param->noiseReductionInter > 2000, "Valid noise reduction range 0 - 2000");<br>
-    CHECK(param->rc.rateControlMode == X265_RC_CRF && param->rc.bStatRead,<br>
+    CHECK(param->rc.rateControlMode == X265_RC_CRF && param->rc.bStatRead && param->rc.vbvMaxBitrate == 0,<br>
           "Constant rate-factor is incompatible with 2pass");<br>
     CHECK(param->rc.rateControlMode == X265_RC_CQP && param->rc.bStatRead,<br>
           "Constant QP is incompatible with 2pass");<br>
diff -r 6b308775b6f0 -r ffb0111298cd source/encoder/ratecontrol.cpp<br>
--- a/source/encoder/ratecontrol.cpp    Mon Nov 23 12:26:45 2015 +0530<br>
+++ b/source/encoder/ratecontrol.cpp    Mon Nov 23 14:06:10 2015 +0530<br>
@@ -142,6 +142,8 @@<br>
     rce->expectedVbv = rce2Pass->expectedVbv;<br>
     rce->blurredComplexity = rce2Pass->blurredComplexity;<br>
     rce->sliceType = rce2Pass->sliceType;<br>
+    rce->qpNoVbv = rce2Pass->qpNoVbv;<br>
+    rce->newQp = rce2Pass->newQp;<br>
 }<br>
<br>
 }  // end anonymous namespace<br>
@@ -205,7 +207,7 @@<br>
             m_rateFactorMaxDecrement = m_param->rc.rfConstant - m_param->rc.rfConstantMin;<br>
     }<br>
     m_isAbr = m_param->rc.rateControlMode != X265_RC_CQP && !m_param->rc.bStatRead;<br>
-    m_2pass = m_param->rc.rateControlMode == X265_RC_ABR && m_param->rc.bStatRead;<br>
+    m_2pass = (m_param->rc.rateControlMode == X265_RC_ABR || m_param->rc.vbvMaxBitrate > 0) && m_param->rc.bStatRead;<br>
     m_bitrate = m_param->rc.bitrate * 1000;<br>
     m_frameDuration = (double)m_param->fpsDenom / m_param->fpsNum;<br>
     m_qp = m_param->rc.qp;<br>
@@ -488,6 +490,12 @@<br>
                  x265_log(m_param, X265_LOG_ERROR, "Rce Entries for 2 pass cannot be allocated\n");<br>
                  return false;<br>
             }<br>
+            m_encOrder = X265_MALLOC(int, m_numEntries);<br>
+            if (!m_encOrder)<br>
+            {<br>
+                x265_log(m_param, X265_LOG_ERROR, "Encode order for 2 pass cannot be allocated\n");<br>
+                return false;<br>
+            }<br>
             /* init all to skipped p frames */<br>
             for (int i = 0; i < m_numEntries; i++)<br>
             {<br>
@@ -504,6 +512,7 @@<br>
             {<br>
                 RateControlEntry *rce;<br>
                 int frameNumber;<br>
+                int encodeOrder;<br>
                 char picType;<br>
                 int e;<br>
                 char *next;<br>
@@ -511,13 +520,14 @@<br>
                 next = strstr(p, ";");<br>
                 if (next)<br>
                     *next++ = 0;<br>
-                e = sscanf(p, " in:%d ", &frameNumber);<br>
+                e = sscanf(p, " in:%d out:%d", &frameNumber, &encodeOrder);<br>
                 if (frameNumber < 0 || frameNumber >= m_numEntries)<br>
                 {<br>
                     x265_log(m_param, X265_LOG_ERROR, "bad frame number (%d) at stats line %d\n", frameNumber, i);<br>
                     return false;<br>
                 }<br>
-                rce = &m_rce2Pass[frameNumber];<br>
+                rce = &m_rce2Pass[encodeOrder];<br>
+                m_encOrder[frameNumber] = encodeOrder;<br>
                 e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf q-noVbv:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf",<br>
                        &picType, &qpRc, &qpAq, &qNoVbv, &rce->coeffBits,<br>
                        &rce->mvBits, &rce->miscBits, &rce->iCuCount, &rce->pCuCount,<br>
@@ -546,8 +556,7 @@<br>
                 p = next;<br>
             }<br>
             X265_FREE(statsBuf);<br>
-<br>
-            if (m_param->rc.rateControlMode == X265_RC_ABR)<br>
+            if (m_param->rc.rateControlMode == X265_RC_ABR || m_param->rc.vbvMaxBitrate > 0)<br>
             {<br>
                 if (!initPass2())<br>
                     return false;<br>
@@ -630,11 +639,8 @@<br>
<br>
     #undef MAX_DURATION<br>
 }<br>
-<br>
-bool RateControl::initPass2()<br>
+bool RateControl::analyseABR2Pass(int startIndex, int endIndex, uint64_t allAvailableBits)<br>
 {<br>
-    uint64_t allConstBits = 0;<br>
-    uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * m_numEntries * m_frameDuration);<br>
     double rateFactor, stepMult;<br>
     double qBlur = m_param->rc.qblur;<br>
     double cplxBlur = m_param->rc.complexityBlur;<br>
@@ -643,30 +649,19 @@<br>
     double *qScale, *blurredQscale;<br>
     double baseCplx = m_ncu * (m_param->bframes ? 120 : 80);<br>
     double clippedDuration = CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION;<br>
-<br>
-    /* find total/average complexity & const_bits */<br>
-    for (int i = 0; i < m_numEntries; i++)<br>
-        allConstBits += m_rce2Pass[i].miscBits;<br>
-<br>
-    if (allAvailableBits < allConstBits)<br>
-    {<br>
-        x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too low. estimated minimum is %d kbps\n",<br>
-                 (int)(allConstBits * m_fps / m_numEntries * 1000.));<br>
-        return false;<br>
-    }<br>
-<br>
+    int framesCount = endIndex - startIndex + 1;<br>
     /* Blur complexities, to reduce local fluctuation of QP.<br>
      * We don't blur the QPs directly, because then one very simple frame<br>
      * could drag down the QP of a nearby complex frame and give it more<br>
      * bits than intended. */<br>
-    for (int i = 0; i < m_numEntries; i++)<br>
+    for (int i = startIndex; i <= endIndex; i++)<br>
     {<br>
         double weightSum = 0;<br>
         double cplxSum = 0;<br>
         double weight = 1.0;<br>
         double gaussianWeight;<br>
         /* weighted average of cplx of future frames */<br>
-        for (int j = 1; j < cplxBlur * 2 && j < m_numEntries - i; j++)<br>
+        for (int j = 1; j < cplxBlur * 2 && j <= endIndex - i; j++)<br>
         {<br>
             RateControlEntry *rcj = &m_rce2Pass[i + j];<br>
             weight *= 1 - pow(rcj->iCuCount / m_ncu, 2);<br>
@@ -690,11 +685,10 @@<br>
         }<br>
         m_rce2Pass[i].blurredComplexity = cplxSum / weightSum;<br>
     }<br>
-<br>
-    CHECKED_MALLOC(qScale, double, m_numEntries);<br>
+    CHECKED_MALLOC(qScale, double, framesCount);<br>
     if (filterSize > 1)<br>
     {<br>
-        CHECKED_MALLOC(blurredQscale, double, m_numEntries);<br>
+        CHECKED_MALLOC(blurredQscale, double, framesCount);<br>
     }<br>
     else<br>
         blurredQscale = qScale;<br>
@@ -705,9 +699,8 @@<br>
      * because qscale2bits is not invertible, but we can start with the simple<br>
      * approximation of scaling the 1st pass by the ratio of bitrates.<br>
      * The search range is probably overkill, but speed doesn't matter here. */<br>
-<br>
     expectedBits = 1;<br>
-    for (int i = 0; i < m_numEntries; i++)<br>
+    for (int i = startIndex; i <= endIndex; i++)<br>
     {<br>
         RateControlEntry* rce = &m_rce2Pass[i];<br>
         double q = getQScale(rce, 1.0);<br>
@@ -784,12 +777,10 @@<br>
     X265_FREE(qScale);<br>
     if (filterSize > 1)<br>
         X265_FREE(blurredQscale);<br>
-<br>
     if (m_isVbv)<br>
-        if (!vbv2Pass(allAvailableBits))<br>
+    if (!vbv2Pass(allAvailableBits, endIndex, startIndex))<br>
             return false;<br>
-    expectedBits = countExpectedBits();<br>
-<br>
+    expectedBits = countExpectedBits(startIndex, endIndex);<br>
     if (fabs(expectedBits / allAvailableBits - 1.0) > 0.01)<br>
     {<br>
         double avgq = 0;<br>
@@ -822,7 +813,127 @@<br>
     return false;<br>
 }<br>
<br>
-bool RateControl::vbv2Pass(uint64_t allAvailableBits)<br>
+bool RateControl::initPass2()<br>
+{<br>
+    uint64_t allConstBits = 0, allCodedBits = 0;<br>
+    uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * m_numEntries * m_frameDuration);<br>
+    int startIndex, framesCount, endIndex, cnt;<br>
+    int fps = (int)(m_fps + 0.5);<br>
+    startIndex = endIndex = framesCount = 0;<br>
+    allAvailableBits = uint64_t(m_param->rc.vbvMaxBitrate * 1000. * m_numEntries * m_frameDuration);<br>
+    bool isQpModified = true;<br>
+    int diffQp = 0;<br>
+    int64_t targetBits = 0;<br>
+    int64_t expectedBits = 0;<br>
+    for (startIndex = 0, endIndex = 0; endIndex < m_numEntries; endIndex++)<br>
+    {<br>
+        allConstBits += m_rce2Pass[endIndex].miscBits;<br>
+        allCodedBits += m_rce2Pass[endIndex].coeffBits + m_rce2Pass[endIndex].mvBits;<br>
+        if (m_param->rc.rateControlMode == X265_RC_CRF)<br>
+        {<br>
+            framesCount = endIndex - startIndex + 1;<br>
+            if (m_rce2Pass[endIndex].newQScale < 0)<br>
+                m_rce2Pass[endIndex].newQScale = m_rce2Pass[endIndex].qScale;<br>
+            diffQp += int (m_rce2Pass[endIndex].qpaRc - m_rce2Pass[endIndex].qpNoVbv);<br>
+            if (framesCount > fps)<br>
+                diffQp -= int (m_rce2Pass[endIndex - fps].qpaRc - m_rce2Pass[endIndex - fps].qpNoVbv);<br>
+            if (framesCount >= fps)<br>
+            {<br>
+                if (diffQp >= 1)<br>
+                {<br>
+                    if (!isQpModified && endIndex > fps)<br>
+                    {<br>
+                        double factor = 2;<br>
+                        double step = 0;<br>
+                        for (int start = endIndex; start <= endIndex + fps - 1 && start < m_numEntries; start++)<br>
+                        {<br>
+                            RateControlEntry *rce = &m_rce2Pass[start];<br>
+                            targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));<br>
+                            expectedBits += qScale2bits(rce, rce->qScale);<br>
+                        }<br>
+                        if (expectedBits < 0.95 * targetBits)<br>
+                        {<br>
+                            isQpModified = true;<br>
+                            while (endIndex + fps < m_numEntries)<br>
+                            {<br>
+                                step = pow(2, factor / 6.0);<br>
+                                expectedBits = 0;<br>
+                                for (int start = endIndex; start <= endIndex + fps - 1; start++)<br>
+                                {<br>
+                                    RateControlEntry *rce = &m_rce2Pass[start];<br>
+                                    rce->newQScale = rce->qScale / step;<br>
+                                    X265_CHECK(rce->newQScale >= 0, "new Qscale is negative\n");<br>
+                                    expectedBits += qScale2bits(rce, rce->newQScale);<br>
+                                    rce->newQp = x265_qScale2qp(rce->newQScale);<br>
+                                }<br>
+                                if (expectedBits >= targetBits && step > 1)<br>
+                                    factor *= 0.90;<br>
+                                else<br>
+                                    break;<br>
+                            }<br>
+<br>
+                            if (m_isVbv && endIndex + fps < m_numEntries)<br>
+                                if (!vbv2Pass(targetBits, endIndex + fps - 1, endIndex))<br>
+                                    return false;<br>
+<br>
+                            double prevFactor = factor;<br>
+                            targetBits = 0;<br>
+                            expectedBits = 0;<br>
+<br>
+                            for (int start = endIndex - fps; start <= endIndex - 1; start++)<br>
+                            {<br>
+                                RateControlEntry *rce = &m_rce2Pass[start];<br>
+                                targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));<br>
+                            }<br>
+                            while (1)<br>
+                            {<br>
+                                step = pow(2, factor / 6.0);<br>
+                                expectedBits = 0;<br>
+                                for (int start = endIndex - fps; start <= endIndex - 1; start++)<br>
+                                {<br>
+                                    RateControlEntry *rce = &m_rce2Pass[start];<br>
+                                    rce->newQScale = rce->qScale * step;<br>
+                                    X265_CHECK(rce->newQScale >= 0, "new Qscale is negative\n");<br>
+                                    expectedBits += qScale2bits(rce, rce->newQScale);<br>
+                                    rce->newQp = x265_qScale2qp(rce->newQScale);<br>
+                                }<br>
+                                if (expectedBits > targetBits && step > 1)<br>
+                                    factor *= 1.1;<br>
+                                else<br>
+                                     break;<br>
+                            }<br>
+                            if (m_isVbv)<br>
+                            if (!vbv2Pass(targetBits, endIndex - 1, endIndex - fps))<br>
+                                    return false;<br>
+                            diffQp = 0;<br>
+                            startIndex = endIndex + 1;<br>
+                            targetBits = expectedBits = 0;<br>
+                        }<br>
+                        else<br>
+                            targetBits = expectedBits = 0;<br>
+                    }<br>
+                }<br>
+                else<br>
+                    isQpModified = false;<br>
+            }<br>
+        }<br>
+    }<br>
+<br>
+    if (m_param->rc.rateControlMode == X265_RC_ABR)<br>
+    {<br>
+        if (allAvailableBits < allConstBits)<br>
+        {<br>
+            x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too low. estimated minimum is %d kbps\n",<br>
+                     (int)(allConstBits * m_fps / framesCount * 1000.));<br>
+            return false;<br>
+        }<br>
+        if (!analyseABR2Pass(0, m_numEntries - 1, allAvailableBits))<br>
+            return false;<br>
+    }<br>
+    return true;<br>
+}<br>
+<br>
+bool RateControl::vbv2Pass(uint64_t allAvailableBits, int endPos, int startPos)<br>
 {<br>
     /* for each interval of bufferFull .. underflow, uniformly increase the qp of all<br>
      * frames in the interval until either buffer is full at some intermediate frame or the<br>
@@ -848,10 +959,10 @@<br>
         {   /* not first iteration */<br>
             adjustment = X265_MAX(X265_MIN(expectedBits / allAvailableBits, 0.999), 0.9);<br>
             fills[-1] = m_bufferSize * m_param->rc.vbvBufferInit;<br>
-            t0 = 0;<br>
+            t0 = startPos;<br>
             /* fix overflows */<br>
             adjMin = 1;<br>
-            while (adjMin && findUnderflow(fills, &t0, &t1, 1))<br>
+            while (adjMin && findUnderflow(fills, &t0, &t1, 1, endPos))<br>
             {<br>
                 adjMin = fixUnderflow(t0, t1, adjustment, MIN_QPSCALE, MAX_MAX_QPSCALE);<br>
                 t0 = t1;<br>
@@ -862,20 +973,16 @@<br>
         t0 = 0;<br>
         /* fix underflows -- should be done after overflow, as we'd better undersize target than underflowing VBV */<br>
         adjMax = 1;<br>
-        while (adjMax && findUnderflow(fills, &t0, &t1, 0))<br>
+        while (adjMax && findUnderflow(fills, &t0, &t1, 0, endPos))<br>
             adjMax = fixUnderflow(t0, t1, 1.001, MIN_QPSCALE, MAX_MAX_QPSCALE );<br>
-<br>
-        expectedBits = countExpectedBits();<br>
+        expectedBits = countExpectedBits(startPos, endPos);<br>
     }<br>
-    while ((expectedBits < .995 * allAvailableBits) && ((int64_t)(expectedBits+.5) > (int64_t)(prevBits+.5)));<br>
-<br>
+    while ((expectedBits < .995 * allAvailableBits) && ((int64_t)(expectedBits+.5) > (int64_t)(prevBits+.5)) && !(m_param->rc.rateControlMode == X265_RC_CRF));<br>
     if (!adjMax)<br>
         x265_log(m_param, X265_LOG_WARNING, "vbv-maxrate issue, qpmax or vbv-maxrate too low\n");<br>
-<br>
     /* store expected vbv filling values for tracking when encoding */<br>
-    for (int i = 0; i < m_numEntries; i++)<br>
+    for (int i = startPos; i <= endPos; i++)<br>
         m_rce2Pass[i].expectedVbv = m_bufferSize - fills[i];<br>
-<br>
     X265_FREE(fills - 1);<br>
     return true;<br>
<br>
@@ -915,9 +1022,10 @@<br>
                 m_param->bframes = 1;<br>
             return X265_TYPE_AUTO;<br>
         }<br>
-        int frameType = m_rce2Pass[frameNum].sliceType == I_SLICE ? (frameNum > 0 && m_param->bOpenGOP ? X265_TYPE_I : X265_TYPE_IDR)<br>
-                            : m_rce2Pass[frameNum].sliceType == P_SLICE ? X265_TYPE_P<br>
-                            : (m_rce2Pass[frameNum].sliceType == B_SLICE && m_rce2Pass[frameNum].keptAsRef? X265_TYPE_BREF : X265_TYPE_B);<br>
+        int index = m_encOrder[frameNum];<br>
+        int frameType = m_rce2Pass[index].sliceType == I_SLICE ? (frameNum > 0 && m_param->bOpenGOP ? X265_TYPE_I : X265_TYPE_IDR)<br>
+                        : m_rce2Pass[index].sliceType == P_SLICE ? X265_TYPE_P<br>
+                        : (m_rce2Pass[index].sliceType == B_SLICE && m_rce2Pass[index].keptAsRef ? X265_TYPE_BREF : X265_TYPE_B);<br>
         return frameType;<br>
     }<br>
     else<br>
@@ -968,7 +1076,8 @@<br>
     if (m_param->rc.bStatRead)<br>
     {<br>
         X265_CHECK(rce->poc >= 0 && rce->poc < m_numEntries, "bad encode ordinal\n");<br>
-        copyRceData(rce, &m_rce2Pass[rce->poc]);<br>
+        int index = m_encOrder[rce->poc];<br>
+        copyRceData(rce, &m_rce2Pass[index]);<br>
     }<br>
     rce->isActive = true;<br>
     bool isRefFrameScenecut = m_sliceType!= I_SLICE && m_curSlice->m_refPicList[0][0]->m_lowres.bScenecut == 1;<br>
@@ -1032,6 +1141,16 @@<br>
             }<br>
         }<br>
     }<br>
+    if (!m_isAbr && m_2pass && m_param->rc.rateControlMode == X265_RC_CRF)<br>
+    {<br>
+        rce->qScale = rce->newQScale;<br>
+        rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = x265_qScale2qp(rce->newQScale);<br>
+        m_qp = int(rce->qpaRc + 0.5);<br>
+        rce->frameSizePlanned = qScale2bits(rce, rce->qScale);<br>
+        m_framesDone++;<br>
+        return m_qp;<br>
+    }<br>
+<br>
     if (m_isAbr || m_2pass) // ABR,CRF<br>
     {<br>
         if (m_isAbr || m_isVbv)<br>
@@ -1203,11 +1322,10 @@<br>
     }<br>
     return q;<br>
 }<br>
-<br>
-double RateControl::countExpectedBits()<br>
+double RateControl::countExpectedBits(int startPos, int endPos)<br>
 {<br>
     double expectedBits = 0;<br>
-    for( int i = 0; i < m_numEntries; i++ )<br>
+    for (int i = startPos; i <= endPos; i++)<br>
     {<br>
         RateControlEntry *rce = &m_rce2Pass[i];<br>
         rce->expectedBits = (uint64_t)expectedBits;<br>
@@ -1215,8 +1333,7 @@<br>
     }<br>
     return expectedBits;<br>
 }<br>
-<br>
-bool RateControl::findUnderflow(double *fills, int *t0, int *t1, int over)<br>
+bool RateControl::findUnderflow(double *fills, int *t0, int *t1, int over, int endPos)<br>
 {<br>
     /* find an interval ending on an overflow or underflow (depending on whether<br>
      * we're adding or removing bits), and starting on the earliest frame that<br>
@@ -1226,7 +1343,7 @@<br>
     double fill = fills[*t0 - 1];<br>
     double parity = over ? 1. : -1.;<br>
     int start = -1, end = -1;<br>
-    for (int i = *t0; i < m_numEntries; i++)<br>
+    for (int i = *t0; i <= endPos; i++)<br>
     {<br>
         fill += (m_frameDuration * m_vbvMaxRate -<br>
                  qScale2bits(&m_rce2Pass[i], m_rce2Pass[i].newQScale)) * parity;<br>
@@ -1263,12 +1380,11 @@<br>
     }<br>
     return adjusted;<br>
 }<br>
-<br>
 bool RateControl::cuTreeReadFor2Pass(Frame* frame)<br>
 {<br>
-    uint8_t sliceTypeActual = (uint8_t)m_rce2Pass[frame->m_poc].sliceType;<br>
-<br>
-    if (m_rce2Pass[frame->m_poc].keptAsRef)<br>
+    int index = m_encOrder[frame->m_poc];<br>
+    uint8_t sliceTypeActual = (uint8_t)m_rce2Pass[index].sliceType;<br>
+    if (m_rce2Pass[index].keptAsRef)<br>
     {<br>
         /* TODO: We don't need pre-lookahead to measure AQ offsets, but there is currently<br>
          * no way to signal this */<br>
@@ -1948,6 +2064,8 @@<br>
<br>
 int RateControl::rowDiagonalVbvRateControl(Frame* curFrame, uint32_t row, RateControlEntry* rce, double& qpVbv)<br>
 {<br>
+    if (m_param->rc.bStatRead && m_param->rc.rateControlMode == X265_RC_CRF)<br>
+        return 0;<br>
     FrameData& curEncData = *curFrame->m_encData;<br>
     double qScaleVbv = x265_qp2qScale(qpVbv);<br>
     uint64_t rowSatdCost = curEncData.m_rowStat[row].diagSatd;<br>
@@ -2195,7 +2313,7 @@<br>
<br>
     if (m_param->rc.aqMode || m_isVbv)<br>
     {<br>
-        if (m_isVbv)<br>
+        if (m_isVbv && !(m_2pass && m_param->rc.rateControlMode == X265_RC_CRF))<br>
         {<br>
             /* determine avg QP decided by VBV rate control */<br>
             for (uint32_t i = 0; i < slice->m_sps->numCuInHeight; i++)<br>
diff -r 6b308775b6f0 -r ffb0111298cd source/encoder/ratecontrol.h<br>
--- a/source/encoder/ratecontrol.h      Mon Nov 23 12:26:45 2015 +0530<br>
+++ b/source/encoder/ratecontrol.h      Mon Nov 23 14:06:10 2015 +0530<br>
@@ -205,8 +205,8 @@<br>
     double  m_lastAccumPNorm;<br>
     double  m_expectedBitsSum;   /* sum of qscale2bits after rceq, ratefactor, and overflow, only includes finished frames */<br>
     int64_t m_predictedBits;<br>
+    int     *m_encOrder;<br>
     RateControlEntry* m_rce2Pass;<br>
-<br>
     struct<br>
     {<br>
         uint16_t *qpBuffer[2]; /* Global buffers for converting MB-tree quantizer data. */<br>
@@ -258,11 +258,12 @@<br>
     void   checkAndResetABR(RateControlEntry* rce, bool isFrameDone);<br>
     double predictRowsSizeSum(Frame* pic, RateControlEntry* rce, double qpm, int32_t& encodedBits);<br>
     bool   initPass2();<br>
+    bool   analyseABR2Pass(int startPoc, int endPoc, uint64_t allAvailableBits);<br>
     void   initFramePredictors();<br>
     double getDiffLimitedQScale(RateControlEntry *rce, double q);<br>
-    double countExpectedBits();<br>
-    bool   vbv2Pass(uint64_t allAvailableBits);<br>
-    bool   findUnderflow(double *fills, int *t0, int *t1, int over);<br>
+    double countExpectedBits(int startPos, int framesCount);<br>
+    bool   vbv2Pass(uint64_t allAvailableBits, int frameCount, int startPos);<br>
+    bool   findUnderflow(double *fills, int *t0, int *t1, int over, int framesCount);<br>
     bool   fixUnderflow(int t0, int t1, double adjustment, double qscaleMin, double qscaleMax);<br>
 };<br>
 }<br>
</blockquote></div><br></div>