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