aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil/tx.h
blob: cd772ad903198373fc8d5c25e3b426ebc4f6e9d5 (plain) (blame)
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
62
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef AVUTIL_TX_H
#define AVUTIL_TX_H

#include <stdint.h>
#include <stddef.h>

typedef struct AVTXContext AVTXContext;

typedef struct AVComplexFloat {
    float re, im;
} AVComplexFloat;

typedef struct AVComplexDouble {
    double re, im;
} AVComplexDouble;

typedef struct AVComplexInt32 {
    int32_t re, im;
} AVComplexInt32;

enum AVTXType {
    /**
     * Standard complex to complex FFT with sample data type of AVComplexFloat,
     * AVComplexDouble or AVComplexInt32, for each respective variant.
     *
     * Output is not 1/len normalized. Scaling currently unsupported.
     * The stride parameter must be set to the size of a single sample in bytes.
     */
    AV_TX_FLOAT_FFT  = 0,
    AV_TX_DOUBLE_FFT = 2,
    AV_TX_INT32_FFT  = 4,

    /**
     * Standard MDCT with a sample data type of float, double or int32_t,
     * respecively. For the float and int32 variants, the scale type is
     * 'float', while for the double variant, it's 'double'.
     * If scale is NULL, 1.0 will be used as a default.
     *
     * Length is the frame size, not the window size (which is 2x frame).
     * For forward transforms, the stride specifies the spacing between each
     * sample in the output array in bytes. The input must be a flat array.
     *
     * For inverse transforms, the stride specifies the spacing between each
     * sample in the input array in bytes. The output must be a flat array.
     *
     * NOTE: the inverse transform is half-length, meaning the output will not
     * contain redundant data. This is what most codecs work with. To do a full
     * inverse transform, set the AV_TX_FULL_IMDCT flag on init.
     */
    AV_TX_FLOAT_MDCT  = 1,
    AV_TX_DOUBLE_MDCT = 3,
    AV_TX_INT32_MDCT  = 5,

    /**
     * Real to complex and complex to real DFTs.
     * For the float and int32 variants, the scale type is 'float', while for
     * the double variant, it's a 'double'. If scale is NULL, 1.0 will be used
     * as a default.
     *
     * The stride parameter must be set to the size of a single sample in bytes.
     *
     * The forward transform performs a real-to-complex DFT of N samples to
     * N/2+1 complex values.
     *
     * The inverse transform performs a complex-to-real DFT of N/2+1 complex
     * values to N real samples. The output is not normalized, but can be
     * made so by setting the scale value to 1.0/len.
     * NOTE: the inverse transform always overwrites the input.
     */
    AV_TX_FLOAT_RDFT  = 6,
    AV_TX_DOUBLE_RDFT = 7,
    AV_TX_INT32_RDFT  = 8,

    /* Not part of the API, do not use */
    AV_TX_NB,
};

/**
 * Function pointer to a function to perform the transform.
 *
 * @note Using a different context than the one allocated during av_tx_init()
 * is not allowed.
 *
 * @param s the transform context
 * @param out the output array
 * @param in the input array
 * @param stride the input or output stride in bytes
 *
 * The out and in arrays must be aligned to the maximum required by the CPU
 * architecture unless the AV_TX_UNALIGNED flag was set in av_tx_init().
 * The stride must follow the constraints the transform type has specified.
 */
typedef void (*av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride);

/**
 * Flags for av_tx_init()
 */
enum AVTXFlags {
    /**
     * Allows for in-place transformations, where input == output.
     * May be unsupported or slower for some transform types.
     */
    AV_TX_INPLACE = 1ULL << 0,

    /**
     * Relaxes alignment requirement for the in and out arrays of av_tx_fn().
     * May be slower with certain transform types.
     */
    AV_TX_UNALIGNED = 1ULL << 1,

    /**
     * Performs a full inverse MDCT rather than leaving out samples that can be
     * derived through symmetry. Requires an output array of 'len' floats,
     * rather than the usual 'len/2' floats.
     * Ignored for all transforms but inverse MDCTs.
     */
    AV_TX_FULL_IMDCT = 1ULL << 2,
};

/**
 * Initialize a transform context with the given configuration
 * (i)MDCTs with an odd length are currently not supported.
 *
 * @param ctx the context to allocate, will be NULL on error
 * @param tx pointer to the transform function pointer to set
 * @param type type the type of transform
 * @param inv whether to do an inverse or a forward transform
 * @param len the size of the transform in samples
 * @param scale pointer to the value to scale the output if supported by type
 * @param flags a bitmask of AVTXFlags or 0
 *
 * @return 0 on success, negative error code on failure
 */
int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type,
               int inv, int len, const void *scale, uint64_t flags);

/**
 * Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
 */
void av_tx_uninit(AVTXContext **ctx);

#endif /* AVUTIL_TX_H */