sad.c 19.8 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
John Koleszar's avatar
John Koleszar committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4
5
6
7
8
9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
John Koleszar's avatar
John Koleszar committed
10
11
12
 */

#include <stdlib.h>
13

Yaowu Xu's avatar
Yaowu Xu committed
14
15
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
16

Yaowu Xu's avatar
Yaowu Xu committed
17
#include "aom/aom_integer.h"
18
#include "aom_ports/mem.h"
19
#include "aom_dsp/blend.h"
20

Johann's avatar
Johann committed
21
/* Sum the difference between every corresponding element of the buffers. */
clang-format's avatar
clang-format committed
22
23
static INLINE unsigned int sad(const uint8_t *a, int a_stride, const uint8_t *b,
                               int b_stride, int width, int height) {
24
25
26
27
  int y, x;
  unsigned int sad = 0;

  for (y = 0; y < height; y++) {
clang-format's avatar
clang-format committed
28
    for (x = 0; x < width; x++) sad += abs(a[x] - b[x]);
29
30
31
32
33
34

    a += a_stride;
    b += b_stride;
  }
  return sad;
}
John Koleszar's avatar
John Koleszar committed
35

Cheng Chen's avatar
Cheng Chen committed
36
#if CONFIG_JNT_COMP
37
38
39
40
41
42
43
#define sadMxh(m)                                                          \
  unsigned int aom_sad##m##xh_c(const uint8_t *a, int a_stride,            \
                                const uint8_t *b, int b_stride, int width, \
                                int height) {                              \
    return sad(a, a_stride, b, b_stride, width, height);                   \
  }

Cheng Chen's avatar
Cheng Chen committed
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#define sadMxN(m, n)                                                          \
  unsigned int aom_sad##m##x##n##_c(const uint8_t *src, int src_stride,       \
                                    const uint8_t *ref, int ref_stride) {     \
    return sad(src, src_stride, ref, ref_stride, m, n);                       \
  }                                                                           \
  unsigned int aom_sad##m##x##n##_avg_c(const uint8_t *src, int src_stride,   \
                                        const uint8_t *ref, int ref_stride,   \
                                        const uint8_t *second_pred) {         \
    uint8_t comp_pred[m * n];                                                 \
    aom_comp_avg_pred(comp_pred, second_pred, m, n, ref, ref_stride);         \
    return sad(src, src_stride, comp_pred, m, m, n);                          \
  }                                                                           \
  unsigned int aom_jnt_sad##m##x##n##_avg_c(                                  \
      const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \
      const uint8_t *second_pred, const JNT_COMP_PARAMS *jcp_param) {         \
    uint8_t comp_pred[m * n];                                                 \
60
61
    aom_jnt_comp_avg_pred_c(comp_pred, second_pred, m, n, ref, ref_stride,    \
                            jcp_param);                                       \
Cheng Chen's avatar
Cheng Chen committed
62
63
64
    return sad(src, src_stride, comp_pred, m, m, n);                          \
  }
#else  // CONFIG_JNT_COMP
clang-format's avatar
clang-format committed
65
#define sadMxN(m, n)                                                        \
Yaowu Xu's avatar
Yaowu Xu committed
66
  unsigned int aom_sad##m##x##n##_c(const uint8_t *src, int src_stride,     \
clang-format's avatar
clang-format committed
67
68
69
                                    const uint8_t *ref, int ref_stride) {   \
    return sad(src, src_stride, ref, ref_stride, m, n);                     \
  }                                                                         \
Yaowu Xu's avatar
Yaowu Xu committed
70
  unsigned int aom_sad##m##x##n##_avg_c(const uint8_t *src, int src_stride, \
clang-format's avatar
clang-format committed
71
72
73
                                        const uint8_t *ref, int ref_stride, \
                                        const uint8_t *second_pred) {       \
    uint8_t comp_pred[m * n];                                               \
Yaowu Xu's avatar
Yaowu Xu committed
74
    aom_comp_avg_pred_c(comp_pred, second_pred, m, n, ref, ref_stride);     \
clang-format's avatar
clang-format committed
75
76
    return sad(src, src_stride, comp_pred, m, m, n);                        \
  }
Cheng Chen's avatar
Cheng Chen committed
77
#endif  // CONFIG_JNT_COMP
78

Johann's avatar
Johann committed
79
80
// depending on call sites, pass **ref_array to avoid & in subsequent call and
// de-dup with 4D below.
clang-format's avatar
clang-format committed
81
#define sadMxNxK(m, n, k)                                                   \
Yaowu Xu's avatar
Yaowu Xu committed
82
  void aom_sad##m##x##n##x##k##_c(const uint8_t *src, int src_stride,       \
clang-format's avatar
clang-format committed
83
84
85
86
87
                                  const uint8_t *ref_array, int ref_stride, \
                                  uint32_t *sad_array) {                    \
    int i;                                                                  \
    for (i = 0; i < k; ++i)                                                 \
      sad_array[i] =                                                        \
Yaowu Xu's avatar
Yaowu Xu committed
88
          aom_sad##m##x##n##_c(src, src_stride, &ref_array[i], ref_stride); \
clang-format's avatar
clang-format committed
89
  }
90

Johann's avatar
Johann committed
91
// This appears to be equivalent to the above when k == 4 and refs is const
clang-format's avatar
clang-format committed
92
#define sadMxNx4D(m, n)                                                    \
Yaowu Xu's avatar
Yaowu Xu committed
93
  void aom_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride,         \
clang-format's avatar
clang-format committed
94
95
96
97
98
                               const uint8_t *const ref_array[],           \
                               int ref_stride, uint32_t *sad_array) {      \
    int i;                                                                 \
    for (i = 0; i < 4; ++i)                                                \
      sad_array[i] =                                                       \
Yaowu Xu's avatar
Yaowu Xu committed
99
          aom_sad##m##x##n##_c(src, src_stride, ref_array[i], ref_stride); \
clang-format's avatar
clang-format committed
100
  }
101

clang-format's avatar
clang-format committed
102
/* clang-format off */
Yaowu Xu's avatar
Yaowu Xu committed
103
#if CONFIG_AV1 && CONFIG_EXT_PARTITION
104
105
106
107
108
109
110
111
112
113
114
115
116
// 128x128
sadMxN(128, 128)
sadMxNxK(128, 128, 3)
sadMxNxK(128, 128, 8)
sadMxNx4D(128, 128)

// 128x64
sadMxN(128, 64)
sadMxNx4D(128, 64)

// 64x128
sadMxN(64, 128)
sadMxNx4D(64, 128)
Yaowu Xu's avatar
Yaowu Xu committed
117
#endif  // CONFIG_AV1 && CONFIG_EXT_PARTITION
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// 64x64
sadMxN(64, 64)
sadMxNxK(64, 64, 3)
sadMxNxK(64, 64, 8)
sadMxNx4D(64, 64)

// 64x32
sadMxN(64, 32)
sadMxNx4D(64, 32)

// 32x64
sadMxN(32, 64)
sadMxNx4D(32, 64)

// 32x32
sadMxN(32, 32)
sadMxNxK(32, 32, 3)
sadMxNxK(32, 32, 8)
sadMxNx4D(32, 32)

// 32x16
sadMxN(32, 16)
sadMxNx4D(32, 16)

// 16x32
sadMxN(16, 32)
sadMxNx4D(16, 32)

// 16x16
sadMxN(16, 16)
sadMxNxK(16, 16, 3)
sadMxNxK(16, 16, 8)
sadMxNx4D(16, 16)

// 16x8
sadMxN(16, 8)
sadMxNxK(16, 8, 3)
sadMxNxK(16, 8, 8)
sadMxNx4D(16, 8)

// 8x16
sadMxN(8, 16)
sadMxNxK(8, 16, 3)
sadMxNxK(8, 16, 8)
sadMxNx4D(8, 16)

// 8x8
sadMxN(8, 8)
sadMxNxK(8, 8, 3)
sadMxNxK(8, 8, 8)
sadMxNx4D(8, 8)

// 8x4
sadMxN(8, 4)
sadMxNxK(8, 4, 8)
sadMxNx4D(8, 4)

// 4x8
sadMxN(4, 8)
sadMxNxK(4, 8, 8)
sadMxNx4D(4, 8)

// 4x4
sadMxN(4, 4)
sadMxNxK(4, 4, 3)
sadMxNxK(4, 4, 8)
sadMxNx4D(4, 4)
186

187
188
189
190
191
192
193
194
195
196
197
#if CONFIG_JNT_COMP
#if CONFIG_EXT_PARTITION
sadMxh(128);
#endif
sadMxh(64);
sadMxh(32);
sadMxh(16);
sadMxh(8);
sadMxh(4);
#endif  // CONFIG_JNT_COMP

198
199
200
201
202
203
204
205
206
#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
sadMxN(4, 16)
sadMxNx4D(4, 16)
sadMxN(16, 4)
sadMxNx4D(16, 4)
sadMxN(8, 32)
sadMxNx4D(8, 32)
sadMxN(32, 8)
sadMxNx4D(32, 8)
207
208
209
210
sadMxN(16, 64)
sadMxNx4D(16, 64)
sadMxN(64, 16)
sadMxNx4D(64, 16)
211
212
213
214
sadMxN(32, 128)
sadMxNx4D(32, 128)
sadMxN(128, 32)
sadMxNx4D(128, 32)
215
#endif
clang-format's avatar
clang-format committed
216
/* clang-format on */
217

218
#if CONFIG_HIGHBITDEPTH
219
                static INLINE
clang-format's avatar
clang-format committed
220
221
    unsigned int highbd_sad(const uint8_t *a8, int a_stride, const uint8_t *b8,
                            int b_stride, int width, int height) {
222
223
224
225
226
  int y, x;
  unsigned int sad = 0;
  const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
  const uint16_t *b = CONVERT_TO_SHORTPTR(b8);
  for (y = 0; y < height; y++) {
clang-format's avatar
clang-format committed
227
    for (x = 0; x < width; x++) sad += abs(a[x] - b[x]);
228
229
230
231
232
233
234

    a += a_stride;
    b += b_stride;
  }
  return sad;
}

235
236
237
static INLINE unsigned int highbd_sadb(const uint8_t *a8, int a_stride,
                                       const uint16_t *b, int b_stride,
                                       int width, int height) {
238
239
240
241
  int y, x;
  unsigned int sad = 0;
  const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
  for (y = 0; y < height; y++) {
clang-format's avatar
clang-format committed
242
    for (x = 0; x < width; x++) sad += abs(a[x] - b[x]);
243
244
245
246
247
248
249

    a += a_stride;
    b += b_stride;
  }
  return sad;
}

clang-format's avatar
clang-format committed
250
#define highbd_sadMxN(m, n)                                                    \
Yaowu Xu's avatar
Yaowu Xu committed
251
  unsigned int aom_highbd_sad##m##x##n##_c(const uint8_t *src, int src_stride, \
clang-format's avatar
clang-format committed
252
253
254
255
                                           const uint8_t *ref,                 \
                                           int ref_stride) {                   \
    return highbd_sad(src, src_stride, ref, ref_stride, m, n);                 \
  }                                                                            \
Yaowu Xu's avatar
Yaowu Xu committed
256
  unsigned int aom_highbd_sad##m##x##n##_avg_c(                                \
clang-format's avatar
clang-format committed
257
258
259
      const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride,  \
      const uint8_t *second_pred) {                                            \
    uint16_t comp_pred[m * n];                                                 \
Yaowu Xu's avatar
Yaowu Xu committed
260
    aom_highbd_comp_avg_pred_c(comp_pred, second_pred, m, n, ref, ref_stride); \
clang-format's avatar
clang-format committed
261
262
    return highbd_sadb(src, src_stride, comp_pred, m, m, n);                   \
  }
263

clang-format's avatar
clang-format committed
264
#define highbd_sadMxNxK(m, n, k)                                             \
Yaowu Xu's avatar
Yaowu Xu committed
265
  void aom_highbd_sad##m##x##n##x##k##_c(                                    \
clang-format's avatar
clang-format committed
266
267
268
269
      const uint8_t *src, int src_stride, const uint8_t *ref_array,          \
      int ref_stride, uint32_t *sad_array) {                                 \
    int i;                                                                   \
    for (i = 0; i < k; ++i) {                                                \
Yaowu Xu's avatar
Yaowu Xu committed
270
      sad_array[i] = aom_highbd_sad##m##x##n##_c(src, src_stride,            \
clang-format's avatar
clang-format committed
271
272
273
                                                 &ref_array[i], ref_stride); \
    }                                                                        \
  }
274

clang-format's avatar
clang-format committed
275
#define highbd_sadMxNx4D(m, n)                                               \
Yaowu Xu's avatar
Yaowu Xu committed
276
  void aom_highbd_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride,    \
clang-format's avatar
clang-format committed
277
278
279
280
                                      const uint8_t *const ref_array[],      \
                                      int ref_stride, uint32_t *sad_array) { \
    int i;                                                                   \
    for (i = 0; i < 4; ++i) {                                                \
Yaowu Xu's avatar
Yaowu Xu committed
281
      sad_array[i] = aom_highbd_sad##m##x##n##_c(src, src_stride,            \
clang-format's avatar
clang-format committed
282
283
284
                                                 ref_array[i], ref_stride);  \
    }                                                                        \
  }
285

clang-format's avatar
clang-format committed
286
/* clang-format off */
Yaowu Xu's avatar
Yaowu Xu committed
287
#if CONFIG_AV1 && CONFIG_EXT_PARTITION
288
289
290
291
292
293
294
295
296
297
298
299
300
// 128x128
highbd_sadMxN(128, 128)
highbd_sadMxNxK(128, 128, 3)
highbd_sadMxNxK(128, 128, 8)
highbd_sadMxNx4D(128, 128)

// 128x64
highbd_sadMxN(128, 64)
highbd_sadMxNx4D(128, 64)

// 64x128
highbd_sadMxN(64, 128)
highbd_sadMxNx4D(64, 128)
Yaowu Xu's avatar
Yaowu Xu committed
301
#endif  // CONFIG_AV1 && CONFIG_EXT_PARTITION
302

303
// 64x64
304
305
306
307
highbd_sadMxN(64, 64)
highbd_sadMxNxK(64, 64, 3)
highbd_sadMxNxK(64, 64, 8)
highbd_sadMxNx4D(64, 64)
308
309

// 64x32
310
311
highbd_sadMxN(64, 32)
highbd_sadMxNx4D(64, 32)
312
313

// 32x64
314
315
highbd_sadMxN(32, 64)
highbd_sadMxNx4D(32, 64)
316
317

// 32x32
318
319
320
321
highbd_sadMxN(32, 32)
highbd_sadMxNxK(32, 32, 3)
highbd_sadMxNxK(32, 32, 8)
highbd_sadMxNx4D(32, 32)
322
323

// 32x16
324
325
highbd_sadMxN(32, 16)
highbd_sadMxNx4D(32, 16)
326
327

// 16x32
328
329
highbd_sadMxN(16, 32)
highbd_sadMxNx4D(16, 32)
330
331

// 16x16
332
333
334
335
highbd_sadMxN(16, 16)
highbd_sadMxNxK(16, 16, 3)
highbd_sadMxNxK(16, 16, 8)
highbd_sadMxNx4D(16, 16)
336
337

// 16x8
338
339
340
341
highbd_sadMxN(16, 8)
highbd_sadMxNxK(16, 8, 3)
highbd_sadMxNxK(16, 8, 8)
highbd_sadMxNx4D(16, 8)
342
343

// 8x16
344
345
346
347
highbd_sadMxN(8, 16)
highbd_sadMxNxK(8, 16, 3)
highbd_sadMxNxK(8, 16, 8)
highbd_sadMxNx4D(8, 16)
348
349

// 8x8
350
351
352
353
highbd_sadMxN(8, 8)
highbd_sadMxNxK(8, 8, 3)
highbd_sadMxNxK(8, 8, 8)
highbd_sadMxNx4D(8, 8)
354
355

// 8x4
356
357
358
highbd_sadMxN(8, 4)
highbd_sadMxNxK(8, 4, 8)
highbd_sadMxNx4D(8, 4)
359
360

// 4x8
361
362
363
highbd_sadMxN(4, 8)
highbd_sadMxNxK(4, 8, 8)
highbd_sadMxNx4D(4, 8)
364
365

// 4x4
366
367
368
369
highbd_sadMxN(4, 4)
highbd_sadMxNxK(4, 4, 3)
highbd_sadMxNxK(4, 4, 8)
highbd_sadMxNx4D(4, 4)
370
371
372
373
374
375
376
377
378
379

#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
highbd_sadMxN(4, 16)
highbd_sadMxNx4D(4, 16)
highbd_sadMxN(16, 4)
highbd_sadMxNx4D(16, 4)
highbd_sadMxN(8, 32)
highbd_sadMxNx4D(8, 32)
highbd_sadMxN(32, 8)
highbd_sadMxNx4D(32, 8)
380
381
382
383
highbd_sadMxN(16, 64)
highbd_sadMxNx4D(16, 64)
highbd_sadMxN(64, 16)
highbd_sadMxNx4D(64, 16)
384
385
386
387
highbd_sadMxN(32, 128)
highbd_sadMxNx4D(32, 128)
highbd_sadMxN(128, 32)
highbd_sadMxNx4D(128, 32)
388
#endif
clang-format's avatar
clang-format committed
389
/* clang-format on */
390
#endif  // CONFIG_HIGHBITDEPTH
391

392
#if CONFIG_AV1
393
                                                static INLINE
David Barker's avatar
David Barker committed
394
395
396
397
    unsigned int masked_sad(const uint8_t *src, int src_stride,
                            const uint8_t *a, int a_stride, const uint8_t *b,
                            int b_stride, const uint8_t *m, int m_stride,
                            int width, int height) {
398
399
400
401
  int y, x;
  unsigned int sad = 0;
  for (y = 0; y < height; y++) {
    for (x = 0; x < width; x++) {
402
      const int16_t pred = AOM_BLEND_A64(m[x], a[x], b[x]);
403
404
405
406
407
408
409
410
411
412
413
      sad += abs(pred - src[x]);
    }
    src += src_stride;
    a += a_stride;
    b += b_stride;
    m += m_stride;
  }
  sad = (sad + 31) >> 6;
  return sad;
}

David Barker's avatar
David Barker committed
414
415
416
417
418
419
420
421
422
423
424
#define MASKSADMxN(m, n)                                                       \
  unsigned int aom_masked_sad##m##x##n##_c(                                    \
      const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride,  \
      const uint8_t *second_pred, const uint8_t *msk, int msk_stride,          \
      int invert_mask) {                                                       \
    if (!invert_mask)                                                          \
      return masked_sad(src, src_stride, ref, ref_stride, second_pred, m, msk, \
                        msk_stride, m, n);                                     \
    else                                                                       \
      return masked_sad(src, src_stride, second_pred, m, ref, ref_stride, msk, \
                        msk_stride, m, n);                                     \
clang-format's avatar
clang-format committed
425
  }
426

clang-format's avatar
clang-format committed
427
/* clang-format off */
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
#if CONFIG_EXT_PARTITION
MASKSADMxN(128, 128)
MASKSADMxN(128, 64)
MASKSADMxN(64, 128)
#endif  // CONFIG_EXT_PARTITION
MASKSADMxN(64, 64)
MASKSADMxN(64, 32)
MASKSADMxN(32, 64)
MASKSADMxN(32, 32)
MASKSADMxN(32, 16)
MASKSADMxN(16, 32)
MASKSADMxN(16, 16)
MASKSADMxN(16, 8)
MASKSADMxN(8, 16)
MASKSADMxN(8, 8)
MASKSADMxN(8, 4)
MASKSADMxN(4, 8)
MASKSADMxN(4, 4)
446
447
448
449
450
451

#if CONFIG_EXT_PARTITION_TYPES
MASKSADMxN(4, 16)
MASKSADMxN(16, 4)
MASKSADMxN(8, 32)
MASKSADMxN(32, 8)
452
453
MASKSADMxN(16, 64)
MASKSADMxN(64, 16)
454
455
MASKSADMxN(32, 128)
MASKSADMxN(128, 32)
456
#endif
clang-format's avatar
clang-format committed
457
/* clang-format on */
458

459
#if CONFIG_HIGHBITDEPTH
460
                                static INLINE
David Barker's avatar
David Barker committed
461
462
463
464
465
    unsigned int highbd_masked_sad(const uint8_t *src8, int src_stride,
                                   const uint8_t *a8, int a_stride,
                                   const uint8_t *b8, int b_stride,
                                   const uint8_t *m, int m_stride, int width,
                                   int height) {
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
  int y, x;
  unsigned int sad = 0;
  const uint16_t *src = CONVERT_TO_SHORTPTR(src8);
  const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
  const uint16_t *b = CONVERT_TO_SHORTPTR(b8);

  for (y = 0; y < height; y++) {
    for (x = 0; x < width; x++) {
      const uint16_t pred = AOM_BLEND_A64(m[x], a[x], b[x]);
      sad += abs(pred - src[x]);
    }

    src += src_stride;
    a += a_stride;
    b += b_stride;
    m += m_stride;
  }
  sad = (sad + 31) >> 6;

  return sad;
}

David Barker's avatar
David Barker committed
488
489
490
491
492
493
494
495
496
497
498
#define HIGHBD_MASKSADMXN(m, n)                                         \
  unsigned int aom_highbd_masked_sad##m##x##n##_c(                      \
      const uint8_t *src8, int src_stride, const uint8_t *ref8,         \
      int ref_stride, const uint8_t *second_pred8, const uint8_t *msk,  \
      int msk_stride, int invert_mask) {                                \
    if (!invert_mask)                                                   \
      return highbd_masked_sad(src8, src_stride, ref8, ref_stride,      \
                               second_pred8, m, msk, msk_stride, m, n); \
    else                                                                \
      return highbd_masked_sad(src8, src_stride, second_pred8, m, ref8, \
                               ref_stride, msk, msk_stride, m, n);      \
clang-format's avatar
clang-format committed
499
  }
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518

#if CONFIG_EXT_PARTITION
HIGHBD_MASKSADMXN(128, 128)
HIGHBD_MASKSADMXN(128, 64)
HIGHBD_MASKSADMXN(64, 128)
#endif  // CONFIG_EXT_PARTITION
HIGHBD_MASKSADMXN(64, 64)
HIGHBD_MASKSADMXN(64, 32)
HIGHBD_MASKSADMXN(32, 64)
HIGHBD_MASKSADMXN(32, 32)
HIGHBD_MASKSADMXN(32, 16)
HIGHBD_MASKSADMXN(16, 32)
HIGHBD_MASKSADMXN(16, 16)
HIGHBD_MASKSADMXN(16, 8)
HIGHBD_MASKSADMXN(8, 16)
HIGHBD_MASKSADMXN(8, 8)
HIGHBD_MASKSADMXN(8, 4)
HIGHBD_MASKSADMXN(4, 8)
HIGHBD_MASKSADMXN(4, 4)
519
520
521
522
523
524

#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
HIGHBD_MASKSADMXN(4, 16)
HIGHBD_MASKSADMXN(16, 4)
HIGHBD_MASKSADMXN(8, 32)
HIGHBD_MASKSADMXN(32, 8)
525
526
HIGHBD_MASKSADMXN(16, 64)
HIGHBD_MASKSADMXN(64, 16)
527
528
HIGHBD_MASKSADMXN(32, 128)
HIGHBD_MASKSADMXN(128, 32)
529
#endif
530
#endif  // CONFIG_HIGHBITDEPTH
531
#endif  // CONFIG_AV1
532

533
#if CONFIG_AV1
534
535
536
537
// pre: predictor being evaluated
// wsrc: target weighted prediction (has been *4096 to keep precision)
// mask: 2d weights (scaled by 4096)
static INLINE unsigned int obmc_sad(const uint8_t *pre, int pre_stride,
clang-format's avatar
clang-format committed
538
                                    const int32_t *wsrc, const int32_t *mask,
539
540
541
542
543
                                    int width, int height) {
  int y, x;
  unsigned int sad = 0;

  for (y = 0; y < height; y++) {
544
    for (x = 0; x < width; x++)
545
      sad += ROUND_POWER_OF_TWO(abs(wsrc[x] - pre[x] * mask[x]), 12);
546

547
548
549
    pre += pre_stride;
    wsrc += width;
    mask += width;
550
551
552
553
554
  }

  return sad;
}

clang-format's avatar
clang-format committed
555
#define OBMCSADMxN(m, n)                                                     \
Yaowu Xu's avatar
Yaowu Xu committed
556
  unsigned int aom_obmc_sad##m##x##n##_c(const uint8_t *ref, int ref_stride, \
clang-format's avatar
clang-format committed
557
558
559
560
                                         const int32_t *wsrc,                \
                                         const int32_t *mask) {              \
    return obmc_sad(ref, ref_stride, wsrc, mask, m, n);                      \
  }
561

clang-format's avatar
clang-format committed
562
/* clang-format off */
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
#if CONFIG_EXT_PARTITION
OBMCSADMxN(128, 128)
OBMCSADMxN(128, 64)
OBMCSADMxN(64, 128)
#endif  // CONFIG_EXT_PARTITION
OBMCSADMxN(64, 64)
OBMCSADMxN(64, 32)
OBMCSADMxN(32, 64)
OBMCSADMxN(32, 32)
OBMCSADMxN(32, 16)
OBMCSADMxN(16, 32)
OBMCSADMxN(16, 16)
OBMCSADMxN(16, 8)
OBMCSADMxN(8, 16)
OBMCSADMxN(8, 8)
OBMCSADMxN(8, 4)
OBMCSADMxN(4, 8)
OBMCSADMxN(4, 4)
581
582
583
584
585
586

#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
OBMCSADMxN(4, 16)
OBMCSADMxN(16, 4)
OBMCSADMxN(8, 32)
OBMCSADMxN(32, 8)
587
588
OBMCSADMxN(16, 64)
OBMCSADMxN(64, 16)
589
590
OBMCSADMxN(32, 128)
OBMCSADMxN(128, 32)
591
#endif
clang-format's avatar
clang-format committed
592
/* clang-format on */
593

594
#if CONFIG_HIGHBITDEPTH
595
                                static INLINE
clang-format's avatar
clang-format committed
596
597
598
    unsigned int highbd_obmc_sad(const uint8_t *pre8, int pre_stride,
                                 const int32_t *wsrc, const int32_t *mask,
                                 int width, int height) {
599
600
  int y, x;
  unsigned int sad = 0;
601
  const uint16_t *pre = CONVERT_TO_SHORTPTR(pre8);
602
603

  for (y = 0; y < height; y++) {
604
    for (x = 0; x < width; x++)
605
      sad += ROUND_POWER_OF_TWO(abs(wsrc[x] - pre[x] * mask[x]), 12);
606

607
608
609
    pre += pre_stride;
    wsrc += width;
    mask += width;
610
611
612
613
614
  }

  return sad;
}

clang-format's avatar
clang-format committed
615
#define HIGHBD_OBMCSADMXN(m, n)                                \
Yaowu Xu's avatar
Yaowu Xu committed
616
  unsigned int aom_highbd_obmc_sad##m##x##n##_c(               \
clang-format's avatar
clang-format committed
617
618
619
620
      const uint8_t *ref, int ref_stride, const int32_t *wsrc, \
      const int32_t *mask) {                                   \
    return highbd_obmc_sad(ref, ref_stride, wsrc, mask, m, n); \
  }
621

clang-format's avatar
clang-format committed
622
/* clang-format off */
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
#if CONFIG_EXT_PARTITION
HIGHBD_OBMCSADMXN(128, 128)
HIGHBD_OBMCSADMXN(128, 64)
HIGHBD_OBMCSADMXN(64, 128)
#endif  // CONFIG_EXT_PARTITION
HIGHBD_OBMCSADMXN(64, 64)
HIGHBD_OBMCSADMXN(64, 32)
HIGHBD_OBMCSADMXN(32, 64)
HIGHBD_OBMCSADMXN(32, 32)
HIGHBD_OBMCSADMXN(32, 16)
HIGHBD_OBMCSADMXN(16, 32)
HIGHBD_OBMCSADMXN(16, 16)
HIGHBD_OBMCSADMXN(16, 8)
HIGHBD_OBMCSADMXN(8, 16)
HIGHBD_OBMCSADMXN(8, 8)
HIGHBD_OBMCSADMXN(8, 4)
HIGHBD_OBMCSADMXN(4, 8)
HIGHBD_OBMCSADMXN(4, 4)
641
642
643
644
645
646

#if CONFIG_AV1 && CONFIG_EXT_PARTITION_TYPES
HIGHBD_OBMCSADMXN(4, 16)
HIGHBD_OBMCSADMXN(16, 4)
HIGHBD_OBMCSADMXN(8, 32)
HIGHBD_OBMCSADMXN(32, 8)
647
648
HIGHBD_OBMCSADMXN(16, 64)
HIGHBD_OBMCSADMXN(64, 16)
649
650
HIGHBD_OBMCSADMXN(32, 128)
HIGHBD_OBMCSADMXN(128, 32)
651
#endif
clang-format's avatar
clang-format committed
652
/* clang-format on */
653
#endif  // CONFIG_HIGHBITDEPTH
654
#endif  // CONFIG_AV1