2 * Copyright (c) 2018, 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.
15 #include "config/aom_config.h"
16 #include "config/aom_dsp_rtcd.h"
18 #include "aom/aom_codec.h"
19 #include "aom/aom_integer.h"
20 #include "aom_dsp/variance.h"
21 #include "aom_mem/aom_mem.h"
22 #include "aom_ports/aom_timer.h"
23 #include "aom_ports/mem.h"
24 #include "av1/common/reconinter.h"
25 #include "test/acm_random.h"
26 #include "test/clear_system_state.h"
27 #include "test/register_state_check.h"
28 #include "test/util.h"
29 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
31 namespace AV1CompMaskVariance
{
32 typedef void (*comp_mask_pred_func
)(uint8_t *comp_pred
, const uint8_t *pred
,
33 int width
, int height
, const uint8_t *ref
,
34 int ref_stride
, const uint8_t *mask
,
35 int mask_stride
, int invert_mask
);
36 #if HAVE_SSSE3 || HAVE_AV2
37 const BLOCK_SIZE kValidBlockSize
[] = {
38 BLOCK_8X8
, BLOCK_8X16
, BLOCK_8X32
, BLOCK_16X8
, BLOCK_16X16
,
39 BLOCK_16X32
, BLOCK_32X8
, BLOCK_32X16
, BLOCK_32X32
,
42 typedef ::testing::tuple
<comp_mask_pred_func
, BLOCK_SIZE
> CompMaskPredParam
;
44 class AV1CompMaskVarianceTest
45 : public ::testing::TestWithParam
<CompMaskPredParam
> {
47 ~AV1CompMaskVarianceTest();
53 void RunCheckOutput(comp_mask_pred_func test_impl
, BLOCK_SIZE bsize
, int inv
);
54 void RunSpeedTest(comp_mask_pred_func test_impl
, BLOCK_SIZE bsize
);
55 bool CheckResult(int width
, int height
) {
56 for (int y
= 0; y
< height
; ++y
) {
57 for (int x
= 0; x
< width
; ++x
) {
58 const int idx
= y
* width
+ x
;
59 if (comp_pred1_
[idx
] != comp_pred2_
[idx
]) {
60 printf("%dx%d mismatch @%d(%d,%d) ", width
, height
, idx
, y
, x
);
61 printf("%d != %d ", comp_pred1_
[idx
], comp_pred2_
[idx
]);
69 libaom_test::ACMRandom rnd_
;
77 AV1CompMaskVarianceTest::~AV1CompMaskVarianceTest() { ; }
79 void AV1CompMaskVarianceTest::SetUp() {
80 rnd_
.Reset(libaom_test::ACMRandom::DeterministicSeed());
81 av1_init_wedge_masks();
82 comp_pred1_
= (uint8_t *)aom_memalign(16, MAX_SB_SQUARE
);
83 comp_pred2_
= (uint8_t *)aom_memalign(16, MAX_SB_SQUARE
);
84 pred_
= (uint8_t *)aom_memalign(16, MAX_SB_SQUARE
);
85 ref_buffer_
= (uint8_t *)aom_memalign(16, MAX_SB_SQUARE
+ (8 * MAX_SB_SIZE
));
86 ref_
= ref_buffer_
+ (8 * MAX_SB_SIZE
);
87 for (int i
= 0; i
< MAX_SB_SQUARE
; ++i
) {
88 pred_
[i
] = rnd_
.Rand8();
90 for (int i
= 0; i
< MAX_SB_SQUARE
+ (8 * MAX_SB_SIZE
); ++i
) {
91 ref_buffer_
[i
] = rnd_
.Rand8();
95 void AV1CompMaskVarianceTest::TearDown() {
96 aom_free(comp_pred1_
);
97 aom_free(comp_pred2_
);
99 aom_free(ref_buffer_
);
100 libaom_test::ClearSystemState();
103 void AV1CompMaskVarianceTest::RunCheckOutput(comp_mask_pred_func test_impl
,
104 BLOCK_SIZE bsize
, int inv
) {
105 const int w
= block_size_wide
[bsize
];
106 const int h
= block_size_high
[bsize
];
108 int wedge_types
= (1 << get_wedge_bits_lookup(bsize
));
109 for (int wedge_index
= 0; wedge_index
< wedge_types
; ++wedge_index
) {
110 const uint8_t *mask
= av1_get_contiguous_soft_mask(wedge_index
, 1, bsize
);
112 aom_comp_mask_pred_c(comp_pred1_
, pred_
, w
, h
, ref_
, MAX_SB_SIZE
, mask
, w
,
114 test_impl(comp_pred2_
, pred_
, w
, h
, ref_
, MAX_SB_SIZE
, mask
, w
, inv
);
116 ASSERT_EQ(CheckResult(w
, h
), true)
117 << " wedge " << wedge_index
<< " inv " << inv
;
121 void AV1CompMaskVarianceTest::RunSpeedTest(comp_mask_pred_func test_impl
,
123 const int w
= block_size_wide
[bsize
];
124 const int h
= block_size_high
[bsize
];
126 int wedge_types
= (1 << get_wedge_bits_lookup(bsize
));
127 int wedge_index
= wedge_types
/ 2;
128 const uint8_t *mask
= av1_get_contiguous_soft_mask(wedge_index
, 1, bsize
);
129 const int num_loops
= 1000000000 / (w
+ h
);
131 comp_mask_pred_func funcs
[2] = { aom_comp_mask_pred_c
, test_impl
};
132 double elapsed_time
[2] = { 0 };
133 for (int i
= 0; i
< 2; ++i
) {
134 aom_usec_timer timer
;
135 aom_usec_timer_start(&timer
);
136 comp_mask_pred_func func
= funcs
[i
];
137 for (int j
= 0; j
< num_loops
; ++j
) {
138 func(comp_pred1_
, pred_
, w
, h
, ref_
, MAX_SB_SIZE
, mask
, w
, 0);
140 aom_usec_timer_mark(&timer
);
141 double time
= static_cast<double>(aom_usec_timer_elapsed(&timer
));
142 elapsed_time
[i
] = 1000.0 * time
/ num_loops
;
144 printf("compMask %3dx%-3d: %7.2f/%7.2fns", w
, h
, elapsed_time
[0],
146 printf("(%3.2f)\n", elapsed_time
[0] / elapsed_time
[1]);
149 TEST_P(AV1CompMaskVarianceTest
, CheckOutput
) {
151 RunCheckOutput(GET_PARAM(0), GET_PARAM(1), 0);
152 RunCheckOutput(GET_PARAM(0), GET_PARAM(1), 1);
155 TEST_P(AV1CompMaskVarianceTest
, DISABLED_Speed
) {
156 RunSpeedTest(GET_PARAM(0), GET_PARAM(1));
160 INSTANTIATE_TEST_CASE_P(
161 SSSE3
, AV1CompMaskVarianceTest
,
162 ::testing::Combine(::testing::Values(&aom_comp_mask_pred_ssse3
),
163 ::testing::ValuesIn(kValidBlockSize
)));
167 INSTANTIATE_TEST_CASE_P(
168 AVX2
, AV1CompMaskVarianceTest
,
169 ::testing::Combine(::testing::Values(&aom_comp_mask_pred_avx2
),
170 ::testing::ValuesIn(kValidBlockSize
)));
173 #ifndef aom_comp_mask_pred
174 // can't run this test if aom_comp_mask_pred is defined to aom_comp_mask_pred_c
175 class AV1CompMaskUpVarianceTest
: public AV1CompMaskVarianceTest
{
177 ~AV1CompMaskUpVarianceTest();
180 void RunCheckOutput(comp_mask_pred_func test_impl
, BLOCK_SIZE bsize
, int inv
);
181 void RunSpeedTest(comp_mask_pred_func test_impl
, BLOCK_SIZE bsize
,
185 AV1CompMaskUpVarianceTest::~AV1CompMaskUpVarianceTest() { ; }
187 void AV1CompMaskUpVarianceTest::RunCheckOutput(comp_mask_pred_func test_impl
,
188 BLOCK_SIZE bsize
, int inv
) {
189 const int w
= block_size_wide
[bsize
];
190 const int h
= block_size_high
[bsize
];
191 int wedge_types
= (1 << get_wedge_bits_lookup(bsize
));
193 // loop through subx and suby
194 for (int sub
= 0; sub
< 8 * 8; ++sub
) {
195 int subx
= sub
& 0x7;
196 int suby
= (sub
>> 3);
197 for (int wedge_index
= 0; wedge_index
< wedge_types
; ++wedge_index
) {
198 const uint8_t *mask
= av1_get_contiguous_soft_mask(wedge_index
, 1, bsize
);
200 aom_comp_mask_pred
= aom_comp_mask_pred_c
; // ref
201 aom_comp_mask_upsampled_pred(NULL
, NULL
, 0, 0, NULL
, comp_pred1_
, pred_
,
202 w
, h
, subx
, suby
, ref_
, MAX_SB_SIZE
, mask
, w
,
205 aom_comp_mask_pred
= test_impl
; // test
206 aom_comp_mask_upsampled_pred(NULL
, NULL
, 0, 0, NULL
, comp_pred2_
, pred_
,
207 w
, h
, subx
, suby
, ref_
, MAX_SB_SIZE
, mask
, w
,
209 ASSERT_EQ(CheckResult(w
, h
), true)
210 << " wedge " << wedge_index
<< " inv " << inv
<< "sub (" << subx
211 << "," << suby
<< ")";
216 void AV1CompMaskUpVarianceTest::RunSpeedTest(comp_mask_pred_func test_impl
,
217 BLOCK_SIZE bsize
, int havSub
) {
218 const int w
= block_size_wide
[bsize
];
219 const int h
= block_size_high
[bsize
];
220 const int subx
= havSub
? 3 : 0;
221 const int suby
= havSub
? 4 : 0;
223 int wedge_types
= (1 << get_wedge_bits_lookup(bsize
));
224 int wedge_index
= wedge_types
/ 2;
225 const uint8_t *mask
= av1_get_contiguous_soft_mask(wedge_index
, 1, bsize
);
227 const int num_loops
= 1000000000 / (w
+ h
);
228 comp_mask_pred_func funcs
[2] = { &aom_comp_mask_pred_c
, test_impl
};
229 double elapsed_time
[2] = { 0 };
230 for (int i
= 0; i
< 2; ++i
) {
231 aom_usec_timer timer
;
232 aom_usec_timer_start(&timer
);
233 aom_comp_mask_pred
= funcs
[i
];
234 for (int j
= 0; j
< num_loops
; ++j
) {
235 aom_comp_mask_upsampled_pred(NULL
, NULL
, 0, 0, NULL
, comp_pred1_
, pred_
,
236 w
, h
, subx
, suby
, ref_
, MAX_SB_SIZE
, mask
, w
,
239 aom_usec_timer_mark(&timer
);
240 double time
= static_cast<double>(aom_usec_timer_elapsed(&timer
));
241 elapsed_time
[i
] = 1000.0 * time
/ num_loops
;
243 printf("CompMaskUp[%d] %3dx%-3d:%7.2f/%7.2fns", havSub
, w
, h
, elapsed_time
[0],
245 printf("(%3.2f)\n", elapsed_time
[0] / elapsed_time
[1]);
248 TEST_P(AV1CompMaskUpVarianceTest
, CheckOutput
) {
250 RunCheckOutput(GET_PARAM(0), GET_PARAM(1), 0);
251 RunCheckOutput(GET_PARAM(0), GET_PARAM(1), 1);
254 TEST_P(AV1CompMaskUpVarianceTest
, DISABLED_Speed
) {
255 RunSpeedTest(GET_PARAM(0), GET_PARAM(1), 1);
259 INSTANTIATE_TEST_CASE_P(
260 SSSE3
, AV1CompMaskUpVarianceTest
,
261 ::testing::Combine(::testing::Values(&aom_comp_mask_pred_ssse3
),
262 ::testing::ValuesIn(kValidBlockSize
)));
266 INSTANTIATE_TEST_CASE_P(
267 AVX2
, AV1CompMaskUpVarianceTest
,
268 ::testing::Combine(::testing::Values(&aom_comp_mask_pred_avx2
),
269 ::testing::ValuesIn(kValidBlockSize
)));
272 #endif // ifndef aom_comp_mask_pred
273 } // namespace AV1CompMaskVariance