[FFmpeg-devel] [PATCH] Port FFT domain filter.
Michael Niedermayer
michaelni at gmx.at
Sat Feb 28 17:27:12 CET 2015
On Sat, Feb 28, 2015 at 08:22:49PM +0530, arwa arif wrote:
> Updated the patch.
> Makefile | 1
> allfilters.c | 1
> vf_fftfilt.c | 258 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 260 insertions(+)
> dde368ae2972c85600e209bee3a9e26a05938baf 0001-Port-FFT-domain-filter.patch
> From ba761516b97b146f4c62d6c5c08dc5ea02c06af5 Mon Sep 17 00:00:00 2001
> From: Arwa Arif <arwaarif1994 at gmail.com>
> Date: Tue, 24 Feb 2015 12:17:30 +0530
> Subject: [PATCH] Port FFT domain filter.
>
> ---
> libavfilter/Makefile | 1 +
> libavfilter/allfilters.c | 1 +
> libavfilter/vf_fftfilt.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 260 insertions(+)
> create mode 100644 libavfilter/vf_fftfilt.c
>
[...]
> +static int filter_frame(AVFilterLink *inlink, AVFrame *in)
> +{
> + AVFilterContext *ctx = inlink->dst;
> + AVFilterLink *outlink = inlink->dst->outputs[0];
> + FFTFILTContext *fftfilt = ctx->priv;
> + AVFrame *out;
> + int w = inlink->w;
> + int h = inlink->h;
> + size_t rdft_hlen = fftfilt->rdft_hlen;
> + size_t rdft_vlen = fftfilt->rdft_vlen;
> + int i, j;
> +
> + out = ff_get_video_buffer(outlink, inlink->w, inlink->h);
> + if (!out)
> + return AVERROR(ENOMEM);
> +
> + av_frame_copy_props(out, in);
> +
> + /*Horizontal pass - RDFT*/
> + fftfilt->rdft = av_rdft_init(fftfilt->rdft_hbits, DFT_R2C);
> + for (i = 0; i < h; i++)
> + {
> + memset(fftfilt->rdft_hdata + i * rdft_hlen, 0, rdft_hlen * sizeof(*fftfilt->rdft_hdata));
> + for (j = 0; j < w; j++)
> + fftfilt->rdft_hdata[i * rdft_hlen + j] = *(in->data[0] + in->linesize[0] * i + j);
> + }
> +
> + for (i = 0; i < h; i++)
> + av_rdft_calc(fftfilt->rdft, fftfilt->rdft_hdata + i * rdft_hlen);
> +
> + av_rdft_end(fftfilt->rdft);
> +
> + /*Vertical pass - RDFT*/
> + fftfilt->rdft = av_rdft_init(fftfilt->rdft_vbits, DFT_R2C);
> + for (i = 0; i < rdft_hlen; i++)
> + {
> + memset(fftfilt->rdft_vdata + i * rdft_vlen, 0, rdft_vlen * sizeof(*fftfilt->rdft_vdata));
> + for (j = 0; j < h; j++)
> + fftfilt->rdft_vdata[i * rdft_vlen + j] = fftfilt->rdft_hdata[j * rdft_hlen + i];
> + }
> +
> + for (i = 0; i < rdft_hlen; i++)
> + av_rdft_calc(fftfilt->rdft, fftfilt->rdft_vdata + i * rdft_vlen);
> +
> + av_rdft_end(fftfilt->rdft);
> +
> + /*Change user defined parameters*/
> + for (i = 0; i < rdft_hlen; i++)
> + for (j = 0; j < rdft_vlen; j++)
> + fftfilt->rdft_vdata[i * rdft_vlen + j] *= fftfilt->lum_data[i * rdft_vlen + j];
> + fftfilt->rdft_vdata[0] += rdft_hlen * rdft_vlen * fftfilt->dc;
> +
> + /*Vertical pass - IRDFT*/
> + fftfilt->rdft = av_rdft_init(fftfilt->rdft_vbits, IDFT_C2R);
> +
> + for (i = 0; i < rdft_hlen; i++)
> + av_rdft_calc(fftfilt->rdft, fftfilt->rdft_vdata + i * rdft_vlen);
> +
> + for (i = 0; i < rdft_hlen; i++)
> + for (j = 0; j < h; j++)
> + fftfilt->rdft_hdata[j * rdft_hlen + i] = fftfilt->rdft_vdata[i * rdft_vlen + j];
> +
> + av_rdft_end(fftfilt->rdft);
> +
> + /*Horizontal pass - IRDFT*/
> + fftfilt->rdft = av_rdft_init(fftfilt->rdft_hbits, IDFT_C2R);
> +
> + for (i = 0; i < h; i++)
> + av_rdft_calc(fftfilt->rdft, fftfilt->rdft_hdata + i * rdft_hlen);
> +
> + for (i = 0; i < h; i++)
> + for (j = 0; j < w; j++)
> + *(out->data[0] + out->linesize[0] * i + j) = av_clip(fftfilt->rdft_hdata[i * rdft_hlen + j]
> + * 4 / (rdft_hlen * rdft_vlen), 0, 255);
> +
> + av_rdft_end(fftfilt->rdft);
> +
> + av_free(fftfilt->rdft_hdata);
> + av_free(fftfilt->rdft_vdata);
these should be freed in uninit()
otherwise the code will crash on the 2nd frame, i guess you tested
with just a single picture
> +
> + av_frame_free(&in);
> +
> + return ff_filter_frame(outlink, out);
> +}
> +
> +static av_cold void uninit(AVFilterContext *ctx)
> +{
> + FFTFILTContext *fftfilt = ctx->priv;
> + av_expr_free(fftfilt->lum_expr);
> + av_free(fftfilt->lum_data);
> +}
> +
> +static int query_formats(AVFilterContext *ctx)
> +{
> + static const enum AVPixelFormat pixel_fmts_fftfilt[] = {
> + AV_PIX_FMT_GRAY8,
> + AV_PIX_FMT_NONE
gray8 works nicely
if you want, you can try to add yuv support
maybe AV_PIX_FMT_YUV444P first, it should be easiest as chroma planes
have the same size as luma. For the other YUV formats chroma planes
are smaller, av_pix_fmt_get_chroma_sub_sample() can be used to find
out by how much they are smaller
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Old school: Use the lowest level language in which you can solve the problem
conveniently.
New school: Use the highest level language in which the latest supercomputer
can solve the problem without the user falling asleep waiting.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20150228/ac54d853/attachment.asc>
More information about the ffmpeg-devel
mailing list