<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>