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 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 unsigned int sad = 0; 24 25 for (y = 0; y < height; y++) { 26 for (x = 0; x < width; x++) sad += abs(a[x] - b[x]); 27 28 a += a_stride; 29 b += b_stride; 30 } 31 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 DECLARE_ALIGNED(16, 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 sadMxN(64, 64) 73 sadMxNx4D(64, 64) 74 75 // 64x32 76 sadMxN(64, 32) 77 sadMxNx4D(64, 32) 78 79 // 32x64 80 sadMxN(32, 64) 81 sadMxNx4D(32, 64) 82 83 // 32x32 84 sadMxN(32, 32) 85 sadMxNx4D(32, 32) 86 87 // 32x16 88 sadMxN(32, 16) 89 sadMxNx4D(32, 16) 90 91 // 16x32 92 sadMxN(16, 32) 93 sadMxNx4D(16, 32) 94 95 // 16x16 96 sadMxN(16, 16) 97 sadMxNxK(16, 16, 3) 98 sadMxNxK(16, 16, 8) 99 sadMxNx4D(16, 16) 100 101 // 16x8 102 sadMxN(16, 8) 103 sadMxNxK(16, 8, 3) 104 sadMxNxK(16, 8, 8) 105 sadMxNx4D(16, 8) 106 107 // 8x16 108 sadMxN(8, 16) 109 sadMxNxK(8, 16, 3) 110 sadMxNxK(8, 16, 8) 111 sadMxNx4D(8, 16) 112 113 // 8x8 114 sadMxN(8, 8) 115 sadMxNxK(8, 8, 3) 116 sadMxNxK(8, 8, 8) 117 sadMxNx4D(8, 8) 118 119 // 8x4 120 sadMxN(8, 4) 121 sadMxNx4D(8, 4) 122 123 // 4x8 124 sadMxN(4, 8) 125 sadMxNx4D(4, 8) 126 127 // 4x4 128 sadMxN(4, 4) 129 sadMxNxK(4, 4, 3) 130 sadMxNxK(4, 4, 8) 131 sadMxNx4D(4, 4) 132 /* clang-format on */ 133 134 #if CONFIG_VP9_HIGHBITDEPTH 135 static INLINE 136 unsigned int highbd_sad(const uint8_t *a8, int a_stride, const uint8_t *b8, 137 int b_stride, int width, int height) { 138 int y, x; 139 unsigned int sad = 0; 140 const uint16_t *a = CONVERT_TO_SHORTPTR(a8); 141 const uint16_t *b = CONVERT_TO_SHORTPTR(b8); 142 for (y = 0; y < height; y++) { 143 for (x = 0; x < width; x++) sad += abs(a[x] - b[x]); 144 145 a += a_stride; 146 b += b_stride; 147 } 148 return sad; 149 } 150 151 static INLINE unsigned int highbd_sadb(const uint8_t *a8, int a_stride, 152 const uint16_t *b, int b_stride, 153 int width, int height) { 154 int y, x; 155 unsigned int sad = 0; 156 const uint16_t *a = CONVERT_TO_SHORTPTR(a8); 157 for (y = 0; y < height; y++) { 158 for (x = 0; x < width; x++) sad += abs(a[x] - b[x]); 159 160 a += a_stride; 161 b += b_stride; 162 } 163 return sad; 164 } 165 166 #define highbd_sadMxN(m, n) \ 167 unsigned int vpx_highbd_sad##m##x##n##_c(const uint8_t *src, int src_stride, \ 168 const uint8_t *ref, \ 169 int ref_stride) { \ 170 return highbd_sad(src, src_stride, ref, ref_stride, m, n); \ 171 } \ 172 unsigned int vpx_highbd_sad##m##x##n##_avg_c( \ 173 const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \ 174 const uint8_t *second_pred) { \ 175 DECLARE_ALIGNED(16, uint16_t, comp_pred[m * n]); \ 176 vpx_highbd_comp_avg_pred_c(comp_pred, second_pred, m, n, ref, ref_stride); \ 177 return highbd_sadb(src, src_stride, comp_pred, m, m, n); \ 178 } 179 180 #define highbd_sadMxNx4D(m, n) \ 181 void vpx_highbd_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride, \ 182 const uint8_t *const ref_array[], \ 183 int ref_stride, uint32_t *sad_array) { \ 184 int i; \ 185 for (i = 0; i < 4; ++i) { \ 186 sad_array[i] = vpx_highbd_sad##m##x##n##_c(src, src_stride, \ 187 ref_array[i], ref_stride); \ 188 } \ 189 } 190 191 /* clang-format off */ 192 // 64x64 193 highbd_sadMxN(64, 64) 194 highbd_sadMxNx4D(64, 64) 195 196 // 64x32 197 highbd_sadMxN(64, 32) 198 highbd_sadMxNx4D(64, 32) 199 200 // 32x64 201 highbd_sadMxN(32, 64) 202 highbd_sadMxNx4D(32, 64) 203 204 // 32x32 205 highbd_sadMxN(32, 32) 206 highbd_sadMxNx4D(32, 32) 207 208 // 32x16 209 highbd_sadMxN(32, 16) 210 highbd_sadMxNx4D(32, 16) 211 212 // 16x32 213 highbd_sadMxN(16, 32) 214 highbd_sadMxNx4D(16, 32) 215 216 // 16x16 217 highbd_sadMxN(16, 16) 218 highbd_sadMxNx4D(16, 16) 219 220 // 16x8 221 highbd_sadMxN(16, 8) 222 highbd_sadMxNx4D(16, 8) 223 224 // 8x16 225 highbd_sadMxN(8, 16) 226 highbd_sadMxNx4D(8, 16) 227 228 // 8x8 229 highbd_sadMxN(8, 8) 230 highbd_sadMxNx4D(8, 8) 231 232 // 8x4 233 highbd_sadMxN(8, 4) 234 highbd_sadMxNx4D(8, 4) 235 236 // 4x8 237 highbd_sadMxN(4, 8) 238 highbd_sadMxNx4D(4, 8) 239 240 // 4x4 241 highbd_sadMxN(4, 4) 242 highbd_sadMxNx4D(4, 4) 243 /* clang-format on */ 244 245 #endif // CONFIG_VP9_HIGHBITDEPTH 246