FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/avfft.c
Date: 2023-10-02 11:06:47
Exec Total Coverage
Lines: 0 121 0.0%
Functions: 0 15 0.0%
Branches: 0 50 0.0%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <stddef.h>
20 #include <string.h>
21
22 #include "libavutil/attributes.h"
23 #include "libavutil/macros.h"
24 #include "libavutil/mem.h"
25 #include "libavutil/tx.h"
26 #include "avfft.h"
27
28 typedef struct AVTXWrapper {
29 AVTXContext *ctx;
30 av_tx_fn fn;
31
32 AVTXContext *ctx2;
33 av_tx_fn fn2;
34
35 ptrdiff_t stride;
36 int len;
37 int inv;
38
39 float *tmp;
40 int out_of_place;
41 } AVTXWrapper;
42
43 /* FFT */
44
45 FFTContext *av_fft_init(int nbits, int inverse)
46 {
47 int ret;
48 float scale = 1.0f;
49 AVTXWrapper *s = av_malloc(sizeof(*s));
50 if (!s)
51 return NULL;
52
53 ret = av_tx_init(&s->ctx, &s->fn, AV_TX_FLOAT_FFT, inverse, 1 << nbits,
54 &scale, AV_TX_INPLACE);
55 if (ret < 0) {
56 av_free(s);
57 return NULL;
58 }
59
60 return (FFTContext *)s;
61 }
62
63 void av_fft_permute(FFTContext *s, FFTComplex *z)
64 {
65 /* Empty */
66 }
67
68 void av_fft_calc(FFTContext *s, FFTComplex *z)
69 {
70 AVTXWrapper *w = (AVTXWrapper *)s;
71 w->fn(w->ctx, z, (void *)z, sizeof(AVComplexFloat));
72 }
73
74 av_cold void av_fft_end(FFTContext *s)
75 {
76 if (s) {
77 AVTXWrapper *w = (AVTXWrapper *)s;
78 av_tx_uninit(&w->ctx);
79 av_tx_uninit(&w->ctx2);
80 av_free(w);
81 }
82 }
83
84 FFTContext *av_mdct_init(int nbits, int inverse, double scale)
85 {
86 int ret;
87 float scale_f = scale;
88 AVTXWrapper *s = av_malloc(sizeof(*s));
89 if (!s)
90 return NULL;
91
92 ret = av_tx_init(&s->ctx, &s->fn, AV_TX_FLOAT_MDCT, inverse, 1 << (nbits - 1), &scale_f, 0);
93 if (ret < 0) {
94 av_free(s);
95 return NULL;
96 }
97
98 if (inverse) {
99 ret = av_tx_init(&s->ctx2, &s->fn2, AV_TX_FLOAT_MDCT, inverse, 1 << (nbits - 1),
100 &scale_f, AV_TX_FULL_IMDCT);
101 if (ret < 0) {
102 av_tx_uninit(&s->ctx);
103 av_free(s);
104 return NULL;
105 }
106 }
107
108 return (FFTContext *)s;
109 }
110
111 void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
112 {
113 AVTXWrapper *w = (AVTXWrapper *)s;
114 w->fn2(w->ctx2, output, (void *)input, sizeof(float));
115 }
116
117 void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input)
118 {
119 AVTXWrapper *w = (AVTXWrapper *)s;
120 w->fn(w->ctx, output, (void *)input, sizeof(float));
121 }
122
123 void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
124 {
125 AVTXWrapper *w = (AVTXWrapper *)s;
126 w->fn(w->ctx, output, (void *)input, sizeof(float));
127 }
128
129 av_cold void av_mdct_end(FFTContext *s)
130 {
131 if (s) {
132 AVTXWrapper *w = (AVTXWrapper *)s;
133 av_tx_uninit(&w->ctx);
134 av_free(w);
135 }
136 }
137
138 RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans)
139 {
140 int ret;
141 float scale = trans == IDFT_C2R ? 0.5f : 1.0f;
142 AVTXWrapper *s;
143
144 /* The other 2 modes are unconventional, do not form an orthogonal
145 * transform, have never been useful, and so they're not implemented. */
146 if (trans != IDFT_C2R && trans != DFT_R2C)
147 return NULL;
148
149 s = av_malloc(sizeof(*s));
150 if (!s)
151 return NULL;
152
153 ret = av_tx_init(&s->ctx, &s->fn, AV_TX_FLOAT_RDFT, trans == IDFT_C2R,
154 1 << nbits, &scale, AV_TX_INPLACE);
155 if (ret < 0) {
156 av_free(s);
157 return NULL;
158 }
159
160 s->stride = (trans == DFT_C2R) ? sizeof(float) : sizeof(AVComplexFloat);
161 s->len = 1 << nbits;
162 s->inv = trans == IDFT_C2R;
163
164 return (RDFTContext *)s;
165 }
166
167 void av_rdft_calc(RDFTContext *s, FFTSample *data)
168 {
169 AVTXWrapper *w = (AVTXWrapper *)s;
170 if (w->inv)
171 FFSWAP(float, data[1], data[w->len]);
172 w->fn(w->ctx, data, (void *)data, w->stride);
173 if (!w->inv)
174 FFSWAP(float, data[1], data[w->len]);
175 }
176
177 av_cold void av_rdft_end(RDFTContext *s)
178 {
179 if (s) {
180 AVTXWrapper *w = (AVTXWrapper *)s;
181 av_tx_uninit(&w->ctx);
182 av_free(w);
183 }
184 }
185
186 DCTContext *av_dct_init(int nbits, enum DCTTransformType inverse)
187 {
188 int ret;
189 const float scale_map[] = {
190 [DCT_II] = 0.5f,
191 [DCT_III] = 1.0f / (1 << nbits),
192 [DCT_I] = 0.5f,
193 [DST_I] = 2.0f,
194 };
195 static const enum AVTXType type_map[] = {
196 [DCT_II] = AV_TX_FLOAT_DCT,
197 [DCT_III] = AV_TX_FLOAT_DCT,
198 [DCT_I] = AV_TX_FLOAT_DCT_I,
199 [DST_I] = AV_TX_FLOAT_DST_I,
200 };
201
202 AVTXWrapper *s = av_malloc(sizeof(*s));
203 if (!s)
204 return NULL;
205
206 s->len = (1 << nbits);
207 s->out_of_place = (inverse == DCT_I) || (inverse == DST_I);
208
209 ret = av_tx_init(&s->ctx, &s->fn, type_map[inverse],
210 (inverse == DCT_III), 1 << (nbits - (inverse == DCT_III)),
211 &scale_map[inverse], s->out_of_place ? 0 : AV_TX_INPLACE);
212 if (ret < 0) {
213 av_free(s);
214 return NULL;
215 }
216
217 if (s->out_of_place) {
218 s->tmp = av_malloc((1 << (nbits + 1))*sizeof(float));
219 if (!s->tmp) {
220 av_tx_uninit(&s->ctx);
221 av_free(s);
222 return NULL;
223 }
224 }
225
226 return (DCTContext *)s;
227 }
228
229 void av_dct_calc(DCTContext *s, FFTSample *data)
230 {
231 AVTXWrapper *w = (AVTXWrapper *)s;
232 if (w->out_of_place) {
233 memcpy(w->tmp, data, w->len*sizeof(float));
234 w->fn(w->ctx, (void *)data, w->tmp, sizeof(float));
235 } else {
236 w->fn(w->ctx, data, (void *)data, sizeof(float));
237 }
238 }
239
240 av_cold void av_dct_end(DCTContext *s)
241 {
242 if (s) {
243 AVTXWrapper *w = (AVTXWrapper *)s;
244 av_tx_uninit(&w->ctx);
245 av_free(w->tmp);
246 av_free(w);
247 }
248 }
249