[x265] [PATCH] search: add lowres MV into search mv candidate list for search ME
Steve Borho
steve at borho.org
Wed May 13 17:16:12 CEST 2015
On 05/13, gopu at multicorewareinc.com wrote:
> # 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);
if you're going to add cuGeom to this function, add it between mode and
the PU arguments.
>
> 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;
this 0 needs to be ref
> + 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;
the lookahead calculates this stride as:
m_8x8Width = ((m_param->sourceWidth / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
It might end up being the same, but I'm not certain
> +
> + 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];
only the lowres MV at idx 0 is initialized to 0x7fff to signify the
motion search has not been performed (for the whole picture). See
Lowres::init()
> + else
> + lmv = 0;
> + }
> + else
> + lmv = 0;
> + }
> + else
> + lmv = 0;
rather than having three else clauses, lmv could be initialized to 0. in
fact, I think MV still has a default constructor that sets it to zero,
but it is still better to be explicit.
> + 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:
>
> _______________________________________________
> 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