2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
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.
14 #include "test/acm_random.h"
15 #include "test/clear_system_state.h"
16 #include "test/register_state_check.h"
17 #include "test/util.h"
18 #include "third_party/googletest/src/include/gtest/gtest.h"
19 #include "./vpx_config.h"
20 #include "./vp8_rtcd.h"
21 #include "vpx/vpx_integer.h"
22 #include "vpx_mem/vpx_mem.h"
26 typedef void (*sixtap_predict_fn_t)(uint8_t *src_ptr,
27 int src_pixels_per_line,
33 typedef std::tr1::tuple<int, int, sixtap_predict_fn_t> sixtap_predict_param_t;
35 class SixtapPredictTest
36 : public ::testing::TestWithParam<sixtap_predict_param_t> {
38 static void SetUpTestCase() {
39 src_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kSrcSize));
40 dst_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kDstSize));
41 dst_c_ = reinterpret_cast<uint8_t*>(vpx_memalign(kDataAlignment, kDstSize));
44 static void TearDownTestCase() {
53 virtual void TearDown() {
54 libvpx_test::ClearSystemState();
58 // Make test arrays big enough for 16x16 functions. Six-tap filters
59 // need 5 extra pixels outside of the macroblock.
60 static const int kSrcStride = 21;
61 static const int kDstStride = 16;
62 static const int kDataAlignment = 16;
63 static const int kSrcSize = kSrcStride * kSrcStride + 1;
64 static const int kDstSize = kDstStride * kDstStride;
66 virtual void SetUp() {
67 width_ = GET_PARAM(0);
68 height_ = GET_PARAM(1);
69 sixtap_predict_ = GET_PARAM(2);
70 memset(src_, 0, kSrcSize);
71 memset(dst_, 0, kDstSize);
72 memset(dst_c_, 0, kDstSize);
77 sixtap_predict_fn_t sixtap_predict_;
78 // The src stores the macroblock we will filter on, and makes it 1 byte larger
79 // in order to test unaligned access. The result is stored in dst and dst_c(c
80 // reference code result).
83 static uint8_t* dst_c_;
86 uint8_t* SixtapPredictTest::src_ = NULL;
87 uint8_t* SixtapPredictTest::dst_ = NULL;
88 uint8_t* SixtapPredictTest::dst_c_ = NULL;
90 TEST_P(SixtapPredictTest, TestWithPresetData) {
92 static const uint8_t test_data[kSrcSize] = {
93 216, 184, 4, 191, 82, 92, 41, 0, 1, 226, 236, 172, 20, 182, 42, 226, 177,
94 79, 94, 77, 179, 203, 206, 198, 22, 192, 19, 75, 17, 192, 44, 233, 120,
95 48, 168, 203, 141, 210, 203, 143, 180, 184, 59, 201, 110, 102, 171, 32,
96 182, 10, 109, 105, 213, 60, 47, 236, 253, 67, 55, 14, 3, 99, 247, 124,
97 148, 159, 71, 34, 114, 19, 177, 38, 203, 237, 239, 58, 83, 155, 91, 10,
98 166, 201, 115, 124, 5, 163, 104, 2, 231, 160, 16, 234, 4, 8, 103, 153,
99 167, 174, 187, 26, 193, 109, 64, 141, 90, 48, 200, 174, 204, 36, 184,
100 114, 237, 43, 238, 242, 207, 86, 245, 182, 247, 6, 161, 251, 14, 8, 148,
101 182, 182, 79, 208, 120, 188, 17, 6, 23, 65, 206, 197, 13, 242, 126, 128,
102 224, 170, 110, 211, 121, 197, 200, 47, 188, 207, 208, 184, 221, 216, 76,
103 148, 143, 156, 100, 8, 89, 117, 14, 112, 183, 221, 54, 197, 208, 180, 69,
104 176, 94, 180, 131, 215, 121, 76, 7, 54, 28, 216, 238, 249, 176, 58, 142,
105 64, 215, 242, 72, 49, 104, 87, 161, 32, 52, 216, 230, 4, 141, 44, 181,
106 235, 224, 57, 195, 89, 134, 203, 144, 162, 163, 126, 156, 84, 185, 42,
107 148, 145, 29, 221, 194, 134, 52, 100, 166, 105, 60, 140, 110, 201, 184,
108 35, 181, 153, 93, 121, 243, 227, 68, 131, 134, 232, 2, 35, 60, 187, 77,
109 209, 76, 106, 174, 15, 241, 227, 115, 151, 77, 175, 36, 187, 121, 221,
110 223, 47, 118, 61, 168, 105, 32, 237, 236, 167, 213, 238, 202, 17, 170,
111 24, 226, 247, 131, 145, 6, 116, 117, 121, 11, 194, 41, 48, 126, 162, 13,
112 93, 209, 131, 154, 122, 237, 187, 103, 217, 99, 60, 200, 45, 78, 115, 69,
113 49, 106, 200, 194, 112, 60, 56, 234, 72, 251, 19, 120, 121, 182, 134, 215,
114 135, 10, 114, 2, 247, 46, 105, 209, 145, 165, 153, 191, 243, 12, 5, 36,
115 119, 206, 231, 231, 11, 32, 209, 83, 27, 229, 204, 149, 155, 83, 109, 35,
116 93, 223, 37, 84, 14, 142, 37, 160, 52, 191, 96, 40, 204, 101, 77, 67, 52,
117 53, 43, 63, 85, 253, 147, 113, 226, 96, 6, 125, 179, 115, 161, 17, 83,
118 198, 101, 98, 85, 139, 3, 137, 75, 99, 178, 23, 201, 255, 91, 253, 52,
119 134, 60, 138, 131, 208, 251, 101, 48, 2, 227, 228, 118, 132, 245, 202,
120 75, 91, 44, 160, 231, 47, 41, 50, 147, 220, 74, 92, 219, 165, 89, 16
124 static const uint8_t expected_dst[kDstSize] = {
125 117, 102, 74, 135, 42, 98, 175, 206, 70, 73, 222, 197, 50, 24, 39, 49, 38,
126 105, 90, 47, 169, 40, 171, 215, 200, 73, 109, 141, 53, 85, 177, 164, 79,
127 208, 124, 89, 212, 18, 81, 145, 151, 164, 217, 153, 91, 154, 102, 102,
128 159, 75, 164, 152, 136, 51, 213, 219, 186, 116, 193, 224, 186, 36, 231,
129 208, 84, 211, 155, 167, 35, 59, 42, 76, 216, 149, 73, 201, 78, 149, 184,
130 100, 96, 196, 189, 198, 188, 235, 195, 117, 129, 120, 129, 49, 25, 133,
131 113, 69, 221, 114, 70, 143, 99, 157, 108, 189, 140, 78, 6, 55, 65, 240,
132 255, 245, 184, 72, 90, 100, 116, 131, 39, 60, 234, 167, 33, 160, 88, 185,
133 200, 157, 159, 176, 127, 151, 138, 102, 168, 106, 170, 86, 82, 219, 189,
134 76, 33, 115, 197, 106, 96, 198, 136, 97, 141, 237, 151, 98, 137, 191,
135 185, 2, 57, 95, 142, 91, 255, 185, 97, 137, 76, 162, 94, 173, 131, 193,
136 161, 81, 106, 72, 135, 222, 234, 137, 66, 137, 106, 243, 210, 147, 95,
137 15, 137, 110, 85, 66, 16, 96, 167, 147, 150, 173, 203, 140, 118, 196,
138 84, 147, 160, 19, 95, 101, 123, 74, 132, 202, 82, 166, 12, 131, 166,
139 189, 170, 159, 85, 79, 66, 57, 152, 132, 203, 194, 0, 1, 56, 146, 180,
140 224, 156, 28, 83, 181, 79, 76, 80, 46, 160, 175, 59, 106, 43, 87, 75,
141 136, 85, 189, 46, 71, 200, 90
144 uint8_t *src = const_cast<uint8_t*>(test_data);
146 REGISTER_STATE_CHECK(sixtap_predict_(&src[kSrcStride * 2 + 2 + 1], kSrcStride,
147 2, 2, dst_, kDstStride));
149 for (int i = 0; i < height_; ++i)
150 for (int j = 0; j < width_; ++j)
151 ASSERT_EQ(expected_dst[i * kDstStride + j], dst_[i * kDstStride + j])
152 << "i==" << (i * width_ + j);
155 using libvpx_test::ACMRandom;
157 TEST_P(SixtapPredictTest, TestWithRandomData) {
158 ACMRandom rnd(ACMRandom::DeterministicSeed());
159 for (int i = 0; i < kSrcSize; ++i)
160 src_[i] = rnd.Rand8();
162 // Run tests for all possible offsets.
163 for (int xoffset = 0; xoffset < 8; ++xoffset) {
164 for (int yoffset = 0; yoffset < 8; ++yoffset) {
165 // Call c reference function.
166 // Move start point to next pixel to test if the function reads
167 // unaligned data correctly.
168 vp8_sixtap_predict16x16_c(&src_[kSrcStride * 2 + 2 + 1], kSrcStride,
169 xoffset, yoffset, dst_c_, kDstStride);
172 REGISTER_STATE_CHECK(
173 sixtap_predict_(&src_[kSrcStride * 2 + 2 + 1], kSrcStride,
174 xoffset, yoffset, dst_, kDstStride));
176 for (int i = 0; i < height_; ++i)
177 for (int j = 0; j < width_; ++j)
178 ASSERT_EQ(dst_c_[i * kDstStride + j], dst_[i * kDstStride + j])
179 << "i==" << (i * width_ + j);
184 using std::tr1::make_tuple;
186 const sixtap_predict_fn_t sixtap_16x16_c = vp8_sixtap_predict16x16_c;
187 const sixtap_predict_fn_t sixtap_8x8_c = vp8_sixtap_predict8x8_c;
188 const sixtap_predict_fn_t sixtap_8x4_c = vp8_sixtap_predict8x4_c;
189 const sixtap_predict_fn_t sixtap_4x4_c = vp8_sixtap_predict4x4_c;
190 INSTANTIATE_TEST_CASE_P(
191 C, SixtapPredictTest, ::testing::Values(
192 make_tuple(16, 16, sixtap_16x16_c),
193 make_tuple(8, 8, sixtap_8x8_c),
194 make_tuple(8, 4, sixtap_8x4_c),
195 make_tuple(4, 4, sixtap_4x4_c)));
197 const sixtap_predict_fn_t sixtap_16x16_neon = vp8_sixtap_predict16x16_neon;
198 const sixtap_predict_fn_t sixtap_8x8_neon = vp8_sixtap_predict8x8_neon;
199 const sixtap_predict_fn_t sixtap_8x4_neon = vp8_sixtap_predict8x4_neon;
200 INSTANTIATE_TEST_CASE_P(
201 NEON, SixtapPredictTest, ::testing::Values(
202 make_tuple(16, 16, sixtap_16x16_neon),
203 make_tuple(8, 8, sixtap_8x8_neon),
204 make_tuple(8, 4, sixtap_8x4_neon)));
207 const sixtap_predict_fn_t sixtap_16x16_mmx = vp8_sixtap_predict16x16_mmx;
208 const sixtap_predict_fn_t sixtap_8x8_mmx = vp8_sixtap_predict8x8_mmx;
209 const sixtap_predict_fn_t sixtap_8x4_mmx = vp8_sixtap_predict8x4_mmx;
210 const sixtap_predict_fn_t sixtap_4x4_mmx = vp8_sixtap_predict4x4_mmx;
211 INSTANTIATE_TEST_CASE_P(
212 MMX, SixtapPredictTest, ::testing::Values(
213 make_tuple(16, 16, sixtap_16x16_mmx),
214 make_tuple(8, 8, sixtap_8x8_mmx),
215 make_tuple(8, 4, sixtap_8x4_mmx),
216 make_tuple(4, 4, sixtap_4x4_mmx)));
219 const sixtap_predict_fn_t sixtap_16x16_sse2 = vp8_sixtap_predict16x16_sse2;
220 const sixtap_predict_fn_t sixtap_8x8_sse2 = vp8_sixtap_predict8x8_sse2;
221 const sixtap_predict_fn_t sixtap_8x4_sse2 = vp8_sixtap_predict8x4_sse2;
222 INSTANTIATE_TEST_CASE_P(
223 SSE2, SixtapPredictTest, ::testing::Values(
224 make_tuple(16, 16, sixtap_16x16_sse2),
225 make_tuple(8, 8, sixtap_8x8_sse2),
226 make_tuple(8, 4, sixtap_8x4_sse2)));
229 const sixtap_predict_fn_t sixtap_16x16_ssse3 = vp8_sixtap_predict16x16_ssse3;
230 const sixtap_predict_fn_t sixtap_8x8_ssse3 = vp8_sixtap_predict8x8_ssse3;
231 const sixtap_predict_fn_t sixtap_8x4_ssse3 = vp8_sixtap_predict8x4_ssse3;
232 const sixtap_predict_fn_t sixtap_4x4_ssse3 = vp8_sixtap_predict4x4_ssse3;
233 INSTANTIATE_TEST_CASE_P(
234 SSSE3, SixtapPredictTest, ::testing::Values(
235 make_tuple(16, 16, sixtap_16x16_ssse3),
236 make_tuple(8, 8, sixtap_8x8_ssse3),
237 make_tuple(8, 4, sixtap_8x4_ssse3),
238 make_tuple(4, 4, sixtap_4x4_ssse3)));