Revision 47941088

View differences:

Changelog
36 36
- G.722 ADPCM audio encoder/decoder
37 37
- R10k video decoder
38 38
- ocv_smooth filter
39
- frei0r wrapper filter
39 40

  
40 41

  
41 42
version 0.6:
configure
162 162
External library support:
163 163
  --enable-avisynth        enable reading of AVISynth script files [no]
164 164
  --enable-bzlib           enable bzlib [autodetect]
165
  --enable-frei0r          enable frei0r video filtering
165 166
  --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
166 167
  --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
167 168
  --enable-libopencv       enable video filtering via libopencv [no]
......
873 874
    ffprobe
874 875
    ffserver
875 876
    fft
877
    frei0r
876 878
    golomb
877 879
    gpl
878 880
    gray
......
1050 1052
    poll_h
1051 1053
    setrlimit
1052 1054
    strerror_r
1055
    strtok_r
1053 1056
    struct_addrinfo
1054 1057
    struct_ipv6_mreq
1055 1058
    struct_sockaddr_in6
......
1383 1386
x11_grab_device_indev_deps="x11grab XShmCreateImage"
1384 1387
x11_grab_device_indev_extralibs="-lX11 -lXext -lXfixes"
1385 1388

  
1389
# filters
1390
frei0r_filter_deps="frei0r dlopen strtok_r"
1391

  
1386 1392
# protocols
1387 1393
gopher_protocol_deps="network"
1388 1394
http_protocol_deps="network"
......
2647 2653
check_func  ${malloc_prefix}posix_memalign      && enable posix_memalign
2648 2654
check_func  setrlimit
2649 2655
check_func  strerror_r
2656
check_func  strtok_r
2650 2657
check_func_headers io.h setmode
2651 2658
check_func_headers lzo/lzo1x.h lzo1x_999_compress
2652 2659
check_lib2 "windows.h psapi.h" GetProcessMemoryInfo -lpsapi
......
2720 2727

  
2721 2728
# these are off by default, so fail if requested and not available
2722 2729
enabled avisynth   && require2 vfw32 "windows.h vfw.h" AVIFileInit -lavifil32
2730
enabled frei0r     && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; }
2723 2731
enabled libdirac   && add_cflags $(pkg-config --cflags dirac) &&
2724 2732
                      require  libdirac libdirac_decoder/dirac_parser.h dirac_decoder_init $(pkg-config --libs dirac) &&
2725 2733
                      require  libdirac libdirac_encoder/dirac_encoder.h dirac_encoder_init $(pkg-config --libs dirac)
......
3012 3020
echo "SDL support               ${sdl-no}"
3013 3021
echo "Sun medialib support      ${mlib-no}"
3014 3022
echo "AVISynth enabled          ${avisynth-no}"
3023
echo "frei0r enabled            ${frei0r-no}"
3015 3024
echo "libdc1394 support         ${libdc1394-no}"
3016 3025
echo "libdirac enabled          ${libdirac-no}"
3017 3026
echo "libfaac enabled           ${libfaac-no}"
doc/filters.texi
81 81

  
82 82
will convert the input video to the format "yuv420p".
83 83

  
84
@section frei0r
85

  
86
Apply a frei0r effect to the input video.
87

  
88
To enable compilation of this filter you need to install the frei0r
89
header and configure FFmpeg with --enable-frei0r.
90

  
91
The filter supports the syntax:
92
@example
93
@var{filter_name}:@var{param1}:@var{param2}:...:@var{paramN}
94
@end example
95

  
96
@var{filter_name} is the name to the frei0r effect to load. If the
97
environment variable @env{FREI0R_PATH} is defined, the frei0r effect
98
is searched in each one of the directories specified by the colon
99
separated list in @env{FREIOR_PATH}, otherwise in the standard frei0r
100
paths, which are in this order: @file{HOME/.frei0r-1/lib/},
101
@file{/usr/local/lib/frei0r-1/}, @file{/usr/lib/frei0r-1/}.
102

  
103
@var{param1}, @var{param2}, ... , @var{paramN} specify the parameters
104
for the frei0r effect.
105

  
106
A frei0r effect parameter can be a boolean (whose values are specified
107
with "y" and "n"), a double, a color (specified by the syntax
108
@var{R}/@var{G}/@var{B}, @var{R}, @var{G}, and @var{B} being float
109
numbers from 0.0 to 1.0) or by an @code{av_parse_color()} color
110
description), a position (specified by the syntax @var{X}/@var{Y},
111
@var{X} and @var{Y} being float numbers) and a string.
112

  
113
The number and kind of parameters depend on the loaded effect. If an
114
effect parameter is not specified the default value is set.
115

  
116
Some examples follow:
117
@example
118
# apply the distort0r effect, set the first two double parameters
119
frei0r=distort0r:0.5:0.01
120

  
121
# apply the colordistance effect, takes a color as first parameter
122
frei0r=colordistance:0.2/0.3/0.4
123
frei0r=colordistance:violet
124
frei0r=colordistance:0x112233
125

  
126
# apply the perspective effect, specify the top left and top right
127
# image positions
128
frei0r=perspective:0.2/0.2:0.8/0.2
129
@end example
130

  
131
For more information see:
132
@url{http://piksel.org/frei0r}
133

  
84 134
@section hflip
85 135

  
86 136
Flip the input video horizontally.
libavfilter/Makefile
20 20
OBJS-$(CONFIG_CROP_FILTER)                   += vf_crop.o
21 21
OBJS-$(CONFIG_FIFO_FILTER)                   += vf_fifo.o
22 22
OBJS-$(CONFIG_FORMAT_FILTER)                 += vf_format.o
23
OBJS-$(CONFIG_FREI0R_FILTER)                 += vf_frei0r.o
23 24
OBJS-$(CONFIG_HFLIP_FILTER)                  += vf_hflip.o
24 25
OBJS-$(CONFIG_NOFORMAT_FILTER)               += vf_format.o
25 26
OBJS-$(CONFIG_NULL_FILTER)                   += vf_null.o
libavfilter/allfilters.c
40 40
    REGISTER_FILTER (CROP,        crop,        vf);
41 41
    REGISTER_FILTER (FIFO,        fifo,        vf);
42 42
    REGISTER_FILTER (FORMAT,      format,      vf);
43
    REGISTER_FILTER (FREI0R,      frei0r,      vf);
43 44
    REGISTER_FILTER (HFLIP,       hflip,       vf);
44 45
    REGISTER_FILTER (NOFORMAT,    noformat,    vf);
45 46
    REGISTER_FILTER (NULL,        null,        vf);
libavfilter/avfilter.h
25 25
#include "libavutil/avutil.h"
26 26

  
27 27
#define LIBAVFILTER_VERSION_MAJOR  1
28
#define LIBAVFILTER_VERSION_MINOR 39
28
#define LIBAVFILTER_VERSION_MINOR 40
29 29
#define LIBAVFILTER_VERSION_MICRO  0
30 30

  
31 31
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
libavfilter/vf_frei0r.c
1
/*
2
 * copyright (c) 2010 Stefano Sabatini
3
 * This file is part of FFmpeg.
4
 *
5
 * FFmpeg is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2.1 of the License, or (at your option) any later version.
9
 *
10
 * FFmpeg is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with FFmpeg; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
 */
19

  
20
/**
21
 * @file
22
 * frei0r wrapper
23
 */
24

  
25
/* #define DEBUG */
26

  
27
#include <dlfcn.h>
28
#include <frei0r.h>
29
#include "avfilter.h"
30
#include "parseutils.h"
31

  
32
typedef f0r_instance_t (*f0r_construct_f)(unsigned int width, unsigned int height);
33
typedef void (*f0r_destruct_f)(f0r_instance_t instance);
34
typedef void (*f0r_deinit_f)(void);
35
typedef int (*f0r_init_f)(void);
36
typedef void (*f0r_get_plugin_info_f)(f0r_plugin_info_t *info);
37
typedef void (*f0r_get_param_info_f)(f0r_param_info_t *info, int param_index);
38
typedef void (*f0r_update_f)(f0r_instance_t instance, double time, const uint32_t *inframe, uint32_t *outframe);
39
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);
40
typedef void (*f0r_set_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index);
41
typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index);
42

  
43
typedef struct Frei0rContext {
44
    f0r_update_f update;
45
    void *dl_handle;            /* dynamic library handle   */
46
    f0r_instance_t instance;
47
    f0r_plugin_info_t plugin_info;
48

  
49
    f0r_get_param_info_f  get_param_info;
50
    f0r_get_param_value_f get_param_value;
51
    f0r_set_param_value_f set_param_value;
52
    f0r_construct_f       construct;
53
    f0r_destruct_f        destruct;
54
    f0r_deinit_f          deinit;
55
    char params[256];
56
} Frei0rContext;
57

  
58
static void *load_sym(AVFilterContext *ctx, const char *sym_name)
59
{
60
    Frei0rContext *frei0r = ctx->priv;
61
    void *sym = dlsym(frei0r->dl_handle, sym_name);
62
    if (!sym)
63
        av_log(ctx, AV_LOG_ERROR, "Could not find symbol '%s' in loaded module\n", sym_name);
64
    return sym;
65
}
66

  
67
static int set_param(AVFilterContext *ctx, f0r_param_info_t info, int index, char *param)
68
{
69
    Frei0rContext *frei0r = ctx->priv;
70
    union {
71
        double d;
72
        f0r_param_color_t col;
73
        f0r_param_position_t pos;
74
    } val;
75
    char *tail;
76
    uint8_t rgba[4];
77

  
78
    switch (info.type) {
79
    case F0R_PARAM_BOOL:
80
        if      (!strcmp(param, "y")) val.d = 1.0;
81
        else if (!strcmp(param, "n")) val.d = 0.0;
82
        else goto fail;
83
        break;
84

  
85
    case F0R_PARAM_DOUBLE:
86
        val.d = strtod(param, &tail);
87
        if (*tail || val.d == HUGE_VAL)
88
            goto fail;
89
        break;
90

  
91
    case F0R_PARAM_COLOR:
92
        if (sscanf(param, "%f/%f/%f", &val.col.r, &val.col.g, &val.col.b) != 3) {
93
            if (av_parse_color(rgba, param, ctx) < 0)
94
                goto fail;
95
            val.col.r = rgba[0] / 255.0;
96
            val.col.g = rgba[1] / 255.0;
97
            val.col.b = rgba[2] / 255.0;
98
        }
99
        break;
100

  
101
    case F0R_PARAM_POSITION:
102
        if (sscanf(param, "%lf/%lf", &val.pos.x, &val.pos.y) != 2)
103
            goto fail;
104
        break;
105
    }
106

  
107
    frei0r->set_param_value(frei0r->instance, &val, index);
108
    return 0;
109

  
110
fail:
111
    av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for parameter '%s'\n",
112
           param, info.name);
113
    return AVERROR(EINVAL);
114
}
115

  
116
static int set_params(AVFilterContext *ctx, const char *params)
117
{
118
    Frei0rContext *frei0r = ctx->priv;
119
    int i;
120

  
121
    for (i = 0; i < frei0r->plugin_info.num_params; i++) {
122
        f0r_param_info_t info;
123
        char *param;
124
        int ret;
125

  
126
        frei0r->get_param_info(&info, i);
127

  
128
        if (*params) {
129
            if (!(param = av_get_token(&params, ":")))
130
                return AVERROR(ENOMEM);
131
            params++;               /* skip ':' */
132
            ret = set_param(ctx, info, i, param);
133
            av_free(param);
134
            if (ret < 0)
135
                return ret;
136
        }
137

  
138
        av_log(ctx, AV_LOG_INFO,
139
               "idx:%d name:'%s' type:%s explanation:'%s' ",
140
               i, info.name,
141
               info.type == F0R_PARAM_BOOL     ? "bool"     :
142
               info.type == F0R_PARAM_DOUBLE   ? "double"   :
143
               info.type == F0R_PARAM_COLOR    ? "color"    :
144
               info.type == F0R_PARAM_POSITION ? "position" :
145
               info.type == F0R_PARAM_STRING   ? "string"   : "unknown",
146
               info.explanation);
147

  
148
#ifdef DEBUG
149
        av_log(ctx, AV_LOG_INFO, "value:");
150
        switch (info.type) {
151
            void *v;
152
            double d;
153
            char s[128];
154
            f0r_param_color_t col;
155
            f0r_param_position_t pos;
156

  
157
        case F0R_PARAM_BOOL:
158
            v = &d;
159
            frei0r->get_param_value(frei0r->instance, v, i);
160
            av_log(ctx, AV_LOG_INFO, "%s", d >= 0.5 && d <= 1.0 ? "y" : "n");
161
            break;
162
        case F0R_PARAM_DOUBLE:
163
            v = &d;
164
            frei0r->get_param_value(frei0r->instance, v, i);
165
            av_log(ctx, AV_LOG_INFO, "%f", d);
166
            break;
167
        case F0R_PARAM_COLOR:
168
            v = &col;
169
            frei0r->get_param_value(frei0r->instance, v, i);
170
            av_log(ctx, AV_LOG_INFO, "%f/%f/%f", col.r, col.g, col.b);
171
            break;
172
        case F0R_PARAM_POSITION:
173
            v = &pos;
174
            frei0r->get_param_value(frei0r->instance, v, i);
175
            av_log(ctx, AV_LOG_INFO, "%lf/%lf", pos.x, pos.y);
176
            break;
177
        default: /* F0R_PARAM_STRING */
178
            v = s;
179
            frei0r->get_param_value(frei0r->instance, v, i);
180
            av_log(ctx, AV_LOG_INFO, "'%s'\n", s);
181
            break;
182
        }
183
#endif
184
        av_log(ctx, AV_LOG_INFO, "\n");
185
    }
186

  
187
    return 0;
188
}
189

  
190
static void *load_path(AVFilterContext *ctx, const char *prefix, const char *name)
191
{
192
    char path[1024];
193

  
194
    snprintf(path, sizeof(path), "%s%s.so", prefix, name);
195
    av_log(ctx, AV_LOG_DEBUG, "Looking for frei0r effect in '%s'\n", path);
196
    return dlopen(path, RTLD_NOW|RTLD_LOCAL);
197
}
198

  
199
static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
200
{
201
    Frei0rContext *frei0r = ctx->priv;
202
    f0r_init_f            f0r_init;
203
    f0r_get_plugin_info_f f0r_get_plugin_info;
204
    f0r_plugin_info_t *pi;
205
    char dl_name[1024], *path;
206

  
207
    *frei0r->params = 0;
208

  
209
    if (args)
210
        sscanf(args, "%1023[^:]:%255c", dl_name, frei0r->params);
211

  
212
    /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */
213
    if ((path = av_strdup(getenv("FREI0R_PATH")))) {
214
        char *p, *ptr = NULL;
215
        for (p = path; p = strtok_r(p, ":", &ptr); p = NULL)
216
            if (frei0r->dl_handle = load_path(ctx, p, dl_name))
217
                break;
218
        av_free(path);
219
    }
220
    if (!frei0r->dl_handle && (path = av_strdup(getenv("HOME")))) {
221
        char prefix[1024];
222
        snprintf(prefix, sizeof(prefix), "%s/.frei0r-1/lib/", path);
223
        frei0r->dl_handle = load_path(ctx, prefix, dl_name);
224
        av_free(path);
225
    }
226
    if (!frei0r->dl_handle)
227
        frei0r->dl_handle = load_path(ctx, "/usr/local/lib/frei0r-1/", dl_name);
228
    if (!frei0r->dl_handle)
229
        frei0r->dl_handle = load_path(ctx, "/usr/lib/frei0r-1/", dl_name);
230
    if (!frei0r->dl_handle) {
231
        av_log(ctx, AV_LOG_ERROR, "Could not find module '%s'\n", dl_name);
232
        return AVERROR(EINVAL);
233
    }
234

  
235
    if (!(f0r_init                = load_sym(ctx, "f0r_init"           )) ||
236
        !(f0r_get_plugin_info     = load_sym(ctx, "f0r_get_plugin_info")) ||
237
        !(frei0r->get_param_info  = load_sym(ctx, "f0r_get_param_info" )) ||
238
        !(frei0r->get_param_value = load_sym(ctx, "f0r_get_param_value")) ||
239
        !(frei0r->set_param_value = load_sym(ctx, "f0r_set_param_value")) ||
240
        !(frei0r->update          = load_sym(ctx, "f0r_update"         )) ||
241
        !(frei0r->construct       = load_sym(ctx, "f0r_construct"      )) ||
242
        !(frei0r->destruct        = load_sym(ctx, "f0r_destruct"       )) ||
243
        !(frei0r->deinit          = load_sym(ctx, "f0r_deinit"         )))
244
        return AVERROR(EINVAL);
245

  
246
    if (f0r_init() < 0) {
247
        av_log(ctx, AV_LOG_ERROR, "Could not init the frei0r module");
248
        return AVERROR(EINVAL);
249
    }
250

  
251
    f0r_get_plugin_info(&frei0r->plugin_info);
252
    pi = &frei0r->plugin_info;
253
    if (pi->plugin_type != F0R_PLUGIN_TYPE_FILTER) {
254
        av_log(ctx, AV_LOG_ERROR,
255
               "Invalid type '%s' for the plugin, a filter plugin was expected\n",
256
               pi->plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" :
257
               pi->plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" :
258
               pi->plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown");
259
        return AVERROR(EINVAL);
260
    }
261

  
262
    av_log(ctx, AV_LOG_INFO,
263
           "name:%s author:'%s' explanation:'%s' color_model:%s "
264
           "frei0r_version:%d version:%d.%d num_params:%d\n",
265
           pi->name, pi->author, pi->explanation,
266
           pi->color_model == F0R_COLOR_MODEL_BGRA8888 ? "bgra8888" :
267
           pi->color_model == F0R_COLOR_MODEL_RGBA8888 ? "rgba8888" :
268
           pi->color_model == F0R_COLOR_MODEL_PACKED32 ? "packed32" : "unknown",
269
           pi->frei0r_version, pi->major_version, pi->minor_version, pi->num_params);
270

  
271
    return 0;
272
}
273

  
274
static av_cold void uninit(AVFilterContext *ctx)
275
{
276
    Frei0rContext *frei0r = ctx->priv;
277

  
278
    if (frei0r->destruct)
279
        frei0r->destruct(frei0r->instance);
280
    if (frei0r->deinit)
281
        frei0r->deinit();
282
    if (frei0r->dl_handle)
283
        dlclose(frei0r->dl_handle);
284

  
285
    memset(frei0r, 0, sizeof(*frei0r));
286
}
287

  
288
static int config_input_props(AVFilterLink *inlink)
289
{
290
    AVFilterContext *ctx = inlink->dst;
291
    Frei0rContext *frei0r = ctx->priv;
292

  
293
    if (!(frei0r->instance = frei0r->construct(inlink->w, inlink->h))) {
294
        av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance");
295
        return AVERROR(EINVAL);
296
    }
297

  
298
    return set_params(ctx, frei0r->params);
299
}
300

  
301
static int query_formats(AVFilterContext *ctx)
302
{
303
    Frei0rContext *frei0r = ctx->priv;
304
    AVFilterFormats *formats = NULL;
305

  
306
    if        (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) {
307
        avfilter_add_format(&formats, PIX_FMT_BGRA);
308
    } else if (frei0r->plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) {
309
        avfilter_add_format(&formats, PIX_FMT_RGBA);
310
    } else {                                   /* F0R_COLOR_MODEL_PACKED32 */
311
        static const enum PixelFormat pix_fmts[] = {
312
            PIX_FMT_BGRA, PIX_FMT_ARGB, PIX_FMT_ABGR, PIX_FMT_ARGB, PIX_FMT_NONE
313
        };
314
        formats = avfilter_make_format_list(pix_fmts);
315
    }
316

  
317
    if (!formats)
318
        return AVERROR(ENOMEM);
319

  
320
    avfilter_set_common_formats(ctx, formats);
321
    return 0;
322
}
323

  
324
static void null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { }
325

  
326
static void end_frame(AVFilterLink *inlink)
327
{
328
    Frei0rContext *frei0r = inlink->dst->priv;
329
    AVFilterLink *outlink = inlink->dst->outputs[0];
330
    AVFilterBufferRef  *inpicref =  inlink->cur_buf;
331
    AVFilterBufferRef *outpicref = outlink->out_buf;
332

  
333
    frei0r->update(frei0r->instance, (double)inpicref->pts / AV_TIME_BASE,
334
                   (const uint32_t *)inpicref->data[0],
335
                   (uint32_t *)outpicref->data[0]);
336
    avfilter_unref_buffer(inpicref);
337
    avfilter_draw_slice(outlink, 0, outlink->h, 1);
338
    avfilter_end_frame(outlink);
339
    avfilter_unref_buffer(outpicref);
340
}
341

  
342
AVFilter avfilter_vf_frei0r = {
343
    .name      = "frei0r",
344
    .description = NULL_IF_CONFIG_SMALL("Apply a frei0r effect."),
345

  
346
    .query_formats = query_formats,
347
    .init = init,
348
    .uninit = uninit,
349

  
350
    .priv_size = sizeof(Frei0rContext),
351

  
352
    .inputs    = (AVFilterPad[]) {{ .name             = "default",
353
                                    .type             = AVMEDIA_TYPE_VIDEO,
354
                                    .draw_slice       = null_draw_slice,
355
                                    .config_props     = config_input_props,
356
                                    .end_frame        = end_frame,
357
                                    .min_perms        = AV_PERM_READ },
358
                                  { .name = NULL}},
359

  
360
    .outputs   = (AVFilterPad[]) {{ .name             = "default",
361
                                    .type             = AVMEDIA_TYPE_VIDEO, },
362
                                  { .name = NULL}},
363
};

Also available in: Unified diff