aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil/tx.h
blob: 55173810ee9b99ab133214cf3b15e38722a82a85 (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
/*
 * 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 AVComplexFloat.
     * Output is not 1/len normalized. Scaling currently unsupported.
     * The stride parameter is ignored.
     */
    AV_TX_FLOAT_FFT = 0,

    /**
     * Standard MDCT with sample data type of float and a scale type of
     * float. 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 will be a flat array.
     * Stride must be a non-zero multiple of sizeof(float).
     *
     * 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,

    /**
     * Same as AV_TX_FLOAT_FFT with a data type of AVComplexDouble.
     */
    AV_TX_DOUBLE_FFT = 2,

    /**
     * Same as AV_TX_FLOAT_MDCT with data and scale type of double.
     * Stride must be a non-zero multiple of sizeof(double).
     */
    AV_TX_DOUBLE_MDCT = 3,

    /**
     * Same as AV_TX_FLOAT_FFT with a data type of AVComplexInt32.
     */
    AV_TX_INT32_FFT = 4,

    /**
     * Same as AV_TX_FLOAT_MDCT with data type of int32_t and scale type of float.
     * Only scale values less than or equal to 1.0 are supported.
     * Stride must be a non-zero multiple of sizeof(int32_t).
     */
    AV_TX_INT32_MDCT = 5,
};

/**
 * 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 {
    /**
     * Performs an in-place transformation on the input. The output argument
     * of av_tn_fn() MUST match the input. 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 */