<div style="font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0); line-height: 1.43;">From f47f95db0700d52897836787622628550742f476 Mon Sep 17 00:00:00 2001<br />
From: Mr-Z-2697 <74594146+Mr-Z-2697@users.noreply.github.com><br />
Date: Sun, 13 Jul 2025 16:09:53 +0800<br />
Subject: [PATCH] search.cpp: clip the best MV to ensure resulting mvdLX is<br />
compliant<br />
<br />
The value of the mvdLX should be in the range of [-2^15, 2^15-1], as specified in H.265 7.4.9.9 Motion vector difference semantics.<br />
However there was no safety check in this area, the mvdLX have been observed to exceed the range, under some rare circumstances.<br />
Due to the rare nature of the bug, this patch only does simple clipping, without further measures, to minimize the speed penalty.<br />
---<br />
source/encoder/search.cpp | 11 +++++++++++<br />
1 file changed, 11 insertions(+)<br />
<br />
diff --git a/source/encoder/search.cpp b/source/encoder/search.cpp<br />
index 0522f52cc..9dd409499 100644<br />
--- a/source/encoder/search.cpp<br />
+++ b/source/encoder/search.cpp<br />
@@ -2543,6 +2543,12 @@ void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChroma<br />
}<br />
}<br />
<br />
+ // to ensure the mvdLX is in the range of [-2^15, 2^15-1]<br />
+ MV clipmin((int32_t) -(1 << 15) , (int32_t) -(1 << 15) );<br />
+ MV clipmax((int32_t) (1 << 15) - 1, (int32_t) (1 << 15) - 1);<br />
+ bestME[0].mv = bestME[0].mv.clipped(bestME[0].mvp + clipmin, bestME[0].mvp + clipmax);<br />
+ bestME[1].mv = bestME[1].mv.clipped(bestME[1].mvp + clipmin, bestME[1].mvp + clipmax);<br />
+<br />
/* Bi-directional prediction */<br />
MotionData bidir[2];<br />
uint32_t bidirCost = MAX_UINT;<br />
@@ -2648,6 +2654,11 @@ void Search::predInterSearch(Mode& interMode, const CUGeom& cuGeom, bool bChroma<br />
bidirBits = bits0 + bits1 + m_listSelBits[2] - (m_listSelBits[0] + m_listSelBits[1]);<br />
}<br />
}<br />
+ // to ensure the mvdLX is in the range of [-2^15, 2^15-1]<br />
+ MV clipmin((int32_t) -(1 << 15) , (int32_t) -(1 << 15) );<br />
+ MV clipmax((int32_t) (1 << 15) - 1, (int32_t) (1 << 15) - 1);<br />
+ bidir[0].mv = bidir[0].mv.clipped(bidir[0].mvp + clipmin, bidir[0].mvp + clipmax);<br />
+ bidir[1].mv = bidir[1].mv.clipped(bidir[1].mvp + clipmin, bidir[1].mvp + clipmax);<br />
}<br />
<br />
/* select best option and store into CU */<br />
-- <br />
2.49.0.windows.1<br />
</div><div style="font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0); line-height: 1.43;"><br /></div>