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