1 /*
2 * Copyright (c) 2010 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 <stdlib.h>
12
13 #include "./vp9_rtcd.h"
14 #include "./vpx_config.h"
15
16 #include "vpx/vpx_integer.h"
17 #if CONFIG_VP9_HIGHBITDEPTH
18 #include "vp9/common/vp9_common.h"
19 #endif
20 #include "vp9/encoder/vp9_variance.h"
21
sad(const uint8_t * a,int a_stride,const uint8_t * b,int b_stride,int width,int height)22 static INLINE unsigned int sad(const uint8_t *a, int a_stride,
23 const uint8_t *b, int b_stride,
24 int width, int height) {
25 int y, x;
26 unsigned int sad = 0;
27
28 for (y = 0; y < height; y++) {
29 for (x = 0; x < width; x++)
30 sad += abs(a[x] - b[x]);
31
32 a += a_stride;
33 b += b_stride;
34 }
35
36 return sad;
37 }
38
39 #define sadMxN(m, n) \
40 unsigned int vp9_sad##m##x##n##_c(const uint8_t *src, int src_stride, \
41 const uint8_t *ref, int ref_stride) { \
42 return sad(src, src_stride, ref, ref_stride, m, n); \
43 } \
44 unsigned int vp9_sad##m##x##n##_avg_c(const uint8_t *src, int src_stride, \
45 const uint8_t *ref, int ref_stride, \
46 const uint8_t *second_pred) { \
47 uint8_t comp_pred[m * n]; \
48 vp9_comp_avg_pred(comp_pred, second_pred, m, n, ref, ref_stride); \
49 return sad(src, src_stride, comp_pred, m, m, n); \
50 }
51
52 #define sadMxNxK(m, n, k) \
53 void vp9_sad##m##x##n##x##k##_c(const uint8_t *src, int src_stride, \
54 const uint8_t *ref, int ref_stride, \
55 unsigned int *sads) { \
56 int i; \
57 for (i = 0; i < k; ++i) \
58 sads[i] = vp9_sad##m##x##n##_c(src, src_stride, &ref[i], ref_stride); \
59 }
60
61 #define sadMxNx4D(m, n) \
62 void vp9_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride, \
63 const uint8_t *const refs[], int ref_stride, \
64 unsigned int *sads) { \
65 int i; \
66 for (i = 0; i < 4; ++i) \
67 sads[i] = vp9_sad##m##x##n##_c(src, src_stride, refs[i], ref_stride); \
68 }
69
70 // 64x64
71 sadMxN(64, 64)
72 sadMxNxK(64, 64, 3)
73 sadMxNxK(64, 64, 8)
74 sadMxNx4D(64, 64)
75
76 // 64x32
77 sadMxN(64, 32)
78 sadMxNx4D(64, 32)
79
80 // 32x64
81 sadMxN(32, 64)
82 sadMxNx4D(32, 64)
83
84 // 32x32
85 sadMxN(32, 32)
86 sadMxNxK(32, 32, 3)
87 sadMxNxK(32, 32, 8)
88 sadMxNx4D(32, 32)
89
90 // 32x16
91 sadMxN(32, 16)
92 sadMxNx4D(32, 16)
93
94 // 16x32
95 sadMxN(16, 32)
96 sadMxNx4D(16, 32)
97
98 // 16x16
99 sadMxN(16, 16)
100 sadMxNxK(16, 16, 3)
101 sadMxNxK(16, 16, 8)
102 sadMxNx4D(16, 16)
103
104 // 16x8
105 sadMxN(16, 8)
106 sadMxNxK(16, 8, 3)
107 sadMxNxK(16, 8, 8)
108 sadMxNx4D(16, 8)
109
110 // 8x16
111 sadMxN(8, 16)
112 sadMxNxK(8, 16, 3)
113 sadMxNxK(8, 16, 8)
114 sadMxNx4D(8, 16)
115
116 // 8x8
117 sadMxN(8, 8)
118 sadMxNxK(8, 8, 3)
119 sadMxNxK(8, 8, 8)
120 sadMxNx4D(8, 8)
121
122 // 8x4
123 sadMxN(8, 4)
124 sadMxNxK(8, 4, 8)
125 sadMxNx4D(8, 4)
126
127 // 4x8
128 sadMxN(4, 8)
129 sadMxNxK(4, 8, 8)
130 sadMxNx4D(4, 8)
131
132 // 4x4
133 sadMxN(4, 4)
134 sadMxNxK(4, 4, 3)
135 sadMxNxK(4, 4, 8)
136 sadMxNx4D(4, 4)
137
138 #if CONFIG_VP9_HIGHBITDEPTH
high_sad(const uint8_t * a8,int a_stride,const uint8_t * b8,int b_stride,int width,int height)139 static INLINE unsigned int high_sad(const uint8_t *a8, int a_stride,
140 const uint8_t *b8, int b_stride,
141 int width, int height) {
142 int y, x;
143 unsigned int sad = 0;
144 const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
145 const uint16_t *b = CONVERT_TO_SHORTPTR(b8);
146 for (y = 0; y < height; y++) {
147 for (x = 0; x < width; x++)
148 sad += abs(a[x] - b[x]);
149
150 a += a_stride;
151 b += b_stride;
152 }
153 return sad;
154 }
155
high_sadb(const uint8_t * a8,int a_stride,const uint16_t * b,int b_stride,int width,int height)156 static INLINE unsigned int high_sadb(const uint8_t *a8, int a_stride,
157 const uint16_t *b, int b_stride,
158 int width, int height) {
159 int y, x;
160 unsigned int sad = 0;
161 const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
162 for (y = 0; y < height; y++) {
163 for (x = 0; x < width; x++)
164 sad += abs(a[x] - b[x]);
165
166 a += a_stride;
167 b += b_stride;
168 }
169 return sad;
170 }
171
172 #define high_sadMxN(m, n) \
173 unsigned int vp9_high_sad##m##x##n##_c(const uint8_t *src, int src_stride, \
174 const uint8_t *ref, int ref_stride) { \
175 return high_sad(src, src_stride, ref, ref_stride, m, n); \
176 } \
177 unsigned int vp9_high_sad##m##x##n##_avg_c(const uint8_t *src, int src_stride, \
178 const uint8_t *ref, int ref_stride, \
179 const uint8_t *second_pred) { \
180 uint16_t comp_pred[m * n]; \
181 vp9_high_comp_avg_pred(comp_pred, second_pred, m, n, ref, ref_stride); \
182 return high_sadb(src, src_stride, comp_pred, m, m, n); \
183 }
184
185 #define high_sadMxNxK(m, n, k) \
186 void vp9_high_sad##m##x##n##x##k##_c(const uint8_t *src, int src_stride, \
187 const uint8_t *ref, int ref_stride, \
188 unsigned int *sads) { \
189 int i; \
190 for (i = 0; i < k; ++i) \
191 sads[i] = vp9_high_sad##m##x##n##_c(src, src_stride, &ref[i], ref_stride); \
192 }
193
194 #define high_sadMxNx4D(m, n) \
195 void vp9_high_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride, \
196 const uint8_t *const refs[], \
197 int ref_stride, unsigned int *sads) { \
198 int i; \
199 for (i = 0; i < 4; ++i) \
200 sads[i] = vp9_high_sad##m##x##n##_c(src, src_stride, refs[i], ref_stride); \
201 }
202
203 // 64x64
204 high_sadMxN(64, 64)
205 high_sadMxNxK(64, 64, 3)
206 high_sadMxNxK(64, 64, 8)
207 high_sadMxNx4D(64, 64)
208
209 // 64x32
210 high_sadMxN(64, 32)
211 high_sadMxNx4D(64, 32)
212
213 // 32x64
214 high_sadMxN(32, 64)
215 high_sadMxNx4D(32, 64)
216
217 // 32x32
218 high_sadMxN(32, 32)
219 high_sadMxNxK(32, 32, 3)
220 high_sadMxNxK(32, 32, 8)
221 high_sadMxNx4D(32, 32)
222
223 // 32x16
224 high_sadMxN(32, 16)
225 high_sadMxNx4D(32, 16)
226
227 // 16x32
228 high_sadMxN(16, 32)
229 high_sadMxNx4D(16, 32)
230
231 // 16x16
232 high_sadMxN(16, 16)
233 high_sadMxNxK(16, 16, 3)
234 high_sadMxNxK(16, 16, 8)
235 high_sadMxNx4D(16, 16)
236
237 // 16x8
238 high_sadMxN(16, 8)
239 high_sadMxNxK(16, 8, 3)
240 high_sadMxNxK(16, 8, 8)
241 high_sadMxNx4D(16, 8)
242
243 // 8x16
244 high_sadMxN(8, 16)
245 high_sadMxNxK(8, 16, 3)
246 high_sadMxNxK(8, 16, 8)
247 high_sadMxNx4D(8, 16)
248
249 // 8x8
250 high_sadMxN(8, 8)
251 high_sadMxNxK(8, 8, 3)
252 high_sadMxNxK(8, 8, 8)
253 high_sadMxNx4D(8, 8)
254
255 // 8x4
256 high_sadMxN(8, 4)
257 high_sadMxNxK(8, 4, 8)
258 high_sadMxNx4D(8, 4)
259
260 // 4x8
261 high_sadMxN(4, 8)
262 high_sadMxNxK(4, 8, 8)
263 high_sadMxNx4D(4, 8)
264
265 // 4x4
266 high_sadMxN(4, 4)
267 high_sadMxNxK(4, 4, 3)
268 high_sadMxNxK(4, 4, 8)
269 high_sadMxNx4D(4, 4)
270
271 #endif // CONFIG_VP9_HIGHBITDEPTH
272