1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
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.
10 */
11
12 #include <tuple>
13
14 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
15
16 #include "config/av1_rtcd.h"
17
18 #include "test/acm_random.h"
19 #include "test/register_state_check.h"
20 #include "test/util.h"
21 #include "av1/common/enums.h"
22
23 namespace {
24
25 using libaom_test::ACMRandom;
26 using std::tuple;
27
28 typedef void (*Predictor)(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
29 const uint8_t *above, const uint8_t *left, int mode);
30
31 // Note:
32 // Test parameter list:
33 // Reference predictor, optimized predictor, prediction mode, tx size
34 //
35 typedef tuple<Predictor, Predictor, int> PredFuncMode;
36 typedef tuple<PredFuncMode, TX_SIZE> PredParams;
37
38 const int MaxTxSize = 32;
39
40 const int MaxTestNum = 100;
41
42 class AV1FilterIntraPredTest : public ::testing::TestWithParam<PredParams> {
43 public:
~AV1FilterIntraPredTest()44 virtual ~AV1FilterIntraPredTest() {}
SetUp()45 virtual void SetUp() {
46 PredFuncMode funcMode = GET_PARAM(0);
47 predFuncRef_ = std::get<0>(funcMode);
48 predFunc_ = std::get<1>(funcMode);
49 mode_ = std::get<2>(funcMode);
50 txSize_ = GET_PARAM(1);
51
52 alloc_ = new uint8_t[2 * MaxTxSize + 1];
53 predRef_ = new uint8_t[MaxTxSize * MaxTxSize];
54 pred_ = new uint8_t[MaxTxSize * MaxTxSize];
55 }
56
TearDown()57 virtual void TearDown() {
58 delete[] alloc_;
59 delete[] predRef_;
60 delete[] pred_;
61 }
62
63 protected:
RunTest() const64 void RunTest() const {
65 int tstIndex = 0;
66 int stride = tx_size_wide[txSize_];
67 uint8_t *left = alloc_;
68 uint8_t *above = alloc_ + MaxTxSize;
69 while (tstIndex < MaxTestNum) {
70 PrepareBuffer();
71 predFuncRef_(predRef_, stride, txSize_, &above[1], left, mode_);
72 API_REGISTER_STATE_CHECK(
73 predFunc_(pred_, stride, txSize_, &above[1], left, mode_));
74 DiffPred(tstIndex);
75 tstIndex += 1;
76 }
77 }
RunSpeedTest() const78 void RunSpeedTest() const {
79 int stride = tx_size_wide[txSize_];
80 uint8_t *left = alloc_;
81 uint8_t *above = alloc_ + MaxTxSize;
82 const int numIter = 5000;
83
84 PrepareBuffer();
85 aom_usec_timer ref_timer;
86 aom_usec_timer_start(&ref_timer);
87 for (int i = 0; i < numIter; i++) {
88 predFuncRef_(predRef_, stride, txSize_, &above[1], left, mode_);
89 }
90 aom_usec_timer_mark(&ref_timer);
91
92 aom_usec_timer timer;
93 aom_usec_timer_start(&timer);
94 for (int i = 0; i < numIter; i++) {
95 predFunc_(pred_, stride, txSize_, &above[1], left, mode_);
96 }
97 aom_usec_timer_mark(&timer);
98
99 const int ref_sum_time =
100 static_cast<int>(aom_usec_timer_elapsed(&ref_timer));
101 const int sum_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
102
103 printf("c_time = %d \t simd_time = %d \t Gain = %4.2f \t mode = %d \n",
104 ref_sum_time, sum_time,
105 (static_cast<float>(ref_sum_time) / static_cast<float>(sum_time)),
106 static_cast<int>(mode_));
107
108 DiffPred(0);
109 }
110
111 private:
PrepareBuffer() const112 void PrepareBuffer() const {
113 ACMRandom rnd(ACMRandom::DeterministicSeed());
114 int i = 0;
115 while (i < (2 * MaxTxSize + 1)) {
116 alloc_[i] = rnd.Rand8();
117 i++;
118 }
119 }
120
DiffPred(int testNum) const121 void DiffPred(int testNum) const {
122 int i = 0;
123 while (i < tx_size_wide[txSize_] * tx_size_high[txSize_]) {
124 EXPECT_EQ(predRef_[i], pred_[i]) << "Error at position: " << i << " "
125 << "Tx size: " << tx_size_wide[txSize_]
126 << "x" << tx_size_high[txSize_] << " "
127 << "Test number: " << testNum;
128 i++;
129 }
130 }
131
132 Predictor predFunc_;
133 Predictor predFuncRef_;
134 int mode_;
135 TX_SIZE txSize_;
136 uint8_t *alloc_;
137 uint8_t *pred_;
138 uint8_t *predRef_;
139 };
140
TEST_P(AV1FilterIntraPredTest,BitExactCheck)141 TEST_P(AV1FilterIntraPredTest, BitExactCheck) { RunTest(); }
142
TEST_P(AV1FilterIntraPredTest,DISABLED_Speed)143 TEST_P(AV1FilterIntraPredTest, DISABLED_Speed) { RunSpeedTest(); }
144
145 using ::testing::make_tuple;
146 #if HAVE_SSE4_1
147 const PredFuncMode kPredFuncMdArray[] = {
148 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
149 FILTER_DC_PRED),
150 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
151 FILTER_V_PRED),
152 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
153 FILTER_H_PRED),
154 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
155 FILTER_D157_PRED),
156 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_sse4_1,
157 FILTER_PAETH_PRED),
158 };
159
160 const TX_SIZE kTxSize[] = { TX_4X4, TX_8X8, TX_16X16, TX_32X32, TX_4X8,
161 TX_8X4, TX_8X16, TX_16X8, TX_16X32, TX_32X16,
162 TX_4X16, TX_16X4, TX_8X32, TX_32X8 };
163
164 INSTANTIATE_TEST_SUITE_P(
165 SSE4_1, AV1FilterIntraPredTest,
166 ::testing::Combine(::testing::ValuesIn(kPredFuncMdArray),
167 ::testing::ValuesIn(kTxSize)));
168 #endif // HAVE_SSE4_1
169
170 #if HAVE_NEON
171 const PredFuncMode kPredFuncMdArrayNEON[] = {
172 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
173 FILTER_DC_PRED),
174 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
175 FILTER_V_PRED),
176 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
177 FILTER_H_PRED),
178 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
179 FILTER_D157_PRED),
180 make_tuple(&av1_filter_intra_predictor_c, &av1_filter_intra_predictor_neon,
181 FILTER_PAETH_PRED),
182 };
183
184 const TX_SIZE kTxSizeNEON[] = { TX_4X4, TX_8X8, TX_16X16, TX_32X32, TX_4X8,
185 TX_8X4, TX_8X16, TX_16X8, TX_16X32, TX_32X16,
186 TX_4X16, TX_16X4, TX_8X32, TX_32X8 };
187
188 INSTANTIATE_TEST_SUITE_P(
189 NEON, AV1FilterIntraPredTest,
190 ::testing::Combine(::testing::ValuesIn(kPredFuncMdArrayNEON),
191 ::testing::ValuesIn(kTxSizeNEON)));
192 #endif // HAVE_NEON
193
194 } // namespace
195