[x265] [PATCH] improved getInerMergeCandidates(); cached MVs before finding merge candidates
ashok at multicorewareinc.com
ashok at multicorewareinc.com
Wed Mar 18 09:31:15 CET 2015
# HG changeset patch
# User Ashok Kumar Mishra<ashok at multicorewareinc.com>
# Date 1426661940 -19800
# Wed Mar 18 12:29:00 2015 +0530
# Node ID abd266927ba37f11e7f6751ad64dcd8d716e4fb9
# Parent ca0a4b2c53c54431a3b8471bbf4dadf6ee62c8c5
improved getInerMergeCandidates(); cached MVs before finding merge candidates
There is little performance improvement with the new function.
diff -r ca0a4b2c53c5 -r abd266927ba3 source/common/cudata.cpp
--- a/source/common/cudata.cpp Wed Mar 18 08:09:12 2015 +0530
+++ b/source/common/cudata.cpp Wed Mar 18 12:29:00 2015 +0530
@@ -1221,21 +1221,6 @@
outPartAddr = (partAddrTable[partType][partIdx] * m_numPartitions) >> 4;
}
-void CUData::getMvField(const CUData* cu, uint32_t absPartIdx, int picList, MVField& outMvField) const
-{
- if (cu)
- {
- outMvField.mv = cu->m_mv[picList][absPartIdx];
- outMvField.refIdx = cu->m_refIdx[picList][absPartIdx];
- }
- else
- {
- // OUT OF BOUNDARY
- outMvField.mv = 0;
- outMvField.refIdx = REF_NOT_VALID;
- }
-}
-
void CUData::deriveLeftRightTopIdx(uint32_t partIdx, uint32_t& partIdxLT, uint32_t& partIdxRT) const
{
partIdxLT = m_absIdxInCTU;
@@ -1357,17 +1342,17 @@
return outPartIdxRB;
}
-bool CUData::hasEqualMotion(uint32_t absPartIdx, const CUData& candCU, uint32_t candAbsPartIdx) const
+bool CUData::hasEqualMotion(InterNeighbourMV* cand1, InterNeighbourMV* cand2) const
{
- if (m_interDir[absPartIdx] != candCU.m_interDir[candAbsPartIdx])
+ if (cand1->interDir != cand2->interDir)
return false;
- for (uint32_t refListIdx = 0; refListIdx < 2; refListIdx++)
+ for (uint32_t refList = 0; refList < 2; refList++)
{
- if (m_interDir[absPartIdx] & (1 << refListIdx))
+ if (cand1->interDir & (1 << refList))
{
- if (m_mv[refListIdx][absPartIdx] != candCU.m_mv[refListIdx][candAbsPartIdx] ||
- m_refIdx[refListIdx][absPartIdx] != candCU.m_refIdx[refListIdx][candAbsPartIdx])
+ if (cand1->mv[refList] != cand2->mv[refList] ||
+ cand1->refIdx[refList] != cand2->refIdx[refList])
return false;
}
}
@@ -1376,10 +1361,10 @@
}
/* Construct list of merging candidates, returns count */
-uint32_t CUData::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MVField(*candMvField)[2], uint8_t* candDir) const
+uint32_t CUData::getInterMergeCandidates(uint32_t puIdx, MVField(*candMvField)[2], uint8_t* candDir, InterNeighbourMV *neighbours) const
{
- uint32_t absPartAddr = m_absIdxInCTU + absPartIdx;
const bool isInterB = m_slice->isInterB();
+ const int maxList = isInterB ? 2 : 1;
const uint32_t maxNumMergeCand = m_slice->m_maxNumMergeCand;
@@ -1405,86 +1390,75 @@
xP = ((tmp >> 4) * cuSize) >> 2;
yP = ((tmp & 0xF) * cuSize) >> 2;
+ int leftCUAvailable = ((0x3b >> partMode) & 1) | !puIdx;
+ int topCUAvailable = ((0xcd >> partMode) & 1) | !puIdx;
+
uint32_t count = 0;
-
- uint32_t partIdxLT, partIdxRT, partIdxLB = deriveLeftBottomIdx(puIdx);
- PartSize curPS = (PartSize)m_partSize[absPartIdx];
-
// left
- uint32_t leftPartIdx = 0;
- const CUData* cuLeft = getPULeft(leftPartIdx, partIdxLB);
- bool isAvailableA1 = cuLeft &&
- cuLeft->isDiffMER(xP - 1, yP + nPSH - 1, xP, yP) &&
- !(puIdx == 1 && (curPS == SIZE_Nx2N || curPS == SIZE_nLx2N || curPS == SIZE_nRx2N)) &&
- cuLeft->isInter(leftPartIdx);
+ bool isAvailableA1 = isDiffMER(xP - 1, yP + nPSH - 1, xP, yP) &&
+ !!leftCUAvailable && (neighbours[MD_LEFT].unifiedRef != -1);
if (isAvailableA1)
{
+ // get MV and reference idx from left CU
+ for (int i = 0; i < maxList; i++)
+ {
+ candMvField[count][i].mv = neighbours[MD_LEFT].mv[i];
+ candMvField[count][i].refIdx = neighbours[MD_LEFT].refIdx[i];
+ }
// get Inter Dir
- candDir[count] = cuLeft->m_interDir[leftPartIdx];
- // get Mv from Left
- cuLeft->getMvField(cuLeft, leftPartIdx, 0, candMvField[count][0]);
- if (isInterB)
- cuLeft->getMvField(cuLeft, leftPartIdx, 1, candMvField[count][1]);
+ candDir[count] = neighbours[MD_LEFT].interDir;
if (++count == maxNumMergeCand)
return maxNumMergeCand;
}
- deriveLeftRightTopIdx(puIdx, partIdxLT, partIdxRT);
-
// above
- uint32_t abovePartIdx = 0;
- const CUData* cuAbove = getPUAbove(abovePartIdx, partIdxRT);
- bool isAvailableB1 = cuAbove &&
- cuAbove->isDiffMER(xP + nPSW - 1, yP - 1, xP, yP) &&
- !(puIdx == 1 && (curPS == SIZE_2NxN || curPS == SIZE_2NxnU || curPS == SIZE_2NxnD)) &&
- cuAbove->isInter(abovePartIdx);
- if (isAvailableB1 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, *cuAbove, abovePartIdx)))
+ bool isAvailableB1 = isDiffMER(xP + nPSW - 1, yP - 1, xP, yP) &&
+ !!topCUAvailable && (neighbours[MD_ABOVE].unifiedRef != -1);
+ if (isAvailableB1 && (!isAvailableA1 || !hasEqualMotion(neighbours + MD_LEFT, neighbours + MD_ABOVE)))
{
+ // get MV and reference idx from above CU
+ for (int i = 0; i < maxList; i++)
+ {
+ candMvField[count][i].mv = neighbours[MD_ABOVE].mv[i];
+ candMvField[count][i].refIdx = neighbours[MD_ABOVE].refIdx[i];
+ }
// get Inter Dir
- candDir[count] = cuAbove->m_interDir[abovePartIdx];
- // get Mv from Left
- cuAbove->getMvField(cuAbove, abovePartIdx, 0, candMvField[count][0]);
- if (isInterB)
- cuAbove->getMvField(cuAbove, abovePartIdx, 1, candMvField[count][1]);
+ candDir[count] = neighbours[MD_ABOVE].interDir;
if (++count == maxNumMergeCand)
return maxNumMergeCand;
}
// above right
- uint32_t aboveRightPartIdx = 0;
- const CUData* cuAboveRight = getPUAboveRight(aboveRightPartIdx, partIdxRT);
- bool isAvailableB0 = cuAboveRight &&
- cuAboveRight->isDiffMER(xP + nPSW, yP - 1, xP, yP) &&
- cuAboveRight->isInter(aboveRightPartIdx);
- if (isAvailableB0 && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx, *cuAboveRight, aboveRightPartIdx)))
+ bool isAvailableB0 = isDiffMER(xP + nPSW, yP - 1, xP, yP) && (neighbours[MD_ABOVE_RIGHT].unifiedRef != -1);
+ if (isAvailableB0 && (!isAvailableB1 || !hasEqualMotion(neighbours + MD_ABOVE, neighbours + MD_ABOVE_RIGHT)))
{
+ // get MV and reference idx from above right
+ for (int i = 0; i < maxList; i++)
+ {
+ candMvField[count][i].mv = neighbours[MD_ABOVE_RIGHT].mv[i];
+ candMvField[count][i].refIdx = neighbours[MD_ABOVE_RIGHT].refIdx[i];
+ }
// get Inter Dir
- candDir[count] = cuAboveRight->m_interDir[aboveRightPartIdx];
- // get Mv from Left
- cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, 0, candMvField[count][0]);
- if (isInterB)
- cuAboveRight->getMvField(cuAboveRight, aboveRightPartIdx, 1, candMvField[count][1]);
+ candDir[count] = neighbours[MD_ABOVE_RIGHT].interDir;
if (++count == maxNumMergeCand)
return maxNumMergeCand;
}
// left bottom
- uint32_t leftBottomPartIdx = 0;
- const CUData* cuLeftBottom = this->getPUBelowLeft(leftBottomPartIdx, partIdxLB);
- bool isAvailableA0 = cuLeftBottom &&
- cuLeftBottom->isDiffMER(xP - 1, yP + nPSH, xP, yP) &&
- cuLeftBottom->isInter(leftBottomPartIdx);
- if (isAvailableA0 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, *cuLeftBottom, leftBottomPartIdx)))
+ bool isAvailableA0 = isDiffMER(xP - 1, yP + nPSH, xP, yP) && (neighbours[MD_BELOW_LEFT].unifiedRef != -1);
+ if (isAvailableA0 && (!isAvailableA1 || !hasEqualMotion(neighbours + MD_LEFT, neighbours + MD_BELOW_LEFT)))
{
+ // get MV and reference idx from left bottom
+ for (int i = 0; i < maxList; i++)
+ {
+ candMvField[count][i].mv = neighbours[MD_BELOW_LEFT].mv[i];
+ candMvField[count][i].refIdx = neighbours[MD_BELOW_LEFT].refIdx[i];
+ }
// get Inter Dir
- candDir[count] = cuLeftBottom->m_interDir[leftBottomPartIdx];
- // get Mv from Left
- cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, 0, candMvField[count][0]);
- if (isInterB)
- cuLeftBottom->getMvField(cuLeftBottom, leftBottomPartIdx, 1, candMvField[count][1]);
+ candDir[count] = neighbours[MD_BELOW_LEFT].interDir;
if (++count == maxNumMergeCand)
return maxNumMergeCand;
@@ -1493,83 +1467,53 @@
// above left
if (count < 4)
{
- uint32_t aboveLeftPartIdx = 0;
- const CUData* cuAboveLeft = getPUAboveLeft(aboveLeftPartIdx, absPartAddr);
- bool isAvailableB2 = cuAboveLeft &&
- cuAboveLeft->isDiffMER(xP - 1, yP - 1, xP, yP) &&
- cuAboveLeft->isInter(aboveLeftPartIdx);
- if (isAvailableB2 && (!isAvailableA1 || !cuLeft->hasEqualMotion(leftPartIdx, *cuAboveLeft, aboveLeftPartIdx))
- && (!isAvailableB1 || !cuAbove->hasEqualMotion(abovePartIdx, *cuAboveLeft, aboveLeftPartIdx)))
+ bool isAvailableB2 = isDiffMER(xP - 1, yP - 1, xP, yP) && (neighbours[MD_ABOVE_LEFT].unifiedRef != -1);
+ if (isAvailableB2 && (!isAvailableA1 || !hasEqualMotion(neighbours + MD_LEFT, neighbours + MD_ABOVE_LEFT))
+ && (!isAvailableB1 || !hasEqualMotion(neighbours + MD_ABOVE, neighbours + MD_ABOVE_LEFT)))
{
+ // get MV and reference idx from above left
+ for (int i = 0; i < maxList; i++)
+ {
+ candMvField[count][i].mv = neighbours[MD_ABOVE_LEFT].mv[i];
+ candMvField[count][i].refIdx = neighbours[MD_ABOVE_LEFT].refIdx[i];
+ }
// get Inter Dir
- candDir[count] = cuAboveLeft->m_interDir[aboveLeftPartIdx];
- // get Mv from Left
- cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, 0, candMvField[count][0]);
- if (isInterB)
- cuAboveLeft->getMvField(cuAboveLeft, aboveLeftPartIdx, 1, candMvField[count][1]);
-
- if (++count == maxNumMergeCand)
- return maxNumMergeCand;
- }
- }
- if (m_slice->m_sps->bTemporalMVPEnabled)
- {
- uint32_t partIdxRB = deriveRightBottomIdx(puIdx);
- MV colmv;
- int ctuIdx = -1;
-
- // image boundary check
- if (m_encData->getPicCTU(m_cuAddr)->m_cuPelX + g_zscanToPelX[partIdxRB] + UNIT_SIZE < m_slice->m_sps->picWidthInLumaSamples &&
- m_encData->getPicCTU(m_cuAddr)->m_cuPelY + g_zscanToPelY[partIdxRB] + UNIT_SIZE < m_slice->m_sps->picHeightInLumaSamples)
- {
- uint32_t absPartIdxRB = g_zscanToRaster[partIdxRB];
- uint32_t numUnits = s_numPartInCUSize;
- bool bNotLastCol = lessThanCol(absPartIdxRB, numUnits - 1, numUnits); // is not at the last column of CTU
- bool bNotLastRow = lessThanRow(absPartIdxRB, numUnits - 1, numUnits); // is not at the last row of CTU
-
- if (bNotLastCol && bNotLastRow)
- {
- absPartAddr = g_rasterToZscan[absPartIdxRB + numUnits + 1];
- ctuIdx = m_cuAddr;
- }
- else if (bNotLastCol)
- absPartAddr = g_rasterToZscan[(absPartIdxRB + numUnits + 1) & (numUnits - 1)];
- else if (bNotLastRow)
- {
- absPartAddr = g_rasterToZscan[absPartIdxRB + 1];
- ctuIdx = m_cuAddr + 1;
- }
- else // is the right bottom corner of CTU
- absPartAddr = 0;
- }
-
- int maxList = isInterB ? 2 : 1;
- int dir = 0, refIdx = 0;
- for (int list = 0; list < maxList; list++)
- {
- bool bExistMV = ctuIdx >= 0 && getColMVP(colmv, refIdx, list, ctuIdx, absPartAddr);
- if (!bExistMV)
- {
- uint32_t partIdxCenter = deriveCenterIdx(puIdx);
- bExistMV = getColMVP(colmv, refIdx, list, m_cuAddr, partIdxCenter);
- }
- if (bExistMV)
- {
- dir |= (1 << list);
- candMvField[count][list].mv = colmv;
- candMvField[count][list].refIdx = refIdx;
- }
- }
-
- if (dir != 0)
- {
- candDir[count] = (uint8_t)dir;
+ candDir[count] = neighbours[MD_ABOVE_LEFT].interDir;
if (++count == maxNumMergeCand)
return maxNumMergeCand;
}
}
+ if ((m_slice->m_sps->bTemporalMVPEnabled) && (neighbours[MD_COLLOCATED].unifiedRef != -1))
+ {
+ int16_t dir = 0, refIdx = 0;
+ for (int picList = 0; picList < maxList; picList++)
+ {
+ uint32_t cuAddr = neighbours[MD_COLLOCATED].cuAddr[picList];
+ const Frame* colPic = m_slice->m_refPicList[m_slice->isInterB() && !m_slice->m_colFromL0Flag][m_slice->m_colRefIdx];
+ const CUData* colCU = colPic->m_encData->getPicCTU(cuAddr);
+
+ // Scale the vector
+ int tempRefIdx = neighbours[MD_COLLOCATED].refIdx[picList];
+ int colRefPOC = colCU->m_slice->m_refPOCList[tempRefIdx >> 4][tempRefIdx & 0xf];
+ int colPOC = colCU->m_slice->m_poc;
+
+ int curRefPOC = m_slice->m_refPOCList[picList][refIdx];
+ int curPOC = m_slice->m_poc;
+
+ candMvField[count][picList].mv = scaleMvByPOCDist(neighbours[MD_COLLOCATED].mv[picList], curPOC, curRefPOC, colPOC, colRefPOC);
+
+ dir |= (1 << picList);
+ candDir[count] = (uint8_t)dir;
+ candMvField[count][picList].refIdx = refIdx;
+ }
+
+ if (++count == maxNumMergeCand)
+ return maxNumMergeCand;
+ }
+
+ // Create new candidates by mixing the previous ones.
if (isInterB)
{
const uint32_t cutoff = count * (count - 1);
@@ -1586,6 +1530,7 @@
// get Mv from cand[i] and cand[j]
int refIdxL0 = candMvField[i][0].refIdx;
int refIdxL1 = candMvField[j][1].refIdx;
+
int refPOCL0 = m_slice->m_refPOCList[0][refIdxL0];
int refPOCL1 = m_slice->m_refPOCList[1][refIdxL1];
if (!(refPOCL0 == refPOCL1 && candMvField[i][0].mv == candMvField[j][1].mv))
@@ -1602,31 +1547,30 @@
}
}
}
- int numRefIdx = (isInterB) ? X265_MIN(m_slice->m_numRefIdx[0], m_slice->m_numRefIdx[1]) : m_slice->m_numRefIdx[0];
- int r = 0;
- int refcnt = 0;
+
+ int maxIdx = (isInterB) ? X265_MIN(m_slice->m_numRefIdx[0], m_slice->m_numRefIdx[1]) : m_slice->m_numRefIdx[0];
+ for (int i = 0; i < maxIdx; i++)
+ {
+ candDir[count] = isInterB ? 3 : 1;
+ candMvField[count][0].mv.word = 0;
+ candMvField[count][1].mv.word = 0;
+ candMvField[count][0].refIdx = i;
+ candMvField[count][1].refIdx = isInterB ? i : -1;
+
+ if (++count == maxNumMergeCand)
+ return maxNumMergeCand;
+ }
+
+ // Generate null motion vector with reference index 0.
while (count < maxNumMergeCand)
{
- candDir[count] = 1;
+ candDir[count] = isInterB ? 3 : 1;
candMvField[count][0].mv.word = 0;
- candMvField[count][0].refIdx = r;
-
- if (isInterB)
- {
- candDir[count] = 3;
- candMvField[count][1].mv.word = 0;
- candMvField[count][1].refIdx = r;
- }
+ candMvField[count][1].mv.word = 0;
+ candMvField[count][0].refIdx = 0;
+ candMvField[count][1].refIdx = isInterB ? 0 : -1;
count++;
-
- if (refcnt == numRefIdx - 1)
- r = 0;
- else
- {
- ++r;
- ++refcnt;
- }
}
return count;
@@ -1822,12 +1766,12 @@
for (int i = 0; i < 2; i++)
{
- // Get the MV.
+ // Get MV and reference idx.
neighbour->mv[i] = tmpCU->m_mv[i][idx];
-
- // Get the reference idx.
neighbour->refIdx[i] = tmpCU->m_refIdx[i][idx];
}
+
+ neighbour->interDir = tmpCU->m_interDir[idx];
}
void CUData::clipMv(MV& outMV) const
@@ -1883,40 +1827,6 @@
return false;
}
-bool CUData::getColMVP(MV& outMV, int& outRefIdx, int picList, int cuAddr, int partUnitIdx) const
-{
- const Frame* colPic = m_slice->m_refPicList[m_slice->isInterB() && !m_slice->m_colFromL0Flag][m_slice->m_colRefIdx];
- const CUData* colCU = colPic->m_encData->getPicCTU(cuAddr);
-
- uint32_t absPartAddr = partUnitIdx & TMVP_UNIT_MASK;
- if (colCU->m_predMode[partUnitIdx] == MODE_NONE || colCU->isIntra(absPartAddr))
- return false;
-
- int colRefPicList = m_slice->m_bCheckLDC ? picList : m_slice->m_colFromL0Flag;
-
- int colRefIdx = colCU->m_refIdx[colRefPicList][absPartAddr];
-
- if (colRefIdx < 0)
- {
- colRefPicList = !colRefPicList;
- colRefIdx = colCU->m_refIdx[colRefPicList][absPartAddr];
-
- if (colRefIdx < 0)
- return false;
- }
-
- // Scale the vector
- int colRefPOC = colCU->m_slice->m_refPOCList[colRefPicList][colRefIdx];
- int colPOC = colCU->m_slice->m_poc;
- MV colmv = colCU->m_mv[colRefPicList][absPartAddr];
-
- int curRefPOC = m_slice->m_refPOCList[picList][outRefIdx];
- int curPOC = m_slice->m_poc;
-
- outMV = scaleMvByPOCDist(colmv, curPOC, curRefPOC, colPOC, colRefPOC);
- return true;
-}
-
// Cache the collocated MV.
bool CUData::getCollocatedMV(int cuAddr, int partUnitIdx, InterNeighbourMV *neighbour) const
{
diff -r ca0a4b2c53c5 -r abd266927ba3 source/common/cudata.h
--- a/source/common/cudata.h Wed Mar 18 08:09:12 2015 +0530
+++ b/source/common/cudata.h Wed Mar 18 12:29:00 2015 +0530
@@ -98,6 +98,8 @@
// Structure that keeps the neighbour's MV information.
struct InterNeighbourMV
{
+ // Neighbour inter dir.
+ uint8_t interDir;
// Neighbour MV. The index represents the list.
MV mv[2];
@@ -216,7 +218,7 @@
uint8_t getCbf(uint32_t absPartIdx, TextType ttype, uint32_t tuDepth) const { return (m_cbf[ttype][absPartIdx] >> tuDepth) & 0x1; }
uint8_t getQtRootCbf(uint32_t absPartIdx) const { return m_cbf[0][absPartIdx] || m_cbf[1][absPartIdx] || m_cbf[2][absPartIdx]; }
int8_t getRefQP(uint32_t currAbsIdxInCTU) const;
- uint32_t getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx, MVField (*candMvField)[2], uint8_t* candDir) const;
+ uint32_t getInterMergeCandidates(uint32_t puIdx, MVField (*candMvField)[2], uint8_t* candDir, InterNeighbourMV *neighbours) const;
void clipMv(MV& outMV) const;
int getPMV(InterNeighbourMV *neighbours, uint32_t reference_list, uint32_t refIdx, MV* amvpCand, MV* pmv) const;
void getNeighbourMV(uint32_t puIdx, uint32_t absPartIdx, InterNeighbourMV* neighbours) const;
@@ -260,23 +262,18 @@
int8_t getLastCodedQP(uint32_t absPartIdx) const;
int getLastValidPartIdx(int absPartIdx) const;
- bool hasEqualMotion(uint32_t absPartIdx, const CUData& candCU, uint32_t candAbsPartIdx) const;
-
/* Check whether the current PU and a spatial neighboring PU are in same merge region */
bool isDiffMER(int xN, int yN, int xP, int yP) const { return ((xN >> 2) != (xP >> 2)) || ((yN >> 2) != (yP >> 2)); }
+ bool hasEqualMotion(InterNeighbourMV* cand1, InterNeighbourMV* cand2) const;
// add possible motion vector predictor candidates
bool getDirectPMV(MV& pmv, InterNeighbourMV *neighbours, uint32_t picList, uint32_t refIdx) const;
bool getIndirectPMV(MV& outMV, InterNeighbourMV *neighbours, uint32_t reference_list, uint32_t refIdx) const;
void getInterNeighbourMV(InterNeighbourMV *neighbour, uint32_t partUnitIdx, MVP_DIR dir) const;
-
- bool getColMVP(MV& outMV, int& outRefIdx, int picList, int cuAddr, int absPartIdx) const;
bool getCollocatedMV(int cuAddr, int partUnitIdx, InterNeighbourMV *neighbour) const;
-
- MV scaleMvByPOCDist(const MV& inMV, int curPOC, int curRefPOC, int colPOC, int colRefPOC) const;
+ MV scaleMvByPOCDist(const MV& inMV, int curPOC, int curRefPOC, int colPOC, int colRefPOC) const;
void deriveLeftRightTopIdx(uint32_t puIdx, uint32_t& partIdxLT, uint32_t& partIdxRT) const;
-
uint32_t deriveCenterIdx(uint32_t puIdx) const;
uint32_t deriveRightBottomIdx(uint32_t puIdx) const;
uint32_t deriveLeftBottomIdx(uint32_t puIdx) const;
diff -r ca0a4b2c53c5 -r abd266927ba3 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cpp Wed Mar 18 08:09:12 2015 +0530
+++ b/source/encoder/analysis.cpp Wed Mar 18 12:29:00 2015 +0530
@@ -1216,9 +1216,12 @@
bestPred->cu.setPredModeSubParts(MODE_INTER);
bestPred->cu.m_mergeFlag[0] = true;
+ merge.cu.getNeighbourMV(0, 0, merge.interNeighbours);
+
MVField candMvField[MRG_MAX_NUM_CANDS][2]; // double length for mv of both lists
uint8_t candDir[MRG_MAX_NUM_CANDS];
- uint32_t numMergeCand = tempPred->cu.getInterMergeCandidates(0, 0, candMvField, candDir);
+ uint32_t numMergeCand = tempPred->cu.getInterMergeCandidates(0, candMvField, candDir, merge.interNeighbours);
+
PredictionUnit pu(merge.cu, cuGeom, 0);
bestPred->sa8dCost = MAX_INT64;
@@ -1317,9 +1320,11 @@
skip.cu.setPartSizeSubParts(SIZE_2Nx2N);
skip.cu.m_mergeFlag[0] = true;
+ merge.cu.getNeighbourMV(0, 0, merge.interNeighbours);
+
MVField candMvField[MRG_MAX_NUM_CANDS][2]; // double length for mv of both lists
uint8_t candDir[MRG_MAX_NUM_CANDS];
- uint32_t numMergeCand = merge.cu.getInterMergeCandidates(0, 0, candMvField, candDir);
+ uint32_t numMergeCand = merge.cu.getInterMergeCandidates(0, candMvField, candDir, merge.interNeighbours);
PredictionUnit pu(merge.cu, cuGeom, 0);
bool foundCbf0Merge = false;
diff -r ca0a4b2c53c5 -r abd266927ba3 source/encoder/search.cpp
--- a/source/encoder/search.cpp Wed Mar 18 08:09:12 2015 +0530
+++ b/source/encoder/search.cpp Wed Mar 18 12:29:00 2015 +0530
@@ -1808,13 +1808,16 @@
}
/* estimation of best merge coding of an inter PU (2Nx2N merge PUs are evaluated as their own mode) */
-uint32_t Search::mergeEstimation(CUData& cu, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m)
+uint32_t Search::mergeEstimation(Mode& interMode, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m)
{
+ CUData& cu = interMode.cu;
X265_CHECK(cu.m_partSize[0] != SIZE_2Nx2N, "mergeEstimation() called for 2Nx2N\n");
+ interMode.cu.getNeighbourMV(puIdx, pu.puAbsPartIdx, interMode.interNeighbours);
+
MVField candMvField[MRG_MAX_NUM_CANDS][2];
uint8_t candDir[MRG_MAX_NUM_CANDS];
- uint32_t numMergeCand = cu.getInterMergeCandidates(pu.puAbsPartIdx, puIdx, candMvField, candDir);
+ uint32_t numMergeCand = cu.getInterMergeCandidates(puIdx, candMvField, candDir, interMode.interNeighbours);
if (cu.isBipredRestriction())
{
@@ -2021,7 +2024,7 @@
/* find best cost merge candidate. note: 2Nx2N merge and bidir are handled as separate modes */
if (cu.m_partSize[0] != SIZE_2Nx2N)
{
- mrgCost = mergeEstimation(cu, cuGeom, pu, puIdx, merge);
+ mrgCost = mergeEstimation(interMode, cuGeom, pu, puIdx, merge);
if (bMergeOnly && mrgCost != MAX_UINT)
{
diff -r ca0a4b2c53c5 -r abd266927ba3 source/encoder/search.h
--- a/source/encoder/search.h Wed Mar 18 08:09:12 2015 +0530
+++ b/source/encoder/search.h Wed Mar 18 12:29:00 2015 +0530
@@ -371,7 +371,7 @@
/* inter/ME helper functions */
void checkBestMVP(MV* amvpCand, MV cMv, MV& mvPred, int& mvpIdx, uint32_t& outBits, uint32_t& outCost) const;
void setSearchRange(const CUData& cu, MV mvp, int merange, MV& mvmin, MV& mvmax) const;
- uint32_t mergeEstimation(CUData& cu, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m);
+ uint32_t mergeEstimation(Mode& interMode, const CUGeom& cuGeom, const PredictionUnit& pu, int puIdx, MergeData& m);
static void getBlkBits(PartSize cuMode, bool bPSlice, int puIdx, uint32_t lastMode, uint32_t blockBit[3]);
/* intra helper functions */
More information about the x265-devel
mailing list