tor-browser

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

hybrid_fwd_txfm.c (13490B)


      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 "config/aom_config.h"
     13 #include "config/av1_rtcd.h"
     14 #include "config/aom_dsp_rtcd.h"
     15 
     16 #include "av1/common/idct.h"
     17 #include "av1/common/blockd.h"
     18 #include "av1/encoder/hybrid_fwd_txfm.h"
     19 
     20 /* 4-point reversible, orthonormal Walsh-Hadamard in 3.5 adds, 0.5 shifts per
     21   pixel.
     22   Shared for both high and low bit depth.
     23 */
     24 void av1_fwht4x4_c(const int16_t *input, tran_low_t *output, int stride) {
     25  int i;
     26  tran_high_t a1, b1, c1, d1, e1;
     27  const int16_t *ip_pass0 = input;
     28  const tran_low_t *ip = NULL;
     29  tran_low_t *op = output;
     30 
     31  for (i = 0; i < 4; i++) {
     32    a1 = ip_pass0[0 * stride];
     33    b1 = ip_pass0[1 * stride];
     34    c1 = ip_pass0[2 * stride];
     35    d1 = ip_pass0[3 * stride];
     36 
     37    a1 += b1;
     38    d1 = d1 - c1;
     39    e1 = (a1 - d1) >> 1;
     40    b1 = e1 - b1;
     41    c1 = e1 - c1;
     42    a1 -= c1;
     43    d1 += b1;
     44    op[0] = (tran_low_t)a1;
     45    op[1] = (tran_low_t)c1;
     46    op[2] = (tran_low_t)d1;
     47    op[3] = (tran_low_t)b1;
     48 
     49    ip_pass0++;
     50    op += 4;
     51  }
     52  ip = output;
     53  op = output;
     54 
     55  for (i = 0; i < 4; i++) {
     56    a1 = ip[4 * 0];
     57    b1 = ip[4 * 1];
     58    c1 = ip[4 * 2];
     59    d1 = ip[4 * 3];
     60 
     61    a1 += b1;
     62    d1 -= c1;
     63    e1 = (a1 - d1) >> 1;
     64    b1 = e1 - b1;
     65    c1 = e1 - c1;
     66    a1 -= c1;
     67    d1 += b1;
     68    op[4 * 0] = (tran_low_t)(a1 * UNIT_QUANT_FACTOR);
     69    op[4 * 1] = (tran_low_t)(c1 * UNIT_QUANT_FACTOR);
     70    op[4 * 2] = (tran_low_t)(d1 * UNIT_QUANT_FACTOR);
     71    op[4 * 3] = (tran_low_t)(b1 * UNIT_QUANT_FACTOR);
     72 
     73    ip++;
     74    op++;
     75  }
     76 }
     77 
     78 static void highbd_fwd_txfm_4x4(const int16_t *src_diff, tran_low_t *coeff,
     79                                int diff_stride, TxfmParam *txfm_param) {
     80  int32_t *dst_coeff = (int32_t *)coeff;
     81  const TX_TYPE tx_type = txfm_param->tx_type;
     82  const int bd = txfm_param->bd;
     83  if (txfm_param->lossless) {
     84    assert(tx_type == DCT_DCT);
     85    av1_fwht4x4(src_diff, coeff, diff_stride);
     86    return;
     87  }
     88  av1_fwd_txfm2d_4x4(src_diff, dst_coeff, diff_stride, tx_type, bd);
     89 }
     90 
     91 static void highbd_fwd_txfm_4x8(const int16_t *src_diff, tran_low_t *coeff,
     92                                int diff_stride, TxfmParam *txfm_param) {
     93  int32_t *dst_coeff = (int32_t *)coeff;
     94  av1_fwd_txfm2d_4x8(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
     95                     txfm_param->bd);
     96 }
     97 
     98 static void highbd_fwd_txfm_8x4(const int16_t *src_diff, tran_low_t *coeff,
     99                                int diff_stride, TxfmParam *txfm_param) {
    100  int32_t *dst_coeff = (int32_t *)coeff;
    101  av1_fwd_txfm2d_8x4(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    102                     txfm_param->bd);
    103 }
    104 
    105 static void highbd_fwd_txfm_8x16(const int16_t *src_diff, tran_low_t *coeff,
    106                                 int diff_stride, TxfmParam *txfm_param) {
    107  int32_t *dst_coeff = (int32_t *)coeff;
    108  const TX_TYPE tx_type = txfm_param->tx_type;
    109  const int bd = txfm_param->bd;
    110  av1_fwd_txfm2d_8x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
    111 }
    112 
    113 static void highbd_fwd_txfm_16x8(const int16_t *src_diff, tran_low_t *coeff,
    114                                 int diff_stride, TxfmParam *txfm_param) {
    115  int32_t *dst_coeff = (int32_t *)coeff;
    116  const TX_TYPE tx_type = txfm_param->tx_type;
    117  const int bd = txfm_param->bd;
    118  av1_fwd_txfm2d_16x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
    119 }
    120 
    121 static void highbd_fwd_txfm_16x32(const int16_t *src_diff, tran_low_t *coeff,
    122                                  int diff_stride, TxfmParam *txfm_param) {
    123  int32_t *dst_coeff = (int32_t *)coeff;
    124  av1_fwd_txfm2d_16x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    125                       txfm_param->bd);
    126 }
    127 
    128 static void highbd_fwd_txfm_32x16(const int16_t *src_diff, tran_low_t *coeff,
    129                                  int diff_stride, TxfmParam *txfm_param) {
    130  int32_t *dst_coeff = (int32_t *)coeff;
    131  av1_fwd_txfm2d_32x16(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    132                       txfm_param->bd);
    133 }
    134 
    135 #if !CONFIG_REALTIME_ONLY
    136 static void highbd_fwd_txfm_16x4(const int16_t *src_diff, tran_low_t *coeff,
    137                                 int diff_stride, TxfmParam *txfm_param) {
    138  int32_t *dst_coeff = (int32_t *)coeff;
    139  av1_fwd_txfm2d_16x4(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    140                      txfm_param->bd);
    141 }
    142 
    143 static void highbd_fwd_txfm_4x16(const int16_t *src_diff, tran_low_t *coeff,
    144                                 int diff_stride, TxfmParam *txfm_param) {
    145  int32_t *dst_coeff = (int32_t *)coeff;
    146  av1_fwd_txfm2d_4x16(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    147                      txfm_param->bd);
    148 }
    149 
    150 static void highbd_fwd_txfm_32x8(const int16_t *src_diff, tran_low_t *coeff,
    151                                 int diff_stride, TxfmParam *txfm_param) {
    152  int32_t *dst_coeff = (int32_t *)coeff;
    153  av1_fwd_txfm2d_32x8(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    154                      txfm_param->bd);
    155 }
    156 
    157 static void highbd_fwd_txfm_8x32(const int16_t *src_diff, tran_low_t *coeff,
    158                                 int diff_stride, TxfmParam *txfm_param) {
    159  int32_t *dst_coeff = (int32_t *)coeff;
    160  av1_fwd_txfm2d_8x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    161                      txfm_param->bd);
    162 }
    163 #endif
    164 
    165 static void highbd_fwd_txfm_8x8(const int16_t *src_diff, tran_low_t *coeff,
    166                                int diff_stride, TxfmParam *txfm_param) {
    167  int32_t *dst_coeff = (int32_t *)coeff;
    168  const TX_TYPE tx_type = txfm_param->tx_type;
    169  const int bd = txfm_param->bd;
    170  av1_fwd_txfm2d_8x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
    171 }
    172 
    173 static void highbd_fwd_txfm_16x16(const int16_t *src_diff, tran_low_t *coeff,
    174                                  int diff_stride, TxfmParam *txfm_param) {
    175  int32_t *dst_coeff = (int32_t *)coeff;
    176  const TX_TYPE tx_type = txfm_param->tx_type;
    177  const int bd = txfm_param->bd;
    178  av1_fwd_txfm2d_16x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
    179 }
    180 
    181 static void highbd_fwd_txfm_32x32(const int16_t *src_diff, tran_low_t *coeff,
    182                                  int diff_stride, TxfmParam *txfm_param) {
    183  int32_t *dst_coeff = (int32_t *)coeff;
    184  const TX_TYPE tx_type = txfm_param->tx_type;
    185  const int bd = txfm_param->bd;
    186  av1_fwd_txfm2d_32x32(src_diff, dst_coeff, diff_stride, tx_type, bd);
    187 }
    188 
    189 static void highbd_fwd_txfm_32x64(const int16_t *src_diff, tran_low_t *coeff,
    190                                  int diff_stride, TxfmParam *txfm_param) {
    191  assert(txfm_param->tx_type == DCT_DCT);
    192  int32_t *dst_coeff = (int32_t *)coeff;
    193  const int bd = txfm_param->bd;
    194  av1_fwd_txfm2d_32x64(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    195                       bd);
    196 }
    197 
    198 static void highbd_fwd_txfm_64x32(const int16_t *src_diff, tran_low_t *coeff,
    199                                  int diff_stride, TxfmParam *txfm_param) {
    200  assert(txfm_param->tx_type == DCT_DCT);
    201  int32_t *dst_coeff = (int32_t *)coeff;
    202  const int bd = txfm_param->bd;
    203  av1_fwd_txfm2d_64x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    204                       bd);
    205 }
    206 
    207 #if !CONFIG_REALTIME_ONLY
    208 static void highbd_fwd_txfm_16x64(const int16_t *src_diff, tran_low_t *coeff,
    209                                  int diff_stride, TxfmParam *txfm_param) {
    210  assert(txfm_param->tx_type == DCT_DCT);
    211  int32_t *dst_coeff = (int32_t *)coeff;
    212  const int bd = txfm_param->bd;
    213  av1_fwd_txfm2d_16x64(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
    214 }
    215 
    216 static void highbd_fwd_txfm_64x16(const int16_t *src_diff, tran_low_t *coeff,
    217                                  int diff_stride, TxfmParam *txfm_param) {
    218  assert(txfm_param->tx_type == DCT_DCT);
    219  int32_t *dst_coeff = (int32_t *)coeff;
    220  const int bd = txfm_param->bd;
    221  av1_fwd_txfm2d_64x16(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
    222 }
    223 #endif
    224 
    225 static void highbd_fwd_txfm_64x64(const int16_t *src_diff, tran_low_t *coeff,
    226                                  int diff_stride, TxfmParam *txfm_param) {
    227  assert(txfm_param->tx_type == DCT_DCT);
    228  int32_t *dst_coeff = (int32_t *)coeff;
    229  const int bd = txfm_param->bd;
    230  av1_fwd_txfm2d_64x64(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
    231 }
    232 
    233 void av1_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff, int diff_stride,
    234                  TxfmParam *txfm_param) {
    235  if (txfm_param->bd == 8)
    236    av1_lowbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
    237  else
    238    av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
    239 }
    240 
    241 void av1_lowbd_fwd_txfm_c(const int16_t *src_diff, tran_low_t *coeff,
    242                          int diff_stride, TxfmParam *txfm_param) {
    243  av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
    244 }
    245 
    246 void av1_highbd_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff,
    247                         int diff_stride, TxfmParam *txfm_param) {
    248  assert(av1_ext_tx_used[txfm_param->tx_set_type][txfm_param->tx_type]);
    249  const TX_SIZE tx_size = txfm_param->tx_size;
    250  switch (tx_size) {
    251    case TX_64X64:
    252      highbd_fwd_txfm_64x64(src_diff, coeff, diff_stride, txfm_param);
    253      break;
    254    case TX_32X64:
    255      highbd_fwd_txfm_32x64(src_diff, coeff, diff_stride, txfm_param);
    256      break;
    257    case TX_64X32:
    258      highbd_fwd_txfm_64x32(src_diff, coeff, diff_stride, txfm_param);
    259      break;
    260 
    261    case TX_32X32:
    262      highbd_fwd_txfm_32x32(src_diff, coeff, diff_stride, txfm_param);
    263      break;
    264    case TX_16X16:
    265      highbd_fwd_txfm_16x16(src_diff, coeff, diff_stride, txfm_param);
    266      break;
    267    case TX_8X8:
    268      highbd_fwd_txfm_8x8(src_diff, coeff, diff_stride, txfm_param);
    269      break;
    270    case TX_4X8:
    271      highbd_fwd_txfm_4x8(src_diff, coeff, diff_stride, txfm_param);
    272      break;
    273    case TX_8X4:
    274      highbd_fwd_txfm_8x4(src_diff, coeff, diff_stride, txfm_param);
    275      break;
    276    case TX_8X16:
    277      highbd_fwd_txfm_8x16(src_diff, coeff, diff_stride, txfm_param);
    278      break;
    279    case TX_16X8:
    280      highbd_fwd_txfm_16x8(src_diff, coeff, diff_stride, txfm_param);
    281      break;
    282    case TX_16X32:
    283      highbd_fwd_txfm_16x32(src_diff, coeff, diff_stride, txfm_param);
    284      break;
    285    case TX_32X16:
    286      highbd_fwd_txfm_32x16(src_diff, coeff, diff_stride, txfm_param);
    287      break;
    288    case TX_4X4:
    289      highbd_fwd_txfm_4x4(src_diff, coeff, diff_stride, txfm_param);
    290      break;
    291 #if !CONFIG_REALTIME_ONLY
    292    case TX_4X16:
    293      highbd_fwd_txfm_4x16(src_diff, coeff, diff_stride, txfm_param);
    294      break;
    295    case TX_16X4:
    296      highbd_fwd_txfm_16x4(src_diff, coeff, diff_stride, txfm_param);
    297      break;
    298    case TX_8X32:
    299      highbd_fwd_txfm_8x32(src_diff, coeff, diff_stride, txfm_param);
    300      break;
    301    case TX_32X8:
    302      highbd_fwd_txfm_32x8(src_diff, coeff, diff_stride, txfm_param);
    303      break;
    304    case TX_16X64:
    305      highbd_fwd_txfm_16x64(src_diff, coeff, diff_stride, txfm_param);
    306      break;
    307    case TX_64X16:
    308      highbd_fwd_txfm_64x16(src_diff, coeff, diff_stride, txfm_param);
    309      break;
    310 #endif
    311    default: assert(0); break;
    312  }
    313 }
    314 
    315 #if CONFIG_AV1_HIGHBITDEPTH
    316 static inline void highbd_wht_fwd_txfm(TX_SIZE tx_size, const int16_t *src_diff,
    317                                       ptrdiff_t src_stride,
    318                                       tran_low_t *coeff) {
    319  switch (tx_size) {
    320    // As the output transform co-efficients of 4x4 Hadamard transform can be
    321    // represented using 15 bits (for 12-bit clip) use lowbd variant of
    322    // hadamard_4x4.
    323    case TX_4X4: aom_hadamard_4x4(src_diff, src_stride, coeff); break;
    324    case TX_8X8: aom_highbd_hadamard_8x8(src_diff, src_stride, coeff); break;
    325    case TX_16X16:
    326      aom_highbd_hadamard_16x16(src_diff, src_stride, coeff);
    327      break;
    328    case TX_32X32:
    329      aom_highbd_hadamard_32x32(src_diff, src_stride, coeff);
    330      break;
    331    default: assert(0);
    332  }
    333 }
    334 #endif  // CONFIG_AV1_HIGHBITDEPTH
    335 
    336 static inline void wht_fwd_txfm(TX_SIZE tx_size, const int16_t *src_diff,
    337                                ptrdiff_t src_stride, tran_low_t *coeff) {
    338  switch (tx_size) {
    339    case TX_4X4: aom_hadamard_4x4(src_diff, src_stride, coeff); break;
    340    case TX_8X8: aom_hadamard_8x8(src_diff, src_stride, coeff); break;
    341    case TX_16X16: aom_hadamard_16x16(src_diff, src_stride, coeff); break;
    342    case TX_32X32: aom_hadamard_32x32(src_diff, src_stride, coeff); break;
    343    default: assert(0);
    344  }
    345 }
    346 
    347 void av1_quick_txfm(int use_hadamard, TX_SIZE tx_size, BitDepthInfo bd_info,
    348                    const int16_t *src_diff, int src_stride,
    349                    tran_low_t *coeff) {
    350  if (use_hadamard) {
    351 #if CONFIG_AV1_HIGHBITDEPTH
    352    if (bd_info.use_highbitdepth_buf) {
    353      highbd_wht_fwd_txfm(tx_size, src_diff, src_stride, coeff);
    354    } else {
    355      wht_fwd_txfm(tx_size, src_diff, src_stride, coeff);
    356    }
    357 #else
    358    wht_fwd_txfm(tx_size, src_diff, src_stride, coeff);
    359 #endif  // CONFIG_AV1_HIGHBITDEPTH
    360  } else {
    361    TxfmParam txfm_param;
    362    txfm_param.tx_type = DCT_DCT;
    363    txfm_param.tx_size = tx_size;
    364    txfm_param.lossless = 0;
    365    txfm_param.bd = bd_info.bit_depth;
    366    txfm_param.is_hbd = bd_info.use_highbitdepth_buf;
    367    txfm_param.tx_set_type = EXT_TX_SET_ALL16;
    368    av1_fwd_txfm(src_diff, coeff, src_stride, &txfm_param);
    369  }
    370 }