From e326cecf18a01172074bf9b3a9524c5887a122e7 Mon Sep 17 00:00:00 2001 From: Tero Rintaluoma Date: Thu, 22 Aug 2013 11:29:19 +0300 Subject: [PATCH] Fix intermediate height in convolve_c - 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 | 36 +++++++++++++++++++++++++++++++++++- vp9/common/vp9_convolve.c | 5 +---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/test/convolve_test.cc b/test/convolve_test.cc index 9bdce69ff..3100571da 100644 --- a/test/convolve_test.cc +++ b/test/convolve_test.cc @@ -8,6 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include #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( diff --git a/vp9/common/vp9_convolve.c b/vp9/common/vp9_convolve.c index 1e6cd4404..be092f41c 100644 --- a/vp9/common/vp9_convolve.c +++ b/vp9/common/vp9_convolve.c @@ -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);