[FFmpeg-devel] [PATCH] frei0r wrapper
Stefano Sabatini
stefano.sabatini-lala
Thu Sep 9 00:18:45 CEST 2010
On date Wednesday 2010-09-08 16:16:59 +0100, M?ns Rullg?rd encoded:
> Stefano Sabatini <stefano.sabatini-lala at poste.it> writes:
>
> > configure | 8 +
> > doc/filters.texi | 46 ++++++
> > libavfilter/Makefile | 1 +
> > libavfilter/allfilters.c | 1 +
> > libavfilter/vf_frei0r.c | 353 ++++++++++++++++++++++++++++++++++++++++++++++
> > 5 files changed, 409 insertions(+), 0 deletions(-)
> > create mode 100644 libavfilter/vf_frei0r.c
> >
> > diff --git a/configure b/configure
> > index ae3d738..7a2117d 100755
> > --- a/configure
> > +++ b/configure
> > @@ -162,6 +162,7 @@ Configuration options:
> > External library support:
> > --enable-avisynth enable reading of AVISynth script files [no]
> > --enable-bzlib enable bzlib [autodetect]
> > + --enable-frei0r enable frei0r video filtering
> > --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
> > --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
> > --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394
> > @@ -872,6 +873,7 @@ CONFIG_LIST="
> > ffprobe
> > ffserver
> > fft
> > + frei0r
> > golomb
> > gpl
> > gray
> > @@ -1006,6 +1008,7 @@ HAVE_LIST="
> > fast_cmov
> > fcntl
> > fork
> > + frei0r
> > getaddrinfo
> > gethrtime
> > GetProcessMemoryInfo
>
> You can't have something in both of those lists. This one should be
> in CONFIG_LIST only.
Fixed.
>
> > @@ -1379,6 +1382,9 @@ vfwcap_indev_extralibs="-lavicap32"
> > x11_grab_device_indev_deps="x11grab XShmCreateImage"
> > x11_grab_device_indev_extralibs="-lX11 -lXext -lXfixes"
> >
> > +# filters
> > +frei0r_filter_deps="frei0r dlopen"
> > +
> > # protocols
> > gopher_protocol_deps="network"
> > http_protocol_deps="network"
> > @@ -2704,6 +2710,7 @@ check_mathfunc truncf
> >
> > # these are off by default, so fail if requested and not available
> > enabled avisynth && require2 vfw32 "windows.h vfw.h" AVIFileInit -lavifil32
> > +enabled frei0r && check_header frei0r.h
>
> || die "suitable message"
Fixed.
> > diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
> > new file mode 100644
> > index 0000000..4cb1cd5
> > --- /dev/null
> > +++ b/libavfilter/vf_frei0r.c
> > @@ -0,0 +1,353 @@
> > +/*
> > + * Stefano Sabatini 2010
> > + * 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
> > + * frei0r wrapper
> > + */
> > +
> > +/* #define DEBUG */
> > +
> > +#include <dlfcn.h>
> > +#include <frei0r.h>
> > +#include <float.h>
> > +#include "avfilter.h"
> > +#include "parseutils.h"
> > +
> > +typedef f0r_instance_t (*f0r_construct_f)(unsigned int width, unsigned int height);
> > +typedef void (*f0r_destruct_f)(f0r_instance_t instance);
> > +typedef void (*f0r_deinit_f)(void);
> > +typedef int (*f0r_init_f)(void);
> > +typedef void (*f0r_get_plugin_info_f)(f0r_plugin_info_t *info);
> > +typedef void (*f0r_get_param_info_f)(f0r_param_info_t *info, int param_index);
> > +typedef void (*f0r_update_f)(f0r_instance_t instance, double time, const uint32_t *inframe, uint32_t *outframe);
> > +typedef void (*f0r_update2_f)(f0r_instance_t instance, double time, const uint32_t *inframe1, const uint32_t *inframe2, const uint32_t *inframe3, uint32_t *outframe);
> > +typedef void (*f0r_set_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index);
> > +typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index);
> > +
> > +typedef struct Frei0rContext {
> > + f0r_update_f update;
> > + void *dll;
> > + char dll_filename[128];
>
> 128 is a bit short for a filename.
Increased to 256.
> Also, does it really need to be stored here?
It was to help error feedback, but I found an alternative way which
doesn't require that.
> Also "dll" has an unpleasant Windows ring to it.
Stands for Dynamic Linking Loader so no Windows specific, anyway
changed to dl_handle.
> > + f0r_instance_t instance;
> > + f0r_plugin_info_t plugin_info;
> > +
> > + f0r_get_param_info_f get_param_info;
> > + f0r_get_param_value_f get_param_value;
> > + f0r_set_param_value_f set_param_value;
> > + f0r_construct_f construct;
> > + f0r_destruct_f destruct;
> > + f0r_deinit_f deinit;
> > + char params[256];
> > +} Frei0rContext;
> > +
> > +static void *load_sym(AVFilterContext *ctx, const char *sym_name)
> > +{
> > + Frei0rContext *frei0r = ctx->priv;
> > + void *sym = dlsym(frei0r->dll, sym_name);
> > + if (!sym)
> > + av_log(ctx, AV_LOG_ERROR,
> > + "Could not find symbol '%s' in module '%s'\n", sym_name, frei0r->dll_filename);
> > + return sym;
> > +}
> > +
> > +static int set_param(AVFilterContext *ctx, f0r_param_info_t info, int index, char *param)
> > +{
> > + Frei0rContext *frei0r = ctx->priv;
> > + union {
> > + double d;
> > + f0r_param_color_t col;
> > + f0r_param_position_t pos;
> > + } val;
> > +
> > + switch (info.type) {
> > + case F0R_PARAM_BOOL:
> > + if (!strcmp(param, "y")) val.d = 1.0;
> > + else if (!strcmp(param, "n")) val.d = 0.0;
> > + else goto fail;
> > + break;
>
> Strange indentation.
>
> > + case F0R_PARAM_DOUBLE:
> > + {
> > + char *tail;
> > + val.d = strtod(param, &tail);
> > + if (*tail || val.d == HUGE_VAL)
> > + goto fail;
> > + }
> > + break;
>
> Ditto.
>
> > + case F0R_PARAM_COLOR:
> > + if (sscanf(param, "%f/%f/%f", &val.col.r, &val.col.g, &val.col.b) != 3) {
> > + uint8_t rgba[4];
> > + if (av_parse_color(rgba, param, ctx) < 0)
> > + goto fail;
> > + val.col.r = rgba[0] / 255.0;
> > + val.col.g = rgba[1] / 255.0;
> > + val.col.b = rgba[2] / 255.0;
> > + }
> > + break;
>
> And here.
>
> > + case F0R_PARAM_POSITION:
> > + if (sscanf(param, "%lf/%lf", &val.pos.x, &val.pos.y) != 2)
> > + goto fail;
> > + break;
>
> Here too.
Fixed weird indentation.
> > + default: /* F0R_PARAM_STRING */
> > + break;
>
> But not here. However, the default label is rather pointless since it
> contains no code.
Removed.
> > + }
> > +
> > + frei0r->set_param_value(frei0r->instance, &val, index);
> > + return 0;
> > +
> > +fail:
> > + av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for parameter '%s'",
> > + param, info.name);
> > + return AVERROR(EINVAL);
> > +}
> > +
>
> [...]
>
> > +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
> > +{
> > + Frei0rContext *frei0r = ctx->priv;
> > + f0r_init_f f0r_init;
> > + f0r_get_plugin_info_f f0r_get_plugin_info;
> > + f0r_plugin_info_t *pi;
> > + int i;
> > + const char *dll_prefixes[]= {
> > + "", "/usr/lib/frei0r-1/", "/usr/local/lib/frei0r-1/"
> > + };
>
> That's a rather limited set. Is there some environment variable
> customarily used to find these files? If so, use it. If not, pick a
> suitable name and use that.
Checked the specs, now I'm using FREI0R_PATH.
>
> > + char dll_filename[128];
> > +
> > + *(frei0r->params) = 0;
> > +
> > + if (args)
> > + sscanf(args, "%127[^:]:%255c", dll_filename, frei0r->params);
> > +
> > + for (i = 0; i < FF_ARRAY_ELEMS(dll_prefixes); i++) {
> > + snprintf(frei0r->dll_filename, sizeof(frei0r->dll_filename), "%s%s", dll_prefixes[i], dll_filename);
> > + if ((frei0r->dll = dlopen(frei0r->dll_filename, RTLD_NOW)))
>
> Why RTLD_NOW? You also should specify one of RTLD_GLOBAL or
> RTLD_LOCAL. I suggest the latter.
Used RTLD_LAZY|RTLD_LOCAL, note that I'm not such an expert and I
didn't noticed any difference so I'm simply trusting your word.
>
> > + break;
> > + }
> > +
> > + if (!frei0r->dll) {
> > + av_log(ctx, AV_LOG_ERROR, "Could not find module '%s'\n", dll_filename);
> > + return AVERROR(EINVAL);
> > + }
> > +
> > + if (!(f0r_init = load_sym(ctx, "f0r_init" )) ||
> > + !(f0r_get_plugin_info = load_sym(ctx, "f0r_get_plugin_info")) ||
> > + !(frei0r->get_param_info = load_sym(ctx, "f0r_get_param_info" )) ||
> > + !(frei0r->get_param_value = load_sym(ctx, "f0r_get_param_value")) ||
> > + !(frei0r->set_param_value = load_sym(ctx, "f0r_set_param_value")) ||
> > + !(frei0r->update = load_sym(ctx, "f0r_update" )) ||
> > + !(frei0r->construct = load_sym(ctx, "f0r_construct" )) ||
> > + !(frei0r->destruct = load_sym(ctx, "f0r_destruct" )) ||
> > + !(frei0r->deinit = load_sym(ctx, "f0r_deinit" )))
> > + return AVERROR(EINVAL);
> > +
> > + if (f0r_init() < 0) {
> > + av_log(ctx, AV_LOG_ERROR, "Could not init the frei0r module");
> > + return AVERROR(EINVAL);
> > + }
> > +
> > + f0r_get_plugin_info(&frei0r->plugin_info);
> > + pi = &(frei0r->plugin_info);
>
> Useless ().
Removed.
Updated patch in attachment.
--
FFmpeg = Fascinating & Funny Mastering Pacific Elastic Guru
More information about the ffmpeg-devel
mailing list