[FFmpeg-devel] [PATCH] Port gradfun to libavfilter (GCI)

Stefano Sabatini stefano.sabatini-lala
Wed Dec 1 00:07:22 CET 2010


On date Monday 2010-11-29 21:48:18 -0500, Nolan L encoded:
> On Mon, Nov 29, 2010 at 7:18 AM, Nolan L <nol888 at gmail.com> wrote:
> 
> > As part of a GCI task, I've ported the gradfun debanding filter from
> > mplayer to libavfilter.
> >
> > The patch includes changes to the build system to account for CPU
> > optimizations that weren't present previously.
> >
> > There is a SSE2 method that remains unported due to lack of SSE2 detection
> > in the configure script that I wasn't quite sure how to add.
> >
> 
> Here is the resulting patch from the first round of feedback. Things that
> still need to be addressed (mostly with the asm):
>     -Factoring the asm; I don't have enough asm experience to do this.
>     -alignment issues with the asm code. (hopefully someone more experienced
> can take care of this.)
>     -gpl vs lgpl

 
> I looked at direct rendering, and decided that it would be simpler to keep
> it as is. If someone could point out a quick way to implement this without
> almost rewriting the filter I'd be happy to oblige.

Direct rendering in this context simply means that the filter doesn't
request a new buffer for the picture, but will directly write in the
buffer passed by the start_frame function (check the drawbox filter
for an example).

Note that this isn't generally possible, in the case you process the
neighborhood of each processed pixel like you're doing in this filter
(so you need those values not be altered). Point filters (e.g. the eq
filter) only process the pixel so they can don't need to write the
output in a separate buffer.

> As the code in x86/ needs to be compiled and linked (and can be compiled)
> regardless of compiler support for certain instruction sets, I dropped the
> additional conditional compilation lines in the Makefile.

> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 210510f..f50c100 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -28,6 +28,7 @@ OBJS-$(CONFIG_FORMAT_FILTER)                 += vf_format.o
>  OBJS-$(CONFIG_FREI0R_FILTER)                 += vf_frei0r.o
>  OBJS-$(CONFIG_HFLIP_FILTER)                  += vf_hflip.o
>  OBJS-$(CONFIG_NOFORMAT_FILTER)               += vf_format.o
> +OBJS-$(CONFIG_GRADFUN_FILTER)                += vf_gradfun.o
>  OBJS-$(CONFIG_NULL_FILTER)                   += vf_null.o
>  OBJS-$(CONFIG_OCV_SMOOTH_FILTER)             += vf_libopencv.o
>  OBJS-$(CONFIG_OVERLAY_FILTER)                += vf_overlay.o
> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
> index c3067b8..6ac517c 100644
> --- a/libavfilter/allfilters.c
> +++ b/libavfilter/allfilters.c
> @@ -48,6 +48,7 @@ void avfilter_register_all(void)
>      REGISTER_FILTER (FORMAT,      format,      vf);
>      REGISTER_FILTER (FREI0R,      frei0r,      vf);
>      REGISTER_FILTER (HFLIP,       hflip,       vf);
> +    REGISTER_FILTER (GRADFUN,     gradfun,     vf);
>      REGISTER_FILTER (NOFORMAT,    noformat,    vf);
>      REGISTER_FILTER (NULL,        null,        vf);
>      REGISTER_FILTER (OCV_SMOOTH,  ocv_smooth,  vf);
> diff --git a/libavfilter/gradfun.h b/libavfilter/gradfun.h
> new file mode 100644
> index 0000000..35dd78b
> --- /dev/null
> +++ b/libavfilter/gradfun.h
> @@ -0,0 +1,43 @@
> +/*
> + * copyright (c) 2010 Nolan Lum 
> + *               2009 Loren Merritt <lorenm at u.washignton.edu>

NitNitNit: Copyright here and below.

> + *
> + * 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 AVFILTER_GRADFUN_H
> +#define AVFILTER_GRADFUN_H
> +
> +#include "avfilter.h"
> +
> +typedef struct {
> +    int thresh;
> +    int radius;
> +    uint16_t *buf;

Please add some doxy here, especially buf is quite obscure.

> +    void (*filter_line) (uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
> +    void (*blur_line) (uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width);
> +} GradFunContext;
> +
> +void ff_gradfun_filter_line_c(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
> +void ff_gradfun_blur_line_c(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width);
> +
> +void ff_gradfun_filter_line_mmx2(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
> +void ff_gradfun_filter_line_ssse3(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
> +
> +void ff_gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width);
> +
> +#endif /* AVFILTER_YADIF_H */
> diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
> new file mode 100644
> index 0000000..6c8a384
> --- /dev/null
> +++ b/libavfilter/vf_gradfun.c
> @@ -0,0 +1,239 @@
> +/*
> + * copyright (c) 2010 Nolan Lum 
> + *               2009 Loren Merritt <lorenm at u.washignton.edu>
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser 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
> + */
> +
> +/**
> + * @file
> + * gradfun debanding video filter
> + */
> +
> +/*
> + * Debanding algorithm (from gradfun2db by prunedtree):
> + * Boxblur.
> + * Foreach pixel, if it's within threshold of the blurred value, make it closer.
> + * So now we have a smoothed and higher bitdepth version of all the shallow
> + * gradients, while leaving detailed areas untouched.
> + * Dither it back to 8bit.
> + */
> +
> +#include "libavcore/imgutils.h"
> +#include "libavutil/cpu.h"
> +#include "libavutil/pixdesc.h"
> +#include "avfilter.h"
> +#include "gradfun.h"
> +

> +#define CHROMA_WIDTH(link)     -((-link->w) >> av_pix_fmt_descriptors[link->format].log2_chroma_w)
> +#define CHROMA_HEIGHT(link)    -((-link->h) >> av_pix_fmt_descriptors[link->format].log2_chroma_h)
> +#define RADIUS_CHROMA(r, link) (((r >> av_pix_fmt_descriptors[link->format].log2_chroma_w) + \
> +                                (r >> av_pix_fmt_descriptors[link->format].log2_chroma_w)) / 2)

Please drop these macros, they only help to obfuscate the code, also
you can cache the log2_chroma_w/h values during configure stage and
use them directly.

[...]

Also add missing documentation, MPlayer docs should be fine.
-- 
FFmpeg = Friendly and Fancy Minimalistic Practical Eccentric Gadget



More information about the ffmpeg-devel mailing list