daala_fwd_txfm.c 3.82 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include "./av1_rtcd.h"
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
#include "av1/common/daala_tx.h"
#include "av1/encoder/daala_fwd_txfm.h"

#if CONFIG_DAALA_TX

// Complete Daala TX map, sans lossless which is special cased
typedef void (*daala_ftx)(od_coeff[], const od_coeff *, int);

static daala_ftx tx_map[TX_SIZES][TX_TYPES_1D] = {
  //  4-point transforms
  { od_bin_fdct4, od_bin_fdst4, od_bin_fdst4, od_bin_fidtx4 },

  //  8-point transforms
  { od_bin_fdct8, od_bin_fdst8, od_bin_fdst8, od_bin_fidtx8 },

  //  16-point transforms
  { od_bin_fdct16, od_bin_fdst16, od_bin_fdst16, od_bin_fidtx16 },

  //  32-point transforms
  { od_bin_fdct32, od_bin_fdst32, od_bin_fdst32, od_bin_fidtx32 },

#if CONFIG_TX64X64
  //  64-point transforms
  { od_bin_fdct64, NULL, NULL, od_bin_fidtx64 },
#endif
};

static int tx_flip(TX_TYPE_1D t) { return t == 2; }

// Daala TX toplevel entry point, same interface as av1 low-bidepth
// and high-bitdepth TX (av1_fwd_txfm and av1_highbd_fwd_txfm).  This
// same function is intended for both low and high bitdepth cases with
// a tran_low_t of 32 bits (matching od_coeff).
void daala_fwd_txfm(const int16_t *input_pixels, tran_low_t *output_coeffs,
                    int input_stride, TxfmParam *txfm_param) {
  const TX_SIZE tx_size = txfm_param->tx_size;
  const TX_TYPE tx_type = txfm_param->tx_type;
  assert(tx_size <= TX_SIZES_ALL);
  assert(tx_type <= TX_TYPES);

  if (txfm_param->lossless) {
    // Transform function special-cased for lossless
    assert(tx_type == DCT_DCT);
    assert(tx_size == TX_4X4);
    av1_fwht4x4(input_pixels, output_coeffs, input_stride);
  } else {
    // General TX case
62
    const int upshift = TX_COEFF_DEPTH - txfm_param->bd;
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
    assert(upshift >= 0);
    assert(sizeof(tran_low_t) == sizeof(od_coeff));
    assert(sizeof(tran_low_t) >= 4);

    // Hook into existing map translation infrastructure to select
    // appropriate TX functions
    const int cols = tx_size_wide[tx_size];
    const int rows = tx_size_high[tx_size];
    const TX_SIZE col_idx = txsize_vert_map[tx_size];
    const TX_SIZE row_idx = txsize_horz_map[tx_size];
    assert(col_idx <= TX_SIZES);
    assert(row_idx <= TX_SIZES);
    assert(vtx_tab[tx_type] <= (int)TX_TYPES_1D);
    assert(htx_tab[tx_type] <= (int)TX_TYPES_1D);
    daala_ftx col_tx = tx_map[col_idx][vtx_tab[tx_type]];
    daala_ftx row_tx = tx_map[row_idx][htx_tab[tx_type]];
    int col_flip = tx_flip(vtx_tab[tx_type]);
    int row_flip = tx_flip(htx_tab[tx_type]);
    od_coeff tmp[MAX_TX_SIZE];
    int r;
    int c;

    assert(col_tx);
    assert(row_tx);

    // Transform columns
    for (c = 0; c < cols; ++c) {
      // Cast and shift
      for (r = 0; r < rows; ++r)
        tmp[r] =
            ((od_coeff)(input_pixels[r * input_stride + c])) * (1 << upshift);
      if (col_flip)
        col_tx(tmp, tmp + (rows - 1), -1);
      else
        col_tx(tmp, tmp, 1);
      // No ystride in daala_tx lowlevel functions, store output vector
      // into column the long way
      for (r = 0; r < rows; ++r) output_coeffs[r * cols + c] = tmp[r];
    }

    // Transform rows
    for (r = 0; r < rows; ++r) {
      if (row_flip)
        row_tx(output_coeffs + r * cols, output_coeffs + r * cols + cols - 1,
               -1);
      else
        row_tx(output_coeffs + r * cols, output_coeffs + r * cols, 1);
    }
  }
}

#endif