Fix intermediate height in convolve_c
authorTero Rintaluoma <teror@google.com>
Thu, 22 Aug 2013 08:29:19 +0000 (11:29 +0300)
committerTero Rintaluoma <teror@google.com>
Fri, 30 Aug 2013 07:31:21 +0000 (10:31 +0300)
- Intermediate height was not correct i.e. when block size is 4 and
  y_step_q4 is 6. In this case intermediate height was
  (4*6) >> 4 = 1 and vertical interpolation needs two source pixels
  plus 7 extra pixels for taps.
- Also if the current output block is 16x16 and we are using 4x upscaling
  we need only 12 rows after horizontal filtering instead of 16.

  Patch Set 2: Intermediate_height updated after CL 66723
               "Fix bug in convolution functions (filter selection)"

Change-Id: I5a1a1bc2ac9d5edb3a6e0818de618bf318fdd589

test/convolve_test.cc
vp9/common/vp9_convolve.c

index 9bdce69..3100571 100644 (file)
@@ -8,6 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <string.h>
 #include "test/acm_random.h"
 #include "test/register_state_check.h"
 #include "test/util.h"
@@ -187,7 +188,7 @@ class ConvolveTest : public PARAMS(int, int, const ConvolveFunctions*) {
 
  protected:
   static const int kDataAlignment = 16;
-  static const int kOuterBlockSize = 128;
+  static const int kOuterBlockSize = 256;
   static const int kInputStride = kOuterBlockSize;
   static const int kOutputStride = kOuterBlockSize;
   static const int kMaxDimension = 64;
@@ -224,6 +225,10 @@ class ConvolveTest : public PARAMS(int, int, const ConvolveFunctions*) {
       input_[i] = prng.Rand8Extremes();
   }
 
+  void SetConstantInput(int value) {
+    memset(input_, value, kInputBufferSize);
+  }
+
   void CheckGuardBlocks() {
     for (int i = 0; i < kOutputBufferSize; ++i) {
       if (IsIndexInBorder(i))
@@ -543,6 +548,35 @@ TEST_P(ConvolveTest, ChangeFilterWorks) {
   }
 }
 
+/* This test exercises that enough rows and columns are filtered with every
+   possible initial fractional positions and scaling steps. */
+TEST_P(ConvolveTest, CheckScalingFiltering) {
+  uint8_t* const in = input();
+  uint8_t* const out = output();
+
+  SetConstantInput(127);
+
+  for (int frac = 0; frac < 16; ++frac) {
+    for (int step = 1; step <= 32; ++step) {
+      /* Test the horizontal and vertical filters in combination. */
+      REGISTER_STATE_CHECK(UUT_->hv8_(in, kInputStride, out, kOutputStride,
+                                      vp9_sub_pel_filters_8[frac], step,
+                                      vp9_sub_pel_filters_8[frac], step,
+                                      Width(), Height()));
+
+      CheckGuardBlocks();
+
+      for (int y = 0; y < Height(); ++y) {
+        for (int x = 0; x < Width(); ++x) {
+          ASSERT_EQ(in[y * kInputStride + x], out[y * kOutputStride + x])
+              << "x == " << x << ", y == " << y
+              << ", frac == " << frac << ", step == " << step;
+        }
+      }
+    }
+  }
+}
+
 using std::tr1::make_tuple;
 
 const ConvolveFunctions convolve8_c(
index 1e6cd44..be092f4 100644 (file)
@@ -195,7 +195,7 @@ static void convolve_c(const uint8_t *src, ptrdiff_t src_stride,
    * h == 64, taps == 8.
    */
   uint8_t temp[64 * 135];
-  int intermediate_height = MAX(((h * y_step_q4) >> 4), 1) + taps - 1;
+  int intermediate_height = (((h - 1) * y_step_q4 + 15) >> 4) + taps;
 
   assert(w <= 64);
   assert(h <= 64);
@@ -203,9 +203,6 @@ static void convolve_c(const uint8_t *src, ptrdiff_t src_stride,
   assert(y_step_q4 <= 32);
   assert(x_step_q4 <= 32);
 
-  if (intermediate_height < h)
-    intermediate_height = h;
-
   convolve_horiz_c(src - src_stride * (taps / 2 - 1), src_stride, temp, 64,
                    filter_x, x_step_q4, filter_y, y_step_q4, w,
                    intermediate_height, taps);