[x265] [PATCH] search: add lowres MV into search mv candidate list for search ME
gopu at multicorewareinc.com
gopu at multicorewareinc.com
Wed May 13 09:09:09 CEST 2015
# HG changeset patch
# User Gopu Govindaswamy <gopu at multicorewareinc.com>
# Date 1431500901 -19800
# Wed May 13 12:38:21 2015 +0530
# Node ID a8addf6307f7da8d28857297d8de08b255e6610b
# Parent 6a8b7e35213670b6c4803bd1b1a0c16e57205968
search: add lowres MV into search mv candidate list for search ME
Add one more mv (lowres MV) into MV candidates list and this extra candidates
applicable only for depth 2, the lowres MV's are calculated 16x16 blocks
diff -r 6a8b7e352136 -r a8addf6307f7 source/encoder/search.cpp
--- a/source/encoder/search.cpp Tue May 12 10:45:38 2015 -0500
+++ b/source/encoder/search.cpp Wed May 13 12:38:21 2015 +0530
@@ -1930,9 +1930,9 @@
do
{
if (meId < m_slice->m_numRefIdx[0])
- slave.singleMotionEstimation(*this, pme.mode, pme.pu, pme.puIdx, 0, meId);
+ slave.singleMotionEstimation(*this, pme.mode, pme.pu, pme.puIdx, 0, meId, pme.cuGeom);
else
- slave.singleMotionEstimation(*this, pme.mode, pme.pu, pme.puIdx, 1, meId - m_slice->m_numRefIdx[0]);
+ slave.singleMotionEstimation(*this, pme.mode, pme.pu, pme.puIdx, 1, meId - m_slice->m_numRefIdx[0], pme.cuGeom);
meId = -1;
pme.m_lock.acquire();
@@ -1943,20 +1943,25 @@
while (meId >= 0);
}
-void Search::singleMotionEstimation(Search& master, Mode& interMode, const PredictionUnit& pu, int part, int list, int ref)
+void Search::singleMotionEstimation(Search& master, Mode& interMode, const PredictionUnit& pu, int part, int list, int ref, const CUGeom& cuGeom)
{
uint32_t bits = master.m_listSelBits[list] + MVP_IDX_BITS;
bits += getTUBits(ref, m_slice->m_numRefIdx[list]);
MotionData* bestME = interMode.bestME[part];
- MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];
+ // 12 mv candidates including lowresMV
+ MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 2];
int numMvc = interMode.cu.getPMV(interMode.interNeighbours, list, ref, interMode.amvpCand[list][ref], mvc);
const MV* amvp = interMode.amvpCand[list][ref];
int mvpIdx = selectMVP(interMode.cu, pu, amvp, list, ref);
MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
+ MV lmv = getLowresMV(interMode.cu, cuGeom, list);
+ if (lmv.notZero())
+ mvc[numMvc++] = lmv;
+
setSearchRange(interMode.cu, mvp, m_param->searchRange, mvmin, mvmax);
int satdCost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);
@@ -1990,7 +1995,8 @@
CUData& cu = interMode.cu;
Yuv* predYuv = &interMode.predYuv;
- MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 1];
+ // 12 mv candidates including lowresMV
+ MV mvc[(MD_ABOVE_LEFT + 1) * 2 + 2];
const Slice *slice = m_slice;
int numPart = cu.getNumPartInter();
@@ -2039,6 +2045,10 @@
int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
+ MV lmv = getLowresMV(cu, cuGeom, list);
+ if (lmv.notZero())
+ mvc[numMvc++] = lmv;
+
setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);
@@ -2070,7 +2080,7 @@
{
processPME(pme, *this);
- singleMotionEstimation(*this, interMode, pu, puIdx, 0, 0); /* L0-0 */
+ singleMotionEstimation(*this, interMode, pu, puIdx, 0, 0, cuGeom); /* L0-0 */
bDoUnidir = false;
@@ -2096,6 +2106,10 @@
int mvpIdx = selectMVP(cu, pu, amvp, list, ref);
MV mvmin, mvmax, outmv, mvp = amvp[mvpIdx];
+ MV lmv = getLowresMV(cu, cuGeom, list);
+ if (lmv.notZero())
+ mvc[numMvc++] = lmv;
+
setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
int satdCost = m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv);
@@ -3444,3 +3458,37 @@
cu.setQPSubParts(cu.getRefQP(0), 0, cuGeom.depth);
}
}
+
+MV Search::getLowresMV(const CUData& cu, const CUGeom& cuGeom, int list)
+{
+ MV lmv;
+ if (g_maxCUSize >> cuGeom.depth == 16)
+ {
+ int curPoc = m_slice->m_poc;
+ int refPoc = m_slice->m_refPicList[list][0]->m_poc;
+ int diffPoc = abs(curPoc - refPoc);
+
+ if (diffPoc <= m_param->bframes + 1)
+ {
+ MV *mv = m_frame->m_lowres.lowresMvs[list][diffPoc - 1];
+ uint32_t block_x = cu.m_cuPelX + g_zscanToPelX[cuGeom.absPartIdx];
+ uint32_t block_y = cu.m_cuPelY + g_zscanToPelY[cuGeom.absPartIdx];
+
+ /* number of blocks per row in lowres*/
+ uint32_t stride = (m_frame->m_fencPic->m_picWidth + (16 - 1)) / 16;
+
+ uint32_t idx = ((block_y / 16) * stride) + (block_x / 16);
+ /* check whether this motion search was performed by lookahead */
+ if (mv[idx].x != 0x7FFF)
+ lmv = mv[idx];
+ else
+ lmv = 0;
+ }
+ else
+ lmv = 0;
+ }
+ else
+ lmv = 0;
+
+ return lmv;
+}
diff -r 6a8b7e352136 -r a8addf6307f7 source/encoder/search.h
--- a/source/encoder/search.h Tue May 12 10:45:38 2015 -0500
+++ b/source/encoder/search.h Wed May 13 12:38:21 2015 +0530
@@ -319,6 +319,8 @@
void checkDQP(Mode& mode, const CUGeom& cuGeom);
void checkDQPForSplitPred(Mode& mode, const CUGeom& cuGeom);
+ MV getLowresMV(const CUData& cu, const CUGeom& cuGeom, int list);
+
class PME : public BondedTaskGroup
{
public:
@@ -339,7 +341,7 @@
};
void processPME(PME& pme, Search& slave);
- void singleMotionEstimation(Search& master, Mode& interMode, const PredictionUnit& pu, int part, int list, int ref);
+ void singleMotionEstimation(Search& master, Mode& interMode, const PredictionUnit& pu, int part, int list, int ref, const CUGeom& cuGeom);
protected:
More information about the x265-devel
mailing list