1 /* GStreamer
2 * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "gstfrei0r.h"
25 #include "gstfrei0rfilter.h"
26 #include "gstfrei0rsrc.h"
27 #include "gstfrei0rmixer.h"
28
29 #include <string.h>
30 #include <gmodule.h>
31
32 GST_DEBUG_CATEGORY (frei0r_debug);
33 #define GST_CAT_DEFAULT frei0r_debug
34
35 static GstStaticCaps bgra8888_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
36 ("BGRA"));
37 static GstStaticCaps rgba8888_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
38 ("RGBA"));
39 static GstStaticCaps packed32_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
40 ("{ BGRA, RGBA, ABGR, ARGB, BGRx, RGBx, xBGR, xRGB, AYUV }"));
41
42 GstCaps *
gst_frei0r_caps_from_color_model(gint color_model)43 gst_frei0r_caps_from_color_model (gint color_model)
44 {
45 switch (color_model) {
46 case F0R_COLOR_MODEL_BGRA8888:
47 return gst_static_caps_get (&bgra8888_caps);
48 case F0R_COLOR_MODEL_RGBA8888:
49 return gst_static_caps_get (&rgba8888_caps);
50 case F0R_COLOR_MODEL_PACKED32:
51 return gst_static_caps_get (&packed32_caps);
52 default:
53 break;
54 }
55
56 return NULL;
57 }
58
59 void
gst_frei0r_klass_install_properties(GObjectClass * gobject_class,GstFrei0rFuncTable * ftable,GstFrei0rProperty * properties,gint n_properties)60 gst_frei0r_klass_install_properties (GObjectClass * gobject_class,
61 GstFrei0rFuncTable * ftable, GstFrei0rProperty * properties,
62 gint n_properties)
63 {
64 gint i, count = 1;
65 f0r_instance_t *instance = ftable->construct (640, 480);
66
67 g_assert (instance);
68
69 for (i = 0; i < n_properties; i++) {
70 f0r_param_info_t *param_info = &properties[i].info;
71 gchar *prop_name;
72
73 ftable->get_param_info (param_info, i);
74
75 if (!param_info->name) {
76 GST_ERROR ("Property %d of %s without a valid name", i,
77 g_type_name (G_TYPE_FROM_CLASS (gobject_class)));
78 continue;
79 }
80
81 prop_name = g_ascii_strdown (param_info->name, -1);
82 g_strcanon (prop_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-+", '-');
83 /* satisfy glib2 (argname[0] must be [A-Za-z]) */
84 if (!((prop_name[0] >= 'a' && prop_name[0] <= 'z') ||
85 (prop_name[0] >= 'A' && prop_name[0] <= 'Z'))) {
86 gchar *tempstr = prop_name;
87
88 prop_name = g_strconcat ("param-", prop_name, NULL);
89 g_free (tempstr);
90 }
91
92 properties[i].prop_id = count;
93 properties[i].prop_idx = i;
94
95 ftable->get_param_value (instance, &properties[i].default_value, i);
96 if (param_info->type == F0R_PARAM_STRING)
97 properties[i].default_value.data.s =
98 g_strdup (properties[i].default_value.data.s);
99
100 switch (param_info->type) {
101 case F0R_PARAM_BOOL:
102 g_object_class_install_property (gobject_class, count++,
103 g_param_spec_boolean (prop_name, param_info->name,
104 param_info->explanation,
105 properties[i].default_value.data.b ? TRUE : FALSE,
106 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
107 properties[i].n_prop_ids = 1;
108 break;
109 case F0R_PARAM_DOUBLE:{
110 gdouble def = properties[i].default_value.data.d;
111
112 /* If the default is NAN, +-INF we use 0.0 */
113 if (!(def >= 0.0 && def <= 1.0))
114 def = 0.0;
115
116 g_object_class_install_property (gobject_class, count++,
117 g_param_spec_double (prop_name, param_info->name,
118 param_info->explanation, 0.0, 1.0, def,
119 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
120 properties[i].n_prop_ids = 1;
121 break;
122 }
123 case F0R_PARAM_STRING:
124 g_object_class_install_property (gobject_class, count++,
125 g_param_spec_string (prop_name, param_info->name,
126 param_info->explanation, properties[i].default_value.data.s,
127 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
128 properties[i].n_prop_ids = 1;
129 break;
130 case F0R_PARAM_COLOR:{
131 gchar *prop_name_full;
132 gchar *prop_nick_full;
133 gdouble def;
134
135 def = properties[i].default_value.data.color.r;
136 /* If the default is out of range we use 0.0 */
137 if (!(def <= 1.0 && def >= 0.0))
138 def = 0.0;
139 prop_name_full = g_strconcat (prop_name, "-r", NULL);
140 prop_nick_full = g_strconcat (param_info->name, " (R)", NULL);
141 g_object_class_install_property (gobject_class, count++,
142 g_param_spec_float (prop_name_full, prop_nick_full,
143 param_info->explanation, 0.0, 1.0, def,
144 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
145 g_free (prop_name_full);
146 g_free (prop_nick_full);
147
148 def = properties[i].default_value.data.color.g;
149 /* If the default is out of range we use 0.0 */
150 if (!(def <= 1.0 && def >= 0.0))
151 def = 0.0;
152 prop_name_full = g_strconcat (prop_name, "-g", NULL);
153 prop_nick_full = g_strconcat (param_info->name, " (G)", NULL);
154 g_object_class_install_property (gobject_class, count++,
155 g_param_spec_float (prop_name_full, prop_nick_full,
156 param_info->explanation, 0.0, 1.0, def,
157 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
158 g_free (prop_name_full);
159 g_free (prop_nick_full);
160
161 def = properties[i].default_value.data.color.b;
162 /* If the default is out of range we use 0.0 */
163 if (!(def <= 1.0 && def >= 0.0))
164 def = 0.0;
165 prop_name_full = g_strconcat (prop_name, "-b", NULL);
166 prop_nick_full = g_strconcat (param_info->name, " (B)", NULL);
167 g_object_class_install_property (gobject_class, count++,
168 g_param_spec_float (prop_name_full, prop_nick_full,
169 param_info->explanation, 0.0, 1.0, def,
170 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
171 g_free (prop_name_full);
172 g_free (prop_nick_full);
173
174 properties[i].n_prop_ids = 3;
175 break;
176 }
177 case F0R_PARAM_POSITION:{
178 gchar *prop_name_full;
179 gchar *prop_nick_full;
180 gdouble def;
181
182 def = properties[i].default_value.data.position.x;
183 /* If the default is out of range we use 0.0 */
184 if (!(def <= 1.0 && def >= 0.0))
185 def = 0.0;
186 prop_name_full = g_strconcat (prop_name, "-x", NULL);
187 prop_nick_full = g_strconcat (param_info->name, " (X)", NULL);
188 g_object_class_install_property (gobject_class, count++,
189 g_param_spec_double (prop_name_full, prop_nick_full,
190 param_info->explanation, 0.0, 1.0, def,
191 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
192 g_free (prop_name_full);
193 g_free (prop_nick_full);
194
195 def = properties[i].default_value.data.position.y;
196 /* If the default is out of range we use 0.0 */
197 if (!(def <= 1.0 && def >= 0.0))
198 def = 0.0;
199 prop_name_full = g_strconcat (prop_name, "-Y", NULL);
200 prop_nick_full = g_strconcat (param_info->name, " (Y)", NULL);
201 g_object_class_install_property (gobject_class, count++,
202 g_param_spec_double (prop_name_full, prop_nick_full,
203 param_info->explanation, 0.0, 1.0, def,
204 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
205 g_free (prop_name_full);
206 g_free (prop_nick_full);
207
208 properties[i].n_prop_ids = 2;
209 break;
210 }
211 default:
212 g_assert_not_reached ();
213 break;
214 }
215
216 g_free (prop_name);
217 }
218
219 ftable->destruct (instance);
220 }
221
222 GstFrei0rPropertyValue *
gst_frei0r_property_cache_init(GstFrei0rProperty * properties,gint n_properties)223 gst_frei0r_property_cache_init (GstFrei0rProperty * properties,
224 gint n_properties)
225 {
226 gint i;
227 GstFrei0rPropertyValue *ret = g_new0 (GstFrei0rPropertyValue, n_properties);
228
229 for (i = 0; i < n_properties; i++) {
230 memcpy (&ret[i].data, &properties[i].default_value,
231 sizeof (GstFrei0rPropertyValue));
232
233 if (properties[i].info.type == F0R_PARAM_STRING)
234 ret[i].data.s = g_strdup (ret[i].data.s);
235 }
236
237 return ret;
238 }
239
240 void
gst_frei0r_property_cache_free(GstFrei0rProperty * properties,GstFrei0rPropertyValue * property_cache,gint n_properties)241 gst_frei0r_property_cache_free (GstFrei0rProperty * properties,
242 GstFrei0rPropertyValue * property_cache, gint n_properties)
243 {
244 gint i;
245
246 for (i = 0; i < n_properties; i++) {
247 if (properties[i].info.type == F0R_PARAM_STRING)
248 g_free (property_cache[i].data.s);
249 }
250 g_free (property_cache);
251 }
252
253 f0r_instance_t *
gst_frei0r_instance_construct(GstFrei0rFuncTable * ftable,GstFrei0rProperty * properties,gint n_properties,GstFrei0rPropertyValue * property_cache,gint width,gint height)254 gst_frei0r_instance_construct (GstFrei0rFuncTable * ftable,
255 GstFrei0rProperty * properties, gint n_properties,
256 GstFrei0rPropertyValue * property_cache, gint width, gint height)
257 {
258 f0r_instance_t *instance = ftable->construct (width, height);
259 gint i;
260
261 for (i = 0; i < n_properties; i++)
262 ftable->set_param_value (instance, &property_cache[i].data, i);
263
264 return instance;
265 }
266
267 gboolean
gst_frei0r_get_property(f0r_instance_t * instance,GstFrei0rFuncTable * ftable,GstFrei0rProperty * properties,gint n_properties,GstFrei0rPropertyValue * property_cache,guint prop_id,GValue * value)268 gst_frei0r_get_property (f0r_instance_t * instance, GstFrei0rFuncTable * ftable,
269 GstFrei0rProperty * properties, gint n_properties,
270 GstFrei0rPropertyValue * property_cache, guint prop_id, GValue * value)
271 {
272 gint i;
273 GstFrei0rProperty *prop = NULL;
274
275 for (i = 0; i < n_properties; i++) {
276 if (properties[i].prop_id <= prop_id &&
277 properties[i].prop_id + properties[i].n_prop_ids > prop_id) {
278 prop = &properties[i];
279 break;
280 }
281 }
282
283 if (!prop)
284 return FALSE;
285
286 switch (prop->info.type) {
287 case F0R_PARAM_BOOL:{
288 gdouble d;
289
290 if (instance)
291 ftable->get_param_value (instance, &d, prop->prop_idx);
292 else
293 d = property_cache[prop->prop_idx].data.b;
294
295 g_value_set_boolean (value, (d < 0.5) ? FALSE : TRUE);
296 break;
297 }
298 case F0R_PARAM_DOUBLE:{
299 gdouble d;
300
301 if (instance)
302 ftable->get_param_value (instance, &d, prop->prop_idx);
303 else
304 d = property_cache[prop->prop_idx].data.d;
305
306 g_value_set_double (value, d);
307 break;
308 }
309 case F0R_PARAM_STRING:{
310 gchar *s;
311
312 if (instance)
313 ftable->get_param_value (instance, &s, prop->prop_idx);
314 else
315 s = property_cache[prop->prop_idx].data.s;
316 g_value_set_string (value, s);
317 break;
318 }
319 case F0R_PARAM_COLOR:{
320 f0r_param_color_t color;
321
322 if (instance)
323 ftable->get_param_value (instance, &color, prop->prop_idx);
324 else
325 color = property_cache[prop->prop_idx].data.color;
326
327 switch (prop_id - prop->prop_id) {
328 case 0:
329 g_value_set_float (value, color.r);
330 break;
331 case 1:
332 g_value_set_float (value, color.g);
333 break;
334 case 2:
335 g_value_set_float (value, color.b);
336 break;
337 }
338 break;
339 }
340 case F0R_PARAM_POSITION:{
341 f0r_param_position_t position;
342
343 if (instance)
344 ftable->get_param_value (instance, &position, prop->prop_idx);
345 else
346 position = property_cache[prop->prop_idx].data.position;
347
348 switch (prop_id - prop->prop_id) {
349 case 0:
350 g_value_set_double (value, position.x);
351 break;
352 case 1:
353 g_value_set_double (value, position.y);
354 break;
355 }
356 break;
357 }
358 default:
359 g_assert_not_reached ();
360 break;
361 }
362
363 return TRUE;
364 }
365
366 gboolean
gst_frei0r_set_property(f0r_instance_t * instance,GstFrei0rFuncTable * ftable,GstFrei0rProperty * properties,gint n_properties,GstFrei0rPropertyValue * property_cache,guint prop_id,const GValue * value)367 gst_frei0r_set_property (f0r_instance_t * instance, GstFrei0rFuncTable * ftable,
368 GstFrei0rProperty * properties, gint n_properties,
369 GstFrei0rPropertyValue * property_cache, guint prop_id,
370 const GValue * value)
371 {
372 GstFrei0rProperty *prop = NULL;
373 gint i;
374
375 for (i = 0; i < n_properties; i++) {
376 if (properties[i].prop_id <= prop_id &&
377 properties[i].prop_id + properties[i].n_prop_ids > prop_id) {
378 prop = &properties[i];
379 break;
380 }
381 }
382
383 if (!prop)
384 return FALSE;
385
386 switch (prop->info.type) {
387 case F0R_PARAM_BOOL:{
388 gboolean b = g_value_get_boolean (value);
389 gdouble d = b ? 1.0 : 0.0;
390
391 if (instance)
392 ftable->set_param_value (instance, &d, prop->prop_idx);
393 property_cache[prop->prop_idx].data.b = d;
394 break;
395 }
396 case F0R_PARAM_DOUBLE:{
397 gdouble d = g_value_get_double (value);
398
399 if (instance)
400 ftable->set_param_value (instance, &d, prop->prop_idx);
401 property_cache[prop->prop_idx].data.d = d;
402 break;
403 }
404 case F0R_PARAM_STRING:{
405 gchar *s = g_value_dup_string (value);
406
407 /* Copies the string */
408 if (instance)
409 ftable->set_param_value (instance, s, prop->prop_idx);
410 property_cache[prop->prop_idx].data.s = s;
411 break;
412 }
413 case F0R_PARAM_COLOR:{
414 gfloat f = g_value_get_float (value);
415 f0r_param_color_t *color = &property_cache[prop->prop_idx].data.color;
416
417 switch (prop_id - prop->prop_id) {
418 case 0:
419 color->r = f;
420 break;
421 case 1:
422 color->g = f;
423 break;
424 case 2:
425 color->b = f;
426 break;
427 default:
428 g_assert_not_reached ();
429 }
430
431 if (instance)
432 ftable->set_param_value (instance, color, prop->prop_idx);
433 break;
434 }
435 case F0R_PARAM_POSITION:{
436 gdouble d = g_value_get_double (value);
437 f0r_param_position_t *position =
438 &property_cache[prop->prop_idx].data.position;
439
440 switch (prop_id - prop->prop_id) {
441 case 0:
442 position->x = d;
443 break;
444 case 1:
445 position->y = d;
446 break;
447 default:
448 g_assert_not_reached ();
449 }
450 if (instance)
451 ftable->set_param_value (instance, position, prop->prop_idx);
452 break;
453 }
454 default:
455 g_assert_not_reached ();
456 break;
457 }
458
459 return TRUE;
460 }
461
462 static gboolean
register_plugin(GstPlugin * plugin,const gchar * vendor,const gchar * filename)463 register_plugin (GstPlugin * plugin, const gchar * vendor,
464 const gchar * filename)
465 {
466 GModule *module;
467 GstFrei0rPluginRegisterReturn ret = GST_FREI0R_PLUGIN_REGISTER_RETURN_FAILED;
468 GstFrei0rFuncTable ftable = { NULL, };
469 gint i;
470 f0r_plugin_info_t info = { NULL, };
471 f0r_instance_t *instance = NULL;
472
473 GST_DEBUG ("Registering plugin '%s'", filename);
474
475 module = g_module_open (filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
476 if (!module) {
477 GST_WARNING ("Failed to load plugin");
478 return FALSE;
479 }
480
481 if (!g_module_symbol (module, "f0r_init", (gpointer *) & ftable.init)) {
482 GST_INFO ("No frei0r plugin");
483 g_module_close (module);
484 return FALSE;
485 }
486
487 if (!g_module_symbol (module, "f0r_deinit", (gpointer *) & ftable.deinit) ||
488 !g_module_symbol (module, "f0r_construct",
489 (gpointer *) & ftable.construct)
490 || !g_module_symbol (module, "f0r_destruct",
491 (gpointer *) & ftable.destruct)
492 || !g_module_symbol (module, "f0r_get_plugin_info",
493 (gpointer *) & ftable.get_plugin_info)
494 || !g_module_symbol (module, "f0r_get_param_info",
495 (gpointer *) & ftable.get_param_info)
496 || !g_module_symbol (module, "f0r_set_param_value",
497 (gpointer *) & ftable.set_param_value)
498 || !g_module_symbol (module, "f0r_get_param_value",
499 (gpointer *) & ftable.get_param_value))
500 goto invalid_frei0r_plugin;
501
502 /* One of these must exist */
503 g_module_symbol (module, "f0r_update", (gpointer *) & ftable.update);
504 g_module_symbol (module, "f0r_update2", (gpointer *) & ftable.update2);
505
506 if (!ftable.init ()) {
507 GST_WARNING ("Failed to initialize plugin");
508 g_module_close (module);
509 return FALSE;
510 }
511
512 if (!ftable.update && !ftable.update2)
513 goto invalid_frei0r_plugin;
514
515 ftable.get_plugin_info (&info);
516
517 if (info.frei0r_version > 1) {
518 GST_WARNING ("Unsupported frei0r version %d", info.frei0r_version);
519 ftable.deinit ();
520 g_module_close (module);
521 return FALSE;
522 }
523
524 if (info.color_model > F0R_COLOR_MODEL_PACKED32) {
525 GST_WARNING ("Unsupported color model %d", info.color_model);
526 ftable.deinit ();
527 g_module_close (module);
528 return FALSE;
529 }
530
531 for (i = 0; i < info.num_params; i++) {
532 f0r_param_info_t pinfo = { NULL, };
533
534 ftable.get_param_info (&pinfo, i);
535 if (pinfo.type > F0R_PARAM_STRING) {
536 GST_WARNING ("Unsupported parameter type %d", pinfo.type);
537 ftable.deinit ();
538 g_module_close (module);
539 return FALSE;
540 }
541 }
542
543 instance = ftable.construct (640, 480);
544 if (!instance) {
545 GST_WARNING ("Failed to instanciate plugin '%s'", info.name);
546 ftable.deinit ();
547 g_module_close (module);
548 return FALSE;
549 }
550 ftable.destruct (instance);
551
552 switch (info.plugin_type) {
553 case F0R_PLUGIN_TYPE_FILTER:
554 ret = gst_frei0r_filter_register (plugin, vendor, &info, &ftable);
555 break;
556 case F0R_PLUGIN_TYPE_SOURCE:
557 ret = gst_frei0r_src_register (plugin, vendor, &info, &ftable);
558 break;
559 case F0R_PLUGIN_TYPE_MIXER2:
560 case F0R_PLUGIN_TYPE_MIXER3:
561 ret = gst_frei0r_mixer_register (plugin, vendor, &info, &ftable);
562 break;
563 default:
564 break;
565 }
566
567 switch (ret) {
568 case GST_FREI0R_PLUGIN_REGISTER_RETURN_OK:
569 return TRUE;
570 case GST_FREI0R_PLUGIN_REGISTER_RETURN_FAILED:
571 GST_ERROR ("Failed to register frei0r plugin");
572 ftable.deinit ();
573 g_module_close (module);
574 return FALSE;
575 case GST_FREI0R_PLUGIN_REGISTER_RETURN_ALREADY_REGISTERED:
576 GST_DEBUG ("frei0r plugin already registered");
577 ftable.deinit ();
578 g_module_close (module);
579 return TRUE;
580 default:
581 g_return_val_if_reached (FALSE);
582 }
583
584 g_return_val_if_reached (FALSE);
585
586 invalid_frei0r_plugin:
587 GST_ERROR ("Invalid frei0r plugin");
588 ftable.deinit ();
589 g_module_close (module);
590
591 return FALSE;
592 }
593
594 static gboolean
register_plugins(GstPlugin * plugin,GHashTable * plugin_names,const gchar * path,const gchar * base_path)595 register_plugins (GstPlugin * plugin, GHashTable * plugin_names,
596 const gchar * path, const gchar * base_path)
597 {
598 GDir *dir;
599 gchar *filename;
600 const gchar *entry_name;
601 gboolean ret = TRUE;
602
603 GST_DEBUG ("Scanning directory '%s' for frei0r plugins", path);
604
605 dir = g_dir_open (path, 0, NULL);
606 if (!dir)
607 return FALSE;
608
609 while ((entry_name = g_dir_read_name (dir))) {
610 gchar *tmp, *vendor = NULL;
611 gchar *hashtable_name;
612
613 tmp = g_strdup (path + strlen (base_path));
614 if (*tmp == G_DIR_SEPARATOR && *(tmp + 1))
615 vendor = tmp + 1;
616 else if (*tmp)
617 vendor = tmp;
618
619 if (vendor)
620 hashtable_name = g_strconcat (vendor, "-", entry_name, NULL);
621 else
622 hashtable_name = g_strdup (entry_name);
623
624 if (g_hash_table_lookup_extended (plugin_names, hashtable_name, NULL, NULL)) {
625 g_free (hashtable_name);
626 continue;
627 }
628
629 filename = g_build_filename (path, entry_name, NULL);
630 if ((g_str_has_suffix (filename, G_MODULE_SUFFIX)
631 #ifdef GST_EXTRA_MODULE_SUFFIX
632 || g_str_has_suffix (filename, GST_EXTRA_MODULE_SUFFIX)
633 #endif
634 ) && g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
635 gboolean this_ret;
636
637 this_ret = register_plugin (plugin, vendor, filename);
638 if (this_ret)
639 g_hash_table_insert (plugin_names, g_strdup (hashtable_name), NULL);
640
641 ret = ret && this_ret;
642 } else if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
643 ret = ret && register_plugins (plugin, plugin_names, filename, base_path);
644 }
645 g_free (filename);
646 g_free (hashtable_name);
647 g_free (tmp);
648 }
649 g_dir_close (dir);
650
651 return ret;
652 }
653
654 static gboolean
plugin_init(GstPlugin * plugin)655 plugin_init (GstPlugin * plugin)
656 {
657 const gchar *homedir;
658 gchar *path, *libdir_path;
659 GHashTable *plugin_names;
660 const gchar *frei0r_path;
661
662 GST_DEBUG_CATEGORY_INIT (frei0r_debug, "frei0r", 0, "frei0r");
663
664 gst_plugin_add_dependency_simple (plugin,
665 "FREI0R_PATH:HOME/.frei0r-1/lib",
666 LIBDIR "/frei0r-1:"
667 "/usr/lib/frei0r-1:/usr/local/lib/frei0r-1:"
668 "/usr/lib32/frei0r-1:/usr/local/lib32/frei0r-1:"
669 "/usr/lib64/frei0r-1:/usr/local/lib64/frei0r-1",
670 NULL, GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
671
672 plugin_names =
673 g_hash_table_new_full ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal,
674 (GDestroyNotify) g_free, NULL);
675
676 frei0r_path = g_getenv ("FREI0R_PATH");
677 if (frei0r_path && *frei0r_path) {
678 gchar **p, **paths = g_strsplit (frei0r_path, ":", -1);
679
680 for (p = paths; *p; p++) {
681 register_plugins (plugin, plugin_names, *p, *p);
682 }
683
684 g_strfreev (paths);
685 } else {
686 #define register_plugins2(plugin, pn, p) register_plugins(plugin, pn, p, p)
687 homedir = g_get_home_dir ();
688 path = g_build_filename (homedir, ".frei0r-1", "lib", NULL);
689 libdir_path = g_build_filename (LIBDIR, "frei0r-1", NULL);
690 register_plugins2 (plugin, plugin_names, path);
691 g_free (path);
692 register_plugins2 (plugin, plugin_names, libdir_path);
693 g_free (libdir_path);
694 register_plugins2 (plugin, plugin_names, "/usr/local/lib/frei0r-1");
695 register_plugins2 (plugin, plugin_names, "/usr/lib/frei0r-1");
696 register_plugins2 (plugin, plugin_names, "/usr/local/lib32/frei0r-1");
697 register_plugins2 (plugin, plugin_names, "/usr/lib32/frei0r-1");
698 register_plugins2 (plugin, plugin_names, "/usr/local/lib64/frei0r-1");
699 register_plugins2 (plugin, plugin_names, "/usr/lib64/frei0r-1");
700 #undef register_plugins2
701 }
702
703 g_hash_table_unref (plugin_names);
704
705 return TRUE;
706 }
707
708 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
709 GST_VERSION_MINOR,
710 frei0r,
711 "frei0r plugin library",
712 plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
713