[x265] improve getInterMergeCandidates() (Re: add static const for local tables)

Steve Borho steve at borho.org
Mon Feb 10 04:42:50 CET 2014


On Sat, Feb 8, 2014 at 7:59 AM, Satoshi Nakagawa <nakagawa424 at oki.com>wrote:

> further cleanup for getInterMergeCandidates()
>
> # HG changeset patch
> # User Satoshi Nakagawa <nakagawa424 at oki.com>
> # Date 1391867438 -32400
> #      Sat Feb 08 22:50:38 2014 +0900
> # Branch mrg
> # Node ID e74cb7ea8645e073c3102b70f023073e80bbb524
> # Parent  fa9f7b56d4d870f5ebef47bb1007995c2d71ce1a
> improve getInterMergeCandidates()
>

queued, along with the previous patch, thanks.


> diff -r fa9f7b56d4d8 -r e74cb7ea8645 source/Lib/TLibCommon/TComDataCU.cpp
> --- a/source/Lib/TLibCommon/TComDataCU.cpp      Fri Feb 07 21:37:17 2014
> +0530
> +++ b/source/Lib/TLibCommon/TComDataCU.cpp      Sat Feb 08 22:50:38 2014
> +0900
> @@ -1914,19 +1914,19 @@
>   * \param numValidMergeCand
>   */
>  void TComDataCU::getInterMergeCandidates(uint32_t absPartIdx, uint32_t
> puIdx, TComMvField* mvFieldNeighbours, UChar* interDirNeighbours,
> -                                         int& numValidMergeCand, int
> mrgCandIdx)
> +                                         int& numValidMergeCand)
>  {
>      uint32_t absPartAddr = m_absIdxInLCU + absPartIdx;
> -    bool abCandIsInter[MRG_MAX_NUM_CANDS];
> -
> -    for (uint32_t i = 0; i < getSlice()->getMaxNumMergeCand(); ++i)
> +    const uint32_t maxNumMergeCand = getSlice()->getMaxNumMergeCand();
> +    const bool isInterB = getSlice()->isInterB();
> +
> +    for (uint32_t i = 0; i < maxNumMergeCand; ++i)
>      {
> -        abCandIsInter[i] = false;
>          mvFieldNeighbours[(i << 1)].refIdx = NOT_VALID;
>          mvFieldNeighbours[(i << 1) + 1].refIdx = NOT_VALID;
>      }
>
> -    numValidMergeCand = getSlice()->getMaxNumMergeCand();
> +    numValidMergeCand = maxNumMergeCand;
>      // compute the location of the current PU
>      int xP, yP, nPSW, nPSH;
>      this->getPartPosition(puIdx, xP, yP, nPSW, nPSH);
> @@ -1935,7 +1935,6 @@
>
>      uint32_t partIdxLT, partIdxRT, partIdxLB;
>      PartSize curPS = getPartitionSize(absPartIdx);
> -    deriveLeftRightTopIdxGeneral(absPartIdx, puIdx, partIdxLT, partIdxRT);
>      deriveLeftBottomIdxGeneral(absPartIdx, puIdx, partIdxLB);
>
>      //left
> @@ -1948,27 +1947,24 @@
>          !cuLeft->isIntra(leftPartIdx);
>      if (isAvailableA1)
>      {
> -        abCandIsInter[count] = true;
>          // get Inter Dir
>          interDirNeighbours[count] = cuLeft->getInterDir(leftPartIdx);
>          // get Mv from Left
>          cuLeft->getMvField(cuLeft, leftPartIdx, REF_PIC_LIST_0,
> mvFieldNeighbours[count << 1]);
> -        if (getSlice()->isInterB())
> +        if (isInterB)
>          {
>              cuLeft->getMvField(cuLeft, leftPartIdx, REF_PIC_LIST_1,
> mvFieldNeighbours[(count << 1) + 1]);
>          }
> -        if (mrgCandIdx == count)
> +        count++;
> +        // early termination
> +        if (count == maxNumMergeCand)
>          {
>              return;
>          }
> -        count++;
>      }
>
> -    // early termination
> -    if (count == getSlice()->getMaxNumMergeCand())
> -    {
> -        return;
> -    }
> +    deriveLeftRightTopIdxGeneral(absPartIdx, puIdx, partIdxLT, partIdxRT);
> +
>      // above
>      uint32_t abovePartIdx = 0;
>      TComDataCU* cuAbove = 0;
> @@ -1979,25 +1975,20 @@
>          !cuAbove->isIntra(abovePartIdx);
>      if (isAvailableB1 && (!isAvailableA1 ||
> !cuLeft->hasEqualMotion(leftPartIdx, cuAbove, abovePartIdx)))
>      {
> -        abCandIsInter[count] = true;
>          // get Inter Dir
>          interDirNeighbours[count] = cuAbove->getInterDir(abovePartIdx);
>          // get Mv from Left
>          cuAbove->getMvField(cuAbove, abovePartIdx, REF_PIC_LIST_0,
> mvFieldNeighbours[count << 1]);
> -        if (getSlice()->isInterB())
> +        if (isInterB)
>          {
>              cuAbove->getMvField(cuAbove, abovePartIdx, REF_PIC_LIST_1,
> mvFieldNeighbours[(count << 1) + 1]);
>          }
> -        if (mrgCandIdx == count)
> +        count++;
> +        // early termination
> +        if (count == maxNumMergeCand)
>          {
>              return;
>          }
> -        count++;
> -    }
> -    // early termination
> -    if (count == getSlice()->getMaxNumMergeCand())
> -    {
> -        return;
>      }
>
>      // above right
> @@ -2009,25 +2000,20 @@
>          !cuAboveRight->isIntra(aboveRightPartIdx);
>      if (isAvailableB0 && (!isAvailableB1 ||
> !cuAbove->hasEqualMotion(abovePartIdx, cuAboveRight, aboveRightPartIdx)))
>      {
> -        abCandIsInter[count] = true;
>          // get Inter Dir
>          interDirNeighbours[count] =
> cuAboveRight->getInterDir(aboveRightPartIdx);
>          // get Mv from Left
>          cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx,
> REF_PIC_LIST_0, mvFieldNeighbours[count << 1]);
> -        if (getSlice()->isInterB())
> +        if (isInterB)
>          {
>              cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx,
> REF_PIC_LIST_1, mvFieldNeighbours[(count << 1) + 1]);
>          }
> -        if (mrgCandIdx == count)
> +        count++;
> +        // early termination
> +        if (count == maxNumMergeCand)
>          {
>              return;
>          }
> -        count++;
> -    }
> -    // early termination
> -    if (count == getSlice()->getMaxNumMergeCand())
> -    {
> -        return;
>      }
>
>      //left bottom
> @@ -2039,26 +2025,22 @@
>          !cuLeftBottom->isIntra(leftBottomPartIdx);
>      if (isAvailableA0 && (!isAvailableA1 ||
> !cuLeft->hasEqualMotion(leftPartIdx, cuLeftBottom, leftBottomPartIdx)))
>      {
> -        abCandIsInter[count] = true;
>          // get Inter Dir
>          interDirNeighbours[count] =
> cuLeftBottom->getInterDir(leftBottomPartIdx);
>          // get Mv from Left
>          cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx,
> REF_PIC_LIST_0, mvFieldNeighbours[count << 1]);
> -        if (getSlice()->isInterB())
> +        if (isInterB)
>          {
>              cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx,
> REF_PIC_LIST_1, mvFieldNeighbours[(count << 1) + 1]);
>          }
> -        if (mrgCandIdx == count)
> +        count++;
> +        // early termination
> +        if (count == maxNumMergeCand)
>          {
>              return;
>          }
> -        count++;
>      }
> -    // early termination
> -    if (count == getSlice()->getMaxNumMergeCand())
> -    {
> -        return;
> -    }
> +
>      // above left
>      if (count < 4)
>      {
> @@ -2071,32 +2053,26 @@
>          if (isAvailableB2 && (!isAvailableA1 ||
> !cuLeft->hasEqualMotion(leftPartIdx, cuAboveLeft, aboveLeftPartIdx))
>              && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx,
> cuAboveLeft, aboveLeftPartIdx)))
>          {
> -            abCandIsInter[count] = true;
>              // get Inter Dir
>              interDirNeighbours[count] =
> cuAboveLeft->getInterDir(aboveLeftPartIdx);
>              // get Mv from Left
>              cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx,
> REF_PIC_LIST_0, mvFieldNeighbours[count << 1]);
> -            if (getSlice()->isInterB())
> +            if (isInterB)
>              {
>                  cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx,
> REF_PIC_LIST_1, mvFieldNeighbours[(count << 1) + 1]);
>              }
> -            if (mrgCandIdx == count)
> +            count++;
> +            // early termination
> +            if (count == maxNumMergeCand)
>              {
>                  return;
>              }
> -            count++;
>          }
>      }
> -    // early termination
> -    if (count == getSlice()->getMaxNumMergeCand())
> -    {
> -        return;
> -    }
>      if (getSlice()->getEnableTMVPFlag())
>      {
>          //>> MTK colocated-RightBottom
>          uint32_t partIdxRB;
> -        int lcuIdx;
>
>          deriveRightBottomIdx(puIdx, partIdxRB);
>
> @@ -2105,14 +2081,13 @@
>
>          MV colmv;
>          int refIdx;
> +        int lcuIdx = -1;
>
>          if ((m_pic->getCU(m_cuAddr)->getCUPelX() +
> g_rasterToPelX[uiAbsPartIdxTmp] + m_pic->getMinCUWidth()) >=
> m_slice->getSPS()->getPicWidthInLumaSamples())  // image boundary check
>          {
> -            lcuIdx = -1;
>          }
>          else if ((m_pic->getCU(m_cuAddr)->getCUPelY() +
> g_rasterToPelY[uiAbsPartIdxTmp] + m_pic->getMinCUHeight()) >=
> m_slice->getSPS()->getPicHeightInLumaSamples())
>          {
> -            lcuIdx = -1;
>          }
>          else
>          {
> @@ -2125,7 +2100,6 @@
>              else if (uiAbsPartIdxTmp % numPartInCUWidth <
> numPartInCUWidth - 1)       // is not at the last column of LCU But is last
> row of LCU
>              {
>                  absPartAddr = g_rasterToZscan[(uiAbsPartIdxTmp +
> numPartInCUWidth + 1) % m_pic->getNumPartInCU()];
> -                lcuIdx = -1;
>              }
>              else if (uiAbsPartIdxTmp / numPartInCUWidth <
> m_pic->getNumPartInHeight() - 1) // is not at the last row of LCU But is
> last column of LCU
>              {
> @@ -2135,7 +2109,6 @@
>              else //is the right bottom corner of LCU
>              {
>                  absPartAddr = 0;
> -                lcuIdx = -1;
>              }
>          }
>
> @@ -2157,7 +2130,7 @@
>              mvFieldNeighbours[2 * arrayAddr].setMvField(colmv, refIdx);
>          }
>
> -        if (getSlice()->isInterB())
> +        if (isInterB)
>          {
>              bExistMV = lcuIdx >= 0 && xGetColMVP(REF_PIC_LIST_1, lcuIdx,
> absPartAddr, colmv, refIdx);
>              if (bExistMV == false)
> @@ -2174,70 +2147,63 @@
>          if (dir != 0)
>          {
>              interDirNeighbours[arrayAddr] = dir;
> -            abCandIsInter[arrayAddr] = true;
> -
> -            if (mrgCandIdx == count)
> +
> +            count++;
> +            // early termination
> +            if (count == maxNumMergeCand)
>              {
>                  return;
>              }
> -            count++;
>          }
>      }
> -    // early termination
> -    if (count == getSlice()->getMaxNumMergeCand())
> +
> +    uint32_t arrayAddr = count;
> +
> +    if (isInterB)
>      {
> -        return;
> -    }
> -    uint32_t arrayAddr = count;
> -    uint32_t cutoff = arrayAddr;
> -
> -    if (getSlice()->isInterB())
> -    {
> -        // TODO: TComRom??
> -        uint32_t priorityList0[12] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2, 3
> };
> -        uint32_t priorityList1[12] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3, 2
> };
> -
> -        for (int idx = 0; idx < cutoff * (cutoff - 1) && arrayAddr !=
> getSlice()->getMaxNumMergeCand(); idx++)
> +        const int cutoff = count * (count - 1);
> +        uint32_t priorityList0 = 0xEDC984; // { 0, 1, 0, 2, 1, 2, 0, 3,
> 1, 3, 2, 3 }
> +        uint32_t priorityList1 = 0xB73621; // { 1, 0, 2, 0, 2, 1, 3, 0,
> 3, 1, 3, 2 }
> +
> +        for (int idx = 0; idx < cutoff; idx++)
>          {
> -            int i = priorityList0[idx];
> -            int j = priorityList1[idx];
> -            if (abCandIsInter[i] && abCandIsInter[j] &&
> (interDirNeighbours[i] & 0x1) && (interDirNeighbours[j] & 0x2))
> +            int i = priorityList0 & 3;
> +            int j = priorityList1 & 3;
> +            priorityList0 >>= 2;
> +            priorityList1 >>= 2;
> +
> +            if ((interDirNeighbours[i] & 0x1) && (interDirNeighbours[j] &
> 0x2))
>              {
> -                abCandIsInter[arrayAddr] = true;
> -                interDirNeighbours[arrayAddr] = 3;
> -
>                  // get Mv from cand[i] and cand[j]
> -                mvFieldNeighbours[arrayAddr <<
> 1].setMvField(mvFieldNeighbours[i << 1].mv, mvFieldNeighbours[i <<
> 1].refIdx);
> -                mvFieldNeighbours[(arrayAddr << 1) +
> 1].setMvField(mvFieldNeighbours[(j << 1) + 1].mv, mvFieldNeighbours[(j <<
> 1) + 1].refIdx);
> -
> -                int refPOCL0 = m_slice->getRefPOC(REF_PIC_LIST_0,
> mvFieldNeighbours[(arrayAddr << 1)].refIdx);
> -                int refPOCL1 = m_slice->getRefPOC(REF_PIC_LIST_1,
> mvFieldNeighbours[(arrayAddr << 1) + 1].refIdx);
> -                if (refPOCL0 == refPOCL1 && mvFieldNeighbours[(arrayAddr
> << 1)].mv == mvFieldNeighbours[(arrayAddr << 1) + 1].mv)
> +                int refIdxL0 = mvFieldNeighbours[i << 1].refIdx;
> +                int refIdxL1 = mvFieldNeighbours[(j << 1) + 1].refIdx;
> +                int refPOCL0 = m_slice->getRefPOC(REF_PIC_LIST_0,
> refIdxL0);
> +                int refPOCL1 = m_slice->getRefPOC(REF_PIC_LIST_1,
> refIdxL1);
> +                if (!(refPOCL0 == refPOCL1 && mvFieldNeighbours[i <<
> 1].mv == mvFieldNeighbours[(j << 1) + 1].mv))
>                  {
> -                    abCandIsInter[arrayAddr] = false;
> -                }
> -                else
> -                {
> +                    mvFieldNeighbours[arrayAddr <<
> 1].setMvField(mvFieldNeighbours[i << 1].mv, refIdxL0);
> +                    mvFieldNeighbours[(arrayAddr << 1) +
> 1].setMvField(mvFieldNeighbours[(j << 1) + 1].mv, refIdxL1);
> +                    interDirNeighbours[arrayAddr] = 3;
> +
>                      arrayAddr++;
> +                    // early termination
> +                    if (arrayAddr == maxNumMergeCand)
> +                    {
> +                        return;
> +                    }
>                  }
>              }
>          }
>      }
> -    // early termination
> -    if (arrayAddr == getSlice()->getMaxNumMergeCand())
> -    {
> -        return;
> -    }
> -    int numRefIdx = (getSlice()->isInterB()) ?
> X265_MIN(m_slice->getNumRefIdx(REF_PIC_LIST_0),
> m_slice->getNumRefIdx(REF_PIC_LIST_1)) :
> m_slice->getNumRefIdx(REF_PIC_LIST_0);
> +    int numRefIdx = (isInterB) ?
> X265_MIN(m_slice->getNumRefIdx(REF_PIC_LIST_0),
> m_slice->getNumRefIdx(REF_PIC_LIST_1)) :
> m_slice->getNumRefIdx(REF_PIC_LIST_0);
>      int r = 0;
>      int refcnt = 0;
> -    while (arrayAddr < getSlice()->getMaxNumMergeCand())
> +    while (arrayAddr < maxNumMergeCand)
>      {
> -        abCandIsInter[arrayAddr] = true;
>          interDirNeighbours[arrayAddr] = 1;
>          mvFieldNeighbours[arrayAddr << 1].setMvField(MV(0, 0), r);
>
> -        if (getSlice()->isInterB())
> +        if (isInterB)
>          {
>              interDirNeighbours[arrayAddr] = 3;
>              mvFieldNeighbours[(arrayAddr << 1) + 1].setMvField(MV(0, 0),
> r);
> @@ -2253,8 +2219,6 @@
>              ++refcnt;
>          }
>      }
> -
> -    numValidMergeCand = arrayAddr;
>  }
>
>  /** Check whether the current PU and a spatial neighboring PU are in a
> same ME region.
> diff -r fa9f7b56d4d8 -r e74cb7ea8645 source/Lib/TLibCommon/TComDataCU.h
> --- a/source/Lib/TLibCommon/TComDataCU.h        Fri Feb 07 21:37:17 2014
> +0530
> +++ b/source/Lib/TLibCommon/TComDataCU.h        Sat Feb 08 22:50:38 2014
> +0900
> @@ -435,7 +435,7 @@
>      void          deriveLeftBottomIdxAdi(uint32_t& partIdxLB, uint32_t
> partOffset, uint32_t partDepth);
>
>      bool          hasEqualMotion(uint32_t absPartIdx, TComDataCU* candCU,
> uint32_t candAbsPartIdx);
> -    void          getInterMergeCandidates(uint32_t absPartIdx, uint32_t
> puIdx, TComMvField* mFieldNeighbours, UChar* interDirNeighbours, int&
> numValidMergeCand, int mrgCandIdx = -1);
> +    void          getInterMergeCandidates(uint32_t absPartIdx, uint32_t
> puIdx, TComMvField* mFieldNeighbours, UChar* interDirNeighbours, int&
> numValidMergeCand);
>      void          deriveLeftRightTopIdxGeneral(uint32_t absPartIdx,
> uint32_t partIdx, uint32_t& partIdxLT, uint32_t& partIdxRT);
>      void          deriveLeftBottomIdxGeneral(uint32_t absPartIdx,
> uint32_t partIdx, uint32_t& partIdxLB);
>
>
>
>
>
>
>
> From: chen  <chenm003 at 163.com>
> Subject: Re: [x265] add static const for local tables
> Date: Fri, 7 Feb 2014 14:30:25 +0800 (CST)
>
> > diff --git a/source/Lib/TLibCommon/TComDataCU.cpp
> b/source/Lib/TLibCommon/TComDataCU.cpp
> > index 8b2636c..452a464 100644
> > --- a/source/Lib/TLibCommon/TComDataCU.cpp
> > +++ b/source/Lib/TLibCommon/TComDataCU.cpp
> > @@ -2194,13 +2194,16 @@ void
> TComDataCU::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, TC
> >      if (getSlice()->isInterB())
> >      {
> >          // TODO: TComRom??
> > -        uint32_t priorityList0[12] = { 0, 1, 0, 2, 1, 2, 0, 3, 1, 3, 2,
> 3 };
> > -        uint32_t priorityList1[12] = { 1, 0, 2, 0, 2, 1, 3, 0, 3, 1, 3,
> 2 };
> > +        uint32_t priorityList0 = 0xEDC984; // { 0, 1, 0, 2, 1, 2, 0, 3,
> 1, 3, 2, 3 }
> > +        uint32_t priorityList1 = 0xB73621; // { 1, 0, 2, 0, 2, 1, 3, 0,
> 3, 1, 3, 2 }
> >          for (int idx = 0; idx < cutoff * (cutoff - 1) && arrayAddr !=
> getSlice()->getMaxNumMergeCand(); idx
> >          {
> > -            int i = priorityList0[idx];
> > -            int j = priorityList1[idx];
> > +            int i = priorityList0 & 3;
> > +            int j = priorityList1 & 3;
> > +            priorityList0 >>= 2;
> > +            priorityList1 >>= 2;
> > +
> >              if (abCandIsInter[i] && abCandIsInter[j] &&
> (interDirNeighbours[i] & 0x1) && (interDirNeighbour
> >              {
> >                  abCandIsInter[arrayAddr] = true;
> >
> > At 2014-02-07 08:44:02,"Satoshi Nakagawa" <nakagawa424 at oki.com> wrote:
> >># HG changeset patch
> >># User Satoshi Nakagawa <nakagawa424 at oki.com>
> >># Date 1391733642 -32400
> >>#      Fri Feb 07 09:40:42 2014 +0900
> >># Node ID 0564ff2d14d17ec46ea27d5cb20a770c1b80144f
> >># Parent  40bec5582eca28ec0bc896e4e9412d580e42f4e4
> >>add static const for local tables
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>



-- 
Steve Borho
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20140209/a0b5f08f/attachment-0001.html>


More information about the x265-devel mailing list