[x265] [PATCH MV-HEVC 07/10] Add mv constraint

Anusuya Kumarasamy anusuya.kumarasamy at multicorewareinc.com
Tue Aug 6 10:49:40 UTC 2024


>From 9da061411f9e3ef18f4f111e808286de488e5cec Mon Sep 17 00:00:00 2001
From: AnusuyaKumarasamy <anusuya.kumarasamy at multicorewareinc.com>
Date: Fri, 12 Jul 2024 17:03:03 +0530
Subject: [PATCH] Add mv constraint

---
 source/encoder/frameencoder.cpp |  4 ++--
 source/encoder/motion.cpp       |  8 ++++++++
 source/encoder/motion.h         |  2 +-
 source/encoder/search.cpp       | 26 +++++++++++++++++++-------
 source/encoder/search.h         |  2 ++
 source/encoder/slicetype.cpp    |  4 ++--
 6 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/source/encoder/frameencoder.cpp
b/source/encoder/frameencoder.cpp
index 97d033fb6..19d61ec35 100644
--- a/source/encoder/frameencoder.cpp
+++ b/source/encoder/frameencoder.cpp
@@ -1159,8 +1159,8 @@ void FrameEncoder::compressFrame(int layer)
     /* rateControlEnd may also block for earlier frames to call
rateControlUpdateStats */
     if (!layer && m_top->m_rateControl->rateControlEnd(m_frame[layer],
m_accessUnitBits[layer], &m_rce, &filler) < 0)
         m_top->m_aborted = true;
-    if (layer)
-        m_frame[layer]->m_encData->m_avgQpAq =
m_frame[0]->m_encData->m_avgQpAq;
+    if (!layer)
+        m_frame[1]->m_encData->m_avgQpAq =
m_frame[layer]->m_encData->m_avgQpAq;

     if (filler > 0)
     {
diff --git a/source/encoder/motion.cpp b/source/encoder/motion.cpp
index 2bb613ec0..58e943652 100644
--- a/source/encoder/motion.cpp
+++ b/source/encoder/motion.cpp
@@ -770,6 +770,7 @@ int MotionEstimate::motionEstimate(ReferencePlanes *ref,
                                    int              merange,
                                    MV &             outQMv,
                                    uint32_t         maxSlices,
+                                    bool            m_vertRestriction,
                                    pixel *          srcReferencePlane)
 {
     ALIGN_VAR_16(int, costs[16]);
@@ -794,6 +795,13 @@ int MotionEstimate::motionEstimate(ReferencePlanes
*ref,

     // measure SAD cost at clipped QPEL MVP
     MV pmv = qmvp.clipped(qmvmin, qmvmax);
+    if (m_vertRestriction)
+    {
+        if (pmv.y > mvmax.y << 2)
+        {
+            pmv.y = (mvmax.y << 2);
+        }
+    }
     MV bestpre = pmv;
     int bprecost;

diff --git a/source/encoder/motion.h b/source/encoder/motion.h
index 790bc5fb4..c9fe86c82 100644
--- a/source/encoder/motion.h
+++ b/source/encoder/motion.h
@@ -95,7 +95,7 @@ public:
     }

     void refineMV(ReferencePlanes* ref, const MV& mvmin, const MV& mvmax,
const MV& qmvp, MV& outQMv);
-    int motionEstimate(ReferencePlanes* ref, const MV & mvmin, const MV &
mvmax, const MV & qmvp, int numCandidates, const MV * mvc, int merange, MV
& outQMv, uint32_t maxSlices, pixel *srcReferencePlane = 0);
+    int motionEstimate(ReferencePlanes* ref, const MV & mvmin, const MV &
mvmax, const MV & qmvp, int numCandidates, const MV * mvc, int merange, MV
& outQMv, uint32_t maxSlices, bool m_vertRestriction, pixel
*srcReferencePlane = 0);

     int subpelCompare(ReferencePlanes* ref, const MV &qmv, pixelcmp_t);

diff --git a/source/encoder/search.cpp b/source/encoder/search.cpp
index 9dc5f90c5..954ec54d2 100644
--- a/source/encoder/search.cpp
+++ b/source/encoder/search.cpp
@@ -2109,16 +2109,17 @@ void Search::singleMotionEstimation(Search& master,
Mode& interMode, const Predi
             mvp_lowres = lmv;
     }

+    m_vertRestriction = interMode.cu.m_slice->m_refPOCList[list][ref] ==
interMode.cu.m_slice->m_poc;
     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, m_param->maxSlices,
+    int satdCost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin,
mvmax, mvp, numMvc, mvc, m_param->searchRange, outmv, m_param->maxSlices,
m_vertRestriction,
       m_param->bSourceReferenceEstimation ?
m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);

     if (m_param->bEnableHME && mvp_lowres.notZero() && mvp_lowres != mvp)
     {
         MV outmv_lowres;
         setSearchRange(interMode.cu, mvp_lowres, m_param->searchRange,
mvmin, mvmax);
-        int lowresMvCost =
m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvp_lowres,
numMvc, mvc, m_param->searchRange, outmv_lowres, m_param->maxSlices,
+        int lowresMvCost =
m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax, mvp_lowres,
numMvc, mvc, m_param->searchRange, outmv_lowres, m_param->maxSlices,
m_vertRestriction,
             m_param->bSourceReferenceEstimation ?
m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
         if (lowresMvCost < satdCost)
         {
@@ -2168,8 +2169,9 @@ void Search::searchMV(Mode& interMode, int list, int
ref, MV& outmv, MV mvp[3],
         MV bestMV;
         mv = mvp[cand++];
         cu.clipMv(mv);
+        m_vertRestriction = cu.m_slice->m_refPOCList[list][ref] ==
cu.m_slice->m_poc;
         setSearchRange(cu, mv, m_param->searchRange, mvmin, mvmax);
-        int cost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin,
mvmax, mv, numMvc, mvc, m_param->searchRange, bestMV, m_param->maxSlices,
+        int cost = m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin,
mvmax, mv, numMvc, mvc, m_param->searchRange, bestMV, m_param->maxSlices,
m_vertRestriction,
         m_param->bSourceReferenceEstimation ?
m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
         if (bestcost > cost)
         {
@@ -2289,7 +2291,7 @@ void Search::predInterSearch(Mode& interMode, const
CUGeom& cuGeom, bool bChroma
                         if (cand && (mvpSel[cand] == mvpSel[cand - 1] ||
(cand == 2 && mvpSel[cand] == mvpSel[cand - 2])))
                             continue;
                         setSearchRange(cu, mvpSel[cand],
m_param->searchRange, mvmin, mvmax);
-                        int bcost =
m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax,
mvpSel[cand], numMvc, mvc, m_param->searchRange, bestmv, m_param->maxSlices,
+                        int bcost =
m_me.motionEstimate(&m_slice->m_mref[list][ref], mvmin, mvmax,
mvpSel[cand], numMvc, mvc, m_param->searchRange, bestmv,
m_param->maxSlices, m_vertRestriction,
                             m_param->bSourceReferenceEstimation ?
m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
                         if (satdCost > bcost)
                         {
@@ -2303,7 +2305,7 @@ void Search::predInterSearch(Mode& interMode, const
CUGeom& cuGeom, bool bChroma
                 }
                 else
                 {
-                    satdCost =
m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvpIn, numMvc,
mvc, m_param->searchRange, outmv, m_param->maxSlices,
+                    satdCost =
m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvpIn, numMvc,
mvc, m_param->searchRange, outmv, m_param->maxSlices, m_vertRestriction,
                         m_param->bSourceReferenceEstimation ?
m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
                 }

@@ -2427,15 +2429,16 @@ void Search::predInterSearch(Mode& interMode, const
CUGeom& cuGeom, bool bChroma
                         for (int planes = 0; planes < INTEGRAL_PLANE_NUM;
planes++)
                             m_me.integral[planes] =
interMode.fencYuv->m_integral[list][ref][planes] + puX * pu.width + puY *
pu.height * m_slice->m_refFrameList[list][ref]->m_reconPic->m_stride;
                     }
+                    m_vertRestriction =
cu.m_slice->m_refPOCList[list][ref] == cu.m_slice->m_poc;
                     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, m_param->maxSlices,
+                    int satdCost =
m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp, numMvc,
mvc, m_param->searchRange, outmv, m_param->maxSlices, m_vertRestriction,
                       m_param->bSourceReferenceEstimation ?
m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);

                     if (m_param->bEnableHME && mvp_lowres.notZero() &&
mvp_lowres != mvp)
                     {
                         MV outmv_lowres;
                         setSearchRange(cu, mvp_lowres,
m_param->searchRange, mvmin, mvmax);
-                        int lowresMvCost =
m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp_lowres,
numMvc, mvc, m_param->searchRange, outmv_lowres, m_param->maxSlices,
+                        int lowresMvCost =
m_me.motionEstimate(&slice->m_mref[list][ref], mvmin, mvmax, mvp_lowres,
numMvc, mvc, m_param->searchRange, outmv_lowres, m_param->maxSlices,
m_vertRestriction,
                             m_param->bSourceReferenceEstimation ?
m_slice->m_refFrameList[list][ref]->m_fencPic->getLumaAddr(0) : 0);
                         if (lowresMvCost < satdCost)
                         {
@@ -2729,6 +2732,15 @@ void Search::setSearchRange(const CUData& cu, const
MV& mvp, int merange, MV& mv
     mvmin = mvp - dist;
     mvmax = mvp + dist;

+    if (m_vertRestriction)
+    {
+        int mvRestricted = (56 - 1) << 2; // -1 to consider subpel search
+        if (mvmax.y >= mvRestricted)
+        {
+            mvmax.y = mvRestricted; //only positive side is restricted
+        }
+    }
+
     cu.clipMv(mvmin);
     cu.clipMv(mvmax);

diff --git a/source/encoder/search.h b/source/encoder/search.h
index 02bd6e647..ea3fae02f 100644
--- a/source/encoder/search.h
+++ b/source/encoder/search.h
@@ -286,6 +286,8 @@ public:
     int32_t         m_sliceMaxY;
     int32_t         m_sliceMinY;

+    bool            m_vertRestriction;
+
 #if DETAILED_CU_STATS
     /* Accumulate CU statistics separately for each frame encoder */
     CUStats         m_stats[X265_MAX_FRAME_THREADS];
diff --git a/source/encoder/slicetype.cpp b/source/encoder/slicetype.cpp
index 429f0b475..46c6dd4d5 100644
--- a/source/encoder/slicetype.cpp
+++ b/source/encoder/slicetype.cpp
@@ -4160,9 +4160,9 @@ void CostEstimateGroup::estimateCUCost(LookaheadTLD&
tld, int cuX, int cuY, int
         /* ME will never return a cost larger than the cost @MVP, so we do
not
          * have to check that ME cost is more than the estimated merge
cost */
         if(!hme)
-            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0,
NULL, searchRange, *fencMV, m_lookahead.m_param->maxSlices);
+            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0,
NULL, searchRange, *fencMV, m_lookahead.m_param->maxSlices, 0);
         else
-            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0,
NULL, searchRange, *fencMV, m_lookahead.m_param->maxSlices,
fref->lowerResPlane[0]);
+            fencCost = tld.me.motionEstimate(fref, mvmin, mvmax, mvp, 0,
NULL, searchRange, *fencMV, m_lookahead.m_param->maxSlices, 0,
fref->lowerResPlane[0]);
         if (skipCost < 64 && skipCost < fencCost && bBidir)
         {
             fencCost = skipCost;
-- 
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240806/a3cc8832/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0007-Add-mv-constraint.patch
Type: application/x-patch
Size: 11134 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240806/a3cc8832/attachment-0001.bin>


More information about the x265-devel mailing list