Home | History | Annotate | Download | only in encoder
      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/encoder/hybrid_fwd_txfm.h"
     18 
     19 /* 4-point reversible, orthonormal Walsh-Hadamard in 3.5 adds, 0.5 shifts per
     20    pixel. */
     21 void av1_fwht4x4_c(const int16_t *input, tran_low_t *output, int stride) {
     22   int i;
     23   tran_high_t a1, b1, c1, d1, e1;
     24   const int16_t *ip_pass0 = input;
     25   const tran_low_t *ip = NULL;
     26   tran_low_t *op = output;
     27 
     28   for (i = 0; i < 4; i++) {
     29     a1 = ip_pass0[0 * stride];
     30     b1 = ip_pass0[1 * stride];
     31     c1 = ip_pass0[2 * stride];
     32     d1 = ip_pass0[3 * stride];
     33 
     34     a1 += b1;
     35     d1 = d1 - c1;
     36     e1 = (a1 - d1) >> 1;
     37     b1 = e1 - b1;
     38     c1 = e1 - c1;
     39     a1 -= c1;
     40     d1 += b1;
     41     op[0] = (tran_low_t)a1;
     42     op[4] = (tran_low_t)c1;
     43     op[8] = (tran_low_t)d1;
     44     op[12] = (tran_low_t)b1;
     45 
     46     ip_pass0++;
     47     op++;
     48   }
     49   ip = output;
     50   op = output;
     51 
     52   for (i = 0; i < 4; i++) {
     53     a1 = ip[0];
     54     b1 = ip[1];
     55     c1 = ip[2];
     56     d1 = ip[3];
     57 
     58     a1 += b1;
     59     d1 -= c1;
     60     e1 = (a1 - d1) >> 1;
     61     b1 = e1 - b1;
     62     c1 = e1 - c1;
     63     a1 -= c1;
     64     d1 += b1;
     65     op[0] = (tran_low_t)(a1 * UNIT_QUANT_FACTOR);
     66     op[1] = (tran_low_t)(c1 * UNIT_QUANT_FACTOR);
     67     op[2] = (tran_low_t)(d1 * UNIT_QUANT_FACTOR);
     68     op[3] = (tran_low_t)(b1 * UNIT_QUANT_FACTOR);
     69 
     70     ip += 4;
     71     op += 4;
     72   }
     73 }
     74 
     75 void av1_highbd_fwht4x4_c(const int16_t *input, tran_low_t *output,
     76                           int stride) {
     77   av1_fwht4x4_c(input, output, stride);
     78 }
     79 
     80 static void highbd_fwd_txfm_4x4(const int16_t *src_diff, tran_low_t *coeff,
     81                                 int diff_stride, TxfmParam *txfm_param) {
     82   int32_t *dst_coeff = (int32_t *)coeff;
     83   const TX_TYPE tx_type = txfm_param->tx_type;
     84   const int bd = txfm_param->bd;
     85   if (txfm_param->lossless) {
     86     assert(tx_type == DCT_DCT);
     87     av1_highbd_fwht4x4(src_diff, coeff, diff_stride);
     88     return;
     89   }
     90   av1_fwd_txfm2d_4x4(src_diff, dst_coeff, diff_stride, tx_type, bd);
     91 }
     92 
     93 static void highbd_fwd_txfm_4x8(const int16_t *src_diff, tran_low_t *coeff,
     94                                 int diff_stride, TxfmParam *txfm_param) {
     95   int32_t *dst_coeff = (int32_t *)coeff;
     96   av1_fwd_txfm2d_4x8(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
     97                      txfm_param->bd);
     98 }
     99 
    100 static void highbd_fwd_txfm_8x4(const int16_t *src_diff, tran_low_t *coeff,
    101                                 int diff_stride, TxfmParam *txfm_param) {
    102   int32_t *dst_coeff = (int32_t *)coeff;
    103   av1_fwd_txfm2d_8x4(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    104                      txfm_param->bd);
    105 }
    106 
    107 static void highbd_fwd_txfm_8x16(const int16_t *src_diff, tran_low_t *coeff,
    108                                  int diff_stride, TxfmParam *txfm_param) {
    109   int32_t *dst_coeff = (int32_t *)coeff;
    110   const TX_TYPE tx_type = txfm_param->tx_type;
    111   const int bd = txfm_param->bd;
    112   av1_fwd_txfm2d_8x16(src_diff, dst_coeff, diff_stride, tx_type, bd);
    113 }
    114 
    115 static void highbd_fwd_txfm_16x8(const int16_t *src_diff, tran_low_t *coeff,
    116                                  int diff_stride, TxfmParam *txfm_param) {
    117   int32_t *dst_coeff = (int32_t *)coeff;
    118   const TX_TYPE tx_type = txfm_param->tx_type;
    119   const int bd = txfm_param->bd;
    120   av1_fwd_txfm2d_16x8(src_diff, dst_coeff, diff_stride, tx_type, bd);
    121 }
    122 
    123 static void highbd_fwd_txfm_16x32(const int16_t *src_diff, tran_low_t *coeff,
    124                                   int diff_stride, TxfmParam *txfm_param) {
    125   int32_t *dst_coeff = (int32_t *)coeff;
    126   av1_fwd_txfm2d_16x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    127                        txfm_param->bd);
    128 }
    129 
    130 static void highbd_fwd_txfm_32x16(const int16_t *src_diff, tran_low_t *coeff,
    131                                   int diff_stride, TxfmParam *txfm_param) {
    132   int32_t *dst_coeff = (int32_t *)coeff;
    133   av1_fwd_txfm2d_32x16(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    134                        txfm_param->bd);
    135 }
    136 
    137 static void highbd_fwd_txfm_16x4(const int16_t *src_diff, tran_low_t *coeff,
    138                                  int diff_stride, TxfmParam *txfm_param) {
    139   int32_t *dst_coeff = (int32_t *)coeff;
    140   av1_fwd_txfm2d_16x4(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    141                       txfm_param->bd);
    142 }
    143 
    144 static void highbd_fwd_txfm_4x16(const int16_t *src_diff, tran_low_t *coeff,
    145                                  int diff_stride, TxfmParam *txfm_param) {
    146   int32_t *dst_coeff = (int32_t *)coeff;
    147   av1_fwd_txfm2d_4x16(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    148                       txfm_param->bd);
    149 }
    150 
    151 static void highbd_fwd_txfm_32x8(const int16_t *src_diff, tran_low_t *coeff,
    152                                  int diff_stride, TxfmParam *txfm_param) {
    153   int32_t *dst_coeff = (int32_t *)coeff;
    154   av1_fwd_txfm2d_32x8(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    155                       txfm_param->bd);
    156 }
    157 
    158 static void highbd_fwd_txfm_8x32(const int16_t *src_diff, tran_low_t *coeff,
    159                                  int diff_stride, TxfmParam *txfm_param) {
    160   int32_t *dst_coeff = (int32_t *)coeff;
    161   av1_fwd_txfm2d_8x32(src_diff, dst_coeff, diff_stride, txfm_param->tx_type,
    162                       txfm_param->bd);
    163 }
    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 static void highbd_fwd_txfm_16x64(const int16_t *src_diff, tran_low_t *coeff,
    208                                   int diff_stride, TxfmParam *txfm_param) {
    209   assert(txfm_param->tx_type == DCT_DCT);
    210   int32_t *dst_coeff = (int32_t *)coeff;
    211   const int bd = txfm_param->bd;
    212   av1_fwd_txfm2d_16x64(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
    213 }
    214 
    215 static void highbd_fwd_txfm_64x16(const int16_t *src_diff, tran_low_t *coeff,
    216                                   int diff_stride, TxfmParam *txfm_param) {
    217   assert(txfm_param->tx_type == DCT_DCT);
    218   int32_t *dst_coeff = (int32_t *)coeff;
    219   const int bd = txfm_param->bd;
    220   av1_fwd_txfm2d_64x16(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
    221 }
    222 
    223 static void highbd_fwd_txfm_64x64(const int16_t *src_diff, tran_low_t *coeff,
    224                                   int diff_stride, TxfmParam *txfm_param) {
    225   assert(txfm_param->tx_type == DCT_DCT);
    226   int32_t *dst_coeff = (int32_t *)coeff;
    227   const int bd = txfm_param->bd;
    228   av1_fwd_txfm2d_64x64(src_diff, dst_coeff, diff_stride, DCT_DCT, bd);
    229 }
    230 
    231 void av1_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff, int diff_stride,
    232                   TxfmParam *txfm_param) {
    233   if (txfm_param->bd == 8)
    234     av1_lowbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
    235   else
    236     av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
    237 }
    238 
    239 void av1_lowbd_fwd_txfm_c(const int16_t *src_diff, tran_low_t *coeff,
    240                           int diff_stride, TxfmParam *txfm_param) {
    241   av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, txfm_param);
    242 }
    243 
    244 void av1_highbd_fwd_txfm(const int16_t *src_diff, tran_low_t *coeff,
    245                          int diff_stride, TxfmParam *txfm_param) {
    246   assert(av1_ext_tx_used[txfm_param->tx_set_type][txfm_param->tx_type]);
    247   const TX_SIZE tx_size = txfm_param->tx_size;
    248   switch (tx_size) {
    249     case TX_64X64:
    250       highbd_fwd_txfm_64x64(src_diff, coeff, diff_stride, txfm_param);
    251       break;
    252     case TX_32X64:
    253       highbd_fwd_txfm_32x64(src_diff, coeff, diff_stride, txfm_param);
    254       break;
    255     case TX_64X32:
    256       highbd_fwd_txfm_64x32(src_diff, coeff, diff_stride, txfm_param);
    257       break;
    258     case TX_16X64:
    259       highbd_fwd_txfm_16x64(src_diff, coeff, diff_stride, txfm_param);
    260       break;
    261     case TX_64X16:
    262       highbd_fwd_txfm_64x16(src_diff, coeff, diff_stride, txfm_param);
    263       break;
    264     case TX_32X32:
    265       highbd_fwd_txfm_32x32(src_diff, coeff, diff_stride, txfm_param);
    266       break;
    267     case TX_16X16:
    268       highbd_fwd_txfm_16x16(src_diff, coeff, diff_stride, txfm_param);
    269       break;
    270     case TX_8X8:
    271       highbd_fwd_txfm_8x8(src_diff, coeff, diff_stride, txfm_param);
    272       break;
    273     case TX_4X8:
    274       highbd_fwd_txfm_4x8(src_diff, coeff, diff_stride, txfm_param);
    275       break;
    276     case TX_8X4:
    277       highbd_fwd_txfm_8x4(src_diff, coeff, diff_stride, txfm_param);
    278       break;
    279     case TX_8X16:
    280       highbd_fwd_txfm_8x16(src_diff, coeff, diff_stride, txfm_param);
    281       break;
    282     case TX_16X8:
    283       highbd_fwd_txfm_16x8(src_diff, coeff, diff_stride, txfm_param);
    284       break;
    285     case TX_16X32:
    286       highbd_fwd_txfm_16x32(src_diff, coeff, diff_stride, txfm_param);
    287       break;
    288     case TX_32X16:
    289       highbd_fwd_txfm_32x16(src_diff, coeff, diff_stride, txfm_param);
    290       break;
    291     case TX_4X4:
    292       highbd_fwd_txfm_4x4(src_diff, coeff, diff_stride, txfm_param);
    293       break;
    294     case TX_4X16:
    295       highbd_fwd_txfm_4x16(src_diff, coeff, diff_stride, txfm_param);
    296       break;
    297     case TX_16X4:
    298       highbd_fwd_txfm_16x4(src_diff, coeff, diff_stride, txfm_param);
    299       break;
    300     case TX_8X32:
    301       highbd_fwd_txfm_8x32(src_diff, coeff, diff_stride, txfm_param);
    302       break;
    303     case TX_32X8:
    304       highbd_fwd_txfm_32x8(src_diff, coeff, diff_stride, txfm_param);
    305       break;
    306     default: assert(0); break;
    307   }
    308 }
    309