gst/gstcaps.c: Code cleanups.
[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 /**
21  * SECTION:gstcaps
22  * @short_description: Structure describing sets of media formats
23  * @see_also: #GstStructure
24  *
25  * Caps (capabilities) are lighweight refcounted objects describing media types.
26  * They are composed of an array of #GstStructure.
27  *
28  * Caps are exposed on #GstPadTemplate to describe all possible types a
29  * given pad can handle. They are also stored in the registry along with
30  * a description of the element.
31  *
32  * Caps are exposed on the element pads using the gst_pad_get_caps() pad
33  * function. This function describes the possible types that the pad can
34  * handle or produce at runtime.
35  *
36  * Caps are also attached to buffers to describe to content of the data
37  * pointed to by the buffer with gst_buffer_set_caps(). Caps attached to
38  * a #GstBuffer allow for format negotiation upstream and downstream.
39  *
40  * A #GstCaps can be constructed with the following code fragment:
41  *
42  * <example>
43  *  <title>Creating caps</title>
44  *  <programlisting>
45  *  GstCaps *caps;
46  *  caps = gst_caps_new_simple ("video/x-raw-yuv",
47  *       "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
48  *       "framerate", G_TYPE_DOUBLE, 25.0,
49  *       "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
50  *       "width", G_TYPE_INT, 320,
51  *       "height", G_TYPE_INT, 240,
52  *       NULL);
53  *  </programlisting>
54  * </example>
55  *
56  * A #GstCaps is fixed when it has no properties with ranges or lists. Use
57  * gst_caps_is_fixed() to test for fixed caps. Only fixed caps can be
58  * set on a #GstPad or #GstBuffer.
59  *
60  * Various methods exist to work with the media types such as subtracting
61  * or intersecting.
62  *
63  * Last reviewed on 2005-11-23 (0.9.5)
64  */
65
66 #ifdef HAVE_CONFIG_H
67 #include "config.h"
68 #endif
69 #include <string.h>
70 #include <signal.h>
71
72 #include "gst_private.h"
73 #include <gst/gst.h>
74
75 #define DEBUG_REFCOUNT
76
77 #define CAPS_POISON(caps) G_STMT_START{ \
78   if (caps) { \
79     GstCaps *_newcaps = gst_caps_copy (caps); \
80     gst_caps_unref(caps); \
81     caps = _newcaps; \
82   } \
83 } G_STMT_END
84 #define STRUCTURE_POISON(structure) G_STMT_START{ \
85   if (structure) { \
86     GstStructure *_newstruct = gst_structure_copy (structure); \
87     gst_structure_free(structure); \
88     structure = _newstruct; \
89   } \
90 } G_STMT_END
91 #define IS_WRITABLE(caps) \
92   (g_atomic_int_get (&(caps)->refcount) == 1)
93
94 #if GLIB_CHECK_VERSION (2, 10, 0)
95 #define ALLOC_CAPS()    g_slice_new (GstCaps)
96 #define FREE_CAPS(caps) g_slice_free (GstCaps, caps)
97 #else
98 #define ALLOC_CAPS()    g_new (GstCaps, 1)
99 #define FREE_CAPS(caps) g_free (caps)
100 #endif
101
102 static void gst_caps_transform_to_string (const GValue * src_value,
103     GValue * dest_value);
104 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
105     const gchar * string);
106 static GstCaps *gst_caps_copy_conditional (GstCaps * src);
107
108 GType
109 gst_caps_get_type (void)
110 {
111   static GType gst_caps_type = 0;
112
113   if (G_UNLIKELY (gst_caps_type == 0)) {
114     gst_caps_type = g_boxed_type_register_static ("GstCaps",
115         (GBoxedCopyFunc) gst_caps_copy_conditional,
116         (GBoxedFreeFunc) gst_caps_unref);
117
118     g_value_register_transform_func (gst_caps_type,
119         G_TYPE_STRING, gst_caps_transform_to_string);
120   }
121
122   return gst_caps_type;
123 }
124
125 /* creation/deletion */
126
127 /**
128  * gst_caps_new_empty:
129  *
130  * Creates a new #GstCaps that is empty.  That is, the returned
131  * #GstCaps contains no media formats.
132  * Caller is responsible for unreffing the returned caps.
133  *
134  * Returns: the new #GstCaps
135  */
136 GstCaps *
137 gst_caps_new_empty (void)
138 {
139   GstCaps *caps = ALLOC_CAPS ();
140
141   caps->type = GST_TYPE_CAPS;
142   caps->refcount = 1;
143   caps->flags = 0;
144   caps->structs = g_ptr_array_new ();
145
146 #ifdef DEBUG_REFCOUNT
147   GST_CAT_LOG (GST_CAT_CAPS, "created caps %p", caps);
148 #endif
149
150   return caps;
151 }
152
153 /**
154  * gst_caps_new_any:
155  *
156  * Creates a new #GstCaps that indicates that it is compatible with
157  * any media format.
158  *
159  * Returns: the new #GstCaps
160  */
161 GstCaps *
162 gst_caps_new_any (void)
163 {
164   GstCaps *caps = gst_caps_new_empty ();
165
166   caps->flags = GST_CAPS_FLAGS_ANY;
167
168   return caps;
169 }
170
171 /**
172  * gst_caps_new_simple:
173  * @media_type: the media type of the structure
174  * @fieldname: first field to set
175  * @...: additional arguments
176  *
177  * Creates a new #GstCaps that contains one #GstStructure.  The
178  * structure is defined by the arguments, which have the same format
179  * as gst_structure_new().
180  * Caller is responsible for unreffing the returned caps.
181  *
182  * Returns: the new #GstCaps
183  */
184 GstCaps *
185 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
186 {
187   GstCaps *caps;
188   GstStructure *structure;
189   va_list var_args;
190
191   caps = gst_caps_new_empty ();
192
193   va_start (var_args, fieldname);
194   structure = gst_structure_new_valist (media_type, fieldname, var_args);
195   va_end (var_args);
196
197   gst_caps_append_structure (caps, structure);
198
199   return caps;
200 }
201
202 /**
203  * gst_caps_new_full:
204  * @struct1: the first structure to add
205  * @...: additional structures to add
206  *
207  * Creates a new #GstCaps and adds all the structures listed as
208  * arguments.  The list must be NULL-terminated.  The structures
209  * are not copied; the returned #GstCaps owns the structures.
210  *
211  * Returns: the new #GstCaps
212  */
213 GstCaps *
214 gst_caps_new_full (GstStructure * struct1, ...)
215 {
216   GstCaps *caps;
217   va_list var_args;
218
219   va_start (var_args, struct1);
220   caps = gst_caps_new_full_valist (struct1, var_args);
221   va_end (var_args);
222
223   return caps;
224 }
225
226 /**
227  * gst_caps_new_full_valist:
228  * @structure: the first structure to add
229  * @var_args: additional structures to add
230  *
231  * Creates a new #GstCaps and adds all the structures listed as
232  * arguments.  The list must be NULL-terminated.  The structures
233  * are not copied; the returned #GstCaps owns the structures.
234  *
235  * Returns: the new #GstCaps
236  */
237 GstCaps *
238 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
239 {
240   GstCaps *caps;
241
242   caps = gst_caps_new_empty ();
243
244   while (structure) {
245     gst_caps_append_structure (caps, structure);
246     structure = va_arg (var_args, GstStructure *);
247   }
248
249   return caps;
250 }
251
252 /**
253  * gst_caps_copy:
254  * @caps: the #GstCaps to copy
255  *
256  * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
257  * refcount of 1, owned by the caller. The structures are copied as well.
258  *
259  * Note that this function is the semantic equivalent of a gst_caps_ref()
260  * followed by a gst_caps_make_writable(). If you only want to hold on to a
261  * reference to the data, you should use gst_caps_ref().
262  *
263  * When you are finished with the caps, call gst_caps_unref() on it.
264  *
265  * Returns: the new #GstCaps
266  */
267 GstCaps *
268 gst_caps_copy (const GstCaps * caps)
269 {
270   GstCaps *newcaps;
271   GstStructure *structure;
272   guint i;
273
274   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
275
276   newcaps = gst_caps_new_empty ();
277   newcaps->flags = caps->flags;
278
279   for (i = 0; i < caps->structs->len; i++) {
280     structure = gst_caps_get_structure (caps, i);
281     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
282   }
283
284   return newcaps;
285 }
286
287 static void
288 _gst_caps_free (GstCaps * caps)
289 {
290   GstStructure *structure;
291   guint i;
292
293   /* The refcount must be 0, but since we're only called by gst_caps_unref,
294    * don't bother testing. */
295
296   for (i = 0; i < caps->structs->len; i++) {
297     structure = (GstStructure *) gst_caps_get_structure (caps, i);
298     gst_structure_set_parent_refcount (structure, NULL);
299     gst_structure_free (structure);
300   }
301   g_ptr_array_free (caps->structs, TRUE);
302 #ifdef USE_POISONING
303   memset (caps, 0xff, sizeof (GstCaps));
304 #endif
305   FREE_CAPS (caps);
306 }
307
308 /**
309  * gst_caps_make_writable:
310  * @caps: the #GstCaps to make writable
311  *
312  * Returns a writable copy of @caps.
313  *
314  * If there is only one reference count on @caps, the caller must be the owner,
315  * and so this function will return the caps object unchanged. If on the other
316  * hand there is more than one reference on the object, a new caps object will
317  * be returned. The caller's reference on @caps will be removed, and instead the
318  * caller will own a reference to the returned object.
319  *
320  * In short, this function unrefs the caps in the argument and refs the caps
321  * that it returns. Don't access the argument after calling this function. See
322  * also: gst_caps_ref().
323  *
324  * Returns: the same #GstCaps object.
325  */
326 GstCaps *
327 gst_caps_make_writable (GstCaps * caps)
328 {
329   GstCaps *copy;
330
331   g_return_val_if_fail (caps != NULL, NULL);
332
333   /* we are the only instance reffing this caps */
334   if (g_atomic_int_get (&caps->refcount) == 1)
335     return caps;
336
337   /* else copy */
338   copy = gst_caps_copy (caps);
339   gst_caps_unref (caps);
340
341   return copy;
342 }
343
344 /**
345  * gst_caps_ref:
346  * @caps: the #GstCaps to reference
347  *
348  * Add a reference to a #GstCaps object.
349  *
350  * From this point on, until the caller calls gst_caps_unref() or
351  * gst_caps_make_writable(), it is guaranteed that the caps object will not
352  * change. This means its structures won't change, etc. To use a #GstCaps
353  * object, you must always have a refcount on it -- either the one made
354  * implicitly by gst_caps_new(), or via taking one explicitly with this
355  * function.
356  *
357  * Returns: the same #GstCaps object.
358  */
359 GstCaps *
360 gst_caps_ref (GstCaps * caps)
361 {
362   g_return_val_if_fail (caps != NULL, NULL);
363
364 #ifdef DEBUG_REFCOUNT
365   GST_CAT_LOG (GST_CAT_REFCOUNTING, "%p %d->%d", caps,
366       GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) + 1);
367 #endif
368   g_return_val_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0, NULL);
369
370   g_atomic_int_inc (&caps->refcount);
371
372   return caps;
373 }
374
375 /**
376  * gst_caps_unref:
377  * @caps: the #GstCaps to unref
378  *
379  * Unref a #GstCaps and and free all its structures and the
380  * structures' values when the refcount reaches 0.
381  */
382 void
383 gst_caps_unref (GstCaps * caps)
384 {
385   g_return_if_fail (caps != NULL);
386
387 #ifdef DEBUG_REFCOUNT
388   GST_CAT_LOG (GST_CAT_REFCOUNTING, "%p %d->%d", caps,
389       GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) - 1);
390 #endif
391
392   g_return_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0);
393
394   /* if we ended up with the refcount at zero, free the caps */
395   if (G_UNLIKELY (g_atomic_int_dec_and_test (&caps->refcount)))
396     _gst_caps_free (caps);
397 }
398
399 GType
400 gst_static_caps_get_type (void)
401 {
402   static GType staticcaps_type = 0;
403
404   if (G_UNLIKELY (staticcaps_type == 0)) {
405     staticcaps_type = g_pointer_type_register_static ("GstStaticCaps");
406   }
407   return staticcaps_type;
408 }
409
410
411 /**
412  * gst_static_caps_get:
413  * @static_caps: the #GstStaticCaps to convert
414  *
415  * Converts a #GstStaticCaps to a #GstCaps.
416  *
417  * Returns: A pointer to the #GstCaps. Unref after usage. Since the
418  * core holds an additional ref to the returned caps,
419  * use gst_caps_make_writable() on the returned caps to modify it.
420  */
421 GstCaps *
422 gst_static_caps_get (GstStaticCaps * static_caps)
423 {
424   GstCaps *caps;
425
426   g_return_val_if_fail (static_caps != NULL, NULL);
427
428   caps = (GstCaps *) static_caps;
429
430   if (caps->type == 0) {
431     if (G_UNLIKELY (static_caps->string == NULL))
432       goto no_string;
433
434     caps->type = GST_TYPE_CAPS;
435     /* initialize the caps to a refcount of 1 so the caps can be writable... */
436     gst_atomic_int_set (&caps->refcount, 1);
437     caps->structs = g_ptr_array_new ();
438
439     /* convert to string */
440     if (G_UNLIKELY (!gst_caps_from_string_inplace (caps, static_caps->string)))
441       g_critical ("Could not convert static caps \"%s\"", static_caps->string);
442   }
443   /* ref the caps, makes it not writable */
444   gst_caps_ref (caps);
445
446   return caps;
447
448   /* ERRORS */
449 no_string:
450   {
451     g_warning ("static caps string is NULL");
452     return NULL;
453   }
454 }
455
456 /* manipulation */
457 static GstStructure *
458 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
459 {
460   /* don't use index_fast, gst_caps_do_simplify relies on the order */
461   GstStructure *s = g_ptr_array_remove_index (caps->structs, idx);
462
463   gst_structure_set_parent_refcount (s, NULL);
464   return s;
465 }
466
467 static gboolean
468 gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
469     gpointer data)
470 {
471   GstStructure *struct1 = (GstStructure *) data;
472   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
473
474   if (val1 == NULL)
475     return FALSE;
476   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
477     return TRUE;
478   }
479
480   return FALSE;
481 }
482
483 static gboolean
484 gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
485     gpointer user_data)
486 {
487   GstStructure *subtract_from = user_data;
488   GValue subtraction = { 0, };
489   const GValue *other;
490   gint res;
491
492   other = gst_structure_id_get_value (subtract_from, field_id);
493   if (!other) {
494     /* field is missing in one set */
495     return FALSE;
496   }
497   /*
498    * [1,2] - 1 = 2
499    * 1 - [1,2] = ???
500    */
501   if (!gst_value_subtract (&subtraction, other, value)) {
502     /* empty result -> values are the same, or first was a value and
503      * second was a list
504      * verify that result is empty by swapping args */
505     if (!gst_value_subtract (&subtraction, value, other)) {
506       return TRUE;
507     }
508     g_value_unset (&subtraction);
509     return FALSE;
510   }
511
512   res = gst_value_compare (&subtraction, other);
513   g_value_unset (&subtraction);
514
515   if (res == GST_VALUE_EQUAL) {
516     /* value was empty ? */
517     return FALSE;
518   } else {
519     return TRUE;
520   }
521 }
522
523 static gboolean
524 gst_caps_structure_is_subset (const GstStructure * minuend,
525     const GstStructure * subtrahend)
526 {
527   if ((minuend->name != subtrahend->name) ||
528       (gst_structure_n_fields (minuend) !=
529           gst_structure_n_fields (subtrahend))) {
530     return FALSE;
531   }
532
533   return gst_structure_foreach ((GstStructure *) subtrahend,
534       gst_caps_structure_is_subset_field, (gpointer) minuend);
535 }
536
537 /**
538  * gst_caps_append:
539  * @caps1: the #GstCaps that will be appended to
540  * @caps2: the #GstCaps to append
541  *
542  * Appends the structures contained in @caps2 to @caps1. The structures in
543  * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
544  * freed. If either caps is ANY, the resulting caps will be ANY.
545  */
546 void
547 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
548 {
549   GstStructure *structure;
550   int i;
551
552   g_return_if_fail (GST_IS_CAPS (caps1));
553   g_return_if_fail (GST_IS_CAPS (caps2));
554   g_return_if_fail (IS_WRITABLE (caps1));
555   g_return_if_fail (IS_WRITABLE (caps2));
556
557 #ifdef USE_POISONING
558   CAPS_POISON (caps2);
559 #endif
560   if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2)) {
561     /* FIXME: this leaks */
562     caps1->flags |= GST_CAPS_FLAGS_ANY;
563     for (i = caps2->structs->len - 1; i >= 0; i--) {
564       structure = gst_caps_remove_and_get_structure (caps2, i);
565       gst_structure_free (structure);
566     }
567   } else {
568     int len = caps2->structs->len;
569
570     for (i = 0; i < len; i++) {
571       structure = gst_caps_remove_and_get_structure (caps2, 0);
572       gst_caps_append_structure (caps1, structure);
573     }
574   }
575   gst_caps_unref (caps2);       /* guaranteed to free it */
576 }
577
578 /**
579  * gst_caps_merge:
580  * @caps1: the #GstCaps that will take the new entries
581  * @caps2: the #GstCaps to merge in
582  *
583  * Appends the structures contained in @caps2 to @caps1 if they are not yet
584  * expressed by @caps1. The structures in @caps2 are not copied -- they are
585  * transferred to @caps1, and then @caps2 is freed.
586  * If either caps is ANY, the resulting caps will be ANY.
587  */
588 void
589 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
590 {
591   GstStructure *structure;
592   int i;
593
594   g_return_if_fail (GST_IS_CAPS (caps1));
595   g_return_if_fail (GST_IS_CAPS (caps2));
596   g_return_if_fail (IS_WRITABLE (caps1));
597   g_return_if_fail (IS_WRITABLE (caps2));
598
599 #ifdef USE_POISONING
600   CAPS_POISON (caps2);
601 #endif
602   if (gst_caps_is_any (caps1)) {
603     for (i = caps2->structs->len - 1; i >= 0; i--) {
604       structure = gst_caps_remove_and_get_structure (caps2, i);
605       gst_structure_free (structure);
606     }
607   } else if (gst_caps_is_any (caps2)) {
608     caps1->flags |= GST_CAPS_FLAGS_ANY;
609     for (i = caps1->structs->len - 1; i >= 0; i--) {
610       structure = gst_caps_remove_and_get_structure (caps1, i);
611       gst_structure_free (structure);
612     }
613   } else {
614     int len = caps2->structs->len;
615
616     for (i = 0; i < len; i++) {
617       structure = gst_caps_remove_and_get_structure (caps2, 0);
618       gst_caps_merge_structure (caps1, structure);
619     }
620     /* this is too naive
621        GstCaps *com = gst_caps_intersect (caps1, caps2);
622        GstCaps *add = gst_caps_subtract (caps2, com);
623
624        GST_DEBUG ("common : %d", gst_caps_get_size (com));
625        GST_DEBUG ("adding : %d", gst_caps_get_size (add));
626        gst_caps_append (caps1, add);
627        gst_caps_unref (com);
628      */
629   }
630   gst_caps_unref (caps2);       /* guaranteed to free it */
631 }
632
633 /**
634  * gst_caps_append_structure:
635  * @caps: the #GstCaps that will be appended to
636  * @structure: the #GstStructure to append
637  *
638  * Appends @structure to @caps.  The structure is not copied; @caps
639  * becomes the owner of @structure.
640  */
641 void
642 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
643 {
644   g_return_if_fail (GST_IS_CAPS (caps));
645   g_return_if_fail (IS_WRITABLE (caps));
646
647   if (G_LIKELY (structure)) {
648     g_return_if_fail (structure->parent_refcount == NULL);
649 #if 0
650 #ifdef USE_POISONING
651     STRUCTURE_POISON (structure);
652 #endif
653 #endif
654     gst_structure_set_parent_refcount (structure, &caps->refcount);
655     g_ptr_array_add (caps->structs, structure);
656   }
657 }
658
659 /**
660  * gst_caps_remove_structure:
661  * @caps: the #GstCaps to remove from
662  * @idx: Index of the structure to remove
663  *
664  * removes the stucture with the given index from the list of structures
665  * contained in @caps.
666  */
667 void
668 gst_caps_remove_structure (GstCaps * caps, guint idx)
669 {
670   GstStructure *structure;
671
672   g_return_if_fail (caps != NULL);
673   g_return_if_fail (idx <= gst_caps_get_size (caps));
674   g_return_if_fail (IS_WRITABLE (caps));
675
676   structure = gst_caps_remove_and_get_structure (caps, idx);
677   gst_structure_free (structure);
678 }
679
680 /**
681  * gst_caps_merge_structure:
682  * @caps: the #GstCaps that will the the new structure
683  * @structure: the #GstStructure to merge
684  *
685  * Appends @structure to @caps if its not already expressed by @caps.  The
686  * structure is not copied; @caps becomes the owner of @structure.
687  */
688 void
689 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
690 {
691   g_return_if_fail (GST_IS_CAPS (caps));
692   g_return_if_fail (IS_WRITABLE (caps));
693
694   if (G_LIKELY (structure)) {
695     GstStructure *structure1;
696     int i;
697     gboolean unique = TRUE;
698
699     g_return_if_fail (structure->parent_refcount == NULL);
700 #if 0
701 #ifdef USE_POISONING
702     STRUCTURE_POISON (structure);
703 #endif
704 #endif
705     /* check each structure */
706     for (i = caps->structs->len - 1; i >= 0; i--) {
707       structure1 = gst_caps_get_structure (caps, i);
708       /* if structure is a subset of structure1, then skip it */
709       if (gst_caps_structure_is_subset (structure1, structure)) {
710         unique = FALSE;
711         break;
712       }
713     }
714     if (unique) {
715       gst_structure_set_parent_refcount (structure, &caps->refcount);
716       g_ptr_array_add (caps->structs, structure);
717     } else {
718       gst_structure_free (structure);
719     }
720   }
721 }
722
723
724 /**
725  * gst_caps_get_size:
726  * @caps: a #GstCaps
727  *
728  * Gets the number of structures contained in @caps.
729  *
730  * Returns: the number of structures that @caps contains
731  */
732 guint
733 gst_caps_get_size (const GstCaps * caps)
734 {
735   g_return_val_if_fail (GST_IS_CAPS (caps), 0);
736
737   return caps->structs->len;
738 }
739
740 /**
741  * gst_caps_get_structure:
742  * @caps: a #GstCaps
743  * @index: the index of the structure
744  *
745  * Finds the structure in @caps that has the index @index, and
746  * returns it.
747  *
748  * WARNING: This function takes a const GstCaps *, but returns a
749  * non-const GstStructure *.  This is for programming convenience --
750  * the caller should be aware that structures inside a constant
751  * #GstCaps should not be modified.
752  *
753  * Returns: a pointer to the #GstStructure corresponding to @index
754  */
755 GstStructure *
756 gst_caps_get_structure (const GstCaps * caps, guint index)
757 {
758   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
759   g_return_val_if_fail (index < caps->structs->len, NULL);
760
761   return g_ptr_array_index (caps->structs, index);
762 }
763
764 /**
765  * gst_caps_copy_nth:
766  * @caps: the #GstCaps to copy
767  * @nth: the nth structure to copy
768  *
769  * Creates a new #GstCaps and appends a copy of the nth structure
770  * contained in @caps.
771  *
772  * Returns: the new #GstCaps
773  */
774 GstCaps *
775 gst_caps_copy_nth (const GstCaps * caps, guint nth)
776 {
777   GstCaps *newcaps;
778   GstStructure *structure;
779
780   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
781
782   newcaps = gst_caps_new_empty ();
783   newcaps->flags = caps->flags;
784
785   if (caps->structs->len > nth) {
786     structure = gst_caps_get_structure (caps, nth);
787     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
788   }
789
790   return newcaps;
791 }
792
793 /**
794  * gst_caps_truncate:
795  * @caps: the #GstCaps to truncate
796  *
797  * Destructively discard all but the first structure from @caps. Useful when
798  * fixating. @caps must be writable.
799  */
800 void
801 gst_caps_truncate (GstCaps * caps)
802 {
803   gint i;
804
805   g_return_if_fail (GST_IS_CAPS (caps));
806   g_return_if_fail (IS_WRITABLE (caps));
807
808   i = caps->structs->len - 1;
809
810   while (i > 0)
811     gst_caps_remove_structure (caps, i--);
812 }
813
814 /**
815  * gst_caps_set_simple:
816  * @caps: the #GstCaps to set
817  * @field: first field to set
818  * @...: additional parameters
819  *
820  * Sets fields in a simple #GstCaps.  A simple #GstCaps is one that
821  * only has one structure.  The arguments must be passed in the same
822  * manner as gst_structure_set(), and be NULL-terminated.
823  */
824 void
825 gst_caps_set_simple (GstCaps * caps, char *field, ...)
826 {
827   GstStructure *structure;
828   va_list var_args;
829
830   g_return_if_fail (GST_IS_CAPS (caps));
831   g_return_if_fail (caps->structs->len == 1);
832   g_return_if_fail (IS_WRITABLE (caps));
833
834   structure = gst_caps_get_structure (caps, 0);
835
836   va_start (var_args, field);
837   gst_structure_set_valist (structure, field, var_args);
838   va_end (var_args);
839 }
840
841 /**
842  * gst_caps_set_simple_valist:
843  * @caps: the #GstCaps to copy
844  * @field: first field to set
845  * @varargs: additional parameters
846  *
847  * Sets fields in a simple #GstCaps.  A simple #GstCaps is one that
848  * only has one structure.  The arguments must be passed in the same
849  * manner as gst_structure_set(), and be NULL-terminated.
850  */
851 void
852 gst_caps_set_simple_valist (GstCaps * caps, char *field, va_list varargs)
853 {
854   GstStructure *structure;
855
856   g_return_if_fail (GST_IS_CAPS (caps));
857   g_return_if_fail (caps->structs->len != 1);
858   g_return_if_fail (IS_WRITABLE (caps));
859
860   structure = gst_caps_get_structure (caps, 0);
861
862   gst_structure_set_valist (structure, field, varargs);
863 }
864
865 /* tests */
866
867 /**
868  * gst_caps_is_any:
869  * @caps: the #GstCaps to test
870  *
871  * Determines if @caps represents any media format.
872  *
873  * Returns: TRUE if @caps represents any format.
874  */
875 gboolean
876 gst_caps_is_any (const GstCaps * caps)
877 {
878   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
879
880   return (caps->flags & GST_CAPS_FLAGS_ANY);
881 }
882
883 /**
884  * gst_caps_is_empty:
885  * @caps: the #GstCaps to test
886  *
887  * Determines if @caps represents no media formats.
888  *
889  * Returns: TRUE if @caps represents no formats.
890  */
891 gboolean
892 gst_caps_is_empty (const GstCaps * caps)
893 {
894   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
895
896   if (caps->flags & GST_CAPS_FLAGS_ANY)
897     return FALSE;
898
899   return (caps->structs == NULL) || (caps->structs->len == 0);
900 }
901
902 static gboolean
903 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
904     gpointer unused)
905 {
906   return gst_value_is_fixed (value);
907 }
908
909 /**
910  * gst_caps_is_fixed:
911  * @caps: the #GstCaps to test
912  *
913  * Fixed #GstCaps describe exactly one format, that is, they have exactly
914  * one structure, and each field in the structure describes a fixed type.
915  * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
916  *
917  * Returns: TRUE if @caps is fixed
918  */
919 gboolean
920 gst_caps_is_fixed (const GstCaps * caps)
921 {
922   GstStructure *structure;
923
924   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
925
926   if (caps->structs->len != 1)
927     return FALSE;
928
929   structure = gst_caps_get_structure (caps, 0);
930
931   return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
932 }
933
934 /**
935  * gst_caps_is_equal_fixed:
936  * @caps1: the #GstCaps to test
937  * @caps2: the #GstCaps to test
938  *
939  * Tests if two #GstCaps are equal.  This function only works on fixed
940  * #GstCaps.
941  *
942  * Returns: TRUE if the arguments represent the same format
943  */
944 gboolean
945 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
946 {
947   GstStructure *struct1, *struct2;
948
949   g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
950   g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
951
952   struct1 = gst_caps_get_structure (caps1, 0);
953   struct2 = gst_caps_get_structure (caps2, 0);
954
955   if (struct1->name != struct2->name) {
956     return FALSE;
957   }
958   if (struct1->fields->len != struct2->fields->len) {
959     return FALSE;
960   }
961
962   return gst_structure_foreach (struct1, gst_structure_is_equal_foreach,
963       struct2);
964 }
965
966 /**
967  * gst_caps_is_always_compatible:
968  * @caps1: the #GstCaps to test
969  * @caps2: the #GstCaps to test
970  *
971  * A given #GstCaps structure is always compatible with another if
972  * every media format that is in the first is also contained in the
973  * second.  That is, @caps1 is a subset of @caps2.
974  *
975  * Returns: TRUE if @caps1 is a subset of @caps2.
976  */
977 gboolean
978 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
979 {
980   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
981   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
982
983   return gst_caps_is_subset (caps1, caps2);
984 }
985
986 /**
987  * gst_caps_is_subset:
988  * @subset: a #GstCaps
989  * @superset: a potentially greater #GstCaps
990  *
991  * Checks if all caps represented by @subset are also represented by @superset
992  * <note>This function does not work reliably if optional properties for caps
993  * are included on one caps and omitted on the other.</note>
994  *
995  * Returns: TRUE if @subset is a subset of @superset
996  */
997 gboolean
998 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
999 {
1000   GstCaps *caps;
1001   gboolean ret;
1002
1003   g_return_val_if_fail (subset != NULL, FALSE);
1004   g_return_val_if_fail (superset != NULL, FALSE);
1005
1006   if (gst_caps_is_empty (subset) || gst_caps_is_any (superset))
1007     return TRUE;
1008   if (gst_caps_is_any (subset) || gst_caps_is_empty (superset))
1009     return FALSE;
1010
1011   caps = gst_caps_subtract (subset, superset);
1012   ret = gst_caps_is_empty (caps);
1013   gst_caps_unref (caps);
1014   return ret;
1015 }
1016
1017 /**
1018  * gst_caps_is_equal:
1019  * @caps1: a #GstCaps
1020  * @caps2: another #GstCaps
1021  *
1022  * Checks if the given caps represent the same set of caps.
1023  * <note>This function does not work reliably if optional properties for caps
1024  * are included on one caps and omitted on the other.</note>
1025  *
1026  * This function deals correctly with passing NULL for any of the caps.
1027  *
1028  * Returns: TRUE if both caps are equal.
1029  */
1030 gboolean
1031 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1032 {
1033   /* NULL <-> NULL is allowed here */
1034   if (caps1 == caps2)
1035     return TRUE;
1036
1037   /* one of them NULL => they are different (can't be both NULL because
1038    * we checked that above) */
1039   if (caps1 == NULL || caps2 == NULL)
1040     return FALSE;
1041
1042   if (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2))
1043     return gst_caps_is_equal_fixed (caps1, caps2);
1044
1045   return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1046 }
1047
1048 typedef struct
1049 {
1050   GstStructure *dest;
1051   const GstStructure *intersect;
1052   gboolean first_run;
1053 }
1054 IntersectData;
1055
1056 static gboolean
1057 gst_caps_structure_intersect_field (GQuark id, const GValue * val1,
1058     gpointer data)
1059 {
1060   IntersectData *idata = (IntersectData *) data;
1061   GValue dest_value = { 0 };
1062   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
1063
1064   if (val2 == NULL) {
1065     gst_structure_id_set_value (idata->dest, id, val1);
1066   } else if (idata->first_run) {
1067     if (gst_value_intersect (&dest_value, val1, val2)) {
1068       gst_structure_id_set_value (idata->dest, id, &dest_value);
1069       g_value_unset (&dest_value);
1070     } else {
1071       return FALSE;
1072     }
1073   }
1074
1075   return TRUE;
1076 }
1077
1078 static GstStructure *
1079 gst_caps_structure_intersect (const GstStructure * struct1,
1080     const GstStructure * struct2)
1081 {
1082   IntersectData data;
1083
1084   g_return_val_if_fail (struct1 != NULL, NULL);
1085   g_return_val_if_fail (struct2 != NULL, NULL);
1086
1087   if (struct1->name != struct2->name)
1088     return NULL;
1089
1090   data.dest = gst_structure_id_empty_new (struct1->name);
1091   data.intersect = struct2;
1092   data.first_run = TRUE;
1093   if (!gst_structure_foreach ((GstStructure *) struct1,
1094           gst_caps_structure_intersect_field, &data))
1095     goto error;
1096
1097   data.intersect = struct1;
1098   data.first_run = FALSE;
1099   if (!gst_structure_foreach ((GstStructure *) struct2,
1100           gst_caps_structure_intersect_field, &data))
1101     goto error;
1102
1103   return data.dest;
1104
1105 error:
1106   gst_structure_free (data.dest);
1107   return NULL;
1108 }
1109
1110 #if 0
1111 static GstStructure *
1112 gst_caps_structure_union (const GstStructure * struct1,
1113     const GstStructure * struct2)
1114 {
1115   int i;
1116   GstStructure *dest;
1117   const GstStructureField *field1;
1118   const GstStructureField *field2;
1119   int ret;
1120
1121   /* FIXME this doesn't actually work */
1122
1123   if (struct1->name != struct2->name)
1124     return NULL;
1125
1126   dest = gst_structure_id_empty_new (struct1->name);
1127
1128   for (i = 0; i < struct1->fields->len; i++) {
1129     GValue dest_value = { 0 };
1130
1131     field1 = GST_STRUCTURE_FIELD (struct1, i);
1132     field2 = gst_structure_id_get_field (struct2, field1->name);
1133
1134     if (field2 == NULL) {
1135       continue;
1136     } else {
1137       if (gst_value_union (&dest_value, &field1->value, &field2->value)) {
1138         gst_structure_set_value (dest, g_quark_to_string (field1->name),
1139             &dest_value);
1140       } else {
1141         ret = gst_value_compare (&field1->value, &field2->value);
1142       }
1143     }
1144   }
1145
1146   return dest;
1147 }
1148 #endif
1149
1150 /* operations */
1151
1152 /**
1153  * gst_caps_intersect:
1154  * @caps1: a #GstCaps to intersect
1155  * @caps2: a #GstCaps to intersect
1156  *
1157  * Creates a new #GstCaps that contains all the formats that are common
1158  * to both @caps1 and @caps2.
1159  *
1160  * Returns: the new #GstCaps
1161  */
1162 GstCaps *
1163 gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
1164 {
1165   guint64 i;                    /* index can be up to 2 * G_MAX_UINT */
1166   guint j, k;
1167
1168   GstStructure *struct1;
1169   GstStructure *struct2;
1170   GstCaps *dest;
1171   GstStructure *istruct;
1172
1173   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1174   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1175
1176   if (gst_caps_is_empty (caps1) || gst_caps_is_empty (caps2)) {
1177     return gst_caps_new_empty ();
1178   }
1179   if (gst_caps_is_any (caps1))
1180     return gst_caps_copy (caps2);
1181   if (gst_caps_is_any (caps2))
1182     return gst_caps_copy (caps1);
1183
1184   dest = gst_caps_new_empty ();
1185
1186   /* run zigzag on top line then right line, this preserves the caps order
1187    * much better than a simple loop.
1188    *
1189    * This algorithm zigzags over the caps structures as demonstrated in
1190    * the folowing matrix:
1191    *
1192    *          caps1
1193    *       +-------------
1194    *       | 1  2  4  7
1195    * caps2 | 3  5  8 10
1196    *       | 6  9 11 12
1197    *
1198    * First we iterate over the caps1 structures (top line) intersecting
1199    * the structures diagonally down, then we iterate over the caps2
1200    * structures.
1201    */
1202   for (i = 0; i < caps1->structs->len + caps2->structs->len - 1; i++) {
1203     /* caps1 index goes from 0 to caps1->structs->len-1 */
1204     j = MIN (i, caps1->structs->len - 1);
1205     /* caps2 index stays 0 until i reaches caps1->structs->len, then it counts
1206      * up from 1 to caps2->structs->len - 1 */
1207     k = MAX (0, i - j);
1208
1209     /* now run the diagonal line, end condition is the left or bottom
1210      * border */
1211     while (k < caps2->structs->len) {
1212       struct1 = gst_caps_get_structure (caps1, j);
1213       struct2 = gst_caps_get_structure (caps2, k);
1214
1215       istruct = gst_caps_structure_intersect (struct1, struct2);
1216
1217       gst_caps_append_structure (dest, istruct);
1218       /* move down left */
1219       k++;
1220       if (j == 0)
1221         break;                  /* so we don't roll back to G_MAXUINT */
1222       j--;
1223     }
1224   }
1225   return dest;
1226 }
1227
1228 typedef struct
1229 {
1230   const GstStructure *subtract_from;
1231   GSList *put_into;
1232 }
1233 SubtractionEntry;
1234
1235
1236 static gboolean
1237 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1238     gpointer user_data)
1239 {
1240   SubtractionEntry *e = user_data;
1241   GValue subtraction = { 0, };
1242   const GValue *other;
1243   GstStructure *structure;
1244
1245   other = gst_structure_id_get_value (e->subtract_from, field_id);
1246   if (!other) {
1247     return FALSE;
1248   }
1249   if (!gst_value_subtract (&subtraction, other, value))
1250     return TRUE;
1251   if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1252     g_value_unset (&subtraction);
1253     return FALSE;
1254   } else {
1255     structure = gst_structure_copy (e->subtract_from);
1256     gst_structure_id_set_value (structure, field_id, &subtraction);
1257     g_value_unset (&subtraction);
1258     e->put_into = g_slist_prepend (e->put_into, structure);
1259     return TRUE;
1260   }
1261 }
1262
1263 static gboolean
1264 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1265     const GstStructure * subtrahend)
1266 {
1267   SubtractionEntry e;
1268   gboolean ret;
1269
1270   e.subtract_from = minuend;
1271   e.put_into = NULL;
1272
1273   ret = gst_structure_foreach ((GstStructure *) subtrahend,
1274       gst_caps_structure_subtract_field, &e);
1275   if (ret) {
1276     *into = e.put_into;
1277   } else {
1278     GSList *walk;
1279
1280     for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1281       gst_structure_free (walk->data);
1282     }
1283     g_slist_free (e.put_into);
1284   }
1285   return ret;
1286 }
1287
1288 /**
1289  * gst_caps_subtract:
1290  * @minuend: #GstCaps to substract from
1291  * @subtrahend: #GstCaps to substract
1292  *
1293  * Subtracts the @subtrahend from the @minuend.
1294  * <note>This function does not work reliably if optional properties for caps
1295  * are included on one caps and omitted on the other.</note>
1296  *
1297  * Returns: the resulting caps
1298  */
1299 GstCaps *
1300 gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
1301 {
1302   guint i, j;
1303   GstStructure *min;
1304   GstStructure *sub;
1305   GstCaps *dest = NULL, *src;
1306
1307   g_return_val_if_fail (minuend != NULL, NULL);
1308   g_return_val_if_fail (subtrahend != NULL, NULL);
1309
1310   if (gst_caps_is_empty (minuend) || gst_caps_is_any (subtrahend)) {
1311     return gst_caps_new_empty ();
1312   }
1313   if (gst_caps_is_empty (subtrahend))
1314     return gst_caps_copy (minuend);
1315
1316   /* FIXME: Do we want this here or above?
1317      The reason we need this is that there is no definition about what
1318      ANY means for specific types, so it's not possible to reduce ANY partially
1319      You can only remove everything or nothing and that is done above.
1320      Note: there's a test that checks this behaviour. */
1321   g_return_val_if_fail (!gst_caps_is_any (minuend), NULL);
1322   g_assert (subtrahend->structs->len > 0);
1323
1324   src = gst_caps_copy (minuend);
1325   for (i = 0; i < subtrahend->structs->len; i++) {
1326     sub = gst_caps_get_structure (subtrahend, i);
1327     if (dest) {
1328       gst_caps_unref (src);
1329       src = dest;
1330     }
1331     dest = gst_caps_new_empty ();
1332     for (j = 0; j < src->structs->len; j++) {
1333       min = gst_caps_get_structure (src, j);
1334       if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub)) {
1335         GSList *list;
1336
1337         if (gst_caps_structure_subtract (&list, min, sub)) {
1338           GSList *walk;
1339
1340           for (walk = list; walk; walk = g_slist_next (walk)) {
1341             gst_caps_append_structure (dest, (GstStructure *) walk->data);
1342           }
1343           g_slist_free (list);
1344         } else {
1345           gst_caps_append_structure (dest, gst_structure_copy (min));
1346         }
1347       } else {
1348         gst_caps_append_structure (dest, gst_structure_copy (min));
1349       }
1350     }
1351     if (gst_caps_is_empty (dest)) {
1352       gst_caps_unref (src);
1353       return dest;
1354     }
1355   }
1356
1357   gst_caps_unref (src);
1358   gst_caps_do_simplify (dest);
1359   return dest;
1360 }
1361
1362 /**
1363  * gst_caps_union:
1364  * @caps1: a #GstCaps to union
1365  * @caps2: a #GstCaps to union
1366  *
1367  * Creates a new #GstCaps that contains all the formats that are in
1368  * either @caps1 and @caps2.
1369  *
1370  * Returns: the new #GstCaps
1371  */
1372 GstCaps *
1373 gst_caps_union (const GstCaps * caps1, const GstCaps * caps2)
1374 {
1375   GstCaps *dest1;
1376   GstCaps *dest2;
1377
1378   if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2))
1379     return gst_caps_new_any ();
1380
1381   dest1 = gst_caps_copy (caps1);
1382   dest2 = gst_caps_copy (caps2);
1383   gst_caps_append (dest1, dest2);
1384
1385   gst_caps_do_simplify (dest1);
1386   return dest1;
1387 }
1388
1389 typedef struct _NormalizeForeach
1390 {
1391   GstCaps *caps;
1392   GstStructure *structure;
1393 }
1394 NormalizeForeach;
1395
1396 static gboolean
1397 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1398 {
1399   NormalizeForeach *nf = (NormalizeForeach *) ptr;
1400   GValue val = { 0 };
1401   guint i;
1402
1403   if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1404     for (i = 1; i < gst_value_list_get_size (value); i++) {
1405       const GValue *v = gst_value_list_get_value (value, i);
1406       GstStructure *structure = gst_structure_copy (nf->structure);
1407
1408       gst_structure_id_set_value (structure, field_id, v);
1409       gst_caps_append_structure (nf->caps, structure);
1410     }
1411
1412     gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1413     gst_structure_id_set_value (nf->structure, field_id, &val);
1414     g_value_unset (&val);
1415
1416     return FALSE;
1417   }
1418   return TRUE;
1419 }
1420
1421 /**
1422  * gst_caps_normalize:
1423  * @caps: a #GstCaps to normalize
1424  *
1425  * Creates a new #GstCaps that represents the same set of formats as
1426  * @caps, but contains no lists.  Each list is expanded into separate
1427  * @GstStructures.
1428  *
1429  * Returns: the new #GstCaps
1430  */
1431 GstCaps *
1432 gst_caps_normalize (const GstCaps * caps)
1433 {
1434   NormalizeForeach nf;
1435   GstCaps *newcaps;
1436   guint i;
1437
1438   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1439
1440   newcaps = gst_caps_copy (caps);
1441   nf.caps = newcaps;
1442
1443   for (i = 0; i < newcaps->structs->len; i++) {
1444     nf.structure = gst_caps_get_structure (newcaps, i);
1445
1446     while (!gst_structure_foreach (nf.structure,
1447             gst_caps_normalize_foreach, &nf));
1448   }
1449
1450   return newcaps;
1451 }
1452
1453 static gint
1454 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1455 {
1456   gint ret;
1457   const GstStructure *struct1 = *((const GstStructure **) one);
1458   const GstStructure *struct2 = *((const GstStructure **) two);
1459
1460   /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1461      So what's the best way? */
1462   ret = strcmp (gst_structure_get_name (struct1),
1463       gst_structure_get_name (struct2));
1464   if (ret)
1465     return ret;
1466
1467   return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1468 }
1469
1470 typedef struct
1471 {
1472   GQuark name;
1473   GValue value;
1474   GstStructure *compare;
1475 }
1476 UnionField;
1477
1478 static gboolean
1479 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1480     gpointer user_data)
1481 {
1482   UnionField *u = user_data;
1483   const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1484
1485   if (!val) {
1486     if (u->name)
1487       g_value_unset (&u->value);
1488     return FALSE;
1489   }
1490   if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1491     return TRUE;
1492   if (u->name) {
1493     g_value_unset (&u->value);
1494     return FALSE;
1495   }
1496   u->name = field_id;
1497   gst_value_union (&u->value, val, value);
1498   return TRUE;
1499 }
1500
1501 static gboolean
1502 gst_caps_structure_simplify (GstStructure ** result,
1503     const GstStructure * simplify, GstStructure * compare)
1504 {
1505   GSList *list;
1506   UnionField field = { 0, {0,}, NULL };
1507
1508   /* try to subtract to get a real subset */
1509   if (gst_caps_structure_subtract (&list, simplify, compare)) {
1510     switch (g_slist_length (list)) {
1511       case 0:
1512         *result = NULL;
1513         return TRUE;
1514       case 1:
1515         *result = list->data;
1516         g_slist_free (list);
1517         return TRUE;
1518       default:
1519       {
1520         GSList *walk;
1521
1522         for (walk = list; walk; walk = g_slist_next (walk)) {
1523           gst_structure_free (walk->data);
1524         }
1525         g_slist_free (list);
1526         break;
1527       }
1528     }
1529   }
1530
1531   /* try to union both structs */
1532   field.compare = compare;
1533   if (gst_structure_foreach ((GstStructure *) simplify,
1534           gst_caps_structure_figure_out_union, &field)) {
1535     gboolean ret = FALSE;
1536
1537     /* now we know all of simplify's fields are the same in compare
1538      * but at most one field: field.name */
1539     if (G_IS_VALUE (&field.value)) {
1540       if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
1541         gst_structure_id_set_value (compare, field.name, &field.value);
1542         *result = NULL;
1543         ret = TRUE;
1544       }
1545       g_value_unset (&field.value);
1546     } else if (gst_structure_n_fields (simplify) <=
1547         gst_structure_n_fields (compare)) {
1548       /* compare is just more specific, will be optimized away later */
1549       /* FIXME: do this here? */
1550       GST_LOG ("found a case that will be optimized later.");
1551     } else {
1552       gchar *one = gst_structure_to_string (simplify);
1553       gchar *two = gst_structure_to_string (compare);
1554
1555       GST_ERROR
1556           ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
1557           one, two);
1558       g_free (one);
1559       g_free (two);
1560     }
1561     return ret;
1562   }
1563
1564   return FALSE;
1565 }
1566
1567 static void
1568 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
1569     GstStructure * new, gint i)
1570 {
1571   gst_structure_set_parent_refcount (old, NULL);
1572   gst_structure_free (old);
1573   gst_structure_set_parent_refcount (new, &caps->refcount);
1574   g_ptr_array_index (caps->structs, i) = new;
1575 }
1576
1577 /**
1578  * gst_caps_do_simplify:
1579  * @caps: a #GstCaps to simplify
1580  *
1581  * Modifies the given @caps inplace into a representation that represents the
1582  * same set of formats, but in a simpler form.  Component structures that are
1583  * identical are merged.  Component structures that have values that can be
1584  * merged are also merged.
1585  *
1586  * Returns: TRUE, if the caps could be simplified
1587  */
1588 gboolean
1589 gst_caps_do_simplify (GstCaps * caps)
1590 {
1591   GstStructure *simplify, *compare, *result = NULL;
1592   gint i, j, start;
1593   gboolean changed = FALSE;
1594
1595   g_return_val_if_fail (caps != NULL, FALSE);
1596   g_return_val_if_fail (IS_WRITABLE (caps), FALSE);
1597
1598   if (gst_caps_get_size (caps) < 2)
1599     return FALSE;
1600
1601   g_ptr_array_sort (caps->structs, gst_caps_compare_structures);
1602
1603   start = caps->structs->len - 1;
1604   for (i = caps->structs->len - 1; i >= 0; i--) {
1605     simplify = gst_caps_get_structure (caps, i);
1606     if (gst_structure_get_name_id (simplify) !=
1607         gst_structure_get_name_id (gst_caps_get_structure (caps, start)))
1608       start = i;
1609     for (j = start; j >= 0; j--) {
1610       if (j == i)
1611         continue;
1612       compare = gst_caps_get_structure (caps, j);
1613       if (gst_structure_get_name_id (simplify) !=
1614           gst_structure_get_name_id (compare)) {
1615         break;
1616       }
1617       if (gst_caps_structure_simplify (&result, simplify, compare)) {
1618         if (result) {
1619           gst_caps_switch_structures (caps, simplify, result, i);
1620           simplify = result;
1621         } else {
1622           gst_caps_remove_structure (caps, i);
1623           start--;
1624           break;
1625         }
1626         changed = TRUE;
1627       }
1628     }
1629   }
1630
1631   if (!changed)
1632     return FALSE;
1633
1634   /* gst_caps_do_simplify (caps); */
1635   return TRUE;
1636 }
1637
1638 #ifndef GST_DISABLE_LOADSAVE
1639 /**
1640  * gst_caps_save_thyself:
1641  * @caps: a #GstCaps structure
1642  * @parent: a XML parent node
1643  *
1644  * Serializes a #GstCaps to XML and adds it as a child node of @parent.
1645  *
1646  * Returns: a XML node pointer
1647  */
1648 xmlNodePtr
1649 gst_caps_save_thyself (const GstCaps * caps, xmlNodePtr parent)
1650 {
1651   char *s = gst_caps_to_string (caps);
1652
1653   xmlNewChild (parent, NULL, (xmlChar *) "caps", (xmlChar *) s);
1654   g_free (s);
1655   return parent;
1656 }
1657
1658 /**
1659  * gst_caps_load_thyself:
1660  * @parent: a XML node
1661  *
1662  * Creates a #GstCaps from its XML serialization.
1663  *
1664  * Returns: a new #GstCaps structure
1665  */
1666 GstCaps *
1667 gst_caps_load_thyself (xmlNodePtr parent)
1668 {
1669   if (strcmp ("caps", (char *) parent->name) == 0) {
1670     return gst_caps_from_string ((gchar *) xmlNodeGetContent (parent));
1671   }
1672
1673   return NULL;
1674 }
1675 #endif
1676
1677 /* utility */
1678
1679 /**
1680  * gst_caps_replace:
1681  * @caps: a pointer to #GstCaps
1682  * @newcaps: a #GstCaps to replace *caps
1683  *
1684  * Replaces *caps with @newcaps.  Unrefs the #GstCaps in the location
1685  * pointed to by @caps, if applicable, then modifies @caps to point to
1686  * @newcaps. An additional ref on @newcaps is taken.
1687  *
1688  * This function does not take any locks so you might want to lock
1689  * the object owning @caps pointer.
1690  */
1691 void
1692 gst_caps_replace (GstCaps ** caps, GstCaps * newcaps)
1693 {
1694   GstCaps *oldcaps;
1695
1696   g_return_if_fail (caps != NULL);
1697
1698   oldcaps = *caps;
1699
1700   if (newcaps != oldcaps) {
1701     if (newcaps)
1702       gst_caps_ref (newcaps);
1703
1704     *caps = newcaps;
1705
1706     if (oldcaps)
1707       gst_caps_unref (oldcaps);
1708   }
1709 }
1710
1711 /**
1712  * gst_caps_to_string:
1713  * @caps: a #GstCaps
1714  *
1715  * Converts @caps to a string representation.  This string representation
1716  * can be converted back to a #GstCaps by gst_caps_from_string().
1717  *
1718  * For debugging purposes its easier to do something like this:
1719  * <programlisting>
1720  *  GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
1721  * </programlisting>
1722  * This prints the caps in human readble form.
1723  *
1724  * Returns: a newly allocated string representing @caps.
1725  */
1726 gchar *
1727 gst_caps_to_string (const GstCaps * caps)
1728 {
1729   guint i;
1730   GString *s;
1731
1732   /* NOTE:  This function is potentially called by the debug system,
1733    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
1734    * should be careful to avoid recursion.  This includes any functions
1735    * called by gst_caps_to_string.  In particular, calls should
1736    * not use the GST_PTR_FORMAT extension.  */
1737
1738   if (caps == NULL) {
1739     return g_strdup ("NULL");
1740   }
1741   if (gst_caps_is_any (caps)) {
1742     return g_strdup ("ANY");
1743   }
1744   if (gst_caps_is_empty (caps)) {
1745     return g_strdup ("EMPTY");
1746   }
1747
1748   s = g_string_new ("");
1749   for (i = 0; i < caps->structs->len; i++) {
1750     GstStructure *structure;
1751     char *sstr;
1752
1753     if (i > 0)
1754       g_string_append (s, "; ");
1755
1756     structure = gst_caps_get_structure (caps, i);
1757     sstr = gst_structure_to_string (structure);
1758     g_string_append (s, sstr);
1759     g_free (sstr);
1760   }
1761
1762   return g_string_free (s, FALSE);
1763 }
1764
1765 static gboolean
1766 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
1767 {
1768   GstStructure *structure;
1769   gchar *s;
1770
1771   g_return_val_if_fail (string, FALSE);
1772   if (strcmp ("ANY", string) == 0) {
1773     caps->flags = GST_CAPS_FLAGS_ANY;
1774     return TRUE;
1775   }
1776   if (strcmp ("EMPTY", string) == 0) {
1777     return TRUE;
1778   }
1779
1780   structure = gst_structure_from_string (string, &s);
1781   if (structure == NULL) {
1782     return FALSE;
1783   }
1784   gst_caps_append_structure (caps, structure);
1785
1786   while (*s == ';') {
1787     s++;
1788     while (g_ascii_isspace (*s))
1789       s++;
1790     structure = gst_structure_from_string (s, &s);
1791     if (structure == NULL) {
1792       return FALSE;
1793     }
1794     gst_caps_append_structure (caps, structure);
1795     while (g_ascii_isspace (*s))
1796       s++;
1797   }
1798
1799   if (*s != 0) {
1800     return FALSE;
1801   }
1802
1803   return TRUE;
1804 }
1805
1806 /**
1807  * gst_caps_from_string:
1808  * @string: a string to convert to #GstCaps
1809  *
1810  * Converts @caps from a string representation.
1811  *
1812  * Returns: a newly allocated #GstCaps
1813  */
1814 GstCaps *
1815 gst_caps_from_string (const gchar * string)
1816 {
1817   GstCaps *caps;
1818
1819   caps = gst_caps_new_empty ();
1820   if (gst_caps_from_string_inplace (caps, string)) {
1821     return caps;
1822   } else {
1823     gst_caps_unref (caps);
1824     return NULL;
1825   }
1826 }
1827
1828 static void
1829 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
1830 {
1831   g_return_if_fail (G_IS_VALUE (src_value));
1832   g_return_if_fail (G_IS_VALUE (dest_value));
1833   g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
1834   g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
1835       || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
1836
1837   dest_value->data[0].v_pointer =
1838       gst_caps_to_string (src_value->data[0].v_pointer);
1839 }
1840
1841 static GstCaps *
1842 gst_caps_copy_conditional (GstCaps * src)
1843 {
1844   if (src) {
1845     return gst_caps_ref (src);
1846   } else {
1847     return NULL;
1848   }
1849 }