[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