tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

sad.c (13207B)


      1 /*
      2 * Copyright (c) 2016, 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 /* Sum the difference between every corresponding element of the buffers. */
     22 static inline unsigned int sad(const uint8_t *a, int a_stride, const uint8_t *b,
     23                               int b_stride, int width, int height) {
     24  int y, x;
     25  unsigned int sad = 0;
     26 
     27  for (y = 0; y < height; y++) {
     28    for (x = 0; x < width; x++) {
     29      sad += abs(a[x] - b[x]);
     30    }
     31 
     32    a += a_stride;
     33    b += b_stride;
     34  }
     35  return sad;
     36 }
     37 
     38 #define SADMXN(m, n)                                                      \
     39  unsigned int aom_sad##m##x##n##_c(const uint8_t *src, int src_stride,   \
     40                                    const uint8_t *ref, int ref_stride) { \
     41    return sad(src, src_stride, ref, ref_stride, m, n);                   \
     42  }
     43 
     44 #define SADMXN_AVG(m, n)                                                    \
     45  unsigned int aom_sad##m##x##n##_avg_c(const uint8_t *src, int src_stride, \
     46                                        const uint8_t *ref, int ref_stride, \
     47                                        const uint8_t *second_pred) {       \
     48    uint8_t comp_pred[m * n];                                               \
     49    aom_comp_avg_pred(comp_pred, second_pred, m, n, ref, ref_stride);       \
     50    return sad(src, src_stride, comp_pred, m, m, n);                        \
     51  }
     52 
     53 #define SADMXN_SKIP(m, n)                                                     \
     54  unsigned int aom_sad_skip_##m##x##n##_c(const uint8_t *src, int src_stride, \
     55                                          const uint8_t *ref,                 \
     56                                          int ref_stride) {                   \
     57    return 2 * sad(src, 2 * src_stride, ref, 2 * ref_stride, (m), (n / 2));   \
     58  }
     59 
     60 #define SADMXN_NO_SKIP(m, n) \
     61  SADMXN(m, n)               \
     62  SADMXN_AVG(m, n)
     63 
     64 #define SADMXN_NO_AVG(m, n) \
     65  SADMXN(m, n)              \
     66  SADMXN_SKIP(m, n)
     67 
     68 #define SADMXN_ALL(m, n) \
     69  SADMXN(m, n)           \
     70  SADMXN_AVG(m, n)       \
     71  SADMXN_SKIP(m, n)
     72 
     73 // Calculate sad against 4 reference locations and store each in sad_array
     74 #define SAD_MXNX4D_NO_SKIP(m, n)                                           \
     75  void aom_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride,         \
     76                               const uint8_t *const ref_array[4],          \
     77                               int ref_stride, uint32_t sad_array[4]) {    \
     78    int i;                                                                 \
     79    for (i = 0; i < 4; ++i) {                                              \
     80      sad_array[i] =                                                       \
     81          aom_sad##m##x##n##_c(src, src_stride, ref_array[i], ref_stride); \
     82    }                                                                      \
     83  }
     84 
     85 #define SAD_MXNX4D(m, n)                                                      \
     86  SAD_MXNX4D_NO_SKIP(m, n)                                                    \
     87  void aom_sad_skip_##m##x##n##x4d_c(const uint8_t *src, int src_stride,      \
     88                                     const uint8_t *const ref_array[4],       \
     89                                     int ref_stride, uint32_t sad_array[4]) { \
     90    int i;                                                                    \
     91    for (i = 0; i < 4; ++i) {                                                 \
     92      sad_array[i] = 2 * sad(src, 2 * src_stride, ref_array[i],               \
     93                             2 * ref_stride, (m), (n / 2));                   \
     94    }                                                                         \
     95  }
     96 // Call SIMD version of aom_sad_mxnx4d if the 3d version is unavailable.
     97 #define SAD_MXNX3D(m, n)                                                      \
     98  void aom_sad##m##x##n##x3d_c(const uint8_t *src, int src_stride,            \
     99                               const uint8_t *const ref_array[4],             \
    100                               int ref_stride, uint32_t sad_array[4]) {       \
    101    aom_sad##m##x##n##x4d(src, src_stride, ref_array, ref_stride, sad_array); \
    102  }
    103 
    104 // 128x128
    105 SADMXN_ALL(128, 128)
    106 SAD_MXNX4D(128, 128)
    107 SAD_MXNX3D(128, 128)
    108 
    109 // 128x64
    110 SADMXN_ALL(128, 64)
    111 SAD_MXNX4D(128, 64)
    112 SAD_MXNX3D(128, 64)
    113 
    114 // 64x128
    115 SADMXN_ALL(64, 128)
    116 SAD_MXNX4D(64, 128)
    117 SAD_MXNX3D(64, 128)
    118 
    119 // 64x64
    120 SADMXN_ALL(64, 64)
    121 SAD_MXNX4D(64, 64)
    122 SAD_MXNX3D(64, 64)
    123 
    124 // 64x32
    125 SADMXN_ALL(64, 32)
    126 SAD_MXNX4D(64, 32)
    127 SAD_MXNX3D(64, 32)
    128 
    129 // 32x64
    130 SADMXN_ALL(32, 64)
    131 SAD_MXNX4D(32, 64)
    132 SAD_MXNX3D(32, 64)
    133 
    134 // 32x32
    135 SADMXN_ALL(32, 32)
    136 SAD_MXNX4D(32, 32)
    137 SAD_MXNX3D(32, 32)
    138 
    139 // 32x16
    140 SADMXN_ALL(32, 16)
    141 SAD_MXNX4D(32, 16)
    142 SAD_MXNX3D(32, 16)
    143 
    144 // 16x32
    145 SADMXN_ALL(16, 32)
    146 SAD_MXNX4D(16, 32)
    147 SAD_MXNX3D(16, 32)
    148 
    149 // 16x16
    150 SADMXN_ALL(16, 16)
    151 SAD_MXNX4D(16, 16)
    152 SAD_MXNX3D(16, 16)
    153 
    154 // 16x8
    155 SADMXN_NO_SKIP(16, 8)
    156 SAD_MXNX4D_NO_SKIP(16, 8)
    157 SAD_MXNX3D(16, 8)
    158 
    159 // 8x16
    160 SADMXN_ALL(8, 16)
    161 SAD_MXNX4D(8, 16)
    162 SAD_MXNX3D(8, 16)
    163 
    164 // 8x8
    165 SADMXN_NO_SKIP(8, 8)
    166 SAD_MXNX4D_NO_SKIP(8, 8)
    167 SAD_MXNX3D(8, 8)
    168 
    169 // 8x4
    170 SADMXN(8, 4)
    171 SAD_MXNX4D_NO_SKIP(8, 4)
    172 SAD_MXNX3D(8, 4)
    173 
    174 // 4x8
    175 SADMXN(4, 8)
    176 SAD_MXNX4D_NO_SKIP(4, 8)
    177 SAD_MXNX3D(4, 8)
    178 
    179 // 4x4
    180 SADMXN(4, 4)
    181 SAD_MXNX4D_NO_SKIP(4, 4)
    182 SAD_MXNX3D(4, 4)
    183 
    184 #if !CONFIG_REALTIME_ONLY
    185 SADMXN_NO_AVG(4, 16)
    186 SAD_MXNX4D(4, 16)
    187 SADMXN(16, 4)
    188 SAD_MXNX4D_NO_SKIP(16, 4)
    189 SADMXN_ALL(8, 32)
    190 SAD_MXNX4D(8, 32)
    191 SADMXN_NO_SKIP(32, 8)
    192 SAD_MXNX4D_NO_SKIP(32, 8)
    193 SADMXN_ALL(16, 64)
    194 SAD_MXNX4D(16, 64)
    195 SADMXN_ALL(64, 16)
    196 SAD_MXNX4D(64, 16)
    197 SAD_MXNX3D(4, 16)
    198 SAD_MXNX3D(16, 4)
    199 SAD_MXNX3D(8, 32)
    200 SAD_MXNX3D(32, 8)
    201 SAD_MXNX3D(16, 64)
    202 SAD_MXNX3D(64, 16)
    203 #endif  // !CONFIG_REALTIME_ONLY
    204 
    205 #if CONFIG_AV1_HIGHBITDEPTH
    206 static inline unsigned int highbd_sad(const uint8_t *a8, int a_stride,
    207                                      const uint8_t *b8, int b_stride,
    208                                      int width, int height) {
    209  int y, x;
    210  unsigned int sad = 0;
    211  const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
    212  const uint16_t *b = CONVERT_TO_SHORTPTR(b8);
    213  for (y = 0; y < height; y++) {
    214    for (x = 0; x < width; x++) {
    215      sad += abs(a[x] - b[x]);
    216    }
    217 
    218    a += a_stride;
    219    b += b_stride;
    220  }
    221  return sad;
    222 }
    223 
    224 static inline unsigned int highbd_sadb(const uint8_t *a8, int a_stride,
    225                                       const uint8_t *b8, int b_stride,
    226                                       int width, int height) {
    227  int y, x;
    228  unsigned int sad = 0;
    229  const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
    230  const uint16_t *b = CONVERT_TO_SHORTPTR(b8);
    231  for (y = 0; y < height; y++) {
    232    for (x = 0; x < width; x++) {
    233      sad += abs(a[x] - b[x]);
    234    }
    235 
    236    a += a_stride;
    237    b += b_stride;
    238  }
    239  return sad;
    240 }
    241 
    242 #define HIGHBD_SADMXN(m, n)                                                    \
    243  unsigned int aom_highbd_sad##m##x##n##_c(const uint8_t *src, int src_stride, \
    244                                           const uint8_t *ref,                 \
    245                                           int ref_stride) {                   \
    246    return highbd_sad(src, src_stride, ref, ref_stride, m, n);                 \
    247  }
    248 
    249 #define HIGHBD_SADMXN_AVG(m, n)                                               \
    250  unsigned int aom_highbd_sad##m##x##n##_avg_c(                               \
    251      const uint8_t *src, int src_stride, const uint8_t *ref, int ref_stride, \
    252      const uint8_t *second_pred) {                                           \
    253    uint16_t comp_pred[m * n];                                                \
    254    uint8_t *const comp_pred8 = CONVERT_TO_BYTEPTR(comp_pred);                \
    255    aom_highbd_comp_avg_pred(comp_pred8, second_pred, m, n, ref, ref_stride); \
    256    return highbd_sadb(src, src_stride, comp_pred8, m, m, n);                 \
    257  }
    258 
    259 #define HIGHBD_SADMXN_SKIP(m, n)                                               \
    260  unsigned int aom_highbd_sad_skip_##m##x##n##_c(                              \
    261      const uint8_t *src, int src_stride, const uint8_t *ref,                  \
    262      int ref_stride) {                                                        \
    263    return 2 *                                                                 \
    264           highbd_sad(src, 2 * src_stride, ref, 2 * ref_stride, (m), (n / 2)); \
    265  }
    266 
    267 #define HIGHBD_SADMXN_NO_SKIP(m, n) \
    268  HIGHBD_SADMXN(m, n)               \
    269  HIGHBD_SADMXN_AVG(m, n)
    270 
    271 #define HIGHBD_SADMXN_NO_AVG(m, n) \
    272  HIGHBD_SADMXN(m, n)              \
    273  HIGHBD_SADMXN_SKIP(m, n)
    274 
    275 #define HIGHBD_SADMXN_ALL(m, n) \
    276  HIGHBD_SADMXN(m, n)           \
    277  HIGHBD_SADMXN_AVG(m, n)       \
    278  HIGHBD_SADMXN_SKIP(m, n)
    279 
    280 #define HIGHBD_SAD_MXNX4D_NO_SKIP(m, n)                                        \
    281  void aom_highbd_sad##m##x##n##x4d_c(const uint8_t *src, int src_stride,      \
    282                                      const uint8_t *const ref_array[4],       \
    283                                      int ref_stride, uint32_t sad_array[4]) { \
    284    int i;                                                                     \
    285    for (i = 0; i < 4; ++i) {                                                  \
    286      sad_array[i] = aom_highbd_sad##m##x##n##_c(src, src_stride,              \
    287                                                 ref_array[i], ref_stride);    \
    288    }                                                                          \
    289  }
    290 
    291 #define HIGHBD_SAD_MXNX4D(m, n)                                              \
    292  HIGHBD_SAD_MXNX4D_NO_SKIP(m, n)                                            \
    293  void aom_highbd_sad_skip_##m##x##n##x4d_c(                                 \
    294      const uint8_t *src, int src_stride, const uint8_t *const ref_array[4], \
    295      int ref_stride, uint32_t sad_array[4]) {                               \
    296    int i;                                                                   \
    297    for (i = 0; i < 4; ++i) {                                                \
    298      sad_array[i] = 2 * highbd_sad(src, 2 * src_stride, ref_array[i],       \
    299                                    2 * ref_stride, (m), (n / 2));           \
    300    }                                                                        \
    301  }
    302 // Call SIMD version of aom_highbd_sad_mxnx4d if the 3d version is unavailable.
    303 #define HIGHBD_SAD_MXNX3D(m, n)                                                \
    304  void aom_highbd_sad##m##x##n##x3d_c(const uint8_t *src, int src_stride,      \
    305                                      const uint8_t *const ref_array[4],       \
    306                                      int ref_stride, uint32_t sad_array[4]) { \
    307    aom_highbd_sad##m##x##n##x4d(src, src_stride, ref_array, ref_stride,       \
    308                                 sad_array);                                   \
    309  }
    310 
    311 // 128x128
    312 HIGHBD_SADMXN_ALL(128, 128)
    313 HIGHBD_SAD_MXNX4D(128, 128)
    314 HIGHBD_SAD_MXNX3D(128, 128)
    315 
    316 // 128x64
    317 HIGHBD_SADMXN_ALL(128, 64)
    318 HIGHBD_SAD_MXNX4D(128, 64)
    319 HIGHBD_SAD_MXNX3D(128, 64)
    320 
    321 // 64x128
    322 HIGHBD_SADMXN_ALL(64, 128)
    323 HIGHBD_SAD_MXNX4D(64, 128)
    324 HIGHBD_SAD_MXNX3D(64, 128)
    325 
    326 // 64x64
    327 HIGHBD_SADMXN_ALL(64, 64)
    328 HIGHBD_SAD_MXNX4D(64, 64)
    329 HIGHBD_SAD_MXNX3D(64, 64)
    330 
    331 // 64x32
    332 HIGHBD_SADMXN_ALL(64, 32)
    333 HIGHBD_SAD_MXNX4D(64, 32)
    334 HIGHBD_SAD_MXNX3D(64, 32)
    335 
    336 // 32x64
    337 HIGHBD_SADMXN_ALL(32, 64)
    338 HIGHBD_SAD_MXNX4D(32, 64)
    339 HIGHBD_SAD_MXNX3D(32, 64)
    340 
    341 // 32x32
    342 HIGHBD_SADMXN_ALL(32, 32)
    343 HIGHBD_SAD_MXNX4D(32, 32)
    344 HIGHBD_SAD_MXNX3D(32, 32)
    345 
    346 // 32x16
    347 HIGHBD_SADMXN_ALL(32, 16)
    348 HIGHBD_SAD_MXNX4D(32, 16)
    349 HIGHBD_SAD_MXNX3D(32, 16)
    350 
    351 // 16x32
    352 HIGHBD_SADMXN_ALL(16, 32)
    353 HIGHBD_SAD_MXNX4D(16, 32)
    354 HIGHBD_SAD_MXNX3D(16, 32)
    355 
    356 // 16x16
    357 HIGHBD_SADMXN_ALL(16, 16)
    358 HIGHBD_SAD_MXNX4D(16, 16)
    359 HIGHBD_SAD_MXNX3D(16, 16)
    360 
    361 // 16x8
    362 HIGHBD_SADMXN_NO_SKIP(16, 8)
    363 HIGHBD_SAD_MXNX4D_NO_SKIP(16, 8)
    364 HIGHBD_SAD_MXNX3D(16, 8)
    365 
    366 // 8x16
    367 HIGHBD_SADMXN_ALL(8, 16)
    368 HIGHBD_SAD_MXNX4D(8, 16)
    369 HIGHBD_SAD_MXNX3D(8, 16)
    370 
    371 // 8x8
    372 HIGHBD_SADMXN_NO_SKIP(8, 8)
    373 HIGHBD_SAD_MXNX4D_NO_SKIP(8, 8)
    374 HIGHBD_SAD_MXNX3D(8, 8)
    375 
    376 // 8x4
    377 HIGHBD_SADMXN(8, 4)
    378 HIGHBD_SAD_MXNX4D_NO_SKIP(8, 4)
    379 HIGHBD_SAD_MXNX3D(8, 4)
    380 
    381 // 4x8
    382 HIGHBD_SADMXN(4, 8)
    383 HIGHBD_SAD_MXNX4D_NO_SKIP(4, 8)
    384 HIGHBD_SAD_MXNX3D(4, 8)
    385 
    386 // 4x4
    387 HIGHBD_SADMXN(4, 4)
    388 HIGHBD_SAD_MXNX4D_NO_SKIP(4, 4)
    389 HIGHBD_SAD_MXNX3D(4, 4)
    390 
    391 #if !CONFIG_REALTIME_ONLY
    392 HIGHBD_SADMXN_NO_AVG(4, 16)
    393 HIGHBD_SAD_MXNX4D(4, 16)
    394 HIGHBD_SADMXN(16, 4)
    395 HIGHBD_SAD_MXNX4D_NO_SKIP(16, 4)
    396 HIGHBD_SADMXN_ALL(8, 32)
    397 HIGHBD_SAD_MXNX4D(8, 32)
    398 HIGHBD_SADMXN_NO_SKIP(32, 8)
    399 HIGHBD_SAD_MXNX4D_NO_SKIP(32, 8)
    400 HIGHBD_SADMXN_ALL(16, 64)
    401 HIGHBD_SAD_MXNX4D(16, 64)
    402 HIGHBD_SADMXN_ALL(64, 16)
    403 HIGHBD_SAD_MXNX4D(64, 16)
    404 
    405 HIGHBD_SAD_MXNX3D(4, 16)
    406 HIGHBD_SAD_MXNX3D(16, 4)
    407 HIGHBD_SAD_MXNX3D(8, 32)
    408 HIGHBD_SAD_MXNX3D(32, 8)
    409 HIGHBD_SAD_MXNX3D(16, 64)
    410 HIGHBD_SAD_MXNX3D(64, 16)
    411 #endif  // !CONFIG_REALTIME_ONLY
    412 #endif  // CONFIG_AV1_HIGHBITDEPTH