Hi Richard,
There are parallelism restrict, interpolate can't across slice boundary. The range [-16,+12] is integer pixel [-4,+3], if MV Y-axis in this range, the interpolate may generate incorrect result. There have some special point interpolate in Horizontal direction only, but it is less probability to choice as best MV, so just check ZeroMv enough. Regards Chen At 2025-03-17 23:12:32, "Richard" <ccc7...@foxmail.com> wrote: Zero MV is only one special case of the problem. The code of MV restriction calculation: tld.analysis.m_sliceMinY = -(int32_t)(rowInSlice * m_param->maxCUSize * 4) + 3 * 4; tld.analysis.m_sliceMaxY = (int32_t)((endRowInSlicePlus1 - 1 - row) * (m_param->maxCUSize * 4) - 4 * 4); The constants will cause MVs to be restricted to >12 or <-16 in slice boundaries. example: minY: -2036, maxY: -16 or minY: 12, maxY: 1776 So any MV that has its Y-axis in the range of -16 to 12 will have problem. Original From baff7691e9bc4f93bccc85ae78d95ad9ade7a8d0 Mon Sep 17 00:00:00 2001 From: Min Chen <chenm...@163.com> Date: Fri, 14 Mar 2025 22:27:02 -0700 Subject: [PATCH] Improve Slices option with check zeroMv --- source/encoder/analysis.cpp | 4 ++-- source/encoder/motion.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/source/encoder/analysis.cpp b/source/encoder/analysis.cpp index 5475e4800..e3c410e59 100644 --- a/source/encoder/analysis.cpp +++ b/source/encoder/analysis.cpp @@ -3166,7 +3166,7 @@ void Analysis::checkMerge2Nx2N_rd0_4(Mode& skip, Mode& merge, const CUGeom& cuGe } for (uint32_t i = 0; i < numMergeCand; ++i) { - if (m_bFrameParallel) + if (m_bFrameParallel && candMvField[i][0].mv.notZero()) { // Parallel slices bound check if (m_param->maxSlices > 1) @@ -3300,7 +3300,7 @@ void Analysis::checkMerge2Nx2N_rd5_6(Mode& skip, Mode& merge, const CUGeom& cuGe } for (uint32_t i = 0; i < numMergeCand; i++) { - if (m_bFrameParallel) + if (m_bFrameParallel && candMvField[i][0].mv.notZero()) { // Parallel slices bound check if (m_param->maxSlices > 1) diff --git a/source/encoder/motion.cpp b/source/encoder/motion.cpp index 58e943652..86f413c3d 100644 --- a/source/encoder/motion.cpp +++ b/source/encoder/motion.cpp @@ -1596,6 +1596,14 @@ me_hex2: // check mv range for slice bound X265_CHECK(((bmv.y >= qmvmin.y) & (bmv.y <= qmvmax.y)), "mv beyond range!"); + // Get a chance to ZeroMv + if (bmv.notZero()) + { + int cost = subpelCompare(ref, MV(0, 0), satd) + mvcost(MV(0, 0)); + if (cost <= bcost) + bmv = MV(0, 0); + } + x265_emms(); outQMv = bmv; return bcost; -- 2.43.0.windows.1
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel