caps: Set sysmem features if explicitely requested
[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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /**
21  * SECTION:gstcaps
22  * @short_description: Structure describing sets of media formats
23  * @see_also: #GstStructure, #GstMiniObject
24  *
25  * Caps (capabilities) are lightweight 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 #GstRegistry along with
30  * a description of the #GstElement.
31  *
32  * Caps are exposed on the element pads using the gst_pad_query_caps() pad
33  * function. This function describes the possible types that the pad can
34  * handle or produce at runtime.
35  *
36  * A #GstCaps can be constructed with the following code fragment:
37  *
38  * <example>
39  *  <title>Creating caps</title>
40  *  <programlisting>
41  *  GstCaps *caps;
42  *  caps = gst_caps_new_simple ("video/x-raw",
43  *       "format", G_TYPE_STRING, "I420",
44  *       "framerate", GST_TYPE_FRACTION, 25, 1,
45  *       "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
46  *       "width", G_TYPE_INT, 320,
47  *       "height", G_TYPE_INT, 240,
48  *       NULL);
49  *  </programlisting>
50  * </example>
51  *
52  * A #GstCaps is fixed when it has no properties with ranges or lists. Use
53  * gst_caps_is_fixed() to test for fixed caps. Fixed caps can be used in a
54  * caps event to notify downstream elements of the current media type.
55  *
56  * Various methods exist to work with the media types such as subtracting
57  * or intersecting.
58  *
59  * Last reviewed on 2011-03-28 (0.11.3)
60  */
61
62 #ifdef HAVE_CONFIG_H
63 #include "config.h"
64 #endif
65 #include <string.h>
66 #include <signal.h>
67
68 #include "gst_private.h"
69 #include <gst/gst.h>
70 #include <gobject/gvaluecollector.h>
71
72 #define DEBUG_REFCOUNT
73
74 typedef struct _GstCapsArrayElement
75 {
76   GstStructure *structure;
77   GstCapsFeatures *features;
78 } GstCapsArrayElement;
79
80 typedef struct _GstCapsImpl
81 {
82   GstCaps caps;
83
84   GArray *array;
85 } GstCapsImpl;
86
87 #define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
88
89 #define GST_CAPS_LEN(c)   (GST_CAPS_ARRAY(c)->len)
90
91 #define IS_WRITABLE(caps) \
92   (GST_CAPS_REFCOUNT_VALUE (caps) == 1)
93
94 /* same as gst_caps_is_any () */
95 #define CAPS_IS_ANY(caps)                               \
96   (GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY)
97
98 /* same as gst_caps_is_empty () */
99 #define CAPS_IS_EMPTY(caps)                             \
100   (!CAPS_IS_ANY(caps) && CAPS_IS_EMPTY_SIMPLE(caps))
101
102 #define CAPS_IS_EMPTY_SIMPLE(caps)                                      \
103   ((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
104
105 #define gst_caps_features_copy_conditional(f) ((f && !gst_caps_features_is_equal (f, GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) ? gst_caps_features_copy (f) : NULL)
106
107 /* quick way to get a caps structure at an index without doing a type or array
108  * length check */
109 #define gst_caps_get_structure_unchecked(caps, index) \
110      (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).structure)
111 #define gst_caps_get_features_unchecked(caps, index) \
112      (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
113 /* quick way to append a structure without checking the args */
114 #define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
115   GstCapsArrayElement __e={s, f};                                      \
116   if (gst_structure_set_parent_refcount (__e.structure, &GST_MINI_OBJECT_REFCOUNT(caps)) && \
117       (!__e.features || gst_caps_features_set_parent_refcount (__e.features, &GST_MINI_OBJECT_REFCOUNT(caps))))         \
118     g_array_append_val (GST_CAPS_ARRAY (caps), __e);                             \
119 }G_STMT_END
120
121 /* lock to protect multiple invocations of static caps to caps conversion */
122 G_LOCK_DEFINE_STATIC (static_caps_lock);
123
124 static void gst_caps_transform_to_string (const GValue * src_value,
125     GValue * dest_value);
126 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
127     const gchar * string);
128
129 GType _gst_caps_type = 0;
130 GstCaps *_gst_caps_any;
131 GstCaps *_gst_caps_none;
132
133 GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
134
135 void
136 _priv_gst_caps_initialize (void)
137 {
138   _gst_caps_type = gst_caps_get_type ();
139
140   _gst_caps_any = gst_caps_new_any ();
141   _gst_caps_none = gst_caps_new_empty ();
142
143   g_value_register_transform_func (_gst_caps_type,
144       G_TYPE_STRING, gst_caps_transform_to_string);
145 }
146
147 static GstCaps *
148 _gst_caps_copy (const GstCaps * caps)
149 {
150   GstCaps *newcaps;
151   GstStructure *structure;
152   GstCapsFeatures *features;
153   guint i, n;
154
155   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
156
157   newcaps = gst_caps_new_empty ();
158   GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
159   n = GST_CAPS_LEN (caps);
160
161   GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, caps, "doing copy %p -> %p",
162       caps, newcaps);
163
164   for (i = 0; i < n; i++) {
165     structure = gst_caps_get_structure_unchecked (caps, i);
166     features = gst_caps_get_features_unchecked (caps, i);
167     gst_caps_append_structure_full (newcaps, gst_structure_copy (structure),
168         gst_caps_features_copy_conditional (features));
169   }
170
171   return newcaps;
172 }
173
174 /* creation/deletion */
175 static void
176 _gst_caps_free (GstCaps * caps)
177 {
178   GstStructure *structure;
179   GstCapsFeatures *features;
180   guint i, len;
181
182   /* The refcount must be 0, but since we're only called by gst_caps_unref,
183    * don't bother testing. */
184   len = GST_CAPS_LEN (caps);
185   /* This can be used to get statistics about caps sizes */
186   /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
187   for (i = 0; i < len; i++) {
188     structure = gst_caps_get_structure_unchecked (caps, i);
189     gst_structure_set_parent_refcount (structure, NULL);
190     gst_structure_free (structure);
191     features = gst_caps_get_features_unchecked (caps, i);
192     if (features) {
193       gst_caps_features_set_parent_refcount (features, NULL);
194       gst_caps_features_free (features);
195     }
196   }
197   g_array_free (GST_CAPS_ARRAY (caps), TRUE);
198
199 #ifdef DEBUG_REFCOUNT
200   GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
201 #endif
202   g_slice_free1 (sizeof (GstCapsImpl), caps);
203 }
204
205 static void
206 gst_caps_init (GstCaps * caps)
207 {
208   gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
209       (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
210       (GstMiniObjectFreeFunction) _gst_caps_free);
211
212   /* the 32 has been determined by logging caps sizes in _gst_caps_free
213    * but g_ptr_array uses 16 anyway if it expands once, so this does not help
214    * in practice
215    * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
216    */
217   GST_CAPS_ARRAY (caps) =
218       g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
219 }
220
221 /**
222  * gst_caps_new_empty:
223  *
224  * Creates a new #GstCaps that is empty.  That is, the returned
225  * #GstCaps contains no media formats.
226  * The #GstCaps is guaranteed to be writable.
227  * Caller is responsible for unreffing the returned caps.
228  *
229  * Returns: (transfer full): the new #GstCaps
230  */
231 GstCaps *
232 gst_caps_new_empty (void)
233 {
234   GstCaps *caps;
235
236   caps = (GstCaps *) g_slice_new (GstCapsImpl);
237
238   gst_caps_init (caps);
239
240 #ifdef DEBUG_REFCOUNT
241   GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
242 #endif
243
244   return caps;
245 }
246
247 /**
248  * gst_caps_new_any:
249  *
250  * Creates a new #GstCaps that indicates that it is compatible with
251  * any media format.
252  *
253  * Returns: (transfer full): the new #GstCaps
254  */
255 GstCaps *
256 gst_caps_new_any (void)
257 {
258   GstCaps *caps = gst_caps_new_empty ();
259
260   GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_ANY);
261
262   return caps;
263 }
264
265 /**
266  * gst_caps_new_empty_simple:
267  * @media_type: the media type of the structure
268  *
269  * Creates a new #GstCaps that contains one #GstStructure with name
270  * @media_type.
271  * Caller is responsible for unreffing the returned caps.
272  *
273  * Returns: (transfer full): the new #GstCaps
274  */
275 GstCaps *
276 gst_caps_new_empty_simple (const char *media_type)
277 {
278   GstCaps *caps;
279   GstStructure *structure;
280
281   caps = gst_caps_new_empty ();
282   structure = gst_structure_new_empty (media_type);
283   if (structure)
284     gst_caps_append_structure_unchecked (caps, structure, NULL);
285
286   return caps;
287 }
288
289 /**
290  * gst_caps_new_simple:
291  * @media_type: the media type of the structure
292  * @fieldname: first field to set
293  * @...: additional arguments
294  *
295  * Creates a new #GstCaps that contains one #GstStructure.  The
296  * structure is defined by the arguments, which have the same format
297  * as gst_structure_new().
298  * Caller is responsible for unreffing the returned caps.
299  *
300  * Returns: (transfer full): the new #GstCaps
301  */
302 GstCaps *
303 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
304 {
305   GstCaps *caps;
306   GstStructure *structure;
307   va_list var_args;
308
309   caps = gst_caps_new_empty ();
310
311   va_start (var_args, fieldname);
312   structure = gst_structure_new_valist (media_type, fieldname, var_args);
313   va_end (var_args);
314
315   if (structure)
316     gst_caps_append_structure_unchecked (caps, structure, NULL);
317   else
318     gst_caps_replace (&caps, NULL);
319
320   return caps;
321 }
322
323 /**
324  * gst_caps_new_full:
325  * @struct1: the first structure to add
326  * @...: additional structures to add
327  *
328  * Creates a new #GstCaps and adds all the structures listed as
329  * arguments.  The list must be NULL-terminated.  The structures
330  * are not copied; the returned #GstCaps owns the structures.
331  *
332  * Returns: (transfer full): the new #GstCaps
333  */
334 GstCaps *
335 gst_caps_new_full (GstStructure * struct1, ...)
336 {
337   GstCaps *caps;
338   va_list var_args;
339
340   va_start (var_args, struct1);
341   caps = gst_caps_new_full_valist (struct1, var_args);
342   va_end (var_args);
343
344   return caps;
345 }
346
347 /**
348  * gst_caps_new_full_valist:
349  * @structure: the first structure to add
350  * @var_args: additional structures to add
351  *
352  * Creates a new #GstCaps and adds all the structures listed as
353  * arguments.  The list must be NULL-terminated.  The structures
354  * are not copied; the returned #GstCaps owns the structures.
355  *
356  * Returns: (transfer full): the new #GstCaps
357  */
358 GstCaps *
359 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
360 {
361   GstCaps *caps;
362
363   caps = gst_caps_new_empty ();
364
365   while (structure) {
366     gst_caps_append_structure_unchecked (caps, structure, NULL);
367     structure = va_arg (var_args, GstStructure *);
368   }
369
370   return caps;
371 }
372
373 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
374
375 /**
376  * gst_static_caps_get:
377  * @static_caps: the #GstStaticCaps to convert
378  *
379  * Converts a #GstStaticCaps to a #GstCaps.
380  *
381  * Returns: (transfer full): a pointer to the #GstCaps. Unref after usage.
382  *     Since the core holds an additional ref to the returned caps,
383  *     use gst_caps_make_writable() on the returned caps to modify it.
384  */
385 GstCaps *
386 gst_static_caps_get (GstStaticCaps * static_caps)
387 {
388   GstCaps **caps;
389
390   g_return_val_if_fail (static_caps != NULL, NULL);
391
392   caps = &static_caps->caps;
393
394   /* refcount is 0 when we need to convert */
395   if (G_UNLIKELY (*caps == NULL)) {
396     const char *string;
397
398     G_LOCK (static_caps_lock);
399     /* check if other thread already updated */
400     if (G_UNLIKELY (*caps != NULL))
401       goto done;
402
403     string = static_caps->string;
404
405     if (G_UNLIKELY (string == NULL))
406       goto no_string;
407
408     *caps = gst_caps_from_string (string);
409
410     /* convert to string */
411     if (G_UNLIKELY (*caps == NULL))
412       g_critical ("Could not convert static caps \"%s\"", string);
413
414     GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
415         string);
416   done:
417     G_UNLOCK (static_caps_lock);
418   }
419   /* ref the caps, makes it not writable */
420   if (G_LIKELY (*caps != NULL))
421     gst_caps_ref (*caps);
422
423   return *caps;
424
425   /* ERRORS */
426 no_string:
427   {
428     G_UNLOCK (static_caps_lock);
429     g_warning ("static caps %p string is NULL", static_caps);
430     return NULL;
431   }
432 }
433
434 /**
435  * gst_static_caps_cleanup:
436  * @static_caps: the #GstStaticCaps to clean
437  *
438  * Clean up the cached caps contained in @static_caps.
439  */
440 void
441 gst_static_caps_cleanup (GstStaticCaps * static_caps)
442 {
443   G_LOCK (static_caps_lock);
444   gst_caps_replace (&static_caps->caps, NULL);
445   G_UNLOCK (static_caps_lock);
446 }
447
448 /* manipulation */
449
450 static void
451 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
452     GstStructure ** s, GstCapsFeatures ** f)
453 {
454   GstStructure *s_;
455   GstCapsFeatures *f_;
456
457   s_ = gst_caps_get_structure_unchecked (caps, idx);
458   f_ = gst_caps_get_features_unchecked (caps, idx);
459
460   /* don't use index_fast, gst_caps_simplify relies on the order */
461   g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
462
463   gst_structure_set_parent_refcount (s_, NULL);
464   if (f_) {
465     gst_caps_features_set_parent_refcount (f_, NULL);
466   }
467
468   *s = s_;
469   *f = f_;
470 }
471
472 static GstStructure *
473 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
474 {
475   GstStructure *s;
476   GstCapsFeatures *f;
477
478   gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
479
480   if (f)
481     gst_caps_features_free (f);
482
483   return s;
484 }
485
486
487
488 /**
489  * gst_caps_steal_structure:
490  * @caps: the #GstCaps to retrieve from
491  * @index: Index of the structure to retrieve
492  *
493  * Retrieves the structure with the given index from the list of structures
494  * contained in @caps. The caller becomes the owner of the returned structure.
495  *
496  * Returns: (transfer full): a pointer to the #GstStructure corresponding
497  *     to @index.
498  */
499 GstStructure *
500 gst_caps_steal_structure (GstCaps * caps, guint index)
501 {
502   g_return_val_if_fail (caps != NULL, NULL);
503   g_return_val_if_fail (IS_WRITABLE (caps), NULL);
504
505   if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
506     return NULL;
507
508   return gst_caps_remove_and_get_structure (caps, index);
509 }
510
511 /**
512  * gst_caps_append:
513  * @caps1: the #GstCaps that will be appended to
514  * @caps2: (transfer full): the #GstCaps to append
515  *
516  * Appends the structures contained in @caps2 to @caps1. The structures in
517  * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
518  * freed. If either caps is ANY, the resulting caps will be ANY.
519  */
520 void
521 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
522 {
523   GstStructure *structure;
524   GstCapsFeatures *features;
525   int i;
526
527   g_return_if_fail (GST_IS_CAPS (caps1));
528   g_return_if_fail (GST_IS_CAPS (caps2));
529   g_return_if_fail (IS_WRITABLE (caps1));
530
531   if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
532     GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
533     gst_caps_unref (caps2);
534   } else {
535     caps2 = gst_caps_make_writable (caps2);
536
537     for (i = GST_CAPS_LEN (caps2); i; i--) {
538       gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
539           &features);
540       gst_caps_append_structure_unchecked (caps1, structure, features);
541     }
542     gst_caps_unref (caps2);     /* guaranteed to free it */
543   }
544 }
545
546 /**
547  * gst_caps_merge:
548  * @caps1: (transfer full): the #GstCaps that will take the new entries
549  * @caps2: (transfer full): the #GstCaps to merge in
550  *
551  * Appends the structures contained in @caps2 to @caps1 if they are not yet
552  * expressed by @caps1. The structures in @caps2 are not copied -- they are
553  * transferred to a writable copy of @caps1, and then @caps2 is freed.
554  * If either caps is ANY, the resulting caps will be ANY.
555  *
556  * Returns: (transfer full): the merged caps.
557  */
558 GstCaps *
559 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
560 {
561   GstStructure *structure;
562   GstCapsFeatures *features;
563   int i;
564   GstCaps *result;
565
566   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
567   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
568
569   if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
570     gst_caps_unref (caps2);
571     result = caps1;
572   } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
573     gst_caps_unref (caps1);
574     result = caps2;
575   } else {
576     caps2 = gst_caps_make_writable (caps2);
577
578     for (i = GST_CAPS_LEN (caps2); i; i--) {
579       gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
580           &features);
581       caps1 = gst_caps_merge_structure_full (caps1, structure, features);
582     }
583     gst_caps_unref (caps2);
584     result = caps1;
585
586     /* this is too naive
587        GstCaps *com = gst_caps_intersect (caps1, caps2);
588        GstCaps *add = gst_caps_subtract (caps2, com);
589
590        GST_DEBUG ("common : %d", gst_caps_get_size (com));
591        GST_DEBUG ("adding : %d", gst_caps_get_size (add));
592        gst_caps_append (caps1, add);
593        gst_caps_unref (com);
594      */
595   }
596
597   return result;
598 }
599
600 /**
601  * gst_caps_append_structure:
602  * @caps: the #GstCaps that will be appended to
603  * @structure: (transfer full): the #GstStructure to append
604  *
605  * Appends @structure to @caps.  The structure is not copied; @caps
606  * becomes the owner of @structure.
607  */
608 void
609 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
610 {
611   g_return_if_fail (GST_IS_CAPS (caps));
612   g_return_if_fail (IS_WRITABLE (caps));
613
614   if (G_LIKELY (structure)) {
615     gst_caps_append_structure_unchecked (caps, structure, NULL);
616   }
617 }
618
619 /**
620  * gst_caps_append_structure_full:
621  * @caps: the #GstCaps that will be appended to
622  * @structure: (transfer full): the #GstStructure to append
623  * @features: (transfer full) (allow-none): the #GstCapsFeatures to append
624  *
625  * Appends @structure with @features to @caps.  The structure is not copied; @caps
626  * becomes the owner of @structure.
627  */
628 void
629 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
630     GstCapsFeatures * features)
631 {
632   g_return_if_fail (GST_IS_CAPS (caps));
633   g_return_if_fail (IS_WRITABLE (caps));
634
635   if (G_LIKELY (structure)) {
636     gst_caps_append_structure_unchecked (caps, structure, features);
637   }
638 }
639
640 /**
641  * gst_caps_remove_structure:
642  * @caps: the #GstCaps to remove from
643  * @idx: Index of the structure to remove
644  *
645  * removes the stucture with the given index from the list of structures
646  * contained in @caps.
647  */
648 void
649 gst_caps_remove_structure (GstCaps * caps, guint idx)
650 {
651   GstStructure *structure;
652
653   g_return_if_fail (caps != NULL);
654   g_return_if_fail (idx <= gst_caps_get_size (caps));
655   g_return_if_fail (IS_WRITABLE (caps));
656
657   structure = gst_caps_remove_and_get_structure (caps, idx);
658   gst_structure_free (structure);
659 }
660
661 /**
662  * gst_caps_merge_structure:
663  * @caps: (transfer full): the #GstCaps to merge into
664  * @structure: (transfer full): the #GstStructure to merge
665  *
666  * Appends @structure to @caps if its not already expressed by @caps.
667  *
668  * Returns: (transfer full): the merged caps.
669  */
670 GstCaps *
671 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
672 {
673   GstStructure *structure1;
674   GstCapsFeatures *features1;
675   int i;
676   gboolean unique = TRUE;
677
678   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
679
680   if (G_UNLIKELY (structure == NULL))
681     return caps;
682
683   /* check each structure */
684   for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
685     structure1 = gst_caps_get_structure_unchecked (caps, i);
686     features1 = gst_caps_get_features_unchecked (caps, i);
687     if (!features1)
688       features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
689
690     /* if structure is a subset of structure1 and the
691      * there are no existing features, then skip it */
692     if (gst_structure_is_subset (structure, structure1) &&
693         gst_caps_features_is_equal (features1,
694             GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) {
695       unique = FALSE;
696       break;
697     }
698   }
699   if (unique) {
700     caps = gst_caps_make_writable (caps);
701     gst_caps_append_structure_unchecked (caps, structure, NULL);
702   } else {
703     gst_structure_free (structure);
704   }
705   return caps;
706 }
707
708 /**
709  * gst_caps_merge_structure_full:
710  * @caps: (transfer full): the #GstCaps to merge into
711  * @structure: (transfer full): the #GstStructure to merge
712  * @features: (transfer full) (allow-none): the #GstCapsFeatures to merge
713  *
714  * Appends @structure with @features to @caps if its not already expressed by @caps.
715  *
716  * Returns: (transfer full): the merged caps.
717  */
718 GstCaps *
719 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
720     GstCapsFeatures * features)
721 {
722   GstStructure *structure1;
723   GstCapsFeatures *features1, *features_tmp;
724   int i;
725   gboolean unique = TRUE;
726
727   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
728
729   if (G_UNLIKELY (structure == NULL))
730     return caps;
731
732   /* To make comparisons easier below */
733   features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
734
735   /* check each structure */
736   for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
737     structure1 = gst_caps_get_structure_unchecked (caps, i);
738     features1 = gst_caps_get_features_unchecked (caps, i);
739     if (!features1)
740       features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
741     /* if structure is a subset of structure1 and the
742      * the features are a subset, then skip it */
743     if (gst_structure_is_subset (structure, structure1) &&
744         gst_caps_features_is_equal (features_tmp, features1)) {
745       unique = FALSE;
746       break;
747     }
748   }
749   if (unique) {
750     caps = gst_caps_make_writable (caps);
751     gst_caps_append_structure_unchecked (caps, structure, features);
752   } else {
753     gst_structure_free (structure);
754     if (features)
755       gst_caps_features_free (features);
756   }
757   return caps;
758 }
759
760 /**
761  * gst_caps_get_size:
762  * @caps: a #GstCaps
763  *
764  * Gets the number of structures contained in @caps.
765  *
766  * Returns: the number of structures that @caps contains
767  */
768 guint
769 gst_caps_get_size (const GstCaps * caps)
770 {
771   g_return_val_if_fail (GST_IS_CAPS (caps), 0);
772
773   return GST_CAPS_LEN (caps);
774 }
775
776 /**
777  * gst_caps_get_structure:
778  * @caps: a #GstCaps
779  * @index: the index of the structure
780  *
781  * Finds the structure in @caps that has the index @index, and
782  * returns it.
783  *
784  * WARNING: This function takes a const GstCaps *, but returns a
785  * non-const GstStructure *.  This is for programming convenience --
786  * the caller should be aware that structures inside a constant
787  * #GstCaps should not be modified. However, if you know the caps
788  * are writable, either because you have just copied them or made
789  * them writable with gst_caps_make_writable(), you may modify the
790  * structure returned in the usual way, e.g. with functions like
791  * gst_structure_set().
792  *
793  * You do not need to free or unref the structure returned, it
794  * belongs to the #GstCaps.
795  *
796  * Returns: (transfer none): a pointer to the #GstStructure corresponding
797  *     to @index
798  */
799 GstStructure *
800 gst_caps_get_structure (const GstCaps * caps, guint index)
801 {
802   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
803   g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
804
805   return gst_caps_get_structure_unchecked (caps, index);
806 }
807
808 /**
809  * gst_caps_get_features:
810  * @caps: a #GstCaps
811  * @index: the index of the structure
812  *
813  * Finds the features in @caps that has the index @index, and
814  * returns it.
815  *
816  * WARNING: This function takes a const GstCaps *, but returns a
817  * non-const GstCapsFeatures *.  This is for programming convenience --
818  * the caller should be aware that structures inside a constant
819  * #GstCaps should not be modified. However, if you know the caps
820  * are writable, either because you have just copied them or made
821  * them writable with gst_caps_make_writable(), you may modify the
822  * features returned in the usual way, e.g. with functions like
823  * gst_caps_features_add().
824  *
825  * You do not need to free or unref the structure returned, it
826  * belongs to the #GstCaps.
827  *
828  * Returns: (transfer none): a pointer to the #GstCapsFeatures corresponding
829  *     to @index
830  */
831 GstCapsFeatures *
832 gst_caps_get_features (const GstCaps * caps, guint index)
833 {
834   GstCapsFeatures *features;
835
836   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
837   g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
838
839   features = gst_caps_get_features_unchecked (caps, index);
840   if (!features)
841     features = gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
842
843   return features;
844 }
845
846 /**
847  * gst_caps_set_features:
848  * @caps: a #GstCaps
849  * @index: the index of the structure
850  * @features: (allow-none) (transfer full): the #GstFeatures to set
851  *
852  * Sets the #GstCapsFeatures @features for the structure at @index.
853  */
854 void
855 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
856 {
857   GstCapsFeatures **storage, *old;
858
859   g_return_if_fail (caps != NULL);
860   g_return_if_fail (index <= gst_caps_get_size (caps));
861   g_return_if_fail (IS_WRITABLE (caps));
862
863   storage = &gst_caps_get_features_unchecked (caps, index);
864   old = *storage;
865   *storage = features;
866   if (old)
867     gst_caps_features_free (old);
868 }
869
870 /**
871  * gst_caps_copy_nth:
872  * @caps: the #GstCaps to copy
873  * @nth: the nth structure to copy
874  *
875  * Creates a new #GstCaps and appends a copy of the nth structure
876  * contained in @caps.
877  *
878  * Returns: (transfer full): the new #GstCaps
879  */
880 GstCaps *
881 gst_caps_copy_nth (const GstCaps * caps, guint nth)
882 {
883   GstCaps *newcaps;
884   GstStructure *structure;
885   GstCapsFeatures *features;
886
887   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
888
889   newcaps = gst_caps_new_empty ();
890   GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
891
892   if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
893     structure = gst_caps_get_structure_unchecked (caps, nth);
894     features = gst_caps_get_features_unchecked (caps, nth);
895     gst_caps_append_structure_unchecked (newcaps,
896         gst_structure_copy (structure),
897         gst_caps_features_copy_conditional (features));
898   }
899
900   return newcaps;
901 }
902
903 /**
904  * gst_caps_truncate:
905  * @caps: (transfer full): the #GstCaps to truncate
906  *
907  * Discard all but the first structure from @caps. Useful when
908  * fixating.
909  *
910  * Returns: (transfer full): truncated caps
911  */
912 GstCaps *
913 gst_caps_truncate (GstCaps * caps)
914 {
915   gint i;
916
917   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
918
919   i = GST_CAPS_LEN (caps) - 1;
920   if (i == 0)
921     return caps;
922
923   caps = gst_caps_make_writable (caps);
924   while (i > 0)
925     gst_caps_remove_structure (caps, i--);
926
927   return caps;
928 }
929
930 /**
931  * gst_caps_set_value:
932  * @caps: a writable caps
933  * @field: name of the field to set
934  * @value: value to set the field to
935  *
936  * Sets the given @field on all structures of @caps to the given @value.
937  * This is a convenience function for calling gst_structure_set_value() on
938  * all structures of @caps.
939  **/
940 void
941 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
942 {
943   guint i, len;
944
945   g_return_if_fail (GST_IS_CAPS (caps));
946   g_return_if_fail (IS_WRITABLE (caps));
947   g_return_if_fail (field != NULL);
948   g_return_if_fail (G_IS_VALUE (value));
949
950   len = GST_CAPS_LEN (caps);
951   for (i = 0; i < len; i++) {
952     GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
953     gst_structure_set_value (structure, field, value);
954   }
955 }
956
957 /**
958  * gst_caps_set_simple_valist:
959  * @caps: the #GstCaps to set
960  * @field: first field to set
961  * @varargs: additional parameters
962  *
963  * Sets fields in a #GstCaps.  The arguments must be passed in the same
964  * manner as gst_structure_set(), and be NULL-terminated.
965  */
966 void
967 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
968 {
969   GValue value = { 0, };
970
971   g_return_if_fail (GST_IS_CAPS (caps));
972   g_return_if_fail (IS_WRITABLE (caps));
973
974   while (field) {
975     GType type;
976     char *err;
977
978     type = va_arg (varargs, GType);
979
980     G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
981     if (G_UNLIKELY (err)) {
982       g_critical ("%s", err);
983       return;
984     }
985
986     gst_caps_set_value (caps, field, &value);
987
988     g_value_unset (&value);
989
990     field = va_arg (varargs, const gchar *);
991   }
992 }
993
994 /**
995  * gst_caps_set_simple:
996  * @caps: the #GstCaps to set
997  * @field: first field to set
998  * @...: additional parameters
999  *
1000  * Sets fields in a #GstCaps.  The arguments must be passed in the same
1001  * manner as gst_structure_set(), and be NULL-terminated.
1002  */
1003 void
1004 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1005 {
1006   va_list var_args;
1007
1008   g_return_if_fail (GST_IS_CAPS (caps));
1009   g_return_if_fail (IS_WRITABLE (caps));
1010
1011   va_start (var_args, field);
1012   gst_caps_set_simple_valist (caps, field, var_args);
1013   va_end (var_args);
1014 }
1015
1016 /* tests */
1017
1018 /**
1019  * gst_caps_is_any:
1020  * @caps: the #GstCaps to test
1021  *
1022  * Determines if @caps represents any media format.
1023  *
1024  * Returns: TRUE if @caps represents any format.
1025  */
1026 gboolean
1027 gst_caps_is_any (const GstCaps * caps)
1028 {
1029   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1030
1031   return (CAPS_IS_ANY (caps));
1032 }
1033
1034 /**
1035  * gst_caps_is_empty:
1036  * @caps: the #GstCaps to test
1037  *
1038  * Determines if @caps represents no media formats.
1039  *
1040  * Returns: TRUE if @caps represents no formats.
1041  */
1042 gboolean
1043 gst_caps_is_empty (const GstCaps * caps)
1044 {
1045   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1046
1047   if (CAPS_IS_ANY (caps))
1048     return FALSE;
1049
1050   return CAPS_IS_EMPTY_SIMPLE (caps);
1051 }
1052
1053 static gboolean
1054 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1055     gpointer unused)
1056 {
1057   return gst_value_is_fixed (value);
1058 }
1059
1060 /**
1061  * gst_caps_is_fixed:
1062  * @caps: the #GstCaps to test
1063  *
1064  * Fixed #GstCaps describe exactly one format, that is, they have exactly
1065  * one structure, and each field in the structure describes a fixed type.
1066  * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1067  *
1068  * Returns: TRUE if @caps is fixed
1069  */
1070 gboolean
1071 gst_caps_is_fixed (const GstCaps * caps)
1072 {
1073   GstStructure *structure;
1074
1075   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1076
1077   if (GST_CAPS_LEN (caps) != 1)
1078     return FALSE;
1079
1080   structure = gst_caps_get_structure_unchecked (caps, 0);
1081
1082   return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1083 }
1084
1085 /**
1086  * gst_caps_is_equal_fixed:
1087  * @caps1: the #GstCaps to test
1088  * @caps2: the #GstCaps to test
1089  *
1090  * Tests if two #GstCaps are equal.  This function only works on fixed
1091  * #GstCaps.
1092  *
1093  * Returns: TRUE if the arguments represent the same format
1094  */
1095 gboolean
1096 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1097 {
1098   GstStructure *struct1, *struct2;
1099   GstCapsFeatures *features1, *features2;
1100
1101   g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1102   g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1103
1104   struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1105   features1 = gst_caps_get_features_unchecked (caps1, 0);
1106   if (!features1)
1107     features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1108   struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1109   features2 = gst_caps_get_features_unchecked (caps2, 0);
1110   if (!features2)
1111     features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1112
1113   return gst_structure_is_equal (struct1, struct2) &&
1114       gst_caps_features_is_equal (features1, features2);
1115 }
1116
1117 /**
1118  * gst_caps_is_always_compatible:
1119  * @caps1: the #GstCaps to test
1120  * @caps2: the #GstCaps to test
1121  *
1122  * A given #GstCaps structure is always compatible with another if
1123  * every media format that is in the first is also contained in the
1124  * second.  That is, @caps1 is a subset of @caps2.
1125  *
1126  * Returns: TRUE if @caps1 is a subset of @caps2.
1127  */
1128 gboolean
1129 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1130 {
1131   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1132   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1133
1134   return gst_caps_is_subset (caps1, caps2);
1135 }
1136
1137 /**
1138  * gst_caps_is_subset:
1139  * @subset: a #GstCaps
1140  * @superset: a potentially greater #GstCaps
1141  *
1142  * Checks if all caps represented by @subset are also represented by @superset.
1143  * <note>This function does not work reliably if optional properties for caps
1144  * are included on one caps and omitted on the other.</note>
1145  *
1146  * Returns: %TRUE if @subset is a subset of @superset
1147  */
1148 gboolean
1149 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1150 {
1151   GstStructure *s1, *s2;
1152   GstCapsFeatures *f1, *f2;
1153   gboolean ret = TRUE;
1154   gint i, j;
1155
1156   g_return_val_if_fail (subset != NULL, FALSE);
1157   g_return_val_if_fail (superset != NULL, FALSE);
1158
1159   if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1160     return TRUE;
1161   if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1162     return FALSE;
1163
1164   for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1165     for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1166       s1 = gst_caps_get_structure_unchecked (subset, i);
1167       f1 = gst_caps_get_features_unchecked (subset, i);
1168       if (!f1)
1169         f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1170       s2 = gst_caps_get_structure_unchecked (superset, j);
1171       f2 = gst_caps_get_features_unchecked (superset, j);
1172       if (!f2)
1173         f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1174       if (gst_structure_is_subset (s1, s2) &&
1175           gst_caps_features_is_equal (f1, f2)) {
1176         /* If we found a superset, continue with the next
1177          * subset structure */
1178         break;
1179       }
1180     }
1181     /* If we found no superset for this subset structure
1182      * we return FALSE immediately */
1183     if (j == -1) {
1184       ret = FALSE;
1185       break;
1186     }
1187   }
1188
1189   return ret;
1190 }
1191
1192 /**
1193  * gst_caps_is_subset_structure:
1194  * @caps: a #GstCaps
1195  * @structure: a potential #GstStructure subset of @caps
1196  *
1197  * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1198  * for more information.
1199  *
1200  * Returns: %TRUE if @structure is a subset of @caps
1201  */
1202 gboolean
1203 gst_caps_is_subset_structure (const GstCaps * caps,
1204     const GstStructure * structure)
1205 {
1206   GstStructure *s;
1207   gint i;
1208
1209   g_return_val_if_fail (caps != NULL, FALSE);
1210   g_return_val_if_fail (structure != NULL, FALSE);
1211
1212   if (CAPS_IS_ANY (caps))
1213     return TRUE;
1214   if (CAPS_IS_EMPTY (caps))
1215     return FALSE;
1216
1217   for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1218     s = gst_caps_get_structure_unchecked (caps, i);
1219     if (gst_structure_is_subset (structure, s)) {
1220       /* If we found a superset return TRUE */
1221       return TRUE;
1222     }
1223   }
1224
1225   return FALSE;
1226 }
1227
1228 /**
1229  * gst_caps_is_subset_structure_full:
1230  * @caps: a #GstCaps
1231  * @structure: a potential #GstStructure subset of @caps
1232  * @features: (allow-none): a #GstCapsFeatures for @structure
1233  *
1234  * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1235  * for more information.
1236  *
1237  * Returns: %TRUE if @structure is a subset of @caps
1238  */
1239 gboolean
1240 gst_caps_is_subset_structure_full (const GstCaps * caps,
1241     const GstStructure * structure, const GstCapsFeatures * features)
1242 {
1243   GstStructure *s;
1244   GstCapsFeatures *f;
1245   gint i;
1246
1247   g_return_val_if_fail (caps != NULL, FALSE);
1248   g_return_val_if_fail (structure != NULL, FALSE);
1249
1250   if (CAPS_IS_ANY (caps))
1251     return TRUE;
1252   if (CAPS_IS_EMPTY (caps))
1253     return FALSE;
1254
1255   if (!features)
1256     features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1257
1258   for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1259     s = gst_caps_get_structure_unchecked (caps, i);
1260     f = gst_caps_get_features_unchecked (caps, i);
1261     if (!f)
1262       f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1263     if (gst_structure_is_subset (structure, s) &&
1264         gst_caps_features_is_equal (features, f)) {
1265       /* If we found a superset return TRUE */
1266       return TRUE;
1267     }
1268   }
1269
1270   return FALSE;
1271 }
1272
1273 /**
1274  * gst_caps_is_equal:
1275  * @caps1: a #GstCaps
1276  * @caps2: another #GstCaps
1277  *
1278  * Checks if the given caps represent the same set of caps.
1279  * <note>This function does not work reliably if optional properties for caps
1280  * are included on one caps and omitted on the other.</note>
1281  *
1282  * Returns: TRUE if both caps are equal.
1283  */
1284 gboolean
1285 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1286 {
1287   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1288   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1289
1290   if (G_UNLIKELY (caps1 == caps2))
1291     return TRUE;
1292
1293   if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1294     return gst_caps_is_equal_fixed (caps1, caps2);
1295
1296   return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1297 }
1298
1299 /**
1300  * gst_caps_is_strictly_equal:
1301  * @caps1: a #GstCaps
1302  * @caps2: another #GstCaps
1303  *
1304  * Checks if the given caps are exactly the same set of caps.
1305  *
1306  * Returns: TRUE if both caps are strictly equal.
1307  */
1308 gboolean
1309 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1310 {
1311   int i;
1312   GstStructure *s1, *s2;
1313   GstCapsFeatures *f1, *f2;
1314
1315   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1316   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1317
1318   if (G_UNLIKELY (caps1 == caps2))
1319     return TRUE;
1320
1321   if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1322     return FALSE;
1323
1324   for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1325     s1 = gst_caps_get_structure_unchecked (caps1, i);
1326     f1 = gst_caps_get_features_unchecked (caps1, i);
1327     if (!f1)
1328       f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1329     s2 = gst_caps_get_structure_unchecked (caps2, i);
1330     f2 = gst_caps_get_features_unchecked (caps2, i);
1331     if (!f2)
1332       f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1333
1334     if (!gst_structure_is_equal (s1, s2)
1335         || !gst_caps_features_is_equal (f1, f2))
1336       return FALSE;
1337   }
1338
1339   return TRUE;
1340 }
1341
1342 /* intersect operation */
1343
1344 /**
1345  * gst_caps_can_intersect:
1346  * @caps1: a #GstCaps to intersect
1347  * @caps2: a #GstCaps to intersect
1348  *
1349  * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1350  * be empty
1351  *
1352  * Returns: %TRUE if intersection would be not empty
1353  */
1354 gboolean
1355 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1356 {
1357   guint64 i;                    /* index can be up to 2 * G_MAX_UINT */
1358   guint j, k, len1, len2;
1359   GstStructure *struct1;
1360   GstStructure *struct2;
1361   GstCapsFeatures *features1;
1362   GstCapsFeatures *features2;
1363
1364   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1365   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1366
1367   /* caps are exactly the same pointers */
1368   if (G_UNLIKELY (caps1 == caps2))
1369     return TRUE;
1370
1371   /* empty caps on either side, return empty */
1372   if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1373     return FALSE;
1374
1375   /* one of the caps is any */
1376   if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1377     return TRUE;
1378
1379   /* run zigzag on top line then right line, this preserves the caps order
1380    * much better than a simple loop.
1381    *
1382    * This algorithm zigzags over the caps structures as demonstrated in
1383    * the following matrix:
1384    *
1385    *          caps1                              0  1  2  3
1386    *       +-------------     total distance:  +-------------
1387    *       | 1  2  4  7                      0 | 0  1  2  3
1388    * caps2 | 3  5  8 10                      1 | 1  2  3  4
1389    *       | 6  9 11 12                      2 | 2  3  4  5
1390    *
1391    * First we iterate over the caps1 structures (top line) intersecting
1392    * the structures diagonally down, then we iterate over the caps2
1393    * structures. The result is that the intersections are ordered based on the
1394    * sum of the indexes in the list.
1395    */
1396   len1 = GST_CAPS_LEN (caps1);
1397   len2 = GST_CAPS_LEN (caps2);
1398   for (i = 0; i < len1 + len2 - 1; i++) {
1399     /* superset index goes from 0 to sgst_caps_structure_intersectuperset->structs->len-1 */
1400     j = MIN (i, len1 - 1);
1401     /* subset index stays 0 until i reaches superset->structs->len, then it
1402      * counts up from 1 to subset->structs->len - 1 */
1403     k = (i > j) ? (i - j) : 0;  /* MAX (0, i - j) */
1404     /* now run the diagonal line, end condition is the left or bottom
1405      * border */
1406     while (k < len2) {
1407       struct1 = gst_caps_get_structure_unchecked (caps1, j);
1408       features1 = gst_caps_get_features_unchecked (caps1, j);
1409       if (!features1)
1410         features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1411       struct2 = gst_caps_get_structure_unchecked (caps2, k);
1412       features2 = gst_caps_get_features_unchecked (caps2, k);
1413       if (!features2)
1414         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1415       if (gst_structure_can_intersect (struct1, struct2) &&
1416           gst_caps_features_is_equal (features1, features2)) {
1417         return TRUE;
1418       }
1419       /* move down left */
1420       k++;
1421       if (G_UNLIKELY (j == 0))
1422         break;                  /* so we don't roll back to G_MAXUINT */
1423       j--;
1424     }
1425   }
1426
1427   return FALSE;
1428 }
1429
1430 static GstCaps *
1431 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1432 {
1433   guint64 i;                    /* index can be up to 2 * G_MAX_UINT */
1434   guint j, k, len1, len2;
1435   GstStructure *struct1;
1436   GstStructure *struct2;
1437   GstCapsFeatures *features1;
1438   GstCapsFeatures *features2;
1439   GstCaps *dest;
1440   GstStructure *istruct;
1441
1442   /* caps are exactly the same pointers, just copy one caps */
1443   if (G_UNLIKELY (caps1 == caps2))
1444     return gst_caps_ref (caps1);
1445
1446   /* empty caps on either side, return empty */
1447   if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1448     return gst_caps_ref (GST_CAPS_NONE);
1449
1450   /* one of the caps is any, just copy the other caps */
1451   if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1452     return gst_caps_ref (caps2);
1453
1454   if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1455     return gst_caps_ref (caps1);
1456
1457   dest = gst_caps_new_empty ();
1458   /* run zigzag on top line then right line, this preserves the caps order
1459    * much better than a simple loop.
1460    *
1461    * This algorithm zigzags over the caps structures as demonstrated in
1462    * the following matrix:
1463    *
1464    *          caps1
1465    *       +-------------
1466    *       | 1  2  4  7
1467    * caps2 | 3  5  8 10
1468    *       | 6  9 11 12
1469    *
1470    * First we iterate over the caps1 structures (top line) intersecting
1471    * the structures diagonally down, then we iterate over the caps2
1472    * structures.
1473    */
1474   len1 = GST_CAPS_LEN (caps1);
1475   len2 = GST_CAPS_LEN (caps2);
1476   for (i = 0; i < len1 + len2 - 1; i++) {
1477     /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1478     j = MIN (i, len1 - 1);
1479     /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1480      * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1481     k = (i > j) ? (i - j) : 0;  /* MAX (0, i - j) */
1482     /* now run the diagonal line, end condition is the left or bottom
1483      * border */
1484     while (k < len2) {
1485       struct1 = gst_caps_get_structure_unchecked (caps1, j);
1486       features1 = gst_caps_get_features_unchecked (caps1, j);
1487       if (!features1)
1488         features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1489       struct2 = gst_caps_get_structure_unchecked (caps2, k);
1490       features2 = gst_caps_get_features_unchecked (caps2, k);
1491       if (!features2)
1492         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1493       istruct = gst_structure_intersect (struct1, struct2);
1494       if (istruct && gst_caps_features_is_equal (features1, features2))
1495         dest =
1496             gst_caps_merge_structure_full (dest, istruct,
1497             gst_caps_features_copy_conditional (features1));
1498       /* move down left */
1499       k++;
1500       if (G_UNLIKELY (j == 0))
1501         break;                  /* so we don't roll back to G_MAXUINT */
1502       j--;
1503     }
1504   }
1505   return dest;
1506 }
1507
1508 /**
1509  * gst_caps_intersect_first:
1510  * @caps1: a #GstCaps to intersect
1511  * @caps2: a #GstCaps to intersect
1512  *
1513  * Creates a new #GstCaps that contains all the formats that are common
1514  * to both @caps1 and @caps2.
1515  *
1516  * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1517  * fashion as @caps1.
1518  *
1519  * Returns: the new #GstCaps
1520  */
1521 static GstCaps *
1522 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1523 {
1524   guint i;
1525   guint j, len1, len2;
1526   GstStructure *struct1;
1527   GstStructure *struct2;
1528   GstCapsFeatures *features1;
1529   GstCapsFeatures *features2;
1530   GstCaps *dest;
1531   GstStructure *istruct;
1532
1533   /* caps are exactly the same pointers, just copy one caps */
1534   if (G_UNLIKELY (caps1 == caps2))
1535     return gst_caps_ref (caps1);
1536
1537   /* empty caps on either side, return empty */
1538   if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1539     return gst_caps_ref (GST_CAPS_NONE);
1540
1541   /* one of the caps is any, just copy the other caps */
1542   if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1543     return gst_caps_ref (caps2);
1544
1545   if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1546     return gst_caps_ref (caps1);
1547
1548   dest = gst_caps_new_empty ();
1549   len1 = GST_CAPS_LEN (caps1);
1550   len2 = GST_CAPS_LEN (caps2);
1551   for (i = 0; i < len1; i++) {
1552     struct1 = gst_caps_get_structure_unchecked (caps1, i);
1553     features1 = gst_caps_get_features_unchecked (caps1, i);
1554     if (!features1)
1555       features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1556     for (j = 0; j < len2; j++) {
1557       struct2 = gst_caps_get_structure_unchecked (caps2, j);
1558       features2 = gst_caps_get_features_unchecked (caps2, j);
1559       if (!features2)
1560         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1561       istruct = gst_structure_intersect (struct1, struct2);
1562       if (istruct && gst_caps_features_is_equal (features1, features2))
1563         dest = gst_caps_merge_structure (dest, istruct);
1564     }
1565   }
1566
1567   return dest;
1568 }
1569
1570 /**
1571  * gst_caps_intersect_full:
1572  * @caps1: a #GstCaps to intersect
1573  * @caps2: a #GstCaps to intersect
1574  * @mode: The intersection algorithm/mode to use
1575  *
1576  * Creates a new #GstCaps that contains all the formats that are common
1577  * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1578  * used.
1579  *
1580  * Returns: the new #GstCaps
1581  */
1582 GstCaps *
1583 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1584     GstCapsIntersectMode mode)
1585 {
1586   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1587   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1588
1589   switch (mode) {
1590     case GST_CAPS_INTERSECT_FIRST:
1591       return gst_caps_intersect_first (caps1, caps2);
1592     default:
1593       g_warning ("Unknown caps intersect mode: %d", mode);
1594       /* fallthrough */
1595     case GST_CAPS_INTERSECT_ZIG_ZAG:
1596       return gst_caps_intersect_zig_zag (caps1, caps2);
1597   }
1598 }
1599
1600 /**
1601  * gst_caps_intersect:
1602  * @caps1: a #GstCaps to intersect
1603  * @caps2: a #GstCaps to intersect
1604  *
1605  * Creates a new #GstCaps that contains all the formats that are common
1606  * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1607  *
1608  * Returns: the new #GstCaps
1609  */
1610 GstCaps *
1611 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1612 {
1613   return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1614 }
1615
1616 /* subtract operation */
1617
1618 typedef struct
1619 {
1620   const GstStructure *subtract_from;
1621   GSList *put_into;
1622 } SubtractionEntry;
1623
1624 static gboolean
1625 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1626     gpointer user_data)
1627 {
1628   SubtractionEntry *e = user_data;
1629   GValue subtraction = { 0, };
1630   const GValue *other;
1631   GstStructure *structure;
1632
1633   other = gst_structure_id_get_value (e->subtract_from, field_id);
1634
1635   if (!other) {
1636     return FALSE;
1637   }
1638
1639   if (!gst_value_subtract (&subtraction, other, value))
1640     return TRUE;
1641
1642   if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1643     g_value_unset (&subtraction);
1644     return FALSE;
1645   } else {
1646     structure = gst_structure_copy (e->subtract_from);
1647     gst_structure_id_take_value (structure, field_id, &subtraction);
1648     e->put_into = g_slist_prepend (e->put_into, structure);
1649     return TRUE;
1650   }
1651 }
1652
1653 static gboolean
1654 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1655     const GstStructure * subtrahend)
1656 {
1657   SubtractionEntry e;
1658   gboolean ret;
1659
1660   e.subtract_from = minuend;
1661   e.put_into = NULL;
1662   ret = gst_structure_foreach ((GstStructure *) subtrahend,
1663       gst_caps_structure_subtract_field, &e);
1664
1665   if (ret) {
1666     *into = e.put_into;
1667   } else {
1668     GSList *walk;
1669
1670     for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1671       gst_structure_free (walk->data);
1672     }
1673     g_slist_free (e.put_into);
1674   }
1675
1676   return ret;
1677 }
1678
1679 /**
1680  * gst_caps_subtract:
1681  * @minuend: #GstCaps to subtract from
1682  * @subtrahend: #GstCaps to subtract
1683  *
1684  * Subtracts the @subtrahend from the @minuend.
1685  * <note>This function does not work reliably if optional properties for caps
1686  * are included on one caps and omitted on the other.</note>
1687  *
1688  * Returns: the resulting caps
1689  */
1690 GstCaps *
1691 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1692 {
1693   guint i, j, sublen;
1694   GstStructure *min;
1695   GstStructure *sub;
1696   GstCapsFeatures *min_f, *sub_f;
1697   GstCaps *dest = NULL, *src;
1698
1699   g_return_val_if_fail (minuend != NULL, NULL);
1700   g_return_val_if_fail (subtrahend != NULL, NULL);
1701
1702   if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1703     return gst_caps_new_empty ();
1704   }
1705
1706   if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1707     return gst_caps_ref (minuend);
1708
1709   /* FIXME: Do we want this here or above?
1710      The reason we need this is that there is no definition about what
1711      ANY means for specific types, so it's not possible to reduce ANY partially
1712      You can only remove everything or nothing and that is done above.
1713      Note: there's a test that checks this behaviour. */
1714
1715   g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1716   sublen = GST_CAPS_LEN (subtrahend);
1717   g_assert (sublen > 0);
1718
1719   src = _gst_caps_copy (minuend);
1720   for (i = 0; i < sublen; i++) {
1721     guint srclen;
1722
1723     sub = gst_caps_get_structure_unchecked (subtrahend, i);
1724     sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1725     if (!sub_f)
1726       sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1727     if (dest) {
1728       gst_caps_unref (src);
1729       src = dest;
1730     }
1731     dest = gst_caps_new_empty ();
1732     srclen = GST_CAPS_LEN (src);
1733     for (j = 0; j < srclen; j++) {
1734       min = gst_caps_get_structure_unchecked (src, j);
1735       min_f = gst_caps_get_features_unchecked (src, j);
1736       if (!min_f)
1737         min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1738       if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1739           gst_caps_features_is_equal (min_f, sub_f)) {
1740         GSList *list;
1741
1742         if (gst_caps_structure_subtract (&list, min, sub)) {
1743           GSList *walk;
1744
1745           for (walk = list; walk; walk = g_slist_next (walk)) {
1746             gst_caps_append_structure_unchecked (dest,
1747                 (GstStructure *) walk->data,
1748                 gst_caps_features_copy_conditional (min_f));
1749           }
1750           g_slist_free (list);
1751         } else {
1752           gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1753               gst_caps_features_copy_conditional (min_f));
1754         }
1755       } else {
1756         gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1757             gst_caps_features_copy_conditional (min_f));
1758       }
1759     }
1760
1761     if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1762       gst_caps_unref (src);
1763       return dest;
1764     }
1765   }
1766
1767   gst_caps_unref (src);
1768   dest = gst_caps_simplify (dest);
1769
1770   return dest;
1771 }
1772
1773 /* normalize/simplify operations */
1774
1775 typedef struct _NormalizeForeach
1776 {
1777   GstCaps *caps;
1778   GstStructure *structure;
1779   GstCapsFeatures *features;
1780 } NormalizeForeach;
1781
1782 static gboolean
1783 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1784 {
1785   NormalizeForeach *nf = (NormalizeForeach *) ptr;
1786   GValue val = { 0 };
1787   guint i;
1788
1789   if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1790     guint len = gst_value_list_get_size (value);
1791
1792     for (i = 1; i < len; i++) {
1793       const GValue *v = gst_value_list_get_value (value, i);
1794       GstStructure *structure = gst_structure_copy (nf->structure);
1795
1796       gst_structure_id_set_value (structure, field_id, v);
1797       gst_caps_append_structure_unchecked (nf->caps, structure,
1798           gst_caps_features_copy_conditional (nf->features));
1799     }
1800
1801     gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1802     gst_structure_id_take_value (nf->structure, field_id, &val);
1803     return FALSE;
1804   }
1805
1806   return TRUE;
1807 }
1808
1809 /**
1810  * gst_caps_normalize:
1811  * @caps: (transfer full): a #GstCaps to normalize
1812  *
1813  * Returns a #GstCaps that represents the same set of formats as
1814  * @caps, but contains no lists.  Each list is expanded into separate
1815  * @GstStructures.
1816  *
1817  * This function takes ownership of @caps.
1818  *
1819  * Returns: (transfer full): the normalized #GstCaps
1820  */
1821 GstCaps *
1822 gst_caps_normalize (GstCaps * caps)
1823 {
1824   NormalizeForeach nf;
1825   guint i;
1826
1827   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1828
1829   caps = gst_caps_make_writable (caps);
1830   nf.caps = caps;
1831
1832   for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1833     nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1834     nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1835     while (!gst_structure_foreach (nf.structure,
1836             gst_caps_normalize_foreach, &nf));
1837   }
1838
1839   return nf.caps;
1840 }
1841
1842 static gint
1843 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1844 {
1845   gint ret;
1846   const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1847   const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1848
1849   /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1850      So what's the best way? */
1851   ret = strcmp (gst_structure_get_name (struct1),
1852       gst_structure_get_name (struct2));
1853
1854   if (ret)
1855     return ret;
1856
1857   return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1858 }
1859
1860 typedef struct
1861 {
1862   GQuark name;
1863   GValue value;
1864   GstStructure *compare;
1865 } UnionField;
1866
1867 static gboolean
1868 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1869     gpointer user_data)
1870 {
1871   UnionField *u = user_data;
1872   const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1873
1874   if (!val) {
1875     if (u->name)
1876       g_value_unset (&u->value);
1877     return FALSE;
1878   }
1879
1880   if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1881     return TRUE;
1882
1883   if (u->name) {
1884     g_value_unset (&u->value);
1885     return FALSE;
1886   }
1887
1888   u->name = field_id;
1889   gst_value_union (&u->value, val, value);
1890
1891   return TRUE;
1892 }
1893
1894 static gboolean
1895 gst_caps_structure_simplify (GstStructure ** result,
1896     GstStructure * simplify, GstStructure * compare)
1897 {
1898   GSList *list;
1899   UnionField field = { 0, {0,}, NULL };
1900
1901   /* try to subtract to get a real subset */
1902   if (gst_caps_structure_subtract (&list, simplify, compare)) {
1903     if (list == NULL) {         /* no result */
1904       *result = NULL;
1905       return TRUE;
1906     } else if (list->next == NULL) {    /* one result */
1907       *result = list->data;
1908       g_slist_free (list);
1909       return TRUE;
1910     } else {                    /* multiple results */
1911       g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
1912       g_slist_free (list);
1913       list = NULL;
1914     }
1915   }
1916
1917   /* try to union both structs */
1918   field.compare = compare;
1919   if (gst_structure_foreach (simplify,
1920           gst_caps_structure_figure_out_union, &field)) {
1921     gboolean ret = FALSE;
1922
1923     /* now we know all of simplify's fields are the same in compare
1924      * but at most one field: field.name */
1925     if (G_IS_VALUE (&field.value)) {
1926       if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
1927         gst_structure_id_take_value (compare, field.name, &field.value);
1928         *result = NULL;
1929         ret = TRUE;
1930       } else {
1931         g_value_unset (&field.value);
1932       }
1933     } else
1934         if (gst_structure_n_fields (simplify) <=
1935         gst_structure_n_fields (compare)) {
1936       /* compare is just more specific, will be optimized away later */
1937       /* FIXME: do this here? */
1938       GST_LOG ("found a case that will be optimized later.");
1939     } else {
1940       gchar *one = gst_structure_to_string (simplify);
1941       gchar *two = gst_structure_to_string (compare);
1942
1943       GST_ERROR
1944           ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
1945           one, two);
1946       g_free (one);
1947       g_free (two);
1948     }
1949     return ret;
1950   }
1951
1952   return FALSE;
1953 }
1954
1955 static void
1956 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
1957     GstStructure * new, gint i)
1958 {
1959   gst_structure_set_parent_refcount (old, NULL);
1960   gst_structure_free (old);
1961   gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
1962   g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
1963 }
1964
1965 /**
1966  * gst_caps_simplify:
1967  * @caps: (transfer full): a #GstCaps to simplify
1968  *
1969  * Converts the given @caps into a representation that represents the
1970  * same set of formats, but in a simpler form.  Component structures that are
1971  * identical are merged.  Component structures that have values that can be
1972  * merged are also merged.
1973  *
1974  * This method does not preserve the original order of @caps.
1975  *
1976  * Returns: The simplified caps.
1977  */
1978 GstCaps *
1979 gst_caps_simplify (GstCaps * caps)
1980 {
1981   GstStructure *simplify, *compare, *result = NULL;
1982   GstCapsFeatures *simplify_f, *compare_f;
1983   gint i, j, start;
1984
1985   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1986
1987   start = GST_CAPS_LEN (caps) - 1;
1988   /* one caps, already as simple as can be */
1989   if (start == 0)
1990     return caps;
1991
1992   caps = gst_caps_make_writable (caps);
1993
1994   g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
1995
1996   for (i = start; i >= 0; i--) {
1997     simplify = gst_caps_get_structure_unchecked (caps, i);
1998     simplify_f = gst_caps_get_features_unchecked (caps, i);
1999     if (!simplify_f)
2000       simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2001     compare = gst_caps_get_structure_unchecked (caps, start);
2002     compare_f = gst_caps_get_features_unchecked (caps, start);
2003     if (!compare_f)
2004       compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2005     if (gst_structure_get_name_id (simplify) !=
2006         gst_structure_get_name_id (compare) ||
2007         !gst_caps_features_is_equal (simplify_f, compare_f))
2008       start = i;
2009     for (j = start; j >= 0; j--) {
2010       if (j == i)
2011         continue;
2012       compare = gst_caps_get_structure_unchecked (caps, j);
2013       compare_f = gst_caps_get_features_unchecked (caps, j);
2014       if (!compare_f)
2015         compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2016       if (gst_structure_get_name_id (simplify) !=
2017           gst_structure_get_name_id (compare) ||
2018           !gst_caps_features_is_equal (simplify_f, compare_f)) {
2019         break;
2020       }
2021       if (gst_caps_structure_simplify (&result, simplify, compare)) {
2022         if (result) {
2023           gst_caps_switch_structures (caps, simplify, result, i);
2024           simplify = result;
2025         } else {
2026           gst_caps_remove_structure (caps, i);
2027           start--;
2028           break;
2029         }
2030       }
2031     }
2032   }
2033   return caps;
2034 }
2035
2036 /**
2037  * gst_caps_fixate:
2038  * @caps: (transfer full): a #GstCaps to fixate
2039  *
2040  * Modifies the given @caps into a representation with only fixed
2041  * values. First the caps will be truncated and then the first structure will be
2042  * fixated with gst_structure_fixate().
2043  *
2044  * Returns: (transfer full): the fixated caps
2045  */
2046 GstCaps *
2047 gst_caps_fixate (GstCaps * caps)
2048 {
2049   GstStructure *s;
2050
2051   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2052
2053   /* default fixation */
2054   caps = gst_caps_truncate (caps);
2055   caps = gst_caps_make_writable (caps);
2056   s = gst_caps_get_structure (caps, 0);
2057   gst_structure_fixate (s);
2058
2059   return caps;
2060 }
2061
2062 /* utility */
2063
2064 /**
2065  * gst_caps_to_string:
2066  * @caps: a #GstCaps
2067  *
2068  * Converts @caps to a string representation.  This string representation
2069  * can be converted back to a #GstCaps by gst_caps_from_string().
2070  *
2071  * For debugging purposes its easier to do something like this:
2072  * |[
2073  * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2074  * ]|
2075  * This prints the caps in human readable form.
2076  *
2077  * Returns: (transfer full): a newly allocated string representing @caps.
2078  */
2079 gchar *
2080 gst_caps_to_string (const GstCaps * caps)
2081 {
2082   guint i, slen, clen;
2083   GString *s;
2084
2085   /* NOTE:  This function is potentially called by the debug system,
2086    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2087    * should be careful to avoid recursion.  This includes any functions
2088    * called by gst_caps_to_string.  In particular, calls should
2089    * not use the GST_PTR_FORMAT extension.  */
2090
2091   if (caps == NULL) {
2092     return g_strdup ("NULL");
2093   }
2094   if (CAPS_IS_ANY (caps)) {
2095     return g_strdup ("ANY");
2096   }
2097   if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2098     return g_strdup ("EMPTY");
2099   }
2100
2101   /* estimate a rough string length to avoid unnecessary reallocs in GString */
2102   slen = 0;
2103   clen = GST_CAPS_LEN (caps);
2104   for (i = 0; i < clen; i++) {
2105     GstCapsFeatures *f;
2106
2107     slen +=
2108         STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2109         (caps, i));
2110     f = gst_caps_get_features_unchecked (caps, i);
2111     if (f)
2112       slen += FEATURES_ESTIMATED_STRING_LEN (f);
2113   }
2114
2115   s = g_string_sized_new (slen);
2116   for (i = 0; i < clen; i++) {
2117     GstStructure *structure;
2118     GstCapsFeatures *features;
2119
2120     if (i > 0) {
2121       /* ';' is now added by gst_structure_to_string */
2122       g_string_append_c (s, ' ');
2123     }
2124
2125     structure = gst_caps_get_structure_unchecked (caps, i);
2126     features = gst_caps_get_features_unchecked (caps, i);
2127
2128     g_string_append (s, gst_structure_get_name (structure));
2129     if (features
2130         && !gst_caps_features_is_equal (features,
2131             GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) {
2132       g_string_append_c (s, '(');
2133       priv_gst_caps_features_append_to_gstring (features, s);
2134       g_string_append_c (s, ')');
2135     }
2136     priv_gst_structure_append_to_gstring (structure, s);
2137   }
2138   if (s->len && s->str[s->len - 1] == ';') {
2139     /* remove latest ';' */
2140     s->str[--s->len] = '\0';
2141   }
2142   return g_string_free (s, FALSE);
2143 }
2144
2145 static gboolean
2146 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2147 {
2148   GstStructure *structure;
2149   gchar *s, *copy, *end, *next, save;
2150
2151   if (strcmp ("ANY", string) == 0) {
2152     GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2153     return TRUE;
2154   }
2155
2156   if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2157     return TRUE;
2158   }
2159
2160   copy = s = g_strdup (string);
2161   do {
2162     GstCapsFeatures *features = NULL;
2163
2164     while (g_ascii_isspace (*s))
2165       s++;
2166     if (*s == '\0') {
2167       break;
2168     }
2169
2170     if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2171       g_free (copy);
2172       return FALSE;
2173     }
2174
2175     save = *end;
2176     *end = '\0';
2177     structure = gst_structure_new_empty (s);
2178     *end = save;
2179
2180     if (structure == NULL) {
2181       g_free (copy);
2182       return FALSE;
2183     }
2184
2185     s = next;
2186
2187     if (*s == '\0') {
2188       goto append;
2189     }
2190
2191     if (*s == '(') {
2192       s++;
2193       end = s;
2194
2195       while (TRUE) {
2196         if (*end == '\0') {
2197           break;
2198         } else if (*end == ')') {
2199           break;
2200         } else {
2201           end++;
2202         }
2203       }
2204
2205       save = *end;
2206       *end = '\0';
2207       features = gst_caps_features_from_string (s);
2208       if (!features) {
2209         gst_structure_free (structure);
2210         g_free (copy);
2211         return FALSE;
2212       }
2213       *end = save;
2214       s = end;
2215       if (save == ')')
2216         s++;
2217     }
2218
2219     if (*s == '\0') {
2220       goto append;
2221     }
2222
2223     if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2224       gst_structure_free (structure);
2225       g_free (copy);
2226       return FALSE;
2227     }
2228
2229   append:
2230     gst_caps_append_structure_unchecked (caps, structure, features);
2231     if (*s == '\0')
2232       break;
2233   } while (TRUE);
2234
2235   g_free (copy);
2236
2237   return TRUE;
2238 }
2239
2240 /**
2241  * gst_caps_from_string:
2242  * @string: a string to convert to #GstCaps
2243  *
2244  * Converts @caps from a string representation.
2245  *
2246  * Returns: (transfer full): a newly allocated #GstCaps
2247  */
2248 GstCaps *
2249 gst_caps_from_string (const gchar * string)
2250 {
2251   GstCaps *caps;
2252
2253   g_return_val_if_fail (string, FALSE);
2254
2255   caps = gst_caps_new_empty ();
2256   if (gst_caps_from_string_inplace (caps, string)) {
2257     return caps;
2258   } else {
2259     gst_caps_unref (caps);
2260     return NULL;
2261   }
2262 }
2263
2264 static void
2265 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2266 {
2267   g_return_if_fail (G_IS_VALUE (src_value));
2268   g_return_if_fail (G_IS_VALUE (dest_value));
2269   g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2270   g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2271       || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2272
2273   g_value_take_string (dest_value,
2274       gst_caps_to_string (gst_value_get_caps (src_value)));
2275 }