2 * Copyright (C) <2003> David A. Schleef <ds@schleef.org>
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.
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.
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.
23 * @short_description: Structure describing sets of media formats
24 * @see_also: #GstStructure, #GstMiniObject
26 * Caps (capabilities) are lightweight refcounted objects describing media types.
27 * They are composed of an array of #GstStructure.
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.
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.
37 * A #GstCaps can be constructed with the following code fragment:
38 * |[<!-- language="C" -->
39 * GstCaps *caps = gst_caps_new_simple ("video/x-raw",
40 * "format", G_TYPE_STRING, "I420",
41 * "framerate", GST_TYPE_FRACTION, 25, 1,
42 * "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
43 * "width", G_TYPE_INT, 320,
44 * "height", G_TYPE_INT, 240,
48 * A #GstCaps is fixed when it has no properties with ranges or lists. Use
49 * gst_caps_is_fixed() to test for fixed caps. Fixed caps can be used in a
50 * caps event to notify downstream elements of the current media type.
52 * Various methods exist to work with the media types such as subtracting
55 * Be aware that the current #GstCaps / #GstStructure serialization into string
56 * has limited support for nested #GstCaps / #GstStructure fields. It can only
57 * support one level of nesting. Using more levels will lead to unexpected
58 * behavior when using serialization features, such as gst_caps_to_string() or
59 * gst_value_serialize() and their counterparts.
68 #include "gst_private.h"
70 #include <gobject/gvaluecollector.h>
72 #define DEBUG_REFCOUNT
74 typedef struct _GstCapsArrayElement
76 GstStructure *structure;
77 GstCapsFeatures *features;
78 } GstCapsArrayElement;
80 typedef struct _GstCapsImpl
87 #define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
89 #define GST_CAPS_LEN(c) (GST_CAPS_ARRAY(c)->len)
91 #define IS_WRITABLE(caps) \
92 (GST_CAPS_REFCOUNT_VALUE (caps) == 1)
94 /* same as gst_caps_is_any () */
95 #define CAPS_IS_ANY(caps) \
96 (!!(GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY))
98 /* same as gst_caps_is_empty () */
99 #define CAPS_IS_EMPTY(caps) \
100 (!CAPS_IS_ANY(caps) && CAPS_IS_EMPTY_SIMPLE(caps))
102 #define CAPS_IS_EMPTY_SIMPLE(caps) \
103 ((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
105 #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)
107 /* quick way to get a caps structure at an index without doing a type or array
109 #define gst_caps_get_structure_unchecked(caps, index) \
110 (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).structure)
111 #define gst_caps_get_features_storage_unchecked(caps, index) \
112 (&g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
113 #define gst_caps_get_features_unchecked(caps, index) \
114 (g_atomic_pointer_get (gst_caps_get_features_storage_unchecked (caps, index)))
115 /* quick way to append a structure without checking the args */
116 #define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
117 GstCapsArrayElement __e={s, f}; \
118 if (gst_structure_set_parent_refcount (__e.structure, &GST_MINI_OBJECT_REFCOUNT(caps)) && \
119 (!__e.features || gst_caps_features_set_parent_refcount (__e.features, &GST_MINI_OBJECT_REFCOUNT(caps)))) \
120 g_array_append_val (GST_CAPS_ARRAY (caps), __e); \
123 /* lock to protect multiple invocations of static caps to caps conversion */
124 G_LOCK_DEFINE_STATIC (static_caps_lock);
126 static void gst_caps_transform_to_string (const GValue * src_value,
127 GValue * dest_value);
128 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
129 const gchar * string);
131 GType _gst_caps_type = 0;
132 GstCaps *_gst_caps_any;
133 GstCaps *_gst_caps_none;
135 GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
138 _priv_gst_caps_initialize (void)
140 _gst_caps_type = gst_caps_get_type ();
142 _gst_caps_any = gst_caps_new_any ();
143 _gst_caps_none = gst_caps_new_empty ();
145 g_value_register_transform_func (_gst_caps_type,
146 G_TYPE_STRING, gst_caps_transform_to_string);
150 _priv_gst_caps_cleanup (void)
152 gst_caps_unref (_gst_caps_any);
153 _gst_caps_any = NULL;
154 gst_caps_unref (_gst_caps_none);
155 _gst_caps_none = NULL;
159 __gst_caps_get_features_unchecked (const GstCaps * caps, guint idx)
161 return gst_caps_get_features_unchecked (caps, idx);
165 _gst_caps_copy (const GstCaps * caps)
168 GstStructure *structure;
169 GstCapsFeatures *features;
172 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
174 newcaps = gst_caps_new_empty ();
175 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
176 n = GST_CAPS_LEN (caps);
178 GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, caps, "doing copy %p -> %p",
181 for (i = 0; i < n; i++) {
182 structure = gst_caps_get_structure_unchecked (caps, i);
183 features = gst_caps_get_features_unchecked (caps, i);
184 gst_caps_append_structure_full (newcaps, gst_structure_copy (structure),
185 gst_caps_features_copy_conditional (features));
191 /* creation/deletion */
193 _gst_caps_free (GstCaps * caps)
195 GstStructure *structure;
196 GstCapsFeatures *features;
199 /* The refcount must be 0, but since we're only called by gst_caps_unref,
200 * don't bother testing. */
201 len = GST_CAPS_LEN (caps);
202 /* This can be used to get statistics about caps sizes */
203 /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
204 for (i = 0; i < len; i++) {
205 structure = gst_caps_get_structure_unchecked (caps, i);
206 gst_structure_set_parent_refcount (structure, NULL);
207 gst_structure_free (structure);
208 features = gst_caps_get_features_unchecked (caps, i);
210 gst_caps_features_set_parent_refcount (features, NULL);
211 gst_caps_features_free (features);
214 g_array_free (GST_CAPS_ARRAY (caps), TRUE);
216 #ifdef DEBUG_REFCOUNT
217 GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
221 memset (caps, 0xff, sizeof (GstCapsImpl));
224 g_slice_free1 (sizeof (GstCapsImpl), caps);
228 gst_caps_init (GstCaps * caps)
230 gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
231 (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
232 (GstMiniObjectFreeFunction) _gst_caps_free);
234 /* the 32 has been determined by logging caps sizes in _gst_caps_free
235 * but g_ptr_array uses 16 anyway if it expands once, so this does not help
237 * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
239 GST_CAPS_ARRAY (caps) =
240 g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
244 * gst_caps_new_empty:
246 * Creates a new #GstCaps that is empty. That is, the returned
247 * #GstCaps contains no media formats.
248 * The #GstCaps is guaranteed to be writable.
249 * Caller is responsible for unreffing the returned caps.
251 * Returns: (transfer full): the new #GstCaps
254 gst_caps_new_empty (void)
258 caps = (GstCaps *) g_slice_new (GstCapsImpl);
260 gst_caps_init (caps);
262 #ifdef DEBUG_REFCOUNT
263 GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
272 * Creates a new #GstCaps that indicates that it is compatible with
275 * Returns: (transfer full): the new #GstCaps
278 gst_caps_new_any (void)
280 GstCaps *caps = gst_caps_new_empty ();
282 GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_ANY);
288 * gst_caps_new_empty_simple:
289 * @media_type: the media type of the structure
291 * Creates a new #GstCaps that contains one #GstStructure with name
293 * Caller is responsible for unreffing the returned caps.
295 * Returns: (transfer full): the new #GstCaps
298 gst_caps_new_empty_simple (const char *media_type)
301 GstStructure *structure;
303 caps = gst_caps_new_empty ();
304 structure = gst_structure_new_empty (media_type);
306 gst_caps_append_structure_unchecked (caps, structure, NULL);
312 * gst_caps_new_simple:
313 * @media_type: the media type of the structure
314 * @fieldname: first field to set
315 * @...: additional arguments
317 * Creates a new #GstCaps that contains one #GstStructure. The
318 * structure is defined by the arguments, which have the same format
319 * as gst_structure_new().
320 * Caller is responsible for unreffing the returned caps.
322 * Returns: (transfer full): the new #GstCaps
325 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
328 GstStructure *structure;
331 caps = gst_caps_new_empty ();
333 va_start (var_args, fieldname);
334 structure = gst_structure_new_valist (media_type, fieldname, var_args);
338 gst_caps_append_structure_unchecked (caps, structure, NULL);
340 gst_caps_replace (&caps, NULL);
347 * @struct1: the first structure to add
348 * @...: additional structures to add
350 * Creates a new #GstCaps and adds all the structures listed as
351 * arguments. The list must be %NULL-terminated. The structures
352 * are not copied; the returned #GstCaps owns the structures.
354 * Returns: (transfer full): the new #GstCaps
357 gst_caps_new_full (GstStructure * struct1, ...)
362 va_start (var_args, struct1);
363 caps = gst_caps_new_full_valist (struct1, var_args);
370 * gst_caps_new_full_valist:
371 * @structure: the first structure to add
372 * @var_args: additional structures to add
374 * Creates a new #GstCaps and adds all the structures listed as
375 * arguments. The list must be %NULL-terminated. The structures
376 * are not copied; the returned #GstCaps owns the structures.
378 * Returns: (transfer full): the new #GstCaps
381 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
385 caps = gst_caps_new_empty ();
388 gst_caps_append_structure_unchecked (caps, structure, NULL);
389 structure = va_arg (var_args, GstStructure *);
395 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
398 * gst_static_caps_get:
399 * @static_caps: the #GstStaticCaps to convert
401 * Converts a #GstStaticCaps to a #GstCaps.
403 * Returns: (transfer full) (nullable): a pointer to the #GstCaps. Unref
404 * after usage. Since the core holds an additional ref to the
405 * returned caps, use gst_caps_make_writable() on the returned caps
409 gst_static_caps_get (GstStaticCaps * static_caps)
413 g_return_val_if_fail (static_caps != NULL, NULL);
415 caps = &static_caps->caps;
417 /* refcount is 0 when we need to convert */
418 if (G_UNLIKELY (*caps == NULL)) {
421 G_LOCK (static_caps_lock);
422 /* check if other thread already updated */
423 if (G_UNLIKELY (*caps != NULL))
426 string = static_caps->string;
428 if (G_UNLIKELY (string == NULL))
431 *caps = gst_caps_from_string (string);
433 /* convert to string */
434 if (G_UNLIKELY (*caps == NULL)) {
435 g_critical ("Could not convert static caps \"%s\"", string);
439 /* Caps generated from static caps are usually leaked */
440 GST_MINI_OBJECT_FLAG_SET (*caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
442 GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
445 G_UNLOCK (static_caps_lock);
447 /* ref the caps, makes it not writable */
448 if (G_LIKELY (*caps != NULL))
449 gst_caps_ref (*caps);
456 G_UNLOCK (static_caps_lock);
457 g_warning ("static caps %p string is NULL", static_caps);
463 * gst_static_caps_cleanup:
464 * @static_caps: the #GstStaticCaps to clean
466 * Clean up the cached caps contained in @static_caps.
469 gst_static_caps_cleanup (GstStaticCaps * static_caps)
471 G_LOCK (static_caps_lock);
472 gst_caps_replace (&static_caps->caps, NULL);
473 G_UNLOCK (static_caps_lock);
479 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
480 GstStructure ** s, GstCapsFeatures ** f)
485 s_ = gst_caps_get_structure_unchecked (caps, idx);
486 f_ = gst_caps_get_features_unchecked (caps, idx);
488 /* don't use index_fast, gst_caps_simplify relies on the order */
489 g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
491 gst_structure_set_parent_refcount (s_, NULL);
493 gst_caps_features_set_parent_refcount (f_, NULL);
500 static GstStructure *
501 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
506 gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
509 gst_caps_features_free (f);
515 * gst_caps_steal_structure:
516 * @caps: the #GstCaps to retrieve from
517 * @index: Index of the structure to retrieve
519 * Retrieves the structure with the given index from the list of structures
520 * contained in @caps. The caller becomes the owner of the returned structure.
522 * Returns: (transfer full) (nullable): a pointer to the #GstStructure
523 * corresponding to @index.
526 gst_caps_steal_structure (GstCaps * caps, guint index)
528 g_return_val_if_fail (caps != NULL, NULL);
529 g_return_val_if_fail (IS_WRITABLE (caps), NULL);
531 if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
534 return gst_caps_remove_and_get_structure (caps, index);
539 * @caps1: the #GstCaps that will be appended to
540 * @caps2: (transfer full): the #GstCaps to append
542 * Appends the structures contained in @caps2 to @caps1. The structures in
543 * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
544 * freed. If either caps is ANY, the resulting caps will be ANY.
547 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
549 GstStructure *structure;
550 GstCapsFeatures *features;
553 g_return_if_fail (GST_IS_CAPS (caps1));
554 g_return_if_fail (GST_IS_CAPS (caps2));
555 g_return_if_fail (IS_WRITABLE (caps1));
557 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
558 GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
559 gst_caps_unref (caps2);
561 caps2 = gst_caps_make_writable (caps2);
563 for (i = GST_CAPS_LEN (caps2); i; i--) {
564 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
566 gst_caps_append_structure_unchecked (caps1, structure, features);
568 gst_caps_unref (caps2); /* guaranteed to free it */
574 * @caps1: (transfer full): the #GstCaps that will take the new entries
575 * @caps2: (transfer full): the #GstCaps to merge in
577 * Appends the structures contained in @caps2 to @caps1 if they are not yet
578 * expressed by @caps1. The structures in @caps2 are not copied -- they are
579 * transferred to a writable copy of @caps1, and then @caps2 is freed.
580 * If either caps is ANY, the resulting caps will be ANY.
582 * Returns: (transfer full): the merged caps.
585 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
587 GstStructure *structure;
588 GstCapsFeatures *features;
592 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
593 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
595 if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
596 gst_caps_unref (caps2);
598 } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
599 gst_caps_unref (caps1);
602 caps2 = gst_caps_make_writable (caps2);
604 for (i = GST_CAPS_LEN (caps2); i; i--) {
605 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
607 caps1 = gst_caps_merge_structure_full (caps1, structure, features);
609 gst_caps_unref (caps2);
613 GstCaps *com = gst_caps_intersect (caps1, caps2);
614 GstCaps *add = gst_caps_subtract (caps2, com);
616 GST_DEBUG ("common : %d", gst_caps_get_size (com));
617 GST_DEBUG ("adding : %d", gst_caps_get_size (add));
618 gst_caps_append (caps1, add);
619 gst_caps_unref (com);
627 * gst_caps_append_structure:
628 * @caps: the #GstCaps that will be appended to
629 * @structure: (transfer full): the #GstStructure to append
631 * Appends @structure to @caps. The structure is not copied; @caps
632 * becomes the owner of @structure.
635 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
637 g_return_if_fail (GST_IS_CAPS (caps));
638 g_return_if_fail (IS_WRITABLE (caps));
640 if (G_LIKELY (structure)) {
641 gst_caps_append_structure_unchecked (caps, structure, NULL);
646 * gst_caps_append_structure_full:
647 * @caps: the #GstCaps that will be appended to
648 * @structure: (transfer full): the #GstStructure to append
649 * @features: (transfer full) (allow-none): the #GstCapsFeatures to append
651 * Appends @structure with @features to @caps. The structure is not copied; @caps
652 * becomes the owner of @structure.
657 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
658 GstCapsFeatures * features)
660 g_return_if_fail (GST_IS_CAPS (caps));
661 g_return_if_fail (IS_WRITABLE (caps));
663 if (G_LIKELY (structure)) {
664 gst_caps_append_structure_unchecked (caps, structure, features);
669 * gst_caps_remove_structure:
670 * @caps: the #GstCaps to remove from
671 * @idx: Index of the structure to remove
673 * removes the structure with the given index from the list of structures
674 * contained in @caps.
677 gst_caps_remove_structure (GstCaps * caps, guint idx)
679 GstStructure *structure;
681 g_return_if_fail (caps != NULL);
682 g_return_if_fail (idx <= gst_caps_get_size (caps));
683 g_return_if_fail (IS_WRITABLE (caps));
685 structure = gst_caps_remove_and_get_structure (caps, idx);
686 gst_structure_free (structure);
690 * gst_caps_merge_structure:
691 * @caps: (transfer full): the #GstCaps to merge into
692 * @structure: (transfer full): the #GstStructure to merge
694 * Appends @structure to @caps if its not already expressed by @caps.
696 * Returns: (transfer full): the merged caps.
699 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
701 GstStructure *structure1;
702 GstCapsFeatures *features1;
704 gboolean unique = TRUE;
706 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
708 if (G_UNLIKELY (structure == NULL))
711 /* check each structure */
712 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
713 structure1 = gst_caps_get_structure_unchecked (caps, i);
714 features1 = gst_caps_get_features_unchecked (caps, i);
716 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
718 /* if structure is a subset of structure1 and the
719 * there are no existing features, then skip it */
720 if (gst_caps_features_is_equal (features1,
721 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
722 && gst_structure_is_subset (structure, structure1)) {
728 caps = gst_caps_make_writable (caps);
729 gst_caps_append_structure_unchecked (caps, structure, NULL);
731 gst_structure_free (structure);
737 * gst_caps_merge_structure_full:
738 * @caps: (transfer full): the #GstCaps to merge into
739 * @structure: (transfer full): the #GstStructure to merge
740 * @features: (transfer full) (allow-none): the #GstCapsFeatures to merge
742 * Appends @structure with @features to @caps if its not already expressed by @caps.
744 * Returns: (transfer full): the merged caps.
749 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
750 GstCapsFeatures * features)
752 GstStructure *structure1;
753 GstCapsFeatures *features1, *features_tmp;
755 gboolean unique = TRUE;
757 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
759 if (G_UNLIKELY (structure == NULL))
762 /* To make comparisons easier below */
763 features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
765 /* check each structure */
766 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
767 structure1 = gst_caps_get_structure_unchecked (caps, i);
768 features1 = gst_caps_get_features_unchecked (caps, i);
770 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
771 /* if structure is a subset of structure1 and the
772 * the features are a subset, then skip it */
773 /* FIXME: We only skip if none of the features are
774 * ANY and are still equal. That way all ANY structures
775 * show up in the caps and no non-ANY structures are
776 * swallowed by ANY structures
778 if (((!gst_caps_features_is_any (features_tmp)
779 || gst_caps_features_is_any (features1))
780 && gst_caps_features_is_equal (features_tmp, features1))
781 && gst_structure_is_subset (structure, structure1)) {
787 caps = gst_caps_make_writable (caps);
788 gst_caps_append_structure_unchecked (caps, structure, features);
790 gst_structure_free (structure);
792 gst_caps_features_free (features);
801 * Gets the number of structures contained in @caps.
803 * Returns: the number of structures that @caps contains
806 gst_caps_get_size (const GstCaps * caps)
808 g_return_val_if_fail (GST_IS_CAPS (caps), 0);
810 return GST_CAPS_LEN (caps);
814 * gst_caps_get_structure:
816 * @index: the index of the structure
818 * Finds the structure in @caps that has the index @index, and
821 * WARNING: This function takes a const GstCaps *, but returns a
822 * non-const GstStructure *. This is for programming convenience --
823 * the caller should be aware that structures inside a constant
824 * #GstCaps should not be modified. However, if you know the caps
825 * are writable, either because you have just copied them or made
826 * them writable with gst_caps_make_writable(), you may modify the
827 * structure returned in the usual way, e.g. with functions like
828 * gst_structure_set().
830 * You do not need to free or unref the structure returned, it
831 * belongs to the #GstCaps.
833 * Returns: (transfer none): a pointer to the #GstStructure corresponding
837 gst_caps_get_structure (const GstCaps * caps, guint index)
839 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
840 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
842 return gst_caps_get_structure_unchecked (caps, index);
846 * gst_caps_get_features:
848 * @index: the index of the structure
850 * Finds the features in @caps that has the index @index, and
853 * WARNING: This function takes a const GstCaps *, but returns a
854 * non-const GstCapsFeatures *. This is for programming convenience --
855 * the caller should be aware that structures inside a constant
856 * #GstCaps should not be modified. However, if you know the caps
857 * are writable, either because you have just copied them or made
858 * them writable with gst_caps_make_writable(), you may modify the
859 * features returned in the usual way, e.g. with functions like
860 * gst_caps_features_add().
862 * You do not need to free or unref the structure returned, it
863 * belongs to the #GstCaps.
865 * Returns: (transfer none) (nullable): a pointer to the #GstCapsFeatures
866 * corresponding to @index
871 gst_caps_get_features (const GstCaps * caps, guint index)
873 GstCapsFeatures *features;
875 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
876 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
878 features = gst_caps_get_features_unchecked (caps, index);
880 GstCapsFeatures **storage;
882 /* We have to do some atomic pointer magic here as the caps
883 * might not be writable and someone else calls this function
884 * at the very same time */
885 features = gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
886 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
888 storage = gst_caps_get_features_storage_unchecked (caps, index);
889 if (!g_atomic_pointer_compare_and_exchange (storage, NULL, features)) {
890 /* Someone did the same we just tried in the meantime */
891 gst_caps_features_set_parent_refcount (features, NULL);
892 gst_caps_features_free (features);
894 features = gst_caps_get_features_unchecked (caps, index);
895 g_assert (features != NULL);
903 * gst_caps_set_features:
905 * @index: the index of the structure
906 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
908 * Sets the #GstCapsFeatures @features for the structure at @index.
913 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
915 GstCapsFeatures **storage, *old;
917 g_return_if_fail (caps != NULL);
918 g_return_if_fail (index <= gst_caps_get_size (caps));
919 g_return_if_fail (IS_WRITABLE (caps));
921 storage = gst_caps_get_features_storage_unchecked (caps, index);
922 /* Not much problem here as caps are writable */
923 old = g_atomic_pointer_get (storage);
924 g_atomic_pointer_set (storage, features);
927 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
930 gst_caps_features_set_parent_refcount (old, NULL);
931 gst_caps_features_free (old);
936 * gst_caps_set_features_simple:
938 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
940 * Sets the #GstCapsFeatures @features for all the structures of @caps.
945 gst_caps_set_features_simple (GstCaps * caps, GstCapsFeatures * features)
950 g_return_if_fail (caps != NULL);
951 g_return_if_fail (IS_WRITABLE (caps));
953 n = gst_caps_get_size (caps);
955 for (i = 0; i < n; i++) {
958 /* Transfer ownership of @features to the last structure */
959 if (features && i < n - 1)
960 f = gst_caps_features_copy (features);
964 gst_caps_set_features (caps, i, f);
970 * @caps: the #GstCaps to copy
971 * @nth: the nth structure to copy
973 * Creates a new #GstCaps and appends a copy of the nth structure
974 * contained in @caps.
976 * Returns: (transfer full): the new #GstCaps
979 gst_caps_copy_nth (const GstCaps * caps, guint nth)
982 GstStructure *structure;
983 GstCapsFeatures *features;
985 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
987 newcaps = gst_caps_new_empty ();
988 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
990 if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
991 structure = gst_caps_get_structure_unchecked (caps, nth);
992 features = gst_caps_get_features_unchecked (caps, nth);
993 gst_caps_append_structure_unchecked (newcaps,
994 gst_structure_copy (structure),
995 gst_caps_features_copy_conditional (features));
1002 * gst_caps_truncate:
1003 * @caps: (transfer full): the #GstCaps to truncate
1005 * Discard all but the first structure from @caps. Useful when
1008 * This function takes ownership of @caps and will call gst_caps_make_writable()
1009 * on it if necessary, so you must not use @caps afterwards unless you keep an
1010 * additional reference to it with gst_caps_ref().
1012 * Returns: (transfer full): truncated caps
1015 gst_caps_truncate (GstCaps * caps)
1019 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1021 i = GST_CAPS_LEN (caps) - 1;
1025 caps = gst_caps_make_writable (caps);
1027 gst_caps_remove_structure (caps, i--);
1033 * gst_caps_set_value:
1034 * @caps: a writable caps
1035 * @field: name of the field to set
1036 * @value: value to set the field to
1038 * Sets the given @field on all structures of @caps to the given @value.
1039 * This is a convenience function for calling gst_structure_set_value() on
1040 * all structures of @caps.
1043 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
1047 g_return_if_fail (GST_IS_CAPS (caps));
1048 g_return_if_fail (IS_WRITABLE (caps));
1049 g_return_if_fail (field != NULL);
1050 g_return_if_fail (G_IS_VALUE (value));
1052 len = GST_CAPS_LEN (caps);
1053 for (i = 0; i < len; i++) {
1054 GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
1055 gst_structure_set_value (structure, field, value);
1060 * gst_caps_set_simple_valist:
1061 * @caps: the #GstCaps to set
1062 * @field: first field to set
1063 * @varargs: additional parameters
1065 * Sets fields in a #GstCaps. The arguments must be passed in the same
1066 * manner as gst_structure_set(), and be %NULL-terminated.
1069 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
1071 GValue value = { 0, };
1073 g_return_if_fail (GST_IS_CAPS (caps));
1074 g_return_if_fail (IS_WRITABLE (caps));
1080 type = va_arg (varargs, GType);
1082 G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1083 if (G_UNLIKELY (err)) {
1084 g_critical ("%s", err);
1089 gst_caps_set_value (caps, field, &value);
1091 g_value_unset (&value);
1093 field = va_arg (varargs, const gchar *);
1098 * gst_caps_set_simple:
1099 * @caps: the #GstCaps to set
1100 * @field: first field to set
1101 * @...: additional parameters
1103 * Sets fields in a #GstCaps. The arguments must be passed in the same
1104 * manner as gst_structure_set(), and be %NULL-terminated.
1107 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1111 g_return_if_fail (GST_IS_CAPS (caps));
1112 g_return_if_fail (IS_WRITABLE (caps));
1114 va_start (var_args, field);
1115 gst_caps_set_simple_valist (caps, field, var_args);
1123 * @caps: the #GstCaps to test
1125 * Determines if @caps represents any media format.
1127 * Returns: %TRUE if @caps represents any format.
1130 gst_caps_is_any (const GstCaps * caps)
1132 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1134 return (CAPS_IS_ANY (caps));
1138 * gst_caps_is_empty:
1139 * @caps: the #GstCaps to test
1141 * Determines if @caps represents no media formats.
1143 * Returns: %TRUE if @caps represents no formats.
1146 gst_caps_is_empty (const GstCaps * caps)
1148 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1150 if (CAPS_IS_ANY (caps))
1153 return CAPS_IS_EMPTY_SIMPLE (caps);
1157 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1160 return gst_value_is_fixed (value);
1164 * gst_caps_is_fixed:
1165 * @caps: the #GstCaps to test
1167 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1168 * one structure, and each field in the structure describes a fixed type.
1169 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1171 * Returns: %TRUE if @caps is fixed
1174 gst_caps_is_fixed (const GstCaps * caps)
1176 GstStructure *structure;
1177 GstCapsFeatures *features;
1179 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1181 if (GST_CAPS_LEN (caps) != 1)
1184 features = gst_caps_get_features_unchecked (caps, 0);
1185 if (features && gst_caps_features_is_any (features))
1188 structure = gst_caps_get_structure_unchecked (caps, 0);
1190 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1194 * gst_caps_is_equal_fixed:
1195 * @caps1: the #GstCaps to test
1196 * @caps2: the #GstCaps to test
1198 * Tests if two #GstCaps are equal. This function only works on fixed
1201 * Returns: %TRUE if the arguments represent the same format
1204 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1206 GstStructure *struct1, *struct2;
1207 GstCapsFeatures *features1, *features2;
1209 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1210 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1212 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1213 features1 = gst_caps_get_features_unchecked (caps1, 0);
1215 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1216 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1217 features2 = gst_caps_get_features_unchecked (caps2, 0);
1219 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1221 return gst_structure_is_equal (struct1, struct2) &&
1222 gst_caps_features_is_equal (features1, features2);
1226 * gst_caps_is_always_compatible:
1227 * @caps1: the #GstCaps to test
1228 * @caps2: the #GstCaps to test
1230 * A given #GstCaps structure is always compatible with another if
1231 * every media format that is in the first is also contained in the
1232 * second. That is, @caps1 is a subset of @caps2.
1234 * Returns: %TRUE if @caps1 is a subset of @caps2.
1237 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1239 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1240 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1242 return gst_caps_is_subset (caps1, caps2);
1246 * gst_caps_is_subset:
1247 * @subset: a #GstCaps
1248 * @superset: a potentially greater #GstCaps
1250 * Checks if all caps represented by @subset are also represented by @superset.
1252 * Returns: %TRUE if @subset is a subset of @superset
1255 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1257 GstStructure *s1, *s2;
1258 GstCapsFeatures *f1, *f2;
1259 gboolean ret = TRUE;
1262 g_return_val_if_fail (subset != NULL, FALSE);
1263 g_return_val_if_fail (superset != NULL, FALSE);
1265 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1267 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1270 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1271 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1272 s1 = gst_caps_get_structure_unchecked (subset, i);
1273 f1 = gst_caps_get_features_unchecked (subset, i);
1275 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1276 s2 = gst_caps_get_structure_unchecked (superset, j);
1277 f2 = gst_caps_get_features_unchecked (superset, j);
1279 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1280 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1281 gst_caps_features_is_equal (f1, f2)
1282 && gst_structure_is_subset (s1, s2)) {
1283 /* If we found a superset, continue with the next
1284 * subset structure */
1288 /* If we found no superset for this subset structure
1289 * we return FALSE immediately */
1300 * gst_caps_is_subset_structure:
1302 * @structure: a potential #GstStructure subset of @caps
1304 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1305 * for more information.
1307 * Returns: %TRUE if @structure is a subset of @caps
1310 gst_caps_is_subset_structure (const GstCaps * caps,
1311 const GstStructure * structure)
1316 g_return_val_if_fail (caps != NULL, FALSE);
1317 g_return_val_if_fail (structure != NULL, FALSE);
1319 if (CAPS_IS_ANY (caps))
1321 if (CAPS_IS_EMPTY (caps))
1324 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1325 s = gst_caps_get_structure_unchecked (caps, i);
1326 if (gst_structure_is_subset (structure, s)) {
1327 /* If we found a superset return TRUE */
1336 * gst_caps_is_subset_structure_full:
1338 * @structure: a potential #GstStructure subset of @caps
1339 * @features: (allow-none): a #GstCapsFeatures for @structure
1341 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1342 * for more information.
1344 * Returns: %TRUE if @structure is a subset of @caps
1349 gst_caps_is_subset_structure_full (const GstCaps * caps,
1350 const GstStructure * structure, const GstCapsFeatures * features)
1356 g_return_val_if_fail (caps != NULL, FALSE);
1357 g_return_val_if_fail (structure != NULL, FALSE);
1359 if (CAPS_IS_ANY (caps))
1361 if (CAPS_IS_EMPTY (caps))
1365 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1367 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1368 s = gst_caps_get_structure_unchecked (caps, i);
1369 f = gst_caps_get_features_unchecked (caps, i);
1371 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1372 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1373 && gst_caps_features_is_equal (features, f)
1374 && gst_structure_is_subset (structure, s)) {
1375 /* If we found a superset return TRUE */
1384 * gst_caps_is_equal:
1385 * @caps1: a #GstCaps
1386 * @caps2: another #GstCaps
1388 * Checks if the given caps represent the same set of caps.
1390 * Returns: %TRUE if both caps are equal.
1393 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1395 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1396 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1398 if (G_UNLIKELY (caps1 == caps2))
1401 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1402 return gst_caps_is_equal_fixed (caps1, caps2);
1404 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1408 * gst_caps_is_strictly_equal:
1409 * @caps1: a #GstCaps
1410 * @caps2: another #GstCaps
1412 * Checks if the given caps are exactly the same set of caps.
1414 * Returns: %TRUE if both caps are strictly equal.
1417 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1420 GstStructure *s1, *s2;
1421 GstCapsFeatures *f1, *f2;
1423 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1424 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1426 if (G_UNLIKELY (caps1 == caps2))
1429 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1432 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1433 s1 = gst_caps_get_structure_unchecked (caps1, i);
1434 f1 = gst_caps_get_features_unchecked (caps1, i);
1436 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1437 s2 = gst_caps_get_structure_unchecked (caps2, i);
1438 f2 = gst_caps_get_features_unchecked (caps2, i);
1440 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1442 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1443 !gst_caps_features_is_equal (f1, f2) ||
1444 !gst_structure_is_equal (s1, s2))
1451 /* intersect operation */
1454 * gst_caps_can_intersect:
1455 * @caps1: a #GstCaps to intersect
1456 * @caps2: a #GstCaps to intersect
1458 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1461 * Returns: %TRUE if intersection would be not empty
1464 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1466 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1467 guint j, k, len1, len2;
1468 GstStructure *struct1;
1469 GstStructure *struct2;
1470 GstCapsFeatures *features1;
1471 GstCapsFeatures *features2;
1473 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1474 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1476 /* caps are exactly the same pointers */
1477 if (G_UNLIKELY (caps1 == caps2))
1480 /* empty caps on either side, return empty */
1481 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1484 /* one of the caps is any */
1485 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1488 /* run zigzag on top line then right line, this preserves the caps order
1489 * much better than a simple loop.
1491 * This algorithm zigzags over the caps structures as demonstrated in
1492 * the following matrix:
1495 * +------------- total distance: +-------------
1496 * | 1 2 4 7 0 | 0 1 2 3
1497 * caps2 | 3 5 8 10 1 | 1 2 3 4
1498 * | 6 9 11 12 2 | 2 3 4 5
1500 * First we iterate over the caps1 structures (top line) intersecting
1501 * the structures diagonally down, then we iterate over the caps2
1502 * structures. The result is that the intersections are ordered based on the
1503 * sum of the indexes in the list.
1505 len1 = GST_CAPS_LEN (caps1);
1506 len2 = GST_CAPS_LEN (caps2);
1507 for (i = 0; i < len1 + len2 - 1; i++) {
1508 /* superset index goes from 0 to superset->structs->len-1 */
1509 j = MIN (i, len1 - 1);
1510 /* subset index stays 0 until i reaches superset->structs->len, then it
1511 * counts up from 1 to subset->structs->len - 1 */
1512 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1513 /* now run the diagonal line, end condition is the left or bottom
1516 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1517 features1 = gst_caps_get_features_unchecked (caps1, j);
1519 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1520 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1521 features2 = gst_caps_get_features_unchecked (caps2, k);
1523 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1524 if (gst_caps_features_is_equal (features1, features2) &&
1525 gst_structure_can_intersect (struct1, struct2)) {
1528 /* move down left */
1530 if (G_UNLIKELY (j == 0))
1531 break; /* so we don't roll back to G_MAXUINT */
1540 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1542 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1543 guint j, k, len1, len2;
1544 GstStructure *struct1;
1545 GstStructure *struct2;
1546 GstCapsFeatures *features1;
1547 GstCapsFeatures *features2;
1549 GstStructure *istruct;
1551 /* caps are exactly the same pointers, just copy one caps */
1552 if (G_UNLIKELY (caps1 == caps2))
1553 return gst_caps_ref (caps1);
1555 /* empty caps on either side, return empty */
1556 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1557 return gst_caps_ref (GST_CAPS_NONE);
1559 /* one of the caps is any, just copy the other caps */
1560 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1561 return gst_caps_ref (caps2);
1563 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1564 return gst_caps_ref (caps1);
1566 dest = gst_caps_new_empty ();
1567 /* run zigzag on top line then right line, this preserves the caps order
1568 * much better than a simple loop.
1570 * This algorithm zigzags over the caps structures as demonstrated in
1571 * the following matrix:
1579 * First we iterate over the caps1 structures (top line) intersecting
1580 * the structures diagonally down, then we iterate over the caps2
1583 len1 = GST_CAPS_LEN (caps1);
1584 len2 = GST_CAPS_LEN (caps2);
1585 for (i = 0; i < len1 + len2 - 1; i++) {
1586 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1587 j = MIN (i, len1 - 1);
1588 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1589 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1590 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1591 /* now run the diagonal line, end condition is the left or bottom
1594 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1595 features1 = gst_caps_get_features_unchecked (caps1, j);
1597 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1598 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1599 features2 = gst_caps_get_features_unchecked (caps2, k);
1601 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1602 if (gst_caps_features_is_equal (features1, features2)) {
1603 istruct = gst_structure_intersect (struct1, struct2);
1605 if (gst_caps_features_is_any (features1))
1607 gst_caps_merge_structure_full (dest, istruct,
1608 gst_caps_features_copy_conditional (features2));
1611 gst_caps_merge_structure_full (dest, istruct,
1612 gst_caps_features_copy_conditional (features1));
1615 /* move down left */
1617 if (G_UNLIKELY (j == 0))
1618 break; /* so we don't roll back to G_MAXUINT */
1626 * gst_caps_intersect_first:
1627 * @caps1: a #GstCaps to intersect
1628 * @caps2: a #GstCaps to intersect
1630 * Creates a new #GstCaps that contains all the formats that are common
1631 * to both @caps1 and @caps2.
1633 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1634 * fashion as @caps1.
1636 * Returns: (transfer full): the new #GstCaps
1639 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1642 guint j, len1, len2;
1643 GstStructure *struct1;
1644 GstStructure *struct2;
1645 GstCapsFeatures *features1;
1646 GstCapsFeatures *features2;
1648 GstStructure *istruct;
1650 /* caps are exactly the same pointers, just copy one caps */
1651 if (G_UNLIKELY (caps1 == caps2))
1652 return gst_caps_ref (caps1);
1654 /* empty caps on either side, return empty */
1655 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1656 return gst_caps_ref (GST_CAPS_NONE);
1658 /* one of the caps is any, just copy the other caps */
1659 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1660 return gst_caps_ref (caps2);
1662 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1663 return gst_caps_ref (caps1);
1665 dest = gst_caps_new_empty ();
1666 len1 = GST_CAPS_LEN (caps1);
1667 len2 = GST_CAPS_LEN (caps2);
1668 for (i = 0; i < len1; i++) {
1669 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1670 features1 = gst_caps_get_features_unchecked (caps1, i);
1672 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1673 for (j = 0; j < len2; j++) {
1674 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1675 features2 = gst_caps_get_features_unchecked (caps2, j);
1677 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1678 if (gst_caps_features_is_equal (features1, features2)) {
1679 istruct = gst_structure_intersect (struct1, struct2);
1681 if (gst_caps_features_is_any (features1))
1683 gst_caps_merge_structure_full (dest, istruct,
1684 gst_caps_features_copy_conditional (features2));
1687 gst_caps_merge_structure_full (dest, istruct,
1688 gst_caps_features_copy_conditional (features1));
1698 * gst_caps_intersect_full:
1699 * @caps1: a #GstCaps to intersect
1700 * @caps2: a #GstCaps to intersect
1701 * @mode: The intersection algorithm/mode to use
1703 * Creates a new #GstCaps that contains all the formats that are common
1704 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1707 * Returns: (transfer full): the new #GstCaps
1710 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1711 GstCapsIntersectMode mode)
1713 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1714 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1717 case GST_CAPS_INTERSECT_FIRST:
1718 return gst_caps_intersect_first (caps1, caps2);
1720 g_warning ("Unknown caps intersect mode: %d", mode);
1722 case GST_CAPS_INTERSECT_ZIG_ZAG:
1723 return gst_caps_intersect_zig_zag (caps1, caps2);
1728 * gst_caps_intersect:
1729 * @caps1: a #GstCaps to intersect
1730 * @caps2: a #GstCaps to intersect
1732 * Creates a new #GstCaps that contains all the formats that are common
1733 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1735 * Returns: (transfer full): the new #GstCaps
1738 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1740 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1743 /* subtract operation */
1747 const GstStructure *subtract_from;
1752 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1755 SubtractionEntry *e = user_data;
1756 GValue subtraction = { 0, };
1757 const GValue *other;
1758 GstStructure *structure;
1760 other = gst_structure_id_get_value (e->subtract_from, field_id);
1766 if (!gst_value_subtract (&subtraction, other, value))
1769 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1770 g_value_unset (&subtraction);
1773 structure = gst_structure_copy (e->subtract_from);
1774 gst_structure_id_take_value (structure, field_id, &subtraction);
1775 e->put_into = g_slist_prepend (e->put_into, structure);
1781 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1782 const GstStructure * subtrahend)
1787 e.subtract_from = minuend;
1789 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1790 gst_caps_structure_subtract_field, &e);
1797 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1798 gst_structure_free (walk->data);
1800 g_slist_free (e.put_into);
1807 * gst_caps_subtract:
1808 * @minuend: #GstCaps to subtract from
1809 * @subtrahend: #GstCaps to subtract
1811 * Subtracts the @subtrahend from the @minuend.
1812 * > This function does not work reliably if optional properties for caps
1813 * > are included on one caps and omitted on the other.
1815 * Returns: (transfer full): the resulting caps
1818 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1823 GstCapsFeatures *min_f, *sub_f;
1824 GstCaps *dest = NULL, *src;
1826 g_return_val_if_fail (minuend != NULL, NULL);
1827 g_return_val_if_fail (subtrahend != NULL, NULL);
1829 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1830 return gst_caps_new_empty ();
1833 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1834 return gst_caps_ref (minuend);
1836 /* FIXME: Do we want this here or above?
1837 The reason we need this is that there is no definition about what
1838 ANY means for specific types, so it's not possible to reduce ANY partially
1839 You can only remove everything or nothing and that is done above.
1840 Note: there's a test that checks this behaviour. */
1842 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1843 sublen = GST_CAPS_LEN (subtrahend);
1844 g_assert (sublen > 0);
1846 src = _gst_caps_copy (minuend);
1847 for (i = 0; i < sublen; i++) {
1850 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1851 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1853 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1855 gst_caps_unref (src);
1858 dest = gst_caps_new_empty ();
1859 srclen = GST_CAPS_LEN (src);
1860 for (j = 0; j < srclen; j++) {
1861 min = gst_caps_get_structure_unchecked (src, j);
1862 min_f = gst_caps_get_features_unchecked (src, j);
1864 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1866 /* Same reason as above for ANY caps */
1867 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1869 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1870 gst_caps_features_is_equal (min_f, sub_f)) {
1873 if (gst_caps_structure_subtract (&list, min, sub)) {
1876 for (walk = list; walk; walk = g_slist_next (walk)) {
1877 gst_caps_append_structure_unchecked (dest,
1878 (GstStructure *) walk->data,
1879 gst_caps_features_copy_conditional (min_f));
1881 g_slist_free (list);
1883 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1884 gst_caps_features_copy_conditional (min_f));
1887 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1888 gst_caps_features_copy_conditional (min_f));
1892 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1893 gst_caps_unref (src);
1898 gst_caps_unref (src);
1899 dest = gst_caps_simplify (dest);
1904 /* normalize/simplify operations */
1906 typedef struct _NormalizeForeach
1909 GstStructure *structure;
1910 GstCapsFeatures *features;
1914 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1916 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1920 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1921 guint len = gst_value_list_get_size (value);
1923 for (i = 1; i < len; i++) {
1924 const GValue *v = gst_value_list_get_value (value, i);
1925 GstStructure *structure = gst_structure_copy (nf->structure);
1927 gst_structure_id_set_value (structure, field_id, v);
1928 gst_caps_append_structure_unchecked (nf->caps, structure,
1929 gst_caps_features_copy_conditional (nf->features));
1932 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1933 gst_structure_id_take_value (nf->structure, field_id, &val);
1941 * gst_caps_normalize:
1942 * @caps: (transfer full): a #GstCaps to normalize
1944 * Returns a #GstCaps that represents the same set of formats as
1945 * @caps, but contains no lists. Each list is expanded into separate
1948 * This function takes ownership of @caps and will call gst_caps_make_writable()
1949 * on it so you must not use @caps afterwards unless you keep an additional
1950 * reference to it with gst_caps_ref().
1952 * Returns: (transfer full): the normalized #GstCaps
1955 gst_caps_normalize (GstCaps * caps)
1957 NormalizeForeach nf;
1960 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1962 caps = gst_caps_make_writable (caps);
1965 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1966 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1967 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1968 while (!gst_structure_foreach (nf.structure,
1969 gst_caps_normalize_foreach, &nf));
1976 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1979 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1980 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1982 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1983 So what's the best way? */
1984 ret = strcmp (gst_structure_get_name (struct1),
1985 gst_structure_get_name (struct2));
1990 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1997 GstStructure *compare;
2001 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
2004 UnionField *u = user_data;
2005 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
2009 g_value_unset (&u->value);
2013 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
2017 g_value_unset (&u->value);
2022 gst_value_union (&u->value, val, value);
2028 gst_caps_structure_simplify (GstStructure ** result,
2029 GstStructure * simplify, GstStructure * compare)
2032 UnionField field = { 0, {0,}, NULL };
2034 /* try to subtract to get a real subset */
2035 if (gst_caps_structure_subtract (&list, simplify, compare)) {
2036 if (list == NULL) { /* no result */
2039 } else if (list->next == NULL) { /* one result */
2040 *result = list->data;
2041 g_slist_free (list);
2043 } else { /* multiple results */
2044 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
2045 g_slist_free (list);
2050 /* try to union both structs */
2051 field.compare = compare;
2052 if (gst_structure_foreach (simplify,
2053 gst_caps_structure_figure_out_union, &field)) {
2054 gboolean ret = FALSE;
2056 /* now we know all of simplify's fields are the same in compare
2057 * but at most one field: field.name */
2058 if (G_IS_VALUE (&field.value)) {
2059 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
2060 gst_structure_id_take_value (compare, field.name, &field.value);
2064 g_value_unset (&field.value);
2067 if (gst_structure_n_fields (simplify) <=
2068 gst_structure_n_fields (compare)) {
2069 /* compare is just more specific, will be optimized away later */
2070 /* FIXME: do this here? */
2071 GST_LOG ("found a case that will be optimized later.");
2073 gchar *one = gst_structure_to_string (simplify);
2074 gchar *two = gst_structure_to_string (compare);
2077 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2089 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2090 GstStructure * new, gint i)
2092 gst_structure_set_parent_refcount (old, NULL);
2093 gst_structure_free (old);
2094 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2095 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2099 * gst_caps_simplify:
2100 * @caps: (transfer full): a #GstCaps to simplify
2102 * Converts the given @caps into a representation that represents the
2103 * same set of formats, but in a simpler form. Component structures that are
2104 * identical are merged. Component structures that have values that can be
2105 * merged are also merged.
2107 * This function takes ownership of @caps and will call gst_caps_make_writable()
2108 * on it if necessary, so you must not use @caps afterwards unless you keep an
2109 * additional reference to it with gst_caps_ref().
2111 * This method does not preserve the original order of @caps.
2113 * Returns: (transfer full): The simplified caps.
2116 gst_caps_simplify (GstCaps * caps)
2118 GstStructure *simplify, *compare, *result = NULL;
2119 GstCapsFeatures *simplify_f, *compare_f;
2122 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2124 start = GST_CAPS_LEN (caps) - 1;
2125 /* one caps, already as simple as can be */
2129 caps = gst_caps_make_writable (caps);
2131 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2133 for (i = start; i >= 0; i--) {
2134 simplify = gst_caps_get_structure_unchecked (caps, i);
2135 simplify_f = gst_caps_get_features_unchecked (caps, i);
2137 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2138 compare = gst_caps_get_structure_unchecked (caps, start);
2139 compare_f = gst_caps_get_features_unchecked (caps, start);
2141 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2142 if (gst_structure_get_name_id (simplify) !=
2143 gst_structure_get_name_id (compare) ||
2144 !gst_caps_features_is_equal (simplify_f, compare_f))
2146 for (j = start; j >= 0; j--) {
2149 compare = gst_caps_get_structure_unchecked (caps, j);
2150 compare_f = gst_caps_get_features_unchecked (caps, j);
2152 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2153 if (gst_structure_get_name_id (simplify) !=
2154 gst_structure_get_name_id (compare) ||
2155 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2158 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2160 gst_caps_switch_structures (caps, simplify, result, i);
2163 gst_caps_remove_structure (caps, i);
2175 * @caps: (transfer full): a #GstCaps to fixate
2177 * Modifies the given @caps into a representation with only fixed
2178 * values. First the caps will be truncated and then the first structure will be
2179 * fixated with gst_structure_fixate().
2181 * This function takes ownership of @caps and will call gst_caps_make_writable()
2182 * on it so you must not use @caps afterwards unless you keep an additional
2183 * reference to it with gst_caps_ref().
2185 * Returns: (transfer full): the fixated caps
2188 gst_caps_fixate (GstCaps * caps)
2193 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2195 /* default fixation */
2196 caps = gst_caps_truncate (caps);
2197 caps = gst_caps_make_writable (caps);
2198 s = gst_caps_get_structure (caps, 0);
2199 gst_structure_fixate (s);
2201 /* Set features to sysmem if they're still ANY */
2202 f = gst_caps_get_features_unchecked (caps, 0);
2203 if (f && gst_caps_features_is_any (f)) {
2204 f = gst_caps_features_new_empty ();
2205 gst_caps_set_features (caps, 0, f);
2214 * gst_caps_to_string:
2217 * Converts @caps to a string representation. This string representation
2218 * can be converted back to a #GstCaps by gst_caps_from_string().
2220 * For debugging purposes its easier to do something like this:
2221 * |[<!-- language="C" -->
2222 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2224 * This prints the caps in human readable form.
2226 * The current implementation of serialization will lead to unexpected results
2227 * when there are nested #GstCaps / #GstStructure deeper than one level.
2229 * Returns: (transfer full): a newly allocated string representing @caps.
2232 gst_caps_to_string (const GstCaps * caps)
2234 guint i, slen, clen;
2237 /* NOTE: This function is potentially called by the debug system,
2238 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2239 * should be careful to avoid recursion. This includes any functions
2240 * called by gst_caps_to_string. In particular, calls should
2241 * not use the GST_PTR_FORMAT extension. */
2244 return g_strdup ("NULL");
2246 if (CAPS_IS_ANY (caps)) {
2247 return g_strdup ("ANY");
2249 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2250 return g_strdup ("EMPTY");
2253 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2255 clen = GST_CAPS_LEN (caps);
2256 for (i = 0; i < clen; i++) {
2260 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2262 f = gst_caps_get_features_unchecked (caps, i);
2264 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2267 s = g_string_sized_new (slen);
2268 for (i = 0; i < clen; i++) {
2269 GstStructure *structure;
2270 GstCapsFeatures *features;
2273 /* ';' is now added by gst_structure_to_string */
2274 g_string_append_c (s, ' ');
2277 structure = gst_caps_get_structure_unchecked (caps, i);
2278 features = gst_caps_get_features_unchecked (caps, i);
2280 g_string_append (s, gst_structure_get_name (structure));
2281 if (features && (gst_caps_features_is_any (features)
2282 || !gst_caps_features_is_equal (features,
2283 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2284 g_string_append_c (s, '(');
2285 priv_gst_caps_features_append_to_gstring (features, s);
2286 g_string_append_c (s, ')');
2288 priv_gst_structure_append_to_gstring (structure, s);
2290 if (s->len && s->str[s->len - 1] == ';') {
2291 /* remove latest ';' */
2292 s->str[--s->len] = '\0';
2294 return g_string_free (s, FALSE);
2298 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2300 GstStructure *structure;
2301 gchar *s, *copy, *end, *next, save;
2303 if (strcmp ("ANY", string) == 0) {
2304 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2308 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2312 copy = s = g_strdup (string);
2314 GstCapsFeatures *features = NULL;
2316 while (g_ascii_isspace (*s))
2322 if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2329 structure = gst_structure_new_empty (s);
2332 if (structure == NULL) {
2350 } else if (*end == ')') {
2359 features = gst_caps_features_from_string (s);
2361 gst_structure_free (structure);
2375 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2376 gst_structure_free (structure);
2378 gst_caps_features_free (features);
2384 gst_caps_append_structure_unchecked (caps, structure, features);
2396 * gst_caps_from_string:
2397 * @string: a string to convert to #GstCaps
2399 * Converts @caps from a string representation.
2401 * The current implementation of serialization will lead to unexpected results
2402 * when there are nested #GstCaps / #GstStructure deeper than one level.
2404 * Returns: (transfer full) (nullable): a newly allocated #GstCaps
2407 gst_caps_from_string (const gchar * string)
2411 g_return_val_if_fail (string, FALSE);
2413 caps = gst_caps_new_empty ();
2414 if (gst_caps_from_string_inplace (caps, string)) {
2417 gst_caps_unref (caps);
2423 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2425 g_return_if_fail (G_IS_VALUE (src_value));
2426 g_return_if_fail (G_IS_VALUE (dest_value));
2427 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2428 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2429 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2431 g_value_take_string (dest_value,
2432 gst_caps_to_string (gst_value_get_caps (src_value)));
2438 * @func: (scope call): a function to call for each field
2439 * @user_data: (closure): private data
2441 * Calls the provided function once for each structure and caps feature in the
2442 * #GstCaps. The function must not modify the fields.
2443 * Also see gst_caps_map_in_place() and gst_caps_filter_and_map_in_place().
2445 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2451 gst_caps_foreach (const GstCaps * caps, GstCapsForeachFunc func,
2455 GstCapsFeatures *features;
2456 GstStructure *structure;
2459 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2460 g_return_val_if_fail (func != NULL, FALSE);
2462 n = GST_CAPS_LEN (caps);
2464 for (i = 0; i < n; i++) {
2465 features = gst_caps_get_features_unchecked (caps, i);
2466 structure = gst_caps_get_structure_unchecked (caps, i);
2468 ret = func (features, structure, user_data);
2469 if (G_UNLIKELY (!ret))
2477 * gst_caps_map_in_place:
2479 * @func: (scope call): a function to call for each field
2480 * @user_data: (closure): private data
2482 * Calls the provided function once for each structure and caps feature in the
2483 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify but not
2484 * delete the structures and features. The caps must be mutable.
2486 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2492 gst_caps_map_in_place (GstCaps * caps, GstCapsMapFunc func, gpointer user_data)
2495 GstCapsFeatures *features;
2496 GstStructure *structure;
2499 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2500 g_return_val_if_fail (gst_caps_is_writable (caps), FALSE);
2501 g_return_val_if_fail (func != NULL, FALSE);
2503 n = GST_CAPS_LEN (caps);
2505 for (i = 0; i < n; i++) {
2506 features = gst_caps_get_features_unchecked (caps, i);
2507 structure = gst_caps_get_structure_unchecked (caps, i);
2509 /* Provide sysmem features if there are none yet */
2512 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2513 gst_caps_set_features (caps, i, features);
2516 ret = func (features, structure, user_data);
2517 if (G_UNLIKELY (!ret))
2525 * gst_caps_filter_and_map_in_place:
2527 * @func: (scope call): a function to call for each field
2528 * @user_data: (closure): private data
2530 * Calls the provided function once for each structure and caps feature in the
2531 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify the
2532 * structure and features. In contrast to gst_caps_filter_and_map_in_place(),
2533 * the structure and features are removed from the caps if %FALSE is returned
2534 * from the function.
2535 * The caps must be mutable.
2540 gst_caps_filter_and_map_in_place (GstCaps * caps, GstCapsFilterMapFunc func,
2544 GstCapsFeatures *features;
2545 GstStructure *structure;
2548 g_return_if_fail (GST_IS_CAPS (caps));
2549 g_return_if_fail (gst_caps_is_writable (caps));
2550 g_return_if_fail (func != NULL);
2552 n = GST_CAPS_LEN (caps);
2554 for (i = 0; i < n;) {
2555 features = gst_caps_get_features_unchecked (caps, i);
2556 structure = gst_caps_get_structure_unchecked (caps, i);
2558 /* Provide sysmem features if there are none yet */
2561 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2562 gst_caps_set_features (caps, i, features);
2565 ret = func (features, structure, user_data);
2567 GST_CAPS_ARRAY (caps) = g_array_remove_index (GST_CAPS_ARRAY (caps), i);
2569 gst_structure_set_parent_refcount (structure, NULL);
2570 gst_structure_free (structure);
2572 gst_caps_features_set_parent_refcount (features, NULL);
2573 gst_caps_features_free (features);
2576 n = GST_CAPS_LEN (caps);
2585 * @caps: a #GstCaps.
2587 * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
2588 * refcount of 1, owned by the caller. The structures are copied as well.
2590 * Note that this function is the semantic equivalent of a gst_caps_ref()
2591 * followed by a gst_caps_make_writable(). If you only want to hold on to a
2592 * reference to the data, you should use gst_caps_ref().
2594 * When you are finished with the caps, call gst_caps_unref() on it.
2596 * Returns: the new #GstCaps
2598 GstCaps *(gst_caps_copy) (const GstCaps * caps)
2600 return GST_CAPS (gst_mini_object_copy (GST_MINI_OBJECT_CAST (caps)));