gst/gstpad.h: Fix inline docs for GstPadLinkReturn.
[platform/upstream/gstreamer.git] / gst / gststructure.c
1 /* GStreamer
2  * Copyright (C) 2003 David A. Schleef <ds@schleef.org>
3  *
4  * gststructure.c: lists of { GQuark, GValue } tuples
5  *
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.
10  *
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.
15  *
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.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include "gst_private.h"
29 #include <gst/gst.h>
30 #include <gobject/gvaluecollector.h>
31
32 typedef struct _GstStructureField GstStructureField;
33
34 struct _GstStructureField
35 {
36   GQuark name;
37   GValue value;
38 };
39
40 #define GST_STRUCTURE_FIELD(structure, index) \
41     &g_array_index((structure)->fields, GstStructureField, (index))
42
43 #define IS_MUTABLE(structure) \
44     (!(structure)->parent_refcount || \
45      g_atomic_int_get ((structure)->parent_refcount) == 1)
46
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,
54     GValue * dest_value);
55 static GstStructure *gst_structure_copy_conditional (const GstStructure *
56     structure);
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);
60
61 GType
62 gst_structure_get_type (void)
63 {
64   static GType gst_structure_type = 0;
65
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);
70
71     g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
72         gst_structure_transform_to_string);
73   }
74
75   return gst_structure_type;
76 }
77
78 static GstStructure *
79 gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc)
80 {
81   GstStructure *structure;
82
83   structure = g_new0 (GstStructure, 1);
84   structure->type = gst_structure_get_type ();
85   structure->name = quark;
86   structure->fields =
87       g_array_sized_new (FALSE, TRUE, sizeof (GstStructureField), prealloc);
88
89   return structure;
90 }
91
92 /**
93  * gst_structure_id_empty_new:
94  * @quark: name of new structure
95  *
96  * Creates a new, empty #GstStructure with the given name.
97  *
98  * Returns: a new, empty #GstStructure
99  */
100 GstStructure *
101 gst_structure_id_empty_new (GQuark quark)
102 {
103   g_return_val_if_fail (quark != 0, NULL);
104
105   return gst_structure_id_empty_new_with_size (quark, 0);
106 }
107
108 /**
109  * gst_structure_empty_new:
110  * @name: name of new structure
111  *
112  * Creates a new, empty #GstStructure with the given name.
113  *
114  * Returns: a new, empty #GstStructure
115  */
116 GstStructure *
117 gst_structure_empty_new (const gchar * name)
118 {
119   g_return_val_if_fail (name != NULL, NULL);
120
121   return gst_structure_id_empty_new_with_size (g_quark_from_string (name), 0);
122 }
123
124 /**
125  * gst_structure_new:
126  * @name: name of new structure
127  * @firstfield: name of first field to set
128  * @...: additional arguments
129  *
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.
134  *
135  * Returns: a new #GstStructure
136  */
137 GstStructure *
138 gst_structure_new (const gchar * name, const gchar * firstfield, ...)
139 {
140   GstStructure *structure;
141   va_list varargs;
142
143   g_return_val_if_fail (name != NULL, NULL);
144
145   va_start (varargs, firstfield);
146
147   structure = gst_structure_new_valist (name, firstfield, varargs);
148
149   va_end (varargs);
150
151   return structure;
152 }
153
154 /**
155  * gst_structure_new_valist:
156  * @name: name of new structure
157  * @firstfield: name of first field to set
158  * @varargs: variable argument list
159  *
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.
163  *
164  * Returns: a new #GstStructure
165  */
166 GstStructure *
167 gst_structure_new_valist (const gchar * name,
168     const gchar * firstfield, va_list varargs)
169 {
170   GstStructure *structure;
171
172   g_return_val_if_fail (name != NULL, NULL);
173
174   structure = gst_structure_empty_new (name);
175   gst_structure_set_valist (structure, firstfield, varargs);
176
177   return structure;
178 }
179
180 /**
181  * gst_structure_set_parent_refcount:
182  * @structure: a #GstStructure
183  * @refcount: a pointer to the parent's refcount
184  *
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.
189  *
190  * Returns: a new #GstStructure.
191  */
192 void
193 gst_structure_set_parent_refcount (GstStructure * structure, int *refcount)
194 {
195   g_return_if_fail (structure != NULL);
196
197   /* if we have a parent_refcount already, we can only clear
198    * if with a NULL refcount */
199   if (structure->parent_refcount)
200     g_return_if_fail (refcount == NULL);
201   else
202     g_return_if_fail (refcount != NULL);
203
204   structure->parent_refcount = refcount;
205 }
206
207 /**
208  * gst_structure_copy:
209  * @structure: a #GstStructure to duplicate
210  *
211  * Duplicates a #GstStructure and all its fields and values.
212  *
213  * Returns: a new #GstStructure.
214  */
215 GstStructure *
216 gst_structure_copy (const GstStructure * structure)
217 {
218   GstStructure *new_structure;
219   GstStructureField *field;
220   int i;
221
222   g_return_val_if_fail (structure != NULL, NULL);
223
224   new_structure =
225       gst_structure_id_empty_new_with_size (structure->name,
226       structure->fields->len);
227
228   for (i = 0; i < structure->fields->len; i++) {
229     GstStructureField new_field = { 0 };
230
231     field = GST_STRUCTURE_FIELD (structure, i);
232
233     new_field.name = field->name;
234     gst_value_init_and_copy (&new_field.value, &field->value);
235     g_array_append_val (new_structure->fields, new_field);
236   }
237
238   return new_structure;
239 }
240
241 /**
242  * gst_structure_free: 
243  * @structure: the #GstStructure to free
244  *
245  * Frees a #GstStructure and all its fields and values. The structure must not
246  * have a parent when this function is called.
247  */
248 void
249 gst_structure_free (GstStructure * structure)
250 {
251   GstStructureField *field;
252   int i;
253
254   g_return_if_fail (structure != NULL);
255   g_return_if_fail (structure->parent_refcount == NULL);
256
257   for (i = 0; i < structure->fields->len; i++) {
258     field = GST_STRUCTURE_FIELD (structure, i);
259
260     if (G_IS_VALUE (&field->value)) {
261       g_value_unset (&field->value);
262     }
263   }
264   g_array_free (structure->fields, TRUE);
265 #ifdef USE_POISONING
266   memset (structure, 0xff, sizeof (GstStructure));
267 #endif
268   g_free (structure);
269 }
270
271 /**
272  * gst_structure_get_name:
273  * @structure: a #GstStructure
274  *
275  * Accessor fuction.
276  *
277  * Returns: the name of the structure.
278  */
279 const gchar *
280 gst_structure_get_name (const GstStructure * structure)
281 {
282   g_return_val_if_fail (structure != NULL, NULL);
283
284   return g_quark_to_string (structure->name);
285 }
286
287 /**
288  * gst_structure_has_name:
289  * @structure: a #GstStructure
290  * @name: structure name to check for
291  *
292  * Returns: TRUE if @name matches the name of the structure.
293  */
294 gboolean
295 gst_structure_has_name (const GstStructure * structure, const gchar * name)
296 {
297   const gchar *structure_name;
298
299   g_return_val_if_fail (structure != NULL, FALSE);
300   g_return_val_if_fail (name != NULL, FALSE);
301
302   structure_name = g_quark_to_string (structure->name);
303
304   return (structure_name && strcmp (structure_name, name) == 0);
305 }
306
307 /**
308  * gst_structure_get_name_id:
309  * @structure: a #GstStructure
310  *
311  * Accessor fuction.
312  *
313  * Returns: the quark representing the name of the structure.
314  */
315 GQuark
316 gst_structure_get_name_id (const GstStructure * structure)
317 {
318   g_return_val_if_fail (structure != NULL, 0);
319
320   return structure->name;
321 }
322
323 /**
324  * gst_structure_set_name:
325  * @structure: a #GstStructure
326  * @name: the new name of the structure
327  *
328  * Sets the name of the structure to the given name.  The string
329  * provided is copied before being used.
330  */
331 void
332 gst_structure_set_name (GstStructure * structure, const gchar * name)
333 {
334   g_return_if_fail (structure != NULL);
335   g_return_if_fail (name != NULL);
336   g_return_if_fail (IS_MUTABLE (structure));
337
338   structure->name = g_quark_from_string (name);
339 }
340
341 /**
342  * gst_structure_id_set_value:
343  * @structure: a #GstStructure
344  * @field: a #GQuark representing a field
345  * @value: the new value of the field
346  *
347  * Sets the field with the given ID to the provided value.  If the field
348  * does not exist, it is created.  If the field exists, the previous
349  * value is freed.
350  */
351 void
352 gst_structure_id_set_value (GstStructure * structure,
353     GQuark field, const GValue * value)
354 {
355   GstStructureField gsfield = { 0, {0,} };
356
357   g_return_if_fail (structure != NULL);
358   g_return_if_fail (G_IS_VALUE (value));
359   g_return_if_fail (IS_MUTABLE (structure));
360
361   gsfield.name = field;
362   gst_value_init_and_copy (&gsfield.value, value);
363
364   gst_structure_set_field (structure, &gsfield);
365 }
366
367 /**
368  * gst_structure_set_value:
369  * @structure: a #GstStructure
370  * @fieldname: the name of the field to set
371  * @value: the new value of the field
372  *
373  * Sets the field with the given name to the provided value.  If the field
374  * does not exist, it is created.  If the field exists, the previous
375  * value is freed.
376  */
377 void
378 gst_structure_set_value (GstStructure * structure,
379     const gchar * fieldname, const GValue * value)
380 {
381   g_return_if_fail (structure != NULL);
382   g_return_if_fail (fieldname != NULL);
383   g_return_if_fail (G_IS_VALUE (value));
384   g_return_if_fail (IS_MUTABLE (structure));
385
386   gst_structure_id_set_value (structure, g_quark_from_string (fieldname),
387       value);
388 }
389
390 /**
391  * gst_structure_set:
392  * @structure: a #GstStructure
393  * @fieldname: the name of the field to set
394  * @...: variable arguments
395  *
396  * Parses the variable arguments and sets fields accordingly.
397  * Variable arguments should be in the form field name, field type
398  * (as a GType), value.  The last variable argument should be NULL.
399  */
400 void
401 gst_structure_set (GstStructure * structure, const gchar * field, ...)
402 {
403   va_list varargs;
404
405   g_return_if_fail (structure != NULL);
406
407   va_start (varargs, field);
408
409   gst_structure_set_valist (structure, field, varargs);
410
411   va_end (varargs);
412 }
413
414 /**
415  * gst_structure_set_valist:
416  * @structure: a #GstStructure
417  * @fieldname: the name of the field to set
418  * @varargs: variable arguments
419  *
420  * va_list form of #gst_structure_set.
421  */
422 void
423 gst_structure_set_valist (GstStructure * structure,
424     const gchar * fieldname, va_list varargs)
425 {
426   gchar *err = NULL;
427   GType type;
428
429   g_return_if_fail (structure != NULL);
430   g_return_if_fail (IS_MUTABLE (structure));
431
432   while (fieldname) {
433     GstStructureField field = { 0 };
434
435     field.name = g_quark_from_string (fieldname);
436
437     type = va_arg (varargs, GType);
438     g_value_init (&field.value, type);
439     G_VALUE_COLLECT (&field.value, varargs, 0, &err);
440     if (err) {
441       g_critical ("%s", err);
442       return;
443     }
444     gst_structure_set_field (structure, &field);
445
446     fieldname = va_arg (varargs, gchar *);
447   }
448 }
449
450 /* If the structure currently contains a field with the same name, it is
451  * replaced with the provided field. Otherwise, the field is added to the
452  * structure. The field's value is not deeply copied.
453  */
454 static void
455 gst_structure_set_field (GstStructure * structure, GstStructureField * field)
456 {
457   GstStructureField *f;
458   int i;
459
460   for (i = 0; i < structure->fields->len; i++) {
461     f = GST_STRUCTURE_FIELD (structure, i);
462
463     if (f->name == field->name) {
464       g_value_unset (&f->value);
465       memcpy (f, field, sizeof (GstStructureField));
466       return;
467     }
468   }
469
470   g_array_append_val (structure->fields, *field);
471 }
472
473 /* If there is no field with the given ID, NULL is returned.
474  */
475 static GstStructureField *
476 gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
477 {
478   GstStructureField *field;
479   int i;
480
481   g_return_val_if_fail (structure != NULL, NULL);
482
483   for (i = 0; i < structure->fields->len; i++) {
484     field = GST_STRUCTURE_FIELD (structure, i);
485
486     if (field->name == field_id)
487       return field;
488   }
489
490   return NULL;
491 }
492
493 /* If there is no field with the given ID, NULL is returned.
494  */
495 static GstStructureField *
496 gst_structure_get_field (const GstStructure * structure,
497     const gchar * fieldname)
498 {
499   g_return_val_if_fail (structure != NULL, NULL);
500   g_return_val_if_fail (fieldname != NULL, NULL);
501
502   return gst_structure_id_get_field (structure,
503       g_quark_from_string (fieldname));
504 }
505
506 /**
507  * gst_structure_get_value:
508  * @structure: a #GstStructure
509  * @fieldname: the name of the field to get
510  *
511  * Accessor function.
512  *
513  * Returns: the #GValue corresponding to the field with the given name.
514  */
515 const GValue *
516 gst_structure_get_value (const GstStructure * structure,
517     const gchar * fieldname)
518 {
519   GstStructureField *field;
520
521   g_return_val_if_fail (structure != NULL, NULL);
522   g_return_val_if_fail (fieldname != NULL, NULL);
523
524   field = gst_structure_get_field (structure, fieldname);
525   if (field == NULL)
526     return NULL;
527
528   return &field->value;
529 }
530
531 /**
532  * gst_structure_id_get_value:
533  * @structure: a #GstStructure
534  * @field: the #GQuark of the field to get
535  *
536  * Accessor function.
537  *
538  * Returns: the #GValue corresponding to the field with the given name 
539  *          identifier.
540  */
541 const GValue *
542 gst_structure_id_get_value (const GstStructure * structure, GQuark field)
543 {
544   GstStructureField *gsfield;
545
546   g_return_val_if_fail (structure != NULL, NULL);
547
548   gsfield = gst_structure_id_get_field (structure, field);
549   if (gsfield == NULL)
550     return NULL;
551
552   return &gsfield->value;
553 }
554
555 /**
556  * gst_structure_remove_field:
557  * @structure: a #GstStructure
558  * @fieldname: the name of the field to remove
559  *
560  * Removes the field with the given name.  If the field with the given
561  * name does not exist, the structure is unchanged.
562  */
563 void
564 gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
565 {
566   GstStructureField *field;
567   GQuark id;
568   int i;
569
570   g_return_if_fail (structure != NULL);
571   g_return_if_fail (fieldname != NULL);
572   g_return_if_fail (IS_MUTABLE (structure));
573
574   id = g_quark_from_string (fieldname);
575
576   for (i = 0; i < structure->fields->len; i++) {
577     field = GST_STRUCTURE_FIELD (structure, i);
578
579     if (field->name == id) {
580       if (G_IS_VALUE (&field->value)) {
581         g_value_unset (&field->value);
582       }
583       structure->fields = g_array_remove_index (structure->fields, i);
584       return;
585     }
586   }
587 }
588
589 /**
590  * gst_structure_remove_fields:
591  * @structure: a #GstStructure
592  * @fieldname: the name of the field to remove
593  * @...: NULL-terminated list of more fieldnames to remove
594  *
595  * Removes the field with the given names. If a field does not exist, the
596  * argument is ignored.
597  */
598 void
599 gst_structure_remove_fields (GstStructure * structure,
600     const gchar * fieldname, ...)
601 {
602   va_list varargs;
603
604   g_return_if_fail (structure != NULL);
605   g_return_if_fail (fieldname != NULL);
606   /* mutability checked in remove_field */
607
608   va_start (varargs, fieldname);
609
610   gst_structure_remove_fields_valist (structure, fieldname, varargs);
611
612   va_end (varargs);
613 }
614
615 /**
616  * gst_structure_remove_fields_valist:
617  * @structure: a #GstStructure
618  * @fieldname: the name of the field to remove
619  * @varargs: NULL-terminated list of more fieldnames to remove
620  *
621  * Removes the field with the given names. If a field does not exist, the
622  * argument is ignored.
623  */
624 void
625 gst_structure_remove_fields_valist (GstStructure * structure,
626     const gchar * fieldname, va_list varargs)
627 {
628   gchar *field = (gchar *) fieldname;
629
630   g_return_if_fail (structure != NULL);
631   g_return_if_fail (fieldname != NULL);
632   /* mutability checked in remove_field */
633
634   while (field) {
635     gst_structure_remove_field (structure, field);
636     field = va_arg (varargs, char *);
637   }
638 }
639
640 /**
641  * gst_structure_remove_all_fields:
642  * @structure: a #GstStructure
643  *
644  * Removes all fields in a GstStructure. 
645  */
646 void
647 gst_structure_remove_all_fields (GstStructure * structure)
648 {
649   GstStructureField *field;
650   int i;
651
652   g_return_if_fail (structure != NULL);
653   g_return_if_fail (IS_MUTABLE (structure));
654
655   for (i = structure->fields->len - 1; i >= 0; i--) {
656     field = GST_STRUCTURE_FIELD (structure, i);
657
658     if (G_IS_VALUE (&field->value)) {
659       g_value_unset (&field->value);
660     }
661     structure->fields = g_array_remove_index (structure->fields, i);
662   }
663 }
664
665 /**
666  * gst_structure_get_field_type:
667  * @structure: a #GstStructure
668  * @fieldname: the name of the field
669  *
670  * Finds the field with the given name, and returns the type of the
671  * value it contains.  If the field is not found, G_TYPE_INVALID is
672  * returned.
673  *
674  * Returns: the #GValue of the field
675  */
676 GType
677 gst_structure_get_field_type (const GstStructure * structure,
678     const gchar * fieldname)
679 {
680   GstStructureField *field;
681
682   g_return_val_if_fail (structure != NULL, G_TYPE_INVALID);
683   g_return_val_if_fail (fieldname != NULL, G_TYPE_INVALID);
684
685   field = gst_structure_get_field (structure, fieldname);
686   if (field == NULL)
687     return G_TYPE_INVALID;
688
689   return G_VALUE_TYPE (&field->value);
690 }
691
692 /**
693  * gst_structure_n_fields:
694  * @structure: a #GstStructure
695  *
696  * Accessor function.
697  *
698  * Returns: the number of fields in the structure
699  */
700 gint
701 gst_structure_n_fields (const GstStructure * structure)
702 {
703   g_return_val_if_fail (structure != NULL, 0);
704
705   return structure->fields->len;
706 }
707
708 /**
709  * gst_structure_nth_field_name:
710  * @structure: a #GstStructure
711  *
712  * Returns: the name of the given field number, counting from 0 onwards.
713  */
714 const gchar *
715 gst_structure_nth_field_name (const GstStructure * structure, guint index)
716 {
717   GstStructureField *field;
718
719   field = GST_STRUCTURE_FIELD (structure, index);
720   return g_quark_to_string (field->name);
721 }
722
723 /**
724  * gst_structure_foreach:
725  * @structure: a #GstStructure
726  * @func: a function to call for each field
727  * @user_data: private data
728  *
729  * Calls the provided function once for each field in the #GstStructure. The
730  * function must not modify the fields. Also see gst_structure_map_in_place().
731  *
732  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
733  * FALSE otherwise.
734  */
735 gboolean
736 gst_structure_foreach (const GstStructure * structure,
737     GstStructureForeachFunc func, gpointer user_data)
738 {
739   int i;
740   GstStructureField *field;
741   gboolean ret;
742
743   g_return_val_if_fail (structure != NULL, FALSE);
744
745   for (i = 0; i < structure->fields->len; i++) {
746     field = GST_STRUCTURE_FIELD (structure, i);
747
748     ret = func (field->name, &field->value, user_data);
749     if (!ret)
750       return FALSE;
751   }
752
753   return TRUE;
754 }
755
756 /**
757  * gst_structure_map_in_place:
758  * @structure: a #GstStructure
759  * @func: a function to call for each field
760  * @user_data: private data
761  *
762  * Calls the provided function once for each field in the #GstStructure. In
763  * contrast to gst_structure_foreach(), the function may modify the fields. The
764  * structure must be mutable.
765  *
766  * Returns: TRUE if the supplied function returns TRUE For each of the fields,
767  * FALSE otherwise.
768  */
769 gboolean
770 gst_structure_map_in_place (GstStructure * structure,
771     GstStructureMapFunc func, gpointer user_data)
772 {
773   int i;
774   GstStructureField *field;
775   gboolean ret;
776
777   g_return_val_if_fail (structure != NULL, FALSE);
778   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
779
780   for (i = 0; i < structure->fields->len; i++) {
781     field = GST_STRUCTURE_FIELD (structure, i);
782
783     ret = func (field->name, &field->value, user_data);
784     if (!ret)
785       return FALSE;
786   }
787
788   return TRUE;
789 }
790
791 /**
792  * gst_structure_has_field:
793  * @structure: a #GstStructure
794  * @fieldname: the name of a field
795  *
796  * Accessor function.
797  *
798  * Returns: TRUE if the structure contains a field with the given name
799  */
800 gboolean
801 gst_structure_has_field (const GstStructure * structure,
802     const gchar * fieldname)
803 {
804   GstStructureField *field;
805
806   g_return_val_if_fail (structure != NULL, 0);
807   g_return_val_if_fail (fieldname != NULL, 0);
808
809   field = gst_structure_get_field (structure, fieldname);
810
811   return (field != NULL);
812 }
813
814 /**
815  * gst_structure_has_field_typed:
816  * @structure: a #GstStructure
817  * @fieldname: the name of a field
818  * @type: the type of a value
819  *
820  * Accessor function.
821  *
822  * Returns: TRUE if the structure contains a field with the given name and type
823  */
824 gboolean
825 gst_structure_has_field_typed (const GstStructure * structure,
826     const gchar * fieldname, GType type)
827 {
828   GstStructureField *field;
829
830   g_return_val_if_fail (structure != NULL, 0);
831   g_return_val_if_fail (fieldname != NULL, 0);
832
833   field = gst_structure_get_field (structure, fieldname);
834   if (field == NULL)
835     return FALSE;
836
837   return (G_VALUE_TYPE (&field->value) == type);
838 }
839
840
841 /* utility functions */
842
843 /**
844  * gst_structure_get_boolean:
845  * @structure: a #GstStructure
846  * @fieldname: the name of a field
847  * @value: a pointer to a #gboolean to set
848  *
849  * Sets the boolean pointed to by @value corresponding to the value of the
850  * given field.  Caller is responsible for making sure the field exists
851  * and has the correct type.
852  *
853  * Returns: TRUE if the value could be set correctly
854  */
855 gboolean
856 gst_structure_get_boolean (const GstStructure * structure,
857     const gchar * fieldname, gboolean * value)
858 {
859   GstStructureField *field;
860
861   g_return_val_if_fail (structure != NULL, FALSE);
862   g_return_val_if_fail (fieldname != NULL, FALSE);
863
864   field = gst_structure_get_field (structure, fieldname);
865
866   if (field == NULL)
867     return FALSE;
868   if (!G_VALUE_HOLDS_BOOLEAN (&field->value))
869     return FALSE;
870
871   *value = g_value_get_boolean (&field->value);
872
873   return TRUE;
874 }
875
876 /**
877  * gst_structure_get_int:
878  * @structure: a #GstStructure
879  * @fieldname: the name of a field
880  * @value: a pointer to an int to set
881  *
882  * Sets the int pointed to by @value corresponding to the value of the
883  * given field.  Caller is responsible for making sure the field exists
884  * and has the correct type.
885  *
886  * Returns: TRUE if the value could be set correctly
887  */
888 gboolean
889 gst_structure_get_int (const GstStructure * structure,
890     const gchar * fieldname, gint * value)
891 {
892   GstStructureField *field;
893
894   g_return_val_if_fail (structure != NULL, FALSE);
895   g_return_val_if_fail (fieldname != NULL, FALSE);
896   g_return_val_if_fail (value != NULL, FALSE);
897
898   field = gst_structure_get_field (structure, fieldname);
899
900   if (field == NULL)
901     return FALSE;
902   if (!G_VALUE_HOLDS_INT (&field->value))
903     return FALSE;
904
905   *value = g_value_get_int (&field->value);
906
907   return TRUE;
908 }
909
910 /**
911  * gst_structure_get_fourcc:
912  * @structure: a #GstStructure
913  * @fieldname: the name of a field
914  * @value: a pointer to a #GstFourcc to set
915  *
916  * Sets the #GstFourcc pointed to by @value corresponding to the value of the
917  * given field.  Caller is responsible for making sure the field exists
918  * and has the correct type.
919  *
920  * Returns: TRUE if the value could be set correctly
921  */
922 gboolean
923 gst_structure_get_fourcc (const GstStructure * structure,
924     const gchar * fieldname, guint32 * value)
925 {
926   GstStructureField *field;
927
928   g_return_val_if_fail (structure != NULL, FALSE);
929   g_return_val_if_fail (fieldname != NULL, FALSE);
930   g_return_val_if_fail (value != NULL, FALSE);
931
932   field = gst_structure_get_field (structure, fieldname);
933
934   if (field == NULL)
935     return FALSE;
936   if (!GST_VALUE_HOLDS_FOURCC (&field->value))
937     return FALSE;
938
939   *value = gst_value_get_fourcc (&field->value);
940
941   return TRUE;
942 }
943
944 /**
945  * gst_structure_get_double:
946  * @structure: a #GstStructure
947  * @fieldname: the name of a field
948  * @value: a pointer to a #GstFourcc to set
949  *
950  * Sets the double pointed to by @value corresponding to the value of the
951  * given field.  Caller is responsible for making sure the field exists
952  * and has the correct type.
953  *
954  * Returns: TRUE if the value could be set correctly
955  */
956 gboolean
957 gst_structure_get_double (const GstStructure * structure,
958     const gchar * fieldname, gdouble * value)
959 {
960   GstStructureField *field;
961
962   g_return_val_if_fail (structure != NULL, FALSE);
963   g_return_val_if_fail (fieldname != NULL, FALSE);
964   g_return_val_if_fail (value != NULL, FALSE);
965
966   field = gst_structure_get_field (structure, fieldname);
967
968   if (field == NULL)
969     return FALSE;
970   if (!G_VALUE_HOLDS_DOUBLE (&field->value))
971     return FALSE;
972
973   *value = g_value_get_double (&field->value);
974
975   return TRUE;
976 }
977
978 /**
979  * gst_structure_get_string:
980  * @structure: a #GstStructure
981  * @fieldname: the name of a field
982  *
983  * Finds the field corresponding to @fieldname, and returns the string
984  * contained in the field's value.  Caller is responsible for making
985  * sure the field exists and has the correct type.
986  *
987  * The string should not be modified, and remains valid until the next
988  * call to a gst_structure_*() function with the given structure.
989  *
990  * Returns: a pointer to the string
991  */
992 const gchar *
993 gst_structure_get_string (const GstStructure * structure,
994     const gchar * fieldname)
995 {
996   GstStructureField *field;
997
998   g_return_val_if_fail (structure != NULL, NULL);
999   g_return_val_if_fail (fieldname != NULL, NULL);
1000
1001   field = gst_structure_get_field (structure, fieldname);
1002
1003   if (field == NULL)
1004     return NULL;
1005   if (!G_VALUE_HOLDS_STRING (&field->value))
1006     return NULL;
1007
1008   return g_value_get_string (&field->value);
1009 }
1010
1011 typedef struct _GstStructureAbbreviation
1012 {
1013   char *type_name;
1014   GType type;
1015 }
1016 GstStructureAbbreviation;
1017
1018 static GstStructureAbbreviation *
1019 gst_structure_get_abbrs (gint * n_abbrs)
1020 {
1021   static GstStructureAbbreviation *abbrs = NULL;
1022   static gint num = 0;
1023
1024   if (abbrs == NULL) {
1025     /* dynamically generate the array */
1026     GstStructureAbbreviation dyn_abbrs[] = {
1027       {"int", G_TYPE_INT}
1028       ,
1029       {"i", G_TYPE_INT}
1030       ,
1031       {"float", G_TYPE_FLOAT}
1032       ,
1033       {"f", G_TYPE_FLOAT}
1034       ,
1035       {"double", G_TYPE_DOUBLE}
1036       ,
1037       {"d", G_TYPE_DOUBLE}
1038       ,
1039       {"buffer", GST_TYPE_BUFFER}
1040       ,
1041       {"fourcc", GST_TYPE_FOURCC}
1042       ,
1043       {"4", GST_TYPE_FOURCC}
1044       ,
1045       {"fraction", GST_TYPE_FRACTION}
1046       ,
1047       {"boolean", G_TYPE_BOOLEAN}
1048       ,
1049       {"bool", G_TYPE_BOOLEAN}
1050       ,
1051       {"b", G_TYPE_BOOLEAN}
1052       ,
1053       {"string", G_TYPE_STRING}
1054       ,
1055       {"str", G_TYPE_STRING}
1056       ,
1057       {"s", G_TYPE_STRING}
1058     };
1059     num = G_N_ELEMENTS (dyn_abbrs);
1060     /* permanently allocate and copy the array now */
1061     abbrs = g_new0 (GstStructureAbbreviation, num);
1062     memcpy (abbrs, dyn_abbrs, sizeof (GstStructureAbbreviation) * num);
1063   }
1064   *n_abbrs = num;
1065
1066   return abbrs;
1067 }
1068
1069 static GType
1070 gst_structure_from_abbr (const char *type_name)
1071 {
1072   int i;
1073   GstStructureAbbreviation *abbrs;
1074   gint n_abbrs;
1075
1076   g_return_val_if_fail (type_name != NULL, G_TYPE_INVALID);
1077
1078   abbrs = gst_structure_get_abbrs (&n_abbrs);
1079
1080   for (i = 0; i < n_abbrs; i++) {
1081     if (strcmp (type_name, abbrs[i].type_name) == 0) {
1082       return abbrs[i].type;
1083     }
1084   }
1085
1086   /* this is the fallback */
1087   return g_type_from_name (type_name);
1088 }
1089
1090 static const char *
1091 gst_structure_to_abbr (GType type)
1092 {
1093   int i;
1094   GstStructureAbbreviation *abbrs;
1095   gint n_abbrs;
1096
1097   g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
1098
1099   abbrs = gst_structure_get_abbrs (&n_abbrs);
1100
1101   for (i = 0; i < n_abbrs; i++) {
1102     if (type == abbrs[i].type) {
1103       return abbrs[i].type_name;
1104     }
1105   }
1106
1107   return g_type_name (type);
1108 }
1109
1110 static GType
1111 gst_structure_value_get_generic_type (GValue * val)
1112 {
1113   if (G_VALUE_TYPE (val) == GST_TYPE_LIST
1114       || G_VALUE_TYPE (val) == GST_TYPE_ARRAY) {
1115     GArray *array = g_value_peek_pointer (val);
1116
1117     if (array->len > 0) {
1118       GValue *value = &g_array_index (array, GValue, 0);
1119
1120       return gst_structure_value_get_generic_type (value);
1121     } else {
1122       return G_TYPE_INT;
1123     }
1124   } else if (G_VALUE_TYPE (val) == GST_TYPE_INT_RANGE) {
1125     return G_TYPE_INT;
1126   } else if (G_VALUE_TYPE (val) == GST_TYPE_DOUBLE_RANGE) {
1127     return G_TYPE_DOUBLE;
1128   }
1129   return G_VALUE_TYPE (val);
1130 }
1131
1132 #define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
1133       ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
1134       ((c) == '.'))
1135
1136 /**
1137  * gst_structure_to_string:
1138  * @structure: a #GstStructure
1139  *
1140  * Converts @structure to a human-readable representation.
1141  * 
1142  * Returns: a pointer to string allocated by g_malloc()
1143  */
1144 gchar *
1145 gst_structure_to_string (const GstStructure * structure)
1146 {
1147   GstStructureField *field;
1148   GString *s;
1149   int i;
1150
1151   /* NOTE:  This function is potentially called by the debug system,
1152    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1153    * should be careful to avoid recursion.  This includes any functions
1154    * called by gst_structure_to_string.  In particular, calls should
1155    * not use the GST_PTR_FORMAT extension.  */
1156
1157   g_return_val_if_fail (structure != NULL, NULL);
1158
1159   s = g_string_new ("");
1160   /* FIXME this string may need to be escaped */
1161   g_string_append_printf (s, "%s", g_quark_to_string (structure->name));
1162   for (i = 0; i < structure->fields->len; i++) {
1163     char *t;
1164     GType type;
1165
1166     field = GST_STRUCTURE_FIELD (structure, i);
1167
1168     t = gst_value_serialize (&field->value);
1169     type = gst_structure_value_get_generic_type (&field->value);
1170
1171     g_string_append_printf (s, ", %s=(%s)%s", g_quark_to_string (field->name),
1172         gst_structure_to_abbr (type), t);
1173     g_free (t);
1174   }
1175   return g_string_free (s, FALSE);
1176 }
1177
1178 /*
1179  * r will still point to the string. if end == next, the string will not be 
1180  * null-terminated. In all other cases it will be.
1181  * end = pointer to char behind end of string, next = pointer to start of
1182  * unread data.
1183  * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING 
1184  */
1185 static gboolean
1186 gst_structure_parse_string (gchar * s, gchar ** end, gchar ** next)
1187 {
1188   gchar *w;
1189
1190   if (*s == 0)
1191     return FALSE;
1192
1193   if (*s != '"') {
1194     int ret;
1195
1196     ret = gst_structure_parse_simple_string (s, end);
1197     *next = *end;
1198
1199     return ret;
1200   }
1201
1202   w = s;
1203   s++;
1204   while (*s != '"') {
1205     if (*s == 0)
1206       return FALSE;
1207
1208     if (*s == '\\') {
1209       s++;
1210     }
1211
1212     *w = *s;
1213     w++;
1214     s++;
1215   }
1216   s++;
1217
1218   *end = w;
1219   *next = s;
1220
1221   return TRUE;
1222 }
1223
1224 static gboolean
1225 gst_structure_parse_range (gchar * s, gchar ** after, GValue * value,
1226     GType type)
1227 {
1228   GValue value1 = { 0 };
1229   GValue value2 = { 0 };
1230   GType range_type;
1231   gboolean ret;
1232
1233
1234   if (*s != '[')
1235     return FALSE;
1236   s++;
1237
1238   ret = gst_structure_parse_value (s, &s, &value1, type);
1239   if (ret == FALSE)
1240     return FALSE;
1241
1242   while (g_ascii_isspace (*s))
1243     s++;
1244
1245   if (*s != ',')
1246     return FALSE;
1247   s++;
1248
1249   while (g_ascii_isspace (*s))
1250     s++;
1251
1252   ret = gst_structure_parse_value (s, &s, &value2, type);
1253   if (ret == FALSE)
1254     return FALSE;
1255
1256   while (g_ascii_isspace (*s))
1257     s++;
1258
1259   if (*s != ']')
1260     return FALSE;
1261   s++;
1262
1263   if (G_VALUE_TYPE (&value1) != G_VALUE_TYPE (&value2))
1264     return FALSE;
1265
1266   if (G_VALUE_TYPE (&value1) == G_TYPE_DOUBLE) {
1267     range_type = GST_TYPE_DOUBLE_RANGE;
1268   } else if (G_VALUE_TYPE (&value1) == G_TYPE_INT) {
1269     range_type = GST_TYPE_INT_RANGE;
1270   } else {
1271     return FALSE;
1272   }
1273
1274   g_value_init (value, range_type);
1275   if (range_type == GST_TYPE_DOUBLE_RANGE) {
1276     gst_value_set_double_range (value, g_value_get_double (&value1),
1277         g_value_get_double (&value2));
1278   } else {
1279     gst_value_set_int_range (value, g_value_get_int (&value1),
1280         g_value_get_int (&value2));
1281   }
1282
1283   *after = s;
1284   return TRUE;
1285 }
1286
1287 static gboolean
1288 gst_structure_parse_any_list (gchar * s, gchar ** after, GValue * value,
1289     GType type, GType list_type, char begin, char end)
1290 {
1291   GValue list_value = { 0 };
1292   gboolean ret;
1293   GArray *array;
1294
1295   g_value_init (value, list_type);
1296   array = g_value_peek_pointer (value);
1297
1298   if (*s != begin)
1299     return FALSE;
1300   s++;
1301
1302   while (g_ascii_isspace (*s))
1303     s++;
1304   if (*s == end) {
1305     s++;
1306     *after = s;
1307     return TRUE;
1308   }
1309
1310   ret = gst_structure_parse_value (s, &s, &list_value, type);
1311   if (ret == FALSE)
1312     return FALSE;
1313
1314   g_array_append_val (array, list_value);
1315
1316   while (g_ascii_isspace (*s))
1317     s++;
1318
1319   while (*s != end) {
1320     if (*s != ',')
1321       return FALSE;
1322     s++;
1323
1324     while (g_ascii_isspace (*s))
1325       s++;
1326
1327     memset (&list_value, 0, sizeof (list_value));
1328     ret = gst_structure_parse_value (s, &s, &list_value, type);
1329     if (ret == FALSE)
1330       return FALSE;
1331
1332     g_array_append_val (array, list_value);
1333     while (g_ascii_isspace (*s))
1334       s++;
1335   }
1336
1337   s++;
1338
1339   *after = s;
1340   return TRUE;
1341 }
1342
1343 static gboolean
1344 gst_structure_parse_list (gchar * s, gchar ** after, GValue * value, GType type)
1345 {
1346   return gst_structure_parse_any_list (s, after, value, type, GST_TYPE_LIST,
1347       '{', '}');
1348 }
1349
1350 static gboolean
1351 gst_structure_parse_array (gchar * s, gchar ** after, GValue * value,
1352     GType type)
1353 {
1354   return gst_structure_parse_any_list (s, after, value, type,
1355       GST_TYPE_ARRAY, '<', '>');
1356 }
1357
1358 static gboolean
1359 gst_structure_parse_simple_string (gchar * str, gchar ** end)
1360 {
1361   char *s = str;
1362
1363   while (GST_ASCII_IS_STRING (*s)) {
1364     s++;
1365   }
1366
1367   *end = s;
1368
1369   return (s != str);
1370 }
1371
1372 static gboolean
1373 gst_structure_parse_field (gchar * str,
1374     gchar ** after, GstStructureField * field)
1375 {
1376   gchar *name;
1377   gchar *name_end;
1378   gchar *s;
1379   gchar c;
1380
1381   s = str;
1382
1383   while (g_ascii_isspace (*s))
1384     s++;
1385   name = s;
1386   if (!gst_structure_parse_simple_string (s, &name_end))
1387     return FALSE;
1388
1389   s = name_end;
1390   while (g_ascii_isspace (*s))
1391     s++;
1392
1393   if (*s != '=')
1394     return FALSE;
1395   s++;
1396
1397   c = *name_end;
1398   *name_end = 0;
1399   field->name = g_quark_from_string (name);
1400   *name_end = c;
1401
1402   if (!gst_structure_parse_value (s, &s, &field->value, G_TYPE_INVALID))
1403     return FALSE;
1404
1405   *after = s;
1406   return TRUE;
1407 }
1408
1409 static gboolean
1410 gst_structure_parse_value (gchar * str,
1411     gchar ** after, GValue * value, GType default_type)
1412 {
1413   gchar *type_name;
1414   gchar *type_end;
1415   gchar *value_s;
1416   gchar *value_end;
1417   gchar *s;
1418   gchar c;
1419   int ret = 0;
1420   GType type = default_type;
1421
1422
1423   s = str;
1424   while (g_ascii_isspace (*s))
1425     s++;
1426
1427   type_name = NULL;
1428   if (*s == '(') {
1429     type = G_TYPE_INVALID;
1430
1431     s++;
1432     while (g_ascii_isspace (*s))
1433       s++;
1434     type_name = s;
1435     if (!gst_structure_parse_simple_string (s, &type_end))
1436       return FALSE;
1437     s = type_end;
1438     while (g_ascii_isspace (*s))
1439       s++;
1440     if (*s != ')')
1441       return FALSE;
1442     s++;
1443     while (g_ascii_isspace (*s))
1444       s++;
1445
1446     c = *type_end;
1447     *type_end = 0;
1448     type = gst_structure_from_abbr (type_name);
1449     *type_end = c;
1450
1451     if (type == G_TYPE_INVALID)
1452       return FALSE;
1453   }
1454
1455   while (g_ascii_isspace (*s))
1456     s++;
1457   if (*s == '[') {
1458     ret = gst_structure_parse_range (s, &s, value, type);
1459   } else if (*s == '{') {
1460     ret = gst_structure_parse_list (s, &s, value, type);
1461   } else if (*s == '<') {
1462     ret = gst_structure_parse_array (s, &s, value, type);
1463   } else {
1464     value_s = s;
1465     if (!gst_structure_parse_string (s, &value_end, &s))
1466       return FALSE;
1467
1468     c = *value_end;
1469     *value_end = 0;
1470     if (type == G_TYPE_INVALID) {
1471       GType try_types[] = { G_TYPE_INT, G_TYPE_DOUBLE, G_TYPE_STRING };
1472       int i;
1473
1474       for (i = 0; i < 3; i++) {
1475         g_value_init (value, try_types[i]);
1476         ret = gst_value_deserialize (value, value_s);
1477         if (ret)
1478           break;
1479         g_value_unset (value);
1480       }
1481     } else {
1482       g_value_init (value, type);
1483
1484       ret = gst_value_deserialize (value, value_s);
1485     }
1486     *value_end = c;
1487   }
1488
1489   *after = s;
1490
1491   return ret;
1492 }
1493
1494 /**
1495  * gst_structure_from_string:
1496  * @string: a string representation of a #GstStructure.
1497  * @end: pointer to store the end of the string in.
1498  *
1499  * Creates a #GstStructure from a string representation.
1500  * If end is not NULL, a pointer to the place inside the given string
1501  * where parsing ended will be returned.
1502  *
1503  * Returns: a new #GstStructure
1504  */
1505 GstStructure *
1506 gst_structure_from_string (const gchar * string, gchar ** end)
1507 {
1508   char *name;
1509   char *copy;
1510   char *w;
1511   char *r;
1512   char save;
1513   GstStructure *structure = NULL;
1514   GstStructureField field = { 0 };
1515
1516   g_return_val_if_fail (string != NULL, NULL);
1517
1518   copy = g_strdup (string);
1519   r = copy;
1520
1521   name = r;
1522   if (!gst_structure_parse_string (r, &w, &r))
1523     goto error;
1524
1525   while (g_ascii_isspace (*r))
1526     r++;
1527   if (*r != 0 && *r != ';' && *r != ',')
1528     goto error;
1529
1530   save = *w;
1531   *w = 0;
1532   structure = gst_structure_empty_new (name);
1533   *w = save;
1534
1535   while (*r && (*r != ';')) {
1536     if (*r != ',')
1537       goto error;
1538     r++;
1539     while (*r && g_ascii_isspace (*r))
1540       r++;
1541
1542     memset (&field, 0, sizeof (field));
1543     if (!gst_structure_parse_field (r, &r, &field))
1544       goto error;
1545     gst_structure_set_field (structure, &field);
1546     while (*r && g_ascii_isspace (*r))
1547       r++;
1548   }
1549
1550   if (end)
1551     *end = (char *) string + (r - copy);
1552
1553   g_free (copy);
1554   return structure;
1555
1556 error:
1557   if (structure)
1558     gst_structure_free (structure);
1559   g_free (copy);
1560   return NULL;
1561 }
1562
1563 static void
1564 gst_structure_transform_to_string (const GValue * src_value,
1565     GValue * dest_value)
1566 {
1567   g_return_if_fail (src_value != NULL);
1568   g_return_if_fail (dest_value != NULL);
1569
1570   dest_value->data[0].v_pointer =
1571       gst_structure_to_string (src_value->data[0].v_pointer);
1572 }
1573
1574 static GstStructure *
1575 gst_structure_copy_conditional (const GstStructure * structure)
1576 {
1577   if (structure)
1578     return gst_structure_copy (structure);
1579   return NULL;
1580 }
1581
1582 /* fixate utility functions */
1583
1584 /**
1585  * gst_caps_structure_fixate_field_nearest_int:
1586  * @structure: a #GstStructure
1587  * @field_name: a field in @structure
1588  * @target: the target value of the fixation
1589  *
1590  * Fixates a #GstStructure by changing the given field to the nearest
1591  * integer to @target that is a subset of the existing field.
1592  *
1593  * Returns: TRUE if the structure could be fixated
1594  */
1595 gboolean
1596 gst_caps_structure_fixate_field_nearest_int (GstStructure * structure,
1597     const char *field_name, int target)
1598 {
1599   const GValue *value;
1600
1601   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
1602   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1603
1604   value = gst_structure_get_value (structure, field_name);
1605
1606   if (G_VALUE_TYPE (value) == G_TYPE_INT) {
1607     /* already fixed */
1608     return FALSE;
1609   } else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
1610     int x;
1611
1612     x = gst_value_get_int_range_min (value);
1613     if (target < x)
1614       target = x;
1615     x = gst_value_get_int_range_max (value);
1616     if (target > x)
1617       target = x;
1618     gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
1619     return TRUE;
1620   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1621     const GValue *list_value;
1622     int i, n;
1623     int best = 0;
1624     int best_index = -1;
1625
1626     n = gst_value_list_get_size (value);
1627     for (i = 0; i < n; i++) {
1628       list_value = gst_value_list_get_value (value, i);
1629       if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
1630         int x = g_value_get_int (list_value);
1631
1632         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
1633           best_index = i;
1634           best = x;
1635         }
1636       }
1637     }
1638     if (best_index != -1) {
1639       gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
1640       return TRUE;
1641     }
1642     return FALSE;
1643   }
1644
1645   return FALSE;
1646 }
1647
1648 /**
1649  * gst_caps_structure_fixate_field_nearest_double:
1650  * @structure: a #GstStructure
1651  * @field_name: a field in @structure
1652  * @target: the target value of the fixation
1653  *
1654  * Fixates a #GstStructure by changing the given field to the nearest
1655  * double to @target that is a subset of the existing field.
1656  *
1657  * Returns: TRUE if the structure could be fixated
1658  */
1659 gboolean
1660 gst_caps_structure_fixate_field_nearest_double (GstStructure * structure,
1661     const char *field_name, double target)
1662 {
1663   const GValue *value;
1664
1665   g_return_val_if_fail (gst_structure_has_field (structure, field_name), FALSE);
1666   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
1667
1668   value = gst_structure_get_value (structure, field_name);
1669
1670   if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
1671     /* already fixed */
1672     return FALSE;
1673   } else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
1674     double x;
1675
1676     x = gst_value_get_double_range_min (value);
1677     if (target < x)
1678       target = x;
1679     x = gst_value_get_double_range_max (value);
1680     if (target > x)
1681       target = x;
1682     gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
1683     return TRUE;
1684   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1685     const GValue *list_value;
1686     int i, n;
1687     double best = 0;
1688     int best_index = -1;
1689
1690     n = gst_value_list_get_size (value);
1691     for (i = 0; i < n; i++) {
1692       list_value = gst_value_list_get_value (value, i);
1693       if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
1694         double x = g_value_get_double (list_value);
1695
1696         if (best_index == -1 || (ABS (target - x) < ABS (target - best))) {
1697           best_index = i;
1698           best = x;
1699         }
1700       }
1701     }
1702     if (best_index != -1) {
1703       gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);
1704       return TRUE;
1705     }
1706     return FALSE;
1707   }
1708
1709   return FALSE;
1710
1711 }