No dct business yet; meant to be a minimal setup for now. Such things added as FIXME's and TODO's.
Signed-off-by: Ganesh Ajjanagadde <gajja...@gmail.com> --- libavcodec/Makefile | 1 + libavcodec/fftw.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ libavcodec/fftw.h | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 libavcodec/fftw.c create mode 100644 libavcodec/fftw.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index ef9eb98..5b35d89 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -63,6 +63,7 @@ FFT-OBJS-$(CONFIG_HARDCODED_TABLES) += cos_tables.o cos_fixed_tables.o OBJS-$(CONFIG_FFT) += avfft.o fft_fixed.o fft_float.o \ fft_fixed_32.o fft_init_table.o \ $(FFT-OBJS-yes) +OBJS-$(CONFIG_LIBFFTW3) += fftw.o OBJS-$(CONFIG_FLACDSP) += flacdsp.o OBJS-$(CONFIG_FMTCONVERT) += fmtconvert.o OBJS-$(CONFIG_GOLOMB) += golomb.o diff --git a/libavcodec/fftw.c b/libavcodec/fftw.c new file mode 100644 index 0000000..d3c2e1f --- /dev/null +++ b/libavcodec/fftw.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003, 2007-11 Matteo Frigo + * Copyright (c) 2003, 2007-11 Massachusetts Institute of Technology. + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + */ + +#include "libavutil/mem.h" +#include "fftw.h" + +static void fft_calc(struct FFTWContext *s, FFTWComplex *z) +{ + fftwf_execute_dft(s->plan, z, z); +} + +av_cold int ff_fftw_init(FFTWContext *s, int n, int inverse) +{ + FFTWComplex *tmp; + s->n = n; + s->inverse = inverse; + s->fft_calc = fft_calc; + // create a temporary array for computing the plan + // note: there is no real advantage to doing this on the first calc run; + // plan creation is not guaranteed to not touch the array at hand. + tmp = av_malloc(sizeof(*tmp) * n); + if (!tmp) + goto fail; + else { + /* FIXME: plan creation is not threadsafe */ + /* TODO: some time generate "wisdom" files offline for common arches + and fft sizes, dump them in a folder, w/o compression as the one time + plan init can get expensive for long FFT's (seconds for len ~ 8192). */ + if (inverse) + s->plan = fftwf_plan_dft_1d(n, tmp, tmp, FFTW_BACKWARD, FFTW_PATIENT); + else + s->plan = fftwf_plan_dft_1d(n, tmp, tmp, FFTW_FORWARD, FFTW_PATIENT); + /* apparently never happens in default fftw configurations; just being safe */ + if (!s->plan) + goto fail; + } + av_free(tmp); + return 0; +fail: + av_freep(&tmp); + return AVERROR(ENOMEM); +} + +av_cold void ff_fftw_deinit(FFTWContext *s) +{ + fftwf_destroy_plan(s->plan); + // TODO: doing this complete cleanup may not be ideal; it will bring FFTW + // to a clean slate and thus future init's won't benefit from some of the + // accumulated plan knowledge/"wisdom". + fftwf_cleanup(); +} diff --git a/libavcodec/fftw.h b/libavcodec/fftw.h new file mode 100644 index 0000000..656e5db --- /dev/null +++ b/libavcodec/fftw.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2003, 2007-11 Matteo Frigo + * Copyright (c) 2003, 2007-11 Massachusetts Institute of Technology. + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 AVCODEC_FFTW_H +#define AVCODEC_FFTW_H + +/** + * @file + * @ingroup libavc + * FFTW based FFT functions header + */ + +#include <fftw3.h> + +typedef fftwf_complex FFTWComplex; +typedef fftwf_plan FFTWPlan; + +typedef struct FFTWContext { + /** + * Length of the FFT. Note that the length need not be a power of 2; powers + * of 2 are most efficient though. + */ + int n; + /** + * if 0 perform forward transform, if 1 perform reverse transform. + */ + int inverse; + /** + * An opaque internal pointer containing plan information, essentially target + * optimization information for the specified FFT parameters such as n. + * NOTE: If one calls fft_calc on the exact same array repeatedly, or on the + * same length with proper alignment, and with the same flags, there is no + * issue. However, if these conditions are not met, it is necessary to + * recompute plans. Note that this is often cheap. For precise information on + * this, see the fftw docs: http://www.fftw.org/fftw3.pdf, or + * http://www.fftw.org/faq/section3.html#planperarray. + */ + FFTWPlan plan; + /** + * Do a complex, in-place FFT with the parameters defined in ff_fftw_init(). + * No 1.0/sqrt(n) normalization is done. + */ + void (*fft_calc)(struct FFTWContext *s, FFTWComplex *z); + /* TODO: add dct, rdft, etc */ +} FFTWContext; + +/** + * Set up a complex, in-place FFT. + * @param s pointer to an FFTWContext + * @param n length of the input array + * @param inverse if 0 perform the forward transform, if 1 perform the inverse + * @return 0 on success, negative AVERROR code otherwise + */ +int ff_fftw_init(FFTWContext *s, int n, int inverse); + +/** + * Clean up an FFTWContext. + * @param s pointer to an FFTWContext + */ +void ff_fftw_deinit(FFTWContext *s); + + +#endif /* AVCODEC_FFTW_H */ -- 2.7.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel