2 * Copyright (C) 2003 David A. Schleef <ds@schleef.org>
4 * gststructure.c: lists of { GQuark, GValue } tuples
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
28 #include "gst_private.h"
30 #include <gobject/gvaluecollector.h>
32 typedef struct _GstStructureField GstStructureField;
34 struct _GstStructureField
40 #define GST_STRUCTURE_FIELD(structure, index) \
41 &g_array_index((structure)->fields, GstStructureField, (index))
43 #define IS_MUTABLE(structure) \
44 (!(structure)->parent_refcount || \
45 gst_atomic_int_read ((structure)->parent_refcount) == 1)
47 static void gst_structure_set_field (GstStructure * structure,
48 GstStructureField * field);
49 static GstStructureField *gst_structure_get_field (const GstStructure *
50 structure, const gchar * fieldname);
51 static GstStructureField *gst_structure_id_get_field (const GstStructure *
52 structure, GQuark field);
53 static void gst_structure_transform_to_string (const GValue * src_value,
55 static GstStructure *gst_structure_copy_conditional (const GstStructure *
57 static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
58 GValue * value, GType default_type);
59 static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
62 gst_structure_get_type (void)
64 static GType gst_structure_type;
66 if (!gst_structure_type) {
67 gst_structure_type = g_boxed_type_register_static ("GstStructure",
68 (GBoxedCopyFunc) gst_structure_copy_conditional,
69 (GBoxedFreeFunc) gst_structure_free);
71 g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
72 gst_structure_transform_to_string);
75 return gst_structure_type;
79 gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc)
81 GstStructure *structure;
83 structure = g_new0 (GstStructure, 1);
84 structure->type = gst_structure_get_type ();
85 structure->name = quark;
87 g_array_sized_new (FALSE, TRUE, sizeof (GstStructureField), prealloc);
93 * gst_structure_id_empty_new:
94 * @quark: name of new structure
96 * Creates a new, empty #GstStructure with the given name.
98 * Returns: a new, empty #GstStructure
101 gst_structure_id_empty_new (GQuark quark)
103 g_return_val_if_fail (quark != 0, NULL);
105 return gst_structure_id_empty_new_with_size (quark, 0);
109 * gst_structure_empty_new:
110 * @name: name of new structure
112 * Creates a new, empty #GstStructure with the given name.
114 * Returns: a new, empty #GstStructure
117 gst_structure_empty_new (const gchar * name)
119 g_return_val_if_fail (name != NULL, NULL);
121 return gst_structure_id_empty_new_with_size (g_quark_from_string (name), 0);
126 * @name: name of new structure
127 * @firstfield: name of first field to set
128 * @...: additional arguments
130 * Creates a new #GstStructure with the given name. Parses the
131 * list of variable arguments and sets fields to the values listed.
132 * Variable arguments should be passed as field name, field type,
133 * and value. Last variable argument should be NULL.
135 * Returns: a new #GstStructure
138 gst_structure_new (const gchar * name, const gchar * firstfield, ...)
140 GstStructure *structure;
143 g_return_val_if_fail (name != NULL, NULL);
145 va_start (varargs, firstfield);
147 structure = gst_structure_new_valist (name, firstfield, varargs);
155 * gst_structure_new_valist:
156 * @name: name of new structure
157 * @firstfield: name of first field to set
158 * @varargs: variable argument list
160 * Creates a new #GstStructure with the given name. Structure fields
161 * are set according to the varargs in a manner similar to
162 * @gst_structure_new.
164 * Returns: a new #GstStructure
167 gst_structure_new_valist (const gchar * name,
168 const gchar * firstfield, va_list varargs)
170 GstStructure *structure;
172 g_return_val_if_fail (name != NULL, NULL);
174 structure = gst_structure_empty_new (name);
175 gst_structure_set_valist (structure, firstfield, varargs);
181 * gst_structure_set_parent_refcount:
182 * @structure: a #GstStructure
183 * @refcount: a pointer to the parent's #GstAtomicInt refcount
185 * Sets the parent_refcount field of #GstStructure. This field is used to
186 * determine whether a structure is mutable or not. This function should only be
187 * called by code implementing parent objects of GstStructure, as described in
188 * the MT Refcounting section of the design documents.
190 * Returns: a new #GstStructure.
193 gst_structure_set_parent_refcount (GstStructure * structure,
194 GstAtomicInt * refcount)
196 if (structure->parent_refcount)
197 g_return_if_fail (refcount == NULL);
199 g_return_if_fail (refcount != NULL);
201 structure->parent_refcount = refcount;
205 * gst_structure_copy:
206 * @structure: a #GstStructure to duplicate
208 * Duplicates a #GstStructure and all its fields and values.
210 * Returns: a new #GstStructure.
213 gst_structure_copy (const GstStructure * structure)
215 GstStructure *new_structure;
216 GstStructureField *field;
219 g_return_val_if_fail (structure != NULL, NULL);
222 gst_structure_id_empty_new_with_size (structure->name,
223 structure->fields->len);
225 for (i = 0; i < structure->fields->len; i++) {
226 GstStructureField new_field = { 0 };
228 field = GST_STRUCTURE_FIELD (structure, i);
230 new_field.name = field->name;
231 gst_value_init_and_copy (&new_field.value, &field->value);
232 g_array_append_val (new_structure->fields, new_field);
235 return new_structure;
239 * gst_structure_free:
240 * @structure: the #GstStructure to free
242 * Frees a #GstStructure and all its fields and values. The structure must not
243 * parent when this function is called.
246 gst_structure_free (GstStructure * structure)
248 GstStructureField *field;
251 g_return_if_fail (structure != NULL);
252 g_return_if_fail (structure->parent_refcount == NULL);
254 for (i = 0; i < structure->fields->len; i++) {
255 field = GST_STRUCTURE_FIELD (structure, i);
257 if (G_IS_VALUE (&field->value)) {
258 g_value_unset (&field->value);
261 g_array_free (structure->fields, TRUE);
263 memset (structure, 0xff, sizeof (GstStructure));
269 * gst_structure_get_name:
270 * @structure: a #GstStructure
274 * Returns: the name of the structure.
277 gst_structure_get_name (const GstStructure * structure)
279 g_return_val_if_fail (structure != NULL, NULL);
281 return g_quark_to_string (structure->name);
285 * gst_structure_get_name:
286 * @structure: a #GstStructure
290 * Returns: the quark representing the name of the structure.
293 gst_structure_get_name_id (const GstStructure * structure)
295 g_return_val_if_fail (structure != NULL, 0);
297 return structure->name;
301 * gst_structure_set_name:
302 * @structure: a #GstStructure
303 * @name: the new name of the structure
305 * Sets the name of the structure to the given name. The string
306 * provided is copied before being used.
309 gst_structure_set_name (GstStructure * structure, const gchar * name)
311 g_return_if_fail (structure != NULL);
312 g_return_if_fail (name != NULL);
313 g_return_if_fail (IS_MUTABLE (structure));
315 structure->name = g_quark_from_string (name);
319 * gst_structure_id_set_value:
320 * @structure: a #GstStructure
321 * @field: a #GQuark representing a field
322 * @value: the new value of the field
324 * Sets the field with the given ID to the provided value. If the field
325 * does not exist, it is created. If the field exists, the previous
329 gst_structure_id_set_value (GstStructure * structure,
330 GQuark field, const GValue * value)
332 GstStructureField gsfield = { 0, {0,} };
334 g_return_if_fail (structure != NULL);
335 g_return_if_fail (G_IS_VALUE (value));
336 g_return_if_fail (IS_MUTABLE (structure));
338 gsfield.name = field;
339 gst_value_init_and_copy (&gsfield.value, value);
341 gst_structure_set_field (structure, &gsfield);
345 * gst_structure_set_value:
346 * @structure: a #GstStructure
347 * @fieldname: the name of the field to set
348 * @value: the new value of the field
350 * Sets the field with the given name to the provided value. If the field
351 * does not exist, it is created. If the field exists, the previous
355 gst_structure_set_value (GstStructure * structure,
356 const gchar * fieldname, const GValue * value)
358 g_return_if_fail (structure != NULL);
359 g_return_if_fail (fieldname != NULL);
360 g_return_if_fail (G_IS_VALUE (value));
361 g_return_if_fail (IS_MUTABLE (structure));
363 gst_structure_id_set_value (structure, g_quark_from_string (fieldname),
369 * @structure: a #GstStructure
370 * @fieldname: the name of the field to set
371 * @...: variable arguments
373 * Parses the variable arguments and sets fields accordingly.
374 * Variable arguments should be in the form field name, field type
375 * (as a GType), value. The last variable argument should be NULL.
378 gst_structure_set (GstStructure * structure, const gchar * field, ...)
382 g_return_if_fail (structure != NULL);
384 va_start (varargs, field);
386 gst_structure_set_valist (structure, field, varargs);
392 * gst_structure_set_valist:
393 * @structure: a #GstStructure
394 * @fieldname: the name of the field to set
395 * @varargs: variable arguments
397 * va_list form of #gst_structure_set.
400 gst_structure_set_valist (GstStructure * structure,
401 const gchar * fieldname, va_list varargs)
408 g_return_if_fail (structure != NULL);
409 g_return_if_fail (IS_MUTABLE (structure));
412 GstStructureField field = { 0 };
414 field.name = g_quark_from_string (fieldname);
416 type = va_arg (varargs, GType);
420 i = va_arg (varargs, int);
422 g_value_init (&field.value, G_TYPE_INT);
423 g_value_set_int (&field.value, i);
426 d = va_arg (varargs, double);
428 g_value_init (&field.value, G_TYPE_DOUBLE);
429 g_value_set_double (&field.value, d);
432 i = va_arg (varargs, int);
434 g_value_init (&field.value, G_TYPE_BOOLEAN);
435 g_value_set_boolean (&field.value, i);
438 s = va_arg (varargs, char *);
440 g_value_init (&field.value, G_TYPE_STRING);
441 g_value_set_string (&field.value, s);
444 if (type == GST_TYPE_FOURCC) {
445 i = va_arg (varargs, int);
447 g_value_init (&field.value, GST_TYPE_FOURCC);
448 gst_value_set_fourcc (&field.value, i);
449 } else if (type == GST_TYPE_INT_RANGE) {
451 min = va_arg (varargs, int);
452 max = va_arg (varargs, int);
454 g_value_init (&field.value, GST_TYPE_INT_RANGE);
455 gst_value_set_int_range (&field.value, min, max);
456 } else if (type == GST_TYPE_DOUBLE_RANGE) {
458 min = va_arg (varargs, double);
459 max = va_arg (varargs, double);
461 g_value_init (&field.value, GST_TYPE_DOUBLE_RANGE);
462 gst_value_set_double_range (&field.value, min, max);
463 } else if (type == GST_TYPE_BUFFER) {
464 GstBuffer *buffer = va_arg (varargs, GstBuffer *);
466 g_value_init (&field.value, GST_TYPE_BUFFER);
467 g_value_set_boxed (&field.value, buffer);
468 } else if (type == GST_TYPE_FRACTION) {
470 n = va_arg (varargs, int);
471 d = va_arg (varargs, int);
473 g_value_init (&field.value, GST_TYPE_FRACTION);
474 gst_value_set_fraction (&field.value, n, d);
476 g_critical ("unimplemented vararg field type %d\n", (int) type);
482 gst_structure_set_field (structure, &field);
484 fieldname = va_arg (varargs, gchar *);
488 /* If the structure currently contains a field with the same name, it is
489 * replaced with the provided field. Otherwise, the field is added to the
490 * structure. The field's value is not deeply copied.
493 gst_structure_set_field (GstStructure * structure, GstStructureField * field)
495 GstStructureField *f;
498 for (i = 0; i < structure->fields->len; i++) {
499 f = GST_STRUCTURE_FIELD (structure, i);
501 if (f->name == field->name) {
502 g_value_unset (&f->value);
503 memcpy (f, field, sizeof (GstStructureField));
508 g_array_append_val (structure->fields, *field);
511 /* If there is no field with the given ID, NULL is returned.
513 static GstStructureField *
514 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
516 GstStructureField *field;
519 g_return_val_if_fail (structure != NULL, NULL);
521 for (i = 0; i < structure->fields->len; i++) {
522 field = GST_STRUCTURE_FIELD (structure, i);
524 if (field->name == field_id)
531 /* If there is no field with the given ID, NULL is returned.
533 static GstStructureField *
534 gst_structure_get_field (const GstStructure * structure,
535 const gchar * fieldname)
537 g_return_val_if_fail (structure != NULL, NULL);
538 g_return_val_if_fail (fieldname != NULL, NULL);
540 return gst_structure_id_get_field (structure,
541 g_quark_from_string (fieldname));
545 * gst_structure_get_value:
546 * @structure: a #GstStructure
547 * @fieldname: the name of the field to get
551 * Returns: the #GValue corresponding to the field with the given name.
554 gst_structure_get_value (const GstStructure * structure,
555 const gchar * fieldname)
557 GstStructureField *field;
559 g_return_val_if_fail (structure != NULL, NULL);
560 g_return_val_if_fail (fieldname != NULL, NULL);
562 field = gst_structure_get_field (structure, fieldname);
566 return &field->value;
570 * gst_structure_id_get_value:
571 * @structure: a #GstStructure
572 * @field: the #GQuark of the field to get
576 * Returns: the #GValue corresponding to the field with the given name
580 gst_structure_id_get_value (const GstStructure * structure, GQuark field)
582 GstStructureField *gsfield;
584 g_return_val_if_fail (structure != NULL, NULL);
586 gsfield = gst_structure_id_get_field (structure, field);
590 return &gsfield->value;
594 * gst_structure_remove_field:
595 * @structure: a #GstStructure
596 * @fieldname: the name of the field to remove
598 * Removes the field with the given name. If the field with the given
599 * name does not exist, the structure is unchanged.
602 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
604 GstStructureField *field;
608 g_return_if_fail (structure != NULL);
609 g_return_if_fail (fieldname != NULL);
610 g_return_if_fail (IS_MUTABLE (structure));
612 id = g_quark_from_string (fieldname);
614 for (i = 0; i < structure->fields->len; i++) {
615 field = GST_STRUCTURE_FIELD (structure, i);
617 if (field->name == id) {
618 if (G_IS_VALUE (&field->value)) {
619 g_value_unset (&field->value);
621 structure->fields = g_array_remove_index (structure->fields, i);
628 * gst_structure_remove_fields:
629 * @structure: a #GstStructure
630 * @fieldname: the name of the field to remove
631 * @...: NULL-terminated list of more fieldnames to remove
633 * Removes the field with the given names. If a field does not exist, the
634 * argument is ignored.
637 gst_structure_remove_fields (GstStructure * structure,
638 const gchar * fieldname, ...)
642 g_return_if_fail (structure != NULL);
643 g_return_if_fail (fieldname != NULL);
644 /* mutability checked in remove_field */
646 va_start (varargs, fieldname);
648 gst_structure_remove_fields_valist (structure, fieldname, varargs);
654 * gst_structure_remove_fields_valist:
655 * @structure: a #GstStructure
656 * @fieldname: the name of the field to remove
657 * @varargs: NULL-terminated list of more fieldnames to remove
659 * Removes the field with the given names. If a field does not exist, the
660 * argument is ignored.
663 gst_structure_remove_fields_valist (GstStructure * structure,
664 const gchar * fieldname, va_list varargs)
666 gchar *field = (gchar *) fieldname;
668 g_return_if_fail (structure != NULL);
669 g_return_if_fail (fieldname != NULL);
670 /* mutability checked in remove_field */
673 gst_structure_remove_field (structure, field);
674 field = va_arg (varargs, char *);
679 * gst_structure_remove_all_fields:
680 * @structure: a #GstStructure
682 * Removes all fields in a GstStructure.
685 gst_structure_remove_all_fields (GstStructure * structure)
687 GstStructureField *field;
690 g_return_if_fail (structure != NULL);
691 g_return_if_fail (IS_MUTABLE (structure));
693 for (i = structure->fields->len - 1; i >= 0; i--) {
694 field = GST_STRUCTURE_FIELD (structure, i);
696 if (G_IS_VALUE (&field->value)) {
697 g_value_unset (&field->value);
699 structure->fields = g_array_remove_index (structure->fields, i);
704 * gst_structure_get_field_type:
705 * @structure: a #GstStructure
706 * @fieldname: the name of the field
708 * Finds the field with the given name, and returns the type of the
709 * value it contains. If the field is not found, G_TYPE_INVALID is
712 * Returns: the #GValue of the field
715 gst_structure_get_field_type (const GstStructure * structure,
716 const gchar * fieldname)
718 GstStructureField *field;
720 g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
721 g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
723 field = gst_structure_get_field (structure, fieldname);
725 return G_TYPE_INVALID;
727 return G_VALUE_TYPE (&field->value);
731 * gst_structure_n_fields:
732 * @structure: a #GstStructure
736 * Returns: the number of fields in the structure
739 gst_structure_n_fields (const GstStructure * structure)
741 g_return_val_if_fail (structure != NULL, 0);
743 return structure->fields->len;
747 * gst_structure_foreach:
748 * @structure: a #GstStructure
749 * @func: a function to call for each field
750 * @user_data: private data
752 * Calls the provided function once for each field in the #GstStructure. The
753 * function must not modify the fields. Also see gst_structure_map_in_place().
755 * Returns: TRUE if the supplied function returns TRUE For each of the fields,
759 gst_structure_foreach (const GstStructure * structure,
760 GstStructureForeachFunc func, gpointer user_data)
763 GstStructureField *field;
766 g_return_val_if_fail (structure != NULL, FALSE);
768 for (i = 0; i < structure->fields->len; i++) {
769 field = GST_STRUCTURE_FIELD (structure, i);
771 ret = func (field->name, &field->value, user_data);
780 * gst_structure_map_in_place:
781 * @structure: a #GstStructure
782 * @func: a function to call for each field
783 * @user_data: private data
785 * Calls the provided function once for each field in the #GstStructure. In
786 * contrast to gst_structure_foreach(), the function may modify the fields. The
787 * structure must be mutable.
789 * Returns: TRUE if the supplied function returns TRUE For each of the fields,
793 gst_structure_map_in_place (GstStructure * structure,
794 GstStructureMapFunc func, gpointer user_data)
797 GstStructureField *field;
800 g_return_val_if_fail (structure != NULL, FALSE);
801 g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
803 for (i = 0; i < structure->fields->len; i++) {
804 field = GST_STRUCTURE_FIELD (structure, i);
806 ret = func (field->name, &field->value, user_data);
815 * gst_structure_has_field:
816 * @structure: a #GstStructure
817 * @fieldname: the name of a field
821 * Returns: TRUE if the structure contains a field with the given name
824 gst_structure_has_field (const GstStructure * structure,
825 const gchar * fieldname)
827 GstStructureField *field;
829 g_return_val_if_fail (structure != NULL, 0);
830 g_return_val_if_fail (fieldname != NULL, 0);
832 field = gst_structure_get_field (structure, fieldname);
834 return (field != NULL);
838 * gst_structure_has_field_typed:
839 * @structure: a #GstStructure
840 * @fieldname: the name of a field
841 * @type: the type of a value
845 * Returns: TRUE if the structure contains a field with the given name and type
848 gst_structure_has_field_typed (const GstStructure * structure,
849 const gchar * fieldname, GType type)
851 GstStructureField *field;
853 g_return_val_if_fail (structure != NULL, 0);
854 g_return_val_if_fail (fieldname != NULL, 0);
856 field = gst_structure_get_field (structure, fieldname);
860 return (G_VALUE_TYPE (&field->value) == type);
864 /* utility functions */
867 * gst_structure_get_boolean:
868 * @structure: a #GstStructure
869 * @fieldname: the name of a field
870 * @value: a pointer to a #gboolean to set
872 * Sets the boolean pointed to by @value corresponding to the value of the
873 * given field. Caller is responsible for making sure the field exists
874 * and has the correct type.
876 * Returns: TRUE if the value could be set correctly
879 gst_structure_get_boolean (const GstStructure * structure,
880 const gchar * fieldname, gboolean * value)
882 GstStructureField *field;
884 g_return_val_if_fail (structure != NULL, FALSE);
885 g_return_val_if_fail (fieldname != NULL, FALSE);
887 field = gst_structure_get_field (structure, fieldname);
891 if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
894 *value = g_value_get_boolean (&field->value);
900 * gst_structure_get_int:
901 * @structure: a #GstStructure
902 * @fieldname: the name of a field
903 * @value: a pointer to an int to set
905 * Sets the int pointed to by @value corresponding to the value of the
906 * given field. Caller is responsible for making sure the field exists
907 * and has the correct type.
909 * Returns: TRUE if the value could be set correctly
912 gst_structure_get_int (const GstStructure * structure,
913 const gchar * fieldname, gint * value)
915 GstStructureField *field;
917 g_return_val_if_fail (structure != NULL, FALSE);
918 g_return_val_if_fail (fieldname != NULL, FALSE);
919 g_return_val_if_fail (value != NULL, FALSE);
921 field = gst_structure_get_field (structure, fieldname);
925 if (!G_VALUE_HOLDS_INT (&field->value))
928 *value = g_value_get_int (&field->value);
934 * gst_structure_get_fourcc:
935 * @structure: a #GstStructure
936 * @fieldname: the name of a field
937 * @value: a pointer to a #GstFourcc to set
939 * Sets the #GstFourcc pointed to by @value corresponding to the value of the
940 * given field. Caller is responsible for making sure the field exists
941 * and has the correct type.
943 * Returns: TRUE if the value could be set correctly
946 gst_structure_get_fourcc (const GstStructure * structure,
947 const gchar * fieldname, guint32 * value)
949 GstStructureField *field;
951 g_return_val_if_fail (structure != NULL, FALSE);
952 g_return_val_if_fail (fieldname != NULL, FALSE);
953 g_return_val_if_fail (value != NULL, FALSE);
955 field = gst_structure_get_field (structure, fieldname);
959 if (!GST_VALUE_HOLDS_FOURCC (&field->value))
962 *value = gst_value_get_fourcc (&field->value);
968 * gst_structure_get_double:
969 * @structure: a #GstStructure
970 * @fieldname: the name of a field
971 * @value: a pointer to a #GstFourcc to set
973 * Sets the double pointed to by @value corresponding to the value of the
974 * given field. Caller is responsible for making sure the field exists
975 * and has the correct type.
977 * Returns: TRUE if the value could be set correctly
980 gst_structure_get_double (const GstStructure * structure,
981 const gchar * fieldname, gdouble * value)
983 GstStructureField *field;
985 g_return_val_if_fail (structure != NULL, FALSE);
986 g_return_val_if_fail (fieldname != NULL, FALSE);
987 g_return_val_if_fail (value != NULL, FALSE);
989 field = gst_structure_get_field (structure, fieldname);
993 if (!G_VALUE_HOLDS_DOUBLE (&field->value))
996 *value = g_value_get_double (&field->value);
1002 * gst_structure_get_string:
1003 * @structure: a #GstStructure
1004 * @fieldname: the name of a field
1006 * Finds the field corresponding to @fieldname, and returns the string
1007 * contained in the field's value. Caller is responsible for making
1008 * sure the field exists and has the correct type.
1010 * The string should not be modified, and remains valid until the next
1011 * call to a gst_structure_*() function with the given structure.
1013 * Returns: a pointer to the string
1016 gst_structure_get_string (const GstStructure * structure,
1017 const gchar * fieldname)
1019 GstStructureField *field;
1021 g_return_val_if_fail (structure != NULL, NULL);
1022 g_return_val_if_fail (fieldname != NULL, NULL);
1024 field = gst_structure_get_field (structure, fieldname);
1028 if (!G_VALUE_HOLDS_STRING (&field->value))
1031 return g_value_get_string (&field->value);
1034 typedef struct _GstStructureAbbreviation
1039 GstStructureAbbreviation;
1041 static GstStructureAbbreviation *
1042 gst_structure_get_abbrs (gint * n_abbrs)
1044 static GstStructureAbbreviation *abbrs = NULL;
1045 static gint num = 0;
1047 if (abbrs == NULL) {
1048 /* dynamically generate the array */
1049 GstStructureAbbreviation dyn_abbrs[] = {
1054 {"float", G_TYPE_FLOAT}
1058 {"double", G_TYPE_DOUBLE}
1060 {"d", G_TYPE_DOUBLE}
1062 {"buffer", GST_TYPE_BUFFER}
1064 {"fourcc", GST_TYPE_FOURCC}
1066 {"4", GST_TYPE_FOURCC}
1068 {"fraction", GST_TYPE_FRACTION}
1070 {"boolean", G_TYPE_BOOLEAN}
1072 {"bool", G_TYPE_BOOLEAN}
1074 {"b", G_TYPE_BOOLEAN}
1076 {"string", G_TYPE_STRING}
1078 {"str", G_TYPE_STRING}
1080 {"s", G_TYPE_STRING}
1082 num = G_N_ELEMENTS (dyn_abbrs);
1083 /* permanently allocate and copy the array now */
1084 abbrs = g_new0 (GstStructureAbbreviation, num);
1085 memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * num);
1093 gst_structure_from_abbr (const char *type_name)
1096 GstStructureAbbreviation *abbrs;
1099 g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
1101 abbrs = gst_structure_get_abbrs (&n_abbrs);
1103 for (i = 0; i < n_abbrs; i++) {
1104 if (strcmp (type_name, abbrs[i].type_name) == 0) {
1105 return abbrs[i].type;
1109 /* this is the fallback */
1110 return g_type_from_name (type_name);
1114 gst_structure_to_abbr (GType type)
1117 GstStructureAbbreviation *abbrs;
1120 g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
1122 abbrs = gst_structure_get_abbrs (&n_abbrs);
1124 for (i = 0; i < n_abbrs; i++) {
1125 if (type == abbrs[i].type) {
1126 return abbrs[i].type_name;
1130 return g_type_name (type);
1134 gst_structure_value_get_generic_type (GValue * val)
1136 if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1137 || G_VALUE_TYPE (val) == GST_TYPE_FIXED_LIST) {
1138 GArray *array = g_value_peek_pointer (val);
1140 if (array->len > 0) {
1141 GValue *value = &g_array_index (array, GValue, 0);
1143 return gst_structure_value_get_generic_type (value);
1147 } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1149 } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1150 return G_TYPE_DOUBLE;
1152 return G_VALUE_TYPE (val);
1155 #define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
1156 ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
1160 * gst_structure_to_string:
1161 * @structure: a #GstStructure
1163 * Converts @structure to a human-readable representation.
1165 * Returns: a pointer to string allocated by g_malloc()
1168 gst_structure_to_string (const GstStructure * structure)
1170 GstStructureField *field;
1174 /* NOTE: This function is potentially called by the debug system,
1175 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1176 * should be careful to avoid recursion. This includes any functions
1177 * called by gst_structure_to_string. In particular, calls should
1178 * not use the GST_PTR_FORMAT extension. */
1180 g_return_val_if_fail (structure != NULL, NULL);
1182 s = g_string_new ("");
1183 /* FIXME this string may need to be escaped */
1184 g_string_append_printf (s, "%s", g_quark_to_string (structure->name));
1185 for (i = 0; i < structure->fields->len; i++) {
1189 field = GST_STRUCTURE_FIELD (structure, i);
1191 t = gst_value_serialize (&field->value);
1192 type = gst_structure_value_get_generic_type (&field->value);
1194 g_string_append_printf (s, ", %s=(%s)%s", g_quark_to_string (field->name),
1195 gst_structure_to_abbr (type), t);
1198 return g_string_free (s, FALSE);
1202 * r will still point to the string. if end == next, the string will not be
1203 * null-terminated. In all other cases it will be.
1204 * end = pointer to char behind end of string, next = pointer to start of
1206 * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING
1209 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next)
1219 ret = gst_structure_parse_simple_string (s, end);
1248 gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
1251 GValue value1 = { 0 };
1252 GValue value2 = { 0 };
1261 ret = gst_structure_parse_value (s, &s, &value1, type);
1265 while (g_ascii_isspace (*s))
1272 while (g_ascii_isspace (*s))
1275 ret = gst_structure_parse_value (s, &s, &value2, type);
1279 while (g_ascii_isspace (*s))
1286 if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
1289 if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1290 range_type = GST_TYPE_DOUBLE_RANGE;
1291 } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1292 range_type = GST_TYPE_INT_RANGE;
1297 g_value_init (value, range_type);
1298 if (range_type == GST_TYPE_DOUBLE_RANGE) {
1299 gst_value_set_double_range (value, g_value_get_double (&value1),
1300 g_value_get_double (&value2));
1302 gst_value_set_int_range (value, g_value_get_int (&value1),
1303 g_value_get_int (&value2));
1311 gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
1312 GType type, GType list_type, char begin, char end)
1314 GValue list_value = { 0 };
1318 g_value_init (value, list_type);
1319 array = g_value_peek_pointer (value);
1325 while (g_ascii_isspace (*s))
1333 ret = gst_structure_parse_value (s, &s, &list_value, type);
1337 g_array_append_val (array, list_value);
1339 while (g_ascii_isspace (*s))
1347 while (g_ascii_isspace (*s))
1350 memset (&list_value, 0, sizeof (list_value));
1351 ret = gst_structure_parse_value (s, &s, &list_value, type);
1355 g_array_append_val (array, list_value);
1356 while (g_ascii_isspace (*s))
1367 gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
1369 return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
1374 gst_structure_parse_fixed_list (gchar * s, gchar ** after, GValue * value,
1377 return gst_structure_parse_any_list (s, after, value, type,
1378 GST_TYPE_FIXED_LIST, '<', '>');
1382 gst_structure_parse_simple_string (gchar * str, gchar ** end)
1386 while (GST_ASCII_IS_STRING (*s)) {
1396 gst_structure_parse_field (gchar * str,
1397 gchar ** after, GstStructureField * field)
1406 while (g_ascii_isspace (*s))
1409 if (!gst_structure_parse_simple_string (s, &name_end))
1413 while (g_ascii_isspace (*s))
1422 field->name = g_quark_from_string (name);
1425 if (!gst_structure_parse_value (s, &s, &field->value, G_TYPE_INVALID))
1433 gst_structure_parse_value (gchar * str,
1434 gchar ** after, GValue * value, GType default_type)
1443 GType type = default_type;
1447 while (g_ascii_isspace (*s))
1452 type = G_TYPE_INVALID;
1455 while (g_ascii_isspace (*s))
1458 if (!gst_structure_parse_simple_string (s, &type_end))
1461 while (g_ascii_isspace (*s))
1466 while (g_ascii_isspace (*s))
1471 type = gst_structure_from_abbr (type_name);
1474 if (type == G_TYPE_INVALID)
1478 while (g_ascii_isspace (*s))
1481 ret = gst_structure_parse_range (s, &s, value, type);
1482 } else if (*s == '{') {
1483 ret = gst_structure_parse_list (s, &s, value, type);
1484 } else if (*s == '<') {
1485 ret = gst_structure_parse_fixed_list (s, &s, value, type);
1488 if (!gst_structure_parse_string (s, &value_end, &s))
1493 if (type == G_TYPE_INVALID) {
1494 GType try_types[] = { G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_STRING };
1497 for (i = 0; i < 3; i++) {
1498 g_value_init (value, try_types[i]);
1499 ret = gst_value_deserialize (value, value_s);
1502 g_value_unset (value);
1505 g_value_init (value, type);
1507 ret = gst_value_deserialize (value, value_s);
1518 * gst_structure_from_string:
1519 * @string: a string representation of a #GstStructure.
1520 * @end: FIXME, deduce from code
1522 * Creates a #GstStructure from a string representation.
1524 * Returns: a new #GstStructure
1527 gst_structure_from_string (const gchar * string, gchar ** end)
1534 GstStructure *structure = NULL;
1535 GstStructureField field = { 0 };
1537 g_return_val_if_fail (string != NULL, NULL);
1539 copy = g_strdup (string);
1543 if (!gst_structure_parse_string (r, &w, &r))
1546 while (g_ascii_isspace (*r))
1548 if (*r != 0 && *r != ';' && *r != ',')
1553 structure = gst_structure_empty_new (name);
1556 while (*r && (*r != ';')) {
1560 while (*r && g_ascii_isspace (*r))
1563 memset (&field, 0, sizeof (field));
1564 if (!gst_structure_parse_field (r, &r, &field))
1566 gst_structure_set_field (structure, &field);
1567 while (*r && g_ascii_isspace (*r))
1572 *end = (char *) string + (r - copy);
1579 gst_structure_free (structure);
1585 gst_structure_transform_to_string (const GValue * src_value,
1586 GValue * dest_value)
1588 g_return_if_fail (src_value != NULL);
1589 g_return_if_fail (dest_value != NULL);
1591 dest_value->data[0].v_pointer =
1592 gst_structure_to_string (src_value->data[0].v_pointer);
1595 static GstStructure *
1596 gst_structure_copy_conditional (const GstStructure * structure)
1599 return gst_structure_copy (structure);
1603 /* fixate utility functions */
1606 * gst_caps_structure_fixate_field_nearest_int:
1607 * @structure: a #GstStructure
1608 * @field_name: a field in @structure
1609 * @target: the target value of the fixation
1611 * Fixates a #GstStructure by changing the given field to the nearest
1612 * integer to @target that is a subset of the existing field.
1614 * Returns: TRUE if the structure could be fixated
1617 gst_caps_structure_fixate_field_nearest_int (GstStructure * structure,
1618 const char *field_name, int target)
1620 const GValue *value;
1622 g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
1623 g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1625 value = gst_structure_get_value (structure, field_name);
1627 if (G_VALUE_TYPE (value) == G_TYPE_INT) {
1630 } else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
1633 x = gst_value_get_int_range_min (value);
1636 x = gst_value_get_int_range_max (value);
1639 gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
1641 } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1642 const GValue *list_value;
1645 int best_index = -1;
1647 n = gst_value_list_get_size (value);
1648 for (i = 0; i < n; i++) {
1649 list_value = gst_value_list_get_value (value, i);
1650 if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
1651 int x = g_value_get_int (list_value);
1653 if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
1659 if (best_index != -1) {
1660 gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
1670 * gst_caps_structure_fixate_field_nearest_double:
1671 * @structure: a #GstStructure
1672 * @field_name: a field in @structure
1673 * @target: the target value of the fixation
1675 * Fixates a #GstStructure by changing the given field to the nearest
1676 * double to @target that is a subset of the existing field.
1678 * Returns: TRUE if the structure could be fixated
1681 gst_caps_structure_fixate_field_nearest_double (GstStructure * structure,
1682 const char *field_name, double target)
1684 const GValue *value;
1686 g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
1687 g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1689 value = gst_structure_get_value (structure, field_name);
1691 if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
1694 } else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
1697 x = gst_value_get_double_range_min (value);
1700 x = gst_value_get_double_range_max (value);
1703 gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
1705 } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1706 const GValue *list_value;
1709 int best_index = -1;
1711 n = gst_value_list_get_size (value);
1712 for (i = 0; i < n; i++) {
1713 list_value = gst_value_list_get_value (value, i);
1714 if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
1715 double x = g_value_get_double (list_value);
1717 if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
1723 if (best_index != -1) {
1724 gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);