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);
937 * @caps: the #GstCaps to copy
938 * @nth: the nth structure to copy
940 * Creates a new #GstCaps and appends a copy of the nth structure
941 * contained in @caps.
943 * Returns: (transfer full): the new #GstCaps
946 gst_caps_copy_nth (const GstCaps * caps, guint nth)
949 GstStructure *structure;
950 GstCapsFeatures *features;
952 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
954 newcaps = gst_caps_new_empty ();
955 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
957 if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
958 structure = gst_caps_get_structure_unchecked (caps, nth);
959 features = gst_caps_get_features_unchecked (caps, nth);
960 gst_caps_append_structure_unchecked (newcaps,
961 gst_structure_copy (structure),
962 gst_caps_features_copy_conditional (features));
970 * @caps: (transfer full): the #GstCaps to truncate
972 * Discard all but the first structure from @caps. Useful when
975 * This function takes ownership of @caps and will call gst_caps_make_writable()
976 * on it if necessary, so you must not use @caps afterwards unless you keep an
977 * additional reference to it with gst_caps_ref().
979 * Returns: (transfer full): truncated caps
982 gst_caps_truncate (GstCaps * caps)
986 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
988 i = GST_CAPS_LEN (caps) - 1;
992 caps = gst_caps_make_writable (caps);
994 gst_caps_remove_structure (caps, i--);
1000 * gst_caps_set_value:
1001 * @caps: a writable caps
1002 * @field: name of the field to set
1003 * @value: value to set the field to
1005 * Sets the given @field on all structures of @caps to the given @value.
1006 * This is a convenience function for calling gst_structure_set_value() on
1007 * all structures of @caps.
1010 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
1014 g_return_if_fail (GST_IS_CAPS (caps));
1015 g_return_if_fail (IS_WRITABLE (caps));
1016 g_return_if_fail (field != NULL);
1017 g_return_if_fail (G_IS_VALUE (value));
1019 len = GST_CAPS_LEN (caps);
1020 for (i = 0; i < len; i++) {
1021 GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
1022 gst_structure_set_value (structure, field, value);
1027 * gst_caps_set_simple_valist:
1028 * @caps: the #GstCaps to set
1029 * @field: first field to set
1030 * @varargs: additional parameters
1032 * Sets fields in a #GstCaps. The arguments must be passed in the same
1033 * manner as gst_structure_set(), and be %NULL-terminated.
1036 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
1038 GValue value = { 0, };
1040 g_return_if_fail (GST_IS_CAPS (caps));
1041 g_return_if_fail (IS_WRITABLE (caps));
1047 type = va_arg (varargs, GType);
1049 G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1050 if (G_UNLIKELY (err)) {
1051 g_critical ("%s", err);
1055 gst_caps_set_value (caps, field, &value);
1057 g_value_unset (&value);
1059 field = va_arg (varargs, const gchar *);
1064 * gst_caps_set_simple:
1065 * @caps: the #GstCaps to set
1066 * @field: first field to set
1067 * @...: additional parameters
1069 * Sets fields in a #GstCaps. The arguments must be passed in the same
1070 * manner as gst_structure_set(), and be %NULL-terminated.
1073 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1077 g_return_if_fail (GST_IS_CAPS (caps));
1078 g_return_if_fail (IS_WRITABLE (caps));
1080 va_start (var_args, field);
1081 gst_caps_set_simple_valist (caps, field, var_args);
1089 * @caps: the #GstCaps to test
1091 * Determines if @caps represents any media format.
1093 * Returns: %TRUE if @caps represents any format.
1096 gst_caps_is_any (const GstCaps * caps)
1098 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1100 return (CAPS_IS_ANY (caps));
1104 * gst_caps_is_empty:
1105 * @caps: the #GstCaps to test
1107 * Determines if @caps represents no media formats.
1109 * Returns: %TRUE if @caps represents no formats.
1112 gst_caps_is_empty (const GstCaps * caps)
1114 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1116 if (CAPS_IS_ANY (caps))
1119 return CAPS_IS_EMPTY_SIMPLE (caps);
1123 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1126 return gst_value_is_fixed (value);
1130 * gst_caps_is_fixed:
1131 * @caps: the #GstCaps to test
1133 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1134 * one structure, and each field in the structure describes a fixed type.
1135 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1137 * Returns: %TRUE if @caps is fixed
1140 gst_caps_is_fixed (const GstCaps * caps)
1142 GstStructure *structure;
1143 GstCapsFeatures *features;
1145 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1147 if (GST_CAPS_LEN (caps) != 1)
1150 features = gst_caps_get_features_unchecked (caps, 0);
1151 if (features && gst_caps_features_is_any (features))
1154 structure = gst_caps_get_structure_unchecked (caps, 0);
1156 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1160 * gst_caps_is_equal_fixed:
1161 * @caps1: the #GstCaps to test
1162 * @caps2: the #GstCaps to test
1164 * Tests if two #GstCaps are equal. This function only works on fixed
1167 * Returns: %TRUE if the arguments represent the same format
1170 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1172 GstStructure *struct1, *struct2;
1173 GstCapsFeatures *features1, *features2;
1175 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1176 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1178 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1179 features1 = gst_caps_get_features_unchecked (caps1, 0);
1181 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1182 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1183 features2 = gst_caps_get_features_unchecked (caps2, 0);
1185 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1187 return gst_structure_is_equal (struct1, struct2) &&
1188 gst_caps_features_is_equal (features1, features2);
1192 * gst_caps_is_always_compatible:
1193 * @caps1: the #GstCaps to test
1194 * @caps2: the #GstCaps to test
1196 * A given #GstCaps structure is always compatible with another if
1197 * every media format that is in the first is also contained in the
1198 * second. That is, @caps1 is a subset of @caps2.
1200 * Returns: %TRUE if @caps1 is a subset of @caps2.
1203 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1205 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1206 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1208 return gst_caps_is_subset (caps1, caps2);
1212 * gst_caps_is_subset:
1213 * @subset: a #GstCaps
1214 * @superset: a potentially greater #GstCaps
1216 * Checks if all caps represented by @subset are also represented by @superset.
1218 * Returns: %TRUE if @subset is a subset of @superset
1221 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1223 GstStructure *s1, *s2;
1224 GstCapsFeatures *f1, *f2;
1225 gboolean ret = TRUE;
1228 g_return_val_if_fail (subset != NULL, FALSE);
1229 g_return_val_if_fail (superset != NULL, FALSE);
1231 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1233 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1236 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1237 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1238 s1 = gst_caps_get_structure_unchecked (subset, i);
1239 f1 = gst_caps_get_features_unchecked (subset, i);
1241 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1242 s2 = gst_caps_get_structure_unchecked (superset, j);
1243 f2 = gst_caps_get_features_unchecked (superset, j);
1245 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1246 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1247 gst_caps_features_is_equal (f1, f2)
1248 && gst_structure_is_subset (s1, s2)) {
1249 /* If we found a superset, continue with the next
1250 * subset structure */
1254 /* If we found no superset for this subset structure
1255 * we return FALSE immediately */
1266 * gst_caps_is_subset_structure:
1268 * @structure: a potential #GstStructure subset of @caps
1270 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1271 * for more information.
1273 * Returns: %TRUE if @structure is a subset of @caps
1276 gst_caps_is_subset_structure (const GstCaps * caps,
1277 const GstStructure * structure)
1282 g_return_val_if_fail (caps != NULL, FALSE);
1283 g_return_val_if_fail (structure != NULL, FALSE);
1285 if (CAPS_IS_ANY (caps))
1287 if (CAPS_IS_EMPTY (caps))
1290 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1291 s = gst_caps_get_structure_unchecked (caps, i);
1292 if (gst_structure_is_subset (structure, s)) {
1293 /* If we found a superset return TRUE */
1302 * gst_caps_is_subset_structure_full:
1304 * @structure: a potential #GstStructure subset of @caps
1305 * @features: (allow-none): a #GstCapsFeatures for @structure
1307 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1308 * for more information.
1310 * Returns: %TRUE if @structure is a subset of @caps
1315 gst_caps_is_subset_structure_full (const GstCaps * caps,
1316 const GstStructure * structure, const GstCapsFeatures * features)
1322 g_return_val_if_fail (caps != NULL, FALSE);
1323 g_return_val_if_fail (structure != NULL, FALSE);
1325 if (CAPS_IS_ANY (caps))
1327 if (CAPS_IS_EMPTY (caps))
1331 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1333 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1334 s = gst_caps_get_structure_unchecked (caps, i);
1335 f = gst_caps_get_features_unchecked (caps, i);
1337 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1338 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1339 && gst_caps_features_is_equal (features, f)
1340 && gst_structure_is_subset (structure, s)) {
1341 /* If we found a superset return TRUE */
1350 * gst_caps_is_equal:
1351 * @caps1: a #GstCaps
1352 * @caps2: another #GstCaps
1354 * Checks if the given caps represent the same set of caps.
1356 * Returns: %TRUE if both caps are equal.
1359 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1361 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1362 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1364 if (G_UNLIKELY (caps1 == caps2))
1367 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1368 return gst_caps_is_equal_fixed (caps1, caps2);
1370 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1374 * gst_caps_is_strictly_equal:
1375 * @caps1: a #GstCaps
1376 * @caps2: another #GstCaps
1378 * Checks if the given caps are exactly the same set of caps.
1380 * Returns: %TRUE if both caps are strictly equal.
1383 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1386 GstStructure *s1, *s2;
1387 GstCapsFeatures *f1, *f2;
1389 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1390 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1392 if (G_UNLIKELY (caps1 == caps2))
1395 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1398 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1399 s1 = gst_caps_get_structure_unchecked (caps1, i);
1400 f1 = gst_caps_get_features_unchecked (caps1, i);
1402 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1403 s2 = gst_caps_get_structure_unchecked (caps2, i);
1404 f2 = gst_caps_get_features_unchecked (caps2, i);
1406 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1408 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1409 !gst_caps_features_is_equal (f1, f2) ||
1410 !gst_structure_is_equal (s1, s2))
1417 /* intersect operation */
1420 * gst_caps_can_intersect:
1421 * @caps1: a #GstCaps to intersect
1422 * @caps2: a #GstCaps to intersect
1424 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1427 * Returns: %TRUE if intersection would be not empty
1430 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1432 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1433 guint j, k, len1, len2;
1434 GstStructure *struct1;
1435 GstStructure *struct2;
1436 GstCapsFeatures *features1;
1437 GstCapsFeatures *features2;
1439 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1440 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1442 /* caps are exactly the same pointers */
1443 if (G_UNLIKELY (caps1 == caps2))
1446 /* empty caps on either side, return empty */
1447 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1450 /* one of the caps is any */
1451 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1454 /* run zigzag on top line then right line, this preserves the caps order
1455 * much better than a simple loop.
1457 * This algorithm zigzags over the caps structures as demonstrated in
1458 * the following matrix:
1461 * +------------- total distance: +-------------
1462 * | 1 2 4 7 0 | 0 1 2 3
1463 * caps2 | 3 5 8 10 1 | 1 2 3 4
1464 * | 6 9 11 12 2 | 2 3 4 5
1466 * First we iterate over the caps1 structures (top line) intersecting
1467 * the structures diagonally down, then we iterate over the caps2
1468 * structures. The result is that the intersections are ordered based on the
1469 * sum of the indexes in the list.
1471 len1 = GST_CAPS_LEN (caps1);
1472 len2 = GST_CAPS_LEN (caps2);
1473 for (i = 0; i < len1 + len2 - 1; i++) {
1474 /* superset index goes from 0 to superset->structs->len-1 */
1475 j = MIN (i, len1 - 1);
1476 /* subset index stays 0 until i reaches superset->structs->len, then it
1477 * counts up from 1 to subset->structs->len - 1 */
1478 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1479 /* now run the diagonal line, end condition is the left or bottom
1482 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1483 features1 = gst_caps_get_features_unchecked (caps1, j);
1485 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1486 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1487 features2 = gst_caps_get_features_unchecked (caps2, k);
1489 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1490 if (gst_caps_features_is_equal (features1, features2) &&
1491 gst_structure_can_intersect (struct1, struct2)) {
1494 /* move down left */
1496 if (G_UNLIKELY (j == 0))
1497 break; /* so we don't roll back to G_MAXUINT */
1506 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1508 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1509 guint j, k, len1, len2;
1510 GstStructure *struct1;
1511 GstStructure *struct2;
1512 GstCapsFeatures *features1;
1513 GstCapsFeatures *features2;
1515 GstStructure *istruct;
1517 /* caps are exactly the same pointers, just copy one caps */
1518 if (G_UNLIKELY (caps1 == caps2))
1519 return gst_caps_ref (caps1);
1521 /* empty caps on either side, return empty */
1522 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1523 return gst_caps_ref (GST_CAPS_NONE);
1525 /* one of the caps is any, just copy the other caps */
1526 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1527 return gst_caps_ref (caps2);
1529 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1530 return gst_caps_ref (caps1);
1532 dest = gst_caps_new_empty ();
1533 /* run zigzag on top line then right line, this preserves the caps order
1534 * much better than a simple loop.
1536 * This algorithm zigzags over the caps structures as demonstrated in
1537 * the following matrix:
1545 * First we iterate over the caps1 structures (top line) intersecting
1546 * the structures diagonally down, then we iterate over the caps2
1549 len1 = GST_CAPS_LEN (caps1);
1550 len2 = GST_CAPS_LEN (caps2);
1551 for (i = 0; i < len1 + len2 - 1; i++) {
1552 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1553 j = MIN (i, len1 - 1);
1554 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1555 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1556 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1557 /* now run the diagonal line, end condition is the left or bottom
1560 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1561 features1 = gst_caps_get_features_unchecked (caps1, j);
1563 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1564 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1565 features2 = gst_caps_get_features_unchecked (caps2, k);
1567 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1568 if (gst_caps_features_is_equal (features1, features2)) {
1569 istruct = gst_structure_intersect (struct1, struct2);
1571 if (gst_caps_features_is_any (features1))
1573 gst_caps_merge_structure_full (dest, istruct,
1574 gst_caps_features_copy_conditional (features2));
1577 gst_caps_merge_structure_full (dest, istruct,
1578 gst_caps_features_copy_conditional (features1));
1581 /* move down left */
1583 if (G_UNLIKELY (j == 0))
1584 break; /* so we don't roll back to G_MAXUINT */
1592 * gst_caps_intersect_first:
1593 * @caps1: a #GstCaps to intersect
1594 * @caps2: a #GstCaps to intersect
1596 * Creates a new #GstCaps that contains all the formats that are common
1597 * to both @caps1 and @caps2.
1599 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1600 * fashion as @caps1.
1602 * Returns: (transfer full): the new #GstCaps
1605 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1608 guint j, len1, len2;
1609 GstStructure *struct1;
1610 GstStructure *struct2;
1611 GstCapsFeatures *features1;
1612 GstCapsFeatures *features2;
1614 GstStructure *istruct;
1616 /* caps are exactly the same pointers, just copy one caps */
1617 if (G_UNLIKELY (caps1 == caps2))
1618 return gst_caps_ref (caps1);
1620 /* empty caps on either side, return empty */
1621 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1622 return gst_caps_ref (GST_CAPS_NONE);
1624 /* one of the caps is any, just copy the other caps */
1625 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1626 return gst_caps_ref (caps2);
1628 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1629 return gst_caps_ref (caps1);
1631 dest = gst_caps_new_empty ();
1632 len1 = GST_CAPS_LEN (caps1);
1633 len2 = GST_CAPS_LEN (caps2);
1634 for (i = 0; i < len1; i++) {
1635 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1636 features1 = gst_caps_get_features_unchecked (caps1, i);
1638 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1639 for (j = 0; j < len2; j++) {
1640 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1641 features2 = gst_caps_get_features_unchecked (caps2, j);
1643 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1644 if (gst_caps_features_is_equal (features1, features2)) {
1645 istruct = gst_structure_intersect (struct1, struct2);
1647 if (gst_caps_features_is_any (features1))
1649 gst_caps_merge_structure_full (dest, istruct,
1650 gst_caps_features_copy_conditional (features2));
1653 gst_caps_merge_structure_full (dest, istruct,
1654 gst_caps_features_copy_conditional (features1));
1664 * gst_caps_intersect_full:
1665 * @caps1: a #GstCaps to intersect
1666 * @caps2: a #GstCaps to intersect
1667 * @mode: The intersection algorithm/mode to use
1669 * Creates a new #GstCaps that contains all the formats that are common
1670 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1673 * Returns: (transfer full): the new #GstCaps
1676 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1677 GstCapsIntersectMode mode)
1679 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1680 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1683 case GST_CAPS_INTERSECT_FIRST:
1684 return gst_caps_intersect_first (caps1, caps2);
1686 g_warning ("Unknown caps intersect mode: %d", mode);
1688 case GST_CAPS_INTERSECT_ZIG_ZAG:
1689 return gst_caps_intersect_zig_zag (caps1, caps2);
1694 * gst_caps_intersect:
1695 * @caps1: a #GstCaps to intersect
1696 * @caps2: a #GstCaps to intersect
1698 * Creates a new #GstCaps that contains all the formats that are common
1699 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1701 * Returns: (transfer full): the new #GstCaps
1704 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1706 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1709 /* subtract operation */
1713 const GstStructure *subtract_from;
1718 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1721 SubtractionEntry *e = user_data;
1722 GValue subtraction = { 0, };
1723 const GValue *other;
1724 GstStructure *structure;
1726 other = gst_structure_id_get_value (e->subtract_from, field_id);
1732 if (!gst_value_subtract (&subtraction, other, value))
1735 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1736 g_value_unset (&subtraction);
1739 structure = gst_structure_copy (e->subtract_from);
1740 gst_structure_id_take_value (structure, field_id, &subtraction);
1741 e->put_into = g_slist_prepend (e->put_into, structure);
1747 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1748 const GstStructure * subtrahend)
1753 e.subtract_from = minuend;
1755 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1756 gst_caps_structure_subtract_field, &e);
1763 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1764 gst_structure_free (walk->data);
1766 g_slist_free (e.put_into);
1773 * gst_caps_subtract:
1774 * @minuend: #GstCaps to subtract from
1775 * @subtrahend: #GstCaps to subtract
1777 * Subtracts the @subtrahend from the @minuend.
1778 * > This function does not work reliably if optional properties for caps
1779 * > are included on one caps and omitted on the other.
1781 * Returns: (transfer full): the resulting caps
1784 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1789 GstCapsFeatures *min_f, *sub_f;
1790 GstCaps *dest = NULL, *src;
1792 g_return_val_if_fail (minuend != NULL, NULL);
1793 g_return_val_if_fail (subtrahend != NULL, NULL);
1795 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1796 return gst_caps_new_empty ();
1799 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1800 return gst_caps_ref (minuend);
1802 /* FIXME: Do we want this here or above?
1803 The reason we need this is that there is no definition about what
1804 ANY means for specific types, so it's not possible to reduce ANY partially
1805 You can only remove everything or nothing and that is done above.
1806 Note: there's a test that checks this behaviour. */
1808 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1809 sublen = GST_CAPS_LEN (subtrahend);
1810 g_assert (sublen > 0);
1812 src = _gst_caps_copy (minuend);
1813 for (i = 0; i < sublen; i++) {
1816 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1817 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1819 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1821 gst_caps_unref (src);
1824 dest = gst_caps_new_empty ();
1825 srclen = GST_CAPS_LEN (src);
1826 for (j = 0; j < srclen; j++) {
1827 min = gst_caps_get_structure_unchecked (src, j);
1828 min_f = gst_caps_get_features_unchecked (src, j);
1830 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1832 /* Same reason as above for ANY caps */
1833 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1835 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1836 gst_caps_features_is_equal (min_f, sub_f)) {
1839 if (gst_caps_structure_subtract (&list, min, sub)) {
1842 for (walk = list; walk; walk = g_slist_next (walk)) {
1843 gst_caps_append_structure_unchecked (dest,
1844 (GstStructure *) walk->data,
1845 gst_caps_features_copy_conditional (min_f));
1847 g_slist_free (list);
1849 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1850 gst_caps_features_copy_conditional (min_f));
1853 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1854 gst_caps_features_copy_conditional (min_f));
1858 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1859 gst_caps_unref (src);
1864 gst_caps_unref (src);
1865 dest = gst_caps_simplify (dest);
1870 /* normalize/simplify operations */
1872 typedef struct _NormalizeForeach
1875 GstStructure *structure;
1876 GstCapsFeatures *features;
1880 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1882 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1886 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1887 guint len = gst_value_list_get_size (value);
1889 for (i = 1; i < len; i++) {
1890 const GValue *v = gst_value_list_get_value (value, i);
1891 GstStructure *structure = gst_structure_copy (nf->structure);
1893 gst_structure_id_set_value (structure, field_id, v);
1894 gst_caps_append_structure_unchecked (nf->caps, structure,
1895 gst_caps_features_copy_conditional (nf->features));
1898 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1899 gst_structure_id_take_value (nf->structure, field_id, &val);
1907 * gst_caps_normalize:
1908 * @caps: (transfer full): a #GstCaps to normalize
1910 * Returns a #GstCaps that represents the same set of formats as
1911 * @caps, but contains no lists. Each list is expanded into separate
1914 * This function takes ownership of @caps and will call gst_caps_make_writable()
1915 * on it so you must not use @caps afterwards unless you keep an additional
1916 * reference to it with gst_caps_ref().
1918 * Returns: (transfer full): the normalized #GstCaps
1921 gst_caps_normalize (GstCaps * caps)
1923 NormalizeForeach nf;
1926 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1928 caps = gst_caps_make_writable (caps);
1931 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1932 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1933 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1934 while (!gst_structure_foreach (nf.structure,
1935 gst_caps_normalize_foreach, &nf));
1942 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1945 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1946 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1948 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1949 So what's the best way? */
1950 ret = strcmp (gst_structure_get_name (struct1),
1951 gst_structure_get_name (struct2));
1956 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1963 GstStructure *compare;
1967 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1970 UnionField *u = user_data;
1971 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1975 g_value_unset (&u->value);
1979 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1983 g_value_unset (&u->value);
1988 gst_value_union (&u->value, val, value);
1994 gst_caps_structure_simplify (GstStructure ** result,
1995 GstStructure * simplify, GstStructure * compare)
1998 UnionField field = { 0, {0,}, NULL };
2000 /* try to subtract to get a real subset */
2001 if (gst_caps_structure_subtract (&list, simplify, compare)) {
2002 if (list == NULL) { /* no result */
2005 } else if (list->next == NULL) { /* one result */
2006 *result = list->data;
2007 g_slist_free (list);
2009 } else { /* multiple results */
2010 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
2011 g_slist_free (list);
2016 /* try to union both structs */
2017 field.compare = compare;
2018 if (gst_structure_foreach (simplify,
2019 gst_caps_structure_figure_out_union, &field)) {
2020 gboolean ret = FALSE;
2022 /* now we know all of simplify's fields are the same in compare
2023 * but at most one field: field.name */
2024 if (G_IS_VALUE (&field.value)) {
2025 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
2026 gst_structure_id_take_value (compare, field.name, &field.value);
2030 g_value_unset (&field.value);
2033 if (gst_structure_n_fields (simplify) <=
2034 gst_structure_n_fields (compare)) {
2035 /* compare is just more specific, will be optimized away later */
2036 /* FIXME: do this here? */
2037 GST_LOG ("found a case that will be optimized later.");
2039 gchar *one = gst_structure_to_string (simplify);
2040 gchar *two = gst_structure_to_string (compare);
2043 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2055 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2056 GstStructure * new, gint i)
2058 gst_structure_set_parent_refcount (old, NULL);
2059 gst_structure_free (old);
2060 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2061 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2065 * gst_caps_simplify:
2066 * @caps: (transfer full): a #GstCaps to simplify
2068 * Converts the given @caps into a representation that represents the
2069 * same set of formats, but in a simpler form. Component structures that are
2070 * identical are merged. Component structures that have values that can be
2071 * merged are also merged.
2073 * This function takes ownership of @caps and will call gst_caps_make_writable()
2074 * on it if necessary, so you must not use @caps afterwards unless you keep an
2075 * additional reference to it with gst_caps_ref().
2077 * This method does not preserve the original order of @caps.
2079 * Returns: (transfer full): The simplified caps.
2082 gst_caps_simplify (GstCaps * caps)
2084 GstStructure *simplify, *compare, *result = NULL;
2085 GstCapsFeatures *simplify_f, *compare_f;
2088 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2090 start = GST_CAPS_LEN (caps) - 1;
2091 /* one caps, already as simple as can be */
2095 caps = gst_caps_make_writable (caps);
2097 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2099 for (i = start; i >= 0; i--) {
2100 simplify = gst_caps_get_structure_unchecked (caps, i);
2101 simplify_f = gst_caps_get_features_unchecked (caps, i);
2103 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2104 compare = gst_caps_get_structure_unchecked (caps, start);
2105 compare_f = gst_caps_get_features_unchecked (caps, start);
2107 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2108 if (gst_structure_get_name_id (simplify) !=
2109 gst_structure_get_name_id (compare) ||
2110 !gst_caps_features_is_equal (simplify_f, compare_f))
2112 for (j = start; j >= 0; j--) {
2115 compare = gst_caps_get_structure_unchecked (caps, j);
2116 compare_f = gst_caps_get_features_unchecked (caps, j);
2118 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2119 if (gst_structure_get_name_id (simplify) !=
2120 gst_structure_get_name_id (compare) ||
2121 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2124 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2126 gst_caps_switch_structures (caps, simplify, result, i);
2129 gst_caps_remove_structure (caps, i);
2141 * @caps: (transfer full): a #GstCaps to fixate
2143 * Modifies the given @caps into a representation with only fixed
2144 * values. First the caps will be truncated and then the first structure will be
2145 * fixated with gst_structure_fixate().
2147 * This function takes ownership of @caps and will call gst_caps_make_writable()
2148 * on it so you must not use @caps afterwards unless you keep an additional
2149 * reference to it with gst_caps_ref().
2151 * Returns: (transfer full): the fixated caps
2154 gst_caps_fixate (GstCaps * caps)
2159 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2161 /* default fixation */
2162 caps = gst_caps_truncate (caps);
2163 caps = gst_caps_make_writable (caps);
2164 s = gst_caps_get_structure (caps, 0);
2165 gst_structure_fixate (s);
2167 /* Set features to sysmem if they're still ANY */
2168 f = gst_caps_get_features_unchecked (caps, 0);
2169 if (f && gst_caps_features_is_any (f)) {
2170 f = gst_caps_features_new_empty ();
2171 gst_caps_set_features (caps, 0, f);
2180 * gst_caps_to_string:
2183 * Converts @caps to a string representation. This string representation
2184 * can be converted back to a #GstCaps by gst_caps_from_string().
2186 * For debugging purposes its easier to do something like this:
2187 * |[<!-- language="C" -->
2188 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2190 * This prints the caps in human readable form.
2192 * The current implementation of serialization will lead to unexpected results
2193 * when there are nested #GstCaps / #GstStructure deeper than one level.
2195 * Returns: (transfer full): a newly allocated string representing @caps.
2198 gst_caps_to_string (const GstCaps * caps)
2200 guint i, slen, clen;
2203 /* NOTE: This function is potentially called by the debug system,
2204 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2205 * should be careful to avoid recursion. This includes any functions
2206 * called by gst_caps_to_string. In particular, calls should
2207 * not use the GST_PTR_FORMAT extension. */
2210 return g_strdup ("NULL");
2212 if (CAPS_IS_ANY (caps)) {
2213 return g_strdup ("ANY");
2215 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2216 return g_strdup ("EMPTY");
2219 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2221 clen = GST_CAPS_LEN (caps);
2222 for (i = 0; i < clen; i++) {
2226 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2228 f = gst_caps_get_features_unchecked (caps, i);
2230 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2233 s = g_string_sized_new (slen);
2234 for (i = 0; i < clen; i++) {
2235 GstStructure *structure;
2236 GstCapsFeatures *features;
2239 /* ';' is now added by gst_structure_to_string */
2240 g_string_append_c (s, ' ');
2243 structure = gst_caps_get_structure_unchecked (caps, i);
2244 features = gst_caps_get_features_unchecked (caps, i);
2246 g_string_append (s, gst_structure_get_name (structure));
2247 if (features && (gst_caps_features_is_any (features)
2248 || !gst_caps_features_is_equal (features,
2249 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2250 g_string_append_c (s, '(');
2251 priv_gst_caps_features_append_to_gstring (features, s);
2252 g_string_append_c (s, ')');
2254 priv_gst_structure_append_to_gstring (structure, s);
2256 if (s->len && s->str[s->len - 1] == ';') {
2257 /* remove latest ';' */
2258 s->str[--s->len] = '\0';
2260 return g_string_free (s, FALSE);
2264 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2266 GstStructure *structure;
2267 gchar *s, *copy, *end, *next, save;
2269 if (strcmp ("ANY", string) == 0) {
2270 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2274 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2278 copy = s = g_strdup (string);
2280 GstCapsFeatures *features = NULL;
2282 while (g_ascii_isspace (*s))
2288 if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2295 structure = gst_structure_new_empty (s);
2298 if (structure == NULL) {
2316 } else if (*end == ')') {
2325 features = gst_caps_features_from_string (s);
2327 gst_structure_free (structure);
2341 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2342 gst_structure_free (structure);
2344 gst_caps_features_free (features);
2350 gst_caps_append_structure_unchecked (caps, structure, features);
2362 * gst_caps_from_string:
2363 * @string: a string to convert to #GstCaps
2365 * Converts @caps from a string representation.
2367 * The current implementation of serialization will lead to unexpected results
2368 * when there are nested #GstCaps / #GstStructure deeper than one level.
2370 * Returns: (transfer full) (nullable): a newly allocated #GstCaps
2373 gst_caps_from_string (const gchar * string)
2377 g_return_val_if_fail (string, FALSE);
2379 caps = gst_caps_new_empty ();
2380 if (gst_caps_from_string_inplace (caps, string)) {
2383 gst_caps_unref (caps);
2389 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2391 g_return_if_fail (G_IS_VALUE (src_value));
2392 g_return_if_fail (G_IS_VALUE (dest_value));
2393 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2394 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2395 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2397 g_value_take_string (dest_value,
2398 gst_caps_to_string (gst_value_get_caps (src_value)));
2404 * @func: (scope call): a function to call for each field
2405 * @user_data: (closure): private data
2407 * Calls the provided function once for each structure and caps feature in the
2408 * #GstCaps. The function must not modify the fields.
2409 * Also see gst_caps_map_in_place() and gst_caps_filter_and_map_in_place().
2411 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2417 gst_caps_foreach (const GstCaps * caps, GstCapsForeachFunc func,
2421 GstCapsFeatures *features;
2422 GstStructure *structure;
2425 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2426 g_return_val_if_fail (func != NULL, FALSE);
2428 n = GST_CAPS_LEN (caps);
2430 for (i = 0; i < n; i++) {
2431 features = gst_caps_get_features_unchecked (caps, i);
2432 structure = gst_caps_get_structure_unchecked (caps, i);
2434 ret = func (features, structure, user_data);
2435 if (G_UNLIKELY (!ret))
2443 * gst_caps_map_in_place:
2445 * @func: (scope call): a function to call for each field
2446 * @user_data: (closure): private data
2448 * Calls the provided function once for each structure and caps feature in the
2449 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify but not
2450 * delete the structures and features. The caps must be mutable.
2452 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2458 gst_caps_map_in_place (GstCaps * caps, GstCapsMapFunc func, gpointer user_data)
2461 GstCapsFeatures *features;
2462 GstStructure *structure;
2465 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2466 g_return_val_if_fail (gst_caps_is_writable (caps), FALSE);
2467 g_return_val_if_fail (func != NULL, FALSE);
2469 n = GST_CAPS_LEN (caps);
2471 for (i = 0; i < n; i++) {
2472 features = gst_caps_get_features_unchecked (caps, i);
2473 structure = gst_caps_get_structure_unchecked (caps, i);
2475 /* Provide sysmem features if there are none yet */
2478 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2479 gst_caps_set_features (caps, i, features);
2482 ret = func (features, structure, user_data);
2483 if (G_UNLIKELY (!ret))
2491 * gst_caps_filter_and_map_in_place:
2493 * @func: (scope call): a function to call for each field
2494 * @user_data: (closure): private data
2496 * Calls the provided function once for each structure and caps feature in the
2497 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify the
2498 * structure and features. In contrast to gst_caps_filter_and_map_in_place(),
2499 * the structure and features are removed from the caps if %FALSE is returned
2500 * from the function.
2501 * The caps must be mutable.
2506 gst_caps_filter_and_map_in_place (GstCaps * caps, GstCapsFilterMapFunc func,
2510 GstCapsFeatures *features;
2511 GstStructure *structure;
2514 g_return_if_fail (GST_IS_CAPS (caps));
2515 g_return_if_fail (gst_caps_is_writable (caps));
2516 g_return_if_fail (func != NULL);
2518 n = GST_CAPS_LEN (caps);
2520 for (i = 0; i < n;) {
2521 features = gst_caps_get_features_unchecked (caps, i);
2522 structure = gst_caps_get_structure_unchecked (caps, i);
2524 /* Provide sysmem features if there are none yet */
2527 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2528 gst_caps_set_features (caps, i, features);
2531 ret = func (features, structure, user_data);
2533 GST_CAPS_ARRAY (caps) = g_array_remove_index (GST_CAPS_ARRAY (caps), i);
2535 gst_structure_set_parent_refcount (structure, NULL);
2536 gst_structure_free (structure);
2538 gst_caps_features_set_parent_refcount (features, NULL);
2539 gst_caps_features_free (features);
2542 n = GST_CAPS_LEN (caps);
2551 * @caps: a #GstCaps.
2553 * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
2554 * refcount of 1, owned by the caller. The structures are copied as well.
2556 * Note that this function is the semantic equivalent of a gst_caps_ref()
2557 * followed by a gst_caps_make_writable(). If you only want to hold on to a
2558 * reference to the data, you should use gst_caps_ref().
2560 * When you are finished with the caps, call gst_caps_unref() on it.
2562 * Returns: the new #GstCaps
2564 GstCaps *(gst_caps_copy) (const GstCaps * caps)
2566 return GST_CAPS (gst_mini_object_copy (GST_MINI_OBJECT_CAST (caps)));