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 #include <dlfcn.h>
26 #include <frei0r.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include "config.h"
42
49 typedef void (*
f0r_update_f)(f0r_instance_t instance,
double time,
const uint32_t *inframe, uint32_t *outframe);
50 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);
53
60
67
72
73 /* only used by the source */
78
80 {
82 void *sym = dlsym(s->
dl_handle, sym_name);
83 if (!sym)
85 return sym;
86 }
87
89 {
91 union {
92 double d;
93 f0r_param_color_t col;
94 f0r_param_position_t pos;
96 char *tail;
98
99 switch (info.type) {
100 case F0R_PARAM_BOOL:
101 if (!strcmp(param,
"y"))
val.d = 1.0;
102 else if (!strcmp(param,
"n"))
val.d = 0.0;
103 else goto fail;
104 break;
105
106 case F0R_PARAM_DOUBLE:
108 if (*tail ||
val.d == HUGE_VAL)
109 goto fail;
110 break;
111
112 case F0R_PARAM_COLOR:
113 if (sscanf(param,
"%f/%f/%f", &
val.col.r, &
val.col.g, &
val.col.b) != 3) {
115 goto fail;
116 val.col.r = rgba[0] / 255.0;
117 val.col.g = rgba[1] / 255.0;
118 val.col.b = rgba[2] / 255.0;
119 }
120 break;
121
122 case F0R_PARAM_POSITION:
123 if (sscanf(param,
"%lf/%lf", &
val.pos.x, &
val.pos.y) != 2)
124 goto fail;
125 break;
126 }
127
129 return 0;
130
131 fail:
133 param, info.name);
135 }
136
138 {
140 int i;
141
142 if (!params)
143 return 0;
144
146 f0r_param_info_t info;
147 char *param;
149
151
152 if (*params) {
155 params++; /* skip ':' */
158 if (ret < 0)
160 }
161
163 "idx:%d name:'%s' type:%s explanation:'%s' ",
164 i, info.name,
165 info.type == F0R_PARAM_BOOL ? "bool" :
166 info.type == F0R_PARAM_DOUBLE ? "double" :
167 info.type == F0R_PARAM_COLOR ? "color" :
168 info.type == F0R_PARAM_POSITION ? "position" :
169 info.type == F0R_PARAM_STRING ? "string" : "unknown",
170 info.explanation);
171
172 #ifdef DEBUG
174 switch (info.type) {
176 double d;
177 char s[128];
178 f0r_param_color_t col;
179 f0r_param_position_t pos;
180
181 case F0R_PARAM_BOOL:
182 v = &d;
185 break;
186 case F0R_PARAM_DOUBLE:
187 v = &d;
188 s->get_param_value(s->instance, v, i);
190 break;
191 case F0R_PARAM_COLOR:
192 v = &col;
193 s->get_param_value(s->instance, v, i);
195 break;
196 case F0R_PARAM_POSITION:
197 v = &pos;
198 s->get_param_value(s->instance, v, i);
200 break;
201 default: /* F0R_PARAM_STRING */
203 s->get_param_value(s->instance, v, i);
205 break;
206 }
207 #endif
209 }
210
211 return 0;
212 }
213
215 {
216 char *path =
av_asprintf(
"%s%s%s", prefix, name, SLIBSUF);
217 if (!path)
220 *handle_ptr = dlopen(path, RTLD_NOW|RTLD_LOCAL);
222 return 0;
223 }
224
226 const char *dl_name, int type)
227 {
231 f0r_plugin_info_t *pi;
232 char *path;
234
235 if (!dl_name) {
238 }
239
240 /* see: http://frei0r.dyne.org/codedoc/html/group__pluglocations.html */
241 if ((path =
av_strdup(getenv(
"FREI0R_PATH")))) {
242 #ifdef _WIN32
243 const char *separator = ";";
244 #else
245 const char *separator = ":";
246 #endif
247 char *p, *ptr = NULL;
248 for (p = path; p =
av_strtok(p, separator, &ptr); p = NULL) {
249 /* add additional trailing slash in case it is missing */
251 if (!p1) {
253 goto check_path_end;
254 }
257 if (ret < 0)
258 goto check_path_end;
260 break;
261 }
262
263 check_path_end:
265 if (ret < 0)
267 }
268 if (!s->
dl_handle && (path = getenv(
"HOME"))) {
269 char *prefix =
av_asprintf(
"%s/.frei0r-1/lib/", path);
270 if (!prefix)
274 if (ret < 0)
276 }
279 if (ret < 0)
281 }
284 if (ret < 0)
286 }
290 }
291
292 if (!(f0r_init =
load_sym(ctx,
"f0r_init" )) ||
293 !(f0r_get_plugin_info =
load_sym(ctx,
"f0r_get_plugin_info")) ||
302
303 if (f0r_init() < 0) {
306 }
307
310 if (pi->plugin_type != type) {
312 "Invalid type '%s' for the plugin\n",
313 pi->plugin_type == F0R_PLUGIN_TYPE_FILTER ? "filter" :
314 pi->plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" :
315 pi->plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" :
316 pi->plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown");
318 }
319
321 "name:%s author:'%s' explanation:'%s' color_model:%s "
322 "frei0r_version:%d version:%d.%d num_params:%d\n",
323 pi->name, pi->author, pi->explanation,
324 pi->color_model == F0R_COLOR_MODEL_BGRA8888 ? "bgra8888" :
325 pi->color_model == F0R_COLOR_MODEL_RGBA8888 ? "rgba8888" :
326 pi->color_model == F0R_COLOR_MODEL_PACKED32 ? "packed32" : "unknown",
327 pi->frei0r_version, pi->major_version, pi->minor_version, pi->num_params);
328
329 return 0;
330 }
331
333 {
335
337 }
338
340 {
342
349 }
350
352 {
355
361 }
362
364 }
365
367 {
370
371 if (s->
plugin_info.color_model == F0R_COLOR_MODEL_BGRA8888) {
373 }
else if (s->
plugin_info.color_model == F0R_COLOR_MODEL_RGBA8888) {
375 } else { /* F0R_COLOR_MODEL_PACKED32 */
378 };
380 }
381
382 if (!formats)
384
386 return 0;
387 }
388
390 {
394
396 if (!out) {
399 }
401
403 (
const uint32_t *)in->
data[0],
404 (uint32_t *)out->
data[0]);
405
407
409 }
410
411 #define OFFSET(x) offsetof(Frei0rContext, x)
412 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
416 { NULL },
417 };
418
420
422 {
427 },
428 { NULL }
429 };
430
432 {
435 },
436 { NULL }
437 };
438
442
446
448 .priv_class = &frei0r_class,
449
450 .
inputs = avfilter_vf_frei0r_inputs,
451
452 .
outputs = avfilter_vf_frei0r_outputs,
453 };
454
456 {
459
463 }
464
468 }
471
473 }
474
476 {
479
486
492 }
493
495 }
496
498 {
501
502 if (!frame)
504
507
510
512 }
513
519 { NULL },
520 };
521
523
525 {
530 },
531 { NULL }
532 };
533
535 .
name =
"frei0r_src",
537
539 .priv_class = &frei0r_src_class,
542
544
546
547 .
outputs = avfilter_vsrc_frei0r_src_outputs,
548 };