Go to the documentation of this file.
66 double freq = 2*
M_PI/m;
68 for(
int i = 0;
i <= m/4;
i++)
69 tab[
i] = RESCALE(cos(
i*freq));
70 for(
int i = 1;
i < m/4;
i++)
74 #define INIT_FF_COS_TABS_FUNC(index, size) \
75 static av_cold void init_cos_tabs_ ## size (void) \
77 init_cos_tabs_idx(index); \
145 mtmp[0] = (int64_t)
TX_NAME(ff_cos_53)[0].
re *
tmp[0].re;
146 mtmp[1] = (int64_t)
TX_NAME(ff_cos_53)[0].
im *
tmp[0].im;
147 mtmp[2] = (int64_t)
TX_NAME(ff_cos_53)[1].
re *
tmp[1].re;
148 mtmp[3] = (int64_t)
TX_NAME(ff_cos_53)[1].
re *
tmp[1].im;
149 out[1*
stride].re =
in[0].re - (mtmp[2] + mtmp[0] + 0x40000000 >> 31);
150 out[1*
stride].im =
in[0].im - (mtmp[3] - mtmp[1] + 0x40000000 >> 31);
151 out[2*
stride].re =
in[0].re - (mtmp[2] - mtmp[0] + 0x40000000 >> 31);
152 out[2*
stride].im =
in[0].im - (mtmp[3] + mtmp[1] + 0x40000000 >> 31);
165 #define DECL_FFT5(NAME, D0, D1, D2, D3, D4) \
166 static av_always_inline void NAME(FFTComplex *out, FFTComplex *in, \
169 FFTComplex z0[4], t[6]; \
171 BF(t[1].im, t[0].re, in[1].re, in[4].re); \
172 BF(t[1].re, t[0].im, in[1].im, in[4].im); \
173 BF(t[3].im, t[2].re, in[2].re, in[3].re); \
174 BF(t[3].re, t[2].im, in[2].im, in[3].im); \
176 out[D0*stride].re = in[0].re + t[0].re + t[2].re; \
177 out[D0*stride].im = in[0].im + t[0].im + t[2].im; \
179 SMUL(t[4].re, t[0].re, TX_NAME(ff_cos_53)[2].re, TX_NAME(ff_cos_53)[3].re, t[2].re, t[0].re); \
180 SMUL(t[4].im, t[0].im, TX_NAME(ff_cos_53)[2].re, TX_NAME(ff_cos_53)[3].re, t[2].im, t[0].im); \
181 CMUL(t[5].re, t[1].re, TX_NAME(ff_cos_53)[2].im, TX_NAME(ff_cos_53)[3].im, t[3].re, t[1].re); \
182 CMUL(t[5].im, t[1].im, TX_NAME(ff_cos_53)[2].im, TX_NAME(ff_cos_53)[3].im, t[3].im, t[1].im); \
184 BF(z0[0].re, z0[3].re, t[0].re, t[1].re); \
185 BF(z0[0].im, z0[3].im, t[0].im, t[1].im); \
186 BF(z0[2].re, z0[1].re, t[4].re, t[5].re); \
187 BF(z0[2].im, z0[1].im, t[4].im, t[5].im); \
189 out[D1*stride].re = in[0].re + z0[3].re; \
190 out[D1*stride].im = in[0].im + z0[0].im; \
191 out[D2*stride].re = in[0].re + z0[2].re; \
192 out[D2*stride].im = in[0].im + z0[1].im; \
193 out[D3*stride].re = in[0].re + z0[1].re; \
194 out[D3*stride].im = in[0].im + z0[2].im; \
195 out[D4*stride].re = in[0].re + z0[0].re; \
196 out[D4*stride].im = in[0].im + z0[3].im; \
209 for (
int i = 0;
i < 5;
i++)
217 #define BUTTERFLIES(a0,a1,a2,a3) {\
219 BF(a2.re, a0.re, a0.re, t5);\
220 BF(a3.im, a1.im, a1.im, t3);\
222 BF(a3.re, a1.re, a1.re, t4);\
223 BF(a2.im, a0.im, a0.im, t6);\
229 #define BUTTERFLIES_BIG(a0,a1,a2,a3) {\
230 FFTSample r0=a0.re, i0=a0.im, r1=a1.re, i1=a1.im;\
232 BF(a2.re, a0.re, r0, t5);\
233 BF(a3.im, a1.im, i1, t3);\
235 BF(a3.re, a1.re, r1, t4);\
236 BF(a2.im, a0.im, i0, t6);\
239 #define TRANSFORM(a0,a1,a2,a3,wre,wim) {\
240 CMUL(t1, t2, a2.re, a2.im, wre, -wim);\
241 CMUL(t5, t6, a3.re, a3.im, wre, wim);\
242 BUTTERFLIES(a0,a1,a2,a3)\
245 #define TRANSFORM_ZERO(a0,a1,a2,a3) {\
250 BUTTERFLIES(a0,a1,a2,a3)\
255 static void name(FFTComplex *z, const FFTSample *wre, unsigned int n)\
257 FFTSample t1, t2, t3, t4, t5, t6;\
261 const FFTSample *wim = wre+o1;\
264 TRANSFORM_ZERO(z[0],z[o1],z[o2],z[o3]);\
265 TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
270 TRANSFORM(z[0],z[o1],z[o2],z[o3],wre[0],wim[0]);\
271 TRANSFORM(z[1],z[o1+1],z[o2+1],z[o3+1],wre[1],wim[-1]);\
277 #define BUTTERFLIES BUTTERFLIES_BIG
280 #define DECL_FFT(n,n2,n4)\
281 static void fft##n(FFTComplex *z)\
286 pass(z,TX_NAME(ff_cos_##n),n4/2);\
338 TRANSFORM(z[1],z[5],z[9],z[13],cos_16_1,cos_16_3);
339 TRANSFORM(z[3],z[7],z[11],z[15],cos_16_3,cos_16_1);
347 #define pass pass_big
358 NULL,
fft2,
fft4,
fft8,
fft16, fft32, fft64, fft128, fft256, fft512,
359 fft1024, fft2048, fft4096, fft8192, fft16384, fft32768, fft65536, fft131072
362 #define DECL_COMP_FFT(N) \
363 static void compound_fft_##N##xM(AVTXContext *s, void *_out, \
364 void *_in, ptrdiff_t stride) \
366 const int m = s->m, *in_map = s->pfatab, *out_map = in_map + N*m; \
367 FFTComplex *in = _in; \
368 FFTComplex *out = _out; \
369 FFTComplex fft##N##in[N]; \
370 void (*fftp)(FFTComplex *z) = fft_dispatch[av_log2(m)]; \
372 for (int i = 0; i < m; i++) { \
373 for (int j = 0; j < N; j++) \
374 fft##N##in[j] = in[in_map[i*N + j]]; \
375 fft##N(s->tmp + s->revtab[i], fft##N##in, m); \
378 for (int i = 0; i < N; i++) \
379 fftp(s->tmp + m*i); \
381 for (int i = 0; i < N*m; i++) \
382 out[i] = s->tmp[out_map[i]]; \
395 for (
int i = 0;
i < m;
i++)
400 #define DECL_COMP_IMDCT(N) \
401 static void compound_imdct_##N##xM(AVTXContext *s, void *_dst, void *_src, \
404 FFTComplex fft##N##in[N]; \
405 FFTComplex *z = _dst, *exp = s->exptab; \
406 const int m = s->m, len8 = N*m >> 1; \
407 const int *in_map = s->pfatab, *out_map = in_map + N*m; \
408 const FFTSample *src = _src, *in1, *in2; \
409 void (*fftp)(FFTComplex *) = fft_dispatch[av_log2(m)]; \
411 stride /= sizeof(*src); \
413 in2 = src + ((N*m*2) - 1) * stride; \
415 for (int i = 0; i < m; i++) { \
416 for (int j = 0; j < N; j++) { \
417 const int k = in_map[i*N + j]; \
418 FFTComplex tmp = { in2[-k*stride], in1[k*stride] }; \
419 CMUL3(fft##N##in[j], tmp, exp[k >> 1]); \
421 fft##N(s->tmp + s->revtab[i], fft##N##in, m); \
424 for (int i = 0; i < N; i++) \
425 fftp(s->tmp + m*i); \
427 for (int i = 0; i < len8; i++) { \
428 const int i0 = len8 + i, i1 = len8 - i - 1; \
429 const int s0 = out_map[i0], s1 = out_map[i1]; \
430 FFTComplex src1 = { s->tmp[s1].im, s->tmp[s1].re }; \
431 FFTComplex src0 = { s->tmp[s0].im, s->tmp[s0].re }; \
433 CMUL(z[i1].re, z[i0].im, src1.re, src1.im, exp[i1].im, exp[i1].re); \
434 CMUL(z[i0].re, z[i1].im, src0.re, src0.im, exp[i0].im, exp[i0].re); \
442 #define DECL_COMP_MDCT(N) \
443 static void compound_mdct_##N##xM(AVTXContext *s, void *_dst, void *_src, \
446 FFTSample *src = _src, *dst = _dst; \
447 FFTComplex *exp = s->exptab, tmp, fft##N##in[N]; \
448 const int m = s->m, len4 = N*m, len3 = len4 * 3, len8 = len4 >> 1; \
449 const int *in_map = s->pfatab, *out_map = in_map + N*m; \
450 void (*fftp)(FFTComplex *) = fft_dispatch[av_log2(m)]; \
452 stride /= sizeof(*dst); \
454 for (int i = 0; i < m; i++) { \
455 for (int j = 0; j < N; j++) { \
456 const int k = in_map[i*N + j]; \
458 tmp.re = FOLD(-src[ len4 + k], src[1*len4 - 1 - k]); \
459 tmp.im = FOLD(-src[ len3 + k], -src[1*len3 - 1 - k]); \
461 tmp.re = FOLD(-src[ len4 + k], -src[5*len4 - 1 - k]); \
462 tmp.im = FOLD( src[-len4 + k], -src[1*len3 - 1 - k]); \
464 CMUL(fft##N##in[j].im, fft##N##in[j].re, tmp.re, tmp.im, \
465 exp[k >> 1].re, exp[k >> 1].im); \
467 fft##N(s->tmp + s->revtab[i], fft##N##in, m); \
470 for (int i = 0; i < N; i++) \
471 fftp(s->tmp + m*i); \
473 for (int i = 0; i < len8; i++) { \
474 const int i0 = len8 + i, i1 = len8 - i - 1; \
475 const int s0 = out_map[i0], s1 = out_map[i1]; \
476 FFTComplex src1 = { s->tmp[s1].re, s->tmp[s1].im }; \
477 FFTComplex src0 = { s->tmp[s0].re, s->tmp[s0].im }; \
479 CMUL(dst[2*i1*stride + stride], dst[2*i0*stride], src0.re, src0.im, \
480 exp[i0].im, exp[i0].re); \
481 CMUL(dst[2*i0*stride + stride], dst[2*i1*stride], src1.re, src1.im, \
482 exp[i1].im, exp[i1].re); \
494 const int m =
s->m, len8 = m >> 1;
502 for (
int i = 0;
i < m;
i++) {
509 for (
int i = 0;
i < len8;
i++) {
510 const int i0 = len8 +
i, i1 = len8 -
i - 1;
524 const int m =
s->m, len4 = m, len3 = len4 * 3, len8 = len4 >> 1;
529 for (
int i = 0;
i < m;
i++) {
532 tmp.re = FOLD(-
src[ len4 + k],
src[1*len4 - 1 - k]);
533 tmp.im = FOLD(-
src[ len3 + k], -
src[1*len3 - 1 - k]);
535 tmp.re = FOLD(-
src[ len4 + k], -
src[5*len4 - 1 - k]);
536 tmp.im = FOLD(
src[-len4 + k], -
src[1*len3 - 1 - k]);
544 for (
int i = 0;
i < len8;
i++) {
545 const int i0 = len8 +
i, i1 = len8 -
i - 1;
558 const double theta = (scale < 0 ? len4 : 0) + 1.0/8.0;
563 scale = sqrt(fabs(scale));
564 for (
int i = 0;
i < len4;
i++) {
566 s->exptab[
i].re = RESCALE(cos(
alpha) * scale);
567 s->exptab[
i].im = RESCALE(sin(
alpha) * scale);
575 const void *scale, uint64_t
flags)
583 #define CHECK_FACTOR(DST, FACTOR, SRC) \
584 if (DST == 1 && !(SRC % FACTOR)) { \
594 if (!(
len & (
len - 1)) &&
len >= 2 &&
len <= max_ptwo) {
605 if (
len > 1 || m == 1) {
607 "m = %i, residual = %i!\n", n, m,
len);
609 }
else if (n > 1 && m > 1) {
614 *tx = n == 3 ? compound_fft_3xM :
615 n == 5 ? compound_fft_5xM :
618 *tx = n == 3 ? inv ? compound_imdct_3xM : compound_mdct_3xM :
619 n == 5 ? inv ? compound_imdct_5xM : compound_mdct_5xM :
620 inv ? compound_imdct_15xM : compound_mdct_15xM;
int(* func)(AVBPrint *dst, const char *in, const char *arg)
static void monolithic_imdct(AVTXContext *s, void *_dst, void *_src, ptrdiff_t stride)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
static void fft16(FFTComplex *z)
#define TRANSFORM(a0, a1, a2, a3, wre, wim)
static void fft2(FFTComplex *z)
#define TRANSFORM_ZERO(a0, a1, a2, a3)
static void fft5(FFTComplex *out, FFTComplex *in, FFTComplex exptab[2])
static void fft4(FFTComplex *z)
#define DECL_FFT5(NAME, D0, D1, D2, D3, D4)
static CosTabsInitOnce cos_tabs_init_once[]
static const struct twinvq_data tab
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
static int ff_thread_once(char *control, void(*routine)(void))
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
static void fft8(FFTComplex *z)
int ff_tx_gen_compound_mapping(AVTXContext *s)
static int gen_mdct_exptab(AVTXContext *s, int len4, double scale)
static av_cold void ff_init_53_tabs(void)
static void monolithic_mdct(AVTXContext *s, void *_dst, void *_src, ptrdiff_t stride)
#define DECL_COMP_MDCT(N)
int ff_tx_gen_ptwo_revtab(AVTXContext *s)
#define CHECK_FACTOR(DST, FACTOR, SRC)
int ff_tx_type_is_mdct(enum AVTXType type)
int TX_NAME() ff_tx_init_mdct_fft(AVTXContext *s, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
#define DECLARE_ALIGNED(n, t, v)
#define DECL_FFT(n, n2, n4)
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
#define i(width, name, range_min, range_max)
#define av_malloc_array(a, b)
#define DECL_COMP_IMDCT(N)
static av_cold void init_cos_tabs(int index)
static av_always_inline void fft15(FFTComplex *out, FFTComplex *in, ptrdiff_t stride)
static void(*const fft_dispatch[])(FFTComplex *)
#define FF_ARRAY_ELEMS(a)
#define INIT_FF_COS_TABS_FUNC(index, size)
static FFTSample *const cos_tabs[18]
#define BUTTERFLIES(a0, a1, a2, a3)
FFTComplex TX_NAME(ff_cos_53)[4]
static av_always_inline void init_cos_tabs_idx(int index)
static void monolithic_fft(AVTXContext *s, void *_out, void *_in, ptrdiff_t stride)
static const int16_t alpha[]
#define flags(name, subs,...)
#define CMUL(dre, dim, are, aim, bre, bim)
static av_always_inline void fft3(FFTComplex *out, FFTComplex *in, ptrdiff_t stride)