sad_av1.c (8116B)
1 /* 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 "config/aom_config.h" 15 #include "config/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 static inline unsigned int masked_sad(const uint8_t *src, int src_stride, 22 const uint8_t *a, int a_stride, 23 const uint8_t *b, int b_stride, 24 const uint8_t *m, int m_stride, int width, 25 int height) { 26 int y, x; 27 unsigned int sad = 0; 28 for (y = 0; y < height; y++) { 29 for (x = 0; x < width; x++) { 30 const int16_t pred = AOM_BLEND_A64(m[x], a[x], b[x]); 31 sad += abs(pred - src[x]); 32 } 33 src += src_stride; 34 a += a_stride; 35 b += b_stride; 36 m += m_stride; 37 } 38 return sad; 39 } 40 41 #define MASKSADMXN(m, n) \ 42 unsigned int aom_masked_sad##m##x##n##_c( \ 43 const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ 44 const uint8_t *second_pred, const uint8_t *msk, int msk_stride, \ 45 int invert_mask) { \ 46 if (!invert_mask) \ 47 return masked_sad(src, src_stride, ref, ref_stride, second_pred, m, msk, \ 48 msk_stride, m, n); \ 49 else \ 50 return masked_sad(src, src_stride, second_pred, m, ref, ref_stride, msk, \ 51 msk_stride, m, n); \ 52 } 53 54 MASKSADMXN(128, 128) 55 MASKSADMXN(128, 64) 56 MASKSADMXN(64, 128) 57 MASKSADMXN(64, 64) 58 MASKSADMXN(64, 32) 59 MASKSADMXN(32, 64) 60 MASKSADMXN(32, 32) 61 MASKSADMXN(32, 16) 62 MASKSADMXN(16, 32) 63 MASKSADMXN(16, 16) 64 MASKSADMXN(16, 8) 65 MASKSADMXN(8, 16) 66 MASKSADMXN(8, 8) 67 MASKSADMXN(8, 4) 68 MASKSADMXN(4, 8) 69 MASKSADMXN(4, 4) 70 #if !CONFIG_REALTIME_ONLY 71 MASKSADMXN(4, 16) 72 MASKSADMXN(16, 4) 73 MASKSADMXN(8, 32) 74 MASKSADMXN(32, 8) 75 MASKSADMXN(16, 64) 76 MASKSADMXN(64, 16) 77 #endif // !CONFIG_REALTIME_ONLY 78 79 #if CONFIG_AV1_HIGHBITDEPTH 80 static inline unsigned int highbd_masked_sad(const uint8_t *src8, 81 int src_stride, const uint8_t *a8, 82 int a_stride, const uint8_t *b8, 83 int b_stride, const uint8_t *m, 84 int m_stride, int width, 85 int height) { 86 int y, x; 87 unsigned int sad = 0; 88 const uint16_t *src = CONVERT_TO_SHORTPTR(src8); 89 const uint16_t *a = CONVERT_TO_SHORTPTR(a8); 90 const uint16_t *b = CONVERT_TO_SHORTPTR(b8); 91 92 for (y = 0; y < height; y++) { 93 for (x = 0; x < width; x++) { 94 const uint16_t pred = AOM_BLEND_A64(m[x], a[x], b[x]); 95 sad += abs(pred - src[x]); 96 } 97 98 src += src_stride; 99 a += a_stride; 100 b += b_stride; 101 m += m_stride; 102 } 103 104 return sad; 105 } 106 107 #define HIGHBD_MASKSADMXN(m, n) \ 108 unsigned int aom_highbd_masked_sad##m##x##n##_c( \ 109 const uint8_t *src8, int src_stride, const uint8_t *ref8, \ 110 int ref_stride, const uint8_t *second_pred8, const uint8_t *msk, \ 111 int msk_stride, int invert_mask) { \ 112 if (!invert_mask) \ 113 return highbd_masked_sad(src8, src_stride, ref8, ref_stride, \ 114 second_pred8, m, msk, msk_stride, m, n); \ 115 else \ 116 return highbd_masked_sad(src8, src_stride, second_pred8, m, ref8, \ 117 ref_stride, msk, msk_stride, m, n); \ 118 } 119 120 HIGHBD_MASKSADMXN(128, 128) 121 HIGHBD_MASKSADMXN(128, 64) 122 HIGHBD_MASKSADMXN(64, 128) 123 HIGHBD_MASKSADMXN(64, 64) 124 HIGHBD_MASKSADMXN(64, 32) 125 HIGHBD_MASKSADMXN(32, 64) 126 HIGHBD_MASKSADMXN(32, 32) 127 HIGHBD_MASKSADMXN(32, 16) 128 HIGHBD_MASKSADMXN(16, 32) 129 HIGHBD_MASKSADMXN(16, 16) 130 HIGHBD_MASKSADMXN(16, 8) 131 HIGHBD_MASKSADMXN(8, 16) 132 HIGHBD_MASKSADMXN(8, 8) 133 HIGHBD_MASKSADMXN(8, 4) 134 HIGHBD_MASKSADMXN(4, 8) 135 HIGHBD_MASKSADMXN(4, 4) 136 #if !CONFIG_REALTIME_ONLY 137 HIGHBD_MASKSADMXN(4, 16) 138 HIGHBD_MASKSADMXN(16, 4) 139 HIGHBD_MASKSADMXN(8, 32) 140 HIGHBD_MASKSADMXN(32, 8) 141 HIGHBD_MASKSADMXN(16, 64) 142 HIGHBD_MASKSADMXN(64, 16) 143 #endif // !CONFIG_REALTIME_ONLY 144 #endif // CONFIG_AV1_HIGHBITDEPTH 145 146 #if !CONFIG_REALTIME_ONLY 147 // pre: predictor being evaluated 148 // wsrc: target weighted prediction (has been *4096 to keep precision) 149 // mask: 2d weights (scaled by 4096) 150 static inline unsigned int obmc_sad(const uint8_t *pre, int pre_stride, 151 const int32_t *wsrc, const int32_t *mask, 152 int width, int height) { 153 int y, x; 154 unsigned int sad = 0; 155 156 for (y = 0; y < height; y++) { 157 for (x = 0; x < width; x++) 158 sad += ROUND_POWER_OF_TWO(abs(wsrc[x] - pre[x] * mask[x]), 12); 159 160 pre += pre_stride; 161 wsrc += width; 162 mask += width; 163 } 164 165 return sad; 166 } 167 168 #define OBMCSADMXN(m, n) \ 169 unsigned int aom_obmc_sad##m##x##n##_c(const uint8_t *ref, int ref_stride, \ 170 const int32_t *wsrc, \ 171 const int32_t *mask) { \ 172 return obmc_sad(ref, ref_stride, wsrc, mask, m, n); \ 173 } 174 175 OBMCSADMXN(128, 128) 176 OBMCSADMXN(128, 64) 177 OBMCSADMXN(64, 128) 178 OBMCSADMXN(64, 64) 179 OBMCSADMXN(64, 32) 180 OBMCSADMXN(32, 64) 181 OBMCSADMXN(32, 32) 182 OBMCSADMXN(32, 16) 183 OBMCSADMXN(16, 32) 184 OBMCSADMXN(16, 16) 185 OBMCSADMXN(16, 8) 186 OBMCSADMXN(8, 16) 187 OBMCSADMXN(8, 8) 188 OBMCSADMXN(8, 4) 189 OBMCSADMXN(4, 8) 190 OBMCSADMXN(4, 4) 191 OBMCSADMXN(4, 16) 192 OBMCSADMXN(16, 4) 193 OBMCSADMXN(8, 32) 194 OBMCSADMXN(32, 8) 195 OBMCSADMXN(16, 64) 196 OBMCSADMXN(64, 16) 197 198 #if CONFIG_AV1_HIGHBITDEPTH 199 static inline unsigned int highbd_obmc_sad(const uint8_t *pre8, int pre_stride, 200 const int32_t *wsrc, 201 const int32_t *mask, int width, 202 int height) { 203 int y, x; 204 unsigned int sad = 0; 205 const uint16_t *pre = CONVERT_TO_SHORTPTR(pre8); 206 207 for (y = 0; y < height; y++) { 208 for (x = 0; x < width; x++) 209 sad += ROUND_POWER_OF_TWO(abs(wsrc[x] - pre[x] * mask[x]), 12); 210 211 pre += pre_stride; 212 wsrc += width; 213 mask += width; 214 } 215 216 return sad; 217 } 218 219 #define HIGHBD_OBMCSADMXN(m, n) \ 220 unsigned int aom_highbd_obmc_sad##m##x##n##_c( \ 221 const uint8_t *ref, int ref_stride, const int32_t *wsrc, \ 222 const int32_t *mask) { \ 223 return highbd_obmc_sad(ref, ref_stride, wsrc, mask, m, n); \ 224 } 225 226 HIGHBD_OBMCSADMXN(128, 128) 227 HIGHBD_OBMCSADMXN(128, 64) 228 HIGHBD_OBMCSADMXN(64, 128) 229 HIGHBD_OBMCSADMXN(64, 64) 230 HIGHBD_OBMCSADMXN(64, 32) 231 HIGHBD_OBMCSADMXN(32, 64) 232 HIGHBD_OBMCSADMXN(32, 32) 233 HIGHBD_OBMCSADMXN(32, 16) 234 HIGHBD_OBMCSADMXN(16, 32) 235 HIGHBD_OBMCSADMXN(16, 16) 236 HIGHBD_OBMCSADMXN(16, 8) 237 HIGHBD_OBMCSADMXN(8, 16) 238 HIGHBD_OBMCSADMXN(8, 8) 239 HIGHBD_OBMCSADMXN(8, 4) 240 HIGHBD_OBMCSADMXN(4, 8) 241 HIGHBD_OBMCSADMXN(4, 4) 242 HIGHBD_OBMCSADMXN(4, 16) 243 HIGHBD_OBMCSADMXN(16, 4) 244 HIGHBD_OBMCSADMXN(8, 32) 245 HIGHBD_OBMCSADMXN(32, 8) 246 HIGHBD_OBMCSADMXN(16, 64) 247 HIGHBD_OBMCSADMXN(64, 16) 248 #endif // CONFIG_AV1_HIGHBITDEPTH 249 #endif // !CONFIG_REALTIME_ONLY