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