<div dir="ltr"><div># HG changeset patch</div><div># User weixuan</div><div># Date 1475895706 -28800</div><div>#      Sat Oct 08 11:01:46 2016 +0800</div><div># Node ID 6f244c89eb2d8b8415e04f4464a18a773b55b5b8</div><div># Parent  a3d4e3b13c6c70061bc74a0a052bdf5cd408eeb2</div><div>Store most frequently used list in ref list in PPS</div><div><br></div><div>diff -r a3d4e3b13c6c -r 6f244c89eb2d source/common/slice.h</div><div>--- a/source/common/slice.h<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>Wed Sep 28 15:09:58 2016 +0800</div><div>+++ b/source/common/slice.h<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>Sat Oct 08 11:01:46 2016 +0800</div><div>@@ -282,6 +282,9 @@</div><div> </div><div>     bool     bDeblockingFilterControlPresent;</div><div>     bool     bPicDisableDeblockingFilter;</div><div>+</div><div>+    int      ppsId;</div><div>+    int      numRefIdxDefault[2];</div><div> };</div><div> </div><div> struct WeightParam</div><div>@@ -348,7 +351,8 @@</div><div>     bool        m_colFromL0Flag;   // collocated picture from List0 or List1 flag</div><div> </div><div>     int         m_iPPSQpMinus26;</div><div>-<span class="gmail-Apple-tab-span" style="white-space:pre">     </span></div><div>+    int         numRefIdxDefault[2];</div><div>+</div><div>     Slice()</div><div>     {</div><div>         m_lastIDR = 0;</div><div>@@ -359,6 +363,8 @@</div><div>         memset(m_refPOCList, 0, sizeof(m_refPOCList));</div><div>         disableWeights();</div><div>         m_iPPSQpMinus26 = 0;</div><div>+        numRefIdxDefault[0] = 1;</div><div>+        numRefIdxDefault[1] = 1;</div><div>     }</div><div> </div><div>     void disableWeights();</div><div>diff -r a3d4e3b13c6c -r 6f244c89eb2d source/encoder/encoder.cpp</div><div>--- a/source/encoder/encoder.cpp<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Wed Sep 28 15:09:58 2016 +0800</div><div>+++ b/source/encoder/encoder.cpp<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>Sat Oct 08 11:01:46 2016 +0800</div><div>@@ -320,6 +320,14 @@</div><div>     if (!m_lookahead->create())</div><div>         m_aborted = true;</div><div> </div><div>+    m_refIdxPPS = X265_MALLOC(RefIdxPPS, 1);</div><div>+    if (!m_refIdxPPS)</div><div>+    {</div><div>+        x265_log(m_param, X265_LOG_ERROR, "Ref Idx for PPS cannot be allocated\n");</div><div>+        m_aborted = true;</div><div>+    }</div><div>+    initRefIdx();</div><div>+</div><div>     if (m_param->analysisMode)</div><div>     {</div><div>         const char* name = m_param->analysisFileName;</div><div>@@ -406,6 +414,7 @@</div><div>     }</div><div> </div><div>     X265_FREE(m_offsetEmergency);</div><div>+    X265_FREE(m_refIdxPPS);</div><div> </div><div>     if (m_analysisFile)</div><div>         fclose(m_analysisFile);</div><div>@@ -900,6 +909,8 @@</div><div>             }</div><div> </div><div>             frameEnc->m_encData->m_slice->m_iPPSQpMinus26 = m_iPPSQpMinus26;</div><div>+            frameEnc->m_encData->m_slice->numRefIdxDefault[0] = m_pps.numRefIdxDefault[0];</div><div>+            frameEnc->m_encData->m_slice->numRefIdxDefault[1] = m_pps.numRefIdxDefault[1];</div><div> </div><div>             curEncoder->m_rce.encodeOrder = frameEnc->m_encodeOrder = m_encodedFrameNum++;</div><div>             if (m_bframeDelay)</div><div>@@ -1446,6 +1457,67 @@</div><div> #pragma warning(disable: 4127) // conditional expression is constant</div><div> #endif</div><div> </div><div>+void Encoder::initRefIdx()</div><div>+{</div><div>+    int j = 0;</div><div>+</div><div>+    for (j = 0; j < MAX_NUM_REF_IDX; j++)</div><div>+    {</div><div>+        m_refIdxPPS[0].numRefIdxl0[j] = 0;</div><div>+        m_refIdxPPS[0].numRefIdxl1[j] = 0;</div><div>+    }</div><div>+</div><div>+    return;</div><div>+}</div><div>+</div><div>+void Encoder::analyseRefIdx(int *numRefIdx)</div><div>+{</div><div>+    int i_l0 = 0;</div><div>+    int i_l1 = 0;</div><div>+</div><div>+    i_l0 = numRefIdx[0];</div><div>+    i_l1 = numRefIdx[1];</div><div>+</div><div>+    if ((0 < i_l0) && (MAX_NUM_REF_IDX > i_l0))</div><div>+        m_refIdxPPS[0].numRefIdxl0[i_l0]++;</div><div>+    if ((0 < i_l1) && (MAX_NUM_REF_IDX > i_l1))</div><div>+        m_refIdxPPS[0].numRefIdxl1[i_l1]++;</div><div>+</div><div>+    return;</div><div>+}</div><div>+</div><div>+void Encoder::updateRefIdx()</div><div>+{</div><div>+    int i_max_l0 = 0;</div><div>+    int i_max_l1 = 0;</div><div>+    int j = 0;</div><div>+</div><div>+    i_max_l0 = 0;</div><div>+    i_max_l1 = 0;</div><div>+    m_refIdxPPS[0].numRefIdxDefault[0] = 1;</div><div>+    m_refIdxPPS[0].numRefIdxDefault[1] = 1;</div><div>+    for (j = 0; j < MAX_NUM_REF_IDX; j++)</div><div>+    {</div><div>+        if (i_max_l0 < m_refIdxPPS[0].numRefIdxl0[j])</div><div>+        {</div><div>+            i_max_l0 = m_refIdxPPS[0].numRefIdxl0[j];</div><div>+            m_refIdxPPS[0].numRefIdxDefault[0] = j;</div><div>+        }</div><div>+        if (i_max_l1 < m_refIdxPPS[0].numRefIdxl1[j])</div><div>+        {</div><div>+            i_max_l1 = m_refIdxPPS[0].numRefIdxl1[j];</div><div>+            m_refIdxPPS[0].numRefIdxDefault[1] = j;</div><div>+        }</div><div>+    }</div><div>+</div><div>+    m_pps.ppsId++;</div><div>+    m_pps.numRefIdxDefault[0] = m_refIdxPPS[0].numRefIdxDefault[0];</div><div>+    m_pps.numRefIdxDefault[1] = m_refIdxPPS[0].numRefIdxDefault[1];</div><div>+    initRefIdx();</div><div>+</div><div>+    return;</div><div>+}</div><div>+</div><div> void Encoder::getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs)</div><div> {</div><div>     sbacCoder.setBitstream(&bs);</div><div>@@ -1654,6 +1726,10 @@</div><div>     pps->deblockingFilterTcOffsetDiv2 = m_param->deblockingFilterTCOffset;</div><div> </div><div>     pps->bEntropyCodingSyncEnabled = m_param->bEnableWavefront;</div><div>+</div><div>+    pps->ppsId = 0;</div><div>+    pps->numRefIdxDefault[0] = 1;</div><div>+    pps->numRefIdxDefault[1] = 1;</div><div> }</div><div> </div><div> void Encoder::configure(x265_param *p)</div><div>diff -r a3d4e3b13c6c -r 6f244c89eb2d source/encoder/encoder.h</div><div>--- a/source/encoder/encoder.h<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Wed Sep 28 15:09:58 2016 +0800</div><div>+++ b/source/encoder/encoder.h<span class="gmail-Apple-tab-span" style="white-space:pre">   </span>Sat Oct 08 11:01:46 2016 +0800</div><div>@@ -70,6 +70,16 @@</div><div>     void addSsim(double ssim);</div><div> };</div><div> </div><div>+#define MAX_NUM_REF_IDX 64</div><div>+</div><div>+struct RefIdxPPS</div><div>+{</div><div>+    int ppsId;</div><div>+    int numRefIdxDefault[2];</div><div>+    int numRefIdxl0[MAX_NUM_REF_IDX];</div><div>+    int numRefIdxl1[MAX_NUM_REF_IDX];</div><div>+};</div><div>+</div><div> class FrameEncoder;</div><div> class DPB;</div><div> class Lookahead;</div><div>@@ -143,6 +153,9 @@</div><div>     int64_t            m_iBitsCostSum[QP_MAX_MAX + 1];</div><div>     int                m_iPPSQpMinus26;</div><div> </div><div>+    Lock               m_sliceRefIdxLock;</div><div>+    RefIdxPPS*         m_refIdxPPS;</div><div>+</div><div>     Encoder();</div><div>     ~Encoder() {}</div><div> </div><div>@@ -180,6 +193,10 @@</div><div> </div><div>     void calcRefreshInterval(Frame* frameEnc);</div><div> </div><div>+    void initRefIdx();</div><div>+    void analyseRefIdx(int *numRefIdx);</div><div>+    void updateRefIdx();</div><div>+</div><div> protected:</div><div> </div><div>     void initVPS(VPS *vps);</div><div>diff -r a3d4e3b13c6c -r 6f244c89eb2d source/encoder/entropy.cpp</div><div>--- a/source/encoder/entropy.cpp<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Wed Sep 28 15:09:58 2016 +0800</div><div>+++ b/source/encoder/entropy.cpp<span class="gmail-Apple-tab-span" style="white-space:pre"> </span>Sat Oct 08 11:01:46 2016 +0800</div><div>@@ -333,8 +333,8 @@</div><div>     WRITE_CODE(0, 3,                       "num_extra_slice_header_bits");</div><div>     WRITE_FLAG(pps.bSignHideEnabled,       "sign_data_hiding_flag");</div><div>     WRITE_FLAG(0,                          "cabac_init_present_flag");</div><div>-    WRITE_UVLC(0,                          "num_ref_idx_l0_default_active_minus1");</div><div>-    WRITE_UVLC(0,                          "num_ref_idx_l1_default_active_minus1");</div><div>+    WRITE_UVLC(pps.numRefIdxDefault[0] - 1, "num_ref_idx_l0_default_active_minus1");</div><div>+    WRITE_UVLC(pps.numRefIdxDefault[1] - 1, "num_ref_idx_l1_default_active_minus1");</div><div> </div><div>     WRITE_SVLC(iPPSInitQpMinus26,         "init_qp_minus26");</div><div>     WRITE_FLAG(pps.bConstrainedIntraPred, "constrained_intra_pred_flag");</div><div>@@ -633,7 +633,7 @@</div><div> </div><div>     if (!slice.isIntra())</div><div>     {</div><div>-        bool overrideFlag = (slice.m_numRefIdx[0] != 1 || (slice.isInterB() && slice.m_numRefIdx[1] != 1));</div><div>+        bool overrideFlag = (slice.m_numRefIdx[0] != slice.numRefIdxDefault[0] || (slice.isInterB() && slice.m_numRefIdx[1] != slice.numRefIdxDefault[1]));</div><div>         WRITE_FLAG(overrideFlag, "num_ref_idx_active_override_flag");</div><div>         if (overrideFlag)</div><div>         {</div><div>diff -r a3d4e3b13c6c -r 6f244c89eb2d source/encoder/frameencoder.cpp</div><div>--- a/source/encoder/frameencoder.cpp<span class="gmail-Apple-tab-span" style="white-space:pre">       </span>Wed Sep 28 15:09:58 2016 +0800</div><div>+++ b/source/encoder/frameencoder.cpp<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>Sat Oct 08 11:01:46 2016 +0800</div><div>@@ -353,7 +353,11 @@</div><div>         m_nalList.serialize(NAL_UNIT_ACCESS_UNIT_DELIMITER, m_bs);</div><div>     }</div><div>     if (m_frame->m_lowres.bKeyframe && m_param->bRepeatHeaders)</div><div>+    {</div><div>+        ScopedLock refIdxLock(m_top->m_sliceRefIdxLock);</div><div>+        m_top->updateRefIdx();</div><div>         m_top->getStreamHeaders(m_nalList, m_entropyCoder, m_bs);</div><div>+    }</div><div> </div><div>     // Weighted Prediction parameters estimation.</div><div>     bool bUseWeightP = slice->m_sliceType == P_SLICE && slice->m_pps->bUseWeightPred;</div><div>@@ -857,8 +861,9 @@</div><div>             const uint32_t sliceAddr = nextSliceRow * m_numCols;</div><div>             //CUData* ctu = m_frame->m_encData->getPicCTU(sliceAddr);</div><div>             //const int sliceQp = ctu->m_qp[0];</div><div>+            ScopedLock refIdxLock(m_top->m_sliceRefIdxLock);</div><div>+            m_top->analyseRefIdx(slice->m_numRefIdx);</div><div>             m_entropyCoder.codeSliceHeader(*slice, *m_frame->m_encData, sliceAddr, m_sliceAddrBits, slice->m_sliceQp);</div><div>-</div><div>             // Find rows of current slice</div><div>             const uint32_t prevSliceRow = nextSliceRow;</div><div>             while(nextSliceRow < m_numRows && m_rows[nextSliceRow].sliceId == sliceId)</div><div>@@ -880,6 +885,8 @@</div><div>     }</div><div>     else</div><div>     {</div><div>+        ScopedLock refIdxLock(m_top->m_sliceRefIdxLock);</div><div>+        m_top->analyseRefIdx(slice->m_numRefIdx);</div><div>         m_entropyCoder.codeSliceHeader(*slice, *m_frame->m_encData, 0, 0, slice->m_sliceQp);</div><div> </div><div>         // serialize each row, record final lengths in slice header</div><div><br></div><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><br><div>Thanks,</div><div>weixuan</div></div></div>
</div>