[x265] [PATCH] interpolate: fix bug that generate error interpolate pixel in border area

Min Chen chenm003 at 163.com
Fri Aug 30 07:36:12 CEST 2013


# HG changeset patch
# User Min Chen <chenm003 at 163.com>
# Date 1377840963 -28800
# Node ID 291cbb41ab477cc7f4ad0f8e544c08ebe3b137f6
# Parent  8b78d8cff9d8ab78b88ab813de0847fdaff804cf
interpolate: fix bug that generate error interpolate pixel in border area

diff -r 8b78d8cff9d8 -r 291cbb41ab47 source/common/ipfilter.cpp
--- a/source/common/ipfilter.cpp	Thu Aug 29 11:23:16 2013 -0500
+++ b/source/common/ipfilter.cpp	Fri Aug 30 13:36:03 2013 +0800
@@ -591,17 +591,36 @@
             ::memcpy(src - marginX + (height + y) * srcStride, src - marginX + (height - 1) * srcStride, sizeof(pixel) * (width + (marginX << 1)));
         }
     }
-    filterHorizontal_p_s<8>(src, srcStride, midA, midStride, width, height, g_lumaFilter[1]);
-    filterHorizontal_p_s<8>(src, srcStride, midB, midStride, width, height, g_lumaFilter[2]);
-    filterHorizontal_p_s<8>(src, srcStride, midC, midStride, width, height, g_lumaFilter[3]);
-    filterConvertShortToPel(midA, midStride, dstA, srcStride, width, height);
-    filterConvertShortToPel(midB, midStride, dstB, srcStride, width, height);
-    filterConvertShortToPel(midC, midStride, dstC, srcStride, width, height);
+
+    filterHorizontal_p_s<8>(src - 4, srcStride, midA - 4, midStride, width + 7, height, g_lumaFilter[1]);
+    filterHorizontal_p_s<8>(src - 4, srcStride, midB - 4, midStride, width + 7, height, g_lumaFilter[2]);
+    filterHorizontal_p_s<8>(src - 4, srcStride, midC - 4, midStride, width + 7, height, g_lumaFilter[3]);
+    filterConvertShortToPel(midA - 4, midStride, dstA - 4, srcStride, width + 7, height);
+    filterConvertShortToPel(midB - 4, midStride, dstB - 4, srcStride, width + 7, height);
+    filterConvertShortToPel(midC - 4, midStride, dstC - 4, srcStride, width + 7, height);
 
     // Extend SubPel Left and Right
-    extendCURowColBorder(dstA, srcStride, width, height, marginX);
-    extendCURowColBorder(dstB, srcStride, width, height, marginX);
-    extendCURowColBorder(dstC, srcStride, width, height, marginX);
+    for(int y = 0; y < height; y++)
+    {
+        for(int x = 0; x < marginX; x++)
+        {
+            // Left
+            if (x < marginX - 4)
+            {
+                dstA[y * srcStride - marginX + x] = dstA[y * srcStride - 4];
+                dstB[y * srcStride - marginX + x] = dstB[y * srcStride - 4];
+                dstC[y * srcStride - marginX + x] = dstC[y * srcStride - 4];
+            }
+
+            // Right
+            if (x > 2)
+            {
+                dstA[y * srcStride + width + x] = dstA[y * srcStride + width + 2];
+                dstB[y * srcStride + width + x] = dstB[y * srcStride + width + 2];
+                dstC[y * srcStride + width + x] = dstC[y * srcStride + width + 2];
+            }
+        }
+    }
 
     if (row == 0)
     {
@@ -613,12 +632,12 @@
             ::memcpy(dstC - marginX - (y + 1) * srcStride, dstC - marginX, sizeof(pixel) * srcStride);
         }
 
-        // Extend midPel Top(only 3 rows)
-        for(int y = 0; y < 3; y++)
+        // Extend midPel Top(7 rows)
+        for(int y = 0; y < 7; y++)
         {
-            ::memcpy(midA - (y + 1) * midStride, midA, midStride * sizeof(short));
-            ::memcpy(midB - (y + 1) * midStride, midB, midStride * sizeof(short));
-            ::memcpy(midC - (y + 1) * midStride, midC, midStride * sizeof(short));
+            ::memcpy(midA - 4 - (y + 1) * midStride, midA - 4, midStride * sizeof(short));
+            ::memcpy(midB - 4 - (y + 1) * midStride, midB - 4, midStride * sizeof(short));
+            ::memcpy(midC - 4 - (y + 1) * midStride, midC - 4, midStride * sizeof(short));
         }
     }
 
@@ -632,80 +651,104 @@
             ::memcpy(dstC - marginX + (height + y) * srcStride, dstC - marginX + (height - 1) * srcStride, sizeof(pixel) * srcStride);
         }
 
-        // Extend midPel Bottom(only 4 rows)
-        for(int y = 0; y < 4; y++)
+        // Extend midPel Bottom(7 rows)
+        for(int y = 0; y < 7; y++)
         {
-            ::memcpy(midA + (height + y) * midStride, midA + (height - 1) * midStride, midStride * sizeof(short));
-            ::memcpy(midB + (height + y) * midStride, midB + (height - 1) * midStride, midStride * sizeof(short));
-            ::memcpy(midC + (height + y) * midStride, midC + (height - 1) * midStride, midStride * sizeof(short));
+            ::memcpy(midA - 4 + (height + y) * midStride, midA - 4 + (height - 1) * midStride, midStride * sizeof(short));
+            ::memcpy(midB - 4 + (height + y) * midStride, midB - 4 + (height - 1) * midStride, midStride * sizeof(short));
+            ::memcpy(midC - 4 + (height + y) * midStride, midC - 4 + (height - 1) * midStride, midStride * sizeof(short));
         }
     }
 }
 
 void filterRowV_0(pixel *src, int srcStride, pixel *dstA, pixel *dstB, pixel *dstC, int width, int height, int marginX, int marginY, int row, int isLastRow)
 {
-    filterVertical_p_p<8>(src, srcStride, dstA, srcStride, width, height, g_lumaFilter[1]);
-    filterVertical_p_p<8>(src, srcStride, dstB, srcStride, width, height, g_lumaFilter[2]);
-    filterVertical_p_p<8>(src, srcStride, dstC, srcStride, width, height, g_lumaFilter[3]);
+    int row_first = (row == 0 ? 4 : 0);
+    int row_last = (isLastRow ? 3 : 0);
+
+    filterVertical_p_p<8>(src - row_first * srcStride, srcStride, dstA - row_first * srcStride, srcStride, width, height + row_first + row_last, g_lumaFilter[1]);
+    filterVertical_p_p<8>(src - row_first * srcStride, srcStride, dstB - row_first * srcStride, srcStride, width, height + row_first + row_last, g_lumaFilter[2]);
+    filterVertical_p_p<8>(src - row_first * srcStride, srcStride, dstC - row_first * srcStride, srcStride, width, height + row_first + row_last, g_lumaFilter[3]);
 
     // Extend SubPel Left and Right
-    extendCURowColBorder(dstA, srcStride, width, height, marginX);
-    extendCURowColBorder(dstB, srcStride, width, height, marginX);
-    extendCURowColBorder(dstC, srcStride, width, height, marginX);
+    extendCURowColBorder(dstA - row_first * srcStride, srcStride, width, height + row_first + row_last, marginX);
+    extendCURowColBorder(dstB - row_first * srcStride, srcStride, width, height + row_first + row_last, marginX);
+    extendCURowColBorder(dstC - row_first * srcStride, srcStride, width, height + row_first + row_last, marginX);
 
     if (row == 0)
     {
         // Extend SubPel Top
-        for(int y = 0; y < marginY; y++)
+        for(int y = row_first; y < marginY; y++)
         {
-            ::memcpy(dstA - marginX - (y + 1) * srcStride, dstA - marginX, sizeof(pixel) * srcStride);
-            ::memcpy(dstB - marginX - (y + 1) * srcStride, dstB - marginX, sizeof(pixel) * srcStride);
-            ::memcpy(dstC - marginX - (y + 1) * srcStride, dstC - marginX, sizeof(pixel) * srcStride);
+            ::memcpy(dstA - marginX - (y + 1) * srcStride, dstA - marginX - row_first * srcStride, sizeof(pixel) * srcStride);
+            ::memcpy(dstB - marginX - (y + 1) * srcStride, dstB - marginX - row_first * srcStride, sizeof(pixel) * srcStride);
+            ::memcpy(dstC - marginX - (y + 1) * srcStride, dstC - marginX - row_first * srcStride, sizeof(pixel) * srcStride);
         }
     }
 
     if (isLastRow)
     {
         // Extend SubPel Bottom
-        for(int y = 0; y < marginY; y++)
+        for(int y = row_last; y < marginY; y++)
         {
-            ::memcpy(dstA - marginX + (height + y) * srcStride, dstA - marginX + (height - 1) * srcStride, sizeof(pixel) * srcStride);
-            ::memcpy(dstB - marginX + (height + y) * srcStride, dstB - marginX + (height - 1) * srcStride, sizeof(pixel) * srcStride);
-            ::memcpy(dstC - marginX + (height + y) * srcStride, dstC - marginX + (height - 1) * srcStride, sizeof(pixel) * srcStride);
+            ::memcpy(dstA - marginX + (height + y) * srcStride, dstA - marginX + (height - 1 + row_last) * srcStride, sizeof(pixel) * srcStride);
+            ::memcpy(dstB - marginX + (height + y) * srcStride, dstB - marginX + (height - 1 + row_last) * srcStride, sizeof(pixel) * srcStride);
+            ::memcpy(dstC - marginX + (height + y) * srcStride, dstC - marginX + (height - 1 + row_last) * srcStride, sizeof(pixel) * srcStride);
         }
     }
 }
 
 void filterRowV_N(short *midA, int midStride, pixel *dstA, pixel *dstB, pixel *dstC, int dstStride, int width, int height, int marginX, int marginY, int row, int isLastRow)
 {
-    filterVertical_s_p<8>(midA, midStride, dstA, dstStride, width, height, g_lumaFilter[1]);
-    filterVertical_s_p<8>(midA, midStride, dstB, dstStride, width, height, g_lumaFilter[2]);
-    filterVertical_s_p<8>(midA, midStride, dstC, dstStride, width, height, g_lumaFilter[3]);
+    int row_first = (row == 0 ? 4 : 0);
+    int row_last = (isLastRow ? 3 : 0);
+
+    filterVertical_s_p<8>(midA - 4 - row_first * midStride, midStride, dstA - 4 - row_first * dstStride, dstStride, width + 7, height + row_first + row_last, g_lumaFilter[1]);
+    filterVertical_s_p<8>(midA - 4 - row_first * midStride, midStride, dstB - 4 - row_first * dstStride, dstStride, width + 7, height + row_first + row_last, g_lumaFilter[2]);
+    filterVertical_s_p<8>(midA - 4 - row_first * midStride, midStride, dstC - 4 - row_first * dstStride, dstStride, width + 7, height + row_first + row_last, g_lumaFilter[3]);
 
     // Extend SubPel Left and Right
-    extendCURowColBorder(dstA, dstStride, width, height, marginX);
-    extendCURowColBorder(dstB, dstStride, width, height, marginX);
-    extendCURowColBorder(dstC, dstStride, width, height, marginX);
+    for(int y = 0; y < height + row_first + row_last; y++)
+    {
+        for(int x = 0; x < marginX; x++)
+        {
+            // Left
+            if (x < marginX - 4)
+            {
+                dstA[(y - row_first) * dstStride - marginX + x] = dstA[(y - row_first) * dstStride - 4];
+                dstB[(y - row_first) * dstStride - marginX + x] = dstB[(y - row_first) * dstStride - 4];
+                dstC[(y - row_first) * dstStride - marginX + x] = dstC[(y - row_first) * dstStride - 4];
+            }
+
+            // Right
+            if (x > 2)
+            {
+                dstA[(y - row_first) * dstStride + width + x] = dstA[(y - row_first) * dstStride + width + 2];
+                dstB[(y - row_first) * dstStride + width + x] = dstB[(y - row_first) * dstStride + width + 2];
+                dstC[(y - row_first) * dstStride + width + x] = dstC[(y - row_first) * dstStride + width + 2];
+            }
+        }
+    }
 
     if (row == 0)
     {
         // Extend SubPel Top
-        for(int y = 0; y < marginY; y++)
+        for(int y = row_first; y < marginY; y++)
         {
-            ::memcpy(dstA - marginX - (y + 1) * dstStride, dstA - marginX, sizeof(pixel) * dstStride);
-            ::memcpy(dstB - marginX - (y + 1) * dstStride, dstB - marginX, sizeof(pixel) * dstStride);
-            ::memcpy(dstC - marginX - (y + 1) * dstStride, dstC - marginX, sizeof(pixel) * dstStride);
+            ::memcpy(dstA - marginX - (y + 1) * dstStride, dstA - marginX - row_first * dstStride, sizeof(pixel) * dstStride);
+            ::memcpy(dstB - marginX - (y + 1) * dstStride, dstB - marginX - row_first * dstStride, sizeof(pixel) * dstStride);
+            ::memcpy(dstC - marginX - (y + 1) * dstStride, dstC - marginX - row_first * dstStride, sizeof(pixel) * dstStride);
         }
     }
 
     if (isLastRow)
     {
         // Extend SubPel Bottom
-        for(int y = 0; y < marginY; y++)
+        for(int y = row_last; y < marginY; y++)
         {
-            ::memcpy(dstA - marginX + (height + y) * dstStride, dstA - marginX + (height - 1) * dstStride, sizeof(pixel) * dstStride);
-            ::memcpy(dstB - marginX + (height + y) * dstStride, dstB - marginX + (height - 1) * dstStride, sizeof(pixel) * dstStride);
-            ::memcpy(dstC - marginX + (height + y) * dstStride, dstC - marginX + (height - 1) * dstStride, sizeof(pixel) * dstStride);
+            ::memcpy(dstA - marginX + (height + y) * dstStride, dstA - marginX + (height - 1 + row_last) * dstStride, sizeof(pixel) * dstStride);
+            ::memcpy(dstB - marginX + (height + y) * dstStride, dstB - marginX + (height - 1 + row_last) * dstStride, sizeof(pixel) * dstStride);
+            ::memcpy(dstC - marginX + (height + y) * dstStride, dstC - marginX + (height - 1 + row_last) * dstStride, sizeof(pixel) * dstStride);
         }
     }
 }
diff -r 8b78d8cff9d8 -r 291cbb41ab47 source/common/reference.cpp
--- a/source/common/reference.cpp	Thu Aug 29 11:23:16 2013 -0500
+++ b/source/common/reference.cpp	Fri Aug 30 13:36:03 2013 +0800
@@ -82,8 +82,8 @@
     for (int i = 0; i < 4; i++)
     {
         // TODO: I am not sure [0] need space when weight, for safe I alloc either, but I DON'T FILL [0] anymore
-        m_midBuf[i] = new short[width * (height + 3 + 4)];  // middle buffer extend size: left(0), right(0), top(3), bottom(4)
-        m_midBuf[i] += 3 * width;
+        m_midBuf[i] = new short[(width + 7) * (height + 7 + 7)];  // middle buffer extend size: left(4), right(3), top(7), bottom(7)
+        m_midBuf[i] += 7 * (width + 7) + 4;
     }
 
     if (w) 
@@ -122,7 +122,7 @@
 
     for (int i = 0; i < 4; i++)
     {
-        m_midBuf[i] -= 3 * width;
+        m_midBuf[i] -= 7 * (width + 7) + 4;
         if (m_midBuf[i])
         {
             delete[] m_midBuf[i];
@@ -173,7 +173,7 @@
        }
        else
        {
-            int midStride = m_reconPic->getWidth();
+            int midStride = m_reconPic->getWidth() + 7;
             int height = g_maxCUHeight;
             for(int i = 0; i < m_reconPic->m_numCuInHeight; i++ )
             {
@@ -271,7 +271,7 @@
     }
     else
     {
-        int midStride = m_reconPic->getWidth();
+        int midStride = m_reconPic->getWidth() + 7;
         int height = g_maxCUHeight;
         for(int i = 0; i < m_reconPic->m_numCuInHeight; i++ )
         {



More information about the x265-devel mailing list