[FFmpeg-devel] port mplayer eq filter to libavfilter

William Yu genwillyu
Wed Nov 24 08:21:20 CET 2010


Hi.
I have moved process to draw_slice.
And i have fix problem you pointd out me. Please check it. Thanks.

2010/11/24 Stefano Sabatini <stefano.sabatini-lala at poste.it>:
> On date Tuesday 2010-11-23 22:22:47 +0800, William Yu encoded:
>> I have fix the problem mention below.
>> and change to directly process the input picture.
>> Please check it again.
>> BTW, I had send a mail to D Richard Felker III <dalias <at> aerifal.cx>.
>> If he agree relicense these under LGPL. I will patch it to LGPL. Thanks.
>>
>> 2010/11/22 Stefano Sabatini <stefano.sabatini-lala at poste.it>:
>> > On date Monday 2010-11-22 15:15:25 +0100, Stefano Sabatini encoded:
>> >> On date Monday 2010-11-22 20:33:11 +0800, William Yu encoded:
>> > [...]
>> >> > +}
>> >> > +
>> >> > +static void end_frame(AVFilterLink *link)
>> >>
>> >> inlink for enhanced readability
>> >>
>> >> > +{
>> >> > + ? ?EQContext * eq = link->dst->priv;
>> >> > + ? ?AVFilterBufferRef *in ?= link->cur_buf;
>> >> > + ? ?AVFilterBufferRef *out = link->dst->outputs[0]->out_buf;
>> >> > +
>> >> > + ? ?eq->process(out->data[0], out->linesize[0],
>> >> > + ? ? ? ?in->data[0], in->linesize[0],
>> >> > + ? ? ? ?link->w, link->h, eq->brightness, eq->contrast);
>> >> > + ? ?copy_chroma(in,out,link);
>> >
>> > Also is it really necessary to copy the chroma planes to a new frame?
>> > Maybe It would be possible to directly process the input picture, no need to
>> > allocate another one and to copy back the chroma planes.
>> >
>> > Regards.
>> > --
>> > FFmpeg = Fundamentalist & Free Multipurpose Portable Ecumenical God
>> > _______________________________________________
>> > ffmpeg-devel mailing list
>> > ffmpeg-devel at mplayerhq.hu
>> > https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel
>> >
>
>> diff --git a/Changelog b/Changelog
>> index dc949cd..6a6a0c7 100644
>> --- a/Changelog
>> +++ b/Changelog
>> @@ -59,6 +59,7 @@ version <next>:
>> ?- overlay filter added
>> ?- rename aspect filter to setdar, and pixelaspect to setsar
>> ?- IEC 61937 demuxer
>> +- eq video filter added
>>
>>
>> ?version 0.6:
>> diff --git a/configure b/configure
>> index 7dcb50f..c076ea9 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"
>> ?ocv_smooth_filter_deps="libopencv"
>> ?yadif_filter_deps="gpl"
>> diff --git a/doc/filters.texi b/doc/filters.texi
>> index 1cba2d6..0a45e7b 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 or contrast of the input video.
>
> or -> and/or
>
>> +
>> +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 210510f..37df7ee 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 9e3ba14..dae6848 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..f6b98d2
>> --- /dev/null
>> +++ b/libavfilter/eq.h
>> @@ -0,0 +1,18 @@
>> +/*
>> + * Ported to FFmpeg from MPlayer libmpcodecs/vf_eq.c
>> + * Port copyright (C) 2010 William Yu <genwillyu at gmail dot com>
>
> Ehm missing LGPL notice. Also I'd prefer to just use:
> ?* Copyright (c) 2010 William Yu <genwillyu at gmail dot com>
> ?* Copyright (c) 200X Richard Felker <genwillyu at gmail dot com>
>
> so it's easier to understand which the copyright holders are. You can
> mention this is a port in the @file notice of vf_eq.c.
>
>> + *
>> + * @file libavfilter/eq.h
>> + */
>> +
>> +#ifndef AVFILTER_EQ_H
>> +#define AVFILTER_EQ_H
>> +
>> +#include "avfilter.h"
>> +
>> +void ff_eq_filter_process_mmx(uint8_t *dest,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int dstride, uint8_t *src, int sstride,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?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..dba556d
>> --- /dev/null
>> +++ b/libavfilter/vf_eq.c
>> @@ -0,0 +1,138 @@
>> +/*
>
>> + * Ported to FFmpeg from MPlayer libmpcodecs/vf_eq.c
>> + * Port copyright (C) 2010 William Yu <genwillyu at gmail dot com>
>
> Same here as above.
>
>> + *
>> + * @file libavfilter/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
>> + ? ? ? ?unsigned char *dest,
>> + ? ? ? ?int dstride,
>> + ? ? ? ?unsigned char *src,
>> + ? ? ? ?int sstride,
>> + ? ? ? ?int w, int h,
>> + ? ? ? ?int brightness,
>> + ? ? ? ?int contrast);
>> +} ?EQContext;
>> +
>
>> +static void process_c(unsigned char *dest, int dstride, unsigned char *src, int sstride,
>> + ? ? ? ? ? ?int w, int h, int brightness, int contrast)
>
> Nits: dest -> dst
> ? ? ?sstride -> src_stride
> ? ? ?dstride -> dst_stride
>
>> +{
>> + ? ?int i;
>> + ? ?int pel;
>> + ? ?int dstep = dstride-w;
>> + ? ?int sstep = sstride-w;
>> +
>> + ? ?contrast = ((contrast+100)*256*256)/100;
>> + ? ?brightness = ((brightness+100)*511)/200-128 - (contrast>>9);
>> +
>> + ? ?while (h--) {
>> + ? ? ? ?for (i = w; i; i--) {
>> + ? ? ? ? ? ?pel = ((*src++* contrast)>>16) + brightness;
>> + ? ? ? ? ? ?if (pel&768) pel = (-pel)>>31;
>> + ? ? ? ? ? ?*dest++ = pel;
>> + ? ? ? ?}
>> + ? ? ? ?src += sstep;
>> + ? ? ? ?dest += dstep;
>> + ? ?}
>> +}
>> +
>> +static int query_formats(AVFilterContext *ctx)
>> +{
>> + ? ?enum PixelFormat pix_fmts[] = {
>> + ? ? ? ?PIX_FMT_YUV420P, ?PIX_FMT_YUV422P, ?PIX_FMT_YUV444P, ?PIX_FMT_YUV410P,
>> + ? ? ? ?PIX_FMT_YUV411P, ?PIX_FMT_YUV440P, ?PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P,
>> + ? ? ? ?PIX_FMT_YUVJ444P, PIX_FMT_YUVJ440P, PIX_FMT_NONE
>> + ? ?};
>> +
>> + ? ?avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
>> +
>> + ? ?return 0;
>> +}
>> +
>> +static av_cold int init(AVFilterContext *ctx, const char * args, void * opaque)
>> +{
>> + ? ?EQContext * eq = ctx->priv;
>> + ? ?av_unused int cpu_flags = av_get_cpu_flags();
>> +
>> + ? ?eq->brightness = 0;
>> + ? ?eq->contrast = 0;
>> +
>> + ? ?if (args)
>> + ? ? ? ?sscanf(args, "%d:%d", &(eq->brightness), &(eq->contrast));
>> +
>> + ? ?if (eq->brightness < -100 || eq->brightness > 100 ||
>> + ? ? ? ?eq->contrast < -100 || eq->contrast > 100) {
>> + ? ? ? ?av_log(ctx, AV_LOG_ERROR,
>> + ? ? ? ? ? ? ? ?"Invalid brightness or contrast value %d:%d\n",
>> + ? ? ? ? ? ? ? ?eq->brightness, eq->contrast);
>> + ? ? ? ?return AVERROR(EINVAL);
>> + ? ?}
>> +
>> + ? ?av_log(ctx, AV_LOG_INFO,
>> + ? ? ? ?"brightness and contrast value %d:%d\n",
>> + ? ? ? ?eq->brightness, eq->contrast);
>
> Nit:
> ? av_log(ctx, AV_LOG_INFO, "brightness:%d contrast:%d\n",
> ? ? ? ? ?eq->brightness, eq->contrast);
>
> simpler and easier to parse, also more consistent with the other
> filters.
>
>> + ? ?eq->process = NULL;
>> + ? ?if (eq->brightness || eq->contrast) {
>> + ? ? ? ?eq->process = process_c;
>> + ? ? ? ?if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
>> + ? ? ? ? ? ?av_log(ctx,AV_LOG_INFO,"use mmx\n");
>> + ? ? ? ? ? ?eq->process = ff_eq_filter_process_mmx;
>> + ? ? ? ?}
>> + ? ?}
>
> you can merge the two info logs and have:
> ? "brightness:%d contrast:%d use_mmx:%d\n"
>
>
>> + ? ?return 0;
>> +}
>> +
>> +static void start_frame(AVFilterLink * link, AVFilterBufferRef *picref)
>> +{
>> + ? ?AVFilterBufferRef *ref2 = avfilter_ref_buffer(picref,~0);
>> +
>> + ? ?avfilter_start_frame(link->dst->outputs[0], ref2);
>> +}
>
> this is not required
>
>> +
>> +static void end_frame(AVFilterLink *inlink)
>> +{
>> + ? ?EQContext * eq = inlink->dst->priv;
>> + ? ?AVFilterBufferRef *in ?= inlink->cur_buf;
>> +
>> + ? ?if ( eq->process )
>> + ? ? ? ?eq->process(in->data[0], in->linesize[0],
>> + ? ? ? ? ? ?in->data[0], in->linesize[0],
>> + ? ? ? ? ? ?inlink->w, inlink->h, eq->brightness, eq->contrast);
>> +
>> + ? ?avfilter_unref_buffer(in);
>> + ? ?avfilter_draw_slice(inlink->dst->outputs[0], 0, inlink->h, 1);
>> + ? ?avfilter_end_frame(inlink->dst->outputs[0]);
>> +}
>> +
>> +static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
>> +{
>> +}
>
> As Bobby pointed out you can exploit cache locality for enhanced
> performance and put the code in draw_slice, as it is done in the
> drawbox filter, check also the documentation of slicify.
>
> [...]
> --
> FFmpeg = Freak and Fierce MultiPurpose Evil Guru
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at mplayerhq.hu
> https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: vf_eq.diff
Type: application/octet-stream
Size: 12621 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20101124/504b53a3/attachment.obj>



More information about the ffmpeg-devel mailing list