FFmpeg
avfft.c
Go to the documentation of this file.
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 {
31 
34 
35  ptrdiff_t stride;
36  int len;
37  int inv;
38 
39  float *tmp;
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,
55  if (ret < 0) {
56  av_free(s);
57  return NULL;
58  }
59 
60  return (FFTContext *)s;
61 }
62 
64 {
65  /* Empty */
66 }
67 
69 {
70  AVTXWrapper *w = (AVTXWrapper *)s;
71  w->fn(w->ctx, z, (void *)z, sizeof(AVComplexFloat));
72 }
73 
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 
112 {
113  AVTXWrapper *w = (AVTXWrapper *)s;
114  w->fn2(w->ctx2, output, (void *)input, sizeof(float));
115 }
116 
118 {
119  AVTXWrapper *w = (AVTXWrapper *)s;
120  w->fn(w->ctx, output, (void *)input, sizeof(float));
121 }
122 
124 {
125  AVTXWrapper *w = (AVTXWrapper *)s;
126  w->fn(w->ctx, output, (void *)input, sizeof(float));
127 }
128 
130 {
131  if (s) {
132  AVTXWrapper *w = (AVTXWrapper *)s;
133  av_tx_uninit(&w->ctx);
134  av_free(w);
135  }
136 }
137 
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 
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 
178 {
179  if (s) {
180  AVTXWrapper *w = (AVTXWrapper *)s;
181  av_tx_uninit(&w->ctx);
182  av_free(w);
183  }
184 }
185 
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[] = {
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 
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 
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 }
AVTXWrapper::len
int len
Definition: avfft.c:36
DCT_I
@ DCT_I
Definition: avfft.h:121
AVTXWrapper::inv
int inv
Definition: avfft.c:37
av_dct_calc
void av_dct_calc(DCTContext *s, FFTSample *data)
Definition: avfft.c:229
inverse
inverse
Definition: af_crystalizer.c:121
av_fft_calc
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:68
AVTXContext
Definition: tx_priv.h:235
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
DFT_C2R
@ DFT_C2R
Definition: avfft.h:95
w
uint8_t w
Definition: llviddspenc.c:38
data
const char data[16]
Definition: mxf.c:148
AVComplexFloat
Definition: tx.h:27
AVTXWrapper::fn
av_tx_fn fn
Definition: avfft.c:30
av_imdct_half
void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: avfft.c:117
AVTXWrapper
Definition: avfft.c:28
av_tx_init
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
Definition: tx.c:901
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AVTXWrapper::ctx2
AVTXContext * ctx2
Definition: avfft.c:32
DCT_III
@ DCT_III
Definition: avfft.h:120
macros.h
IDFT_C2R
@ IDFT_C2R
Definition: avfft.h:93
scale
static av_always_inline float scale(float x, float s)
Definition: vf_v360.c:1389
AVTXWrapper::stride
ptrdiff_t stride
Definition: avfft.c:35
av_mdct_end
av_cold void av_mdct_end(FFTContext *s)
Definition: avfft.c:129
av_cold
#define av_cold
Definition: attributes.h:90
av_tx_fn
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
Definition: tx.h:151
float
float
Definition: af_crystalizer.c:121
AV_TX_FLOAT_MDCT
@ AV_TX_FLOAT_MDCT
Standard MDCT with a sample data type of float, double or int32_t, respecively.
Definition: tx.h:68
s
#define s(width, name)
Definition: cbs_vp9.c:254
av_mdct_calc
void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: avfft.c:123
AV_TX_FLOAT_FFT
@ AV_TX_FLOAT_FFT
Standard complex to complex FFT with sample data type of AVComplexFloat, AVComplexDouble or AVComplex...
Definition: tx.h:47
AV_TX_FULL_IMDCT
@ AV_TX_FULL_IMDCT
Performs a full inverse MDCT rather than leaving out samples that can be derived through symmetry.
Definition: tx.h:175
NULL
#define NULL
Definition: coverity.c:32
av_fft_init
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:45
AV_TX_INPLACE
@ AV_TX_INPLACE
Allows for in-place transformations, where input == output.
Definition: tx.h:161
DFT_R2C
@ DFT_R2C
Definition: avfft.h:92
FFTSample
float FFTSample
Definition: avfft.h:39
avfft.h
av_rdft_end
av_cold void av_rdft_end(RDFTContext *s)
Definition: avfft.c:177
AVTXWrapper::ctx
AVTXContext * ctx
Definition: avfft.c:29
av_mdct_init
FFTContext * av_mdct_init(int nbits, int inverse, double scale)
Definition: avfft.c:84
AVTXWrapper::out_of_place
int out_of_place
Definition: avfft.c:40
f
f
Definition: af_crystalizer.c:121
AV_TX_FLOAT_DCT_I
@ AV_TX_FLOAT_DCT_I
Discrete Cosine Transform I.
Definition: tx.h:116
AVTXType
AVTXType
Definition: tx.h:39
attributes.h
AVTXWrapper::fn2
av_tx_fn fn2
Definition: avfft.c:33
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
av_tx_uninit
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
Definition: tx.c:294
DST_I
@ DST_I
Definition: avfft.h:122
av_imdct_calc
void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: avfft.c:111
FFTContext
Definition: fft.h:76
RDFTContext
Definition: rdft.h:28
RDFTransformType
RDFTransformType
Definition: avfft.h:91
DCTContext
Definition: dct.h:32
av_dct_init
DCTContext * av_dct_init(int nbits, enum DCTTransformType inverse)
Set up DCT.
Definition: avfft.c:186
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AV_TX_FLOAT_RDFT
@ AV_TX_FLOAT_RDFT
Real to complex and complex to real DFTs.
Definition: tx.h:90
AV_TX_FLOAT_DST_I
@ AV_TX_FLOAT_DST_I
Discrete Sine Transform I.
Definition: tx.h:128
mem.h
av_rdft_calc
void av_rdft_calc(RDFTContext *s, FFTSample *data)
Definition: avfft.c:167
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_dct_end
av_cold void av_dct_end(DCTContext *s)
Definition: avfft.c:240
AV_TX_FLOAT_DCT
@ AV_TX_FLOAT_DCT
Real to real (DCT) transforms.
Definition: tx.h:104
DCT_II
@ DCT_II
Definition: avfft.h:119
av_fft_end
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:74
AVTXWrapper::tmp
float * tmp
Definition: avfft.c:39
DCTTransformType
DCTTransformType
Definition: avfft.h:118
av_rdft_init
RDFTContext * av_rdft_init(int nbits, enum RDFTransformType trans)
Set up a real FFT.
Definition: avfft.c:138
av_fft_permute
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
Definition: avfft.c:63
FFTComplex
Definition: avfft.h:41
tx.h