[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