<div dir="ltr"><div dir="ltr"># HG changeset patch<br># User Masaharu Tamura <<a href="mailto:tamura@pegasys-inc.com" target="_blank">tamura@pegasys-inc.com</a>><br># Date 1553818841 -32400<br># Fri Mar 29 09:20:41 2019 +0900<br># Node ID 0018ca1ca42f1c91422b9a78091967cc45bb944c<br># Parent 3e5032228123c1898d408a30e45ac15eb687ffb6<br>Fix MV Wrap-around<br></div><div dir="ltr"><br></div><div>Pushed to default branch of x265.</div><div><br></div><div>Thanks & Regards,</div><div>Dinesh</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 29, 2019 at 5:53 AM <<a href="mailto:tamura@pegasys-inc.com">tamura@pegasys-inc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># HG changeset patch<br>
# User Masaharu Tamura <<a href="mailto:tamura@pegasys-inc.com" target="_blank">tamura@pegasys-inc.com</a>><br>
# Date 1553818841 -32400<br>
# Fri Mar 29 09:20:41 2019 +0900<br>
# Node ID 0018ca1ca42f1c91422b9a78091967cc45bb944c<br>
# Parent 3e5032228123c1898d408a30e45ac15eb687ffb6<br>
Fix MV Wrap-around<br>
<br>
Fixed that wrap-around from MV structure overflow occurred around 8K pixels or over.<br>
<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/CMakeLists.txt<br>
--- a/source/CMakeLists.txt Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/CMakeLists.txt Fri Mar 29 09:20:41 2019 +0900<br>
@@ -29,7 +29,7 @@<br>
option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)<br>
mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)<br>
# X265_BUILD must be incremented each time the public API is changed<br>
-set(X265_BUILD 172)<br>
+set(X265_BUILD 173)<br>
configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>"<br>
"${PROJECT_BINARY_DIR}/x265.def")<br>
configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265_config.h.in" rel="noreferrer" target="_blank">x265_config.h.in</a>"<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/common/cudata.cpp<br>
--- a/source/common/cudata.cpp Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/common/cudata.cpp Fri Mar 29 09:20:41 2019 +0900<br>
@@ -106,7 +106,7 @@<br>
int mvx = x265_clip3(-32768, 32767, (scale * mv.x + 127 + (scale * mv.x < 0)) >> 8);<br>
int mvy = x265_clip3(-32768, 32767, (scale * mv.y + 127 + (scale * mv.y < 0)) >> 8);<br>
<br>
- return MV((int16_t)mvx, (int16_t)mvy);<br>
+ return MV((int32_t)mvx, (int32_t)mvy);<br>
}<br>
<br>
}<br>
@@ -1917,11 +1917,11 @@<br>
const uint32_t mvshift = 2;<br>
uint32_t offset = 8;<br>
<br>
- int16_t xmax = (int16_t)((m_slice->m_sps->picWidthInLumaSamples + offset - m_cuPelX - 1) << mvshift);<br>
- int16_t xmin = -(int16_t)((m_encData->m_param->maxCUSize + offset + m_cuPelX - 1) << mvshift);<br>
+ int32_t xmax = (int32_t)((m_slice->m_sps->picWidthInLumaSamples + offset - m_cuPelX - 1) << mvshift);<br>
+ int32_t xmin = -(int32_t)((m_encData->m_param->maxCUSize + offset + m_cuPelX - 1) << mvshift);<br>
<br>
- int16_t ymax = (int16_t)((m_slice->m_sps->picHeightInLumaSamples + offset - m_cuPelY - 1) << mvshift);<br>
- int16_t ymin = -(int16_t)((m_encData->m_param->maxCUSize + offset + m_cuPelY - 1) << mvshift);<br>
+ int32_t ymax = (int32_t)((m_slice->m_sps->picHeightInLumaSamples + offset - m_cuPelY - 1) << mvshift);<br>
+ int32_t ymin = -(int32_t)((m_encData->m_param->maxCUSize + offset + m_cuPelY - 1) << mvshift);<br>
<br>
outMV.x = X265_MIN(xmax, X265_MAX(xmin, outMV.x));<br>
outMV.y = X265_MIN(ymax, X265_MAX(ymin, outMV.y));<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/common/mv.h<br>
--- a/source/common/mv.h Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/common/mv.h Fri Mar 29 09:20:41 2019 +0900<br>
@@ -39,16 +39,16 @@<br>
public:<br>
<br>
union {<br>
- struct { int16_t x, y; };<br>
+ struct { int32_t x, y; };<br>
<br>
- int32_t word;<br>
+ int64_t word;<br>
};<br>
<br>
MV() {}<br>
- MV(int32_t w) : word(w) {}<br>
- MV(int16_t _x, int16_t _y) : x(_x), y(_y) {}<br>
+ MV(int64_t w) : word(w) {}<br>
+ MV(int32_t _x, int32_t _y) : x(_x), y(_y) {}<br>
<br>
- MV& operator =(uint32_t w) { word = w; return *this; }<br>
+ MV& operator =(uint64_t w) { word = w; return *this; }<br>
<br>
MV& operator +=(const MV& other) { x += other.x; y += other.y; return *this; }<br>
<br>
@@ -67,7 +67,7 @@<br>
<br>
MV operator >>(int i) const { return MV(x >> i, y >> i); }<br>
<br>
- MV operator *(int16_t i) const { return MV(x * i, y * i); }<br>
+ MV operator *(int32_t i) const { return MV(x * i, y * i); }<br>
<br>
MV operator -(const MV& other) const { return MV(x - other.x, y - other.y); }<br>
<br>
@@ -87,7 +87,7 @@<br>
<br>
bool inline notZero() const { return this->word != 0; }<br>
<br>
- bool inline isSubpel() const { return (this->word & 0x00030003) != 0; }<br>
+ bool inline isSubpel() const { return (this->word & 0x0000000300000003ll) != 0; }<br>
<br>
MV mvmin(const MV& m) const { return MV(x > m.x ? m.x : x, y > m.y ? m.y : y); }<br>
<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/encoder/encoder.cpp Fri Mar 29 09:20:41 2019 +0900<br>
@@ -3631,8 +3631,8 @@<br>
(analysis->interData)->refIdx[i][count + pu] = refIdx[i][d];<br>
if (m_param->scaleFactor)<br>
{<br>
- mv[i][d].x *= (int16_t)m_param->scaleFactor;<br>
- mv[i][d].y *= (int16_t)m_param->scaleFactor;<br>
+ mv[i][d].x *= (int32_t)m_param->scaleFactor;<br>
+ mv[i][d].y *= (int32_t)m_param->scaleFactor;<br>
}<br>
memcpy(&(analysis->interData)->mv[i][count + pu], &mv[i][d], sizeof(MV));<br>
}<br>
@@ -4014,8 +4014,8 @@<br>
{<br>
(analysis->interData)->mvpIdx[i][count + pu] = mvpIdx[i][d];<br>
(analysis->interData)->refIdx[i][count + pu] = refIdx[i][d];<br>
- mvCopy[i].x = mv[i][d].x * (int16_t)m_param->scaleFactor;<br>
- mvCopy[i].y = mv[i][d].y * (int16_t)m_param->scaleFactor;<br>
+ mvCopy[i].x = mv[i][d].x * (int32_t)m_param->scaleFactor;<br>
+ mvCopy[i].y = mv[i][d].y * (int32_t)m_param->scaleFactor;<br>
memcpy(&(analysis->interData)->mv[i][count + pu], &mvCopy[i], sizeof(MV));<br>
}<br>
}<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/encoder/frameencoder.cpp Fri Mar 29 09:20:41 2019 +0900<br>
@@ -1406,8 +1406,8 @@<br>
}<br>
<br>
// Initialize restrict on MV range in slices<br>
- tld.analysis.m_sliceMinY = -(int16_t)(rowInSlice * m_param->maxCUSize * 4) + 3 * 4;<br>
- tld.analysis.m_sliceMaxY = (int16_t)((endRowInSlicePlus1 - 1 - row) * (m_param->maxCUSize * 4) - 4 * 4);<br>
+ tld.analysis.m_sliceMinY = -(int32_t)(rowInSlice * m_param->maxCUSize * 4) + 3 * 4;<br>
+ tld.analysis.m_sliceMaxY = (int32_t)((endRowInSlicePlus1 - 1 - row) * (m_param->maxCUSize * 4) - 4 * 4);<br>
<br>
// Handle single row slice<br>
if (tld.analysis.m_sliceMaxY < tld.analysis.m_sliceMinY)<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/encoder/motion.cpp<br>
--- a/source/encoder/motion.cpp Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/encoder/motion.cpp Fri Mar 29 09:20:41 2019 +0900<br>
@@ -382,10 +382,10 @@<br>
4 * 5<br>
7<br>
*/<br>
- const int16_t top = omv.y - dist;<br>
- const int16_t bottom = omv.y + dist;<br>
- const int16_t left = omv.x - dist;<br>
- const int16_t right = omv.x + dist;<br>
+ const int32_t top = omv.y - dist;<br>
+ const int32_t bottom = omv.y + dist;<br>
+ const int32_t left = omv.x - dist;<br>
+ const int32_t right = omv.x + dist;<br>
<br>
if (top >= mvmin.y && left >= mvmin.x && right <= mvmax.x && bottom <= mvmax.y)<br>
{<br>
@@ -430,14 +430,14 @@<br>
Points 2, 4, 5, 7 are dist<br>
Points 1, 3, 6, 8 are dist>>1<br>
*/<br>
- const int16_t top = omv.y - dist;<br>
- const int16_t bottom = omv.y + dist;<br>
- const int16_t left = omv.x - dist;<br>
- const int16_t right = omv.x + dist;<br>
- const int16_t top2 = omv.y - (dist >> 1);<br>
- const int16_t bottom2 = omv.y + (dist >> 1);<br>
- const int16_t left2 = omv.x - (dist >> 1);<br>
- const int16_t right2 = omv.x + (dist >> 1);<br>
+ const int32_t top = omv.y - dist;<br>
+ const int32_t bottom = omv.y + dist;<br>
+ const int32_t left = omv.x - dist;<br>
+ const int32_t right = omv.x + dist;<br>
+ const int32_t top2 = omv.y - (dist >> 1);<br>
+ const int32_t bottom2 = omv.y + (dist >> 1);<br>
+ const int32_t left2 = omv.x - (dist >> 1);<br>
+ const int32_t right2 = omv.x + (dist >> 1);<br>
saved = bcost;<br>
<br>
if (top >= mvmin.y && left >= mvmin.x &&<br>
@@ -502,10 +502,10 @@<br>
<br>
for (int16_t dist = 16; dist <= (int16_t)merange; dist <<= 1)<br>
{<br>
- const int16_t top = omv.y - dist;<br>
- const int16_t bottom = omv.y + dist;<br>
- const int16_t left = omv.x - dist;<br>
- const int16_t right = omv.x + dist;<br>
+ const int32_t top = omv.y - dist;<br>
+ const int32_t bottom = omv.y + dist;<br>
+ const int32_t left = omv.x - dist;<br>
+ const int32_t right = omv.x + dist;<br>
<br>
saved = bcost;<br>
if (top >= mvmin.y && left >= mvmin.x &&<br>
@@ -530,10 +530,10 @@<br>
<br>
for (int16_t index = 1; index < 4; index++)<br>
{<br>
- int16_t posYT = top + ((dist >> 2) * index);<br>
- int16_t posYB = bottom - ((dist >> 2) * index);<br>
- int16_t posXL = omv.x - ((dist >> 2) * index);<br>
- int16_t posXR = omv.x + ((dist >> 2) * index);<br>
+ int32_t posYT = top + ((dist >> 2) * index);<br>
+ int32_t posYB = bottom - ((dist >> 2) * index);<br>
+ int32_t posXL = omv.x - ((dist >> 2) * index);<br>
+ int32_t posXR = omv.x + ((dist >> 2) * index);<br>
<br>
COST_MV_PT_DIST_X4(posXL, posYT, 0, dist,<br>
posXR, posYT, 0, dist,<br>
@@ -561,10 +561,10 @@<br>
}<br>
for (int16_t index = 1; index < 4; index++)<br>
{<br>
- int16_t posYT = top + ((dist >> 2) * index);<br>
- int16_t posYB = bottom - ((dist >> 2) * index);<br>
- int16_t posXL = omv.x - ((dist >> 2) * index);<br>
- int16_t posXR = omv.x + ((dist >> 2) * index);<br>
+ int32_t posYT = top + ((dist >> 2) * index);<br>
+ int32_t posYB = bottom - ((dist >> 2) * index);<br>
+ int32_t posXL = omv.x - ((dist >> 2) * index);<br>
+ int32_t posXR = omv.x + ((dist >> 2) * index);<br>
<br>
if (posYT >= mvmin.y) // check top<br>
{<br>
@@ -1235,10 +1235,10 @@<br>
case X265_SEA:<br>
{<br>
// Successive Elimination Algorithm<br>
- const int16_t minX = X265_MAX(omv.x - (int16_t)merange, mvmin.x);<br>
- const int16_t minY = X265_MAX(omv.y - (int16_t)merange, mvmin.y);<br>
- const int16_t maxX = X265_MIN(omv.x + (int16_t)merange, mvmax.x);<br>
- const int16_t maxY = X265_MIN(omv.y + (int16_t)merange, mvmax.y);<br>
+ const int32_t minX = X265_MAX(omv.x - (int32_t)merange, mvmin.x);<br>
+ const int32_t minY = X265_MAX(omv.y - (int32_t)merange, mvmin.y);<br>
+ const int32_t maxX = X265_MIN(omv.x + (int32_t)merange, mvmax.x);<br>
+ const int32_t maxY = X265_MIN(omv.y + (int32_t)merange, mvmax.y);<br>
const uint16_t *p_cost_mvx = m_cost_mvx - qmvp.x;<br>
const uint16_t *p_cost_mvy = m_cost_mvy - qmvp.y;<br>
int16_t* meScratchBuffer = NULL;<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/encoder/search.cpp<br>
--- a/source/encoder/search.cpp Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/encoder/search.cpp Fri Mar 29 09:20:41 2019 +0900<br>
@@ -2633,7 +2633,7 @@<br>
<br>
void Search::setSearchRange(const CUData& cu, const MV& mvp, int merange, MV& mvmin, MV& mvmax) const<br>
{<br>
- MV dist((int16_t)merange << 2, (int16_t)merange << 2);<br>
+ MV dist((int32_t)merange << 2, (int32_t)merange << 2);<br>
mvmin = mvp - dist;<br>
mvmax = mvp + dist;<br>
<br>
@@ -2670,8 +2670,8 @@<br>
mvmax >>= 2;<br>
<br>
/* conditional clipping for frame parallelism */<br>
- mvmin.y = X265_MIN(mvmin.y, (int16_t)m_refLagPixels);<br>
- mvmax.y = X265_MIN(mvmax.y, (int16_t)m_refLagPixels);<br>
+ mvmin.y = X265_MIN(mvmin.y, (int32_t)m_refLagPixels);<br>
+ mvmax.y = X265_MIN(mvmax.y, (int32_t)m_refLagPixels);<br>
<br>
/* conditional clipping for negative mv range */<br>
mvmax.y = X265_MAX(mvmax.y, mvmin.y);<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/encoder/search.h<br>
--- a/source/encoder/search.h Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/encoder/search.h Fri Mar 29 09:20:41 2019 +0900<br>
@@ -283,8 +283,8 @@<br>
int32_t m_maxTUDepth;<br>
uint16_t m_limitTU;<br>
<br>
- int16_t m_sliceMaxY;<br>
- int16_t m_sliceMinY;<br>
+ int32_t m_sliceMaxY;<br>
+ int32_t m_sliceMinY;<br>
<br>
#if DETAILED_CU_STATS<br>
/* Accumulate CU statistics separately for each frame encoder */<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/encoder/slicetype.cpp<br>
--- a/source/encoder/slicetype.cpp Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/encoder/slicetype.cpp Fri Mar 29 09:20:41 2019 +0900<br>
@@ -2860,10 +2860,10 @@<br>
<br>
// TODO: restrict to slices boundaries<br>
// establish search bounds that don't cross extended frame boundaries<br>
- mvmin.x = (int16_t)(-cuX * cuSize - 8);<br>
- mvmin.y = (int16_t)(-cuY * cuSize - 8);<br>
- mvmax.x = (int16_t)((widthInCU - cuX - 1) * cuSize + 8);<br>
- mvmax.y = (int16_t)((heightInCU - cuY - 1) * cuSize + 8);<br>
+ mvmin.x = (int32_t)(-cuX * cuSize - 8);<br>
+ mvmin.y = (int32_t)(-cuY * cuSize - 8);<br>
+ mvmax.x = (int32_t)((widthInCU - cuX - 1) * cuSize + 8);<br>
+ mvmax.y = (int32_t)((heightInCU - cuY - 1) * cuSize + 8);<br>
<br>
for (int i = 0; i < 1 + bBidir; i++)<br>
{<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/encoder/weightPrediction.cpp<br>
--- a/source/encoder/weightPrediction.cpp Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/encoder/weightPrediction.cpp Fri Mar 29 09:20:41 2019 +0900<br>
@@ -69,15 +69,15 @@<br>
for (int y = 0; y < ref.lines; y += cuSize)<br>
{<br>
intptr_t pixoff = y * stride;<br>
- mvmin.y = (int16_t)((-y - 8) * mvshift);<br>
- mvmax.y = (int16_t)((ref.lines - y - 1 + 8) * mvshift);<br>
+ mvmin.y = (int32_t)((-y - 8) * mvshift);<br>
+ mvmax.y = (int32_t)((ref.lines - y - 1 + 8) * mvshift);<br>
<br>
for (int x = 0; x < ref.width; x += cuSize, pixoff += cuSize, cu++)<br>
{<br>
ALIGN_VAR_16(pixel, buf8x8[8 * 8]);<br>
intptr_t bstride = 8;<br>
- mvmin.x = (int16_t)((-x - 8) * mvshift);<br>
- mvmax.x = (int16_t)((ref.width - x - 1 + 8) * mvshift);<br>
+ mvmin.x = (int32_t)((-x - 8) * mvshift);<br>
+ mvmax.x = (int32_t)((ref.width - x - 1 + 8) * mvshift);<br>
<br>
/* clip MV to available pixels */<br>
MV mv = mvs[cu];<br>
@@ -113,8 +113,8 @@<br>
* into the lowres structures */<br>
int cu = y * cache.lowresWidthInCU;<br>
intptr_t pixoff = y * stride;<br>
- mvmin.y = (int16_t)((-y - 8) * mvshift);<br>
- mvmax.y = (int16_t)((height - y - 1 + 8) * mvshift);<br>
+ mvmin.y = (int32_t)((-y - 8) * mvshift);<br>
+ mvmax.y = (int32_t)((height - y - 1 + 8) * mvshift);<br>
<br>
for (int x = 0; x < width; x += bw, cu++, pixoff += bw)<br>
{<br>
@@ -126,8 +126,8 @@<br>
mv.y >>= cache.vshift;<br>
<br>
/* clip MV to available pixels */<br>
- mvmin.x = (int16_t)((-x - 8) * mvshift);<br>
- mvmax.x = (int16_t)((width - x - 1 + 8) * mvshift);<br>
+ mvmin.x = (int32_t)((-x - 8) * mvshift);<br>
+ mvmax.x = (int32_t)((width - x - 1 + 8) * mvshift);<br>
mv = mv.clipped(mvmin, mvmax);<br>
<br>
intptr_t fpeloffset = (mv.y >> 2) * stride + (mv.x >> 2);<br>
diff -r 3e5032228123 -r 0018ca1ca42f source/x265.h<br>
--- a/source/x265.h Fri Mar 22 13:09:49 2019 +0530<br>
+++ b/source/x265.h Fri Mar 29 09:20:41 2019 +0900<br>
@@ -147,9 +147,9 @@<br>
typedef struct x265_analysis_MV<br>
{<br>
union{<br>
- struct { int16_t x, y; };<br>
+ struct { int32_t x, y; };<br>
<br>
- int32_t word;<br>
+ int64_t word;<br>
};<br>
}x265_analysis_MV;<br>
<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div></div>