summaryrefslogtreecommitdiffstats
path: root/media/libvpx/libvpx/test/comp_avg_pred_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'media/libvpx/libvpx/test/comp_avg_pred_test.cc')
-rw-r--r--media/libvpx/libvpx/test/comp_avg_pred_test.cc270
1 files changed, 270 insertions, 0 deletions
diff --git a/media/libvpx/libvpx/test/comp_avg_pred_test.cc b/media/libvpx/libvpx/test/comp_avg_pred_test.cc
new file mode 100644
index 0000000000..f747c3524e
--- /dev/null
+++ b/media/libvpx/libvpx/test/comp_avg_pred_test.cc
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2017 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "third_party/googletest/src/include/gtest/gtest.h"
+
+#include "./vpx_dsp_rtcd.h"
+
+#include "test/acm_random.h"
+#include "test/buffer.h"
+#include "test/register_state_check.h"
+#include "vpx_ports/vpx_timer.h"
+
+namespace {
+
+using ::libvpx_test::ACMRandom;
+using ::libvpx_test::Buffer;
+
+template <typename Pixel>
+Pixel avg_with_rounding(Pixel a, Pixel b) {
+ return (a + b + 1) >> 1;
+}
+
+template <typename Pixel>
+void reference_pred(const Buffer<Pixel> &pred, const Buffer<Pixel> &ref,
+ int width, int height, Buffer<Pixel> *avg) {
+ ASSERT_NE(avg->TopLeftPixel(), nullptr);
+ ASSERT_NE(pred.TopLeftPixel(), nullptr);
+ ASSERT_NE(ref.TopLeftPixel(), nullptr);
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ avg->TopLeftPixel()[y * avg->stride() + x] =
+ avg_with_rounding<Pixel>(pred.TopLeftPixel()[y * pred.stride() + x],
+ ref.TopLeftPixel()[y * ref.stride() + x]);
+ }
+ }
+}
+
+using AvgPredFunc = void (*)(uint8_t *a, const uint8_t *b, int w, int h,
+ const uint8_t *c, int c_stride);
+
+template <int bitdepth, typename Pixel>
+class AvgPredTest : public ::testing::TestWithParam<AvgPredFunc> {
+ public:
+ virtual void SetUp() {
+ avg_pred_func_ = GetParam();
+ rnd_.Reset(ACMRandom::DeterministicSeed());
+ }
+
+ void TestSizeCombinations();
+ void TestCompareReferenceRandom();
+ void TestSpeed();
+
+ protected:
+ AvgPredFunc avg_pred_func_;
+ ACMRandom rnd_;
+};
+
+template <int bitdepth, typename Pixel>
+void AvgPredTest<bitdepth, Pixel>::TestSizeCombinations() {
+ // This is called as part of the sub pixel variance. As such it must be one of
+ // the variance block sizes.
+ for (int width_pow = 2; width_pow <= 6; ++width_pow) {
+ for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
+ ++height_pow) {
+ // Don't test 4x2 or 64x128
+ if (height_pow == 1 || height_pow == 7) continue;
+
+ // The sse2 special-cases when ref width == stride, so make sure to test
+ // it.
+ for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
+ const int width = 1 << width_pow;
+ const int height = 1 << height_pow;
+ // Only the reference buffer may have a stride not equal to width.
+ Buffer<Pixel> ref = Buffer<Pixel>(width, height, ref_padding ? 8 : 0);
+ ASSERT_TRUE(ref.Init());
+ Buffer<Pixel> pred = Buffer<Pixel>(width, height, 0, 16);
+ ASSERT_TRUE(pred.Init());
+ Buffer<Pixel> avg_ref = Buffer<Pixel>(width, height, 0, 16);
+ ASSERT_TRUE(avg_ref.Init());
+ Buffer<Pixel> avg_chk = Buffer<Pixel>(width, height, 0, 16);
+ ASSERT_TRUE(avg_chk.Init());
+ const int bitdepth_mask = (1 << bitdepth) - 1;
+ for (int h = 0; h < height; ++h) {
+ for (int w = 0; w < width; ++w) {
+ ref.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask;
+ }
+ }
+ for (int h = 0; h < height; ++h) {
+ for (int w = 0; w < width; ++w) {
+ pred.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask;
+ }
+ }
+
+ reference_pred<Pixel>(pred, ref, width, height, &avg_ref);
+ ASM_REGISTER_STATE_CHECK(avg_pred_func_(
+ (uint8_t *)avg_chk.TopLeftPixel(), (uint8_t *)pred.TopLeftPixel(),
+ width, height, (uint8_t *)ref.TopLeftPixel(), ref.stride()));
+
+ EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
+ if (HasFailure()) {
+ printf("Width: %d Height: %d\n", width, height);
+ avg_chk.PrintDifference(avg_ref);
+ return;
+ }
+ }
+ }
+ }
+}
+
+template <int bitdepth, typename Pixel>
+void AvgPredTest<bitdepth, Pixel>::TestCompareReferenceRandom() {
+ const int width = 64;
+ const int height = 32;
+ Buffer<Pixel> ref = Buffer<Pixel>(width, height, 8);
+ ASSERT_TRUE(ref.Init());
+ Buffer<Pixel> pred = Buffer<Pixel>(width, height, 0, 16);
+ ASSERT_TRUE(pred.Init());
+ Buffer<Pixel> avg_ref = Buffer<Pixel>(width, height, 0, 16);
+ ASSERT_TRUE(avg_ref.Init());
+ Buffer<Pixel> avg_chk = Buffer<Pixel>(width, height, 0, 16);
+ ASSERT_TRUE(avg_chk.Init());
+
+ for (int i = 0; i < 500; ++i) {
+ const int bitdepth_mask = (1 << bitdepth) - 1;
+ for (int h = 0; h < height; ++h) {
+ for (int w = 0; w < width; ++w) {
+ ref.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask;
+ }
+ }
+ for (int h = 0; h < height; ++h) {
+ for (int w = 0; w < width; ++w) {
+ pred.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask;
+ }
+ }
+
+ reference_pred<Pixel>(pred, ref, width, height, &avg_ref);
+ ASM_REGISTER_STATE_CHECK(avg_pred_func_(
+ (uint8_t *)avg_chk.TopLeftPixel(), (uint8_t *)pred.TopLeftPixel(),
+ width, height, (uint8_t *)ref.TopLeftPixel(), ref.stride()));
+ EXPECT_TRUE(avg_chk.CheckValues(avg_ref));
+ if (HasFailure()) {
+ printf("Width: %d Height: %d\n", width, height);
+ avg_chk.PrintDifference(avg_ref);
+ return;
+ }
+ }
+}
+
+template <int bitdepth, typename Pixel>
+void AvgPredTest<bitdepth, Pixel>::TestSpeed() {
+ for (int width_pow = 2; width_pow <= 6; ++width_pow) {
+ for (int height_pow = width_pow - 1; height_pow <= width_pow + 1;
+ ++height_pow) {
+ // Don't test 4x2 or 64x128
+ if (height_pow == 1 || height_pow == 7) continue;
+
+ for (int ref_padding = 0; ref_padding < 2; ref_padding++) {
+ const int width = 1 << width_pow;
+ const int height = 1 << height_pow;
+ Buffer<Pixel> ref = Buffer<Pixel>(width, height, ref_padding ? 8 : 0);
+ ASSERT_TRUE(ref.Init());
+ Buffer<Pixel> pred = Buffer<Pixel>(width, height, 0, 16);
+ ASSERT_TRUE(pred.Init());
+ Buffer<Pixel> avg = Buffer<Pixel>(width, height, 0, 16);
+ ASSERT_TRUE(avg.Init());
+ const int bitdepth_mask = (1 << bitdepth) - 1;
+ for (int h = 0; h < height; ++h) {
+ for (int w = 0; w < width; ++w) {
+ ref.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask;
+ }
+ }
+ for (int h = 0; h < height; ++h) {
+ for (int w = 0; w < width; ++w) {
+ pred.TopLeftPixel()[w + h * width] = rnd_.Rand16() & bitdepth_mask;
+ }
+ }
+
+ vpx_usec_timer timer;
+ vpx_usec_timer_start(&timer);
+ for (int i = 0; i < 100000000 / (width * height); ++i) {
+ avg_pred_func_((uint8_t *)avg.TopLeftPixel(),
+ (uint8_t *)pred.TopLeftPixel(), width, height,
+ (uint8_t *)ref.TopLeftPixel(), ref.stride());
+ }
+ vpx_usec_timer_mark(&timer);
+
+ const int elapsed_time =
+ static_cast<int>(vpx_usec_timer_elapsed(&timer));
+ printf("Average Test (ref_padding: %d) %dx%d time: %5d us\n",
+ ref_padding, width, height, elapsed_time);
+ }
+ }
+ }
+}
+
+using AvgPredTestLBD = AvgPredTest<8, uint8_t>;
+
+TEST_P(AvgPredTestLBD, SizeCombinations) { TestSizeCombinations(); }
+
+TEST_P(AvgPredTestLBD, CompareReferenceRandom) { TestCompareReferenceRandom(); }
+
+TEST_P(AvgPredTestLBD, DISABLED_Speed) { TestSpeed(); }
+
+INSTANTIATE_TEST_SUITE_P(C, AvgPredTestLBD,
+ ::testing::Values(&vpx_comp_avg_pred_c));
+
+#if HAVE_SSE2
+INSTANTIATE_TEST_SUITE_P(SSE2, AvgPredTestLBD,
+ ::testing::Values(&vpx_comp_avg_pred_sse2));
+#endif // HAVE_SSE2
+
+#if HAVE_NEON
+INSTANTIATE_TEST_SUITE_P(NEON, AvgPredTestLBD,
+ ::testing::Values(&vpx_comp_avg_pred_neon));
+#endif // HAVE_NEON
+
+#if HAVE_VSX
+INSTANTIATE_TEST_SUITE_P(VSX, AvgPredTestLBD,
+ ::testing::Values(&vpx_comp_avg_pred_vsx));
+#endif // HAVE_VSX
+
+#if HAVE_LSX
+INSTANTIATE_TEST_SUITE_P(LSX, AvgPredTestLBD,
+ ::testing::Values(&vpx_comp_avg_pred_lsx));
+#endif // HAVE_LSX
+
+#if CONFIG_VP9_HIGHBITDEPTH
+using HighbdAvgPredFunc = void (*)(uint16_t *a, const uint16_t *b, int w, int h,
+ const uint16_t *c, int c_stride);
+
+template <HighbdAvgPredFunc fn>
+void highbd_wrapper(uint8_t *a, const uint8_t *b, int w, int h,
+ const uint8_t *c, int c_stride) {
+ fn((uint16_t *)a, (const uint16_t *)b, w, h, (const uint16_t *)c, c_stride);
+}
+
+using AvgPredTestHBD = AvgPredTest<12, uint16_t>;
+
+TEST_P(AvgPredTestHBD, SizeCombinations) { TestSizeCombinations(); }
+
+TEST_P(AvgPredTestHBD, CompareReferenceRandom) { TestCompareReferenceRandom(); }
+
+TEST_P(AvgPredTestHBD, DISABLED_Speed) { TestSpeed(); }
+
+INSTANTIATE_TEST_SUITE_P(
+ C, AvgPredTestHBD,
+ ::testing::Values(&highbd_wrapper<vpx_highbd_comp_avg_pred_c>));
+
+#if HAVE_SSE2
+INSTANTIATE_TEST_SUITE_P(
+ SSE2, AvgPredTestHBD,
+ ::testing::Values(&highbd_wrapper<vpx_highbd_comp_avg_pred_sse2>));
+#endif // HAVE_SSE2
+
+#if HAVE_NEON
+INSTANTIATE_TEST_SUITE_P(
+ NEON, AvgPredTestHBD,
+ ::testing::Values(&highbd_wrapper<vpx_highbd_comp_avg_pred_neon>));
+#endif // HAVE_NEON
+
+#endif // CONFIG_VP9_HIGHBITDEPTH
+} // namespace