blob: 9216480398bfb20b921e5409177908b33ad0a575 [file] [log] [blame]
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +01001/*
2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12#include <stdlib.h>
13
14#include "./aom_config.h"
15#include "./aom_dsp_rtcd.h"
16
17#include "aom/aom_integer.h"
18#include "aom_ports/mem.h"
19#include "aom_dsp/blend.h"
20
21#if CONFIG_AV1
22static INLINE unsigned int masked_sad(const uint8_t *src, int src_stride,
23 const uint8_t *a, int a_stride,
24 const uint8_t *b, int b_stride,
25 const uint8_t *m, int m_stride, int width,
26 int height) {
27 int y, x;
28 unsigned int sad = 0;
29 for (y = 0; y < height; y++) {
30 for (x = 0; x < width; x++) {
31 const int16_t pred = AOM_BLEND_A64(m[x], a[x], b[x]);
32 sad += abs(pred - src[x]);
33 }
34 src += src_stride;
35 a += a_stride;
36 b += b_stride;
37 m += m_stride;
38 }
39 sad = (sad + 31) >> 6;
40 return sad;
41}
42
43#define MASKSADMxN(m, n) \
44 unsigned int aom_masked_sad##m##x##n##_c( \
45 const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \
46 const uint8_t *second_pred, const uint8_t *msk, int msk_stride, \
47 int invert_mask) { \
48 if (!invert_mask) \
49 return masked_sad(src, src_stride, ref, ref_stride, second_pred, m, msk, \
50 msk_stride, m, n); \
51 else \
52 return masked_sad(src, src_stride, second_pred, m, ref, ref_stride, msk, \
53 msk_stride, m, n); \
54 }
55
56/* clang-format off */
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +010057MASKSADMxN(128, 128)
58MASKSADMxN(128, 64)
59MASKSADMxN(64, 128)
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +010060MASKSADMxN(64, 64)
61MASKSADMxN(64, 32)
62MASKSADMxN(32, 64)
63MASKSADMxN(32, 32)
64MASKSADMxN(32, 16)
65MASKSADMxN(16, 32)
66MASKSADMxN(16, 16)
67MASKSADMxN(16, 8)
68MASKSADMxN(8, 16)
69MASKSADMxN(8, 8)
70MASKSADMxN(8, 4)
71MASKSADMxN(4, 8)
72MASKSADMxN(4, 4)
73
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +010074MASKSADMxN(4, 16)
75MASKSADMxN(16, 4)
76MASKSADMxN(8, 32)
77MASKSADMxN(32, 8)
78MASKSADMxN(16, 64)
79MASKSADMxN(64, 16)
80MASKSADMxN(32, 128)
81MASKSADMxN(128, 32)
Debargha Mukherjee16870852018-02-28 10:00:17 -080082
Yaowu Xud3e7c682017-12-21 14:08:25 -080083 /* clang-format on */
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +010084
Yaowu Xud3e7c682017-12-21 14:08:25 -080085 static INLINE
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +010086 unsigned int highbd_masked_sad(const uint8_t *src8, int src_stride,
87 const uint8_t *a8, int a_stride,
88 const uint8_t *b8, int b_stride,
89 const uint8_t *m, int m_stride, int width,
90 int height) {
91 int y, x;
92 unsigned int sad = 0;
93 const uint16_t *src = CONVERT_TO_SHORTPTR(src8);
94 const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
95 const uint16_t *b = CONVERT_TO_SHORTPTR(b8);
96
97 for (y = 0; y < height; y++) {
98 for (x = 0; x < width; x++) {
99 const uint16_t pred = AOM_BLEND_A64(m[x], a[x], b[x]);
100 sad += abs(pred - src[x]);
101 }
102
103 src += src_stride;
104 a += a_stride;
105 b += b_stride;
106 m += m_stride;
107 }
108 sad = (sad + 31) >> 6;
109
110 return sad;
111}
112
113#define HIGHBD_MASKSADMXN(m, n) \
114 unsigned int aom_highbd_masked_sad##m##x##n##_c( \
115 const uint8_t *src8, int src_stride, const uint8_t *ref8, \
116 int ref_stride, const uint8_t *second_pred8, const uint8_t *msk, \
117 int msk_stride, int invert_mask) { \
118 if (!invert_mask) \
119 return highbd_masked_sad(src8, src_stride, ref8, ref_stride, \
120 second_pred8, m, msk, msk_stride, m, n); \
121 else \
122 return highbd_masked_sad(src8, src_stride, second_pred8, m, ref8, \
123 ref_stride, msk, msk_stride, m, n); \
124 }
125
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100126HIGHBD_MASKSADMXN(128, 128)
127HIGHBD_MASKSADMXN(128, 64)
128HIGHBD_MASKSADMXN(64, 128)
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100129HIGHBD_MASKSADMXN(64, 64)
130HIGHBD_MASKSADMXN(64, 32)
131HIGHBD_MASKSADMXN(32, 64)
132HIGHBD_MASKSADMXN(32, 32)
133HIGHBD_MASKSADMXN(32, 16)
134HIGHBD_MASKSADMXN(16, 32)
135HIGHBD_MASKSADMXN(16, 16)
136HIGHBD_MASKSADMXN(16, 8)
137HIGHBD_MASKSADMXN(8, 16)
138HIGHBD_MASKSADMXN(8, 8)
139HIGHBD_MASKSADMXN(8, 4)
140HIGHBD_MASKSADMXN(4, 8)
141HIGHBD_MASKSADMXN(4, 4)
142
Debargha Mukherjee16870852018-02-28 10:00:17 -0800143#if CONFIG_AV1
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100144HIGHBD_MASKSADMXN(4, 16)
145HIGHBD_MASKSADMXN(16, 4)
146HIGHBD_MASKSADMXN(8, 32)
147HIGHBD_MASKSADMXN(32, 8)
148HIGHBD_MASKSADMXN(16, 64)
149HIGHBD_MASKSADMXN(64, 16)
150HIGHBD_MASKSADMXN(32, 128)
151HIGHBD_MASKSADMXN(128, 32)
152#endif
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100153
154// pre: predictor being evaluated
155// wsrc: target weighted prediction (has been *4096 to keep precision)
156// mask: 2d weights (scaled by 4096)
157static INLINE unsigned int obmc_sad(const uint8_t *pre, int pre_stride,
158 const int32_t *wsrc, const int32_t *mask,
159 int width, int height) {
160 int y, x;
161 unsigned int sad = 0;
162
163 for (y = 0; y < height; y++) {
164 for (x = 0; x < width; x++)
165 sad += ROUND_POWER_OF_TWO(abs(wsrc[x] - pre[x] * mask[x]), 12);
166
167 pre += pre_stride;
168 wsrc += width;
169 mask += width;
170 }
171
172 return sad;
173}
174
175#define OBMCSADMxN(m, n) \
176 unsigned int aom_obmc_sad##m##x##n##_c(const uint8_t *ref, int ref_stride, \
177 const int32_t *wsrc, \
178 const int32_t *mask) { \
179 return obmc_sad(ref, ref_stride, wsrc, mask, m, n); \
180 }
181
182/* clang-format off */
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100183OBMCSADMxN(128, 128)
184OBMCSADMxN(128, 64)
185OBMCSADMxN(64, 128)
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100186OBMCSADMxN(64, 64)
187OBMCSADMxN(64, 32)
188OBMCSADMxN(32, 64)
189OBMCSADMxN(32, 32)
190OBMCSADMxN(32, 16)
191OBMCSADMxN(16, 32)
192OBMCSADMxN(16, 16)
193OBMCSADMxN(16, 8)
194OBMCSADMxN(8, 16)
195OBMCSADMxN(8, 8)
196OBMCSADMxN(8, 4)
197OBMCSADMxN(4, 8)
198OBMCSADMxN(4, 4)
199
Debargha Mukherjee16870852018-02-28 10:00:17 -0800200#if CONFIG_AV1
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100201OBMCSADMxN(4, 16)
202OBMCSADMxN(16, 4)
203OBMCSADMxN(8, 32)
204OBMCSADMxN(32, 8)
205OBMCSADMxN(16, 64)
206OBMCSADMxN(64, 16)
207OBMCSADMxN(32, 128)
208OBMCSADMxN(128, 32)
209#endif
Yaowu Xud3e7c682017-12-21 14:08:25 -0800210 /* clang-format on */
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100211
Yaowu Xud3e7c682017-12-21 14:08:25 -0800212 static INLINE
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100213 unsigned int highbd_obmc_sad(const uint8_t *pre8, int pre_stride,
214 const int32_t *wsrc, const int32_t *mask,
215 int width, int height) {
216 int y, x;
217 unsigned int sad = 0;
218 const uint16_t *pre = CONVERT_TO_SHORTPTR(pre8);
219
220 for (y = 0; y < height; y++) {
221 for (x = 0; x < width; x++)
222 sad += ROUND_POWER_OF_TWO(abs(wsrc[x] - pre[x] * mask[x]), 12);
223
224 pre += pre_stride;
225 wsrc += width;
226 mask += width;
227 }
228
229 return sad;
230}
231
232#define HIGHBD_OBMCSADMXN(m, n) \
233 unsigned int aom_highbd_obmc_sad##m##x##n##_c( \
234 const uint8_t *ref, int ref_stride, const int32_t *wsrc, \
235 const int32_t *mask) { \
236 return highbd_obmc_sad(ref, ref_stride, wsrc, mask, m, n); \
237 }
238
239/* clang-format off */
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100240HIGHBD_OBMCSADMXN(128, 128)
241HIGHBD_OBMCSADMXN(128, 64)
242HIGHBD_OBMCSADMXN(64, 128)
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100243HIGHBD_OBMCSADMXN(64, 64)
244HIGHBD_OBMCSADMXN(64, 32)
245HIGHBD_OBMCSADMXN(32, 64)
246HIGHBD_OBMCSADMXN(32, 32)
247HIGHBD_OBMCSADMXN(32, 16)
248HIGHBD_OBMCSADMXN(16, 32)
249HIGHBD_OBMCSADMXN(16, 16)
250HIGHBD_OBMCSADMXN(16, 8)
251HIGHBD_OBMCSADMXN(8, 16)
252HIGHBD_OBMCSADMXN(8, 8)
253HIGHBD_OBMCSADMXN(8, 4)
254HIGHBD_OBMCSADMXN(4, 8)
255HIGHBD_OBMCSADMXN(4, 4)
256
Debargha Mukherjee16870852018-02-28 10:00:17 -0800257#if CONFIG_AV1
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100258HIGHBD_OBMCSADMXN(4, 16)
259HIGHBD_OBMCSADMXN(16, 4)
260HIGHBD_OBMCSADMXN(8, 32)
261HIGHBD_OBMCSADMXN(32, 8)
262HIGHBD_OBMCSADMXN(16, 64)
263HIGHBD_OBMCSADMXN(64, 16)
264HIGHBD_OBMCSADMXN(32, 128)
265HIGHBD_OBMCSADMXN(128, 32)
266#endif
267/* clang-format on */
Sebastien Alaiwan20dadea2017-11-22 17:38:31 +0100268#endif // CONFIG_AV1