Line data Source code
1 : /*
2 : * Copyright(c) 2019 Intel Corporation
3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 : */
5 :
6 : #include "EbComputeSAD_C.h"
7 : #include "EbUtility.h"
8 :
9 : /*******************************************
10 : * combined_averaging_sad
11 : *
12 : *******************************************/
13 0 : uint32_t combined_averaging_sad(
14 : uint8_t *src,
15 : uint32_t src_stride,
16 : uint8_t *ref1,
17 : uint32_t ref1_stride,
18 : uint8_t *ref2,
19 : uint32_t ref2_stride,
20 : uint32_t height,
21 : uint32_t width)
22 : {
23 : uint32_t x, y;
24 0 : uint32_t sad = 0;
25 : uint8_t avgpel;
26 :
27 0 : for (y = 0; y < height; y++)
28 : {
29 0 : for (x = 0; x < width; x++)
30 : {
31 0 : avgpel = (ref1[x] + ref2[x] + 1) >> 1;
32 0 : sad += EB_ABS_DIFF(src[x], avgpel);
33 : }
34 0 : src += src_stride;
35 0 : ref1 += ref1_stride;
36 0 : ref2 += ref2_stride;
37 : }
38 :
39 0 : return sad;
40 : }
41 :
42 : /*******************************************
43 : * returns NxM Sum of Absolute Differences
44 : Note: moved from picture operators.
45 : keep this function here for profiling
46 : issues.
47 : *******************************************/
48 0 : uint32_t fast_loop_nxm_sad_kernel(
49 : const uint8_t *src, // input parameter, source samples Ptr
50 : uint32_t src_stride, // input parameter, source stride
51 : const uint8_t *ref, // input parameter, reference samples Ptr
52 : uint32_t ref_stride, // input parameter, reference stride
53 : uint32_t height, // input parameter, block height (M)
54 : uint32_t width) // input parameter, block width (N)
55 : {
56 : uint32_t x, y;
57 0 : uint32_t sad = 0;
58 :
59 0 : for (y = 0; y < height; y++)
60 : {
61 0 : for (x = 0; x < width; x++)
62 0 : sad += EB_ABS_DIFF(src[x], ref[x]);
63 0 : src += src_stride;
64 0 : ref += ref_stride;
65 : }
66 :
67 0 : return sad;
68 : }
69 :
70 0 : uint32_t sad_16b_kernel(
71 : uint16_t *src, // input parameter, source samples Ptr
72 : uint32_t src_stride, // input parameter, source stride
73 : uint16_t *ref, // input parameter, reference samples Ptr
74 : uint32_t ref_stride, // input parameter, reference stride
75 : uint32_t height, // input parameter, block height (M)
76 : uint32_t width) // input parameter, block width (N)
77 : {
78 : uint32_t x, y;
79 0 : uint32_t sad = 0;
80 :
81 0 : for (y = 0; y < height; y++) {
82 0 : for (x = 0; x < width; x++)
83 0 : sad += EB_ABS_DIFF(src[x], ref[x]);
84 0 : src += src_stride;
85 0 : ref += ref_stride;
86 : }
87 :
88 0 : return sad;
89 : }
90 :
91 0 : void sad_loop_kernel_sparse_c(
92 : uint8_t *src, // input parameter, source samples Ptr
93 : uint32_t srcStride, // input parameter, source stride
94 : uint8_t *ref, // input parameter, reference samples Ptr
95 : uint32_t refStride, // input parameter, reference stride
96 : uint32_t block_height, // input parameter, block height (M)
97 : uint32_t block_width, // input parameter, block width (N)
98 : uint64_t *bestSad,
99 : int16_t *xSearchCenter,
100 : int16_t *ySearchCenter,
101 : uint32_t srcStrideRaw, // input parameter, source stride (no line skipping)
102 : int16_t searchAreaWidth, int16_t searchAreaHeight) {
103 : int16_t xSearchIndex;
104 : int16_t ySearchIndex;
105 :
106 0 : *bestSad = 0xffffff;
107 :
108 0 : for (ySearchIndex = 0; ySearchIndex < searchAreaHeight; ySearchIndex++) {
109 0 : for (xSearchIndex = 0; xSearchIndex < searchAreaWidth; xSearchIndex++) {
110 0 : uint8_t doThisPoint = 0;
111 0 : uint32_t group = (xSearchIndex / 8);
112 0 : if ((group & 1) == (ySearchIndex & 1))
113 0 : doThisPoint = 1;
114 :
115 0 : if (doThisPoint) {
116 : uint32_t x, y;
117 0 : uint32_t sad = 0;
118 :
119 0 : for (y = 0; y < block_height; y++) {
120 0 : for (x = 0; x < block_width; x++)
121 0 : sad +=
122 0 : EB_ABS_DIFF(src[y * srcStride + x],
123 : ref[xSearchIndex + y * refStride + x]);
124 : }
125 :
126 : // Update results
127 0 : if (sad < *bestSad) {
128 0 : *bestSad = sad;
129 0 : *xSearchCenter = xSearchIndex;
130 0 : *ySearchCenter = ySearchIndex;
131 : }
132 : }
133 : }
134 :
135 0 : ref += srcStrideRaw;
136 : }
137 :
138 0 : return;
139 : }
140 :
141 0 : void sad_loop_kernel_c(
142 : uint8_t *src, // input parameter, source samples Ptr
143 : uint32_t src_stride, // input parameter, source stride
144 : uint8_t *ref, // input parameter, reference samples Ptr
145 : uint32_t ref_stride, // input parameter, reference stride
146 : uint32_t block_height, // input parameter, block height (M)
147 : uint32_t block_width, // input parameter, block width (N)
148 : uint64_t *best_sad,
149 : int16_t *x_search_center,
150 : int16_t *y_search_center,
151 : uint32_t src_stride_raw, // input parameter, source stride (no line skipping)
152 : int16_t search_area_width,
153 : int16_t search_area_height)
154 : {
155 : int16_t xSearchIndex;
156 : int16_t ySearchIndex;
157 :
158 0 : *best_sad = 0xffffff;
159 :
160 0 : for (ySearchIndex = 0; ySearchIndex < search_area_height; ySearchIndex++)
161 : {
162 0 : for (xSearchIndex = 0; xSearchIndex < search_area_width; xSearchIndex++)
163 : {
164 : uint32_t x, y;
165 0 : uint32_t sad = 0;
166 :
167 0 : for (y = 0; y < block_height; y++)
168 : {
169 0 : for (x = 0; x < block_width; x++)
170 0 : sad += EB_ABS_DIFF(src[y*src_stride + x], ref[xSearchIndex + y * ref_stride + x]);
171 : }
172 :
173 : // Update results
174 0 : if (sad < *best_sad)
175 : {
176 0 : *best_sad = sad;
177 0 : *x_search_center = xSearchIndex;
178 0 : *y_search_center = ySearchIndex;
179 : }
180 : }
181 :
182 0 : ref += src_stride_raw;
183 : }
184 :
185 0 : return;
186 : }
187 :
188 : /* Sum the difference between every corresponding element of the buffers. */
189 0 : static INLINE uint32_t sad_inline_c(const uint8_t *a, int a_stride,
190 : const uint8_t *b, int b_stride, int width, int height) {
191 : int y, x;
192 0 : unsigned int sad = 0;
193 :
194 0 : for (y = 0; y < height; y++) {
195 0 : for (x = 0; x < width; x++)
196 0 : sad += EB_ABS_DIFF(a[x], b[x]);
197 0 : a += a_stride;
198 0 : b += b_stride;
199 : }
200 0 : return sad;
201 : }
202 :
203 : #define sadMxN(m, n) \
204 : uint32_t eb_aom_sad##m##x##n##_c(const uint8_t *src, int src_stride, \
205 : const uint8_t *ref, int ref_stride) { \
206 : return sad_inline_c(src, src_stride, ref, ref_stride, m, n); \
207 : }
208 :
209 : // Calculate sad against 4 reference locations and store each in sad_array
210 : #define sadMxNx4D(m, n) \
211 : void eb_aom_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride, \
212 : const uint8_t *const ref_array[], \
213 : int ref_stride, uint32_t *sad_array) { \
214 : int i; \
215 : for (i = 0; i < 4; ++i) { \
216 : sad_array[i] = \
217 : eb_aom_sad##m##x##n##_c(src, src_stride, ref_array[i], ref_stride); \
218 : } \
219 : }
220 :
221 : // 128x128
222 0 : sadMxN(128, 128);
223 0 : sadMxNx4D(128, 128);
224 :
225 : // 128x64
226 0 : sadMxN(128, 64);
227 0 : sadMxNx4D(128, 64);
228 :
229 : // 64x128
230 0 : sadMxN(64, 128);
231 0 : sadMxNx4D(64, 128);
232 :
233 : // 64x64
234 0 : sadMxN(64, 64);
235 0 : sadMxNx4D(64, 64);
236 :
237 : // 64x32
238 0 : sadMxN(64, 32);
239 0 : sadMxNx4D(64, 32);
240 :
241 : // 32x64
242 0 : sadMxN(32, 64);
243 0 : sadMxNx4D(32, 64);
244 :
245 : // 32x32
246 0 : sadMxN(32, 32);
247 0 : sadMxNx4D(32, 32);
248 :
249 : // 32x16
250 0 : sadMxN(32, 16);
251 0 : sadMxNx4D(32, 16);
252 :
253 : // 16x32
254 0 : sadMxN(16, 32);
255 0 : sadMxNx4D(16, 32);
256 :
257 : // 16x16
258 0 : sadMxN(16, 16);
259 0 : sadMxNx4D(16, 16);
260 :
261 : // 16x8
262 0 : sadMxN(16, 8);
263 0 : sadMxNx4D(16, 8);
264 :
265 : // 8x16
266 0 : sadMxN(8, 16);
267 0 : sadMxNx4D(8, 16);
268 :
269 : // 8x8
270 0 : sadMxN(8, 8);
271 0 : sadMxNx4D(8, 8);
272 :
273 : // 8x4
274 0 : sadMxN(8, 4);
275 0 : sadMxNx4D(8, 4);
276 :
277 : // 4x8
278 0 : sadMxN(4, 8);
279 0 : sadMxNx4D(4, 8);
280 :
281 : // 4x4
282 0 : sadMxN(4, 4);
283 0 : sadMxNx4D(4, 4);
284 :
285 0 : sadMxN(4, 16);
286 0 : sadMxNx4D(4, 16);
287 0 : sadMxN(16, 4);
288 0 : sadMxNx4D(16, 4);
289 0 : sadMxN(8, 32);
290 0 : sadMxNx4D(8, 32);
291 0 : sadMxN(32, 8);
292 0 : sadMxNx4D(32, 8);
293 0 : sadMxN(16, 64);
294 0 : sadMxNx4D(16, 64);
295 0 : sadMxN(64, 16);
296 0 : sadMxNx4D(64, 16);
297 :
298 0 : uint32_t nxm_sad_kernel_helper_c(
299 : const uint8_t *src,
300 : uint32_t src_stride,
301 : const uint8_t *ref,
302 : uint32_t ref_stride,
303 : uint32_t height,
304 : uint32_t width)
305 : {
306 0 : uint32_t nxm_sad = 0;
307 :
308 0 : switch (width) {
309 0 : case 4:
310 : case 8:
311 : case 16:
312 : case 24:
313 : case 32:
314 : case 48:
315 : case 64:
316 : case 128:
317 0 : nxm_sad = fast_loop_nxm_sad_kernel(src, src_stride, ref, ref_stride, height, width); break;
318 0 : default:
319 : assert(0);
320 : }
321 :
322 0 : return nxm_sad;
323 : };
324 :
325 0 : uint32_t nxm_sad_avg_kernel_helper_c(
326 : uint8_t *src,
327 : uint32_t src_stride,
328 : uint8_t *ref1,
329 : uint32_t ref1_stride,
330 : uint8_t *ref2,
331 : uint32_t ref2_stride,
332 : uint32_t height,
333 : uint32_t width)
334 : {
335 :
336 0 : uint32_t nxm_sad_avg = 0;
337 :
338 0 : switch (width) {
339 0 : case 4:
340 : case 8:
341 : case 16:
342 : case 24:
343 : case 32:
344 : case 48:
345 : case 64:
346 0 : nxm_sad_avg = combined_averaging_sad(src, src_stride, ref1, ref1_stride, ref2, ref2_stride, height, width); break;
347 0 : case 40:
348 : case 56:
349 0 : break; //void_func();
350 0 : default:
351 : assert(0);
352 : }
353 :
354 0 : return nxm_sad_avg;
355 : }
|