[x265] [PATCH] improved getInerMergeCandidates(); cached MVs before finding merge candidates
Steve Borho
steve at borho.org
Wed Mar 18 17:14:21 CET 2015
On 03/18, ashok at multicorewareinc.com wrote:
> # 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.
queeud for testing
> 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 */
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
--
Steve Borho
More information about the x265-devel
mailing list