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.
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
;
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
>
41 class ErrorBlockTest
: public ::testing::TestWithParam
<ErrorBlockParam
> {
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(); }
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;
69 const int msb
= bit_depth_
+ 8 - 1;
70 for (int i
= 0; i
< kNumIterations
; ++i
) {
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.
78 coeff
[j
] = rnd(1 << msb
);
79 dqcoeff
[j
] = rnd(1 << msb
);
82 coeff
[j
] = -rnd(1 << msb
);
83 dqcoeff
[j
] = -rnd(1 << msb
);
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
) {
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;
112 const int msb
= bit_depth_
+ 8 - 1;
113 int max_val
= ((1 << msb
) - 1);
114 for (int i
= 0; i
< kNumIterations
; ++i
) {
118 // Change the maximum coeff value, to test different bit boundaries
119 if (k
== 8 && (i
% 9) == 0) {
122 block_size
= 16 << (i
% 9); // All block sizes from 4x4, 8x4 ..64x64
123 for (int j
= 0; j
< block_size
; j
++) {
125 // Test at positive maximum values
126 coeff
[j
] = k
% 2 ? max_val
: 0;
127 dqcoeff
[j
] = (k
>> 1) % 2 ? max_val
: 0;
129 // Test at negative maximum values
130 coeff
[j
] = k
% 2 ? -max_val
: 0;
131 dqcoeff
[j
] = (k
>> 1) % 2 ? -max_val
: 0;
135 coeff
[j
] = rnd(1 << 14);
136 dqcoeff
[j
] = rnd(1 << 14);
139 coeff
[j
] = -rnd(1 << 14);
140 dqcoeff
[j
] = -rnd(1 << 14);
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
) {
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
)));