ref: a6622470704b5252e415db18263cb5f8ee194800
parent: 53dc2d9d96d2c1bf397b2c1293acaab708371e7d
author: Angie Chiang <angiebird@google.com>
date: Sun Jul 14 04:59:18 EDT 2019
Add unit test for vpx_sadMxNx8 Change-Id: Ica85e3738708e2a6cc7388fd2cbf6a8840a540d5
--- a/test/sad_test.cc
+++ b/test/sad_test.cc
@@ -48,6 +48,12 @@
unsigned int *sad_array);
typedef TestParams<SadMxNx4Func> SadMxNx4Param;
+typedef void (*SadMxNx8Func)(const uint8_t *src_ptr, int src_stride,
+ const uint8_t *ref_ptr, int ref_stride,
+ unsigned int *sad_array);
+
+typedef TestParams<SadMxNx8Func> SadMxNx8Param;
+
using libvpx_test::ACMRandom;
namespace {
@@ -114,25 +120,36 @@
static const int kDataBlockSize = 64 * 128;
static const int kDataBufferSize = 4 * kDataBlockSize;
- uint8_t *GetReference(int block_idx) const {
+ int GetBlockRefOffset(int block_idx) const {
+ return block_idx * kDataBlockSize;
+ }
+
+ uint8_t *GetReferenceFromOffset(int ref_offset) const {
+ assert((params_.height - 1) * reference_stride_ + params_.width - 1 +
+ ref_offset <
+ kDataBufferSize);
#if CONFIG_VP9_HIGHBITDEPTH
if (use_high_bit_depth_) {
return CONVERT_TO_BYTEPTR(CONVERT_TO_SHORTPTR(reference_data_) +
- block_idx * kDataBlockSize);
+ ref_offset);
}
#endif // CONFIG_VP9_HIGHBITDEPTH
- return reference_data_ + block_idx * kDataBlockSize;
+ return reference_data_ + ref_offset;
}
+ uint8_t *GetReference(int block_idx) const {
+ return GetReferenceFromOffset(GetBlockRefOffset(block_idx));
+ }
+
// Sum of Absolute Differences. Given two blocks, calculate the absolute
// difference between two pixels in the same relative location; accumulate.
- uint32_t ReferenceSAD(int block_idx) const {
+ uint32_t ReferenceSAD(int ref_offset) const {
uint32_t sad = 0;
- const uint8_t *const reference8 = GetReference(block_idx);
+ const uint8_t *const reference8 = GetReferenceFromOffset(ref_offset);
const uint8_t *const source8 = source_data_;
#if CONFIG_VP9_HIGHBITDEPTH
const uint16_t *const reference16 =
- CONVERT_TO_SHORTPTR(GetReference(block_idx));
+ CONVERT_TO_SHORTPTR(GetReferenceFromOffset(ref_offset));
const uint16_t *const source16 = CONVERT_TO_SHORTPTR(source_data_);
#endif // CONFIG_VP9_HIGHBITDEPTH
for (int h = 0; h < params_.height; ++h) {
@@ -203,18 +220,18 @@
}
}
- void FillRandom(uint8_t *data, int stride) {
+ void FillRandomWH(uint8_t *data, int stride, int w, int h) {
uint8_t *data8 = data;
#if CONFIG_VP9_HIGHBITDEPTH
uint16_t *data16 = CONVERT_TO_SHORTPTR(data);
#endif // CONFIG_VP9_HIGHBITDEPTH
- for (int h = 0; h < params_.height; ++h) {
- for (int w = 0; w < params_.width; ++w) {
+ for (int r = 0; r < h; ++r) {
+ for (int c = 0; c < w; ++c) {
if (!use_high_bit_depth_) {
- data8[h * stride + w] = rnd_.Rand8();
+ data8[r * stride + c] = rnd_.Rand8();
#if CONFIG_VP9_HIGHBITDEPTH
} else {
- data16[h * stride + w] = rnd_.Rand16() & mask_;
+ data16[r * stride + c] = rnd_.Rand16() & mask_;
#endif // CONFIG_VP9_HIGHBITDEPTH
}
}
@@ -221,6 +238,10 @@
}
}
+ void FillRandom(uint8_t *data, int stride) {
+ FillRandomWH(data, stride, params_.width, params_.height);
+ }
+
uint32_t mask_;
vpx_bit_depth_t bit_depth_;
int source_stride_;
@@ -241,6 +262,29 @@
ParamType params_;
};
+class SADx8Test : public SADTestBase<SadMxNx8Param> {
+ public:
+ SADx8Test() : SADTestBase(GetParam()) {}
+
+ protected:
+ void SADs(unsigned int *results) const {
+ const uint8_t *reference = GetReferenceFromOffset(0);
+
+ ASM_REGISTER_STATE_CHECK(params_.func(
+ source_data_, source_stride_, reference, reference_stride_, results));
+ }
+
+ void CheckSADs() const {
+ uint32_t reference_sad, exp_sad[8];
+
+ SADs(exp_sad);
+ for (int offset = 0; offset < 8; ++offset) {
+ reference_sad = ReferenceSAD(offset);
+ EXPECT_EQ(reference_sad, exp_sad[offset]) << "offset " << offset;
+ }
+ }
+};
+
class SADx4Test : public SADTestBase<SadMxNx4Param> {
public:
SADx4Test() : SADTestBase(GetParam()) {}
@@ -259,7 +303,7 @@
SADs(exp_sad);
for (int block = 0; block < 4; ++block) {
- reference_sad = ReferenceSAD(block);
+ reference_sad = ReferenceSAD(GetBlockRefOffset(block));
EXPECT_EQ(reference_sad, exp_sad[block]) << "block " << block;
}
@@ -281,7 +325,7 @@
}
void CheckSAD() const {
- const unsigned int reference_sad = ReferenceSAD(0);
+ const unsigned int reference_sad = ReferenceSAD(GetBlockRefOffset(0));
const unsigned int exp_sad = SAD(0);
ASSERT_EQ(reference_sad, exp_sad);
@@ -498,7 +542,7 @@
vpx_usec_timer_start(&timer);
for (int i = 0; i < kCountSpeedTestBlock; ++i) {
for (int block = 0; block < 4; ++block) {
- reference_sad[block] = ReferenceSAD(block);
+ reference_sad[block] = ReferenceSAD(GetBlockRefOffset(block));
}
}
vpx_usec_timer_mark(&timer);
@@ -513,6 +557,13 @@
reference_stride_ = tmp_stride;
}
+TEST_P(SADx8Test, Regular) {
+ FillRandomWH(source_data_, source_stride_, params_.width, params_.height);
+ FillRandomWH(GetReferenceFromOffset(0), reference_stride_, params_.width + 8,
+ params_.height);
+ CheckSADs();
+}
+
//------------------------------------------------------------------------------
// C functions
const SadMxNParam c_tests[] = {
@@ -689,6 +740,24 @@
};
INSTANTIATE_TEST_CASE_P(C, SADx4Test, ::testing::ValuesIn(x4d_c_tests));
+// TODO(angiebird): implement the marked-down sad functions
+const SadMxNx8Param x8_c_tests[] = {
+ // SadMxNx8Param(64, 64, &vpx_sad64x64x8_c),
+ // SadMxNx8Param(64, 32, &vpx_sad64x32x8_c),
+ // SadMxNx8Param(32, 64, &vpx_sad32x64x8_c),
+ // SadMxNx8Param(32, 32, &vpx_sad32x32x8_c),
+ // SadMxNx8Param(32, 16, &vpx_sad32x16x8_c),
+ // SadMxNx8Param(16, 32, &vpx_sad16x32x8_c),
+ SadMxNx8Param(16, 16, &vpx_sad16x16x8_c),
+ SadMxNx8Param(16, 8, &vpx_sad16x8x8_c),
+ SadMxNx8Param(8, 16, &vpx_sad8x16x8_c),
+ SadMxNx8Param(8, 8, &vpx_sad8x8x8_c),
+ // SadMxNx8Param(8, 4, &vpx_sad8x4x8_c),
+ // SadMxNx8Param(4, 8, &vpx_sad4x8x8_c),
+ SadMxNx8Param(4, 4, &vpx_sad4x4x8_c),
+};
+INSTANTIATE_TEST_CASE_P(C, SADx8Test, ::testing::ValuesIn(x8_c_tests));
+
//------------------------------------------------------------------------------
// ARM functions
#if HAVE_NEON
@@ -917,7 +986,15 @@
#endif // HAVE_SSSE3
#if HAVE_SSE4_1
-// Only functions are x8, which do not have tests.
+const SadMxNx8Param x8_sse4_1_tests[] = {
+ SadMxNx8Param(16, 16, &vpx_sad16x16x8_sse4_1),
+ SadMxNx8Param(16, 8, &vpx_sad16x8x8_sse4_1),
+ SadMxNx8Param(8, 16, &vpx_sad8x16x8_sse4_1),
+ SadMxNx8Param(8, 8, &vpx_sad8x8x8_sse4_1),
+ SadMxNx8Param(4, 4, &vpx_sad4x4x8_sse4_1),
+};
+INSTANTIATE_TEST_CASE_P(SSE4_1, SADx8Test,
+ ::testing::ValuesIn(x8_sse4_1_tests));
#endif // HAVE_SSE4_1
#if HAVE_AVX2