Backed out 3 changesets (bug 1790375) for causing wd failures on fetch_error.py....
[gecko.git] / third_party / aom / test / error_block_test.cc
blob353947c3d70872bdf356fa71f1d180ec26b9b45a
1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
12 #include <cmath>
13 #include <cstdlib>
14 #include <string>
16 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
18 #include "config/aom_config.h"
19 #include "config/av1_rtcd.h"
21 #include "test/acm_random.h"
22 #include "test/clear_system_state.h"
23 #include "test/register_state_check.h"
24 #include "test/util.h"
25 #include "av1/common/entropy.h"
26 #include "aom/aom_codec.h"
27 #include "aom/aom_integer.h"
29 using libaom_test::ACMRandom;
31 namespace {
32 const int kNumIterations = 1000;
34 typedef int64_t (*ErrorBlockFunc)(const tran_low_t *coeff,
35 const tran_low_t *dqcoeff,
36 intptr_t block_size, int64_t *ssz, int bps);
38 typedef ::testing::tuple<ErrorBlockFunc, ErrorBlockFunc, aom_bit_depth_t>
39 ErrorBlockParam;
41 class ErrorBlockTest : public ::testing::TestWithParam<ErrorBlockParam> {
42 public:
43 virtual ~ErrorBlockTest() {}
44 virtual void SetUp() {
45 error_block_op_ = GET_PARAM(0);
46 ref_error_block_op_ = GET_PARAM(1);
47 bit_depth_ = GET_PARAM(2);
50 virtual void TearDown() { libaom_test::ClearSystemState(); }
52 protected:
53 aom_bit_depth_t bit_depth_;
54 ErrorBlockFunc error_block_op_;
55 ErrorBlockFunc ref_error_block_op_;
58 TEST_P(ErrorBlockTest, OperationCheck) {
59 ACMRandom rnd(ACMRandom::DeterministicSeed());
60 DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
61 DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
62 int err_count_total = 0;
63 int first_failure = -1;
64 intptr_t block_size;
65 int64_t ssz;
66 int64_t ret;
67 int64_t ref_ssz;
68 int64_t ref_ret;
69 const int msb = bit_depth_ + 8 - 1;
70 for (int i = 0; i < kNumIterations; ++i) {
71 int err_count = 0;
72 block_size = 16 << (i % 9); // All block sizes from 4x4, 8x4 ..64x64
73 for (int j = 0; j < block_size; j++) {
74 // coeff and dqcoeff will always have at least the same sign, and this
75 // can be used for optimization, so generate test input precisely.
76 if (rnd(2)) {
77 // Positive number
78 coeff[j] = rnd(1 << msb);
79 dqcoeff[j] = rnd(1 << msb);
80 } else {
81 // Negative number
82 coeff[j] = -rnd(1 << msb);
83 dqcoeff[j] = -rnd(1 << msb);
86 ref_ret =
87 ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz, bit_depth_);
88 ASM_REGISTER_STATE_CHECK(
89 ret = error_block_op_(coeff, dqcoeff, block_size, &ssz, bit_depth_));
90 err_count += (ref_ret != ret) | (ref_ssz != ssz);
91 if (err_count && !err_count_total) {
92 first_failure = i;
94 err_count_total += err_count;
96 EXPECT_EQ(0, err_count_total)
97 << "Error: Error Block Test, C output doesn't match optimized output. "
98 << "First failed at test case " << first_failure;
101 TEST_P(ErrorBlockTest, ExtremeValues) {
102 ACMRandom rnd(ACMRandom::DeterministicSeed());
103 DECLARE_ALIGNED(16, tran_low_t, coeff[4096]);
104 DECLARE_ALIGNED(16, tran_low_t, dqcoeff[4096]);
105 int err_count_total = 0;
106 int first_failure = -1;
107 intptr_t block_size;
108 int64_t ssz;
109 int64_t ret;
110 int64_t ref_ssz;
111 int64_t ref_ret;
112 const int msb = bit_depth_ + 8 - 1;
113 int max_val = ((1 << msb) - 1);
114 for (int i = 0; i < kNumIterations; ++i) {
115 int err_count = 0;
116 int k = (i / 9) % 9;
118 // Change the maximum coeff value, to test different bit boundaries
119 if (k == 8 && (i % 9) == 0) {
120 max_val >>= 1;
122 block_size = 16 << (i % 9); // All block sizes from 4x4, 8x4 ..64x64
123 for (int j = 0; j < block_size; j++) {
124 if (k < 4) {
125 // Test at positive maximum values
126 coeff[j] = k % 2 ? max_val : 0;
127 dqcoeff[j] = (k >> 1) % 2 ? max_val : 0;
128 } else if (k < 8) {
129 // Test at negative maximum values
130 coeff[j] = k % 2 ? -max_val : 0;
131 dqcoeff[j] = (k >> 1) % 2 ? -max_val : 0;
132 } else {
133 if (rnd(2)) {
134 // Positive number
135 coeff[j] = rnd(1 << 14);
136 dqcoeff[j] = rnd(1 << 14);
137 } else {
138 // Negative number
139 coeff[j] = -rnd(1 << 14);
140 dqcoeff[j] = -rnd(1 << 14);
144 ref_ret =
145 ref_error_block_op_(coeff, dqcoeff, block_size, &ref_ssz, bit_depth_);
146 ASM_REGISTER_STATE_CHECK(
147 ret = error_block_op_(coeff, dqcoeff, block_size, &ssz, bit_depth_));
148 err_count += (ref_ret != ret) | (ref_ssz != ssz);
149 if (err_count && !err_count_total) {
150 first_failure = i;
152 err_count_total += err_count;
154 EXPECT_EQ(0, err_count_total)
155 << "Error: Error Block Test, C output doesn't match optimized output. "
156 << "First failed at test case " << first_failure;
159 #if (HAVE_SSE2 || HAVE_AVX)
160 using ::testing::make_tuple;
162 INSTANTIATE_TEST_CASE_P(
163 SSE2, ErrorBlockTest,
164 ::testing::Values(make_tuple(&av1_highbd_block_error_sse2,
165 &av1_highbd_block_error_c, AOM_BITS_10),
166 make_tuple(&av1_highbd_block_error_sse2,
167 &av1_highbd_block_error_c, AOM_BITS_12),
168 make_tuple(&av1_highbd_block_error_sse2,
169 &av1_highbd_block_error_c, AOM_BITS_8)));
170 #endif // HAVE_SSE2
171 } // namespace