gstutils.c 14.7 KB
Newer Older
1
2
3
4
/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
5
 * gstutils.c: Utility functions: gtk_get_property stuff, etc.
Erik Walthinsen's avatar
Erik Walthinsen committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

23
#include <stdio.h>
Wim Taymans's avatar
Wim Taymans committed
24
#include <string.h>
25

26
#include "gst_private.h"
27
#include "gstutils.h"
Erik Walthinsen's avatar
Erik Walthinsen committed
28

29
30
#include "gstextratypes.h"

31
32
#define ZERO(mem) memset(&mem, 0, sizeof(mem))

Wim Taymans's avatar
Wim Taymans committed
33
34
35
36
37
/**
 * gst_util_get_int_arg:
 * @object: the object to query
 * @argname: the name of the argument
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
38
 * Retrieves a property of an object as an integer.
Wim Taymans's avatar
Wim Taymans committed
39
40
41
 *
 * Returns: the property of the object
 */
Wim Taymans's avatar
Wim Taymans committed
42
gint
43
gst_util_get_int_arg (GObject * object, const gchar * argname)
Wim Taymans's avatar
Wim Taymans committed
44
{
45
  GValue value;
Erik Walthinsen's avatar
Erik Walthinsen committed
46

47
  ZERO (value);
48
  g_value_init (&value, G_TYPE_INT);
49
  g_object_get_property (G_OBJECT (object), argname, &value);
50

51
  return g_value_get_int (&value);
Erik Walthinsen's avatar
Erik Walthinsen committed
52
53
}

Wim Taymans's avatar
Wim Taymans committed
54
55
56
57
58
/**
 * gst_util_get_bool_arg:
 * @object: the object to query
 * @argname: the name of the argument
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
59
 * Retrieves a property of an object as a boolean.
Wim Taymans's avatar
Wim Taymans committed
60
61
62
 *
 * Returns: the property of the object
 */
Wim Taymans's avatar
Wim Taymans committed
63
gint
64
gst_util_get_bool_arg (GObject * object, const gchar * argname)
Wim Taymans's avatar
Wim Taymans committed
65
{
66
  GValue value;
Wim Taymans's avatar
Wim Taymans committed
67

68
  ZERO (value);
69
  g_value_init (&value, G_TYPE_BOOLEAN);
70
  g_object_get_property (G_OBJECT (object), argname, &value);
71

72
  return g_value_get_boolean (&value);
Wim Taymans's avatar
Wim Taymans committed
73
74
}

Wim Taymans's avatar
Wim Taymans committed
75
76
77
78
79
/**
 * gst_util_get_long_arg:
 * @object: the object to query
 * @argname: the name of the argument
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
80
 * Retrieves a property of an object as a long.
Wim Taymans's avatar
Wim Taymans committed
81
82
83
 *
 * Returns: the property of the object
 */
Wim Taymans's avatar
Wim Taymans committed
84
glong
85
gst_util_get_long_arg (GObject * object, const gchar * argname)
Wim Taymans's avatar
Wim Taymans committed
86
{
87
  GValue value;
Erik Walthinsen's avatar
Erik Walthinsen committed
88

89
  ZERO (value);
90
  g_value_init (&value, G_TYPE_LONG);
91
  g_object_get_property (G_OBJECT (object), argname, &value);
92

93
  return g_value_get_long (&value);
Erik Walthinsen's avatar
Erik Walthinsen committed
94
95
}

96
/**
Wim Taymans's avatar
Wim Taymans committed
97
 * gst_util_get_int64_arg:
98
99
100
 * @object: the object to query
 * @argname: the name of the argument
 *
Wim Taymans's avatar
Wim Taymans committed
101
 * Retrieves a property of an object as an int64.
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
 *
 * Returns: the property of the object
 */
gint64
gst_util_get_int64_arg (GObject *object, const gchar *argname)
{
  GValue value;

  ZERO (value);
  g_value_init (&value, G_TYPE_INT64);
  g_object_get_property (G_OBJECT (object), argname, &value);

  return g_value_get_int64 (&value);
}

Wim Taymans's avatar
Wim Taymans committed
117
118
119
120
121
/**
 * gst_util_get_float_arg:
 * @object: the object to query
 * @argname: the name of the argument
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
122
 * Retrieves a property of an object as a float.
Wim Taymans's avatar
Wim Taymans committed
123
124
125
 *
 * Returns: the property of the object
 */
Wim Taymans's avatar
Wim Taymans committed
126
gfloat
127
gst_util_get_float_arg (GObject * object, const gchar * argname)
Wim Taymans's avatar
Wim Taymans committed
128
{
129
  GValue value;
Erik Walthinsen's avatar
Erik Walthinsen committed
130

131
  ZERO (value);
132
  g_value_init (&value, G_TYPE_FLOAT);
133
  g_object_get_property (G_OBJECT (object), argname, &value);
134

135
  return g_value_get_float (&value);
Erik Walthinsen's avatar
Erik Walthinsen committed
136
137
}

Wim Taymans's avatar
Wim Taymans committed
138
139
140
141
142
/**
 * gst_util_get_double_arg:
 * @object: the object to query
 * @argname: the name of the argument
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
143
 * Retrieves a property of an object as a double.
Wim Taymans's avatar
Wim Taymans committed
144
145
146
 *
 * Returns: the property of the object
 */
147
148
gdouble
gst_util_get_double_arg (GObject * object, const gchar * argname)
Wim Taymans's avatar
Wim Taymans committed
149
{
150
  GValue value;
Erik Walthinsen's avatar
Erik Walthinsen committed
151

152
  ZERO (value);
153
  g_value_init (&value, G_TYPE_DOUBLE);
154
  g_object_get_property (G_OBJECT (object), argname, &value);
155

156
  return g_value_get_double (&value);
Erik Walthinsen's avatar
Erik Walthinsen committed
157
158
}

Wim Taymans's avatar
Wim Taymans committed
159
160
161
162
163
/**
 * gst_util_get_string_arg:
 * @object: the object to query
 * @argname: the name of the argument
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
164
 * Retrieves a property of an object as a string.
Wim Taymans's avatar
Wim Taymans committed
165
166
167
 *
 * Returns: the property of the object
 */
168
169
const gchar *
gst_util_get_string_arg (GObject * object, const gchar * argname)
Wim Taymans's avatar
Wim Taymans committed
170
{
171
  GValue value;
Erik Walthinsen's avatar
Erik Walthinsen committed
172

173
  ZERO (value);
174
  g_value_init (&value, G_TYPE_STRING);
175
  g_object_get_property (G_OBJECT (object), argname, &value);
176

177
  return g_value_get_string (&value);	/* memleak? */
Erik Walthinsen's avatar
Erik Walthinsen committed
178
179
}

Wim Taymans's avatar
Wim Taymans committed
180
181
182
183
184
/**
 * gst_util_get_pointer_arg:
 * @object: the object to query
 * @argname: the name of the argument
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
185
 * Retrieves a property of an object as a pointer.
Wim Taymans's avatar
Wim Taymans committed
186
187
188
 *
 * Returns: the property of the object
 */
Wim Taymans's avatar
Wim Taymans committed
189
gpointer
190
gst_util_get_pointer_arg (GObject * object, const gchar * argname)
Wim Taymans's avatar
Wim Taymans committed
191
{
192
  GValue value;
Erik Walthinsen's avatar
Erik Walthinsen committed
193

194
  ZERO (value);
195
  g_value_init (&value, G_TYPE_POINTER);
196
  g_object_get_property (G_OBJECT (object), argname, &value);
197

198
  return g_value_get_pointer (&value);
Erik Walthinsen's avatar
Erik Walthinsen committed
199
200
}

Wim Taymans's avatar
Wim Taymans committed
201
/**
202
 * gst_util_get_widget_property:
Wim Taymans's avatar
Wim Taymans committed
203
204
205
 * @object: the object to query
 * @argname: the name of the argument
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
206
 * Retrieves a property of an object as a widget.
Wim Taymans's avatar
Wim Taymans committed
207
208
209
 *
 * Returns: the property of the object
 */
210
/* COMMENTED OUT BECAUSE WE HAVE NO MORE gtk.h
Wim Taymans's avatar
Wim Taymans committed
211
GtkWidget*
212
gst_util_get_widget_property (GObject *object, const gchar *argname) 
Wim Taymans's avatar
Wim Taymans committed
213
{
Erik Walthinsen's avatar
Erik Walthinsen committed
214
215
216
  GtkArg arg;

  arg.name = argname;
217
  gtk_object_getv(G_OBJECT(object),1,&arg);
Wim Taymans's avatar
Wim Taymans committed
218
  
219
  return GTK_WIDGET(G_VALUE_OBJECT(arg));
Erik Walthinsen's avatar
Erik Walthinsen committed
220
}
221
*/
222

Wim Taymans's avatar
Wim Taymans committed
223
224
225
226
227
/**
 * gst_util_dump_mem:
 * @mem: a pointer to the memory to dump
 * @size: the size of the memory block to dump
 *
Erik Walthinsen's avatar
Erik Walthinsen committed
228
 * Dumps the memory block into a hex representation. Useful for debugging.
Wim Taymans's avatar
Wim Taymans committed
229
 */
230
231
void
gst_util_dump_mem (guchar * mem, guint size)
Wim Taymans's avatar
Wim Taymans committed
232
{
233
234
  guint i, j;

235
236
  i = j = 0;
  while (i < size) {
237
    if (j == 0) {
238
      g_print ("\n%08x : ", i);
239
      j = 15;
240
241
    }
    else {
242
      j--;
243
    }
244
    g_print ("%02x ", mem[i]);
245
246
    i++;
  }
247
  g_print ("\n");
248
}
249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

/**
 * gst_util_set_value_from_string:
 * @value: the value to set
 * @value_str: the string to get the value from
 *
 * Converts the string to the type of the value and
 * sets the value with it.
 */
void
gst_util_set_value_from_string(GValue *value, const gchar *value_str)
{

	g_return_if_fail(value != NULL);
	g_return_if_fail(value_str != NULL);
	
	GST_DEBUG(GST_CAT_PARAMS, "parsing '%s' to type %s\n", value_str, g_type_name(G_VALUE_TYPE(value)));

	switch (G_VALUE_TYPE(value)) {
		case G_TYPE_STRING:
			g_value_set_string(value, g_strdup(value_str));
			break;
		case G_TYPE_ENUM: 
		case G_TYPE_INT: {
			gint i;
			sscanf (value_str, "%d", &i);
			g_value_set_int(value, i);
			break;
		}
		case G_TYPE_UINT: {
			guint i;
			sscanf (value_str, "%u", &i);
			g_value_set_uint(value, i);
			break;
		}
		case G_TYPE_LONG: {
			glong i;
			sscanf (value_str, "%ld", &i);
			g_value_set_long(value, i);
			break;
		}
		case G_TYPE_ULONG: {
			gulong i;
			sscanf (value_str, "%lu", &i);
			g_value_set_ulong(value, i);
			break;
		}
		case G_TYPE_BOOLEAN: {
			gboolean i = FALSE;
			if (!strncmp ("true", value_str, 4)) i = TRUE;
			g_value_set_boolean(value, i);
			break;
		}
		case G_TYPE_CHAR: {
			gchar i;
			sscanf (value_str, "%c", &i);
			g_value_set_char(value, i);
			break;
		}
		case G_TYPE_UCHAR: {
			guchar i;
			sscanf (value_str, "%c", &i);
			g_value_set_uchar(value, i);
			break;
		}
		case G_TYPE_FLOAT: {
			gfloat i;
			sscanf (value_str, "%f", &i);
			g_value_set_float(value, i);
			break;
		}
		case G_TYPE_DOUBLE: {
			gfloat i;
			sscanf (value_str, "%g", &i);
			g_value_set_double(value, (gdouble)i);
			break;
		}
		default:
	  		break;
	}
}

Wim Taymans's avatar
Wim Taymans committed
332
333
334
335
336
337
338
339
340
341
/**
 * gst_util_set_object_arg:
 * @object: the object to set the argument of
 * @name: the name of the argument to set
 * @value: the string value to set
 *
 * Convertes the string value to the type of the objects argument and
 * sets the argument with it.
 */
void
342
gst_util_set_object_arg (GObject * object, const gchar * name, const gchar * value)
343
344
{
  if (name && value) {
345
    GParamSpec *paramspec;
346

347
    paramspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
348

349
350
    if (!paramspec) {
      return;
351
    }
352

353
    GST_DEBUG (0, "paramspec->flags is %d, paramspec->value_type is %d\n",
354
	       paramspec->flags, (gint) paramspec->value_type);
355
356
357

    if (paramspec->flags & G_PARAM_WRITABLE) {
      switch (paramspec->value_type) {
358
359
360
361
362
363
364
365
366
	case G_TYPE_STRING:
	  g_object_set (G_OBJECT (object), name, value, NULL);
	  break;
	case G_TYPE_ENUM:
	case G_TYPE_INT:{
	  gint i;

	  sscanf (value, "%d", &i);
	  g_object_set (G_OBJECT (object), name, i, NULL);
367
368
	  break;
	}
369
370
371
372
373
	case G_TYPE_UINT:{
	  guint i;

	  sscanf (value, "%u", &i);
	  g_object_set (G_OBJECT (object), name, i, NULL);
374
375
	  break;
	}
376
	case G_TYPE_LONG:{
377
	  glong i;
378

379
	  sscanf (value, "%ld", &i);
380
	  g_object_set (G_OBJECT (object), name, i, NULL);
381
382
	  break;
	}
383
	case G_TYPE_ULONG:{
384
	  gulong i;
385

386
	  sscanf (value, "%lu", &i);
387
	  g_object_set (G_OBJECT (object), name, i, NULL);
388
389
	  break;
	}
390
	case G_TYPE_BOOLEAN:{
391
	  gboolean i = FALSE;
392
393
394
395

	  if (!strncmp ("true", value, 4))
	    i = TRUE;
	  g_object_set (G_OBJECT (object), name, i, NULL);
396
397
	  break;
	}
398
	case G_TYPE_CHAR:{
399
	  gchar i;
400

401
	  sscanf (value, "%c", &i);
402
	  g_object_set (G_OBJECT (object), name, i, NULL);
403
404
	  break;
	}
405
	case G_TYPE_UCHAR:{
406
	  guchar i;
407

408
	  sscanf (value, "%c", &i);
409
	  g_object_set (G_OBJECT (object), name, i, NULL);
410
411
	  break;
	}
412
	case G_TYPE_FLOAT:{
413
	  gfloat i;
414

415
	  sscanf (value, "%f", &i);
416
	  g_object_set (G_OBJECT (object), name, i, NULL);
417
418
	  break;
	}
419
	case G_TYPE_DOUBLE:{
420
	  gfloat i;
421

422
	  sscanf (value, "%g", &i);
423
	  g_object_set (G_OBJECT (object), name, (gdouble) i, NULL);
424
425
	  break;
	}
426
427
428
429
430
431
	default:
	  if (G_IS_PARAM_SPEC_ENUM (paramspec)) {
	    gint i;

	    sscanf (value, "%d", &i);
	    g_object_set (G_OBJECT (object), name, i, NULL);
Wim Taymans's avatar
Wim Taymans committed
432
	  }
433
	  else if (paramspec->value_type == GST_TYPE_FILENAME) {
434
	    g_object_set (G_OBJECT (object), name, value, NULL);
435
436
437
438
439
440
	  }
	  break;
      }
    }
  }
}
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
441

442
443
444
445
446
/* -----------------------------------------------------
 *
 *  The following code will be moved out of the main
 * gstreamer library someday.
 */
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
447
448
449
450
451
452

#include "gstpad.h"
#include "gsttype.h"
#include "gstprops.h"
#include "gstpropsprivate.h"

453
454
static void
string_append_indent (GString * str, gint count)
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
455
456
{
  gint xx;
457
458

  for (xx = 0; xx < count; xx++)
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
459
460
461
    g_string_append_c (str, ' ');
}

462
463
static void
gst_print_props (GString * buf, gint indent, GList * props, gboolean showname)
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
464
465
{
  GList *elem;
466
  guint width = 0;
467

468
  if (showname)
469
470
471
    for (elem = props; elem; elem = g_list_next (elem)) {
      GstPropsEntry *prop = elem->data;
      const gchar *name = g_quark_to_string (prop->propid);
472

473
474
475
      if (width < strlen (name))
	width = strlen (name);
    }
476

477
478
  for (elem = props; elem; elem = g_list_next (elem)) {
    GstPropsEntry *prop = elem->data;
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
479

480
481
482
483
484
485
486
    string_append_indent (buf, indent);
    if (showname) {
      const gchar *name = g_quark_to_string (prop->propid);

      g_string_append (buf, name);
      string_append_indent (buf, 2 + width - strlen (name));
    }
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
487

488
    switch (prop->propstype) {
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
489
      case GST_PROPS_INT_ID:
490
	g_string_append_printf (buf, "%d (int)\n", prop->data.int_data);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
491
492
	break;
      case GST_PROPS_INT_RANGE_ID:
493
	g_string_append_printf (buf, "%d - %d (int)\n",
494
				prop->data.int_range_data.min, prop->data.int_range_data.max);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
495
496
	break;
      case GST_PROPS_FLOAT_ID:
497
	g_string_append_printf (buf, "%f (float)\n", prop->data.float_data);
498
	break;
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
499
      case GST_PROPS_FLOAT_RANGE_ID:
500
	g_string_append_printf (buf, "%f - %f (float)\n",
501
				prop->data.float_range_data.min, prop->data.float_range_data.max);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
502
503
	break;
      case GST_PROPS_BOOL_ID:
504
	g_string_append_printf (buf, "%s\n", prop->data.bool_data ? "TRUE" : "FALSE");
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
505
506
	break;
      case GST_PROPS_STRING_ID:
507
	g_string_append_printf (buf, "\"%s\"\n", prop->data.string_data.string);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
508
509
	break;
      case GST_PROPS_FOURCC_ID:
510
	g_string_append_printf (buf, "'%c%c%c%c' (fourcc)\n",
511
512
513
514
				prop->data.fourcc_data & 0xff,
				prop->data.fourcc_data >> 8 & 0xff,
				prop->data.fourcc_data >> 16 & 0xff,
				prop->data.fourcc_data >> 24 & 0xff);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
515
516
	break;
      case GST_PROPS_LIST_ID:
517
	gst_print_props (buf, indent + 2, prop->data.list_data.entries, FALSE);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
518
519
	break;
      default:
520
	g_string_append_printf (buf, "unknown proptype %d\n", prop->propstype);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
521
	break;
522
    }
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
523
524
525
  }
}

526
527
528
529
530
531
532
533
534
535
536
/**
 * gst_print_pad_caps:
 * @buf: the buffer to print the caps in
 * @indent: initial indentation
 * @pad: the pad to print the caps from
 *
 * Write the pad capabilities in a human readable format into
 * the given GString.
 */
void
gst_print_pad_caps (GString * buf, gint indent, GstPad * pad)
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
537
538
539
540
{
  GstRealPad *realpad;
  GstCaps *caps;

541
  realpad = GST_PAD_REALIZE (pad);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
542
543
  caps = realpad->caps;

544
545
546
547
548
549
  if (!caps) {
    string_append_indent (buf, indent);
    g_string_printf (buf, "%s:%s has no capabilities", GST_DEBUG_PAD_NAME (pad));
  }
  else {
    gint capx = 0;
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
550

551
552
    while (caps) {
      GstType *type;
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
553

554
555
      string_append_indent (buf, indent);
      g_string_append_printf (buf, "Cap[%d]: %s\n", capx++, caps->name);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
556

557
558
559
      type = gst_type_find_by_id (caps->id);
      string_append_indent (buf, indent + 2);
      g_string_append_printf (buf, "MIME type: %s\n", type->mime ? type->mime : "unknown/unknown");
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
560

561
562
      if (caps->properties)
	gst_print_props (buf, indent + 4, caps->properties->properties, TRUE);
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
563

564
      caps = caps->next;
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
565
    }
566
  }
Joshua N. Pritikin's avatar
Joshua N. Pritikin committed
567
}
568

569
570
571
572
573
574
575
576
577
578
579
/**
 * gst_print_element_args:
 * @buf: the buffer to print the args in
 * @indent: initial indentation
 * @element: the element to print the args of
 *
 * Print the element argument in a human readable format in the given
 * GString.
 */
void
gst_print_element_args (GString * buf, gint indent, GstElement * element)
580
581
{
  guint width;
582
583
584
  GValue value = { 0, }; /* the important thing is that value.type = 0 */
  gchar *str = 0;
  GParamSpec *spec, **specs, **walk;
585

586
587
  specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (element), NULL);
  
588
  width = 0;
589
590
591
592
  for (walk = specs; *walk; walk++) {
    spec = *walk;
    if (width < strlen (spec->name))
      width = strlen (spec->name);
593
594
  }

595
596
597
598
599
600
601
602
603
604
  for (walk = specs; *walk; walk++) {
    spec = *walk;
    
    if (spec->flags & G_PARAM_READABLE) {
      g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE (spec));
      g_object_get_property (G_OBJECT (element), spec->name, &value);
      str = g_strdup_value_contents (&value);
      g_value_unset(&value);
    } else {
      str = g_strdup ("Parameter not readable.");
605
    }
606

607
608
609
610
    string_append_indent (buf, indent);
    g_string_append (buf, spec->name);
    string_append_indent (buf, 2 + width - strlen (spec->name));
    g_string_append (buf, str);
611
    g_string_append_c (buf, '\n');
612
613
    
    g_free (str);
614
  }
615
616

  g_free (specs);
617
}
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

/**
 * gst_util_has_arg:
 * @object: an object
 * @argname: a property it might have
 * @arg_type: the type of the argument it should have
 * 
 * Determines whether this @object has a property of name
 * @argname and of type @arg_type
 * 
 * Return value: TRUE if it has the prop, else FALSE
 **/
gboolean
gst_util_has_arg (GObject *object, const gchar *argname, GType arg_type)
{
  GParamSpec *pspec;

  pspec = g_object_class_find_property (
	  G_OBJECT_GET_CLASS (object), argname);

  if (!pspec)
    return FALSE;

  if (pspec->value_type != arg_type)
    return FALSE;

  return TRUE;
}