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 GST_PARAM_DOC_SHOW_DEFAULT));
108 properties[i].n_prop_ids = 1;
109 break;
110 case F0R_PARAM_DOUBLE:{
111 gdouble def = properties[i].default_value.data.d;
112
113 /* If the default is NAN, +-INF we use 0.0 */
114 if (!(def >= 0.0 && def <= 1.0))
115 def = 0.0;
116
117 g_object_class_install_property (gobject_class, count++,
118 g_param_spec_double (prop_name, param_info->name,
119 param_info->explanation, 0.0, 1.0, def,
120 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
121 GST_PARAM_DOC_SHOW_DEFAULT));
122 properties[i].n_prop_ids = 1;
123 break;
124 }
125 case F0R_PARAM_STRING:
126 g_object_class_install_property (gobject_class, count++,
127 g_param_spec_string (prop_name, param_info->name,
128 param_info->explanation, properties[i].default_value.data.s,
129 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
130 GST_PARAM_DOC_SHOW_DEFAULT));
131 properties[i].n_prop_ids = 1;
132 break;
133 case F0R_PARAM_COLOR:{
134 gchar *prop_name_full;
135 gchar *prop_nick_full;
136 gdouble def;
137
138 def = properties[i].default_value.data.color.r;
139 /* If the default is out of range we use 0.0 */
140 if (!(def <= 1.0 && def >= 0.0))
141 def = 0.0;
142 prop_name_full = g_strconcat (prop_name, "-r", NULL);
143 prop_nick_full = g_strconcat (param_info->name, " (R)", NULL);
144 g_object_class_install_property (gobject_class, count++,
145 g_param_spec_float (prop_name_full, prop_nick_full,
146 param_info->explanation, 0.0, 1.0, def,
147 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
148 GST_PARAM_DOC_SHOW_DEFAULT));
149 g_free (prop_name_full);
150 g_free (prop_nick_full);
151
152 def = properties[i].default_value.data.color.g;
153 /* If the default is out of range we use 0.0 */
154 if (!(def <= 1.0 && def >= 0.0))
155 def = 0.0;
156 prop_name_full = g_strconcat (prop_name, "-g", NULL);
157 prop_nick_full = g_strconcat (param_info->name, " (G)", NULL);
158 g_object_class_install_property (gobject_class, count++,
159 g_param_spec_float (prop_name_full, prop_nick_full,
160 param_info->explanation, 0.0, 1.0, def,
161 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
162 GST_PARAM_DOC_SHOW_DEFAULT));
163 g_free (prop_name_full);
164 g_free (prop_nick_full);
165
166 def = properties[i].default_value.data.color.b;
167 /* If the default is out of range we use 0.0 */
168 if (!(def <= 1.0 && def >= 0.0))
169 def = 0.0;
170 prop_name_full = g_strconcat (prop_name, "-b", NULL);
171 prop_nick_full = g_strconcat (param_info->name, " (B)", NULL);
172 g_object_class_install_property (gobject_class, count++,
173 g_param_spec_float (prop_name_full, prop_nick_full,
174 param_info->explanation, 0.0, 1.0, def,
175 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
176 GST_PARAM_DOC_SHOW_DEFAULT));
177 g_free (prop_name_full);
178 g_free (prop_nick_full);
179
180 properties[i].n_prop_ids = 3;
181 break;
182 }
183 case F0R_PARAM_POSITION:{
184 gchar *prop_name_full;
185 gchar *prop_nick_full;
186 gdouble def;
187
188 def = properties[i].default_value.data.position.x;
189 /* If the default is out of range we use 0.0 */
190 if (!(def <= 1.0 && def >= 0.0))
191 def = 0.0;
192 prop_name_full = g_strconcat (prop_name, "-x", NULL);
193 prop_nick_full = g_strconcat (param_info->name, " (X)", NULL);
194 g_object_class_install_property (gobject_class, count++,
195 g_param_spec_double (prop_name_full, prop_nick_full,
196 param_info->explanation, 0.0, 1.0, def,
197 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
198 GST_PARAM_DOC_SHOW_DEFAULT));
199 g_free (prop_name_full);
200 g_free (prop_nick_full);
201
202 def = properties[i].default_value.data.position.y;
203 /* If the default is out of range we use 0.0 */
204 if (!(def <= 1.0 && def >= 0.0))
205 def = 0.0;
206 prop_name_full = g_strconcat (prop_name, "-Y", NULL);
207 prop_nick_full = g_strconcat (param_info->name, " (Y)", NULL);
208 g_object_class_install_property (gobject_class, count++,
209 g_param_spec_double (prop_name_full, prop_nick_full,
210 param_info->explanation, 0.0, 1.0, def,
211 G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE |
212 GST_PARAM_DOC_SHOW_DEFAULT));
213 g_free (prop_name_full);
214 g_free (prop_nick_full);
215
216 properties[i].n_prop_ids = 2;
217 break;
218 }
219 default:
220 g_assert_not_reached ();
221 break;
222 }
223
224 g_free (prop_name);
225 }
226
227 ftable->destruct (instance);
228 }
229
230 GstFrei0rPropertyValue *
gst_frei0r_property_cache_init(GstFrei0rProperty * properties,gint n_properties)231 gst_frei0r_property_cache_init (GstFrei0rProperty * properties,
232 gint n_properties)
233 {
234 gint i;
235 GstFrei0rPropertyValue *ret = g_new0 (GstFrei0rPropertyValue, n_properties);
236
237 for (i = 0; i < n_properties; i++) {
238 memcpy (&ret[i].data, &properties[i].default_value,
239 sizeof (GstFrei0rPropertyValue));
240
241 if (properties[i].info.type == F0R_PARAM_STRING)
242 ret[i].data.s = g_strdup (ret[i].data.s);
243 }
244
245 return ret;
246 }
247
248 void
gst_frei0r_property_cache_free(GstFrei0rProperty * properties,GstFrei0rPropertyValue * property_cache,gint n_properties)249 gst_frei0r_property_cache_free (GstFrei0rProperty * properties,
250 GstFrei0rPropertyValue * property_cache, gint n_properties)
251 {
252 gint i;
253
254 for (i = 0; i < n_properties; i++) {
255 if (properties[i].info.type == F0R_PARAM_STRING)
256 g_free (property_cache[i].data.s);
257 }
258 g_free (property_cache);
259 }
260
261 f0r_instance_t *
gst_frei0r_instance_construct(GstFrei0rFuncTable * ftable,GstFrei0rProperty * properties,gint n_properties,GstFrei0rPropertyValue * property_cache,gint width,gint height)262 gst_frei0r_instance_construct (GstFrei0rFuncTable * ftable,
263 GstFrei0rProperty * properties, gint n_properties,
264 GstFrei0rPropertyValue * property_cache, gint width, gint height)
265 {
266 f0r_instance_t *instance = ftable->construct (width, height);
267 gint i;
268
269 for (i = 0; i < n_properties; i++)
270 ftable->set_param_value (instance, &property_cache[i].data, i);
271
272 return instance;
273 }
274
275 gboolean
gst_frei0r_get_property(f0r_instance_t * instance,GstFrei0rFuncTable * ftable,GstFrei0rProperty * properties,gint n_properties,GstFrei0rPropertyValue * property_cache,guint prop_id,GValue * value)276 gst_frei0r_get_property (f0r_instance_t * instance, GstFrei0rFuncTable * ftable,
277 GstFrei0rProperty * properties, gint n_properties,
278 GstFrei0rPropertyValue * property_cache, guint prop_id, GValue * value)
279 {
280 gint i;
281 GstFrei0rProperty *prop = NULL;
282
283 for (i = 0; i < n_properties; i++) {
284 if (properties[i].prop_id <= prop_id &&
285 properties[i].prop_id + properties[i].n_prop_ids > prop_id) {
286 prop = &properties[i];
287 break;
288 }
289 }
290
291 if (!prop)
292 return FALSE;
293
294 switch (prop->info.type) {
295 case F0R_PARAM_BOOL:{
296 gdouble d;
297
298 if (instance)
299 ftable->get_param_value (instance, &d, prop->prop_idx);
300 else
301 d = property_cache[prop->prop_idx].data.b;
302
303 g_value_set_boolean (value, (d < 0.5) ? FALSE : TRUE);
304 break;
305 }
306 case F0R_PARAM_DOUBLE:{
307 gdouble d;
308
309 if (instance)
310 ftable->get_param_value (instance, &d, prop->prop_idx);
311 else
312 d = property_cache[prop->prop_idx].data.d;
313
314 g_value_set_double (value, d);
315 break;
316 }
317 case F0R_PARAM_STRING:{
318 gchar *s;
319
320 if (instance)
321 ftable->get_param_value (instance, &s, prop->prop_idx);
322 else
323 s = property_cache[prop->prop_idx].data.s;
324 g_value_set_string (value, s);
325 break;
326 }
327 case F0R_PARAM_COLOR:{
328 f0r_param_color_t color;
329
330 if (instance)
331 ftable->get_param_value (instance, &color, prop->prop_idx);
332 else
333 color = property_cache[prop->prop_idx].data.color;
334
335 switch (prop_id - prop->prop_id) {
336 case 0:
337 g_value_set_float (value, color.r);
338 break;
339 case 1:
340 g_value_set_float (value, color.g);
341 break;
342 case 2:
343 g_value_set_float (value, color.b);
344 break;
345 }
346 break;
347 }
348 case F0R_PARAM_POSITION:{
349 f0r_param_position_t position;
350
351 if (instance)
352 ftable->get_param_value (instance, &position, prop->prop_idx);
353 else
354 position = property_cache[prop->prop_idx].data.position;
355
356 switch (prop_id - prop->prop_id) {
357 case 0:
358 g_value_set_double (value, position.x);
359 break;
360 case 1:
361 g_value_set_double (value, position.y);
362 break;
363 }
364 break;
365 }
366 default:
367 g_assert_not_reached ();
368 break;
369 }
370
371 return TRUE;
372 }
373
374 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)375 gst_frei0r_set_property (f0r_instance_t * instance, GstFrei0rFuncTable * ftable,
376 GstFrei0rProperty * properties, gint n_properties,
377 GstFrei0rPropertyValue * property_cache, guint prop_id,
378 const GValue * value)
379 {
380 GstFrei0rProperty *prop = NULL;
381 gint i;
382
383 for (i = 0; i < n_properties; i++) {
384 if (properties[i].prop_id <= prop_id &&
385 properties[i].prop_id + properties[i].n_prop_ids > prop_id) {
386 prop = &properties[i];
387 break;
388 }
389 }
390
391 if (!prop)
392 return FALSE;
393
394 switch (prop->info.type) {
395 case F0R_PARAM_BOOL:{
396 gboolean b = g_value_get_boolean (value);
397 gdouble d = b ? 1.0 : 0.0;
398
399 if (instance)
400 ftable->set_param_value (instance, &d, prop->prop_idx);
401 property_cache[prop->prop_idx].data.b = d;
402 break;
403 }
404 case F0R_PARAM_DOUBLE:{
405 gdouble d = g_value_get_double (value);
406
407 if (instance)
408 ftable->set_param_value (instance, &d, prop->prop_idx);
409 property_cache[prop->prop_idx].data.d = d;
410 break;
411 }
412 case F0R_PARAM_STRING:{
413 gchar *s = g_value_dup_string (value);
414
415 /* Copies the string */
416 if (instance)
417 ftable->set_param_value (instance, s, prop->prop_idx);
418 property_cache[prop->prop_idx].data.s = s;
419 break;
420 }
421 case F0R_PARAM_COLOR:{
422 gfloat f = g_value_get_float (value);
423 f0r_param_color_t *color = &property_cache[prop->prop_idx].data.color;
424
425 switch (prop_id - prop->prop_id) {
426 case 0:
427 color->r = f;
428 break;
429 case 1:
430 color->g = f;
431 break;
432 case 2:
433 color->b = f;
434 break;
435 default:
436 g_assert_not_reached ();
437 }
438
439 if (instance)
440 ftable->set_param_value (instance, color, prop->prop_idx);
441 break;
442 }
443 case F0R_PARAM_POSITION:{
444 gdouble d = g_value_get_double (value);
445 f0r_param_position_t *position =
446 &property_cache[prop->prop_idx].data.position;
447
448 switch (prop_id - prop->prop_id) {
449 case 0:
450 position->x = d;
451 break;
452 case 1:
453 position->y = d;
454 break;
455 default:
456 g_assert_not_reached ();
457 }
458 if (instance)
459 ftable->set_param_value (instance, position, prop->prop_idx);
460 break;
461 }
462 default:
463 g_assert_not_reached ();
464 break;
465 }
466
467 return TRUE;
468 }
469
470 static gboolean
register_plugin(GstPlugin * plugin,const gchar * vendor,const gchar * filename)471 register_plugin (GstPlugin * plugin, const gchar * vendor,
472 const gchar * filename)
473 {
474 GModule *module;
475 GstFrei0rPluginRegisterReturn ret = GST_FREI0R_PLUGIN_REGISTER_RETURN_FAILED;
476 GstFrei0rFuncTable ftable = { NULL, };
477 gint i;
478 f0r_plugin_info_t info = { NULL, };
479 f0r_instance_t *instance = NULL;
480
481 GST_DEBUG ("Registering plugin '%s'", filename);
482
483 module = g_module_open (filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
484 if (!module) {
485 GST_WARNING ("Failed to load plugin");
486 return FALSE;
487 }
488
489 if (!g_module_symbol (module, "f0r_init", (gpointer *) & ftable.init)) {
490 GST_INFO ("No frei0r plugin");
491 g_module_close (module);
492 return FALSE;
493 }
494
495 if (!g_module_symbol (module, "f0r_deinit", (gpointer *) & ftable.deinit) ||
496 !g_module_symbol (module, "f0r_construct",
497 (gpointer *) & ftable.construct)
498 || !g_module_symbol (module, "f0r_destruct",
499 (gpointer *) & ftable.destruct)
500 || !g_module_symbol (module, "f0r_get_plugin_info",
501 (gpointer *) & ftable.get_plugin_info)
502 || !g_module_symbol (module, "f0r_get_param_info",
503 (gpointer *) & ftable.get_param_info)
504 || !g_module_symbol (module, "f0r_set_param_value",
505 (gpointer *) & ftable.set_param_value)
506 || !g_module_symbol (module, "f0r_get_param_value",
507 (gpointer *) & ftable.get_param_value))
508 goto invalid_frei0r_plugin;
509
510 /* One of these must exist */
511 g_module_symbol (module, "f0r_update", (gpointer *) & ftable.update);
512 g_module_symbol (module, "f0r_update2", (gpointer *) & ftable.update2);
513
514 if (!ftable.init ()) {
515 GST_WARNING ("Failed to initialize plugin");
516 g_module_close (module);
517 return FALSE;
518 }
519
520 if (!ftable.update && !ftable.update2)
521 goto invalid_frei0r_plugin;
522
523 ftable.get_plugin_info (&info);
524
525 if (info.frei0r_version > 1) {
526 GST_WARNING ("Unsupported frei0r version %d", info.frei0r_version);
527 ftable.deinit ();
528 g_module_close (module);
529 return FALSE;
530 }
531
532 if (info.color_model > F0R_COLOR_MODEL_PACKED32) {
533 GST_WARNING ("Unsupported color model %d", info.color_model);
534 ftable.deinit ();
535 g_module_close (module);
536 return FALSE;
537 }
538
539 for (i = 0; i < info.num_params; i++) {
540 f0r_param_info_t pinfo = { NULL, };
541
542 ftable.get_param_info (&pinfo, i);
543 if (pinfo.type > F0R_PARAM_STRING) {
544 GST_WARNING ("Unsupported parameter type %d", pinfo.type);
545 ftable.deinit ();
546 g_module_close (module);
547 return FALSE;
548 }
549 }
550
551 instance = ftable.construct (640, 480);
552 if (!instance) {
553 GST_WARNING ("Failed to instantiate plugin '%s'", info.name);
554 ftable.deinit ();
555 g_module_close (module);
556 return FALSE;
557 }
558 ftable.destruct (instance);
559
560 switch (info.plugin_type) {
561 case F0R_PLUGIN_TYPE_FILTER:
562 ret = gst_frei0r_filter_register (plugin, vendor, &info, &ftable);
563 break;
564 case F0R_PLUGIN_TYPE_SOURCE:
565 ret = gst_frei0r_src_register (plugin, vendor, &info, &ftable);
566 break;
567 case F0R_PLUGIN_TYPE_MIXER2:
568 case F0R_PLUGIN_TYPE_MIXER3:
569 ret = gst_frei0r_mixer_register (plugin, vendor, &info, &ftable);
570 break;
571 default:
572 break;
573 }
574
575 switch (ret) {
576 case GST_FREI0R_PLUGIN_REGISTER_RETURN_OK:
577 return TRUE;
578 case GST_FREI0R_PLUGIN_REGISTER_RETURN_FAILED:
579 GST_ERROR ("Failed to register frei0r plugin");
580 ftable.deinit ();
581 g_module_close (module);
582 return FALSE;
583 case GST_FREI0R_PLUGIN_REGISTER_RETURN_ALREADY_REGISTERED:
584 GST_DEBUG ("frei0r plugin already registered");
585 ftable.deinit ();
586 g_module_close (module);
587 return TRUE;
588 default:
589 g_return_val_if_reached (FALSE);
590 }
591
592 g_return_val_if_reached (FALSE);
593
594 invalid_frei0r_plugin:
595 GST_ERROR ("Invalid frei0r plugin");
596 ftable.deinit ();
597 g_module_close (module);
598
599 return FALSE;
600 }
601
602 static gboolean
register_plugins(GstPlugin * plugin,GHashTable * plugin_names,const gchar * path,const gchar * base_path)603 register_plugins (GstPlugin * plugin, GHashTable * plugin_names,
604 const gchar * path, const gchar * base_path)
605 {
606 GDir *dir;
607 gchar *filename;
608 const gchar *entry_name;
609 gboolean ret = TRUE;
610
611 GST_DEBUG ("Scanning directory '%s' for frei0r plugins", path);
612
613 dir = g_dir_open (path, 0, NULL);
614 if (!dir)
615 return FALSE;
616
617 while ((entry_name = g_dir_read_name (dir))) {
618 gchar *tmp, *vendor = NULL;
619 gchar *hashtable_name;
620
621 tmp = g_strdup (path + strlen (base_path));
622 if (*tmp == G_DIR_SEPARATOR && *(tmp + 1))
623 vendor = tmp + 1;
624 else if (*tmp)
625 vendor = tmp;
626
627 if (vendor)
628 hashtable_name = g_strconcat (vendor, "-", entry_name, NULL);
629 else
630 hashtable_name = g_strdup (entry_name);
631
632 if (g_hash_table_lookup_extended (plugin_names, hashtable_name, NULL, NULL)) {
633 g_free (hashtable_name);
634 continue;
635 }
636
637 filename = g_build_filename (path, entry_name, NULL);
638 if ((g_str_has_suffix (filename, G_MODULE_SUFFIX)
639 #ifdef GST_EXTRA_MODULE_SUFFIX
640 || g_str_has_suffix (filename, GST_EXTRA_MODULE_SUFFIX)
641 #endif
642 ) && g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
643 gboolean this_ret;
644
645 this_ret = register_plugin (plugin, vendor, filename);
646 if (this_ret)
647 g_hash_table_insert (plugin_names, g_strdup (hashtable_name), NULL);
648
649 ret = ret && this_ret;
650 } else if (g_file_test (filename, G_FILE_TEST_IS_DIR)) {
651 ret = ret && register_plugins (plugin, plugin_names, filename, base_path);
652 }
653 g_free (filename);
654 g_free (hashtable_name);
655 g_free (tmp);
656 }
657 g_dir_close (dir);
658
659 return ret;
660 }
661
662 static gboolean
plugin_init(GstPlugin * plugin)663 plugin_init (GstPlugin * plugin)
664 {
665 const gchar *homedir;
666 gchar *path, *libdir_path;
667 GHashTable *plugin_names;
668 const gchar *frei0r_path;
669
670 GST_DEBUG_CATEGORY_INIT (frei0r_debug, "frei0r", 0, "frei0r");
671
672 gst_plugin_add_dependency_simple (plugin,
673 "FREI0R_PATH:HOME/.frei0r-1/lib",
674 LIBDIR "/frei0r-1:"
675 "/usr/lib/frei0r-1:/usr/local/lib/frei0r-1:"
676 "/usr/lib32/frei0r-1:/usr/local/lib32/frei0r-1:"
677 "/usr/lib64/frei0r-1:/usr/local/lib64/frei0r-1",
678 NULL, GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
679
680 plugin_names =
681 g_hash_table_new_full ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal,
682 (GDestroyNotify) g_free, NULL);
683
684 frei0r_path = g_getenv ("FREI0R_PATH");
685 if (frei0r_path && *frei0r_path) {
686 gchar **p, **paths = g_strsplit (frei0r_path, ":", -1);
687
688 for (p = paths; *p; p++) {
689 register_plugins (plugin, plugin_names, *p, *p);
690 }
691
692 g_strfreev (paths);
693 } else {
694 #define register_plugins2(plugin, pn, p) register_plugins(plugin, pn, p, p)
695 homedir = g_get_home_dir ();
696 path = g_build_filename (homedir, ".frei0r-1", "lib", NULL);
697 libdir_path = g_build_filename (LIBDIR, "frei0r-1", NULL);
698 register_plugins2 (plugin, plugin_names, path);
699 g_free (path);
700 register_plugins2 (plugin, plugin_names, libdir_path);
701 g_free (libdir_path);
702 register_plugins2 (plugin, plugin_names, "/usr/local/lib/frei0r-1");
703 register_plugins2 (plugin, plugin_names, "/usr/lib/frei0r-1");
704 register_plugins2 (plugin, plugin_names, "/usr/local/lib32/frei0r-1");
705 register_plugins2 (plugin, plugin_names, "/usr/lib32/frei0r-1");
706 register_plugins2 (plugin, plugin_names, "/usr/local/lib64/frei0r-1");
707 register_plugins2 (plugin, plugin_names, "/usr/lib64/frei0r-1");
708 #undef register_plugins2
709 }
710
711 g_hash_table_unref (plugin_names);
712
713 return TRUE;
714 }
715
716 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
717 GST_VERSION_MINOR,
718 frei0r,
719 "frei0r plugin library",
720 plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
721