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