[FFmpeg-devel] port mplayer eq filter to libavfilter

Michael Niedermayer michaelni
Fri Dec 3 02:47:58 CET 2010


On Wed, Dec 01, 2010 at 10:17:28PM +0800, William Yu wrote:
> 2010/12/1 Ronald S. Bultje <rsbultje at gmail.com>:
> > Hi,
> >
> > On Tue, Nov 30, 2010 at 4:10 AM, William Yu <genwillyu at gmail.com> wrote:
> >> 2010/11/30 Ronald S. Bultje <rsbultje at gmail.com>:
> >>> Hi,
> >>>
> >>> On Mon, Nov 29, 2010 at 10:57 AM, William Yu <genwillyu at gmail.com> wrote:
> >>>> 2010/11/26 Ronald S. Bultje <rsbultje at gmail.com>:
> >>>>> On Fri, Nov 26, 2010 at 9:38 AM, William Yu <genwillyu at gmail.com> wrote:
> >>>>>> 2010/11/25 Ronald S. Bultje <rsbultje at gmail.com> wrote:
> >>>>>>> On Thu, Nov 25, 2010 at 4:27 AM, William Yu <genwillyu at gmail.com> wrote:
> >>>[..]
> > Looking almost good. Now, it doesn't work on x86-64 yet because you're
> > using a combination of size-specific calls and general registers:
> >
> >> ? ? ? ? "incl %0 \n\t"
> >
> > Should be inc
> >
> >> ? ? ? ? "addl %5, %0 \n\t"
> >
> > Should be add.
> >
> > Can anyone enlighten me what the "+m"(h) and "m"(step) do? Doing
> > "+m"(h) -> "+r"(h) has no effect, and doing the same for step causes a
> > compilation failure, probably because register size of int isn't the
> > same as for a pointer, so add destptr, step fails. But other than
> > that, what's the difference?
> >
> 
> I have using macro OPSIZE and REG_x to replace size-specifically call
> and generally registers.
> Is my understanding right?
> 
> patch is updated. Please review it.
> 
> > Ronald
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel at mplayerhq.hu
> > https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel
> >

>  Changelog                |    1 
>  configure                |    1 
>  doc/filters.texi         |   32 +++++++++++
>  libavfilter/Makefile     |    1 
>  libavfilter/allfilters.c |    1 
>  libavfilter/eq.h         |   30 ++++++++++
>  libavfilter/vf_eq.c      |  136 +++++++++++++++++++++++++++++++++++++++++++++++
>  libavfilter/x86/Makefile |    1 
>  libavfilter/x86/eq.c     |   90 +++++++++++++++++++++++++++++++
>  9 files changed, 293 insertions(+)
> fd4293a556a703b69509a24469ea8c8bb11a151d  vf_eq.diff
>  Changelog                |    1 +
>  configure                |    1 +
>  doc/filters.texi         |   32 +++++++++++
>  libavfilter/Makefile     |    1 +
>  libavfilter/allfilters.c |    1 +
>  libavfilter/eq.h         |   30 ++++++++++
>  libavfilter/vf_eq.c      |  136 ++++++++++++++++++++++++++++++++++++++++++++++
>  libavfilter/x86/Makefile |    1 +
>  libavfilter/x86/eq.c     |   90 ++++++++++++++++++++++++++++++
>  9 files changed, 293 insertions(+), 0 deletions(-)
> 
> diff --git a/Changelog b/Changelog
> index 5890aa7..f87354d 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -61,6 +61,7 @@ version <next>:
>  - IEC 61937 demuxer
>  - Mobotix .mxg demuxer
>  - frei0r source added
> +- eq video filter added
>  
>  
>  version 0.6:
> diff --git a/configure b/configure
> index a882501..79676bc 100755
> --- a/configure
> +++ b/configure
> @@ -1405,6 +1405,7 @@ udp_protocol_deps="network"
>  # filters
>  blackframe_filter_deps="gpl"
>  cropdetect_filter_deps="gpl"
> +eq_filter_deps="gpl"
>  frei0r_filter_deps="frei0r dlopen strtok_r"
>  frei0r_src_filter_deps="frei0r dlopen strtok_r"
>  ocv_smooth_filter_deps="libopencv"
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 9583e4e..0b5b7b2 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -257,6 +257,38 @@ drawbox
>  drawbox=10:20:200:60:red@@0.5"
>  @end example
>  
> + at section eq
> +
> +Adjust brightness and/or contrast of the input video.
> +
> +It accepts the following parameters:
> + at var{brightness}:@var{constrast}
> +
> +Negative values for the amount will descrease the corresponding value
> +for the lightness or contrast of the input video, while positive
> +values will increase the corresponding value.
> +
> + at table @option
> +
> + at item brightness
> +Set the brightness amount. It can be an integer between -100
> +and 100, default value is 0.
> +
> + at item contrast
> +Set the contrast amount. It can be an integer between -100
> +and 100, default value is 0.
> +
> + at end table
> +
> + at example
> +# increase lightness and contrast by 20 percent
> +eq=20:20
> +
> +# decrease lightness and contrast by 20 percent
> +eq=-20:-20
> +
> + at end example
> +
>  @section fifo
>  
>  Buffer input images and send them when they are requested.
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 792e845..593a0f2 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -23,6 +23,7 @@ OBJS-$(CONFIG_BLACKFRAME_FILTER)             += vf_blackframe.o
>  OBJS-$(CONFIG_CROP_FILTER)                   += vf_crop.o
>  OBJS-$(CONFIG_CROPDETECT_FILTER)             += vf_cropdetect.o
>  OBJS-$(CONFIG_DRAWBOX_FILTER)                += vf_drawbox.o
> +OBJS-$(CONFIG_EQ_FILTER)                     += vf_eq.o
>  OBJS-$(CONFIG_FIFO_FILTER)                   += vf_fifo.o
>  OBJS-$(CONFIG_FORMAT_FILTER)                 += vf_format.o
>  OBJS-$(CONFIG_FREI0R_FILTER)                 += vf_frei0r.o
> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
> index 4ecb00e..6bd65b5 100644
> --- a/libavfilter/allfilters.c
> +++ b/libavfilter/allfilters.c
> @@ -44,6 +44,7 @@ void avfilter_register_all(void)
>      REGISTER_FILTER (CROP,        crop,        vf);
>      REGISTER_FILTER (CROPDETECT,  cropdetect,  vf);
>      REGISTER_FILTER (DRAWBOX,     drawbox,     vf);
> +    REGISTER_FILTER (EQ,          eq,          vf);
>      REGISTER_FILTER (FIFO,        fifo,        vf);
>      REGISTER_FILTER (FORMAT,      format,      vf);
>      REGISTER_FILTER (FREI0R,      frei0r,      vf);
> diff --git a/libavfilter/eq.h b/libavfilter/eq.h
> new file mode 100644
> index 0000000..31c6549
> --- /dev/null
> +++ b/libavfilter/eq.h
> @@ -0,0 +1,30 @@
> +/*
> + * Copyright (c) 2010 William Yu <genwillyu at gmail dot com>
> + * Copyright (c) 2002 Richard Felker <dalias at aerifal dot cx>
> + *
> + * 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_EQ_H
> +#define AVFILTER_EQ_H
> +
> +#include "avfilter.h"
> +
> +void ff_eq_filter_process_mmx(uint8_t *line, int stride,
> +                              int w, int h, int brightness, int contrast);
> +
> +#endif /* AVFILTER_EQ_H */
> diff --git a/libavfilter/vf_eq.c b/libavfilter/vf_eq.c
> new file mode 100644
> index 0000000..4443919
> --- /dev/null
> +++ b/libavfilter/vf_eq.c
> @@ -0,0 +1,136 @@
> +/*
> + * Copyright (c) 2010 William Yu <genwillyu at gmail dot com>
> + * Copyright (c) 2002 Richard Felker <dalias at aerifal dot cx>
> + *
> + * 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
> + */
> +
> +/**
> + * @file
> + * Adjust brightness and/or contrast of the input video
> + * Ported from MPlayer libmpcodecs/vf_eq.c.
> + */
> +
> +#include "libavutil/cpu.h"
> +#include "libavutil/common.h"
> +#include "avfilter.h"
> +#include "eq.h"
> +
> +typedef struct EQContext {
> +    int brightness;         ///< scale from -100 to 100
> +    int contrast;           ///< scale from -100 to 100
> +    void (*process)(        ///< process function
> +        uint8_t *line, int stride, int w, int h, int brightness, int contrast);
> +}  EQContext;
> +
> +static void process_c( uint8_t *line, int stride,
> +    int w, int h, int brightness, int contrast)
> +{
> +    int i;
> +    int pel;
> +    int step = stride-w;
> +
> +    contrast = FASTDIV(((contrast+100)*256*256),100);
> +    brightness = FASTDIV(((brightness+100)*511),200)-128 - (contrast>>9);
[...]
> +    contrast = FASTDIV(((contrast+100)*256*16),100);
> +    brightness = FASTDIV(((brightness+100)*511),200)-128 - (contrast>>5);

they match in mplayer, they dont here, why?
i think SIMD and C have identical output in mplayers variant but not here.
If so i think this change should be undone



> +
> +    __asm__ volatile (
> +        "movd %3, %%mm3 \n\t"
> +        "movd %4, %%mm4 \n\t"
> +        "punpcklwd %%mm3, %%mm3 \n\t"
> +        "punpcklwd %%mm4, %%mm4 \n\t"
> +        "punpckldq %%mm3, %%mm3 \n\t"
> +        "punpckldq %%mm4, %%mm4 \n\t"
> +        "1: \n\t"
> +        "pxor %%mm0, %%mm0 \n\t"
> +        "mov %2, %%"REG_c" \n\t"
> +        "sar $3, %%"REG_c" \n\t"
> +        "2: \n\t"
> +        "movq (%0), %%mm1 \n\t"

> +        "movq %%mm1, %%mm2 \n\t"

have you benchmarked changeing this one from mplayer?


> +        "punpcklbw %%mm0, %%mm1 \n\t"
> +        "punpckhbw %%mm0, %%mm2 \n\t"
> +        "psllw $4, %%mm1 \n\t"
> +        "psllw $4, %%mm2 \n\t"
> +        "pmulhw %%mm4, %%mm1 \n\t"
> +        "pmulhw %%mm4, %%mm2 \n\t"
> +        "paddw %%mm3, %%mm1 \n\t"
> +        "paddw %%mm3, %%mm2 \n\t"
> +        "packuswb %%mm2, %%mm1 \n\t"
> +        "movq %%mm1, (%0) \n\t"
> +        "add $8, %0 \n\t"
> +        "dec %%"REG_c" \n\t"
> +        "jnz 2b \n\t"
> +        "mov %2, %%"REG_c" \n\t"
> +        "and $7, %%"REG_c" \n\t"
> +        "je 5f \n\t"
> +        "3: \n\t"
> +        "movzb (%0), %%"REG_a" \n\t"
> +        "imul %4, %%"REG_a" \n\t"
> +        "sar $12, %%"REG_a" \n\t"
> +        "add %3, %%"REG_a" \n\t"
> +        "mov %%"REG_a", %%"REG_d" \n\t"
> +        "and $768, %%"REG_a" \n\t"
> +        "je 4f \n\t"
> +        "mov %%"REG_d", %%"REG_a" \n\t"
> +        "neg %%"REG_a" \n\t"
> +        "sar $31, %%"REG_a" \n\t"
> +        "mov %%"REG_a", %%"REG_d" \n\t"
> +        "4: \n\t"
> +        "movb %%dl, (%0) \n\t"
> +        "inc %0 \n\t"
> +        "dec %%"REG_a" \n\t"
> +        "jnz 3b \n\t"
> +        "5: \n\t"
> +        "add %5, %0 \n\t"
> +        "dec"OPSIZE " %1 \n\t"
> +        "jnz 1b \n\t"

> +        : "+r" (line), "+m" (h)
> +        : "r" (w), "r" (brightness), "r" (contrast), "m" (step)
> +        : "%"REG_c, "%"REG_d, "%"REG_a, "memory"

this has some potential to fail on some x86_32 compilers

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I am the wisest man alive, for I know one thing, and that is that I know
nothing. -- Socrates
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20101203/155a6641/attachment.pgp>



More information about the ffmpeg-devel mailing list