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);
1056 gst_caps_set_value (caps, field, &value);
1058 g_value_unset (&value);
1060 field = va_arg (varargs, const gchar *);
1065 * gst_caps_set_simple:
1066 * @caps: the #GstCaps to set
1067 * @field: first field to set
1068 * @...: additional parameters
1070 * Sets fields in a #GstCaps. The arguments must be passed in the same
1071 * manner as gst_structure_set(), and be %NULL-terminated.
1074 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1078 g_return_if_fail (GST_IS_CAPS (caps));
1079 g_return_if_fail (IS_WRITABLE (caps));
1081 va_start (var_args, field);
1082 gst_caps_set_simple_valist (caps, field, var_args);
1090 * @caps: the #GstCaps to test
1092 * Determines if @caps represents any media format.
1094 * Returns: %TRUE if @caps represents any format.
1097 gst_caps_is_any (const GstCaps * caps)
1099 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1101 return (CAPS_IS_ANY (caps));
1105 * gst_caps_is_empty:
1106 * @caps: the #GstCaps to test
1108 * Determines if @caps represents no media formats.
1110 * Returns: %TRUE if @caps represents no formats.
1113 gst_caps_is_empty (const GstCaps * caps)
1115 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1117 if (CAPS_IS_ANY (caps))
1120 return CAPS_IS_EMPTY_SIMPLE (caps);
1124 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1127 return gst_value_is_fixed (value);
1131 * gst_caps_is_fixed:
1132 * @caps: the #GstCaps to test
1134 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1135 * one structure, and each field in the structure describes a fixed type.
1136 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1138 * Returns: %TRUE if @caps is fixed
1141 gst_caps_is_fixed (const GstCaps * caps)
1143 GstStructure *structure;
1144 GstCapsFeatures *features;
1146 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1148 if (GST_CAPS_LEN (caps) != 1)
1151 features = gst_caps_get_features_unchecked (caps, 0);
1152 if (features && gst_caps_features_is_any (features))
1155 structure = gst_caps_get_structure_unchecked (caps, 0);
1157 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1161 * gst_caps_is_equal_fixed:
1162 * @caps1: the #GstCaps to test
1163 * @caps2: the #GstCaps to test
1165 * Tests if two #GstCaps are equal. This function only works on fixed
1168 * Returns: %TRUE if the arguments represent the same format
1171 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1173 GstStructure *struct1, *struct2;
1174 GstCapsFeatures *features1, *features2;
1176 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1177 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1179 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1180 features1 = gst_caps_get_features_unchecked (caps1, 0);
1182 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1183 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1184 features2 = gst_caps_get_features_unchecked (caps2, 0);
1186 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1188 return gst_structure_is_equal (struct1, struct2) &&
1189 gst_caps_features_is_equal (features1, features2);
1193 * gst_caps_is_always_compatible:
1194 * @caps1: the #GstCaps to test
1195 * @caps2: the #GstCaps to test
1197 * A given #GstCaps structure is always compatible with another if
1198 * every media format that is in the first is also contained in the
1199 * second. That is, @caps1 is a subset of @caps2.
1201 * Returns: %TRUE if @caps1 is a subset of @caps2.
1204 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1206 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1207 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1209 return gst_caps_is_subset (caps1, caps2);
1213 * gst_caps_is_subset:
1214 * @subset: a #GstCaps
1215 * @superset: a potentially greater #GstCaps
1217 * Checks if all caps represented by @subset are also represented by @superset.
1219 * Returns: %TRUE if @subset is a subset of @superset
1222 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1224 GstStructure *s1, *s2;
1225 GstCapsFeatures *f1, *f2;
1226 gboolean ret = TRUE;
1229 g_return_val_if_fail (subset != NULL, FALSE);
1230 g_return_val_if_fail (superset != NULL, FALSE);
1232 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1234 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1237 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1238 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1239 s1 = gst_caps_get_structure_unchecked (subset, i);
1240 f1 = gst_caps_get_features_unchecked (subset, i);
1242 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1243 s2 = gst_caps_get_structure_unchecked (superset, j);
1244 f2 = gst_caps_get_features_unchecked (superset, j);
1246 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1247 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1248 gst_caps_features_is_equal (f1, f2)
1249 && gst_structure_is_subset (s1, s2)) {
1250 /* If we found a superset, continue with the next
1251 * subset structure */
1255 /* If we found no superset for this subset structure
1256 * we return FALSE immediately */
1267 * gst_caps_is_subset_structure:
1269 * @structure: a potential #GstStructure subset of @caps
1271 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1272 * for more information.
1274 * Returns: %TRUE if @structure is a subset of @caps
1277 gst_caps_is_subset_structure (const GstCaps * caps,
1278 const GstStructure * structure)
1283 g_return_val_if_fail (caps != NULL, FALSE);
1284 g_return_val_if_fail (structure != NULL, FALSE);
1286 if (CAPS_IS_ANY (caps))
1288 if (CAPS_IS_EMPTY (caps))
1291 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1292 s = gst_caps_get_structure_unchecked (caps, i);
1293 if (gst_structure_is_subset (structure, s)) {
1294 /* If we found a superset return TRUE */
1303 * gst_caps_is_subset_structure_full:
1305 * @structure: a potential #GstStructure subset of @caps
1306 * @features: (allow-none): a #GstCapsFeatures for @structure
1308 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1309 * for more information.
1311 * Returns: %TRUE if @structure is a subset of @caps
1316 gst_caps_is_subset_structure_full (const GstCaps * caps,
1317 const GstStructure * structure, const GstCapsFeatures * features)
1323 g_return_val_if_fail (caps != NULL, FALSE);
1324 g_return_val_if_fail (structure != NULL, FALSE);
1326 if (CAPS_IS_ANY (caps))
1328 if (CAPS_IS_EMPTY (caps))
1332 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1334 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1335 s = gst_caps_get_structure_unchecked (caps, i);
1336 f = gst_caps_get_features_unchecked (caps, i);
1338 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1339 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1340 && gst_caps_features_is_equal (features, f)
1341 && gst_structure_is_subset (structure, s)) {
1342 /* If we found a superset return TRUE */
1351 * gst_caps_is_equal:
1352 * @caps1: a #GstCaps
1353 * @caps2: another #GstCaps
1355 * Checks if the given caps represent the same set of caps.
1357 * Returns: %TRUE if both caps are equal.
1360 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1362 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1363 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1365 if (G_UNLIKELY (caps1 == caps2))
1368 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1369 return gst_caps_is_equal_fixed (caps1, caps2);
1371 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1375 * gst_caps_is_strictly_equal:
1376 * @caps1: a #GstCaps
1377 * @caps2: another #GstCaps
1379 * Checks if the given caps are exactly the same set of caps.
1381 * Returns: %TRUE if both caps are strictly equal.
1384 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1387 GstStructure *s1, *s2;
1388 GstCapsFeatures *f1, *f2;
1390 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1391 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1393 if (G_UNLIKELY (caps1 == caps2))
1396 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1399 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1400 s1 = gst_caps_get_structure_unchecked (caps1, i);
1401 f1 = gst_caps_get_features_unchecked (caps1, i);
1403 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1404 s2 = gst_caps_get_structure_unchecked (caps2, i);
1405 f2 = gst_caps_get_features_unchecked (caps2, i);
1407 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1409 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1410 !gst_caps_features_is_equal (f1, f2) ||
1411 !gst_structure_is_equal (s1, s2))
1418 /* intersect operation */
1421 * gst_caps_can_intersect:
1422 * @caps1: a #GstCaps to intersect
1423 * @caps2: a #GstCaps to intersect
1425 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1428 * Returns: %TRUE if intersection would be not empty
1431 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1433 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1434 guint j, k, len1, len2;
1435 GstStructure *struct1;
1436 GstStructure *struct2;
1437 GstCapsFeatures *features1;
1438 GstCapsFeatures *features2;
1440 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1441 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1443 /* caps are exactly the same pointers */
1444 if (G_UNLIKELY (caps1 == caps2))
1447 /* empty caps on either side, return empty */
1448 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1451 /* one of the caps is any */
1452 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1455 /* run zigzag on top line then right line, this preserves the caps order
1456 * much better than a simple loop.
1458 * This algorithm zigzags over the caps structures as demonstrated in
1459 * the following matrix:
1462 * +------------- total distance: +-------------
1463 * | 1 2 4 7 0 | 0 1 2 3
1464 * caps2 | 3 5 8 10 1 | 1 2 3 4
1465 * | 6 9 11 12 2 | 2 3 4 5
1467 * First we iterate over the caps1 structures (top line) intersecting
1468 * the structures diagonally down, then we iterate over the caps2
1469 * structures. The result is that the intersections are ordered based on the
1470 * sum of the indexes in the list.
1472 len1 = GST_CAPS_LEN (caps1);
1473 len2 = GST_CAPS_LEN (caps2);
1474 for (i = 0; i < len1 + len2 - 1; i++) {
1475 /* superset index goes from 0 to superset->structs->len-1 */
1476 j = MIN (i, len1 - 1);
1477 /* subset index stays 0 until i reaches superset->structs->len, then it
1478 * counts up from 1 to subset->structs->len - 1 */
1479 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1480 /* now run the diagonal line, end condition is the left or bottom
1483 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1484 features1 = gst_caps_get_features_unchecked (caps1, j);
1486 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1487 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1488 features2 = gst_caps_get_features_unchecked (caps2, k);
1490 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1491 if (gst_caps_features_is_equal (features1, features2) &&
1492 gst_structure_can_intersect (struct1, struct2)) {
1495 /* move down left */
1497 if (G_UNLIKELY (j == 0))
1498 break; /* so we don't roll back to G_MAXUINT */
1507 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1509 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1510 guint j, k, len1, len2;
1511 GstStructure *struct1;
1512 GstStructure *struct2;
1513 GstCapsFeatures *features1;
1514 GstCapsFeatures *features2;
1516 GstStructure *istruct;
1518 /* caps are exactly the same pointers, just copy one caps */
1519 if (G_UNLIKELY (caps1 == caps2))
1520 return gst_caps_ref (caps1);
1522 /* empty caps on either side, return empty */
1523 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1524 return gst_caps_ref (GST_CAPS_NONE);
1526 /* one of the caps is any, just copy the other caps */
1527 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1528 return gst_caps_ref (caps2);
1530 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1531 return gst_caps_ref (caps1);
1533 dest = gst_caps_new_empty ();
1534 /* run zigzag on top line then right line, this preserves the caps order
1535 * much better than a simple loop.
1537 * This algorithm zigzags over the caps structures as demonstrated in
1538 * the following matrix:
1546 * First we iterate over the caps1 structures (top line) intersecting
1547 * the structures diagonally down, then we iterate over the caps2
1550 len1 = GST_CAPS_LEN (caps1);
1551 len2 = GST_CAPS_LEN (caps2);
1552 for (i = 0; i < len1 + len2 - 1; i++) {
1553 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1554 j = MIN (i, len1 - 1);
1555 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1556 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1557 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1558 /* now run the diagonal line, end condition is the left or bottom
1561 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1562 features1 = gst_caps_get_features_unchecked (caps1, j);
1564 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1565 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1566 features2 = gst_caps_get_features_unchecked (caps2, k);
1568 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1569 if (gst_caps_features_is_equal (features1, features2)) {
1570 istruct = gst_structure_intersect (struct1, struct2);
1572 if (gst_caps_features_is_any (features1))
1574 gst_caps_merge_structure_full (dest, istruct,
1575 gst_caps_features_copy_conditional (features2));
1578 gst_caps_merge_structure_full (dest, istruct,
1579 gst_caps_features_copy_conditional (features1));
1582 /* move down left */
1584 if (G_UNLIKELY (j == 0))
1585 break; /* so we don't roll back to G_MAXUINT */
1593 * gst_caps_intersect_first:
1594 * @caps1: a #GstCaps to intersect
1595 * @caps2: a #GstCaps to intersect
1597 * Creates a new #GstCaps that contains all the formats that are common
1598 * to both @caps1 and @caps2.
1600 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1601 * fashion as @caps1.
1603 * Returns: (transfer full): the new #GstCaps
1606 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1609 guint j, len1, len2;
1610 GstStructure *struct1;
1611 GstStructure *struct2;
1612 GstCapsFeatures *features1;
1613 GstCapsFeatures *features2;
1615 GstStructure *istruct;
1617 /* caps are exactly the same pointers, just copy one caps */
1618 if (G_UNLIKELY (caps1 == caps2))
1619 return gst_caps_ref (caps1);
1621 /* empty caps on either side, return empty */
1622 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1623 return gst_caps_ref (GST_CAPS_NONE);
1625 /* one of the caps is any, just copy the other caps */
1626 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1627 return gst_caps_ref (caps2);
1629 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1630 return gst_caps_ref (caps1);
1632 dest = gst_caps_new_empty ();
1633 len1 = GST_CAPS_LEN (caps1);
1634 len2 = GST_CAPS_LEN (caps2);
1635 for (i = 0; i < len1; i++) {
1636 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1637 features1 = gst_caps_get_features_unchecked (caps1, i);
1639 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1640 for (j = 0; j < len2; j++) {
1641 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1642 features2 = gst_caps_get_features_unchecked (caps2, j);
1644 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1645 if (gst_caps_features_is_equal (features1, features2)) {
1646 istruct = gst_structure_intersect (struct1, struct2);
1648 if (gst_caps_features_is_any (features1))
1650 gst_caps_merge_structure_full (dest, istruct,
1651 gst_caps_features_copy_conditional (features2));
1654 gst_caps_merge_structure_full (dest, istruct,
1655 gst_caps_features_copy_conditional (features1));
1665 * gst_caps_intersect_full:
1666 * @caps1: a #GstCaps to intersect
1667 * @caps2: a #GstCaps to intersect
1668 * @mode: The intersection algorithm/mode to use
1670 * Creates a new #GstCaps that contains all the formats that are common
1671 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1674 * Returns: (transfer full): the new #GstCaps
1677 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1678 GstCapsIntersectMode mode)
1680 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1681 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1684 case GST_CAPS_INTERSECT_FIRST:
1685 return gst_caps_intersect_first (caps1, caps2);
1687 g_warning ("Unknown caps intersect mode: %d", mode);
1689 case GST_CAPS_INTERSECT_ZIG_ZAG:
1690 return gst_caps_intersect_zig_zag (caps1, caps2);
1695 * gst_caps_intersect:
1696 * @caps1: a #GstCaps to intersect
1697 * @caps2: a #GstCaps to intersect
1699 * Creates a new #GstCaps that contains all the formats that are common
1700 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1702 * Returns: (transfer full): the new #GstCaps
1705 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1707 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1710 /* subtract operation */
1714 const GstStructure *subtract_from;
1719 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1722 SubtractionEntry *e = user_data;
1723 GValue subtraction = { 0, };
1724 const GValue *other;
1725 GstStructure *structure;
1727 other = gst_structure_id_get_value (e->subtract_from, field_id);
1733 if (!gst_value_subtract (&subtraction, other, value))
1736 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1737 g_value_unset (&subtraction);
1740 structure = gst_structure_copy (e->subtract_from);
1741 gst_structure_id_take_value (structure, field_id, &subtraction);
1742 e->put_into = g_slist_prepend (e->put_into, structure);
1748 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1749 const GstStructure * subtrahend)
1754 e.subtract_from = minuend;
1756 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1757 gst_caps_structure_subtract_field, &e);
1764 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1765 gst_structure_free (walk->data);
1767 g_slist_free (e.put_into);
1774 * gst_caps_subtract:
1775 * @minuend: #GstCaps to subtract from
1776 * @subtrahend: #GstCaps to subtract
1778 * Subtracts the @subtrahend from the @minuend.
1779 * > This function does not work reliably if optional properties for caps
1780 * > are included on one caps and omitted on the other.
1782 * Returns: (transfer full): the resulting caps
1785 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1790 GstCapsFeatures *min_f, *sub_f;
1791 GstCaps *dest = NULL, *src;
1793 g_return_val_if_fail (minuend != NULL, NULL);
1794 g_return_val_if_fail (subtrahend != NULL, NULL);
1796 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1797 return gst_caps_new_empty ();
1800 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1801 return gst_caps_ref (minuend);
1803 /* FIXME: Do we want this here or above?
1804 The reason we need this is that there is no definition about what
1805 ANY means for specific types, so it's not possible to reduce ANY partially
1806 You can only remove everything or nothing and that is done above.
1807 Note: there's a test that checks this behaviour. */
1809 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1810 sublen = GST_CAPS_LEN (subtrahend);
1811 g_assert (sublen > 0);
1813 src = _gst_caps_copy (minuend);
1814 for (i = 0; i < sublen; i++) {
1817 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1818 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1820 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1822 gst_caps_unref (src);
1825 dest = gst_caps_new_empty ();
1826 srclen = GST_CAPS_LEN (src);
1827 for (j = 0; j < srclen; j++) {
1828 min = gst_caps_get_structure_unchecked (src, j);
1829 min_f = gst_caps_get_features_unchecked (src, j);
1831 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1833 /* Same reason as above for ANY caps */
1834 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1836 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1837 gst_caps_features_is_equal (min_f, sub_f)) {
1840 if (gst_caps_structure_subtract (&list, min, sub)) {
1843 for (walk = list; walk; walk = g_slist_next (walk)) {
1844 gst_caps_append_structure_unchecked (dest,
1845 (GstStructure *) walk->data,
1846 gst_caps_features_copy_conditional (min_f));
1848 g_slist_free (list);
1850 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1851 gst_caps_features_copy_conditional (min_f));
1854 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1855 gst_caps_features_copy_conditional (min_f));
1859 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1860 gst_caps_unref (src);
1865 gst_caps_unref (src);
1866 dest = gst_caps_simplify (dest);
1871 /* normalize/simplify operations */
1873 typedef struct _NormalizeForeach
1876 GstStructure *structure;
1877 GstCapsFeatures *features;
1881 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1883 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1887 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1888 guint len = gst_value_list_get_size (value);
1890 for (i = 1; i < len; i++) {
1891 const GValue *v = gst_value_list_get_value (value, i);
1892 GstStructure *structure = gst_structure_copy (nf->structure);
1894 gst_structure_id_set_value (structure, field_id, v);
1895 gst_caps_append_structure_unchecked (nf->caps, structure,
1896 gst_caps_features_copy_conditional (nf->features));
1899 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1900 gst_structure_id_take_value (nf->structure, field_id, &val);
1908 * gst_caps_normalize:
1909 * @caps: (transfer full): a #GstCaps to normalize
1911 * Returns a #GstCaps that represents the same set of formats as
1912 * @caps, but contains no lists. Each list is expanded into separate
1915 * This function takes ownership of @caps and will call gst_caps_make_writable()
1916 * on it so you must not use @caps afterwards unless you keep an additional
1917 * reference to it with gst_caps_ref().
1919 * Returns: (transfer full): the normalized #GstCaps
1922 gst_caps_normalize (GstCaps * caps)
1924 NormalizeForeach nf;
1927 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1929 caps = gst_caps_make_writable (caps);
1932 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1933 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1934 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1935 while (!gst_structure_foreach (nf.structure,
1936 gst_caps_normalize_foreach, &nf));
1943 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1946 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1947 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1949 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1950 So what's the best way? */
1951 ret = strcmp (gst_structure_get_name (struct1),
1952 gst_structure_get_name (struct2));
1957 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1964 GstStructure *compare;
1968 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1971 UnionField *u = user_data;
1972 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1976 g_value_unset (&u->value);
1980 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1984 g_value_unset (&u->value);
1989 gst_value_union (&u->value, val, value);
1995 gst_caps_structure_simplify (GstStructure ** result,
1996 GstStructure * simplify, GstStructure * compare)
1999 UnionField field = { 0, {0,}, NULL };
2001 /* try to subtract to get a real subset */
2002 if (gst_caps_structure_subtract (&list, simplify, compare)) {
2003 if (list == NULL) { /* no result */
2006 } else if (list->next == NULL) { /* one result */
2007 *result = list->data;
2008 g_slist_free (list);
2010 } else { /* multiple results */
2011 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
2012 g_slist_free (list);
2017 /* try to union both structs */
2018 field.compare = compare;
2019 if (gst_structure_foreach (simplify,
2020 gst_caps_structure_figure_out_union, &field)) {
2021 gboolean ret = FALSE;
2023 /* now we know all of simplify's fields are the same in compare
2024 * but at most one field: field.name */
2025 if (G_IS_VALUE (&field.value)) {
2026 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
2027 gst_structure_id_take_value (compare, field.name, &field.value);
2031 g_value_unset (&field.value);
2034 if (gst_structure_n_fields (simplify) <=
2035 gst_structure_n_fields (compare)) {
2036 /* compare is just more specific, will be optimized away later */
2037 /* FIXME: do this here? */
2038 GST_LOG ("found a case that will be optimized later.");
2040 gchar *one = gst_structure_to_string (simplify);
2041 gchar *two = gst_structure_to_string (compare);
2044 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2056 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2057 GstStructure * new, gint i)
2059 gst_structure_set_parent_refcount (old, NULL);
2060 gst_structure_free (old);
2061 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2062 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2066 * gst_caps_simplify:
2067 * @caps: (transfer full): a #GstCaps to simplify
2069 * Converts the given @caps into a representation that represents the
2070 * same set of formats, but in a simpler form. Component structures that are
2071 * identical are merged. Component structures that have values that can be
2072 * merged are also merged.
2074 * This function takes ownership of @caps and will call gst_caps_make_writable()
2075 * on it if necessary, so you must not use @caps afterwards unless you keep an
2076 * additional reference to it with gst_caps_ref().
2078 * This method does not preserve the original order of @caps.
2080 * Returns: (transfer full): The simplified caps.
2083 gst_caps_simplify (GstCaps * caps)
2085 GstStructure *simplify, *compare, *result = NULL;
2086 GstCapsFeatures *simplify_f, *compare_f;
2089 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2091 start = GST_CAPS_LEN (caps) - 1;
2092 /* one caps, already as simple as can be */
2096 caps = gst_caps_make_writable (caps);
2098 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2100 for (i = start; i >= 0; i--) {
2101 simplify = gst_caps_get_structure_unchecked (caps, i);
2102 simplify_f = gst_caps_get_features_unchecked (caps, i);
2104 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2105 compare = gst_caps_get_structure_unchecked (caps, start);
2106 compare_f = gst_caps_get_features_unchecked (caps, start);
2108 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2109 if (gst_structure_get_name_id (simplify) !=
2110 gst_structure_get_name_id (compare) ||
2111 !gst_caps_features_is_equal (simplify_f, compare_f))
2113 for (j = start; j >= 0; j--) {
2116 compare = gst_caps_get_structure_unchecked (caps, j);
2117 compare_f = gst_caps_get_features_unchecked (caps, j);
2119 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2120 if (gst_structure_get_name_id (simplify) !=
2121 gst_structure_get_name_id (compare) ||
2122 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2125 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2127 gst_caps_switch_structures (caps, simplify, result, i);
2130 gst_caps_remove_structure (caps, i);
2142 * @caps: (transfer full): a #GstCaps to fixate
2144 * Modifies the given @caps into a representation with only fixed
2145 * values. First the caps will be truncated and then the first structure will be
2146 * fixated with gst_structure_fixate().
2148 * This function takes ownership of @caps and will call gst_caps_make_writable()
2149 * on it so you must not use @caps afterwards unless you keep an additional
2150 * reference to it with gst_caps_ref().
2152 * Returns: (transfer full): the fixated caps
2155 gst_caps_fixate (GstCaps * caps)
2160 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2162 /* default fixation */
2163 caps = gst_caps_truncate (caps);
2164 caps = gst_caps_make_writable (caps);
2165 s = gst_caps_get_structure (caps, 0);
2166 gst_structure_fixate (s);
2168 /* Set features to sysmem if they're still ANY */
2169 f = gst_caps_get_features_unchecked (caps, 0);
2170 if (f && gst_caps_features_is_any (f)) {
2171 f = gst_caps_features_new_empty ();
2172 gst_caps_set_features (caps, 0, f);
2181 * gst_caps_to_string:
2184 * Converts @caps to a string representation. This string representation
2185 * can be converted back to a #GstCaps by gst_caps_from_string().
2187 * For debugging purposes its easier to do something like this:
2188 * |[<!-- language="C" -->
2189 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2191 * This prints the caps in human readable form.
2193 * The current implementation of serialization will lead to unexpected results
2194 * when there are nested #GstCaps / #GstStructure deeper than one level.
2196 * Returns: (transfer full): a newly allocated string representing @caps.
2199 gst_caps_to_string (const GstCaps * caps)
2201 guint i, slen, clen;
2204 /* NOTE: This function is potentially called by the debug system,
2205 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2206 * should be careful to avoid recursion. This includes any functions
2207 * called by gst_caps_to_string. In particular, calls should
2208 * not use the GST_PTR_FORMAT extension. */
2211 return g_strdup ("NULL");
2213 if (CAPS_IS_ANY (caps)) {
2214 return g_strdup ("ANY");
2216 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2217 return g_strdup ("EMPTY");
2220 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2222 clen = GST_CAPS_LEN (caps);
2223 for (i = 0; i < clen; i++) {
2227 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2229 f = gst_caps_get_features_unchecked (caps, i);
2231 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2234 s = g_string_sized_new (slen);
2235 for (i = 0; i < clen; i++) {
2236 GstStructure *structure;
2237 GstCapsFeatures *features;
2240 /* ';' is now added by gst_structure_to_string */
2241 g_string_append_c (s, ' ');
2244 structure = gst_caps_get_structure_unchecked (caps, i);
2245 features = gst_caps_get_features_unchecked (caps, i);
2247 g_string_append (s, gst_structure_get_name (structure));
2248 if (features && (gst_caps_features_is_any (features)
2249 || !gst_caps_features_is_equal (features,
2250 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2251 g_string_append_c (s, '(');
2252 priv_gst_caps_features_append_to_gstring (features, s);
2253 g_string_append_c (s, ')');
2255 priv_gst_structure_append_to_gstring (structure, s);
2257 if (s->len && s->str[s->len - 1] == ';') {
2258 /* remove latest ';' */
2259 s->str[--s->len] = '\0';
2261 return g_string_free (s, FALSE);
2265 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2267 GstStructure *structure;
2268 gchar *s, *copy, *end, *next, save;
2270 if (strcmp ("ANY", string) == 0) {
2271 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2275 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2279 copy = s = g_strdup (string);
2281 GstCapsFeatures *features = NULL;
2283 while (g_ascii_isspace (*s))
2289 if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2296 structure = gst_structure_new_empty (s);
2299 if (structure == NULL) {
2317 } else if (*end == ')') {
2326 features = gst_caps_features_from_string (s);
2328 gst_structure_free (structure);
2342 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2343 gst_structure_free (structure);
2345 gst_caps_features_free (features);
2351 gst_caps_append_structure_unchecked (caps, structure, features);
2363 * gst_caps_from_string:
2364 * @string: a string to convert to #GstCaps
2366 * Converts @caps from a string representation.
2368 * The current implementation of serialization will lead to unexpected results
2369 * when there are nested #GstCaps / #GstStructure deeper than one level.
2371 * Returns: (transfer full) (nullable): a newly allocated #GstCaps
2374 gst_caps_from_string (const gchar * string)
2378 g_return_val_if_fail (string, FALSE);
2380 caps = gst_caps_new_empty ();
2381 if (gst_caps_from_string_inplace (caps, string)) {
2384 gst_caps_unref (caps);
2390 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2392 g_return_if_fail (G_IS_VALUE (src_value));
2393 g_return_if_fail (G_IS_VALUE (dest_value));
2394 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2395 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2396 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2398 g_value_take_string (dest_value,
2399 gst_caps_to_string (gst_value_get_caps (src_value)));
2405 * @func: (scope call): a function to call for each field
2406 * @user_data: (closure): private data
2408 * Calls the provided function once for each structure and caps feature in the
2409 * #GstCaps. The function must not modify the fields.
2410 * Also see gst_caps_map_in_place() and gst_caps_filter_and_map_in_place().
2412 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2418 gst_caps_foreach (const GstCaps * caps, GstCapsForeachFunc func,
2422 GstCapsFeatures *features;
2423 GstStructure *structure;
2426 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2427 g_return_val_if_fail (func != NULL, FALSE);
2429 n = GST_CAPS_LEN (caps);
2431 for (i = 0; i < n; i++) {
2432 features = gst_caps_get_features_unchecked (caps, i);
2433 structure = gst_caps_get_structure_unchecked (caps, i);
2435 ret = func (features, structure, user_data);
2436 if (G_UNLIKELY (!ret))
2444 * gst_caps_map_in_place:
2446 * @func: (scope call): a function to call for each field
2447 * @user_data: (closure): private data
2449 * Calls the provided function once for each structure and caps feature in the
2450 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify but not
2451 * delete the structures and features. The caps must be mutable.
2453 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2459 gst_caps_map_in_place (GstCaps * caps, GstCapsMapFunc func, gpointer user_data)
2462 GstCapsFeatures *features;
2463 GstStructure *structure;
2466 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2467 g_return_val_if_fail (gst_caps_is_writable (caps), FALSE);
2468 g_return_val_if_fail (func != NULL, FALSE);
2470 n = GST_CAPS_LEN (caps);
2472 for (i = 0; i < n; i++) {
2473 features = gst_caps_get_features_unchecked (caps, i);
2474 structure = gst_caps_get_structure_unchecked (caps, i);
2476 /* Provide sysmem features if there are none yet */
2479 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2480 gst_caps_set_features (caps, i, features);
2483 ret = func (features, structure, user_data);
2484 if (G_UNLIKELY (!ret))
2492 * gst_caps_filter_and_map_in_place:
2494 * @func: (scope call): a function to call for each field
2495 * @user_data: (closure): private data
2497 * Calls the provided function once for each structure and caps feature in the
2498 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify the
2499 * structure and features. In contrast to gst_caps_filter_and_map_in_place(),
2500 * the structure and features are removed from the caps if %FALSE is returned
2501 * from the function.
2502 * The caps must be mutable.
2507 gst_caps_filter_and_map_in_place (GstCaps * caps, GstCapsFilterMapFunc func,
2511 GstCapsFeatures *features;
2512 GstStructure *structure;
2515 g_return_if_fail (GST_IS_CAPS (caps));
2516 g_return_if_fail (gst_caps_is_writable (caps));
2517 g_return_if_fail (func != NULL);
2519 n = GST_CAPS_LEN (caps);
2521 for (i = 0; i < n;) {
2522 features = gst_caps_get_features_unchecked (caps, i);
2523 structure = gst_caps_get_structure_unchecked (caps, i);
2525 /* Provide sysmem features if there are none yet */
2528 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2529 gst_caps_set_features (caps, i, features);
2532 ret = func (features, structure, user_data);
2534 GST_CAPS_ARRAY (caps) = g_array_remove_index (GST_CAPS_ARRAY (caps), i);
2536 gst_structure_set_parent_refcount (structure, NULL);
2537 gst_structure_free (structure);
2539 gst_caps_features_set_parent_refcount (features, NULL);
2540 gst_caps_features_free (features);
2543 n = GST_CAPS_LEN (caps);
2552 * @caps: a #GstCaps.
2554 * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
2555 * refcount of 1, owned by the caller. The structures are copied as well.
2557 * Note that this function is the semantic equivalent of a gst_caps_ref()
2558 * followed by a gst_caps_make_writable(). If you only want to hold on to a
2559 * reference to the data, you should use gst_caps_ref().
2561 * When you are finished with the caps, call gst_caps_unref() on it.
2563 * Returns: the new #GstCaps
2565 GstCaps *(gst_caps_copy) (const GstCaps * caps)
2567 return GST_CAPS (gst_mini_object_copy (GST_MINI_OBJECT_CAST (caps)));