fix doc build fix autogen
[platform/upstream/gstreamer.git] / gst / gstcaps.c
1 /* GStreamer
2  * Copyright (C) <2003> David A. Schleef <ds@schleef.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include <string.h>
24
25 #include <gst/gst.h>
26
27 #define CAPS_POISON(caps) do{ \
28   GstCaps *_newcaps = gst_caps_copy (caps); \
29   gst_caps_free(caps); \
30   caps = _newcaps; \
31 } while (0)
32 #define STRUCTURE_POISON(structure) do{ \
33   GstStructure *_newstruct = gst_structure_copy (structure); \
34   gst_structure_free(structure); \
35   structure = _newstruct; \
36 } while (0)
37
38
39 static void _gst_caps_transform_to_string (const GValue *src_value,
40     GValue *dest_value);
41 static void _gst_caps_value_init (GValue *value);
42 static void _gst_caps_value_free (GValue *value);
43 static void _gst_caps_value_copy (const GValue *src, GValue *dest);
44 static gpointer _gst_caps_value_peek_pointer (const GValue *value);
45 static gboolean _gst_caps_from_string_inplace (GstCaps *caps,
46     const gchar *string);
47
48
49 GType _gst_caps_type;
50
51 void _gst_caps_initialize (void)
52 {
53   static const GTypeValueTable type_value_table = {
54     _gst_caps_value_init,
55     _gst_caps_value_free,
56     _gst_caps_value_copy,
57     _gst_caps_value_peek_pointer,
58     NULL,
59     NULL,
60     NULL,
61     NULL,
62   };
63   static const GTypeInfo caps2_info = {
64     0,
65     NULL,
66     NULL,
67     NULL,
68     NULL,
69     NULL,
70     0,
71     0,
72     NULL,
73     &type_value_table,
74   };
75
76   _gst_caps_type = g_type_register_static (G_TYPE_BOXED, "GstCaps",
77       &caps2_info, 0);
78
79   g_value_register_transform_func (_gst_caps_type, G_TYPE_STRING,
80       _gst_caps_transform_to_string);
81 }
82
83 GType gst_caps_get_type (void)
84 {
85   return _gst_caps_type;
86 }
87
88 /* creation/deletion */
89
90 /**
91  * gst_caps_new_empty:
92  *
93  * Creates a new #GstCaps that is empty.  That is, the returned
94  * #GstCaps contains no media formats.
95  *
96  * Returns: the new #GstCaps
97  */
98 GstCaps *gst_caps_new_empty (void)
99 {
100   GstCaps *caps = g_new0(GstCaps, 1);
101
102   caps->type = _gst_caps_type;
103   caps->structs = g_ptr_array_new();
104
105   return caps;
106 }
107
108 /**
109  * gst_caps_new_empty:
110  *
111  * Creates a new #GstCaps that indicates that it is compatible with
112  * any media format.
113  *
114  * Returns: the new #GstCaps
115  */
116 GstCaps *gst_caps_new_any (void)
117 {
118   GstCaps *caps = g_new0(GstCaps, 1);
119
120   caps->type = _gst_caps_type;
121   caps->structs = g_ptr_array_new();
122   caps->flags = GST_CAPS_FLAGS_ANY;
123
124   return caps;
125 }
126
127 /**
128  * gst_caps_new_simple:
129  * @media_type: the media type of the structure
130  * @...: additional arguments
131  *
132  * Creates a new #GstCaps that contains one #GstStructure.  The
133  * structure is defined by the arguments, which have the same format
134  * as @gst_structure_new().
135  *
136  * Returns: the new #GstCaps
137  */
138 GstCaps *gst_caps_new_simple (const char *media_type, const char *fieldname,
139     ...)
140 {
141   GstCaps *caps;
142   GstStructure *structure;
143   va_list var_args;
144
145   caps = g_new0(GstCaps, 1);
146   caps->type = _gst_caps_type;
147   caps->structs = g_ptr_array_new();
148
149   va_start (var_args, fieldname);
150   structure = gst_structure_new_valist (media_type, fieldname, var_args);
151   va_end (var_args);
152
153   gst_caps_append_structure (caps, structure);
154   
155   return caps;
156 }
157
158 /**
159  * gst_caps_new_full:
160  * @struct1: the first structure to add
161  * @...: additional structures to add
162  *
163  * Creates a new #GstCaps and adds all the structures listed as
164  * arguments.  The list must be NULL-terminated.  The structures
165  * are not copied; the returned #GstCaps owns the structures.
166  *
167  * Returns: the new #GstCaps
168  */
169 GstCaps *gst_caps_new_full (GstStructure *struct1, ...)
170 {
171   GstCaps *caps;
172   va_list var_args;
173
174   va_start (var_args, struct1);
175   caps = gst_caps_new_full_valist (struct1, var_args);
176   va_end (var_args);
177
178   return caps;
179 }
180
181 /**
182  * gst_caps_new_full_valist:
183  * @struct1: the first structure to add
184  * @var_args: additional structures to add
185  *
186  * Creates a new #GstCaps and adds all the structures listed as
187  * arguments.  The list must be NULL-terminated.  The structures
188  * are not copied; the returned #GstCaps owns the structures.
189  *
190  * Returns: the new #GstCaps
191  */
192 GstCaps *gst_caps_new_full_valist (GstStructure *structure,
193     va_list var_args)
194 {
195   GstCaps *caps;
196
197   caps = g_new0(GstCaps, 1);
198   caps->type = _gst_caps_type;
199   caps->structs = g_ptr_array_new();
200
201   while(structure){
202     gst_caps_append_structure (caps, structure);
203     structure = va_arg (var_args, GstStructure *);
204   }
205
206   return caps;
207 }
208
209 /**
210  * gst_caps_copy:
211  * @caps: the #GstCaps to copy
212  *
213  * Deeply copies a #GstCaps, including all structures and all the
214  * structures' values.
215  *
216  * Returns: the new #GstCaps
217  */
218 GstCaps *gst_caps_copy (const GstCaps *caps)
219 {
220   GstCaps *newcaps;
221   GstStructure *structure;
222   int i;
223
224   g_return_val_if_fail(caps != NULL, NULL);
225
226   newcaps = g_new0(GstCaps, 1);
227   newcaps->type = _gst_caps_type;
228   newcaps->flags = caps->flags;
229   newcaps->structs = g_ptr_array_new();
230
231   for(i=0;i<caps->structs->len;i++){
232     structure = gst_caps_get_structure (caps, i);
233     gst_caps_append_structure (newcaps, gst_structure_copy(structure));
234   }
235
236   return newcaps;
237 }
238
239 /**
240  * gst_caps_free:
241  * @caps: the #GstCaps to free
242  *
243  * Frees a #GstCaps and all its structures and the structures'
244  * values.
245  */
246 void gst_caps_free (GstCaps *caps)
247 {
248   GstStructure *structure;
249   int i;
250   
251   g_return_if_fail(caps != NULL);
252
253   for(i=0;i<caps->structs->len;i++){
254     structure = gst_caps_get_structure (caps, i);
255     gst_structure_free (structure);
256   }
257   g_ptr_array_free(caps->structs, TRUE);
258 #ifdef USE_POISONING
259   memset (caps, 0xff, sizeof(GstCaps));
260 #endif
261   g_free(caps);
262 }
263
264 /**
265  * gst_static_caps_get:
266  * @static_caps: the #GstStaticCaps to convert
267  *
268  * Converts a #GstStaticCaps to a #GstCaps.
269  *
270  * Returns: the new #GstCaps
271  */
272 const GstCaps *gst_static_caps_get (GstStaticCaps *static_caps)
273 {
274   GstCaps *caps = (GstCaps *)static_caps;
275   gboolean ret;
276
277   if (caps->type == 0) {
278     caps->type = _gst_caps_type;
279     caps->structs = g_ptr_array_new();
280     ret = _gst_caps_from_string_inplace (caps, static_caps->string);
281
282     if (!ret) {
283       g_critical ("Could not convert static caps \"%s\"", static_caps->string);
284     }
285   }
286
287   return caps;
288 }
289
290 /* manipulation */
291
292 /**
293  * gst_caps_append:
294  * @caps1: the #GstCaps that will be appended to
295  * @caps2: the #GstCaps to append
296  *
297  * Appends the structures contained in @caps2 to @caps1.  The structures
298  * in @caps2 are not copied -- they are transferred to @caps1, and then
299  * @caps2 is freed.
300  */
301 void gst_caps_append (GstCaps *caps1, GstCaps *caps2)
302 {
303   GstStructure *structure;
304   int i;
305
306   g_return_if_fail (caps1 != NULL);
307   g_return_if_fail (caps2 != NULL);
308
309 #ifdef USE_POISONING
310   CAPS_POISON (caps2);
311 #endif
312   for(i=0;i<caps2->structs->len;i++){
313     structure = gst_caps_get_structure (caps2, i);
314     gst_caps_append_structure (caps1, structure);
315   }
316   g_ptr_array_free(caps2->structs, TRUE);
317 #ifdef USE_POISONING
318   memset (caps2, 0xff, sizeof(GstCaps));
319 #endif
320   g_free(caps2);
321 }
322
323 /**
324  * gst_caps_append_structure:
325  * @caps: the #GstCaps that will be appended to
326  * @structure: the #GstStructure to append
327  *
328  * Appends @structure to @caps1.  The structure is not copied; @caps1
329  * becomes the owner of @structure.
330  */
331 void gst_caps_append_structure (GstCaps *caps, GstStructure *structure)
332 {
333   g_return_if_fail(caps != NULL);
334
335   if (structure){
336 #if 0
337 #ifdef USE_POISONING
338     STRUCTURE_POISON (structure);
339 #endif
340 #endif
341     g_ptr_array_add (caps->structs, structure);
342   }
343 }
344
345 /**
346  * gst_caps_split_one:
347  * @caps: 
348  *
349  * Returns:
350  */
351 GstCaps *gst_caps_split_one (GstCaps *caps)
352 {
353   /* FIXME */
354   g_critical ("unimplemented");
355
356   return NULL;
357 }
358
359 /**
360  * gst_caps_split_one:
361  * @caps: a #GstCaps
362  *
363  * Returns: the number of structures that @caps contains
364  */
365 int gst_caps_get_size (const GstCaps *caps)
366 {
367   g_return_val_if_fail (caps != NULL, 0);
368
369   return caps->structs->len;
370 }
371
372 /**
373  * gst_caps_get_structure:
374  * @caps: a #GstCaps
375  * @index: the index of the structure
376  *
377  * Finds the structure in @caps that has the index @index, and 
378  * returns it.
379  *
380  * WARNING: This function takes a const GstCaps *, but returns a
381  * non-const GstStructure *.  This is for programming convenience --
382  * the caller should be aware that structures inside a constant
383  * @GstCaps should not be modified.
384  *
385  * Returns: a pointer to the #GstStructure corresponding to @index
386  */
387 GstStructure *gst_caps_get_structure (const GstCaps *caps, int index)
388 {
389   g_return_val_if_fail (caps != NULL, NULL);
390   g_return_val_if_fail (index >= 0, NULL);
391   g_return_val_if_fail (index < caps->structs->len, NULL);
392
393   return g_ptr_array_index(caps->structs, index);
394 }
395
396 /**
397  * gst_caps_copy_1:
398  * @caps: the @GstCaps to copy
399  *
400  * Creates a new @GstCaps and appends a copy of the first structure
401  * contained in @caps.
402  *
403  * Returns: the new @GstCaps
404  */
405 GstCaps *gst_caps_copy_1 (const GstCaps *caps)
406 {
407   GstCaps *newcaps;
408   GstStructure *structure;
409
410   g_return_val_if_fail(caps != NULL, NULL);
411
412   newcaps = g_new0(GstCaps, 1);
413   newcaps->type = _gst_caps_type;
414   newcaps->flags = caps->flags;
415   newcaps->structs = g_ptr_array_new();
416
417   if (caps->structs->len > 0){
418     structure = gst_caps_get_structure (caps, 0);
419     gst_caps_append_structure (newcaps, gst_structure_copy(structure));
420   }
421
422   return newcaps;
423 }
424
425 /**
426  * gst_caps_set_simple:
427  * @caps: the @GstCaps to set
428  * @field: first field to set
429  * @...: additional parameters
430  *
431  * Sets fields in a simple #GstCaps.  A simple #GstCaps is one that
432  * only has one structure.  The arguments must be passed in the same
433  * manner as @gst_structure_set(), and be NULL-terminated.
434  */
435 void gst_caps_set_simple (GstCaps *caps, char *field, ...)
436 {
437   GstStructure *structure;
438   va_list var_args;
439
440   g_return_if_fail (caps != NULL);
441   g_return_if_fail (caps->structs->len == 1);
442
443   structure = gst_caps_get_structure (caps, 0);
444
445   va_start (var_args, field);
446   gst_structure_set_valist (structure, field, var_args);
447   va_end(var_args);
448 }
449
450 /**
451  * gst_caps_set_simple_valist:
452  * @caps: the @GstCaps to copy
453  * @field: first field to set
454  * @varargs: additional parameters
455  *
456  * Sets fields in a simple #GstCaps.  A simple #GstCaps is one that
457  * only has one structure.  The arguments must be passed in the same
458  * manner as @gst_structure_set(), and be NULL-terminated.
459  */
460 void gst_caps_set_simple_valist (GstCaps *caps, char *field, va_list varargs)
461 {
462   GstStructure *structure;
463
464   g_return_if_fail (caps != NULL);
465   g_return_if_fail (caps->structs->len != 1);
466
467   structure = gst_caps_get_structure (caps, 0);
468
469   gst_structure_set_valist (structure, field, varargs);
470 }
471
472 /* tests */
473
474 /**
475  * gst_caps_is_any:
476  * @caps: the @GstCaps to test
477  *
478  * Returns: TRUE if @caps represents any format.
479  */
480 gboolean gst_caps_is_any (const GstCaps *caps)
481 {
482   g_return_val_if_fail(caps != NULL, FALSE);
483
484   return (caps->flags & GST_CAPS_FLAGS_ANY);
485 }
486
487 /**
488  * gst_caps_is_empty:
489  * @caps: the @GstCaps to test
490  *
491  * Returns: TRUE if @caps represents no formats.
492  */
493 gboolean gst_caps_is_empty (const GstCaps *caps)
494 {
495   g_return_val_if_fail(caps != NULL, FALSE);
496
497   if (caps->flags & GST_CAPS_FLAGS_ANY) return FALSE;
498
499   return (caps->structs == NULL) || (caps->structs->len == 0);
500 }
501
502 /**
503  * gst_caps_is_chained:
504  * @caps: the @GstCaps to test
505  *
506  * Returns: TRUE if @caps contains more than one structure
507  */
508 gboolean gst_caps_is_chained (const GstCaps *caps)
509 {
510   g_return_val_if_fail(caps != NULL, FALSE);
511
512   return (caps->structs->len > 1);
513 }
514
515 static gboolean
516 _gst_caps_is_fixed_foreach (GQuark field_id, GValue *value, gpointer unused)
517 {
518   GType type = G_VALUE_TYPE (value);
519   if (G_TYPE_IS_FUNDAMENTAL (type)) return TRUE;
520   if (type == GST_TYPE_FOURCC) return TRUE;
521   return FALSE;
522 }
523
524 /**
525  * gst_caps_is_fixed:
526  * @caps: the @GstCaps to test
527  *
528  * Fixed @GstCaps describe exactly one format, that is, they have exactly
529  * one structure, and each field in the structure describes a fixed type.
530  * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
531  *
532  * Returns: TRUE if @caps is fixed
533  */
534 gboolean gst_caps_is_fixed (const GstCaps *caps)
535 {
536   GstStructure *structure;
537
538   g_return_val_if_fail(caps != NULL, FALSE);
539
540   if (caps->structs->len != 1) return FALSE;
541
542   structure = gst_caps_get_structure (caps, 0);
543
544   return gst_structure_foreach (structure, _gst_caps_is_fixed_foreach, NULL);
545 }
546
547 static gboolean
548 _gst_structure_is_equal_foreach (GQuark field_id, 
549     GValue *val2, gpointer data)
550 {
551   GstStructure *struct1 = (GstStructure *) data;
552   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
553
554   if (val1 == NULL) return FALSE;
555   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
556     return TRUE;
557   }
558
559   return FALSE;
560 }
561
562 /**
563  * gst_caps_is_equal_fixed:
564  * @caps1: the #GstCaps to test
565  * @caps2: the #GstCaps to test
566  *
567  * Tests if two #GstCaps are equal.  This function only works on fixed
568  * #GstCaps.
569  *
570  * Returns: TRUE if the arguments represent the same format
571  */
572 gboolean gst_caps_is_equal_fixed (const GstCaps *caps1, const GstCaps *caps2)
573 {
574   GstStructure *struct1, *struct2;
575
576   g_return_val_if_fail (gst_caps_is_fixed(caps1), FALSE);
577   g_return_val_if_fail (gst_caps_is_fixed(caps2), FALSE);
578
579   struct1 = gst_caps_get_structure (caps1, 0);
580   struct2 = gst_caps_get_structure (caps2, 0);
581
582   if (struct1->name != struct2->name) {
583     return FALSE;
584   }
585   if (struct1->fields->len != struct2->fields->len) {
586     return FALSE;
587   }
588
589   return gst_structure_foreach (struct1, _gst_structure_is_equal_foreach,
590       struct2);
591 }
592
593 static gboolean
594 _gst_structure_field_has_compatible (GQuark field_id, 
595     GValue *val2, gpointer data)
596 {
597   GValue dest = { 0 };
598   GstStructure *struct1 = (GstStructure *) data;
599   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
600
601   if (val1 == NULL) return FALSE;
602   if (gst_value_intersect (&dest, val1, val2)) {
603     g_value_unset (&dest);
604     return TRUE;
605   }
606
607   return FALSE;
608 }
609
610 static gboolean
611 _gst_cap_is_always_compatible (const GstStructure *struct1,
612     const GstStructure *struct2)
613 {
614   if(struct1->name != struct2->name){
615     return FALSE;
616   }
617
618   /* the reversed order is important */
619   return gst_structure_foreach ((GstStructure *) struct2, 
620       _gst_structure_field_has_compatible, (gpointer) struct1);
621 }
622
623 static gboolean
624 _gst_caps_cap_is_always_compatible (const GstStructure *struct1,
625     const GstCaps *caps2)
626 {
627   int i;
628
629   for(i=0;i<caps2->structs->len;i++){
630     GstStructure *struct2 = gst_caps_get_structure (caps2, i);
631
632     if (_gst_cap_is_always_compatible (struct1, struct2)) {
633       return TRUE;
634     }
635   }
636
637   return FALSE;
638 }
639
640 /**
641  * gst_caps_is_always_compatible
642  * @caps1: the #GstCaps to test
643  * @caps2: the #GstCaps to test
644  *
645  * Returns: TRUE if @caps1 is a subset of @caps2.
646  */
647 gboolean
648 gst_caps_is_always_compatible (const GstCaps *caps1, const GstCaps *caps2)
649 {
650   int i;
651
652   g_return_val_if_fail (caps1 != NULL, FALSE);
653   g_return_val_if_fail (caps2 != NULL, FALSE);
654   /* FIXME: is this right ? */
655   g_return_val_if_fail (!gst_caps_is_empty (caps1), FALSE);
656   g_return_val_if_fail (!gst_caps_is_empty (caps2), FALSE);
657   
658   if (gst_caps_is_any (caps2))
659     return TRUE;
660   if (gst_caps_is_any (caps1))
661     return FALSE;
662   
663   for(i=0;i<caps1->structs->len;i++) {
664     GstStructure *struct1 = gst_caps_get_structure (caps1, i);
665
666     if (_gst_caps_cap_is_always_compatible(struct1, caps2) == FALSE){
667       return FALSE;
668     }
669
670   }
671
672   return FALSE;
673 }
674
675 typedef struct {
676   GstStructure *dest;
677   const GstStructure *intersect;
678   gboolean first_run;
679 } IntersectData;
680
681 static gboolean
682 gst_caps_structure_intersect_field (GQuark id, GValue *val1, gpointer data)
683 {
684   IntersectData *idata = (IntersectData *) data;
685   GValue dest_value = { 0 };
686   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
687
688   if (val2 == NULL) {
689     gst_structure_id_set_value (idata->dest, id, val1);
690   } else if (idata->first_run) {
691     if (gst_value_intersect (&dest_value, val1, val2)) {
692       gst_structure_id_set_value (idata->dest, id, &dest_value);
693       g_value_unset (&dest_value);
694     } else {
695       return FALSE;
696     }
697   }
698   
699   return TRUE;
700 }
701
702 static GstStructure *gst_caps_structure_intersect (const GstStructure *struct1,
703     const GstStructure *struct2)
704 {
705   IntersectData data;
706
707   g_return_val_if_fail(struct1 != NULL, NULL);
708   g_return_val_if_fail(struct2 != NULL, NULL);
709
710   if (struct1->name != struct2->name) return NULL;
711
712   data.dest = gst_structure_id_empty_new (struct1->name);
713   data.intersect = struct2;
714   data.first_run = TRUE;
715   if (!gst_structure_foreach ((GstStructure *) struct1, 
716         gst_caps_structure_intersect_field, &data))
717     goto error;
718   
719   data.intersect = struct1;
720   data.first_run = FALSE;
721   if (!gst_structure_foreach ((GstStructure *) struct2, 
722         gst_caps_structure_intersect_field, &data))
723     goto error;
724
725   return data.dest;
726
727 error:
728   gst_structure_free (data.dest);
729   return NULL;
730 }
731
732 #if 0
733 static GstStructure *gst_caps_structure_union (const GstStructure *struct1,
734     const GstStructure *struct2)
735 {
736   int i;
737   GstStructure *dest;
738   const GstStructureField *field1;
739   const GstStructureField *field2;
740   int ret;
741
742   /* FIXME this doesn't actually work */
743
744   if (struct1->name != struct2->name) return NULL;
745
746   dest = gst_structure_id_empty_new (struct1->name);
747
748   for(i=0;i<struct1->fields->len;i++){
749     GValue dest_value = { 0 };
750
751     field1 = GST_STRUCTURE_FIELD (struct1, i);
752     field2 = gst_structure_id_get_field (struct2, field1->name);
753
754     if (field2 == NULL) {
755       continue;
756     } else {
757       if (gst_value_union (&dest_value, &field1->value, &field2->value)) {
758         gst_structure_set_value (dest, g_quark_to_string(field1->name),
759             &dest_value);
760       } else {
761         ret = gst_value_compare (&field1->value, &field2->value);
762       }
763     }
764   }
765
766   return dest;
767 }
768 #endif
769
770 /* operations */
771
772 /**
773  * gst_caps_intersect:
774  * @caps1: a #GstCaps to intersect
775  * @caps2: a #GstCaps to intersect
776  *
777  * Creates a new #GstCaps that contains all the formats that are common
778  * to both @caps1 and @caps2.
779  *
780  * Returns: the new #GstCaps
781  */
782 GstCaps *gst_caps_intersect (const GstCaps *caps1, const GstCaps *caps2)
783 {
784   int i,j;
785   GstStructure *struct1;
786   GstStructure *struct2;
787   GstCaps *dest;
788 #if 0
789   GstCaps *caps;
790 #endif
791
792   g_return_val_if_fail (caps1 != NULL, NULL);
793   g_return_val_if_fail (caps2 != NULL, NULL);
794
795   if (gst_caps_is_empty (caps1) || gst_caps_is_empty (caps2)){
796     return gst_caps_new_empty ();
797   }
798   if (gst_caps_is_any (caps1)) return gst_caps_copy (caps2);
799   if (gst_caps_is_any (caps2)) return gst_caps_copy (caps1);
800
801   dest = gst_caps_new_empty();
802   for(i=0;i<caps1->structs->len;i++){
803     struct1 = gst_caps_get_structure (caps1, i);
804     for(j=0;j<caps2->structs->len;j++){
805       GstStructure *istruct;
806
807       struct2 = gst_caps_get_structure (caps2, j);
808       istruct = gst_caps_structure_intersect (struct1, struct2);
809
810       gst_caps_append_structure(dest, istruct);
811     }
812   }
813
814 #if 0
815   caps = gst_caps_simplify (dest);
816   gst_caps_free (dest);
817
818   return caps;
819 #else
820   return dest;
821 #endif
822 }
823
824 /**
825  * gst_caps_union:
826  * @caps1: a #GstCaps to union
827  * @caps2: a #GstCaps to union
828  *
829  * Creates a new #GstCaps that contains all the formats that are in
830  * either @caps1 and @caps2.
831  *
832  * Returns: the new #GstCaps
833  */
834 GstCaps *gst_caps_union (const GstCaps *caps1, const GstCaps *caps2)
835 {
836   GstCaps *dest1;
837   GstCaps *dest2;
838
839   dest1 = gst_caps_copy (caps1);
840   dest2 = gst_caps_copy (caps2);
841   gst_caps_append (dest1, dest2);
842
843   /* FIXME: need a simplify function */
844
845   return dest1;
846 }
847
848 typedef struct _NormalizeForeach {
849   GstCaps *caps;
850   GstStructure *structure;
851 } NormalizeForeach;
852
853 static gboolean
854 _gst_caps_normalize_foreach (GQuark field_id, GValue *value, gpointer ptr)
855 {
856   NormalizeForeach *nf = (NormalizeForeach *) ptr;
857   GValue val = { 0 };
858   int i;
859
860   if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
861     for (i=1; i<gst_value_list_get_size (value); i++) {
862       const GValue *v = gst_value_list_get_value (value, i);
863       GstStructure *structure = gst_structure_copy (nf->structure);
864
865       gst_structure_id_set_value (structure, field_id, v);
866       gst_caps_append_structure (nf->caps, structure);
867     }
868
869     gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
870     gst_structure_id_set_value (nf->structure, field_id, &val);
871     g_value_unset (&val);
872
873     return FALSE;
874   }
875   return TRUE;
876 }
877
878 /**
879  * gst_caps_normalize:
880  * @caps: a #GstCaps to normalize
881  *
882  * Creates a new #GstCaps that represents the same set of formats as
883  * @caps, but contains no lists.  Each list is expanded into separate
884  * @GstStructures.
885  *
886  * Returns: the new #GstCaps
887  */
888 GstCaps *gst_caps_normalize (const GstCaps *caps)
889 {
890   NormalizeForeach nf;
891   GstCaps *newcaps;
892   int i;
893
894   g_return_val_if_fail(caps != NULL, NULL);
895
896   newcaps = gst_caps_copy (caps);
897   nf.caps = newcaps;
898
899   for(i=0;i<newcaps->structs->len;i++){
900     nf.structure = gst_caps_get_structure (newcaps, i);
901
902     while (!gst_structure_foreach (nf.structure, _gst_caps_normalize_foreach,
903           &nf));
904   }
905
906   return newcaps;
907 }
908
909 static gboolean
910 simplify_foreach (GQuark field_id, GValue *value, gpointer user_data)
911 {
912   GstStructure *s2 = (GstStructure *) user_data;
913   const GValue *v2;
914
915   v2 = gst_structure_id_get_value (s2, field_id);
916   if (v2 == NULL) return FALSE;
917
918   if (gst_value_compare (value, v2) == GST_VALUE_EQUAL) return TRUE;
919   return FALSE;
920 }
921
922 static gboolean
923 gst_caps_structure_simplify (GstStructure *struct1, const GstStructure *struct2)
924 {
925   /* FIXME this is just a simple compare.  Better would be to merge
926    * the two structures */
927   if (struct1->name != struct2->name) return FALSE;
928   if (struct1->fields->len != struct2->fields->len) return FALSE;
929
930   return gst_structure_foreach (struct1, simplify_foreach, (void *)struct2);
931 }
932
933 /**
934  * gst_caps_simplify:
935  * @caps: a #GstCaps to simplify
936  *
937  * Creates a new #GstCaps that represents the same set of formats as
938  * @caps, but simpler.  Component structures that are identical are
939  * merged.  Component structures that have ranges or lists that can
940  * be merged are also merged.
941  *
942  * Returns: the new #GstCaps
943  */
944 GstCaps *gst_caps_simplify (const GstCaps *caps)
945 {
946   int i;
947   int j;
948   GstCaps *newcaps;
949   GstStructure *structure;
950   GstStructure *struct2;
951
952   if (gst_caps_get_size (caps) < 2) {
953     return gst_caps_copy (caps);
954   }
955
956   newcaps = gst_caps_new_empty ();
957
958   for(i=0;i<gst_caps_get_size (caps);i++){
959     structure = gst_caps_get_structure (caps, i);
960
961     for(j=0;j<gst_caps_get_size (newcaps);j++){
962       struct2 = gst_caps_get_structure (caps, i);
963       if (gst_caps_structure_simplify (struct2, structure)) {
964         break;
965       }
966     }
967     if (j==gst_caps_get_size (newcaps)) {
968       gst_caps_append_structure (newcaps, gst_structure_copy(structure));
969     }
970   }
971
972   return newcaps;
973 }
974
975 #ifndef GST_DISABLE_LOADSAVE
976 xmlNodePtr gst_caps_save_thyself (const GstCaps *caps, xmlNodePtr parent)
977 {
978
979   return 0;
980 }
981
982 GstCaps *gst_caps_load_thyself (xmlNodePtr parent)
983 {
984
985   return NULL;
986 }
987 #endif
988
989 /* utility */
990
991 /**
992  * gst_caps_replace:
993  * @caps: a pointer to #GstCaps
994  * @newcaps: a #GstCaps to replace *caps
995  *
996  * Replaces *caps with @newcaps.  Frees the #GstCaps in the location
997  * pointed to by @caps, if applicable, then modifies @caps to point to
998  * @newcaps.
999  */
1000 void gst_caps_replace (GstCaps **caps, GstCaps *newcaps)
1001 {
1002 #if 0 /* disable this, since too many plugins rely on undefined behavior */
1003 #ifdef USE_POISONING
1004   //if (newcaps) CAPS_POISON (newcaps);
1005 #endif
1006 #endif
1007   if (*caps) gst_caps_free(*caps);
1008   *caps = newcaps;
1009 }
1010
1011 /**
1012  * gst_caps_to_string:
1013  * @caps: a #GstCaps
1014  *
1015  * Converts @caps to a string representation.  This string representation
1016  * can be converted back to a #GstCaps by #gst_caps_from_string().
1017  *
1018  * Returns: a string representing @caps
1019  */
1020 gchar *gst_caps_to_string (const GstCaps *caps)
1021 {
1022   int i;
1023   GstStructure *structure;
1024   GString *s;
1025
1026   /* FIXME does this leak? */
1027
1028   if (caps == NULL) {
1029     return g_strdup("NULL");
1030   }
1031   if(gst_caps_is_any(caps)){
1032     return g_strdup("ANY");
1033   }
1034   if(gst_caps_is_empty(caps)){
1035     return g_strdup("EMPTY");
1036   }
1037   s = g_string_new("");
1038   structure = gst_caps_get_structure (caps, 0);
1039   g_string_append(s, gst_structure_to_string(structure));
1040
1041   for(i=1;i<caps->structs->len;i++){
1042     structure = gst_caps_get_structure (caps, i);
1043
1044     g_string_append(s, "; ");
1045     g_string_append(s, gst_structure_to_string(structure));
1046   }
1047
1048   return g_string_free(s, FALSE);
1049 }
1050
1051 static gboolean _gst_caps_from_string_inplace (GstCaps *caps,
1052     const gchar *string)
1053 {
1054   GstStructure *structure;
1055   gchar *s;
1056
1057   if (strcmp("ANY", string)==0) {
1058     caps->flags = GST_CAPS_FLAGS_ANY;
1059     return TRUE;
1060   }
1061   if (strcmp("NONE", string)==0) {
1062     return TRUE;
1063   }
1064
1065   structure = gst_structure_from_string(string, &s);
1066   if (structure == NULL) {
1067     return FALSE;
1068   }
1069   gst_caps_append_structure (caps, structure);
1070
1071   while (*s == ';') {
1072     s++;
1073     while (g_ascii_isspace(*s))s++;
1074     structure = gst_structure_from_string(s, &s);
1075     if (structure == NULL) {
1076       return FALSE;
1077     }
1078     gst_caps_append_structure (caps, structure);
1079     while (g_ascii_isspace(*s))s++;
1080   }
1081
1082   if (*s != 0){
1083     return FALSE;
1084   }
1085
1086   return TRUE;
1087 }
1088
1089 /**
1090  * gst_caps_from_string:
1091  * @caps: a string to convert to #GstCaps
1092  *
1093  * Converts @caps from a string representation.
1094  *
1095  * Returns: a new #GstCaps
1096  */
1097 GstCaps *gst_caps_from_string (const gchar *string)
1098 {
1099   GstCaps *caps;
1100
1101   caps = gst_caps_new_empty();
1102   if (_gst_caps_from_string_inplace (caps, string)) {
1103     return caps;
1104   } else {
1105     gst_caps_free (caps);
1106     return NULL;
1107   }
1108 }
1109
1110 static void _gst_caps_transform_to_string (const GValue *src_value,
1111     GValue *dest_value)
1112 {
1113   g_return_if_fail (src_value != NULL);
1114   g_return_if_fail (dest_value != NULL);
1115
1116   dest_value->data[0].v_pointer =
1117     gst_caps_to_string (src_value->data[0].v_pointer);
1118 }
1119
1120 static void _gst_caps_value_init (GValue *value)
1121 {
1122   value->data[0].v_pointer = gst_caps_new_empty();
1123 }
1124
1125 static void _gst_caps_value_free (GValue *value)
1126 {
1127   if (value->data[0].v_pointer) gst_caps_free (value->data[0].v_pointer);
1128 }
1129
1130 static void _gst_caps_value_copy (const GValue *src, GValue *dest)
1131 {
1132   if (dest->data[0].v_pointer) {
1133     gst_caps_free (dest->data[0].v_pointer);
1134   }
1135   if (src->data[0].v_pointer) {
1136     dest->data[0].v_pointer = gst_caps_copy (src->data[0].v_pointer);
1137   } else {
1138     dest->data[0].v_pointer = NULL;
1139   }
1140 }
1141
1142 static gpointer _gst_caps_value_peek_pointer (const GValue *value)
1143 {
1144   return value->data[0].v_pointer;
1145 }
1146
1147 /* fixate utility functions */
1148
1149 gboolean gst_caps_structure_fixate_field_nearest_int (GstStructure *structure,
1150     const char *field_name, int target)
1151 {
1152   const GValue *value;
1153
1154   g_return_val_if_fail(gst_structure_has_field (structure, field_name), FALSE);
1155
1156   value = gst_structure_get_value (structure, field_name);
1157
1158   if (G_VALUE_TYPE (value) == G_TYPE_INT) {
1159     /* already fixed */
1160     return FALSE;
1161   } else if (G_VALUE_TYPE (value) == GST_TYPE_INT_RANGE) {
1162     int x;
1163     x = gst_value_get_int_range_min (value);
1164     if (target < x) target = x;
1165     x = gst_value_get_int_range_max (value);
1166     if (target > x) target = x;
1167     gst_structure_set (structure, field_name, G_TYPE_INT, target, NULL);
1168     return TRUE;
1169   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1170     const GValue *list_value;
1171     int i, n;
1172     int best = 0;
1173     int best_index = -1;
1174
1175     n = gst_value_list_get_size (value);
1176     for(i=0;i<n;i++){
1177       list_value = gst_value_list_get_value (value, i);
1178       if (G_VALUE_TYPE (list_value) == G_TYPE_INT) {
1179         int x = g_value_get_int (list_value);
1180         if (best_index == -1 || (ABS(target-x) < ABS(best-x))) {
1181           best_index = i;
1182           best = x;
1183         }
1184       }
1185     }
1186     if(best_index != -1) {
1187       gst_structure_set (structure, field_name, G_TYPE_INT, best, NULL);
1188       return TRUE;
1189     }
1190     return FALSE;
1191   }
1192
1193   return FALSE;
1194 }
1195
1196 gboolean gst_caps_structure_fixate_field_nearest_double (GstStructure
1197     *structure, const char *field_name, double target)
1198 {
1199   const GValue *value;
1200
1201   g_return_val_if_fail(gst_structure_has_field (structure, field_name), FALSE);
1202
1203   value = gst_structure_get_value (structure, field_name);
1204
1205   if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) {
1206     /* already fixed */
1207     return FALSE;
1208   } else if (G_VALUE_TYPE (value) == GST_TYPE_DOUBLE_RANGE) {
1209     double x;
1210     x = gst_value_get_double_range_min (value);
1211     if (target < x) target = x;
1212     x = gst_value_get_double_range_max (value);
1213     if (target > x) target = x;
1214     gst_structure_set (structure, field_name, G_TYPE_DOUBLE, target, NULL);
1215     return TRUE;
1216   } else if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1217     const GValue *list_value;
1218     int i, n;
1219     double best = 0;
1220     int best_index = -1;
1221
1222     n = gst_value_list_get_size (value);
1223     for(i=0;i<n;i++){
1224       list_value = gst_value_list_get_value (value, i);
1225       if (G_VALUE_TYPE (list_value) == G_TYPE_DOUBLE) {
1226         double x = g_value_get_double (list_value);
1227         if (best_index == -1 || (ABS(target-x) < ABS(best-x))) {
1228           best_index = i;
1229           best = x;
1230         }
1231       }
1232     }
1233     if(best_index != -1) {
1234       gst_structure_set (structure, field_name, G_TYPE_DOUBLE, best, NULL);
1235       return TRUE;
1236     }
1237     return FALSE;
1238   }
1239
1240   return FALSE;
1241
1242 }
1243