# HG changeset patch # User Ashok Kumar Mishra<as...@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 */ _______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel