[x265] [PATCH] Store most frequently used list in ref list in PPS

Pradeep Ramachandran pradeep at multicorewareinc.com
Wed Oct 12 10:29:34 CEST 2016


This patch doesn't apply on current x265 tip. Please fix and resend.
Pradeep.

On Sat, Oct 8, 2016 at 8:36 AM, Weixuan Wang <weixuan at multicorewareinc.com>
wrote:

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


More information about the x265-devel mailing list