OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2010 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 "./vpx_config.h" |
| 12 #include "./vpx_dsp_rtcd.h" |
| 13 |
| 14 #include "vpx_ports/mem.h" |
| 15 #include "vpx/vpx_integer.h" |
| 16 |
| 17 unsigned int vpx_get4x4sse_cs_c(const unsigned char *a, int a_stride, |
| 18 const unsigned char *b, int b_stride) { |
| 19 int distortion = 0; |
| 20 int r, c; |
| 21 |
| 22 for (r = 0; r < 4; r++) { |
| 23 for (c = 0; c < 4; c++) { |
| 24 int diff = a[c] - b[c]; |
| 25 distortion += diff * diff; |
| 26 } |
| 27 |
| 28 a += a_stride; |
| 29 b += b_stride; |
| 30 } |
| 31 |
| 32 return distortion; |
| 33 } |
| 34 |
| 35 unsigned int vpx_get_mb_ss_c(const int16_t *a) { |
| 36 unsigned int i, sum = 0; |
| 37 |
| 38 for (i = 0; i < 256; ++i) { |
| 39 sum += a[i] * a[i]; |
| 40 } |
| 41 |
| 42 return sum; |
| 43 } |
| 44 |
| 45 static void variance(const uint8_t *a, int a_stride, |
| 46 const uint8_t *b, int b_stride, |
| 47 int w, int h, unsigned int *sse, int *sum) { |
| 48 int i, j; |
| 49 |
| 50 *sum = 0; |
| 51 *sse = 0; |
| 52 |
| 53 for (i = 0; i < h; i++) { |
| 54 for (j = 0; j < w; j++) { |
| 55 const int diff = a[j] - b[j]; |
| 56 *sum += diff; |
| 57 *sse += diff * diff; |
| 58 } |
| 59 |
| 60 a += a_stride; |
| 61 b += b_stride; |
| 62 } |
| 63 } |
| 64 |
| 65 #define VAR(W, H) \ |
| 66 unsigned int vpx_variance##W##x##H##_c(const uint8_t *a, int a_stride, \ |
| 67 const uint8_t *b, int b_stride, \ |
| 68 unsigned int *sse) { \ |
| 69 int sum; \ |
| 70 variance(a, a_stride, b, b_stride, W, H, sse, &sum); \ |
| 71 return *sse - (((int64_t)sum * sum) / (W * H)); \ |
| 72 } |
| 73 |
| 74 /* Identical to the variance call except it takes an additional parameter, sum, |
| 75 * and returns that value using pass-by-reference instead of returning |
| 76 * sse - sum^2 / w*h |
| 77 */ |
| 78 #define GET_VAR(W, H) \ |
| 79 void vpx_get##W##x##H##var_c(const uint8_t *a, int a_stride, \ |
| 80 const uint8_t *b, int b_stride, \ |
| 81 unsigned int *sse, int *sum) { \ |
| 82 variance(a, a_stride, b, b_stride, W, H, sse, sum); \ |
| 83 } |
| 84 |
| 85 /* Identical to the variance call except it does not calculate the |
| 86 * sse - sum^2 / w*h and returns sse in addtion to modifying the passed in |
| 87 * variable. |
| 88 */ |
| 89 #define MSE(W, H) \ |
| 90 unsigned int vpx_mse##W##x##H##_c(const uint8_t *a, int a_stride, \ |
| 91 const uint8_t *b, int b_stride, \ |
| 92 unsigned int *sse) { \ |
| 93 int sum; \ |
| 94 variance(a, a_stride, b, b_stride, W, H, sse, &sum); \ |
| 95 return *sse; \ |
| 96 } |
| 97 |
| 98 VAR(64, 64) |
| 99 VAR(64, 32) |
| 100 VAR(32, 64) |
| 101 VAR(32, 32) |
| 102 VAR(32, 16) |
| 103 VAR(16, 32) |
| 104 VAR(16, 16) |
| 105 VAR(16, 8) |
| 106 VAR(8, 16) |
| 107 VAR(8, 8) |
| 108 VAR(8, 4) |
| 109 VAR(4, 8) |
| 110 VAR(4, 4) |
| 111 |
| 112 GET_VAR(16, 16) |
| 113 GET_VAR(8, 8) |
| 114 |
| 115 MSE(16, 16) |
| 116 MSE(16, 8) |
| 117 MSE(8, 16) |
| 118 MSE(8, 8) |
| 119 |
| 120 void vpx_comp_avg_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, |
| 121 int height, const uint8_t *ref, int ref_stride) { |
| 122 int i, j; |
| 123 |
| 124 for (i = 0; i < height; i++) { |
| 125 for (j = 0; j < width; j++) { |
| 126 const int tmp = pred[j] + ref[j]; |
| 127 comp_pred[j] = ROUND_POWER_OF_TWO(tmp, 1); |
| 128 } |
| 129 comp_pred += width; |
| 130 pred += width; |
| 131 ref += ref_stride; |
| 132 } |
| 133 } |
| 134 |
| 135 #if CONFIG_VP9_HIGHBITDEPTH |
| 136 static void highbd_variance64(const uint8_t *a8, int a_stride, |
| 137 const uint8_t *b8, int b_stride, |
| 138 int w, int h, uint64_t *sse, uint64_t *sum) { |
| 139 int i, j; |
| 140 |
| 141 uint16_t *a = CONVERT_TO_SHORTPTR(a8); |
| 142 uint16_t *b = CONVERT_TO_SHORTPTR(b8); |
| 143 *sum = 0; |
| 144 *sse = 0; |
| 145 |
| 146 for (i = 0; i < h; i++) { |
| 147 for (j = 0; j < w; j++) { |
| 148 const int diff = a[j] - b[j]; |
| 149 *sum += diff; |
| 150 *sse += diff * diff; |
| 151 } |
| 152 a += a_stride; |
| 153 b += b_stride; |
| 154 } |
| 155 } |
| 156 |
| 157 static void highbd_8_variance(const uint8_t *a8, int a_stride, |
| 158 const uint8_t *b8, int b_stride, |
| 159 int w, int h, unsigned int *sse, int *sum) { |
| 160 uint64_t sse_long = 0; |
| 161 uint64_t sum_long = 0; |
| 162 highbd_variance64(a8, a_stride, b8, b_stride, w, h, &sse_long, &sum_long); |
| 163 *sse = (unsigned int)sse_long; |
| 164 *sum = (int)sum_long; |
| 165 } |
| 166 |
| 167 static void highbd_10_variance(const uint8_t *a8, int a_stride, |
| 168 const uint8_t *b8, int b_stride, |
| 169 int w, int h, unsigned int *sse, int *sum) { |
| 170 uint64_t sse_long = 0; |
| 171 uint64_t sum_long = 0; |
| 172 highbd_variance64(a8, a_stride, b8, b_stride, w, h, &sse_long, &sum_long); |
| 173 *sse = (unsigned int)ROUND_POWER_OF_TWO(sse_long, 4); |
| 174 *sum = (int)ROUND_POWER_OF_TWO(sum_long, 2); |
| 175 } |
| 176 |
| 177 static void highbd_12_variance(const uint8_t *a8, int a_stride, |
| 178 const uint8_t *b8, int b_stride, |
| 179 int w, int h, unsigned int *sse, int *sum) { |
| 180 uint64_t sse_long = 0; |
| 181 uint64_t sum_long = 0; |
| 182 highbd_variance64(a8, a_stride, b8, b_stride, w, h, &sse_long, &sum_long); |
| 183 *sse = (unsigned int)ROUND_POWER_OF_TWO(sse_long, 8); |
| 184 *sum = (int)ROUND_POWER_OF_TWO(sum_long, 4); |
| 185 } |
| 186 |
| 187 #define HIGHBD_VAR(W, H) \ |
| 188 unsigned int vpx_highbd_8_variance##W##x##H##_c(const uint8_t *a, \ |
| 189 int a_stride, \ |
| 190 const uint8_t *b, \ |
| 191 int b_stride, \ |
| 192 unsigned int *sse) { \ |
| 193 int sum; \ |
| 194 highbd_8_variance(a, a_stride, b, b_stride, W, H, sse, &sum); \ |
| 195 return *sse - (((int64_t)sum * sum) / (W * H)); \ |
| 196 } \ |
| 197 \ |
| 198 unsigned int vpx_highbd_10_variance##W##x##H##_c(const uint8_t *a, \ |
| 199 int a_stride, \ |
| 200 const uint8_t *b, \ |
| 201 int b_stride, \ |
| 202 unsigned int *sse) { \ |
| 203 int sum; \ |
| 204 highbd_10_variance(a, a_stride, b, b_stride, W, H, sse, &sum); \ |
| 205 return *sse - (((int64_t)sum * sum) / (W * H)); \ |
| 206 } \ |
| 207 \ |
| 208 unsigned int vpx_highbd_12_variance##W##x##H##_c(const uint8_t *a, \ |
| 209 int a_stride, \ |
| 210 const uint8_t *b, \ |
| 211 int b_stride, \ |
| 212 unsigned int *sse) { \ |
| 213 int sum; \ |
| 214 highbd_12_variance(a, a_stride, b, b_stride, W, H, sse, &sum); \ |
| 215 return *sse - (((int64_t)sum * sum) / (W * H)); \ |
| 216 } |
| 217 |
| 218 #define HIGHBD_GET_VAR(S) \ |
| 219 void vpx_highbd_8_get##S##x##S##var_c(const uint8_t *src, int src_stride, \ |
| 220 const uint8_t *ref, int ref_stride, \ |
| 221 unsigned int *sse, int *sum) { \ |
| 222 highbd_8_variance(src, src_stride, ref, ref_stride, S, S, sse, sum); \ |
| 223 } \ |
| 224 \ |
| 225 void vpx_highbd_10_get##S##x##S##var_c(const uint8_t *src, int src_stride, \ |
| 226 const uint8_t *ref, int ref_stride, \ |
| 227 unsigned int *sse, int *sum) { \ |
| 228 highbd_10_variance(src, src_stride, ref, ref_stride, S, S, sse, sum); \ |
| 229 } \ |
| 230 \ |
| 231 void vpx_highbd_12_get##S##x##S##var_c(const uint8_t *src, int src_stride, \ |
| 232 const uint8_t *ref, int ref_stride, \ |
| 233 unsigned int *sse, int *sum) { \ |
| 234 highbd_12_variance(src, src_stride, ref, ref_stride, S, S, sse, sum); \ |
| 235 } |
| 236 |
| 237 #define HIGHBD_MSE(W, H) \ |
| 238 unsigned int vpx_highbd_8_mse##W##x##H##_c(const uint8_t *src, \ |
| 239 int src_stride, \ |
| 240 const uint8_t *ref, \ |
| 241 int ref_stride, \ |
| 242 unsigned int *sse) { \ |
| 243 int sum; \ |
| 244 highbd_8_variance(src, src_stride, ref, ref_stride, W, H, sse, &sum); \ |
| 245 return *sse; \ |
| 246 } \ |
| 247 \ |
| 248 unsigned int vpx_highbd_10_mse##W##x##H##_c(const uint8_t *src, \ |
| 249 int src_stride, \ |
| 250 const uint8_t *ref, \ |
| 251 int ref_stride, \ |
| 252 unsigned int *sse) { \ |
| 253 int sum; \ |
| 254 highbd_10_variance(src, src_stride, ref, ref_stride, W, H, sse, &sum); \ |
| 255 return *sse; \ |
| 256 } \ |
| 257 \ |
| 258 unsigned int vpx_highbd_12_mse##W##x##H##_c(const uint8_t *src, \ |
| 259 int src_stride, \ |
| 260 const uint8_t *ref, \ |
| 261 int ref_stride, \ |
| 262 unsigned int *sse) { \ |
| 263 int sum; \ |
| 264 highbd_12_variance(src, src_stride, ref, ref_stride, W, H, sse, &sum); \ |
| 265 return *sse; \ |
| 266 } |
| 267 |
| 268 HIGHBD_GET_VAR(8) |
| 269 HIGHBD_GET_VAR(16) |
| 270 |
| 271 HIGHBD_MSE(16, 16) |
| 272 HIGHBD_MSE(16, 8) |
| 273 HIGHBD_MSE(8, 16) |
| 274 HIGHBD_MSE(8, 8) |
| 275 |
| 276 HIGHBD_VAR(64, 64) |
| 277 HIGHBD_VAR(64, 32) |
| 278 HIGHBD_VAR(32, 64) |
| 279 HIGHBD_VAR(32, 32) |
| 280 HIGHBD_VAR(32, 16) |
| 281 HIGHBD_VAR(16, 32) |
| 282 HIGHBD_VAR(16, 16) |
| 283 HIGHBD_VAR(16, 8) |
| 284 HIGHBD_VAR(8, 16) |
| 285 HIGHBD_VAR(8, 8) |
| 286 HIGHBD_VAR(8, 4) |
| 287 HIGHBD_VAR(4, 8) |
| 288 HIGHBD_VAR(4, 4) |
| 289 |
| 290 void vpx_highbd_comp_avg_pred(uint16_t *comp_pred, const uint8_t *pred8, |
| 291 int width, int height, const uint8_t *ref8, |
| 292 int ref_stride) { |
| 293 int i, j; |
| 294 uint16_t *pred = CONVERT_TO_SHORTPTR(pred8); |
| 295 uint16_t *ref = CONVERT_TO_SHORTPTR(ref8); |
| 296 for (i = 0; i < height; i++) { |
| 297 for (j = 0; j < width; j++) { |
| 298 const int tmp = pred[j] + ref[j]; |
| 299 comp_pred[j] = ROUND_POWER_OF_TWO(tmp, 1); |
| 300 } |
| 301 comp_pred += width; |
| 302 pred += width; |
| 303 ref += ref_stride; |
| 304 } |
| 305 } |
| 306 #endif // CONFIG_VP9_HIGHBITDEPTH |
OLD | NEW |