From: Angie Chiang Date: Sun, 14 Jul 2019 15:59:18 +0000 (-0700) Subject: Add unit test for vpx_sadMxNx8 X-Git-Tag: v1.8.2~164 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a6622470704b5252e415db18263cb5f8ee194800;p=libvpx Add unit test for vpx_sadMxNx8 Change-Id: Ica85e3738708e2a6cc7388fd2cbf6a8840a540d5 --- diff --git a/test/sad_test.cc b/test/sad_test.cc index 0902df70a..9888b7cf7 100644 --- a/test/sad_test.cc +++ b/test/sad_test.cc @@ -48,6 +48,12 @@ typedef void (*SadMxNx4Func)(const uint8_t *src_ptr, int src_stride, unsigned int *sad_array); typedef TestParams 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 SadMxNx8Param; + using libvpx_test::ACMRandom; namespace { @@ -114,25 +120,36 @@ class SADTestBase : public ::testing::TestWithParam { 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,24 +220,28 @@ class SADTestBase : public ::testing::TestWithParam { } } - 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 } } } } + 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 @@ class SADTestBase : public ::testing::TestWithParam { ParamType params_; }; +class SADx8Test : public SADTestBase { + 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 { public: SADx4Test() : SADTestBase(GetParam()) {} @@ -259,7 +303,7 @@ class SADx4Test : public SADTestBase { 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 @@ class SADTest : public AbstractBench, public SADTestBase { } 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 @@ TEST_P(SADx4Test, DISABLED_Speed) { 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 @@ TEST_P(SADx4Test, DISABLED_Speed) { 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 @@ const SadMxNx4Param x4d_c_tests[] = { }; 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 @@ INSTANTIATE_TEST_CASE_P(SSE2, SADx4Test, ::testing::ValuesIn(x4d_sse2_tests)); #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