[x265] improve getInterMergeCandidates() (Re: add static const for local tables)
Satoshi Nakagawa
nakagawa424 at oki.com
Sat Feb 8 14:59:41 CET 2014
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()
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
More information about the x265-devel
mailing list