]> granicus.if.org Git - libvpx/commitdiff
Add unit test for x4 multi-SAD functions
authorJohn Koleszar <jkoleszar@google.com>
Fri, 1 Mar 2013 20:43:41 +0000 (12:43 -0800)
committerJohn Koleszar <jkoleszar@google.com>
Sat, 2 Mar 2013 02:14:02 +0000 (18:14 -0800)
Update the function prototypes to match between VP9 and VP8.

Change-Id: If58965073989e87df3b62b67a030ec6ce23ca04f

test/sad_test.cc
vp9/common/vp9_rtcd_defs.sh
vp9/encoder/vp9_sad_c.c
vp9/encoder/vp9_variance.h

index e0c5cfefa01398648a695bc3922c86977db07219..165e2c8f0c58182513ba2a63105f70848c5ad63f 100644 (file)
@@ -37,14 +37,22 @@ typedef unsigned int (*sad_m_by_n_fn_t)(const unsigned char *source_ptr,
                                         int reference_stride,
                                         unsigned int max_sad);
 
+typedef void (*sad_n_by_n_by_4_fn_t)(const uint8_t *src_ptr,
+                                     int src_stride,
+                                     const unsigned char * const ref_ptr[],
+                                     int ref_stride,
+                                     unsigned int *sad_array);
+
 using libvpx_test::ACMRandom;
 
 namespace {
-class SADTest : public PARAMS(int, int, sad_m_by_n_fn_t) {
+class SADTestBase : public ::testing::Test {
  public:
+  SADTestBase(int width, int height) : width_(width), height_(height) {}
+
   static void SetUpTestCase() {
     source_data_ = reinterpret_cast<uint8_t*>(
-        vpx_memalign(kDataAlignment, kDataBufferSize));
+        vpx_memalign(kDataAlignment, kDataBlockSize));
     reference_data_ = reinterpret_cast<uint8_t*>(
         vpx_memalign(kDataAlignment, kDataBufferSize));
   }
@@ -59,35 +67,29 @@ class SADTest : public PARAMS(int, int, sad_m_by_n_fn_t) {
  protected:
   // Handle blocks up to 4 blocks 64x64 with stride up to 128
   static const int kDataAlignment = 16;
-  static const int kDataBufferSize = 4 * 64 * 128;
+  static const int kDataBlockSize = 64 * 128;
+  static const int kDataBufferSize = 4 * kDataBlockSize;
 
   virtual void SetUp() {
-    sad_fn_ = GET_PARAM(2);
-    height_ = GET_PARAM(1);
-    width_ = GET_PARAM(0);
     source_stride_ = (width_ + 31) & ~31;
     reference_stride_ = width_ * 2;
     rnd_.Reset(ACMRandom::DeterministicSeed());
   }
 
-  sad_m_by_n_fn_t sad_fn_;
-  virtual unsigned int SAD(unsigned int max_sad) {
-    unsigned int ret;
-    REGISTER_STATE_CHECK(ret = sad_fn_(source_data_, source_stride_,
-                                       reference_data_, reference_stride_,
-                                       max_sad));
-    return ret;
+  virtual uint8_t* GetReference(int block_idx) {
+    return reference_data_ + block_idx * kDataBlockSize;
   }
 
   // Sum of Absolute Differences. Given two blocks, calculate the absolute
   // difference between two pixels in the same relative location; accumulate.
-  unsigned int ReferenceSAD(unsigned int max_sad) {
+  unsigned int ReferenceSAD(unsigned int max_sad, int block_idx = 0) {
     unsigned int sad = 0;
+    const uint8_t* const reference = GetReference(block_idx);
 
     for (int h = 0; h < height_; ++h) {
       for (int w = 0; w < width_; ++w) {
         sad += abs(source_data_[h * source_stride_ + w]
-               - reference_data_[h * reference_stride_ + w]);
+               - reference[h * reference_stride_ + w]);
       }
       if (sad > max_sad) {
         break;
@@ -112,6 +114,32 @@ class SADTest : public PARAMS(int, int, sad_m_by_n_fn_t) {
     }
   }
 
+  int width_, height_;
+  static uint8_t* source_data_;
+  int source_stride_;
+  static uint8_t* reference_data_;
+  int reference_stride_;
+
+  ACMRandom rnd_;
+};
+
+class SADTest : public SADTestBase,
+    public ::testing::WithParamInterface<
+        std::tr1::tuple<int, int, sad_m_by_n_fn_t> > {
+ public:
+  SADTest() : SADTestBase(GET_PARAM(0), GET_PARAM(1)) {}
+
+ protected:
+  unsigned int SAD(unsigned int max_sad, int block_idx = 0) {
+    unsigned int ret;
+    const uint8_t* const reference = GetReference(block_idx);
+
+    REGISTER_STATE_CHECK(ret = GET_PARAM(2)(source_data_, source_stride_,
+                                            reference, reference_stride_,
+                                            max_sad));
+    return ret;
+  }
+
   void CheckSad(unsigned int max_sad) {
     unsigned int reference_sad, exp_sad;
 
@@ -125,18 +153,38 @@ class SADTest : public PARAMS(int, int, sad_m_by_n_fn_t) {
       ASSERT_GE(exp_sad, reference_sad);
     }
   }
+};
 
-  int height_, width_;
-  static uint8_t* source_data_;
-  int source_stride_;
-  static uint8_t* reference_data_;
-  int reference_stride_;
+class SADx4Test : public SADTestBase,
+    public ::testing::WithParamInterface<
+        std::tr1::tuple<int, int, sad_n_by_n_by_4_fn_t> > {
+ public:
+  SADx4Test() : SADTestBase(GET_PARAM(0), GET_PARAM(1)) {}
 
-  ACMRandom rnd_;
+ protected:
+  void SADs(unsigned int *results) {
+    const uint8_t* refs[] = {GetReference(0), GetReference(1),
+                             GetReference(2), GetReference(3)};
+
+    REGISTER_STATE_CHECK(GET_PARAM(2)(source_data_, source_stride_,
+                                      refs, reference_stride_,
+                                      results));
+  }
+
+  void CheckSADs() {
+    unsigned int reference_sad, exp_sad[4];
+
+    SADs(exp_sad);
+    for (int block = 0; block < 4; block++) {
+      reference_sad = ReferenceSAD(UINT_MAX, block);
+
+      EXPECT_EQ(exp_sad[block], reference_sad) << "block " << block;
+    }
+  }
 };
 
-uint8_t* SADTest::source_data_ = NULL;
-uint8_t* SADTest::reference_data_ = NULL;
+uint8_t* SADTestBase::source_data_ = NULL;
+uint8_t* SADTestBase::reference_data_ = NULL;
 
 TEST_P(SADTest, MaxRef) {
   FillConstant(source_data_, source_stride_, 0);
@@ -144,12 +192,30 @@ TEST_P(SADTest, MaxRef) {
   CheckSad(UINT_MAX);
 }
 
+TEST_P(SADx4Test, MaxRef) {
+  FillConstant(source_data_, source_stride_, 0);
+  FillConstant(GetReference(0), reference_stride_, 255);
+  FillConstant(GetReference(1), reference_stride_, 255);
+  FillConstant(GetReference(2), reference_stride_, 255);
+  FillConstant(GetReference(3), reference_stride_, 255);
+  CheckSADs();
+}
+
 TEST_P(SADTest, MaxSrc) {
   FillConstant(source_data_, source_stride_, 255);
   FillConstant(reference_data_, reference_stride_, 0);
   CheckSad(UINT_MAX);
 }
 
+TEST_P(SADx4Test, MaxSrc) {
+  FillConstant(source_data_, source_stride_, 255);
+  FillConstant(GetReference(0), reference_stride_, 0);
+  FillConstant(GetReference(1), reference_stride_, 0);
+  FillConstant(GetReference(2), reference_stride_, 0);
+  FillConstant(GetReference(3), reference_stride_, 0);
+  CheckSADs();
+}
+
 TEST_P(SADTest, ShortRef) {
   int tmp_stride = reference_stride_;
   reference_stride_ >>= 1;
@@ -159,6 +225,18 @@ TEST_P(SADTest, ShortRef) {
   reference_stride_ = tmp_stride;
 }
 
+TEST_P(SADx4Test, ShortRef) {
+  int tmp_stride = reference_stride_;
+  reference_stride_ >>= 1;
+  FillRandom(source_data_, source_stride_);
+  FillRandom(GetReference(0), reference_stride_);
+  FillRandom(GetReference(1), reference_stride_);
+  FillRandom(GetReference(2), reference_stride_);
+  FillRandom(GetReference(3), reference_stride_);
+  CheckSADs();
+  reference_stride_ = tmp_stride;
+}
+
 TEST_P(SADTest, UnalignedRef) {
   // The reference frame, but not the source frame, may be unaligned for
   // certain types of searches.
@@ -170,6 +248,20 @@ TEST_P(SADTest, UnalignedRef) {
   reference_stride_ = tmp_stride;
 }
 
+TEST_P(SADx4Test, UnalignedRef) {
+  // The reference frame, but not the source frame, may be unaligned for
+  // certain types of searches.
+  int tmp_stride = reference_stride_;
+  reference_stride_ -= 1;
+  FillRandom(source_data_, source_stride_);
+  FillRandom(GetReference(0), reference_stride_);
+  FillRandom(GetReference(1), reference_stride_);
+  FillRandom(GetReference(2), reference_stride_);
+  FillRandom(GetReference(3), reference_stride_);
+  CheckSADs();
+  reference_stride_ = tmp_stride;
+}
+
 TEST_P(SADTest, ShortSrc) {
   int tmp_stride = source_stride_;
   source_stride_ >>= 1;
@@ -179,6 +271,18 @@ TEST_P(SADTest, ShortSrc) {
   source_stride_ = tmp_stride;
 }
 
+TEST_P(SADx4Test, ShortSrc) {
+  int tmp_stride = source_stride_;
+  source_stride_ >>= 1;
+  FillRandom(source_data_, source_stride_);
+  FillRandom(GetReference(0), reference_stride_);
+  FillRandom(GetReference(1), reference_stride_);
+  FillRandom(GetReference(2), reference_stride_);
+  FillRandom(GetReference(3), reference_stride_);
+  CheckSADs();
+  source_stride_ = tmp_stride;
+}
+
 TEST_P(SADTest, MaxSAD) {
   // Verify that, when max_sad is set, the implementation does not return a
   // value lower than the reference.
@@ -231,6 +335,20 @@ INSTANTIATE_TEST_CASE_P(C, SADTest, ::testing::Values(
 #endif
                         ));
 
+#if CONFIG_VP9_ENCODER
+const sad_n_by_n_by_4_fn_t sad_64x64x4d_c = vp9_sad64x64x4d_c;
+const sad_n_by_n_by_4_fn_t sad_32x32x4d_c = vp9_sad32x32x4d_c;
+const sad_n_by_n_by_4_fn_t sad_16x16x4d_c = vp9_sad16x16x4d_c;
+const sad_n_by_n_by_4_fn_t sad_8x8x4d_c = vp9_sad8x8x4d_c;
+const sad_n_by_n_by_4_fn_t sad_4x4x4d_c = vp9_sad4x4x4d_c;
+INSTANTIATE_TEST_CASE_P(C, SADx4Test, ::testing::Values(
+                        make_tuple(64, 64, sad_64x64x4d_c),
+                        make_tuple(32, 32, sad_32x32x4d_c),
+                        make_tuple(16, 16, sad_16x16x4d_c),
+                        make_tuple(8, 8, sad_8x8x4d_c),
+                        make_tuple(4, 4, sad_4x4x4d_c)));
+#endif
+
 // ARM tests
 #if HAVE_MEDIA
 const sad_m_by_n_fn_t sad_16x16_armv6 = vp8_sad16x16_armv6;
@@ -293,6 +411,10 @@ INSTANTIATE_TEST_CASE_P(MMX, SADTest, ::testing::Values(
 const sad_m_by_n_fn_t sad_4x4_sse_vp9 = vp9_sad4x4_sse;
 INSTANTIATE_TEST_CASE_P(SSE, SADTest, ::testing::Values(
                         make_tuple(4, 4, sad_4x4_sse_vp9)));
+
+const sad_n_by_n_by_4_fn_t sad_4x4x4d_sse = vp9_sad4x4x4d_sse;
+INSTANTIATE_TEST_CASE_P(SSE, SADx4Test, ::testing::Values(
+                        make_tuple(4, 4, sad_4x4x4d_sse)));
 #endif
 #endif
 
@@ -330,6 +452,38 @@ INSTANTIATE_TEST_CASE_P(SSE2, SADTest, ::testing::Values(
                         make_tuple(8, 8, sad_8x8_sse2_vp9)
 #endif
                         ));
+
+#if CONFIG_VP9_ENCODER
+const sad_n_by_n_by_4_fn_t sad_64x64x4d_sse2 = vp9_sad64x64x4d_sse2;
+const sad_n_by_n_by_4_fn_t sad_32x32x4d_sse2 = vp9_sad32x32x4d_sse2;
+const sad_n_by_n_by_4_fn_t sad_16x16x4d_sse2 = vp9_sad16x16x4d_sse2;
+const sad_n_by_n_by_4_fn_t sad_16x8x4d_sse2 = vp9_sad16x8x4d_sse2;
+const sad_n_by_n_by_4_fn_t sad_8x16x4d_sse2 = vp9_sad8x16x4d_sse2;
+const sad_n_by_n_by_4_fn_t sad_8x8x4d_sse2 = vp9_sad8x8x4d_sse2;
+INSTANTIATE_TEST_CASE_P(SSE2, SADx4Test, ::testing::Values(
+                        make_tuple(64, 64, sad_64x64x4d_sse2),
+                        make_tuple(32, 32, sad_32x32x4d_sse2),
+                        make_tuple(16, 16, sad_16x16x4d_sse2),
+                        make_tuple(16, 8, sad_16x8x4d_sse2),
+                        make_tuple(8, 16, sad_8x16x4d_sse2),
+                        make_tuple(8, 8, sad_8x8x4d_sse2)));
+#endif
+#endif
+
+#if HAVE_SSE3
+#if CONFIG_VP8_ENCODER
+const sad_n_by_n_by_4_fn_t sad_16x16x4d_sse3 = vp8_sad16x16x4d_sse3;
+const sad_n_by_n_by_4_fn_t sad_16x8x4d_sse3 = vp8_sad16x8x4d_sse3;
+const sad_n_by_n_by_4_fn_t sad_8x16x4d_sse3 = vp8_sad8x16x4d_sse3;
+const sad_n_by_n_by_4_fn_t sad_8x8x4d_sse3 = vp8_sad8x8x4d_sse3;
+const sad_n_by_n_by_4_fn_t sad_4x4x4d_sse3 = vp8_sad4x4x4d_sse3;
+INSTANTIATE_TEST_CASE_P(SSE3, SADx4Test, ::testing::Values(
+                        make_tuple(16, 16, sad_16x16x4d_sse3),
+                        make_tuple(16, 8, sad_16x8x4d_sse3),
+                        make_tuple(8, 16, sad_8x16x4d_sse3),
+                        make_tuple(8, 8, sad_8x8x4d_sse3),
+                        make_tuple(4, 4, sad_4x4x4d_sse3)));
+#endif
 #endif
 
 #if HAVE_SSSE3
index b9acadea7f0c6b869ccda0c01dbc76a79aa3c146..e6dcff4d1a16c9a2cbefbd8af7b2d8e34b3c6eef 100644 (file)
@@ -470,25 +470,25 @@ specialize vp9_sad8x8x8 sse4
 prototype void vp9_sad4x4x8 "const uint8_t *src_ptr, int  src_stride, const uint8_t *ref_ptr, int  ref_stride, uint32_t *sad_array"
 specialize vp9_sad4x4x8 sse4
 
-prototype void vp9_sad64x64x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t **ref_ptr, int  ref_stride, unsigned int *sad_array"
+prototype void vp9_sad64x64x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t* const ref_ptr[], int  ref_stride, unsigned int *sad_array"
 specialize vp9_sad64x64x4d sse2
 
-prototype void vp9_sad32x32x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t **ref_ptr, int  ref_stride, unsigned int *sad_array"
+prototype void vp9_sad32x32x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t* const ref_ptr[], int  ref_stride, unsigned int *sad_array"
 specialize vp9_sad32x32x4d sse2
 
-prototype void vp9_sad16x16x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t **ref_ptr, int  ref_stride, unsigned int *sad_array"
+prototype void vp9_sad16x16x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t* const ref_ptr[], int  ref_stride, unsigned int *sad_array"
 specialize vp9_sad16x16x4d sse2
 
-prototype void vp9_sad16x8x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t **ref_ptr, int  ref_stride, unsigned int *sad_array"
+prototype void vp9_sad16x8x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t* const ref_ptr[], int  ref_stride, unsigned int *sad_array"
 specialize vp9_sad16x8x4d sse2
 
-prototype void vp9_sad8x16x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t **ref_ptr, int  ref_stride, unsigned int *sad_array"
+prototype void vp9_sad8x16x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t* const ref_ptr[], int  ref_stride, unsigned int *sad_array"
 specialize vp9_sad8x16x4d sse2
 
-prototype void vp9_sad8x8x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t **ref_ptr, int  ref_stride, unsigned int *sad_array"
+prototype void vp9_sad8x8x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t* const ref_ptr[], int  ref_stride, unsigned int *sad_array"
 specialize vp9_sad8x8x4d sse2
 
-prototype void vp9_sad4x4x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t **ref_ptr, int  ref_stride, unsigned int *sad_array"
+prototype void vp9_sad4x4x4d "const uint8_t *src_ptr, int  src_stride, const uint8_t* const ref_ptr[], int  ref_stride, unsigned int *sad_array"
 specialize vp9_sad4x4x4d sse
 prototype unsigned int vp9_sub_pixel_mse16x16 "const uint8_t *src_ptr, int  src_pixels_per_line, int  xoffset, int  yoffset, const uint8_t *dst_ptr, int dst_pixels_per_line, unsigned int *sse"
 specialize vp9_sub_pixel_mse16x16 sse2 mmx
index dc21f02f638b804ead98c58fb9b2889ee9fc2791..af5526dce333bf133eff44b957ea3c63951ab766 100644 (file)
@@ -383,7 +383,7 @@ void vp9_sad4x4x8_c(const uint8_t *src_ptr,
 
 void vp9_sad64x64x4d_c(const uint8_t *src_ptr,
                        int  src_stride,
-                       const uint8_t *ref_ptr[],
+                       const uint8_t* const ref_ptr[],
                        int  ref_stride,
                        unsigned int *sad_array) {
   sad_array[0] = vp9_sad64x64(src_ptr, src_stride,
@@ -398,7 +398,7 @@ void vp9_sad64x64x4d_c(const uint8_t *src_ptr,
 
 void vp9_sad32x32x4d_c(const uint8_t *src_ptr,
                        int  src_stride,
-                       const uint8_t *ref_ptr[],
+                       const uint8_t* const ref_ptr[],
                        int  ref_stride,
                        unsigned int *sad_array) {
   sad_array[0] = vp9_sad32x32(src_ptr, src_stride,
@@ -413,7 +413,7 @@ void vp9_sad32x32x4d_c(const uint8_t *src_ptr,
 
 void vp9_sad16x16x4d_c(const uint8_t *src_ptr,
                        int  src_stride,
-                       const uint8_t *ref_ptr[],
+                       const uint8_t* const ref_ptr[],
                        int  ref_stride,
                        unsigned int *sad_array) {
   sad_array[0] = vp9_sad16x16(src_ptr, src_stride,
@@ -428,7 +428,7 @@ void vp9_sad16x16x4d_c(const uint8_t *src_ptr,
 
 void vp9_sad16x8x4d_c(const uint8_t *src_ptr,
                       int  src_stride,
-                      const uint8_t *ref_ptr[],
+                      const uint8_t* const ref_ptr[],
                       int  ref_stride,
                       unsigned int *sad_array) {
   sad_array[0] = vp9_sad16x8(src_ptr, src_stride,
@@ -443,7 +443,7 @@ void vp9_sad16x8x4d_c(const uint8_t *src_ptr,
 
 void vp9_sad8x8x4d_c(const uint8_t *src_ptr,
                      int  src_stride,
-                     const uint8_t *ref_ptr[],
+                     const uint8_t* const ref_ptr[],
                      int  ref_stride,
                      unsigned int *sad_array) {
   sad_array[0] = vp9_sad8x8(src_ptr, src_stride,
@@ -458,7 +458,7 @@ void vp9_sad8x8x4d_c(const uint8_t *src_ptr,
 
 void vp9_sad8x16x4d_c(const uint8_t *src_ptr,
                       int  src_stride,
-                      const uint8_t *ref_ptr[],
+                      const uint8_t* const ref_ptr[],
                       int  ref_stride,
                       unsigned int *sad_array) {
   sad_array[0] = vp9_sad8x16(src_ptr, src_stride,
@@ -473,7 +473,7 @@ void vp9_sad8x16x4d_c(const uint8_t *src_ptr,
 
 void vp9_sad4x4x4d_c(const uint8_t *src_ptr,
                      int  src_stride,
-                     const uint8_t *ref_ptr[],
+                     const uint8_t* const ref_ptr[],
                      int  ref_stride,
                      unsigned int *sad_array) {
   sad_array[0] = vp9_sad4x4(src_ptr, src_stride,
index 7120c5fe7e1fb56140e2bdd9a7eeac1c80d917ef..13dabbda41d711a8dce115cf2892182450083a14 100644 (file)
@@ -33,7 +33,7 @@ typedef void (*vp9_sad_multi1_fn_t)(const uint8_t *src_ptr,
 
 typedef void (*vp9_sad_multi_d_fn_t)(const uint8_t *src_ptr,
                                      int source_stride,
-                                     const uint8_t ** ref_ptr,
+                                     const uint8_t* const ref_ptr[],
                                      int  ref_stride, unsigned int *sad_array);
 
 typedef unsigned int (*vp9_variance_fn_t)(const uint8_t *src_ptr,