Merge "Simplify rd_pick_intra_sby_mode()"
[platform/upstream/libvpx.git] / test / vp9_intrapred_test.cc
1 /*
2  *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11 #include <string>
12
13 #include "test/acm_random.h"
14 #include "test/clear_system_state.h"
15 #include "test/register_state_check.h"
16 #include "third_party/googletest/src/include/gtest/gtest.h"
17
18 #include "./vpx_config.h"
19 #include "./vp9_rtcd.h"
20 #include "vp9/common/vp9_blockd.h"
21 #include "vp9/common/vp9_pred_common.h"
22 #include "vpx_mem/vpx_mem.h"
23 #include "test/util.h"
24
25 namespace {
26
27 using libvpx_test::ACMRandom;
28
29 const int count_test_block = 100000;
30
31 // Base class for VP9 intra prediction tests.
32 class VP9IntraPredBase {
33  public:
34   virtual ~VP9IntraPredBase() { libvpx_test::ClearSystemState(); }
35
36  protected:
37   virtual void Predict(PREDICTION_MODE mode) = 0;
38
39   void CheckPrediction(int test_case_number, int *error_count) const {
40     // For each pixel ensure that the calculated value is the same as reference.
41     for (int y = 0; y < block_size_; y++) {
42       for (int x = 0; x < block_size_; x++) {
43         *error_count += ref_dst_[x + y * stride_] != dst_[x + y * stride_];
44         if (*error_count == 1) {
45           ASSERT_EQ(ref_dst_[x + y * stride_], dst_[x + y * stride_])
46               << " Failed on Test Case Number "<< test_case_number;
47         }
48       }
49     }
50   }
51
52   void RunTest(uint16_t* left_col, uint16_t* above_data,
53                uint16_t* dst, uint16_t* ref_dst) {
54     ACMRandom rnd(ACMRandom::DeterministicSeed());
55     left_col_ = left_col;
56     dst_ = dst;
57     ref_dst_ = ref_dst;
58     above_row_ = above_data + 16;
59     int error_count = 0;
60     for (int i = 0; i < count_test_block; ++i) {
61       // Fill edges with random data, try first with saturated values.
62       for (int x = -1; x <= block_size_*2; x++) {
63         if (i == 0) {
64           above_row_[x] = mask_;
65         } else {
66           above_row_[x] = rnd.Rand16() & mask_;
67         }
68       }
69       for (int y = 0; y < block_size_; y++) {
70         if (i == 0) {
71           left_col_[y] = mask_;
72         } else {
73           left_col_[y] = rnd.Rand16() & mask_;
74         }
75       }
76       Predict(DC_PRED);
77       CheckPrediction(i, &error_count);
78     }
79     ASSERT_EQ(0, error_count);
80   }
81
82   int block_size_;
83   uint16_t *above_row_;
84   uint16_t *left_col_;
85   uint16_t *dst_;
86   uint16_t *ref_dst_;
87   ptrdiff_t stride_;
88   int mask_;
89 };
90
91 typedef void (*intra_pred_fn_t)(
92       uint16_t *dst, ptrdiff_t stride, const uint16_t *above,
93       const uint16_t *left, int bps);
94 typedef std::tr1::tuple<intra_pred_fn_t,
95                         intra_pred_fn_t, int, int> intra_pred_params_t;
96 class VP9IntraPredTest
97     : public VP9IntraPredBase,
98       public ::testing::TestWithParam<intra_pred_params_t> {
99
100   virtual void SetUp() {
101     pred_fn_    = GET_PARAM(0);
102     ref_fn_     = GET_PARAM(1);
103     block_size_ = GET_PARAM(2);
104     bit_depth_  = GET_PARAM(3);
105     stride_     = block_size_ * 3;
106     mask_       = (1 << bit_depth_) - 1;
107   }
108
109   virtual void Predict(PREDICTION_MODE mode) {
110     const uint16_t *const_above_row = above_row_;
111     const uint16_t *const_left_col = left_col_;
112     ref_fn_(ref_dst_, stride_, const_above_row, const_left_col, bit_depth_);
113     ASM_REGISTER_STATE_CHECK(pred_fn_(dst_, stride_, const_above_row,
114                                       const_left_col, bit_depth_));
115   }
116   intra_pred_fn_t pred_fn_;
117   intra_pred_fn_t ref_fn_;
118   int bit_depth_;
119 };
120
121 TEST_P(VP9IntraPredTest, IntraPredTests) {
122   // max block size is 32
123   DECLARE_ALIGNED_ARRAY(16, uint16_t, left_col, 2*32);
124   DECLARE_ALIGNED_ARRAY(16, uint16_t, above_data, 2*32+32);
125   DECLARE_ALIGNED_ARRAY(16, uint16_t, dst, 3 * 32 * 32);
126   DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_dst, 3 * 32 * 32);
127   RunTest(left_col, above_data, dst, ref_dst);
128 }
129
130 using std::tr1::make_tuple;
131
132 #if HAVE_SSE2
133 #if CONFIG_VP9_HIGHBITDEPTH
134 #if ARCH_X86_64
135 INSTANTIATE_TEST_CASE_P(SSE2_TO_C_8, VP9IntraPredTest,
136                         ::testing::Values(
137                             make_tuple(&vp9_high_dc_predictor_32x32_sse2,
138                                        &vp9_high_dc_predictor_32x32_c, 32, 8),
139                             make_tuple(&vp9_high_tm_predictor_16x16_sse2,
140                                        &vp9_high_tm_predictor_16x16_c, 16, 8),
141                             make_tuple(&vp9_high_tm_predictor_32x32_sse2,
142                                        &vp9_high_tm_predictor_32x32_c, 32, 8),
143                             make_tuple(&vp9_high_dc_predictor_4x4_sse,
144                                        &vp9_high_dc_predictor_4x4_c, 4, 8),
145                             make_tuple(&vp9_high_dc_predictor_8x8_sse2,
146                                        &vp9_high_dc_predictor_8x8_c, 8, 8),
147                             make_tuple(&vp9_high_dc_predictor_16x16_sse2,
148                                        &vp9_high_dc_predictor_16x16_c, 16, 8),
149                             make_tuple(&vp9_high_v_predictor_4x4_sse,
150                                        &vp9_high_v_predictor_4x4_c, 4, 8),
151                             make_tuple(&vp9_high_v_predictor_8x8_sse2,
152                                        &vp9_high_v_predictor_8x8_c, 8, 8),
153                             make_tuple(&vp9_high_v_predictor_16x16_sse2,
154                                        &vp9_high_v_predictor_16x16_c, 16, 8),
155                             make_tuple(&vp9_high_v_predictor_32x32_sse2,
156                                        &vp9_high_v_predictor_32x32_c, 32, 8),
157                             make_tuple(&vp9_high_tm_predictor_4x4_sse,
158                                        &vp9_high_tm_predictor_4x4_c, 4, 8),
159                             make_tuple(&vp9_high_tm_predictor_8x8_sse2,
160                                        &vp9_high_tm_predictor_8x8_c, 8, 8)));
161 #else
162 INSTANTIATE_TEST_CASE_P(SSE2_TO_C_8, VP9IntraPredTest,
163                         ::testing::Values(
164                             make_tuple(&vp9_high_dc_predictor_4x4_sse,
165                                        &vp9_high_dc_predictor_4x4_c, 4, 8),
166                             make_tuple(&vp9_high_dc_predictor_8x8_sse2,
167                                        &vp9_high_dc_predictor_8x8_c, 8, 8),
168                             make_tuple(&vp9_high_dc_predictor_16x16_sse2,
169                                        &vp9_high_dc_predictor_16x16_c, 16, 8),
170                             make_tuple(&vp9_high_v_predictor_4x4_sse,
171                                        &vp9_high_v_predictor_4x4_c, 4, 8),
172                             make_tuple(&vp9_high_v_predictor_8x8_sse2,
173                                        &vp9_high_v_predictor_8x8_c, 8, 8),
174                             make_tuple(&vp9_high_v_predictor_16x16_sse2,
175                                        &vp9_high_v_predictor_16x16_c, 16, 8),
176                             make_tuple(&vp9_high_v_predictor_32x32_sse2,
177                                        &vp9_high_v_predictor_32x32_c, 32, 8),
178                             make_tuple(&vp9_high_tm_predictor_4x4_sse,
179                                        &vp9_high_tm_predictor_4x4_c, 4, 8),
180                             make_tuple(&vp9_high_tm_predictor_8x8_sse2,
181                                        &vp9_high_tm_predictor_8x8_c, 8, 8)));
182 #endif
183 #if ARCH_X86_64
184 INSTANTIATE_TEST_CASE_P(SSE2_TO_C_10, VP9IntraPredTest,
185                         ::testing::Values(
186                             make_tuple(&vp9_high_dc_predictor_32x32_sse2,
187                                        &vp9_high_dc_predictor_32x32_c, 32, 10),
188                             make_tuple(&vp9_high_tm_predictor_16x16_sse2,
189                                        &vp9_high_tm_predictor_16x16_c, 16, 10),
190                             make_tuple(&vp9_high_tm_predictor_32x32_sse2,
191                                        &vp9_high_tm_predictor_32x32_c, 32, 10),
192                             make_tuple(&vp9_high_dc_predictor_4x4_sse,
193                                        &vp9_high_dc_predictor_4x4_c, 4, 10),
194                             make_tuple(&vp9_high_dc_predictor_8x8_sse2,
195                                        &vp9_high_dc_predictor_8x8_c, 8, 10),
196                             make_tuple(&vp9_high_dc_predictor_16x16_sse2,
197                                    &vp9_high_dc_predictor_16x16_c, 16, 10),
198                             make_tuple(&vp9_high_v_predictor_4x4_sse,
199                                        &vp9_high_v_predictor_4x4_c, 4, 10),
200                             make_tuple(&vp9_high_v_predictor_8x8_sse2,
201                                        &vp9_high_v_predictor_8x8_c, 8, 10),
202                             make_tuple(&vp9_high_v_predictor_16x16_sse2,
203                                        &vp9_high_v_predictor_16x16_c, 16, 10),
204                             make_tuple(&vp9_high_v_predictor_32x32_sse2,
205                                        &vp9_high_v_predictor_32x32_c, 32, 10),
206                             make_tuple(&vp9_high_tm_predictor_4x4_sse,
207                                        &vp9_high_tm_predictor_4x4_c, 4, 10),
208                             make_tuple(&vp9_high_tm_predictor_8x8_sse2,
209                                        &vp9_high_tm_predictor_8x8_c, 8, 10)));
210 #else
211 INSTANTIATE_TEST_CASE_P(SSE2_TO_C_10, VP9IntraPredTest,
212                         ::testing::Values(
213                             make_tuple(&vp9_high_dc_predictor_4x4_sse,
214                                        &vp9_high_dc_predictor_4x4_c, 4, 10),
215                             make_tuple(&vp9_high_dc_predictor_8x8_sse2,
216                                        &vp9_high_dc_predictor_8x8_c, 8, 10),
217                             make_tuple(&vp9_high_dc_predictor_16x16_sse2,
218                                        &vp9_high_dc_predictor_16x16_c, 16, 10),
219                             make_tuple(&vp9_high_v_predictor_4x4_sse,
220                                        &vp9_high_v_predictor_4x4_c, 4, 10),
221                             make_tuple(&vp9_high_v_predictor_8x8_sse2,
222                                        &vp9_high_v_predictor_8x8_c, 8, 10),
223                             make_tuple(&vp9_high_v_predictor_16x16_sse2,
224                                        &vp9_high_v_predictor_16x16_c, 16, 10),
225                             make_tuple(&vp9_high_v_predictor_32x32_sse2,
226                                        &vp9_high_v_predictor_32x32_c, 32, 10),
227                             make_tuple(&vp9_high_tm_predictor_4x4_sse,
228                                    &vp9_high_tm_predictor_4x4_c, 4, 10),
229                             make_tuple(&vp9_high_tm_predictor_8x8_sse2,
230                                        &vp9_high_tm_predictor_8x8_c, 8, 10)));
231 #endif
232
233 #if ARCH_X86_64
234 INSTANTIATE_TEST_CASE_P(SSE2_TO_C_12, VP9IntraPredTest,
235                         ::testing::Values(
236                             make_tuple(&vp9_high_dc_predictor_32x32_sse2,
237                                        &vp9_high_dc_predictor_32x32_c, 32, 12),
238                             make_tuple(&vp9_high_tm_predictor_16x16_sse2,
239                                        &vp9_high_tm_predictor_16x16_c, 16, 12),
240                             make_tuple(&vp9_high_tm_predictor_32x32_sse2,
241                                        &vp9_high_tm_predictor_32x32_c, 32, 12),
242                             make_tuple(&vp9_high_dc_predictor_4x4_sse,
243                                        &vp9_high_dc_predictor_4x4_c, 4, 12),
244                             make_tuple(&vp9_high_dc_predictor_8x8_sse2,
245                                        &vp9_high_dc_predictor_8x8_c, 8, 12),
246                             make_tuple(&vp9_high_dc_predictor_16x16_sse2,
247                                        &vp9_high_dc_predictor_16x16_c, 16, 12),
248                             make_tuple(&vp9_high_v_predictor_4x4_sse,
249                                        &vp9_high_v_predictor_4x4_c, 4, 12),
250                             make_tuple(&vp9_high_v_predictor_8x8_sse2,
251                                        &vp9_high_v_predictor_8x8_c, 8, 12),
252                             make_tuple(&vp9_high_v_predictor_16x16_sse2,
253                                        &vp9_high_v_predictor_16x16_c, 16, 12),
254                             make_tuple(&vp9_high_v_predictor_32x32_sse2,
255                                        &vp9_high_v_predictor_32x32_c, 32, 12),
256                             make_tuple(&vp9_high_tm_predictor_4x4_sse,
257                                        &vp9_high_tm_predictor_4x4_c, 4, 12),
258                             make_tuple(&vp9_high_tm_predictor_8x8_sse2,
259                                        &vp9_high_tm_predictor_8x8_c, 8, 12)));
260 #else
261 INSTANTIATE_TEST_CASE_P(SSE2_TO_C_12, VP9IntraPredTest,
262                         ::testing::Values(
263                             make_tuple(&vp9_high_dc_predictor_4x4_sse,
264                                        &vp9_high_dc_predictor_4x4_c, 4, 12),
265                             make_tuple(&vp9_high_dc_predictor_8x8_sse2,
266                                        &vp9_high_dc_predictor_8x8_c, 8, 12),
267                             make_tuple(&vp9_high_dc_predictor_16x16_sse2,
268                                        &vp9_high_dc_predictor_16x16_c, 16, 12),
269                             make_tuple(&vp9_high_v_predictor_4x4_sse,
270                                        &vp9_high_v_predictor_4x4_c, 4, 12),
271                             make_tuple(&vp9_high_v_predictor_8x8_sse2,
272                                        &vp9_high_v_predictor_8x8_c, 8, 12),
273                             make_tuple(&vp9_high_v_predictor_16x16_sse2,
274                                        &vp9_high_v_predictor_16x16_c, 16, 12),
275                             make_tuple(&vp9_high_v_predictor_32x32_sse2,
276                                        &vp9_high_v_predictor_32x32_c, 32, 12),
277                             make_tuple(&vp9_high_tm_predictor_4x4_sse,
278                                        &vp9_high_tm_predictor_4x4_c, 4, 12),
279                             make_tuple(&vp9_high_tm_predictor_8x8_sse2,
280                                        &vp9_high_tm_predictor_8x8_c, 8, 12)));
281 #endif
282 #endif  // CONFIG_VP9_HIGHBITDEPTH
283 #endif  // HAVE_SSE2
284 }  // namespace