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 (GST_CAT_PERFORMANCE, "doing copy %p -> %p", caps, newcaps);
180 for (i = 0; i < n; i++) {
181 structure = gst_caps_get_structure_unchecked (caps, i);
182 features = gst_caps_get_features_unchecked (caps, i);
183 gst_caps_append_structure_full (newcaps, gst_structure_copy (structure),
184 gst_caps_features_copy_conditional (features));
190 /* creation/deletion */
192 _gst_caps_free (GstCaps * caps)
194 GstStructure *structure;
195 GstCapsFeatures *features;
198 /* The refcount must be 0, but since we're only called by gst_caps_unref,
199 * don't bother testing. */
200 len = GST_CAPS_LEN (caps);
201 /* This can be used to get statistics about caps sizes */
202 /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
203 for (i = 0; i < len; i++) {
204 structure = gst_caps_get_structure_unchecked (caps, i);
205 gst_structure_set_parent_refcount (structure, NULL);
206 gst_structure_free (structure);
207 features = gst_caps_get_features_unchecked (caps, i);
209 gst_caps_features_set_parent_refcount (features, NULL);
210 gst_caps_features_free (features);
213 g_array_free (GST_CAPS_ARRAY (caps), TRUE);
215 #ifdef DEBUG_REFCOUNT
216 GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
220 memset (caps, 0xff, sizeof (GstCapsImpl));
223 g_slice_free1 (sizeof (GstCapsImpl), caps);
227 gst_caps_init (GstCaps * caps)
229 gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
230 (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
231 (GstMiniObjectFreeFunction) _gst_caps_free);
233 /* the 32 has been determined by logging caps sizes in _gst_caps_free
234 * but g_ptr_array uses 16 anyway if it expands once, so this does not help
236 * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
238 GST_CAPS_ARRAY (caps) =
239 g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
243 * gst_caps_new_empty:
245 * Creates a new #GstCaps that is empty. That is, the returned
246 * #GstCaps contains no media formats.
247 * The #GstCaps is guaranteed to be writable.
248 * Caller is responsible for unreffing the returned caps.
250 * Returns: (transfer full): the new #GstCaps
253 gst_caps_new_empty (void)
257 caps = (GstCaps *) g_slice_new (GstCapsImpl);
259 gst_caps_init (caps);
261 #ifdef DEBUG_REFCOUNT
262 GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
271 * Creates a new #GstCaps that indicates that it is compatible with
274 * Returns: (transfer full): the new #GstCaps
277 gst_caps_new_any (void)
279 GstCaps *caps = gst_caps_new_empty ();
281 GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_ANY);
287 * gst_caps_new_empty_simple:
288 * @media_type: the media type of the structure
290 * Creates a new #GstCaps that contains one #GstStructure with name
292 * Caller is responsible for unreffing the returned caps.
294 * Returns: (transfer full): the new #GstCaps
297 gst_caps_new_empty_simple (const char *media_type)
300 GstStructure *structure;
302 caps = gst_caps_new_empty ();
303 structure = gst_structure_new_empty (media_type);
305 gst_caps_append_structure_unchecked (caps, structure, NULL);
311 * gst_caps_new_simple:
312 * @media_type: the media type of the structure
313 * @fieldname: first field to set
314 * @...: additional arguments
316 * Creates a new #GstCaps that contains one #GstStructure. The
317 * structure is defined by the arguments, which have the same format
318 * as gst_structure_new().
319 * Caller is responsible for unreffing the returned caps.
321 * Returns: (transfer full): the new #GstCaps
324 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
327 GstStructure *structure;
330 caps = gst_caps_new_empty ();
332 va_start (var_args, fieldname);
333 structure = gst_structure_new_valist (media_type, fieldname, var_args);
337 gst_caps_append_structure_unchecked (caps, structure, NULL);
339 gst_caps_replace (&caps, NULL);
346 * @struct1: the first structure to add
347 * @...: additional structures to add
349 * Creates a new #GstCaps and adds all the structures listed as
350 * arguments. The list must be %NULL-terminated. The structures
351 * are not copied; the returned #GstCaps owns the structures.
353 * Returns: (transfer full): the new #GstCaps
356 gst_caps_new_full (GstStructure * struct1, ...)
361 va_start (var_args, struct1);
362 caps = gst_caps_new_full_valist (struct1, var_args);
369 * gst_caps_new_full_valist:
370 * @structure: the first structure to add
371 * @var_args: additional structures to add
373 * Creates a new #GstCaps and adds all the structures listed as
374 * arguments. The list must be %NULL-terminated. The structures
375 * are not copied; the returned #GstCaps owns the structures.
377 * Returns: (transfer full): the new #GstCaps
380 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
384 caps = gst_caps_new_empty ();
387 gst_caps_append_structure_unchecked (caps, structure, NULL);
388 structure = va_arg (var_args, GstStructure *);
394 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
397 * gst_static_caps_get:
398 * @static_caps: the #GstStaticCaps to convert
400 * Converts a #GstStaticCaps to a #GstCaps.
402 * Returns: (transfer full) (nullable): a pointer to the #GstCaps. Unref
403 * after usage. Since the core holds an additional ref to the
404 * returned caps, use gst_caps_make_writable() on the returned caps
408 gst_static_caps_get (GstStaticCaps * static_caps)
412 g_return_val_if_fail (static_caps != NULL, NULL);
414 caps = &static_caps->caps;
416 /* refcount is 0 when we need to convert */
417 if (G_UNLIKELY (*caps == NULL)) {
420 G_LOCK (static_caps_lock);
421 /* check if other thread already updated */
422 if (G_UNLIKELY (*caps != NULL))
425 string = static_caps->string;
427 if (G_UNLIKELY (string == NULL))
430 *caps = gst_caps_from_string (string);
432 /* convert to string */
433 if (G_UNLIKELY (*caps == NULL)) {
434 g_critical ("Could not convert static caps \"%s\"", string);
438 /* Caps generated from static caps are usually leaked */
439 GST_MINI_OBJECT_FLAG_SET (*caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
441 GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
444 G_UNLOCK (static_caps_lock);
446 /* ref the caps, makes it not writable */
447 if (G_LIKELY (*caps != NULL))
448 gst_caps_ref (*caps);
455 G_UNLOCK (static_caps_lock);
456 g_warning ("static caps %p string is NULL", static_caps);
462 * gst_static_caps_cleanup:
463 * @static_caps: the #GstStaticCaps to clean
465 * Clean up the cached caps contained in @static_caps.
468 gst_static_caps_cleanup (GstStaticCaps * static_caps)
470 G_LOCK (static_caps_lock);
471 gst_caps_replace (&static_caps->caps, NULL);
472 G_UNLOCK (static_caps_lock);
478 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
479 GstStructure ** s, GstCapsFeatures ** f)
484 s_ = gst_caps_get_structure_unchecked (caps, idx);
485 f_ = gst_caps_get_features_unchecked (caps, idx);
487 /* don't use index_fast, gst_caps_simplify relies on the order */
488 g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
490 gst_structure_set_parent_refcount (s_, NULL);
492 gst_caps_features_set_parent_refcount (f_, NULL);
499 static GstStructure *
500 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
505 gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
508 gst_caps_features_free (f);
514 * gst_caps_steal_structure:
515 * @caps: the #GstCaps to retrieve from
516 * @index: Index of the structure to retrieve
518 * Retrieves the structure with the given index from the list of structures
519 * contained in @caps. The caller becomes the owner of the returned structure.
521 * Returns: (transfer full) (nullable): a pointer to the #GstStructure
522 * corresponding to @index.
525 gst_caps_steal_structure (GstCaps * caps, guint index)
527 g_return_val_if_fail (caps != NULL, NULL);
528 g_return_val_if_fail (IS_WRITABLE (caps), NULL);
530 if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
533 return gst_caps_remove_and_get_structure (caps, index);
538 * @caps1: the #GstCaps that will be appended to
539 * @caps2: (transfer full): the #GstCaps to append
541 * Appends the structures contained in @caps2 to @caps1. The structures in
542 * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
543 * freed. If either caps is ANY, the resulting caps will be ANY.
546 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
548 GstStructure *structure;
549 GstCapsFeatures *features;
552 g_return_if_fail (GST_IS_CAPS (caps1));
553 g_return_if_fail (GST_IS_CAPS (caps2));
554 g_return_if_fail (IS_WRITABLE (caps1));
556 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
557 GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
558 gst_caps_unref (caps2);
560 caps2 = gst_caps_make_writable (caps2);
562 for (i = GST_CAPS_LEN (caps2); i; i--) {
563 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
565 gst_caps_append_structure_unchecked (caps1, structure, features);
567 gst_caps_unref (caps2); /* guaranteed to free it */
573 * @caps1: (transfer full): the #GstCaps that will take the new entries
574 * @caps2: (transfer full): the #GstCaps to merge in
576 * Appends the structures contained in @caps2 to @caps1 if they are not yet
577 * expressed by @caps1. The structures in @caps2 are not copied -- they are
578 * transferred to a writable copy of @caps1, and then @caps2 is freed.
579 * If either caps is ANY, the resulting caps will be ANY.
581 * Returns: (transfer full): the merged caps.
584 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
586 GstStructure *structure;
587 GstCapsFeatures *features;
591 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
592 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
594 if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
595 gst_caps_unref (caps2);
597 } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
598 gst_caps_unref (caps1);
601 caps2 = gst_caps_make_writable (caps2);
603 for (i = GST_CAPS_LEN (caps2); i; i--) {
604 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
606 caps1 = gst_caps_merge_structure_full (caps1, structure, features);
608 gst_caps_unref (caps2);
612 GstCaps *com = gst_caps_intersect (caps1, caps2);
613 GstCaps *add = gst_caps_subtract (caps2, com);
615 GST_DEBUG ("common : %d", gst_caps_get_size (com));
616 GST_DEBUG ("adding : %d", gst_caps_get_size (add));
617 gst_caps_append (caps1, add);
618 gst_caps_unref (com);
626 * gst_caps_append_structure:
627 * @caps: the #GstCaps that will be appended to
628 * @structure: (transfer full): the #GstStructure to append
630 * Appends @structure to @caps. The structure is not copied; @caps
631 * becomes the owner of @structure.
634 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
636 g_return_if_fail (GST_IS_CAPS (caps));
637 g_return_if_fail (IS_WRITABLE (caps));
639 if (G_LIKELY (structure)) {
640 gst_caps_append_structure_unchecked (caps, structure, NULL);
645 * gst_caps_append_structure_full:
646 * @caps: the #GstCaps that will be appended to
647 * @structure: (transfer full): the #GstStructure to append
648 * @features: (transfer full) (allow-none): the #GstCapsFeatures to append
650 * Appends @structure with @features to @caps. The structure is not copied; @caps
651 * becomes the owner of @structure.
656 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
657 GstCapsFeatures * features)
659 g_return_if_fail (GST_IS_CAPS (caps));
660 g_return_if_fail (IS_WRITABLE (caps));
662 if (G_LIKELY (structure)) {
663 gst_caps_append_structure_unchecked (caps, structure, features);
668 * gst_caps_remove_structure:
669 * @caps: the #GstCaps to remove from
670 * @idx: Index of the structure to remove
672 * removes the structure with the given index from the list of structures
673 * contained in @caps.
676 gst_caps_remove_structure (GstCaps * caps, guint idx)
678 GstStructure *structure;
680 g_return_if_fail (caps != NULL);
681 g_return_if_fail (idx <= gst_caps_get_size (caps));
682 g_return_if_fail (IS_WRITABLE (caps));
684 structure = gst_caps_remove_and_get_structure (caps, idx);
685 gst_structure_free (structure);
689 * gst_caps_merge_structure:
690 * @caps: (transfer full): the #GstCaps to merge into
691 * @structure: (transfer full): the #GstStructure to merge
693 * Appends @structure to @caps if its not already expressed by @caps.
695 * Returns: (transfer full): the merged caps.
698 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
700 GstStructure *structure1;
701 GstCapsFeatures *features1;
703 gboolean unique = TRUE;
705 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
707 if (G_UNLIKELY (structure == NULL))
710 /* check each structure */
711 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
712 structure1 = gst_caps_get_structure_unchecked (caps, i);
713 features1 = gst_caps_get_features_unchecked (caps, i);
715 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
717 /* if structure is a subset of structure1 and the
718 * there are no existing features, then skip it */
719 if (gst_caps_features_is_equal (features1,
720 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
721 && gst_structure_is_subset (structure, structure1)) {
727 caps = gst_caps_make_writable (caps);
728 gst_caps_append_structure_unchecked (caps, structure, NULL);
730 gst_structure_free (structure);
736 * gst_caps_merge_structure_full:
737 * @caps: (transfer full): the #GstCaps to merge into
738 * @structure: (transfer full): the #GstStructure to merge
739 * @features: (transfer full) (allow-none): the #GstCapsFeatures to merge
741 * Appends @structure with @features to @caps if its not already expressed by @caps.
743 * Returns: (transfer full): the merged caps.
748 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
749 GstCapsFeatures * features)
751 GstStructure *structure1;
752 GstCapsFeatures *features1, *features_tmp;
754 gboolean unique = TRUE;
756 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
758 if (G_UNLIKELY (structure == NULL))
761 /* To make comparisons easier below */
762 features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
764 /* check each structure */
765 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
766 structure1 = gst_caps_get_structure_unchecked (caps, i);
767 features1 = gst_caps_get_features_unchecked (caps, i);
769 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
770 /* if structure is a subset of structure1 and the
771 * the features are a subset, then skip it */
772 /* FIXME: We only skip if none of the features are
773 * ANY and are still equal. That way all ANY structures
774 * show up in the caps and no non-ANY structures are
775 * swallowed by ANY structures
777 if (((!gst_caps_features_is_any (features_tmp)
778 || gst_caps_features_is_any (features1))
779 && gst_caps_features_is_equal (features_tmp, features1))
780 && gst_structure_is_subset (structure, structure1)) {
786 caps = gst_caps_make_writable (caps);
787 gst_caps_append_structure_unchecked (caps, structure, features);
789 gst_structure_free (structure);
791 gst_caps_features_free (features);
800 * Gets the number of structures contained in @caps.
802 * Returns: the number of structures that @caps contains
805 gst_caps_get_size (const GstCaps * caps)
807 g_return_val_if_fail (GST_IS_CAPS (caps), 0);
809 return GST_CAPS_LEN (caps);
813 * gst_caps_get_structure:
815 * @index: the index of the structure
817 * Finds the structure in @caps that has the index @index, and
820 * WARNING: This function takes a const GstCaps *, but returns a
821 * non-const GstStructure *. This is for programming convenience --
822 * the caller should be aware that structures inside a constant
823 * #GstCaps should not be modified. However, if you know the caps
824 * are writable, either because you have just copied them or made
825 * them writable with gst_caps_make_writable(), you may modify the
826 * structure returned in the usual way, e.g. with functions like
827 * gst_structure_set().
829 * You do not need to free or unref the structure returned, it
830 * belongs to the #GstCaps.
832 * Returns: (transfer none): a pointer to the #GstStructure corresponding
836 gst_caps_get_structure (const GstCaps * caps, guint index)
838 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
839 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
841 return gst_caps_get_structure_unchecked (caps, index);
845 * gst_caps_get_features:
847 * @index: the index of the structure
849 * Finds the features in @caps that has the index @index, and
852 * WARNING: This function takes a const GstCaps *, but returns a
853 * non-const GstCapsFeatures *. This is for programming convenience --
854 * the caller should be aware that structures inside a constant
855 * #GstCaps should not be modified. However, if you know the caps
856 * are writable, either because you have just copied them or made
857 * them writable with gst_caps_make_writable(), you may modify the
858 * features returned in the usual way, e.g. with functions like
859 * gst_caps_features_add().
861 * You do not need to free or unref the structure returned, it
862 * belongs to the #GstCaps.
864 * Returns: (transfer none) (nullable): a pointer to the #GstCapsFeatures
865 * corresponding to @index
870 gst_caps_get_features (const GstCaps * caps, guint index)
872 GstCapsFeatures *features;
874 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
875 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
877 features = gst_caps_get_features_unchecked (caps, index);
879 GstCapsFeatures **storage;
881 /* We have to do some atomic pointer magic here as the caps
882 * might not be writable and someone else calls this function
883 * at the very same time */
884 features = gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
885 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
887 storage = gst_caps_get_features_storage_unchecked (caps, index);
888 if (!g_atomic_pointer_compare_and_exchange (storage, NULL, features)) {
889 /* Someone did the same we just tried in the meantime */
890 gst_caps_features_set_parent_refcount (features, NULL);
891 gst_caps_features_free (features);
893 features = gst_caps_get_features_unchecked (caps, index);
894 g_assert (features != NULL);
902 * gst_caps_set_features:
904 * @index: the index of the structure
905 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
907 * Sets the #GstCapsFeatures @features for the structure at @index.
912 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
914 GstCapsFeatures **storage, *old;
916 g_return_if_fail (caps != NULL);
917 g_return_if_fail (index <= gst_caps_get_size (caps));
918 g_return_if_fail (IS_WRITABLE (caps));
920 storage = gst_caps_get_features_storage_unchecked (caps, index);
921 /* Not much problem here as caps are writable */
922 old = g_atomic_pointer_get (storage);
923 g_atomic_pointer_set (storage, features);
926 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
929 gst_caps_features_set_parent_refcount (old, NULL);
930 gst_caps_features_free (old);
935 * gst_caps_set_features_simple:
937 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
939 * Sets the #GstCapsFeatures @features for all the structures of @caps.
944 gst_caps_set_features_simple (GstCaps * caps, GstCapsFeatures * features)
949 g_return_if_fail (caps != NULL);
950 g_return_if_fail (IS_WRITABLE (caps));
952 n = gst_caps_get_size (caps);
954 for (i = 0; i < n; i++) {
957 /* Transfer ownership of @features to the last structure */
958 if (features && i < n - 1)
959 f = gst_caps_features_copy (features);
963 gst_caps_set_features (caps, i, f);
969 * @caps: the #GstCaps to copy
970 * @nth: the nth structure to copy
972 * Creates a new #GstCaps and appends a copy of the nth structure
973 * contained in @caps.
975 * Returns: (transfer full): the new #GstCaps
980 gst_caps_copy_nth (const GstCaps * caps, guint nth)
983 GstStructure *structure;
984 GstCapsFeatures *features;
986 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
988 newcaps = gst_caps_new_empty ();
989 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
991 if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
992 structure = gst_caps_get_structure_unchecked (caps, nth);
993 features = gst_caps_get_features_unchecked (caps, nth);
994 gst_caps_append_structure_unchecked (newcaps,
995 gst_structure_copy (structure),
996 gst_caps_features_copy_conditional (features));
1003 * gst_caps_truncate:
1004 * @caps: (transfer full): the #GstCaps to truncate
1006 * Discard all but the first structure from @caps. Useful when
1009 * This function takes ownership of @caps and will call gst_caps_make_writable()
1010 * on it if necessary, so you must not use @caps afterwards unless you keep an
1011 * additional reference to it with gst_caps_ref().
1013 * Returns: (transfer full): truncated caps
1016 gst_caps_truncate (GstCaps * caps)
1020 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1022 i = GST_CAPS_LEN (caps) - 1;
1026 caps = gst_caps_make_writable (caps);
1028 gst_caps_remove_structure (caps, i--);
1034 * gst_caps_set_value:
1035 * @caps: a writable caps
1036 * @field: name of the field to set
1037 * @value: value to set the field to
1039 * Sets the given @field on all structures of @caps to the given @value.
1040 * This is a convenience function for calling gst_structure_set_value() on
1041 * all structures of @caps.
1044 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
1048 g_return_if_fail (GST_IS_CAPS (caps));
1049 g_return_if_fail (IS_WRITABLE (caps));
1050 g_return_if_fail (field != NULL);
1051 g_return_if_fail (G_IS_VALUE (value));
1053 len = GST_CAPS_LEN (caps);
1054 for (i = 0; i < len; i++) {
1055 GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
1056 gst_structure_set_value (structure, field, value);
1061 * gst_caps_set_simple_valist:
1062 * @caps: the #GstCaps to set
1063 * @field: first field to set
1064 * @varargs: additional parameters
1066 * Sets fields in a #GstCaps. The arguments must be passed in the same
1067 * manner as gst_structure_set(), and be %NULL-terminated.
1070 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
1072 GValue value = { 0, };
1074 g_return_if_fail (GST_IS_CAPS (caps));
1075 g_return_if_fail (IS_WRITABLE (caps));
1081 type = va_arg (varargs, GType);
1083 G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1084 if (G_UNLIKELY (err)) {
1085 g_critical ("%s", err);
1090 gst_caps_set_value (caps, field, &value);
1092 g_value_unset (&value);
1094 field = va_arg (varargs, const gchar *);
1099 * gst_caps_set_simple:
1100 * @caps: the #GstCaps to set
1101 * @field: first field to set
1102 * @...: additional parameters
1104 * Sets fields in a #GstCaps. The arguments must be passed in the same
1105 * manner as gst_structure_set(), and be %NULL-terminated.
1108 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1112 g_return_if_fail (GST_IS_CAPS (caps));
1113 g_return_if_fail (IS_WRITABLE (caps));
1115 va_start (var_args, field);
1116 gst_caps_set_simple_valist (caps, field, var_args);
1124 * @caps: the #GstCaps to test
1126 * Determines if @caps represents any media format.
1128 * Returns: %TRUE if @caps represents any format.
1131 gst_caps_is_any (const GstCaps * caps)
1133 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1135 return (CAPS_IS_ANY (caps));
1139 * gst_caps_is_empty:
1140 * @caps: the #GstCaps to test
1142 * Determines if @caps represents no media formats.
1144 * Returns: %TRUE if @caps represents no formats.
1147 gst_caps_is_empty (const GstCaps * caps)
1149 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1151 if (CAPS_IS_ANY (caps))
1154 return CAPS_IS_EMPTY_SIMPLE (caps);
1158 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1161 return gst_value_is_fixed (value);
1165 * gst_caps_is_fixed:
1166 * @caps: the #GstCaps to test
1168 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1169 * one structure, and each field in the structure describes a fixed type.
1170 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1172 * Returns: %TRUE if @caps is fixed
1175 gst_caps_is_fixed (const GstCaps * caps)
1177 GstStructure *structure;
1178 GstCapsFeatures *features;
1180 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1182 if (GST_CAPS_LEN (caps) != 1)
1185 features = gst_caps_get_features_unchecked (caps, 0);
1186 if (features && gst_caps_features_is_any (features))
1189 structure = gst_caps_get_structure_unchecked (caps, 0);
1191 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1195 * gst_caps_is_equal_fixed:
1196 * @caps1: the #GstCaps to test
1197 * @caps2: the #GstCaps to test
1199 * Tests if two #GstCaps are equal. This function only works on fixed
1202 * Returns: %TRUE if the arguments represent the same format
1205 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1207 GstStructure *struct1, *struct2;
1208 GstCapsFeatures *features1, *features2;
1210 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1211 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1213 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1214 features1 = gst_caps_get_features_unchecked (caps1, 0);
1216 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1217 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1218 features2 = gst_caps_get_features_unchecked (caps2, 0);
1220 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1222 return gst_structure_is_equal (struct1, struct2) &&
1223 gst_caps_features_is_equal (features1, features2);
1227 * gst_caps_is_always_compatible:
1228 * @caps1: the #GstCaps to test
1229 * @caps2: the #GstCaps to test
1231 * A given #GstCaps structure is always compatible with another if
1232 * every media format that is in the first is also contained in the
1233 * second. That is, @caps1 is a subset of @caps2.
1235 * Returns: %TRUE if @caps1 is a subset of @caps2.
1238 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1240 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1241 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1243 return gst_caps_is_subset (caps1, caps2);
1247 * gst_caps_is_subset:
1248 * @subset: a #GstCaps
1249 * @superset: a potentially greater #GstCaps
1251 * Checks if all caps represented by @subset are also represented by @superset.
1253 * Returns: %TRUE if @subset is a subset of @superset
1256 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1258 GstStructure *s1, *s2;
1259 GstCapsFeatures *f1, *f2;
1260 gboolean ret = TRUE;
1263 g_return_val_if_fail (subset != NULL, FALSE);
1264 g_return_val_if_fail (superset != NULL, FALSE);
1266 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1268 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1271 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1272 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1273 s1 = gst_caps_get_structure_unchecked (subset, i);
1274 f1 = gst_caps_get_features_unchecked (subset, i);
1276 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1277 s2 = gst_caps_get_structure_unchecked (superset, j);
1278 f2 = gst_caps_get_features_unchecked (superset, j);
1280 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1281 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1282 gst_caps_features_is_equal (f1, f2)
1283 && gst_structure_is_subset (s1, s2)) {
1284 /* If we found a superset, continue with the next
1285 * subset structure */
1289 /* If we found no superset for this subset structure
1290 * we return FALSE immediately */
1301 * gst_caps_is_subset_structure:
1303 * @structure: a potential #GstStructure subset of @caps
1305 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1306 * for more information.
1308 * Returns: %TRUE if @structure is a subset of @caps
1311 gst_caps_is_subset_structure (const GstCaps * caps,
1312 const GstStructure * structure)
1317 g_return_val_if_fail (caps != NULL, FALSE);
1318 g_return_val_if_fail (structure != NULL, FALSE);
1320 if (CAPS_IS_ANY (caps))
1322 if (CAPS_IS_EMPTY (caps))
1325 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1326 s = gst_caps_get_structure_unchecked (caps, i);
1327 if (gst_structure_is_subset (structure, s)) {
1328 /* If we found a superset return TRUE */
1337 * gst_caps_is_subset_structure_full:
1339 * @structure: a potential #GstStructure subset of @caps
1340 * @features: (allow-none): a #GstCapsFeatures for @structure
1342 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1343 * for more information.
1345 * Returns: %TRUE if @structure is a subset of @caps
1350 gst_caps_is_subset_structure_full (const GstCaps * caps,
1351 const GstStructure * structure, const GstCapsFeatures * features)
1357 g_return_val_if_fail (caps != NULL, FALSE);
1358 g_return_val_if_fail (structure != NULL, FALSE);
1360 if (CAPS_IS_ANY (caps))
1362 if (CAPS_IS_EMPTY (caps))
1366 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1368 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1369 s = gst_caps_get_structure_unchecked (caps, i);
1370 f = gst_caps_get_features_unchecked (caps, i);
1372 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1373 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1374 && gst_caps_features_is_equal (features, f)
1375 && gst_structure_is_subset (structure, s)) {
1376 /* If we found a superset return TRUE */
1385 * gst_caps_is_equal:
1386 * @caps1: a #GstCaps
1387 * @caps2: another #GstCaps
1389 * Checks if the given caps represent the same set of caps.
1391 * Returns: %TRUE if both caps are equal.
1394 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1396 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1397 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1399 if (G_UNLIKELY (caps1 == caps2))
1402 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1403 return gst_caps_is_equal_fixed (caps1, caps2);
1405 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1409 * gst_caps_is_strictly_equal:
1410 * @caps1: a #GstCaps
1411 * @caps2: another #GstCaps
1413 * Checks if the given caps are exactly the same set of caps.
1415 * Returns: %TRUE if both caps are strictly equal.
1418 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1421 GstStructure *s1, *s2;
1422 GstCapsFeatures *f1, *f2;
1424 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1425 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1427 if (G_UNLIKELY (caps1 == caps2))
1430 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1433 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1434 s1 = gst_caps_get_structure_unchecked (caps1, i);
1435 f1 = gst_caps_get_features_unchecked (caps1, i);
1437 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1438 s2 = gst_caps_get_structure_unchecked (caps2, i);
1439 f2 = gst_caps_get_features_unchecked (caps2, i);
1441 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1443 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1444 !gst_caps_features_is_equal (f1, f2) ||
1445 !gst_structure_is_equal (s1, s2))
1452 /* intersect operation */
1455 * gst_caps_can_intersect:
1456 * @caps1: a #GstCaps to intersect
1457 * @caps2: a #GstCaps to intersect
1459 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1462 * Returns: %TRUE if intersection would be not empty
1465 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1467 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1468 guint j, k, len1, len2;
1469 GstStructure *struct1;
1470 GstStructure *struct2;
1471 GstCapsFeatures *features1;
1472 GstCapsFeatures *features2;
1474 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1475 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1477 /* caps are exactly the same pointers */
1478 if (G_UNLIKELY (caps1 == caps2))
1481 /* empty caps on either side, return empty */
1482 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1485 /* one of the caps is any */
1486 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1489 /* run zigzag on top line then right line, this preserves the caps order
1490 * much better than a simple loop.
1492 * This algorithm zigzags over the caps structures as demonstrated in
1493 * the following matrix:
1496 * +------------- total distance: +-------------
1497 * | 1 2 4 7 0 | 0 1 2 3
1498 * caps2 | 3 5 8 10 1 | 1 2 3 4
1499 * | 6 9 11 12 2 | 2 3 4 5
1501 * First we iterate over the caps1 structures (top line) intersecting
1502 * the structures diagonally down, then we iterate over the caps2
1503 * structures. The result is that the intersections are ordered based on the
1504 * sum of the indexes in the list.
1506 len1 = GST_CAPS_LEN (caps1);
1507 len2 = GST_CAPS_LEN (caps2);
1508 for (i = 0; i < len1 + len2 - 1; i++) {
1509 /* superset index goes from 0 to superset->structs->len-1 */
1510 j = MIN (i, len1 - 1);
1511 /* subset index stays 0 until i reaches superset->structs->len, then it
1512 * counts up from 1 to subset->structs->len - 1 */
1513 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1514 /* now run the diagonal line, end condition is the left or bottom
1517 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1518 features1 = gst_caps_get_features_unchecked (caps1, j);
1520 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1521 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1522 features2 = gst_caps_get_features_unchecked (caps2, k);
1524 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1525 if (gst_caps_features_is_equal (features1, features2) &&
1526 gst_structure_can_intersect (struct1, struct2)) {
1529 /* move down left */
1531 if (G_UNLIKELY (j == 0))
1532 break; /* so we don't roll back to G_MAXUINT */
1541 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1543 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1544 guint j, k, len1, len2;
1545 GstStructure *struct1;
1546 GstStructure *struct2;
1547 GstCapsFeatures *features1;
1548 GstCapsFeatures *features2;
1550 GstStructure *istruct;
1552 /* caps are exactly the same pointers, just copy one caps */
1553 if (G_UNLIKELY (caps1 == caps2))
1554 return gst_caps_ref (caps1);
1556 /* empty caps on either side, return empty */
1557 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1558 return gst_caps_ref (GST_CAPS_NONE);
1560 /* one of the caps is any, just copy the other caps */
1561 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1562 return gst_caps_ref (caps2);
1564 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1565 return gst_caps_ref (caps1);
1567 dest = gst_caps_new_empty ();
1568 /* run zigzag on top line then right line, this preserves the caps order
1569 * much better than a simple loop.
1571 * This algorithm zigzags over the caps structures as demonstrated in
1572 * the following matrix:
1580 * First we iterate over the caps1 structures (top line) intersecting
1581 * the structures diagonally down, then we iterate over the caps2
1584 len1 = GST_CAPS_LEN (caps1);
1585 len2 = GST_CAPS_LEN (caps2);
1586 for (i = 0; i < len1 + len2 - 1; i++) {
1587 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1588 j = MIN (i, len1 - 1);
1589 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1590 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1591 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1592 /* now run the diagonal line, end condition is the left or bottom
1595 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1596 features1 = gst_caps_get_features_unchecked (caps1, j);
1598 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1599 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1600 features2 = gst_caps_get_features_unchecked (caps2, k);
1602 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1603 if (gst_caps_features_is_equal (features1, features2)) {
1604 istruct = gst_structure_intersect (struct1, struct2);
1606 if (gst_caps_features_is_any (features1))
1608 gst_caps_merge_structure_full (dest, istruct,
1609 gst_caps_features_copy_conditional (features2));
1612 gst_caps_merge_structure_full (dest, istruct,
1613 gst_caps_features_copy_conditional (features1));
1616 /* move down left */
1618 if (G_UNLIKELY (j == 0))
1619 break; /* so we don't roll back to G_MAXUINT */
1627 * gst_caps_intersect_first:
1628 * @caps1: a #GstCaps to intersect
1629 * @caps2: a #GstCaps to intersect
1631 * Creates a new #GstCaps that contains all the formats that are common
1632 * to both @caps1 and @caps2.
1634 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1635 * fashion as @caps1.
1637 * Returns: (transfer full): the new #GstCaps
1640 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1643 guint j, len1, len2;
1644 GstStructure *struct1;
1645 GstStructure *struct2;
1646 GstCapsFeatures *features1;
1647 GstCapsFeatures *features2;
1649 GstStructure *istruct;
1651 /* caps are exactly the same pointers, just copy one caps */
1652 if (G_UNLIKELY (caps1 == caps2))
1653 return gst_caps_ref (caps1);
1655 /* empty caps on either side, return empty */
1656 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1657 return gst_caps_ref (GST_CAPS_NONE);
1659 /* one of the caps is any, just copy the other caps */
1660 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1661 return gst_caps_ref (caps2);
1663 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1664 return gst_caps_ref (caps1);
1666 dest = gst_caps_new_empty ();
1667 len1 = GST_CAPS_LEN (caps1);
1668 len2 = GST_CAPS_LEN (caps2);
1669 for (i = 0; i < len1; i++) {
1670 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1671 features1 = gst_caps_get_features_unchecked (caps1, i);
1673 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1674 for (j = 0; j < len2; j++) {
1675 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1676 features2 = gst_caps_get_features_unchecked (caps2, j);
1678 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1679 if (gst_caps_features_is_equal (features1, features2)) {
1680 istruct = gst_structure_intersect (struct1, struct2);
1682 if (gst_caps_features_is_any (features1))
1684 gst_caps_merge_structure_full (dest, istruct,
1685 gst_caps_features_copy_conditional (features2));
1688 gst_caps_merge_structure_full (dest, istruct,
1689 gst_caps_features_copy_conditional (features1));
1699 * gst_caps_intersect_full:
1700 * @caps1: a #GstCaps to intersect
1701 * @caps2: a #GstCaps to intersect
1702 * @mode: The intersection algorithm/mode to use
1704 * Creates a new #GstCaps that contains all the formats that are common
1705 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1708 * Returns: (transfer full): the new #GstCaps
1711 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1712 GstCapsIntersectMode mode)
1714 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1715 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1718 case GST_CAPS_INTERSECT_FIRST:
1719 return gst_caps_intersect_first (caps1, caps2);
1721 g_warning ("Unknown caps intersect mode: %d", mode);
1723 case GST_CAPS_INTERSECT_ZIG_ZAG:
1724 return gst_caps_intersect_zig_zag (caps1, caps2);
1729 * gst_caps_intersect:
1730 * @caps1: a #GstCaps to intersect
1731 * @caps2: a #GstCaps to intersect
1733 * Creates a new #GstCaps that contains all the formats that are common
1734 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1736 * Returns: (transfer full): the new #GstCaps
1739 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1741 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1744 /* subtract operation */
1748 const GstStructure *subtract_from;
1753 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1756 SubtractionEntry *e = user_data;
1757 GValue subtraction = { 0, };
1758 const GValue *other;
1759 GstStructure *structure;
1761 other = gst_structure_id_get_value (e->subtract_from, field_id);
1767 if (!gst_value_subtract (&subtraction, other, value))
1770 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1771 g_value_unset (&subtraction);
1774 structure = gst_structure_copy (e->subtract_from);
1775 gst_structure_id_take_value (structure, field_id, &subtraction);
1776 e->put_into = g_slist_prepend (e->put_into, structure);
1782 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1783 const GstStructure * subtrahend)
1788 e.subtract_from = minuend;
1790 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1791 gst_caps_structure_subtract_field, &e);
1798 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1799 gst_structure_free (walk->data);
1801 g_slist_free (e.put_into);
1808 * gst_caps_subtract:
1809 * @minuend: #GstCaps to subtract from
1810 * @subtrahend: #GstCaps to subtract
1812 * Subtracts the @subtrahend from the @minuend.
1813 * > This function does not work reliably if optional properties for caps
1814 * > are included on one caps and omitted on the other.
1816 * Returns: (transfer full): the resulting caps
1819 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1824 GstCapsFeatures *min_f, *sub_f;
1825 GstCaps *dest = NULL, *src;
1827 g_return_val_if_fail (minuend != NULL, NULL);
1828 g_return_val_if_fail (subtrahend != NULL, NULL);
1830 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1831 return gst_caps_new_empty ();
1834 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1835 return gst_caps_ref (minuend);
1837 /* FIXME: Do we want this here or above?
1838 The reason we need this is that there is no definition about what
1839 ANY means for specific types, so it's not possible to reduce ANY partially
1840 You can only remove everything or nothing and that is done above.
1841 Note: there's a test that checks this behaviour. */
1843 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1844 sublen = GST_CAPS_LEN (subtrahend);
1845 g_assert (sublen > 0);
1847 src = _gst_caps_copy (minuend);
1848 for (i = 0; i < sublen; i++) {
1851 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1852 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1854 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1856 gst_caps_unref (src);
1859 dest = gst_caps_new_empty ();
1860 srclen = GST_CAPS_LEN (src);
1861 for (j = 0; j < srclen; j++) {
1862 min = gst_caps_get_structure_unchecked (src, j);
1863 min_f = gst_caps_get_features_unchecked (src, j);
1865 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1867 /* Same reason as above for ANY caps */
1868 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1870 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1871 gst_caps_features_is_equal (min_f, sub_f)) {
1874 if (gst_caps_structure_subtract (&list, min, sub)) {
1877 for (walk = list; walk; walk = g_slist_next (walk)) {
1878 gst_caps_append_structure_unchecked (dest,
1879 (GstStructure *) walk->data,
1880 gst_caps_features_copy_conditional (min_f));
1882 g_slist_free (list);
1884 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1885 gst_caps_features_copy_conditional (min_f));
1888 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1889 gst_caps_features_copy_conditional (min_f));
1893 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1894 gst_caps_unref (src);
1899 gst_caps_unref (src);
1900 dest = gst_caps_simplify (dest);
1905 /* normalize/simplify operations */
1907 typedef struct _NormalizeForeach
1910 GstStructure *structure;
1911 GstCapsFeatures *features;
1915 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1917 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1921 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1922 guint len = gst_value_list_get_size (value);
1924 for (i = 1; i < len; i++) {
1925 const GValue *v = gst_value_list_get_value (value, i);
1926 GstStructure *structure = gst_structure_copy (nf->structure);
1928 gst_structure_id_set_value (structure, field_id, v);
1929 gst_caps_append_structure_unchecked (nf->caps, structure,
1930 gst_caps_features_copy_conditional (nf->features));
1933 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1934 gst_structure_id_take_value (nf->structure, field_id, &val);
1942 * gst_caps_normalize:
1943 * @caps: (transfer full): a #GstCaps to normalize
1945 * Returns a #GstCaps that represents the same set of formats as
1946 * @caps, but contains no lists. Each list is expanded into separate
1949 * This function takes ownership of @caps and will call gst_caps_make_writable()
1950 * on it so you must not use @caps afterwards unless you keep an additional
1951 * reference to it with gst_caps_ref().
1953 * Returns: (transfer full): the normalized #GstCaps
1956 gst_caps_normalize (GstCaps * caps)
1958 NormalizeForeach nf;
1961 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1963 caps = gst_caps_make_writable (caps);
1966 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1967 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1968 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1969 while (!gst_structure_foreach (nf.structure,
1970 gst_caps_normalize_foreach, &nf));
1977 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1980 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1981 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1983 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1984 So what's the best way? */
1985 ret = strcmp (gst_structure_get_name (struct1),
1986 gst_structure_get_name (struct2));
1991 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1998 GstStructure *compare;
2002 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
2005 UnionField *u = user_data;
2006 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
2010 g_value_unset (&u->value);
2014 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
2018 g_value_unset (&u->value);
2023 gst_value_union (&u->value, val, value);
2029 gst_caps_structure_simplify (GstStructure ** result,
2030 GstStructure * simplify, GstStructure * compare)
2033 UnionField field = { 0, {0,}, NULL };
2035 /* try to subtract to get a real subset */
2036 if (gst_caps_structure_subtract (&list, simplify, compare)) {
2037 if (list == NULL) { /* no result */
2040 } else if (list->next == NULL) { /* one result */
2041 *result = list->data;
2042 g_slist_free (list);
2044 } else { /* multiple results */
2045 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
2046 g_slist_free (list);
2051 /* try to union both structs */
2052 field.compare = compare;
2053 if (gst_structure_foreach (simplify,
2054 gst_caps_structure_figure_out_union, &field)) {
2055 gboolean ret = FALSE;
2057 /* now we know all of simplify's fields are the same in compare
2058 * but at most one field: field.name */
2059 if (G_IS_VALUE (&field.value)) {
2060 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
2061 gst_structure_id_take_value (compare, field.name, &field.value);
2065 g_value_unset (&field.value);
2068 if (gst_structure_n_fields (simplify) <=
2069 gst_structure_n_fields (compare)) {
2070 /* compare is just more specific, will be optimized away later */
2071 /* FIXME: do this here? */
2072 GST_LOG ("found a case that will be optimized later.");
2074 gchar *one = gst_structure_to_string (simplify);
2075 gchar *two = gst_structure_to_string (compare);
2078 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2090 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2091 GstStructure * new, gint i)
2093 gst_structure_set_parent_refcount (old, NULL);
2094 gst_structure_free (old);
2095 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2096 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2100 * gst_caps_simplify:
2101 * @caps: (transfer full): a #GstCaps to simplify
2103 * Converts the given @caps into a representation that represents the
2104 * same set of formats, but in a simpler form. Component structures that are
2105 * identical are merged. Component structures that have values that can be
2106 * merged are also merged.
2108 * This function takes ownership of @caps and will call gst_caps_make_writable()
2109 * on it if necessary, so you must not use @caps afterwards unless you keep an
2110 * additional reference to it with gst_caps_ref().
2112 * This method does not preserve the original order of @caps.
2114 * Returns: (transfer full): The simplified caps.
2117 gst_caps_simplify (GstCaps * caps)
2119 GstStructure *simplify, *compare, *result = NULL;
2120 GstCapsFeatures *simplify_f, *compare_f;
2123 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2125 start = GST_CAPS_LEN (caps) - 1;
2126 /* one caps, already as simple as can be */
2130 caps = gst_caps_make_writable (caps);
2132 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2134 for (i = start; i >= 0; i--) {
2135 simplify = gst_caps_get_structure_unchecked (caps, i);
2136 simplify_f = gst_caps_get_features_unchecked (caps, i);
2138 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2139 compare = gst_caps_get_structure_unchecked (caps, start);
2140 compare_f = gst_caps_get_features_unchecked (caps, start);
2142 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2143 if (gst_structure_get_name_id (simplify) !=
2144 gst_structure_get_name_id (compare) ||
2145 !gst_caps_features_is_equal (simplify_f, compare_f))
2147 for (j = start; j >= 0; j--) {
2150 compare = gst_caps_get_structure_unchecked (caps, j);
2151 compare_f = gst_caps_get_features_unchecked (caps, j);
2153 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2154 if (gst_structure_get_name_id (simplify) !=
2155 gst_structure_get_name_id (compare) ||
2156 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2159 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2161 gst_caps_switch_structures (caps, simplify, result, i);
2164 gst_caps_remove_structure (caps, i);
2176 * @caps: (transfer full): a #GstCaps to fixate
2178 * Modifies the given @caps into a representation with only fixed
2179 * values. First the caps will be truncated and then the first structure will be
2180 * fixated with gst_structure_fixate().
2182 * This function takes ownership of @caps and will call gst_caps_make_writable()
2183 * on it so you must not use @caps afterwards unless you keep an additional
2184 * reference to it with gst_caps_ref().
2186 * Returns: (transfer full): the fixated caps
2189 gst_caps_fixate (GstCaps * caps)
2194 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2196 /* default fixation */
2197 caps = gst_caps_truncate (caps);
2198 caps = gst_caps_make_writable (caps);
2199 s = gst_caps_get_structure (caps, 0);
2200 gst_structure_fixate (s);
2202 /* Set features to sysmem if they're still ANY */
2203 f = gst_caps_get_features_unchecked (caps, 0);
2204 if (f && gst_caps_features_is_any (f)) {
2205 f = gst_caps_features_new_empty ();
2206 gst_caps_set_features (caps, 0, f);
2215 * gst_caps_to_string:
2218 * Converts @caps to a string representation. This string representation
2219 * can be converted back to a #GstCaps by gst_caps_from_string().
2221 * For debugging purposes its easier to do something like this:
2222 * |[<!-- language="C" -->
2223 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2225 * This prints the caps in human readable form.
2227 * The current implementation of serialization will lead to unexpected results
2228 * when there are nested #GstCaps / #GstStructure deeper than one level.
2230 * Returns: (transfer full): a newly allocated string representing @caps.
2233 gst_caps_to_string (const GstCaps * caps)
2235 guint i, slen, clen;
2238 /* NOTE: This function is potentially called by the debug system,
2239 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2240 * should be careful to avoid recursion. This includes any functions
2241 * called by gst_caps_to_string. In particular, calls should
2242 * not use the GST_PTR_FORMAT extension. */
2245 return g_strdup ("NULL");
2247 if (CAPS_IS_ANY (caps)) {
2248 return g_strdup ("ANY");
2250 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2251 return g_strdup ("EMPTY");
2254 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2256 clen = GST_CAPS_LEN (caps);
2257 for (i = 0; i < clen; i++) {
2261 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2263 f = gst_caps_get_features_unchecked (caps, i);
2265 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2268 s = g_string_sized_new (slen);
2269 for (i = 0; i < clen; i++) {
2270 GstStructure *structure;
2271 GstCapsFeatures *features;
2274 /* ';' is now added by gst_structure_to_string */
2275 g_string_append_c (s, ' ');
2278 structure = gst_caps_get_structure_unchecked (caps, i);
2279 features = gst_caps_get_features_unchecked (caps, i);
2281 g_string_append (s, gst_structure_get_name (structure));
2282 if (features && (gst_caps_features_is_any (features)
2283 || !gst_caps_features_is_equal (features,
2284 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2285 g_string_append_c (s, '(');
2286 priv_gst_caps_features_append_to_gstring (features, s);
2287 g_string_append_c (s, ')');
2289 priv_gst_structure_append_to_gstring (structure, s);
2291 if (s->len && s->str[s->len - 1] == ';') {
2292 /* remove latest ';' */
2293 s->str[--s->len] = '\0';
2295 return g_string_free (s, FALSE);
2299 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2301 GstStructure *structure;
2302 gchar *s, *copy, *end, *next, save;
2304 if (strcmp ("ANY", string) == 0) {
2305 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2309 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2313 copy = s = g_strdup (string);
2315 GstCapsFeatures *features = NULL;
2317 while (g_ascii_isspace (*s))
2323 if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2330 structure = gst_structure_new_empty (s);
2333 if (structure == NULL) {
2351 } else if (*end == ')') {
2360 features = gst_caps_features_from_string (s);
2362 gst_structure_free (structure);
2376 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2377 gst_structure_free (structure);
2379 gst_caps_features_free (features);
2385 gst_caps_append_structure_unchecked (caps, structure, features);
2397 * gst_caps_from_string:
2398 * @string: a string to convert to #GstCaps
2400 * Converts @caps from a string representation.
2402 * The current implementation of serialization will lead to unexpected results
2403 * when there are nested #GstCaps / #GstStructure deeper than one level.
2405 * Returns: (transfer full) (nullable): a newly allocated #GstCaps
2408 gst_caps_from_string (const gchar * string)
2412 g_return_val_if_fail (string, FALSE);
2414 caps = gst_caps_new_empty ();
2415 if (gst_caps_from_string_inplace (caps, string)) {
2418 gst_caps_unref (caps);
2424 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2426 g_return_if_fail (G_IS_VALUE (src_value));
2427 g_return_if_fail (G_IS_VALUE (dest_value));
2428 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2429 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2430 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2432 g_value_take_string (dest_value,
2433 gst_caps_to_string (gst_value_get_caps (src_value)));
2439 * @func: (scope call): a function to call for each field
2440 * @user_data: (closure): private data
2442 * Calls the provided function once for each structure and caps feature in the
2443 * #GstCaps. The function must not modify the fields.
2444 * Also see gst_caps_map_in_place() and gst_caps_filter_and_map_in_place().
2446 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2452 gst_caps_foreach (const GstCaps * caps, GstCapsForeachFunc func,
2456 GstCapsFeatures *features;
2457 GstStructure *structure;
2460 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2461 g_return_val_if_fail (func != NULL, FALSE);
2463 n = GST_CAPS_LEN (caps);
2465 for (i = 0; i < n; i++) {
2466 features = gst_caps_get_features_unchecked (caps, i);
2467 structure = gst_caps_get_structure_unchecked (caps, i);
2469 ret = func (features, structure, user_data);
2470 if (G_UNLIKELY (!ret))
2478 * gst_caps_map_in_place:
2480 * @func: (scope call): a function to call for each field
2481 * @user_data: (closure): private data
2483 * Calls the provided function once for each structure and caps feature in the
2484 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify but not
2485 * delete the structures and features. The caps must be mutable.
2487 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2493 gst_caps_map_in_place (GstCaps * caps, GstCapsMapFunc func, gpointer user_data)
2496 GstCapsFeatures *features;
2497 GstStructure *structure;
2500 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2501 g_return_val_if_fail (gst_caps_is_writable (caps), FALSE);
2502 g_return_val_if_fail (func != NULL, FALSE);
2504 n = GST_CAPS_LEN (caps);
2506 for (i = 0; i < n; i++) {
2507 features = gst_caps_get_features_unchecked (caps, i);
2508 structure = gst_caps_get_structure_unchecked (caps, i);
2510 /* Provide sysmem features if there are none yet */
2513 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2514 gst_caps_set_features (caps, i, features);
2517 ret = func (features, structure, user_data);
2518 if (G_UNLIKELY (!ret))
2526 * gst_caps_filter_and_map_in_place:
2528 * @func: (scope call): a function to call for each field
2529 * @user_data: (closure): private data
2531 * Calls the provided function once for each structure and caps feature in the
2532 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify the
2533 * structure and features. In contrast to gst_caps_filter_and_map_in_place(),
2534 * the structure and features are removed from the caps if %FALSE is returned
2535 * from the function.
2536 * The caps must be mutable.
2541 gst_caps_filter_and_map_in_place (GstCaps * caps, GstCapsFilterMapFunc func,
2545 GstCapsFeatures *features;
2546 GstStructure *structure;
2549 g_return_if_fail (GST_IS_CAPS (caps));
2550 g_return_if_fail (gst_caps_is_writable (caps));
2551 g_return_if_fail (func != NULL);
2553 n = GST_CAPS_LEN (caps);
2555 for (i = 0; i < n;) {
2556 features = gst_caps_get_features_unchecked (caps, i);
2557 structure = gst_caps_get_structure_unchecked (caps, i);
2559 /* Provide sysmem features if there are none yet */
2562 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2563 gst_caps_set_features (caps, i, features);
2566 ret = func (features, structure, user_data);
2568 GST_CAPS_ARRAY (caps) = g_array_remove_index (GST_CAPS_ARRAY (caps), i);
2570 gst_structure_set_parent_refcount (structure, NULL);
2571 gst_structure_free (structure);
2573 gst_caps_features_set_parent_refcount (features, NULL);
2574 gst_caps_features_free (features);
2577 n = GST_CAPS_LEN (caps);
2586 * @caps: a #GstCaps.
2588 * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
2589 * refcount of 1, owned by the caller. The structures are copied as well.
2591 * Note that this function is the semantic equivalent of a gst_caps_ref()
2592 * followed by a gst_caps_make_writable(). If you only want to hold on to a
2593 * reference to the data, you should use gst_caps_ref().
2595 * When you are finished with the caps, call gst_caps_unref() on it.
2597 * Returns: the new #GstCaps
2599 GstCaps *(gst_caps_copy) (const GstCaps * caps)
2601 return GST_CAPS (gst_mini_object_copy (GST_MINI_OBJECT_CAST (caps)));