[x265] [slices] fix multi-slices output non-determination bug
chen
chenm003 at 163.com
Tue Nov 1 16:19:55 CET 2016
2016-11-01 11:40:45,"Pradeep Ramachandran" <pradeep at multicorewareinc.com> :
On Mon, Oct 31, 2016 at 11:03 PM, chen <chenm003 at 163.com> wrote:
# HG changeset patch
# User Min Chen <min.chen at multicorewareinc.com>
# Date 1477935084 18000
# Node ID 9be03f08789954f772a50f26485a9c96ca745497
# Parent b08109b3701e9b86010c5a5ed0ad7b3d6a051911
[slices] fix multi-slices output non-determination bug
---
source/common/common.h | 2 +-
source/encoder/analysis.cpp | 8 +-
source/encoder/frameencoder.cpp | 15 ++---
source/encoder/motion.cpp | 116 +++++++++++++++++++++++++++-----------
source/encoder/sao.cpp | 7 ++
source/encoder/search.cpp | 3 +
6 files changed, 104 insertions(+), 47 deletions(-)
diff -r b08109b3701e -r 9be03f087899 source/common/common.h
--- a/source/common/common.hFri Oct 28 10:28:15 2016 +0800
+++ b/source/common/common.hMon Oct 31 12:31:24 2016 -0500
@@ -176,7 +176,7 @@
#define X265_MIN(a, b) ((a) < (b) ? (a) : (b))
#define X265_MAX(a, b) ((a) > (b) ? (a) : (b))
-#define COPY1_IF_LT(x, y) if ((y) < (x)) (x) = (y);
+#define COPY1_IF_LT(x, y) {if ((y) < (x)) (x) = (y);}
#define COPY2_IF_LT(x, y, a, b) \
if ((y) < (x)) \
{ \
diff -r b08109b3701e -r 9be03f087899 source/encoder/analysis.cpp
--- a/source/encoder/analysis.cppFri Oct 28 10:28:15 2016 +0800
+++ b/source/encoder/analysis.cppMon Oct 31 12:31:24 2016 -0500
@@ -1942,12 +1942,12 @@
if (m_param->maxSlices > 1)
{
// NOTE: First row in slice can't negative
- if ((candMvField[i][0].mv.y < m_sliceMinY) | (candMvField[i][1].mv.y < m_sliceMinY))
+ if (X265_MIN(candMvField[i][0].mv.y, candMvField[i][1].mv.y) < m_sliceMinY)
continue;
// Last row in slice can't reference beyond bound since it is another slice area
// TODO: we may beyond bound in future since these area have a chance to finish because we use parallel slices. Necessary prepare research on load balance
- if ((candMvField[i][0].mv.y > m_sliceMaxY) | (candMvField[i][1].mv.y > m_sliceMaxY))
+ if (X265_MAX(candMvField[i][0].mv.y, candMvField[i][1].mv.y) > m_sliceMaxY)
continue;
}
@@ -2072,12 +2072,12 @@
if (m_param->maxSlices > 1)
{
// NOTE: First row in slice can't negative
- if ((candMvField[i][0].mv.y < m_sliceMinY) | (candMvField[i][1].mv.y < m_sliceMinY))
+ if (X265_MIN(candMvField[i][0].mv.y, candMvField[i][1].mv.y) < m_sliceMinY)
continue;
// Last row in slice can't reference beyond bound since it is another slice area
// TODO: we may beyond bound in future since these area have a chance to finish because we use parallel slices. Necessary prepare research on load balance
- if ((candMvField[i][0].mv.y > m_sliceMaxY) | (candMvField[i][1].mv.y > m_sliceMaxY))
+ if (X265_MAX(candMvField[i][0].mv.y, candMvField[i][1].mv.y) > m_sliceMaxY)
continue;
}
diff -r b08109b3701e -r 9be03f087899 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cppFri Oct 28 10:28:15 2016 +0800
+++ b/source/encoder/frameencoder.cppMon Oct 31 12:31:24 2016 -0500
@@ -123,7 +123,7 @@
int range = m_param->searchRange; /* fpel search */
range += !!(m_param->searchMethod < 2); /* diamond/hex range check lag */
range += NTAPS_LUMA / 2; /* subpel filter half-length */
- range += 2 + MotionEstimate::hpelIterationCount(m_param->subpelRefine) / 2; /* subpel refine steps */
+ range += 2 + (MotionEstimate::hpelIterationCount(m_param->subpelRefine) + 1) / 2; /* subpel refine steps */
m_refLagRows = /*(m_param->maxSlices > 1 ? 1 : 0) +*/ 1 + ((range + g_maxCUSize - 1) / g_maxCUSize);
// NOTE: 2 times of numRows because both Encoder and Filter in same queue
@@ -654,8 +654,7 @@
const uint32_t sliceEndRow = m_sliceBaseRow[sliceId + 1] - 1;
const uint32_t row = sliceStartRow + rowInSlice;
- if (row >= m_numRows)
- break;
+ X265_CHECK(row < m_numRows, "slices row fault was detected");
if (row > sliceEndRow)
continue;
@@ -674,7 +673,7 @@
refpic->m_reconRowFlag[rowIdx].waitForChange(0);
if ((bUseWeightP || bUseWeightB) && m_mref[l][ref].isWeighted)
- m_mref[l][ref].applyWeight(row + m_refLagRows, m_numRows, sliceEndRow + 1, sliceId);
+ m_mref[l][ref].applyWeight(rowIdx, m_numRows, sliceEndRow, sliceId);
}
}
@@ -714,7 +713,7 @@
refpic->m_reconRowFlag[rowIdx].waitForChange(0);
if ((bUseWeightP || bUseWeightB) && m_mref[l][ref].isWeighted)
- m_mref[list][ref].applyWeight(i + m_refLagRows, m_numRows, m_numRows, 0);
+ m_mref[list][ref].applyWeight(rowIdx, m_numRows, m_numRows, 0);
}
}
@@ -1187,8 +1186,8 @@
// TODO: specially case handle on first and last row
// Initialize restrict on MV range in slices
- tld.analysis.m_sliceMinY = -(int16_t)(rowInSlice * g_maxCUSize * 4) + 2 * 4;
- tld.analysis.m_sliceMaxY = (int16_t)((endRowInSlicePlus1 - 1 - row) * (g_maxCUSize * 4) - 3 * 4);
+ tld.analysis.m_sliceMinY = -(int16_t)(rowInSlice * g_maxCUSize * 4) + 3 * 4;
+ tld.analysis.m_sliceMaxY = (int16_t)((endRowInSlicePlus1 - 1 - row) * (g_maxCUSize * 4) - 4 * 4);
// Handle single row slice
if (tld.analysis.m_sliceMaxY < tld.analysis.m_sliceMinY)
@@ -1502,7 +1501,7 @@
ScopedLock self(curRow.lock);
if ((m_bAllRowsStop && intRow > m_vbvResetTriggerRow) ||
- (!bFirstRowInSlice && ((curRow.completed < numCols - 1) || (m_rows[row - 1].completed < numCols)) && m_rows[row - 1].completed < m_rows[row].completed + 2))
+ (!bFirstRowInSlice && ((curRow.completed < numCols - 1) || (m_rows[row - 1].completed < numCols)) && m_rows[row - 1].completed < curRow.completed + 2))
{
curRow.active = false;
curRow.busy = false;
diff -r b08109b3701e -r 9be03f087899 source/encoder/motion.cpp
--- a/source/encoder/motion.cppFri Oct 28 10:28:15 2016 +0800
+++ b/source/encoder/motion.cppMon Oct 31 12:31:24 2016 -0500
@@ -278,10 +278,14 @@
costs[1] += mvcost((omv + MV(m1x, m1y)) << 2); \
costs[2] += mvcost((omv + MV(m2x, m2y)) << 2); \
costs[3] += mvcost((omv + MV(m3x, m3y)) << 2); \
- COPY2_IF_LT(bcost, costs[0], bmv, omv + MV(m0x, m0y)); \
- COPY2_IF_LT(bcost, costs[1], bmv, omv + MV(m1x, m1y)); \
- COPY2_IF_LT(bcost, costs[2], bmv, omv + MV(m2x, m2y)); \
- COPY2_IF_LT(bcost, costs[3], bmv, omv + MV(m3x, m3y)); \
+ if ((g_maxSlices == 1) | ((omv.y + m0y >= mvmin.y) & (omv.y + m0y <= mvmax.y))) \
+ COPY2_IF_LT(bcost, costs[0], bmv, omv + MV(m0x, m0y)); \
+ if ((g_maxSlices == 1) | ((omv.y + m1y >= mvmin.y) & (omv.y + m1y <= mvmax.y))) \
+ COPY2_IF_LT(bcost, costs[1], bmv, omv + MV(m1x, m1y)); \
+ if ((g_maxSlices == 1) | ((omv.y + m2y >= mvmin.y) & (omv.y + m2y <= mvmax.y))) \
+ COPY2_IF_LT(bcost, costs[2], bmv, omv + MV(m2x, m2y)); \
+ if ((g_maxSlices == 1) | ((omv.y + m3y >= mvmin.y) & (omv.y + m3y <= mvmax.y))) \
+ COPY2_IF_LT(bcost, costs[3], bmv, omv + MV(m3x, m3y)); \
Why do you need the `(g_maxSlices == 1) || ` in all the if conditions above? Isn't it safer to do this check for all cases, and not just for multiple slices-per-frame?
I want to keep non-slices mode output match to before.
diff -r b08109b3701e -r 9be03f087899 source/encoder/search.cpp
--- a/source/encoder/search.cppFri Oct 28 10:28:15 2016 +0800
+++ b/source/encoder/search.cppMon Oct 31 12:31:24 2016 -0500
@@ -2545,6 +2545,9 @@
/* conditional clipping for frame parallelism */
mvmin.y = X265_MIN(mvmin.y, (int16_t)m_refLagPixels);
mvmax.y = X265_MIN(mvmax.y, (int16_t)m_refLagPixels);
+
+ /* conditional clipping for negative mv range */
+ mvmax.y = X265_MAX(mvmax.y, mvmin.y);
}
I forgot add a condition here, so the output will be change in non-slices mode
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20161101/c35618a6/attachment-0001.html>
More information about the x265-devel
mailing list