<div dir="ltr"><div style="font-size:14px"># HG changeset patch</div><div style="font-size:14px"># User ZhengWang <<a href="mailto:zheng@multicorewareinc.com" target="_blank">zheng@multicorewareinc.com</a>></div><div style="font-size:14px"># Date 1476863434 -28800</div><div style="font-size:14px">#      Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px"># Node ID b1662beb64862095079cc1600ee2ec<wbr>c8c05d8227</div><div style="font-size:14px"># Parent  0e9e5264054606a38a3fe6c87272a<wbr>1737b340b1a</div><div style="font-size:14px">Store commonly-used RPS in SPS  in 2 pass mode.</div><div style="font-size:14px">Add new param --[no]-multi-pass-opt-rps to control it, default disabled.</div><div style="font-size:14px"><br></div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 doc/reST/cli.rst</div><div style="font-size:14px">--- a/doc/reST/cli.rst<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/doc/reST/cli.rst<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -1389,6 +1389,10 @@</div><div style="font-size:14px"> <span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">      </span>Specify file name of of the multi-pass stats file. If unspecified</div><div style="font-size:14px"> <span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap"> </span>the encoder will use x265_2pass.log</div><div style="font-size:14px"> </div><div style="font-size:14px">+.. option:: --[no]-multi-pass-opt-rps</div><div style="font-size:14px">+</div><div style="font-size:14px">+<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Enable storing commonly RPS in SPS in multi pass mode. Default disabled.</div><div style="font-size:14px">+</div><div style="font-size:14px"> .. option:: --slow-firstpass, --no-slow-firstpass</div><div style="font-size:14px"> </div><div style="font-size:14px"> <span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">    </span>Enable first pass encode with the exact settings specified. </div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/CMakeLists.txt</div><div style="font-size:14px">--- a/source/CMakeLists.txt<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/CMakeLists.txt<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">   </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -30,7 +30,7 @@</div><div style="font-size:14px"> mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)</div><div style="font-size:14px"> </div><div style="font-size:14px"> # X265_BUILD must be incremented each time the public API is changed</div><div style="font-size:14px">-set(X265_BUILD 98)</div><div style="font-size:14px">+set(X265_BUILD 99)</div><div style="font-size:14px"> configure_file("${PROJECT_SOU<wbr>RCE_DIR}/<a href="http://x265.def.in/" target="_blank">x265.def.in</a>"</div><div style="font-size:14px">                "${PROJECT_BINARY_DIR}/<a href="http://x265.de">x265.de</a><wbr>f")</div><div style="font-size:14px"> configure_file("${PROJECT_SOU<wbr>RCE_DIR}/<a href="http://x265_config.h.in/" target="_blank">x265_config.h.in</a>"</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/common/common.h</div><div style="font-size:14px">--- a/source/common/common.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/common/common.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -312,6 +312,7 @@</div><div style="font-size:14px"> </div><div style="font-size:14px"> #define MAX_NUM_REF_PICS            16 // max. number of pictures used for reference</div><div style="font-size:14px"> #define MAX_NUM_REF                 16 // max. number of entries in picture reference list</div><div style="font-size:14px">+#define MAX_NUM_SHORT_TERM_RPS      64 // max. number of short term reference picture set in SPS</div><div style="font-size:14px"> </div><div style="font-size:14px"> #define REF_NOT_VALID               -1</div><div style="font-size:14px"> </div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/common/framedata.cpp</div><div style="font-size:14px">--- a/source/common/framedata.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap"> </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/common/framedata.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">     </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -37,6 +37,9 @@</div><div style="font-size:14px">     m_slice  = new Slice;</div><div style="font-size:14px">     m_picCTU = new CUData[sps.numCUsInFrame];</div><div style="font-size:14px">     m_picCsp = csp;</div><div style="font-size:14px">+    m_spsrpsIdx = -1;</div><div style="font-size:14px">+    if (param.rc.bStatWrite)</div><div style="font-size:14px">+        m_spsrps = const_cast<RPS*>(sps.spsrps);</div><div style="font-size:14px"> </div><div style="font-size:14px">     m_cuMemPool.create(0, param.internalCsp, sps.numCUsInFrame);</div><div style="font-size:14px">     for (uint32_t ctuAddr = 0; ctuAddr < sps.numCUsInFrame; ctuAddr++)</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/common/framedata.h</div><div style="font-size:14px">--- a/source/common/framedata.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">     </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/common/framedata.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -106,6 +106,9 @@</div><div style="font-size:14px">     CUDataMemPool  m_cuMemPool;</div><div style="font-size:14px">     CUData*        m_picCTU;</div><div style="font-size:14px"> </div><div style="font-size:14px">+    RPS*           m_spsrps;</div><div style="font-size:14px">+    int            m_spsrpsIdx;</div><div style="font-size:14px">+</div><div style="font-size:14px">     /* Rate control data used during encode and by references */</div><div style="font-size:14px">     struct RCStatCU</div><div style="font-size:14px">     {</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/common/param.cpp</div><div style="font-size:14px">--- a/source/common/param.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/common/param.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap"> </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -198,6 +198,7 @@</div><div style="font-size:14px">     param->bCULossless = 0;</div><div style="font-size:14px">     param->bEnableTemporalSubLaye<wbr>rs = 0;</div><div style="font-size:14px">     param->bEnableRdRefine = 0;</div><div style="font-size:14px">+    param->bMultiPassOptRPS = 0;</div><div style="font-size:14px"> </div><div style="font-size:14px">     /* Rate control options */</div><div style="font-size:14px">     param->rc.vbvMaxBitrate = 0;</div><div style="font-size:14px">@@ -915,6 +916,8 @@</div><div style="font-size:14px">         OPT("limit-tu") p->limitTU = atoi(value);</div><div style="font-size:14px">         OPT("opt-qp-pps") p->bOptQpPPS = atobool(value);</div><div style="font-size:14px">         OPT("opt-ref-list-length-pps"<wbr>) p->bOptRefListLengthPPS = atobool(value);</div><div style="font-size:14px">+        OPT("multi-pass-opt-rps") p->bMultiPassOptRPS = atobool(value);</div><div style="font-size:14px">+</div><div style="font-size:14px">         else</div><div style="font-size:14px">             return X265_PARAM_BAD_NAME;</div><div style="font-size:14px">     }</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/common/slice.h</div><div style="font-size:14px">--- a/source/common/slice.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/common/slice.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">   </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -239,6 +239,10 @@</div><div style="font-size:14px">     uint32_t maxLatencyIncrease;</div><div style="font-size:14px">     int      numReorderPics;</div><div style="font-size:14px"> </div><div style="font-size:14px">+    RPS      spsrps[MAX_NUM_SHORT_TERM_RPS<wbr>];</div><div style="font-size:14px">+    int      spsrpsNum;</div><div style="font-size:14px">+    int      numGOPBegin;</div><div style="font-size:14px">+</div><div style="font-size:14px">     bool     bUseSAO; // use param</div><div style="font-size:14px">     bool     bUseAMP; // use param</div><div style="font-size:14px">     bool     bUseStrongIntraSmoothing; // use param</div><div style="font-size:14px">@@ -337,6 +341,7 @@</div><div style="font-size:14px">     int         m_sliceQp;</div><div style="font-size:14px">     int         m_poc;</div><div style="font-size:14px">     int         m_lastIDR;</div><div style="font-size:14px">+    int         m_rpsIdx;</div><div style="font-size:14px"> </div><div style="font-size:14px">     uint32_t    m_colRefIdx;       // never modified</div><div style="font-size:14px"> </div><div style="font-size:14px">@@ -352,6 +357,7 @@</div><div style="font-size:14px"> </div><div style="font-size:14px">     int         m_iPPSQpMinus26;</div><div style="font-size:14px">     int         numRefIdxDefault[2];</div><div style="font-size:14px">+    int         m_iNumRPSInSPS;</div><div style="font-size:14px"> </div><div style="font-size:14px">     Slice()</div><div style="font-size:14px">     {</div><div style="font-size:14px">@@ -365,6 +371,7 @@</div><div style="font-size:14px">         m_iPPSQpMinus26 = 0;</div><div style="font-size:14px">         numRefIdxDefault[0] = 1;</div><div style="font-size:14px">         numRefIdxDefault[1] = 1;</div><div style="font-size:14px">+        m_rpsIdx = -1;</div><div style="font-size:14px">     }</div><div style="font-size:14px"> </div><div style="font-size:14px">     void disableWeights();</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/encoder/api.cpp</div><div style="font-size:14px">--- a/source/encoder/api.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">   </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/encoder/api.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">  </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -141,6 +141,11 @@</div><div style="font-size:14px">         Encoder *encoder = static_cast<Encoder*>(enc);</div><div style="font-size:14px">         Entropy sbacCoder;</div><div style="font-size:14px">         Bitstream bs;</div><div style="font-size:14px">+        if (encoder->m_param->rc.bStatRea<wbr>d && encoder->m_param->bMultiPassOp<wbr>tRPS)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            if (!encoder->computeSPSRPSIndex(<wbr>))</div><div style="font-size:14px">+                return -1;</div><div style="font-size:14px">+        }</div><div style="font-size:14px">         encoder->getStreamHeaders(enc<wbr>oder->m_nalList, sbacCoder, bs);</div><div style="font-size:14px">         *pp_nal = &encoder->m_nalList.m_nal[0];</div><div style="font-size:14px">         if (pi_nal) *pi_nal = encoder->m_nalList.m_numNal;</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/encoder/encoder.cpp</div><div style="font-size:14px">--- a/source/encoder/encoder.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/encoder/encoder.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">      </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -77,6 +77,7 @@</div><div style="font-size:14px">     m_iFrameNum = 0;</div><div style="font-size:14px">     m_iPPSQpMinus26 = 0;</div><div style="font-size:14px">     m_iLastSliceQp = 0;</div><div style="font-size:14px">+    m_rpsInSpsCount = 0;</div><div style="font-size:14px">     for (int i = 0; i < X265_MAX_FRAME_THREADS; i++)</div><div style="font-size:14px">         m_frameEncoder[i] = NULL;</div><div style="font-size:14px"> </div><div style="font-size:14px">@@ -905,6 +906,7 @@</div><div style="font-size:14px">             frameEnc->m_encData->m_slice-<wbr>>m_iPPSQpMinus26 = m_iPPSQpMinus26;</div><div style="font-size:14px">             frameEnc->m_encData->m_slice-<wbr>>numRefIdxDefault[0] = m_pps.numRefIdxDefault[0];</div><div style="font-size:14px">             frameEnc->m_encData->m_slice-<wbr>>numRefIdxDefault[1] = m_pps.numRefIdxDefault[1];</div><div style="font-size:14px">+            frameEnc->m_encData->m_slice-<wbr>>m_iNumRPSInSPS = m_sps.spsrpsNum;</div><div style="font-size:14px"> </div><div style="font-size:14px">             curEncoder->m_rce.encodeOrder = frameEnc->m_encodeOrder = m_encodedFrameNum++;</div><div style="font-size:14px">             if (m_bframeDelay)</div><div style="font-size:14px">@@ -1068,6 +1070,13 @@</div><div style="font-size:14px"> </div><div style="font-size:14px">         x265_log(m_param, X265_LOG_INFO, "lossless compression ratio %.2f::1\n", uncompressed / m_analyzeAll.m_accBits);</div><div style="font-size:14px">     }</div><div style="font-size:14px">+    if (m_param->bMultiPassOptRPS && m_param->rc.bStatRead)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        x265_log(m_param, X265_LOG_INFO, "RPS in SPS: %d frames (%.2f%%), RPS not in SPS: %d frames (%.2f%%)\n", </div><div style="font-size:14px">+            m_rpsInSpsCount, (float)100.0 * m_rpsInSpsCount / m_rateControl->m_numEntries, </div><div style="font-size:14px">+            m_rateControl->m_numEntries - m_rpsInSpsCount, </div><div style="font-size:14px">+            (float)100.0 * (m_rateControl->m_numEntries - m_rpsInSpsCount) / m_rateControl->m_numEntries);</div><div style="font-size:14px">+    }</div><div style="font-size:14px"> </div><div style="font-size:14px">     if (m_analyzeAll.m_numPics)</div><div style="font-size:14px">     {</div><div style="font-size:14px">@@ -2433,3 +2442,203 @@</div><div style="font-size:14px">     TOOLCMP(oldParam->maxNumMerge<wbr>Cand, newParam->maxNumMergeCand, "max-merge=%d to %d\n");</div><div style="font-size:14px">     TOOLCMP(oldParam->bIntraInBFr<wbr>ames, newParam->bIntraInBFrames, "b-intra=%d to %d\n");</div><div style="font-size:14px"> }</div><div style="font-size:14px">+</div><div style="font-size:14px">+bool Encoder::computeSPSRPSIndex()</div><div style="font-size:14px">+{</div><div style="font-size:14px">+    RPS* rpsInSPS = m_sps.spsrps;</div><div style="font-size:14px">+    int* rpsNumInPSP = &m_sps.spsrpsNum;</div><div style="font-size:14px">+    int  beginNum = m_sps.numGOPBegin;</div><div style="font-size:14px">+    int  endNum;</div><div style="font-size:14px">+    RPS* rpsInRec;</div><div style="font-size:14px">+    RPS* rpsInIdxList;</div><div style="font-size:14px">+    RPS* thisRpsInSPS;</div><div style="font-size:14px">+    RPS* thisRpsInList;</div><div style="font-size:14px">+    RPSListNode* headRpsIdxList = NULL;</div><div style="font-size:14px">+    RPSListNode* tailRpsIdxList = NULL;</div><div style="font-size:14px">+    RPSListNode* rpsIdxListIter = NULL;</div><div style="font-size:14px">+    RateControlEntry *rce2Pass = m_rateControl->m_rce2Pass;</div><div style="font-size:14px">+    int numEntries = m_rateControl->m_numEntries;</div><div style="font-size:14px">+    RateControlEntry *rce;</div><div style="font-size:14px">+    int idx = 0;</div><div style="font-size:14px">+    int pos = 0;</div><div style="font-size:14px">+    int resultIdx[64];</div><div style="font-size:14px">+    memset(rpsInSPS, 0, sizeof(RPS) * MAX_NUM_SHORT_TERM_RPS);</div><div style="font-size:14px">+</div><div style="font-size:14px">+    // find out all RPS date in current GOP</div><div style="font-size:14px">+    beginNum++;</div><div style="font-size:14px">+    endNum = beginNum;</div><div style="font-size:14px">+    if (!m_param->bRepeatHeaders)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        endNum = numEntries;</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+    else</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        while (endNum < numEntries)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            rce = &rce2Pass[endNum];</div><div style="font-size:14px">+            if (rce->sliceType == I_SLICE)</div><div style="font-size:14px">+            {</div><div style="font-size:14px">+                break;</div><div style="font-size:14px">+            }</div><div style="font-size:14px">+            endNum++;</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+    m_sps.numGOPBegin = endNum;</div><div style="font-size:14px">+</div><div style="font-size:14px">+    // find out all kinds of RPS</div><div style="font-size:14px">+    for (int i = beginNum; i < endNum; i++)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        rce = &rce2Pass[i];</div><div style="font-size:14px">+        rpsInRec = &rce->rpsData;</div><div style="font-size:14px">+        rpsIdxListIter = headRpsIdxList;</div><div style="font-size:14px">+        // i frame don't recode RPS info</div><div style="font-size:14px">+        if (rce->sliceType != I_SLICE)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            while (rpsIdxListIter)</div><div style="font-size:14px">+            {</div><div style="font-size:14px">+                rpsInIdxList = rpsIdxListIter->rps;</div><div style="font-size:14px">+                if (rpsInRec->numberOfPictures == rpsInIdxList->numberOfPictures</div><div style="font-size:14px">+                    && rpsInRec->numberOfNegativePict<wbr>ures == rpsInIdxList->numberOfNegative<wbr>Pictures</div><div style="font-size:14px">+                    && rpsInRec->numberOfPositivePict<wbr>ures == rpsInIdxList->numberOfPositive<wbr>Pictures)</div><div style="font-size:14px">+                {</div><div style="font-size:14px">+                    for (pos = 0; pos < rpsInRec->numberOfPictures; pos++)</div><div style="font-size:14px">+                    {</div><div style="font-size:14px">+                        if (rpsInRec->deltaPOC[pos] != rpsInIdxList->deltaPOC[pos]</div><div style="font-size:14px">+                            || rpsInRec->bUsed[pos] != rpsInIdxList->bUsed[pos])</div><div style="font-size:14px">+                            break;</div><div style="font-size:14px">+                    }</div><div style="font-size:14px">+                    if (pos == rpsInRec->numberOfPictures)    // if this type of RPS has exist</div><div style="font-size:14px">+                    {</div><div style="font-size:14px">+                        rce->rpsIdx = rpsIdxListIter->idx;</div><div style="font-size:14px">+                        rpsIdxListIter->count++;</div><div style="font-size:14px">+                        // sort RPS type link after reset RPS type count.</div><div style="font-size:14px">+                        RPSListNode* next = rpsIdxListIter->next;</div><div style="font-size:14px">+                        RPSListNode* prior = rpsIdxListIter->prior;</div><div style="font-size:14px">+                        RPSListNode* iter = prior;</div><div style="font-size:14px">+                        if (iter)</div><div style="font-size:14px">+                        {</div><div style="font-size:14px">+                            while (iter)</div><div style="font-size:14px">+                            {</div><div style="font-size:14px">+                                if (iter->count > rpsIdxListIter->count)</div><div style="font-size:14px">+                                    break;</div><div style="font-size:14px">+                                iter = iter->prior;</div><div style="font-size:14px">+                            }</div><div style="font-size:14px">+                            if (iter)</div><div style="font-size:14px">+                            {</div><div style="font-size:14px">+                                prior->next = next;</div><div style="font-size:14px">+                                if (next)</div><div style="font-size:14px">+                                    next->prior = prior;</div><div style="font-size:14px">+                                else</div><div style="font-size:14px">+                                    tailRpsIdxList = prior;</div><div style="font-size:14px">+                                rpsIdxListIter->next = iter->next;</div><div style="font-size:14px">+                                rpsIdxListIter->prior = iter;</div><div style="font-size:14px">+                                iter->next->prior = rpsIdxListIter;</div><div style="font-size:14px">+                                iter->next = rpsIdxListIter;</div><div style="font-size:14px">+                            }</div><div style="font-size:14px">+                            else</div><div style="font-size:14px">+                            {</div><div style="font-size:14px">+                                prior->next = next;</div><div style="font-size:14px">+                                if (next)</div><div style="font-size:14px">+                                    next->prior = prior;</div><div style="font-size:14px">+                                else</div><div style="font-size:14px">+                                    tailRpsIdxList = prior;</div><div style="font-size:14px">+                                headRpsIdxList->prior = rpsIdxListIter;</div><div style="font-size:14px">+                                rpsIdxListIter->next = headRpsIdxList;</div><div style="font-size:14px">+                                rpsIdxListIter->prior = NULL;</div><div style="font-size:14px">+                                headRpsIdxList = rpsIdxListIter;</div><div style="font-size:14px">+                            }</div><div style="font-size:14px">+                        }</div><div style="font-size:14px">+                        break;</div><div style="font-size:14px">+                    }</div><div style="font-size:14px">+                }</div><div style="font-size:14px">+                rpsIdxListIter = rpsIdxListIter->next;</div><div style="font-size:14px">+            }</div><div style="font-size:14px">+            if (!rpsIdxListIter)  // add new type of RPS</div><div style="font-size:14px">+            {</div><div style="font-size:14px">+                RPSListNode* newIdxNode = new RPSListNode();</div><div style="font-size:14px">+                if (newIdxNode == NULL)</div><div style="font-size:14px">+                    goto fail;</div><div style="font-size:14px">+                newIdxNode->rps = rpsInRec;</div><div style="font-size:14px">+                newIdxNode->idx = idx++;</div><div style="font-size:14px">+                newIdxNode->count = 1;</div><div style="font-size:14px">+                newIdxNode->next = NULL;</div><div style="font-size:14px">+                newIdxNode->prior = NULL;</div><div style="font-size:14px">+                if (!tailRpsIdxList)</div><div style="font-size:14px">+                    tailRpsIdxList = headRpsIdxList = newIdxNode;</div><div style="font-size:14px">+                else</div><div style="font-size:14px">+                {</div><div style="font-size:14px">+                    tailRpsIdxList->next = newIdxNode;</div><div style="font-size:14px">+                    newIdxNode->prior = tailRpsIdxList;</div><div style="font-size:14px">+                    tailRpsIdxList = newIdxNode;</div><div style="font-size:14px">+                }</div><div style="font-size:14px">+                rce->rpsIdx = newIdxNode->idx;</div><div style="font-size:14px">+            }</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+        else</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            rce->rpsIdx = -1;</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+</div><div style="font-size:14px">+    // get commonly RPS set</div><div style="font-size:14px">+    memset(resultIdx, 0, sizeof(resultIdx));</div><div style="font-size:14px">+    if (idx > MAX_NUM_SHORT_TERM_RPS)</div><div style="font-size:14px">+        idx = MAX_NUM_SHORT_TERM_RPS;</div><div style="font-size:14px">+</div><div style="font-size:14px">+    *rpsNumInPSP = idx;</div><div style="font-size:14px">+    rpsIdxListIter = headRpsIdxList;</div><div style="font-size:14px">+    for (int i = 0; i < idx; i++)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        resultIdx[i] = rpsIdxListIter->idx;</div><div style="font-size:14px">+        m_rpsInSpsCount += rpsIdxListIter->count;</div><div style="font-size:14px">+        thisRpsInSPS = rpsInSPS + i;</div><div style="font-size:14px">+        thisRpsInList = rpsIdxListIter->rps;</div><div style="font-size:14px">+        thisRpsInSPS->numberOfPicture<wbr>s = thisRpsInList->numberOfPicture<wbr>s;</div><div style="font-size:14px">+        thisRpsInSPS->numberOfNegativ<wbr>ePictures = thisRpsInList->numberOfNegativ<wbr>ePictures;</div><div style="font-size:14px">+        thisRpsInSPS->numberOfPositiv<wbr>ePictures = thisRpsInList->numberOfPositiv<wbr>ePictures;</div><div style="font-size:14px">+        for (pos = 0; pos < thisRpsInList->numberOfPicture<wbr>s; pos++)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            thisRpsInSPS->deltaPOC[pos] = thisRpsInList->deltaPOC[pos];</div><div style="font-size:14px">+            thisRpsInSPS->bUsed[pos] = thisRpsInList->bUsed[pos];</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+        rpsIdxListIter = rpsIdxListIter->next;</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+</div><div style="font-size:14px">+    //reset every frame's RPS index</div><div style="font-size:14px">+    for (int i = beginNum; i < endNum; i++)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        int j;</div><div style="font-size:14px">+        rce = &rce2Pass[i];</div><div style="font-size:14px">+        for (j = 0; j < idx; j++)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            if (rce->rpsIdx == resultIdx[j])</div><div style="font-size:14px">+            {</div><div style="font-size:14px">+                rce->rpsIdx = j;</div><div style="font-size:14px">+                break;</div><div style="font-size:14px">+            }</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+</div><div style="font-size:14px">+        if (j == idx)</div><div style="font-size:14px">+            rce->rpsIdx = -1;</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+</div><div style="font-size:14px">+    rpsIdxListIter = headRpsIdxList;</div><div style="font-size:14px">+    while (rpsIdxListIter)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        RPSListNode* freeIndex = rpsIdxListIter;</div><div style="font-size:14px">+        rpsIdxListIter = rpsIdxListIter->next;</div><div style="font-size:14px">+        delete freeIndex;</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+    return true;</div><div style="font-size:14px">+</div><div style="font-size:14px">+fail:</div><div style="font-size:14px">+    rpsIdxListIter = headRpsIdxList;</div><div style="font-size:14px">+    while (rpsIdxListIter)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        RPSListNode* freeIndex = rpsIdxListIter;</div><div style="font-size:14px">+        rpsIdxListIter = rpsIdxListIter->next;</div><div style="font-size:14px">+        delete freeIndex;</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+    return false;</div><div style="font-size:14px">+}</div><div style="font-size:14px">+</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/encoder/encoder.h</div><div style="font-size:14px">--- a/source/encoder/encoder.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/encoder/encoder.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -79,6 +79,15 @@</div><div style="font-size:14px">     int numRefIdxl1[MAX_NUM_REF_IDX];</div><div style="font-size:14px"> };</div><div style="font-size:14px"> </div><div style="font-size:14px">+struct RPSListNode</div><div style="font-size:14px">+{</div><div style="font-size:14px">+    int idx;</div><div style="font-size:14px">+    int count;</div><div style="font-size:14px">+    RPS* rps;</div><div style="font-size:14px">+    RPSListNode* next;</div><div style="font-size:14px">+    RPSListNode* prior;</div><div style="font-size:14px">+};</div><div style="font-size:14px">+</div><div style="font-size:14px"> class FrameEncoder;</div><div style="font-size:14px"> class DPB;</div><div style="font-size:14px"> class Lookahead;</div><div style="font-size:14px">@@ -156,6 +165,9 @@</div><div style="font-size:14px">     Lock               m_sliceRefIdxLock;</div><div style="font-size:14px">     RefIdxLastGOP      m_refIdxLastGOP;</div><div style="font-size:14px"> </div><div style="font-size:14px">+    Lock               m_rpsInSpsLock;</div><div style="font-size:14px">+    int                m_rpsInSpsCount;</div><div style="font-size:14px">+</div><div style="font-size:14px">     Encoder();</div><div style="font-size:14px">     ~Encoder() {}</div><div style="font-size:14px"> </div><div style="font-size:14px">@@ -196,6 +208,7 @@</div><div style="font-size:14px">     void initRefIdx();</div><div style="font-size:14px">     void analyseRefIdx(int *numRefIdx);</div><div style="font-size:14px">     void updateRefIdx();</div><div style="font-size:14px">+    bool computeSPSRPSIndex();</div><div style="font-size:14px"> </div><div style="font-size:14px"> protected:</div><div style="font-size:14px"> </div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/encoder/entropy.cpp</div><div style="font-size:14px">--- a/source/encoder/entropy.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/encoder/entropy.cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">      </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -312,7 +312,9 @@</div><div style="font-size:14px">     WRITE_FLAG(sps.bUseSAO, "sample_adaptive_offset_enable<wbr>d_flag");</div><div style="font-size:14px"> </div><div style="font-size:14px">     WRITE_FLAG(0, "pcm_enabled_flag");</div><div style="font-size:14px">-    WRITE_UVLC(0, "num_short_term_ref_pic_sets")<wbr>;</div><div style="font-size:14px">+    WRITE_UVLC(sps.spsrpsNum, "num_short_term_ref_pic_sets")<wbr>;</div><div style="font-size:14px">+    for (int i = 0; i < sps.spsrpsNum; i++)</div><div style="font-size:14px">+        codeShortTermRefPicSet(sps.sp<wbr>srps[i], i);</div><div style="font-size:14px">     WRITE_FLAG(0, "long_term_ref_pics_present_fl<wbr>ag");</div><div style="font-size:14px"> </div><div style="font-size:14px">     WRITE_FLAG(sps.bTemporalMVPEn<wbr>abled, "sps_temporal_mvp_enable_flag"<wbr>);</div><div style="font-size:14px">@@ -614,8 +616,21 @@</div><div style="font-size:14px">             }</div><div style="font-size:14px"> #endif</div><div style="font-size:14px"> </div><div style="font-size:14px">-        WRITE_FLAG(0, "short_term_ref_pic_set_sps_fl<wbr>ag");</div><div style="font-size:14px">-        codeShortTermRefPicSet(slice.<wbr>m_rps);</div><div style="font-size:14px">+        if (slice.m_rpsIdx < 0)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            WRITE_FLAG(0, "short_term_ref_pic_set_sps_fl<wbr>ag");</div><div style="font-size:14px">+            codeShortTermRefPicSet(slice.<wbr>m_rps, slice.m_sps->spsrpsNum);</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+        else</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            WRITE_FLAG(1, "short_term_ref_pic_set_sps_fl<wbr>ag");</div><div style="font-size:14px">+            int numBits = 0;</div><div style="font-size:14px">+            while ((1 << numBits) < slice.m_iNumRPSInSPS)</div><div style="font-size:14px">+                numBits++;</div><div style="font-size:14px">+</div><div style="font-size:14px">+            if (numBits > 0)</div><div style="font-size:14px">+                WRITE_CODE(slice.m_rpsIdx, numBits, "short_term_ref_pic_set_idx");</div><div style="font-size:14px">+        }</div><div style="font-size:14px"> </div><div style="font-size:14px">         if (slice.m_sps->bTemporalMVPEnab<wbr>led)</div><div style="font-size:14px">             WRITE_FLAG(1, "slice_temporal_mvp_enable_fla<wbr>g");</div><div style="font-size:14px">@@ -707,8 +722,11 @@</div><div style="font-size:14px">         WRITE_CODE(substreamSizes[i] - 1, offsetLen, "entry_point_offset_minus1");</div><div style="font-size:14px"> }</div><div style="font-size:14px"> </div><div style="font-size:14px">-void Entropy::codeShortTermRefPicSe<wbr>t(const RPS& rps)</div><div style="font-size:14px">+void Entropy::codeShortTermRefPicSe<wbr>t(const RPS& rps, int idx)</div><div style="font-size:14px"> {</div><div style="font-size:14px">+    if (idx > 0)</div><div style="font-size:14px">+        WRITE_FLAG(0, "inter_ref_pic_set_prediction_<wbr>flag");</div><div style="font-size:14px">+</div><div style="font-size:14px">     WRITE_UVLC(rps.numberOfNegati<wbr>vePictures, "num_negative_pics");</div><div style="font-size:14px">     WRITE_UVLC(rps.numberOfPositi<wbr>vePictures, "num_positive_pics");</div><div style="font-size:14px">     int prev = 0;</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/encoder/entropy.h</div><div style="font-size:14px">--- a/source/encoder/entropy.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">    </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/encoder/entropy.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -149,7 +149,7 @@</div><div style="font-size:14px"> </div><div style="font-size:14px">     void codeSliceHeader(const Slice& slice, FrameData& encData, uint32_t slice_addr, uint32_t slice_addr_bits, int sliceQp);</div><div style="font-size:14px">     void codeSliceHeaderWPPEntryPoints(<wbr>const uint32_t *substreamSizes, uint32_t numSubStreams, uint32_t maxOffset);</div><div style="font-size:14px">-    void codeShortTermRefPicSet(const RPS& rps);</div><div style="font-size:14px">+    void codeShortTermRefPicSet(const RPS& rps, int idx);</div><div style="font-size:14px">     void finishSlice()                 { encodeBinTrm(1); finish(); dynamic_cast<Bitstream*>(m_bit<wbr>If)->writeByteAlignment(); }</div><div style="font-size:14px"> </div><div style="font-size:14px">     void encodeCTU(const CUData& cu, const CUGeom& cuGeom);</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/encoder/frameencoder.cp<wbr>p</div><div style="font-size:14px">--- a/source/encoder/frameencoder.<wbr>cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap"> </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/encoder/frameencoder.<wbr>cpp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">      </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -359,9 +359,23 @@</div><div style="font-size:14px">             ScopedLock refIdxLock(m_top->m_sliceRefId<wbr>xLock);</div><div style="font-size:14px">             m_top->updateRefIdx();</div><div style="font-size:14px">         }</div><div style="font-size:14px">-        m_top->getStreamHeaders(m_nal<wbr>List, m_entropyCoder, m_bs);</div><div style="font-size:14px">+        if (m_top->m_param->rc.bStatRead  && m_top->m_param->bMultiPassOptR<wbr>PS)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            ScopedLock refIdxLock(m_top->m_rpsInSpsLo<wbr>ck);</div><div style="font-size:14px">+            if (!m_top->computeSPSRPSIndex())</div><div style="font-size:14px">+            {</div><div style="font-size:14px">+                x265_log(m_param, X265_LOG_ERROR, "compute commonly RPS failed!\n");</div><div style="font-size:14px">+                m_top->m_aborted = true;</div><div style="font-size:14px">+            }</div><div style="font-size:14px">+            m_top->getStreamHeaders(m_nal<wbr>List, m_entropyCoder, m_bs);</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+        else</div><div style="font-size:14px">+            m_top->getStreamHeaders(m_nal<wbr>List, m_entropyCoder, m_bs);</div><div style="font-size:14px">     }</div><div style="font-size:14px"> </div><div style="font-size:14px">+    if (m_top->m_param->rc.bStatRead && m_top->m_param->bMultiPassOptR<wbr>PS)</div><div style="font-size:14px">+        m_frame->m_encData->m_slice-><wbr>m_rpsIdx = (m_top->m_rateControl->m_rce2P<wbr>ass + m_frame->m_encodeOrder)->rpsId<wbr>x;</div><div style="font-size:14px">+</div><div style="font-size:14px">     // Weighted Prediction parameters estimation.</div><div style="font-size:14px">     bool bUseWeightP = slice->m_sliceType == P_SLICE && slice->m_pps->bUseWeightPred;</div><div style="font-size:14px">     bool bUseWeightB = slice->m_sliceType == B_SLICE && slice->m_pps->bUseWeightedBiPr<wbr>ed;</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/encoder/ratecontrol.cpp</div><div style="font-size:14px">--- a/source/encoder/ratecontrol.c<wbr>pp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">    </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/encoder/ratecontrol.c<wbr>pp<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -544,10 +544,27 @@</div><div style="font-size:14px">                 }</div><div style="font-size:14px">                 rce = &m_rce2Pass[encodeOrder];</div><div style="font-size:14px">                 m_encOrder[frameNumber] = encodeOrder;</div><div style="font-size:14px">-                e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf q-noVbv:%lf q-Rceq:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf",</div><div style="font-size:14px">-                       &picType, &qpRc, &qpAq, &qNoVbv, &qRceq, &rce->coeffBits,</div><div style="font-size:14px">-                       &rce->mvBits, &rce->miscBits, &rce->iCuCount, &rce->pCuCount,</div><div style="font-size:14px">-                       &rce->skipCuCount);</div><div style="font-size:14px">+                if (!m_param->bMultiPassOptRPS)</div><div style="font-size:14px">+                {</div><div style="font-size:14px">+                    e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf q-noVbv:%lf q-Rceq:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf",</div><div style="font-size:14px">+                        &picType, &qpRc, &qpAq, &qNoVbv, &qRceq, &rce->coeffBits,</div><div style="font-size:14px">+                        &rce->mvBits, &rce->miscBits, &rce->iCuCount, &rce->pCuCount,</div><div style="font-size:14px">+                        &rce->skipCuCount);</div><div style="font-size:14px">+                }</div><div style="font-size:14px">+                else</div><div style="font-size:14px">+                {</div><div style="font-size:14px">+                    char deltaPOC[1024];</div><div style="font-size:14px">+                    char bUsed[1024];</div><div style="font-size:14px">+                    memset(deltaPOC, 0, sizeof(deltaPOC));</div><div style="font-size:14px">+                    memset(bUsed, 0, sizeof(bUsed));</div><div style="font-size:14px">+                    e += sscanf(p, " in:%*d out:%*d type:%c q:%lf q-aq:%lf q-noVbv:%lf q-Rceq:%lf tex:%d mv:%d misc:%d icu:%lf pcu:%lf scu:%lf nump:%d numnegp:%d numposp:%d deltapoc:%s bused:%s",</div><div style="font-size:14px">+                        &picType, &qpRc, &qpAq, &qNoVbv, &qRceq, &rce->coeffBits,</div><div style="font-size:14px">+                        &rce->mvBits, &rce->miscBits, &rce->iCuCount, &rce->pCuCount,</div><div style="font-size:14px">+                        &rce->skipCuCount, &rce->rpsData.numberOfPictures<wbr>, &rce->rpsData.numberOfNegative<wbr>Pictures, &rce->rpsData.numberOfPositive<wbr>Pictures, &deltaPOC, &bUsed);</div><div style="font-size:14px">+                    splitdeltaPOC(deltaPOC, rce);</div><div style="font-size:14px">+                    splitbUsed(bUsed, rce);</div><div style="font-size:14px">+                    rce->rpsIdx = -1;</div><div style="font-size:14px">+                }</div><div style="font-size:14px">                 rce->keptAsRef = true;</div><div style="font-size:14px">                 rce->isIdr = false;</div><div style="font-size:14px">                 if (picType == 'b' || picType == 'p')</div><div style="font-size:14px">@@ -2632,18 +2649,55 @@</div><div style="font-size:14px">     char cType = rce->sliceType == I_SLICE ? (curFrame->m_lowres.sliceType == X265_TYPE_IDR ? 'I' : 'i')</div><div style="font-size:14px">         : rce->sliceType == P_SLICE ? 'P'</div><div style="font-size:14px">         : IS_REFERENCED(curFrame) ? 'B' : 'b';</div><div style="font-size:14px">-    if (fprintf(m_statFileOut,</div><div style="font-size:14px">-                "in:%d out:%d type:%c q:%.2f q-aq:%.2f q-noVbv:%.2f q-Rceq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ;\n",</div><div style="font-size:14px">-                rce->poc, rce->encodeOrder,</div><div style="font-size:14px">-                cType, curEncData.m_avgQpRc, curEncData.m_avgQpAq,</div><div style="font-size:14px">-                rce->qpNoVbv, rce->qRceq,</div><div style="font-size:14px">-                curFrame->m_encData->m_frameS<wbr>tats.coeffBits,</div><div style="font-size:14px">-                curFrame->m_encData->m_frameS<wbr>tats.mvBits,</div><div style="font-size:14px">-                curFrame->m_encData->m_frameS<wbr>tats.miscBits,</div><div style="font-size:14px">-                curFrame->m_encData->m_frameS<wbr>tats.percent8x8Intra * m_ncu,</div><div style="font-size:14px">-                curFrame->m_encData->m_frameS<wbr>tats.percent8x8Inter * m_ncu,</div><div style="font-size:14px">-                curFrame->m_encData->m_frameS<wbr>tats.percent8x8Skip  * m_ncu) < 0)</div><div style="font-size:14px">-        goto writeFailure;</div><div style="font-size:14px">+    </div><div style="font-size:14px">+    if (!curEncData.m_param->bMultiPa<wbr>ssOptRPS)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        if (fprintf(m_statFileOut,</div><div style="font-size:14px">+            "in:%d out:%d type:%c q:%.2f q-aq:%.2f q-noVbv:%.2f q-Rceq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f ;\n",</div><div style="font-size:14px">+            rce->poc, rce->encodeOrder,</div><div style="font-size:14px">+            cType, curEncData.m_avgQpRc, curEncData.m_avgQpAq,</div><div style="font-size:14px">+            rce->qpNoVbv, rce->qRceq,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.coeffBits,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.mvBits,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.miscBits,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.percent8x8Intra * m_ncu,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.percent8x8Inter * m_ncu,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.percent8x8Skip  * m_ncu) < 0)</div><div style="font-size:14px">+            goto writeFailure;</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+    else{</div><div style="font-size:14px">+        RPS* rpsWriter = &curFrame->m_encData->m_slice-<wbr>>m_rps;</div><div style="font-size:14px">+        int i, num = rpsWriter->numberOfPictures;</div><div style="font-size:14px">+        char deltaPOC[128];</div><div style="font-size:14px">+        char bUsed[40];</div><div style="font-size:14px">+        memset(deltaPOC, 0, sizeof(deltaPOC));</div><div style="font-size:14px">+        memset(bUsed, 0, sizeof(bUsed));</div><div style="font-size:14px">+        sprintf(deltaPOC, "deltapoc:~");</div><div style="font-size:14px">+        sprintf(bUsed, "bused:~");</div><div style="font-size:14px">+</div><div style="font-size:14px">+        for (i = 0; i < num; i++)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            sprintf(deltaPOC, "%s%d~", deltaPOC, rpsWriter->deltaPOC[i]);</div><div style="font-size:14px">+            sprintf(bUsed, "%s%d~", bUsed, rpsWriter->bUsed[i]);</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+</div><div style="font-size:14px">+        if (fprintf(m_statFileOut,</div><div style="font-size:14px">+            "in:%d out:%d type:%c q:%.2f q-aq:%.2f q-noVbv:%.2f q-Rceq:%.2f tex:%d mv:%d misc:%d icu:%.2f pcu:%.2f scu:%.2f nump:%d numnegp:%d numposp:%d %s %s ;\n",</div><div style="font-size:14px">+            rce->poc, rce->encodeOrder,</div><div style="font-size:14px">+            cType, curEncData.m_avgQpRc, curEncData.m_avgQpAq,</div><div style="font-size:14px">+            rce->qpNoVbv, rce->qRceq,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.coeffBits,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.mvBits,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.miscBits,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.percent8x8Intra * m_ncu,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.percent8x8Inter * m_ncu,</div><div style="font-size:14px">+            curFrame->m_encData->m_frameS<wbr>tats.percent8x8Skip  * m_ncu,</div><div style="font-size:14px">+            rpsWriter->numberOfPictures,</div><div style="font-size:14px">+            rpsWriter->numberOfNegativePi<wbr>ctures,</div><div style="font-size:14px">+            rpsWriter->numberOfPositivePi<wbr>ctures,</div><div style="font-size:14px">+            deltaPOC, bUsed) < 0)</div><div style="font-size:14px">+            goto writeFailure;</div><div style="font-size:14px">+    }</div><div style="font-size:14px">     /* Don't re-write the data in multi-pass mode. */</div><div style="font-size:14px">     if (m_param->rc.cuTree && IS_REFERENCED(curFrame) && !m_param->rc.bStatRead)</div><div style="font-size:14px">     {</div><div style="font-size:14px">@@ -2736,3 +2790,48 @@</div><div style="font-size:14px">     X265_FREE(m_param->rc.zones);</div><div style="font-size:14px"> }</div><div style="font-size:14px"> </div><div style="font-size:14px">+void RateControl::splitdeltaPOC(cha<wbr>r deltapoc[], RateControlEntry *rce)</div><div style="font-size:14px">+{</div><div style="font-size:14px">+    int idx = 0, length = 0;</div><div style="font-size:14px">+    char tmpStr[128];</div><div style="font-size:14px">+    char* src = deltapoc;</div><div style="font-size:14px">+    char* buf = strstr(src, "~");</div><div style="font-size:14px">+    while (buf)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        memset(tmpStr, 0, sizeof(tmpStr));</div><div style="font-size:14px">+        length = (int)(buf - src);</div><div style="font-size:14px">+        if (length != 0)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            strncpy(tmpStr, src, length);</div><div style="font-size:14px">+            rce->rpsData.deltaPOC[idx] = atoi(tmpStr);</div><div style="font-size:14px">+            idx++;</div><div style="font-size:14px">+            if (idx == rce->rpsData.numberOfPictures)</div><div style="font-size:14px">+                break;</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+        src += (length + 1);</div><div style="font-size:14px">+        buf = strstr(src, "~");</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+}</div><div style="font-size:14px">+</div><div style="font-size:14px">+void RateControl::splitbUsed(char bused[], RateControlEntry *rce)</div><div style="font-size:14px">+{</div><div style="font-size:14px">+    int idx = 0, length = 0;</div><div style="font-size:14px">+    char tmpStr[128];</div><div style="font-size:14px">+    char* src = bused;</div><div style="font-size:14px">+    char* buf = strstr(src, "~");</div><div style="font-size:14px">+    while (buf)</div><div style="font-size:14px">+    {</div><div style="font-size:14px">+        memset(tmpStr, 0, sizeof(tmpStr));</div><div style="font-size:14px">+        length = (int)(buf - src);</div><div style="font-size:14px">+        if (length != 0)</div><div style="font-size:14px">+        {</div><div style="font-size:14px">+            strncpy(tmpStr, src, length);</div><div style="font-size:14px">+            rce->rpsData.bUsed[idx] = atoi(tmpStr) > 0;</div><div style="font-size:14px">+            idx++;</div><div style="font-size:14px">+            if (idx == rce->rpsData.numberOfPictures)</div><div style="font-size:14px">+                break;</div><div style="font-size:14px">+        }</div><div style="font-size:14px">+        src += (length + 1);</div><div style="font-size:14px">+        buf = strstr(src, "~");</div><div style="font-size:14px">+    }</div><div style="font-size:14px">+}</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/encoder/ratecontrol.h</div><div style="font-size:14px">--- a/source/encoder/ratecontrol.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap"> </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/encoder/ratecontrol.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">    </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -111,6 +111,8 @@</div><div style="font-size:14px">     bool     isIdr;</div><div style="font-size:14px">     SEIPictureTiming *picTimingSEI;</div><div style="font-size:14px">     HRDTiming        *hrdTiming;</div><div style="font-size:14px">+    int      rpsIdx;</div><div style="font-size:14px">+    RPS      rpsData;</div><div style="font-size:14px"> };</div><div style="font-size:14px"> </div><div style="font-size:14px"> class RateControl</div><div style="font-size:14px">@@ -282,6 +284,8 @@</div><div style="font-size:14px">     bool   findUnderflow(double *fills, int *t0, int *t1, int over, int framesCount);</div><div style="font-size:14px">     bool   fixUnderflow(int t0, int t1, double adjustment, double qscaleMin, double qscaleMax);</div><div style="font-size:14px">     double tuneQScaleForGrain(double rcOverflow);</div><div style="font-size:14px">+    void   splitdeltaPOC(char deltapoc[], RateControlEntry *rce);</div><div style="font-size:14px">+    void   splitbUsed(char deltapoc[], RateControlEntry *rce);</div><div style="font-size:14px"> };</div><div style="font-size:14px"> }</div><div style="font-size:14px"> #endif // ifndef X265_RATECONTROL_H</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/x265.h</div><div style="font-size:14px">--- a/source/x265.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">       </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/x265.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">   </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -1063,6 +1063,9 @@</div><div style="font-size:14px">      * Default is 0, which is recommended */</div><div style="font-size:14px">     int       crQpOffset;</div><div style="font-size:14px"> </div><div style="font-size:14px">+    /* Enable storing commonly RPS in SPS in multi pass mode */</div><div style="font-size:14px">+    int       bMultiPassOptRPS;</div><div style="font-size:14px">+</div><div style="font-size:14px">     struct</div><div style="font-size:14px">     {</div><div style="font-size:14px">         /* Explicit mode of rate-control, necessary for API users. It must</div><div style="font-size:14px">diff -r 0e9e52640546 -r b1662beb6486 source/x265cli.h</div><div style="font-size:14px">--- a/source/x265cli.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">     </span>Wed Oct 12 17:58:49 2016 +0530</div><div style="font-size:14px">+++ b/source/x265cli.h<span class="gmail-m_164700993836700815gmail-m_6426816771955420305gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>Wed Oct 19 15:50:34 2016 +0800</div><div style="font-size:14px">@@ -236,6 +236,8 @@</div><div style="font-size:14px">     { "pass",           required_argument, NULL, 0 },</div><div style="font-size:14px">     { "slow-firstpass",       no_argument, NULL, 0 },</div><div style="font-size:14px">     { "no-slow-firstpass",    no_argument, NULL, 0 },</div><div style="font-size:14px">+    { "multi-pass-opt-rps",   no_argument, NULL, 0 },</div><div style="font-size:14px">+    { "no-multi-pass-opt-rps", no_argument, NULL, 0 },</div><div style="font-size:14px">     { "analysis-mode",  required_argument, NULL, 0 },</div><div style="font-size:14px">     { "analysis-file",  required_argument, NULL, 0 },</div><div style="font-size:14px">     { "strict-cbr",           no_argument, NULL, 0 },</div><div style="font-size:14px">@@ -422,6 +424,7 @@</div><div style="font-size:14px">     H1("                                 MAX_MAX_QP+1 floats for lambda table, then again for lambda2 table\n");</div><div style="font-size:14px">     H1("                                 Blank lines and lines starting with hash(#) are ignored\n");</div><div style="font-size:14px">     H1("                                 Comma is considered to be white-space\n");</div><div style="font-size:14px">+    H0("   --[no-]multi-pass-opt-rps     Enable storing commonly RPS in SPS in multi pass mode. Default %s\n", OPT(param->bMultiPassOptRPS));</div><div style="font-size:14px">     H0("\nLoop filters (deblock and SAO):\n");</div><div style="font-size:14px">     H0("   --[no-]deblock                Enable Deblocking Loop Filter, optionally specify tC:Beta offsets Default %s\n", OPT(param->bEnableLoopFilter))<wbr>;</div><div style="font-size:14px">     H0("   --[no-]sao                    Enable Sample Adaptive Offset. Default %s\n", OPT(param->bEnableSAO));</div><div style="font-size:14px"><br></div></div>