[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