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:
40 * GstCaps *caps = gst_caps_new_simple ("video/x-raw",
41 * "format", G_TYPE_STRING, "I420",
42 * "framerate", GST_TYPE_FRACTION, 25, 1,
43 * "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
44 * "width", G_TYPE_INT, 320,
45 * "height", G_TYPE_INT, 240,
49 * A #GstCaps is fixed when it has no fields with ranges or lists. Use
50 * gst_caps_is_fixed() to test for fixed caps. Fixed caps can be used in a
51 * caps event to notify downstream elements of the current media type.
53 * Various methods exist to work with the media types such as subtracting
56 * Be aware that until 1.20 the #GstCaps / #GstStructure serialization into string
57 * had limited support for nested #GstCaps / #GstStructure fields. It could only
58 * support one level of nesting. Using more levels would lead to unexpected
59 * behavior when using serialization features, such as gst_caps_to_string() or
60 * gst_value_serialize() and their counterparts.
69 #define GST_DISABLE_MINIOBJECT_INLINE_FUNCTIONS
70 #include "gst_private.h"
72 #include <gobject/gvaluecollector.h>
74 #define DEBUG_REFCOUNT
76 typedef struct _GstCapsArrayElement
78 GstStructure *structure;
79 GstCapsFeatures *features;
80 } GstCapsArrayElement;
82 typedef struct _GstCapsImpl
89 #define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
91 #define GST_CAPS_LEN(c) (GST_CAPS_ARRAY(c)->len)
93 #define IS_WRITABLE(caps) \
94 (GST_CAPS_REFCOUNT_VALUE (caps) == 1)
96 /* same as gst_caps_is_any () */
97 #define CAPS_IS_ANY(caps) \
98 (!!(GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY))
100 /* same as gst_caps_is_empty () */
101 #define CAPS_IS_EMPTY(caps) \
102 (!CAPS_IS_ANY(caps) && CAPS_IS_EMPTY_SIMPLE(caps))
104 #define CAPS_IS_EMPTY_SIMPLE(caps) \
105 ((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
107 #define gst_caps_features_copy_conditional(f) ((f && (gst_caps_features_is_any (f) || !gst_caps_features_is_equal (f, GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) ? gst_caps_features_copy (f) : NULL)
109 /* quick way to get a caps structure at an index without doing a type or array
111 #define gst_caps_get_structure_unchecked(caps, index) \
112 (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).structure)
113 #define gst_caps_get_features_storage_unchecked(caps, index) \
114 (&g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
115 #define gst_caps_get_features_unchecked(caps, index) \
116 (g_atomic_pointer_get (gst_caps_get_features_storage_unchecked (caps, index)))
117 /* quick way to append a structure without checking the args */
118 #define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
119 GstCapsArrayElement __e={s, f}; \
120 if (gst_structure_set_parent_refcount (__e.structure, &GST_MINI_OBJECT_REFCOUNT(caps)) && \
121 (!__e.features || gst_caps_features_set_parent_refcount (__e.features, &GST_MINI_OBJECT_REFCOUNT(caps)))) \
122 g_array_append_val (GST_CAPS_ARRAY (caps), __e); \
125 /* lock to protect multiple invocations of static caps to caps conversion */
126 G_LOCK_DEFINE_STATIC (static_caps_lock);
128 static void gst_caps_transform_to_string (const GValue * src_value,
129 GValue * dest_value);
130 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
131 const gchar * string);
133 GType _gst_caps_type = 0;
134 GstCaps *_gst_caps_any;
135 GstCaps *_gst_caps_none;
137 GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
140 _priv_gst_caps_initialize (void)
142 _gst_caps_type = gst_caps_get_type ();
144 _gst_caps_any = gst_caps_new_any ();
145 _gst_caps_none = gst_caps_new_empty ();
147 g_value_register_transform_func (_gst_caps_type,
148 G_TYPE_STRING, gst_caps_transform_to_string);
152 _priv_gst_caps_cleanup (void)
154 gst_caps_unref (_gst_caps_any);
155 _gst_caps_any = NULL;
156 gst_caps_unref (_gst_caps_none);
157 _gst_caps_none = NULL;
161 __gst_caps_get_features_unchecked (const GstCaps * caps, guint idx)
163 return gst_caps_get_features_unchecked (caps, idx);
167 _gst_caps_copy (const GstCaps * caps)
170 GstStructure *structure;
171 GstCapsFeatures *features;
174 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
176 newcaps = gst_caps_new_empty ();
177 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
178 n = GST_CAPS_LEN (caps);
180 GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "doing copy %p -> %p", caps, newcaps);
182 for (i = 0; i < n; i++) {
183 structure = gst_caps_get_structure_unchecked (caps, i);
184 features = gst_caps_get_features_unchecked (caps, i);
185 gst_caps_append_structure_full (newcaps, gst_structure_copy (structure),
186 gst_caps_features_copy_conditional (features));
192 /* creation/deletion */
194 _gst_caps_free (GstCaps * caps)
196 GstStructure *structure;
197 GstCapsFeatures *features;
200 /* The refcount must be 0, but since we're only called by gst_caps_unref,
201 * don't bother testing. */
202 len = GST_CAPS_LEN (caps);
203 /* This can be used to get statistics about caps sizes */
204 /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
205 for (i = 0; i < len; i++) {
206 structure = gst_caps_get_structure_unchecked (caps, i);
207 gst_structure_set_parent_refcount (structure, NULL);
208 gst_structure_free (structure);
209 features = gst_caps_get_features_unchecked (caps, i);
211 gst_caps_features_set_parent_refcount (features, NULL);
212 gst_caps_features_free (features);
215 g_array_free (GST_CAPS_ARRAY (caps), TRUE);
217 #ifdef DEBUG_REFCOUNT
218 GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
222 memset (caps, 0xff, sizeof (GstCapsImpl));
225 g_slice_free1 (sizeof (GstCapsImpl), caps);
229 gst_caps_init (GstCaps * caps)
231 gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
232 (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
233 (GstMiniObjectFreeFunction) _gst_caps_free);
235 /* the 32 has been determined by logging caps sizes in _gst_caps_free
236 * but g_ptr_array uses 16 anyway if it expands once, so this does not help
238 * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
240 GST_CAPS_ARRAY (caps) =
241 g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
245 * gst_caps_new_empty:
247 * Creates a new #GstCaps that is empty. That is, the returned
248 * #GstCaps contains no media formats.
249 * The #GstCaps is guaranteed to be writable.
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
294 * Returns: (transfer full): the new #GstCaps
297 gst_caps_new_empty_simple (const char *media_type)
300 GstStructure *structure;
302 caps = gst_caps_new_empty ();
303 structure = gst_structure_new_empty (media_type);
305 gst_caps_append_structure_unchecked (caps, structure, NULL);
311 * gst_caps_new_simple:
312 * @media_type: the media type of the structure
313 * @fieldname: first field to set
314 * @...: additional arguments
316 * Creates a new #GstCaps that contains one #GstStructure. The
317 * structure is defined by the arguments, which have the same format
318 * as gst_structure_new().
320 * Returns: (transfer full): the new #GstCaps
323 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
326 GstStructure *structure;
329 caps = gst_caps_new_empty ();
331 va_start (var_args, fieldname);
332 structure = gst_structure_new_valist (media_type, fieldname, var_args);
336 gst_caps_append_structure_unchecked (caps, structure, NULL);
338 gst_caps_replace (&caps, NULL);
345 * @struct1: the first structure to add
346 * @...: additional structures to add
348 * Creates a new #GstCaps and adds all the structures listed as
349 * arguments. The list must be %NULL-terminated. The structures
350 * are not copied; the returned #GstCaps owns the structures.
352 * Returns: (transfer full): the new #GstCaps
355 gst_caps_new_full (GstStructure * struct1, ...)
360 va_start (var_args, struct1);
361 caps = gst_caps_new_full_valist (struct1, var_args);
368 * gst_caps_new_full_valist:
369 * @structure: the first structure to add
370 * @var_args: additional structures to add
372 * Creates a new #GstCaps and adds all the structures listed as
373 * arguments. The list must be %NULL-terminated. The structures
374 * are not copied; the returned #GstCaps owns the structures.
376 * Returns: (transfer full): the new #GstCaps
379 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
383 caps = gst_caps_new_empty ();
386 gst_caps_append_structure_unchecked (caps, structure, NULL);
387 structure = va_arg (var_args, GstStructure *);
393 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
396 * gst_static_caps_get:
397 * @static_caps: the #GstStaticCaps to convert
399 * Converts a #GstStaticCaps to a #GstCaps.
401 * Returns: (transfer full) (nullable): a pointer to the #GstCaps. Since the
402 * core holds an additional ref to the returned caps, use
403 * gst_caps_make_writable() on the returned caps to modify it.
406 gst_static_caps_get (GstStaticCaps * static_caps)
410 g_return_val_if_fail (static_caps != NULL, NULL);
412 caps = &static_caps->caps;
414 /* refcount is 0 when we need to convert */
415 if (G_UNLIKELY (*caps == NULL)) {
418 G_LOCK (static_caps_lock);
419 /* check if other thread already updated */
420 if (G_UNLIKELY (*caps != NULL))
423 string = static_caps->string;
425 if (G_UNLIKELY (string == NULL))
428 *caps = gst_caps_from_string (string);
430 /* convert to string */
431 if (G_UNLIKELY (*caps == NULL)) {
432 g_critical ("Could not convert static caps \"%s\"", string);
436 /* Caps generated from static caps are usually leaked */
437 GST_MINI_OBJECT_FLAG_SET (*caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
439 GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
442 G_UNLOCK (static_caps_lock);
444 /* ref the caps, makes it not writable */
445 if (G_LIKELY (*caps != NULL))
446 gst_caps_ref (*caps);
453 G_UNLOCK (static_caps_lock);
454 g_warning ("static caps %p string is NULL", static_caps);
460 * gst_static_caps_cleanup:
461 * @static_caps: the #GstStaticCaps to clean
463 * Cleans up the cached caps contained in @static_caps.
466 gst_static_caps_cleanup (GstStaticCaps * static_caps)
468 G_LOCK (static_caps_lock);
469 gst_caps_replace (&static_caps->caps, NULL);
470 G_UNLOCK (static_caps_lock);
476 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
477 GstStructure ** s, GstCapsFeatures ** f)
482 s_ = gst_caps_get_structure_unchecked (caps, idx);
483 f_ = gst_caps_get_features_unchecked (caps, idx);
485 /* don't use index_fast, gst_caps_simplify relies on the order */
486 g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
488 gst_structure_set_parent_refcount (s_, NULL);
490 gst_caps_features_set_parent_refcount (f_, NULL);
497 static GstStructure *
498 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
503 gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
506 gst_caps_features_free (f);
512 gst_caps_make_any (GstCaps * caps)
517 /* empty out residual structures */
518 for (i = GST_CAPS_LEN (caps); i; i--) {
519 s = gst_caps_remove_and_get_structure (caps, 0);
520 gst_structure_free (s);
522 GST_CAPS_FLAGS (caps) |= GST_CAPS_FLAG_ANY;
526 * gst_caps_steal_structure:
527 * @caps: the #GstCaps to retrieve from
528 * @index: Index of the structure to retrieve
530 * Retrieves the structure with the given index from the list of structures
531 * contained in @caps. The caller becomes the owner of the returned structure.
533 * Returns: (transfer full) (nullable): a pointer to the #GstStructure
534 * corresponding to @index.
537 gst_caps_steal_structure (GstCaps * caps, guint index)
539 g_return_val_if_fail (caps != NULL, NULL);
540 g_return_val_if_fail (IS_WRITABLE (caps), NULL);
542 if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
545 return gst_caps_remove_and_get_structure (caps, index);
550 * @caps1: the #GstCaps that will be appended to
551 * @caps2: (transfer full): the #GstCaps to append
553 * Appends the structures contained in @caps2 to @caps1. The structures in
554 * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
555 * freed. If either caps is ANY, the resulting caps will be ANY.
558 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
560 GstStructure *structure;
561 GstCapsFeatures *features;
564 g_return_if_fail (GST_IS_CAPS (caps1));
565 g_return_if_fail (GST_IS_CAPS (caps2));
566 g_return_if_fail (IS_WRITABLE (caps1));
568 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
569 gst_caps_make_any (caps1);
570 gst_caps_unref (caps2);
572 caps2 = gst_caps_make_writable (caps2);
574 for (i = GST_CAPS_LEN (caps2); i; i--) {
575 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
577 gst_caps_append_structure_unchecked (caps1, structure, features);
579 gst_caps_unref (caps2); /* guaranteed to free it */
585 * @caps1: (transfer full): the #GstCaps that will take the new entries
586 * @caps2: (transfer full): the #GstCaps to merge in
588 * Appends the structures contained in @caps2 to @caps1 if they are not yet
589 * expressed by @caps1. The structures in @caps2 are not copied -- they are
590 * transferred to a writable copy of @caps1, and then @caps2 is freed.
591 * If either caps is ANY, the resulting caps will be ANY.
593 * Returns: (transfer full): the merged caps.
596 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
598 GstStructure *structure;
599 GstCapsFeatures *features;
603 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
604 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
606 if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
607 gst_caps_unref (caps2);
609 } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
610 gst_caps_unref (caps1);
613 caps2 = gst_caps_make_writable (caps2);
615 for (i = GST_CAPS_LEN (caps2); i; i--) {
616 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
618 caps1 = gst_caps_merge_structure_full (caps1, structure, features);
620 gst_caps_unref (caps2);
624 GstCaps *com = gst_caps_intersect (caps1, caps2);
625 GstCaps *add = gst_caps_subtract (caps2, com);
627 GST_DEBUG ("common : %d", gst_caps_get_size (com));
628 GST_DEBUG ("adding : %d", gst_caps_get_size (add));
629 gst_caps_append (caps1, add);
630 gst_caps_unref (com);
638 * gst_caps_append_structure:
639 * @caps: the #GstCaps that will be appended to
640 * @structure: (transfer full): the #GstStructure to append
642 * Appends @structure to @caps. The structure is not copied; @caps
643 * becomes the owner of @structure.
646 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
648 g_return_if_fail (GST_IS_CAPS (caps));
649 g_return_if_fail (IS_WRITABLE (caps));
651 if (CAPS_IS_ANY (caps)) {
652 /* ANY caps will stay as ANY caps */
654 gst_structure_free (structure);
658 if (G_LIKELY (structure)) {
659 gst_caps_append_structure_unchecked (caps, structure, NULL);
664 * gst_caps_append_structure_full:
665 * @caps: the #GstCaps that will be appended to
666 * @structure: (transfer full): the #GstStructure to append
667 * @features: (transfer full) (allow-none): the #GstCapsFeatures to append
669 * Appends @structure with @features to @caps. The structure is not copied; @caps
670 * becomes the owner of @structure.
675 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
676 GstCapsFeatures * features)
678 g_return_if_fail (GST_IS_CAPS (caps));
679 g_return_if_fail (IS_WRITABLE (caps));
681 if (CAPS_IS_ANY (caps)) {
682 /* ANY caps will stay as ANY caps */
684 gst_structure_free (structure);
686 gst_caps_features_free (features);
690 if (G_LIKELY (structure)) {
691 gst_caps_append_structure_unchecked (caps, structure, features);
696 * gst_caps_remove_structure:
697 * @caps: the #GstCaps to remove from
698 * @idx: Index of the structure to remove
700 * Removes the structure with the given index from the list of structures
701 * contained in @caps.
704 gst_caps_remove_structure (GstCaps * caps, guint idx)
706 GstStructure *structure;
708 g_return_if_fail (caps != NULL);
709 g_return_if_fail (idx < gst_caps_get_size (caps));
710 g_return_if_fail (IS_WRITABLE (caps));
712 structure = gst_caps_remove_and_get_structure (caps, idx);
713 gst_structure_free (structure);
717 * gst_caps_merge_structure:
718 * @caps: (transfer full): the #GstCaps to merge into
719 * @structure: (transfer full): the #GstStructure to merge
721 * Appends @structure to @caps if it is not already expressed by @caps.
723 * Returns: (transfer full): the merged caps.
726 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
728 GstStructure *structure1;
729 GstCapsFeatures *features1;
731 gboolean unique = TRUE;
733 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
735 if (G_UNLIKELY (structure == NULL))
738 if (CAPS_IS_ANY (caps)) {
739 /* ANY caps will stay as ANY caps */
740 gst_structure_free (structure);
744 /* check each structure */
745 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
746 structure1 = gst_caps_get_structure_unchecked (caps, i);
747 features1 = gst_caps_get_features_unchecked (caps, i);
749 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
751 /* if structure is a subset of structure1 and the
752 * there are no existing features, then skip it */
753 if (gst_caps_features_is_equal (features1,
754 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
755 && gst_structure_is_subset (structure, structure1)) {
761 caps = gst_caps_make_writable (caps);
762 gst_caps_append_structure_unchecked (caps, structure, NULL);
764 gst_structure_free (structure);
770 * gst_caps_merge_structure_full:
771 * @caps: (transfer full): the #GstCaps to merge into
772 * @structure: (transfer full): the #GstStructure to merge
773 * @features: (transfer full) (allow-none): the #GstCapsFeatures to merge
775 * Appends @structure with @features to @caps if its not already expressed by @caps.
777 * Returns: (transfer full): the merged caps.
782 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
783 GstCapsFeatures * features)
785 GstStructure *structure1;
786 GstCapsFeatures *features1, *features_tmp;
788 gboolean unique = TRUE;
790 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
792 if (G_UNLIKELY (structure == NULL))
795 if (CAPS_IS_ANY (caps)) {
796 /* ANY caps will stay as ANY caps */
797 gst_structure_free (structure);
799 gst_caps_features_free (features);
803 /* To make comparisons easier below */
804 features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
806 /* check each structure */
807 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
808 structure1 = gst_caps_get_structure_unchecked (caps, i);
809 features1 = gst_caps_get_features_unchecked (caps, i);
811 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
812 /* if structure is a subset of structure1 and the
813 * the features are a subset, then skip it */
814 /* FIXME: We only skip if none of the features are
815 * ANY and are still equal. That way all ANY structures
816 * show up in the caps and no non-ANY structures are
817 * swallowed by ANY structures
819 if (((!gst_caps_features_is_any (features_tmp)
820 || gst_caps_features_is_any (features1))
821 && gst_caps_features_is_equal (features_tmp, features1))
822 && gst_structure_is_subset (structure, structure1)) {
828 caps = gst_caps_make_writable (caps);
829 gst_caps_append_structure_unchecked (caps, structure, features);
831 gst_structure_free (structure);
833 gst_caps_features_free (features);
842 * Gets the number of structures contained in @caps.
844 * Returns: the number of structures that @caps contains
847 gst_caps_get_size (const GstCaps * caps)
849 g_return_val_if_fail (GST_IS_CAPS (caps), 0);
851 return GST_CAPS_LEN (caps);
855 * gst_caps_get_structure:
857 * @index: the index of the structure
859 * Finds the structure in @caps at @index, and returns it.
861 * WARNING: This function takes a `const GstCaps *`, but returns a
862 * non-const `GstStructure *`. This is for programming convenience --
863 * the caller should be aware that structures inside a constant
864 * #GstCaps should not be modified. However, if you know the caps
865 * are writable, either because you have just copied them or made
866 * them writable with gst_caps_make_writable(), you may modify the
867 * structure returned in the usual way, e.g. with functions like
868 * gst_structure_set().
870 * Returns: (transfer none): a pointer to the #GstStructure corresponding
874 gst_caps_get_structure (const GstCaps * caps, guint index)
876 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
877 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
879 return gst_caps_get_structure_unchecked (caps, index);
883 * gst_caps_get_features:
885 * @index: the index of the structure
887 * Finds the features in @caps at @index, and returns it.
889 * WARNING: This function takes a `const GstCaps *`, but returns a
890 * non-const `GstCapsFeatures *`. This is for programming convenience --
891 * the caller should be aware that features inside a constant
892 * #GstCaps should not be modified. However, if you know the caps
893 * are writable, either because you have just copied them or made
894 * them writable with gst_caps_make_writable(), you may modify the
895 * features returned in the usual way, e.g. with functions like
896 * gst_caps_features_add().
898 * Returns: (transfer none) (nullable): a pointer to the #GstCapsFeatures
899 * corresponding to @index
904 gst_caps_get_features (const GstCaps * caps, guint index)
906 GstCapsFeatures *features;
908 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
909 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
911 features = gst_caps_get_features_unchecked (caps, index);
913 GstCapsFeatures **storage;
915 /* We have to do some atomic pointer magic here as the caps
916 * might not be writable and someone else calls this function
917 * at the very same time */
918 features = gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
919 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
921 storage = gst_caps_get_features_storage_unchecked (caps, index);
922 if (!g_atomic_pointer_compare_and_exchange (storage,
923 (GstCapsFeatures *) NULL, features)) {
924 /* Someone did the same we just tried in the meantime */
925 gst_caps_features_set_parent_refcount (features, NULL);
926 gst_caps_features_free (features);
928 features = gst_caps_get_features_unchecked (caps, index);
929 g_assert (features != NULL);
937 * gst_caps_set_features:
939 * @index: the index of the structure
940 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
942 * Sets the @features for the structure at @index.
947 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
949 GstCapsFeatures **storage, *old;
951 g_return_if_fail (caps != NULL);
952 g_return_if_fail (index < gst_caps_get_size (caps));
953 g_return_if_fail (IS_WRITABLE (caps));
955 storage = gst_caps_get_features_storage_unchecked (caps, index);
956 /* Not much problem here as caps are writable */
957 old = g_atomic_pointer_get (storage);
958 g_atomic_pointer_set (storage, features);
961 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
964 gst_caps_features_set_parent_refcount (old, NULL);
965 gst_caps_features_free (old);
970 * gst_caps_set_features_simple:
972 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
974 * Sets the @features for all the structures of @caps.
979 gst_caps_set_features_simple (GstCaps * caps, GstCapsFeatures * features)
984 g_return_if_fail (caps != NULL);
985 g_return_if_fail (IS_WRITABLE (caps));
987 n = gst_caps_get_size (caps);
990 /* features will not be set on any structure */
992 gst_caps_features_free (features);
996 for (i = 0; i < n; i++) {
999 /* Transfer ownership of @features to the last structure */
1000 if (features && i < n - 1)
1001 f = gst_caps_features_copy (features);
1005 gst_caps_set_features (caps, i, f);
1010 * gst_caps_copy_nth:
1011 * @caps: the #GstCaps to copy
1012 * @nth: the nth structure to copy
1014 * Creates a new #GstCaps and appends a copy of the nth structure
1015 * contained in @caps.
1017 * Returns: (transfer full): the new #GstCaps
1022 gst_caps_copy_nth (const GstCaps * caps, guint nth)
1025 GstStructure *structure;
1026 GstCapsFeatures *features;
1028 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1030 newcaps = gst_caps_new_empty ();
1031 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
1033 if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
1034 structure = gst_caps_get_structure_unchecked (caps, nth);
1035 features = gst_caps_get_features_unchecked (caps, nth);
1036 gst_caps_append_structure_unchecked (newcaps,
1037 gst_structure_copy (structure),
1038 gst_caps_features_copy_conditional (features));
1045 * gst_caps_truncate:
1046 * @caps: (transfer full): the #GstCaps to truncate
1048 * Discards all but the first structure from @caps. Useful when
1051 * This function takes ownership of @caps and will call gst_caps_make_writable()
1052 * on it if necessary, so you must not use @caps afterwards unless you keep an
1053 * additional reference to it with gst_caps_ref().
1055 * Note that it is not guaranteed that the returned caps have exactly one
1056 * structure. If @caps is any or empty caps then the returned caps will be
1057 * the same and contain no structure at all.
1059 * Returns: (transfer full): truncated caps
1062 gst_caps_truncate (GstCaps * caps)
1066 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1068 /* Nothing to truncate here */
1069 if (GST_CAPS_LEN (caps) == 0)
1072 i = GST_CAPS_LEN (caps) - 1;
1074 /* Already truncated */
1078 caps = gst_caps_make_writable (caps);
1080 gst_caps_remove_structure (caps, i--);
1086 * gst_caps_set_value:
1087 * @caps: a writable caps
1088 * @field: name of the field to set
1089 * @value: value to set the field to
1091 * Sets the given @field on all structures of @caps to the given @value.
1092 * This is a convenience function for calling gst_structure_set_value() on
1093 * all structures of @caps.
1096 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
1100 g_return_if_fail (GST_IS_CAPS (caps));
1101 g_return_if_fail (IS_WRITABLE (caps));
1102 g_return_if_fail (field != NULL);
1103 g_return_if_fail (G_IS_VALUE (value));
1105 len = GST_CAPS_LEN (caps);
1106 for (i = 0; i < len; i++) {
1107 GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
1108 gst_structure_set_value (structure, field, value);
1113 * gst_caps_set_simple_valist:
1114 * @caps: the #GstCaps to set
1115 * @field: first field to set
1116 * @varargs: additional parameters
1118 * Sets fields in a #GstCaps. The arguments must be passed in the same
1119 * manner as gst_structure_set(), and be %NULL-terminated.
1122 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
1124 GValue value = { 0, };
1126 g_return_if_fail (GST_IS_CAPS (caps));
1127 g_return_if_fail (IS_WRITABLE (caps));
1133 type = va_arg (varargs, GType);
1135 G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1136 if (G_UNLIKELY (err)) {
1137 g_critical ("%s", err);
1142 gst_caps_set_value (caps, field, &value);
1144 g_value_unset (&value);
1146 field = va_arg (varargs, const gchar *);
1151 * gst_caps_set_simple:
1152 * @caps: the #GstCaps to set
1153 * @field: first field to set
1154 * @...: additional parameters
1156 * Sets fields in a #GstCaps. The arguments must be passed in the same
1157 * manner as gst_structure_set(), and be %NULL-terminated.
1160 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1164 g_return_if_fail (GST_IS_CAPS (caps));
1165 g_return_if_fail (IS_WRITABLE (caps));
1167 va_start (var_args, field);
1168 gst_caps_set_simple_valist (caps, field, var_args);
1176 * @caps: the #GstCaps to test
1178 * Determines if @caps represents any media format.
1180 * Returns: %TRUE if @caps represents any format.
1183 gst_caps_is_any (const GstCaps * caps)
1185 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1187 return (CAPS_IS_ANY (caps));
1191 * gst_caps_is_empty:
1192 * @caps: the #GstCaps to test
1194 * Determines if @caps represents no media formats.
1196 * Returns: %TRUE if @caps represents no formats.
1199 gst_caps_is_empty (const GstCaps * caps)
1201 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1203 if (CAPS_IS_ANY (caps))
1206 return CAPS_IS_EMPTY_SIMPLE (caps);
1210 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1213 return gst_value_is_fixed (value);
1217 * gst_caps_is_fixed:
1218 * @caps: the #GstCaps to test
1220 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1221 * one structure, and each field in the structure describes a fixed type.
1222 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1224 * Returns: %TRUE if @caps is fixed
1227 gst_caps_is_fixed (const GstCaps * caps)
1229 GstStructure *structure;
1230 GstCapsFeatures *features;
1232 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1234 if (GST_CAPS_LEN (caps) != 1)
1237 /* double check not ANY, even though ANY caps should have 0 length */
1238 if (CAPS_IS_ANY (caps))
1241 features = gst_caps_get_features_unchecked (caps, 0);
1242 if (features && gst_caps_features_is_any (features))
1245 structure = gst_caps_get_structure_unchecked (caps, 0);
1247 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1251 * gst_caps_is_equal_fixed:
1252 * @caps1: the #GstCaps to test
1253 * @caps2: the #GstCaps to test
1255 * Tests if two #GstCaps are equal. This function only works on fixed
1258 * Returns: %TRUE if the arguments represent the same format
1261 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1263 GstStructure *struct1, *struct2;
1264 GstCapsFeatures *features1, *features2;
1266 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1267 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1269 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1270 features1 = gst_caps_get_features_unchecked (caps1, 0);
1272 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1273 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1274 features2 = gst_caps_get_features_unchecked (caps2, 0);
1276 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1278 return gst_structure_is_equal (struct1, struct2) &&
1279 gst_caps_features_is_equal (features1, features2);
1283 * gst_caps_is_always_compatible:
1284 * @caps1: the #GstCaps to test
1285 * @caps2: the #GstCaps to test
1287 * A given #GstCaps structure is always compatible with another if
1288 * every media format that is in the first is also contained in the
1289 * second. That is, @caps1 is a subset of @caps2.
1291 * Returns: %TRUE if @caps1 is a subset of @caps2.
1294 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1296 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1297 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1299 return gst_caps_is_subset (caps1, caps2);
1303 * gst_caps_is_subset:
1304 * @subset: a #GstCaps
1305 * @superset: a potentially greater #GstCaps
1307 * Checks if all caps represented by @subset are also represented by @superset.
1309 * Returns: %TRUE if @subset is a subset of @superset
1312 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1314 GstStructure *s1, *s2;
1315 GstCapsFeatures *f1, *f2;
1316 gboolean ret = TRUE;
1319 g_return_val_if_fail (subset != NULL, FALSE);
1320 g_return_val_if_fail (superset != NULL, FALSE);
1322 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1324 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1327 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1328 s1 = gst_caps_get_structure_unchecked (subset, i);
1329 f1 = gst_caps_get_features_unchecked (subset, i);
1331 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1333 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1334 s2 = gst_caps_get_structure_unchecked (superset, j);
1335 f2 = gst_caps_get_features_unchecked (superset, j);
1337 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1338 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1339 gst_caps_features_is_equal (f1, f2)
1340 && gst_structure_is_subset (s1, s2)) {
1341 /* If we found a superset, continue with the next
1342 * subset structure */
1347 /* If we found no superset for this subset structure
1348 * we return FALSE immediately */
1359 * gst_caps_is_subset_structure:
1361 * @structure: a potential #GstStructure subset of @caps
1363 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1364 * for more information.
1366 * Returns: %TRUE if @structure is a subset of @caps
1369 gst_caps_is_subset_structure (const GstCaps * caps,
1370 const GstStructure * structure)
1375 g_return_val_if_fail (caps != NULL, FALSE);
1376 g_return_val_if_fail (structure != NULL, FALSE);
1378 if (CAPS_IS_ANY (caps))
1380 if (CAPS_IS_EMPTY (caps))
1383 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1384 s = gst_caps_get_structure_unchecked (caps, i);
1385 if (gst_structure_is_subset (structure, s)) {
1386 /* If we found a superset return TRUE */
1395 * gst_caps_is_subset_structure_full:
1397 * @structure: a potential #GstStructure subset of @caps
1398 * @features: (allow-none): a #GstCapsFeatures for @structure
1400 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1401 * for more information.
1403 * Returns: %TRUE if @structure is a subset of @caps
1408 gst_caps_is_subset_structure_full (const GstCaps * caps,
1409 const GstStructure * structure, const GstCapsFeatures * features)
1415 g_return_val_if_fail (caps != NULL, FALSE);
1416 g_return_val_if_fail (structure != NULL, FALSE);
1418 if (CAPS_IS_ANY (caps))
1420 if (CAPS_IS_EMPTY (caps))
1424 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1426 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1427 s = gst_caps_get_structure_unchecked (caps, i);
1428 f = gst_caps_get_features_unchecked (caps, i);
1430 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1431 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1432 && gst_caps_features_is_equal (features, f)
1433 && gst_structure_is_subset (structure, s)) {
1434 /* If we found a superset return TRUE */
1443 * gst_caps_is_equal:
1444 * @caps1: a #GstCaps
1445 * @caps2: another #GstCaps
1447 * Checks if the given caps represent the same set of caps.
1449 * Returns: %TRUE if both caps are equal.
1452 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1454 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1455 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1457 if (G_UNLIKELY (caps1 == caps2))
1460 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1461 return gst_caps_is_equal_fixed (caps1, caps2);
1463 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1467 * gst_caps_is_strictly_equal:
1468 * @caps1: a #GstCaps
1469 * @caps2: another #GstCaps
1471 * Checks if the given caps are exactly the same set of caps.
1473 * Returns: %TRUE if both caps are strictly equal.
1476 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1479 GstStructure *s1, *s2;
1480 GstCapsFeatures *f1, *f2;
1482 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1483 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1485 if (G_UNLIKELY (caps1 == caps2))
1488 /* if both are ANY caps, consider them strictly equal */
1489 if (CAPS_IS_ANY (caps1))
1490 return (CAPS_IS_ANY (caps2));
1491 else if (CAPS_IS_ANY (caps2))
1494 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1497 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1498 s1 = gst_caps_get_structure_unchecked (caps1, i);
1499 f1 = gst_caps_get_features_unchecked (caps1, i);
1501 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1502 s2 = gst_caps_get_structure_unchecked (caps2, i);
1503 f2 = gst_caps_get_features_unchecked (caps2, i);
1505 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1507 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1508 !gst_caps_features_is_equal (f1, f2) ||
1509 !gst_structure_is_equal (s1, s2))
1516 /* intersect operation */
1519 * gst_caps_can_intersect:
1520 * @caps1: a #GstCaps to intersect
1521 * @caps2: a #GstCaps to intersect
1523 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1526 * Returns: %TRUE if intersection would be not empty
1529 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1531 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1532 guint j, k, len1, len2;
1533 GstStructure *struct1;
1534 GstStructure *struct2;
1535 GstCapsFeatures *features1;
1536 GstCapsFeatures *features2;
1538 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1539 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1541 /* caps are exactly the same pointers */
1542 if (G_UNLIKELY (caps1 == caps2))
1545 /* empty caps on either side, return empty */
1546 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1549 /* one of the caps is any */
1550 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1553 /* run zigzag on top line then right line, this preserves the caps order
1554 * much better than a simple loop.
1556 * This algorithm zigzags over the caps structures as demonstrated in
1557 * the following matrix:
1560 * +------------- total distance: +-------------
1561 * | 1 2 4 7 0 | 0 1 2 3
1562 * caps2 | 3 5 8 10 1 | 1 2 3 4
1563 * | 6 9 11 12 2 | 2 3 4 5
1565 * First we iterate over the caps1 structures (top line) intersecting
1566 * the structures diagonally down, then we iterate over the caps2
1567 * structures. The result is that the intersections are ordered based on the
1568 * sum of the indexes in the list.
1570 len1 = GST_CAPS_LEN (caps1);
1571 len2 = GST_CAPS_LEN (caps2);
1572 for (i = 0; i < len1 + len2 - 1; i++) {
1573 /* superset index goes from 0 to superset->structs->len-1 */
1574 j = MIN (i, len1 - 1);
1575 /* subset index stays 0 until i reaches superset->structs->len, then it
1576 * counts up from 1 to subset->structs->len - 1 */
1577 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1578 /* now run the diagonal line, end condition is the left or bottom
1581 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1582 features1 = gst_caps_get_features_unchecked (caps1, j);
1584 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1585 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1586 features2 = gst_caps_get_features_unchecked (caps2, k);
1588 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1589 if (gst_caps_features_is_equal (features1, features2) &&
1590 gst_structure_can_intersect (struct1, struct2)) {
1593 /* move down left */
1595 if (G_UNLIKELY (j == 0))
1596 break; /* so we don't roll back to G_MAXUINT */
1605 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1607 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1608 guint j, k, len1, len2;
1609 GstStructure *struct1;
1610 GstStructure *struct2;
1611 GstCapsFeatures *features1;
1612 GstCapsFeatures *features2;
1614 GstStructure *istruct;
1616 dest = gst_caps_new_empty ();
1617 /* run zigzag on top line then right line, this preserves the caps order
1618 * much better than a simple loop.
1620 * This algorithm zigzags over the caps structures as demonstrated in
1621 * the following matrix:
1629 * First we iterate over the caps1 structures (top line) intersecting
1630 * the structures diagonally down, then we iterate over the caps2
1633 len1 = GST_CAPS_LEN (caps1);
1634 len2 = GST_CAPS_LEN (caps2);
1635 for (i = 0; i < len1 + len2 - 1; i++) {
1636 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1637 j = MIN (i, len1 - 1);
1638 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1639 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1640 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1641 /* now run the diagonal line, end condition is the left or bottom
1644 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1645 features1 = gst_caps_get_features_unchecked (caps1, j);
1647 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1648 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1649 features2 = gst_caps_get_features_unchecked (caps2, k);
1651 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1652 if (gst_caps_features_is_equal (features1, features2)) {
1653 istruct = gst_structure_intersect (struct1, struct2);
1655 if (gst_caps_features_is_any (features1))
1657 gst_caps_merge_structure_full (dest, istruct,
1658 gst_caps_features_copy_conditional (features2));
1661 gst_caps_merge_structure_full (dest, istruct,
1662 gst_caps_features_copy_conditional (features1));
1665 /* move down left */
1667 if (G_UNLIKELY (j == 0))
1668 break; /* so we don't roll back to G_MAXUINT */
1676 * gst_caps_intersect_first:
1677 * @caps1: a #GstCaps to intersect
1678 * @caps2: a #GstCaps to intersect
1680 * Creates a new #GstCaps that contains all the formats that are common
1681 * to both @caps1 and @caps2.
1683 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1684 * fashion as @caps1.
1686 * Returns: (transfer full): the new #GstCaps
1689 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1692 guint j, len1, len2;
1693 GstStructure *struct1;
1694 GstStructure *struct2;
1695 GstCapsFeatures *features1;
1696 GstCapsFeatures *features2;
1698 GstStructure *istruct;
1700 dest = gst_caps_new_empty ();
1701 len1 = GST_CAPS_LEN (caps1);
1702 len2 = GST_CAPS_LEN (caps2);
1703 for (i = 0; i < len1; i++) {
1704 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1705 features1 = gst_caps_get_features_unchecked (caps1, i);
1707 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1708 for (j = 0; j < len2; j++) {
1709 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1710 features2 = gst_caps_get_features_unchecked (caps2, j);
1712 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1713 if (gst_caps_features_is_equal (features1, features2)) {
1714 istruct = gst_structure_intersect (struct1, struct2);
1716 if (gst_caps_features_is_any (features1))
1718 gst_caps_merge_structure_full (dest, istruct,
1719 gst_caps_features_copy_conditional (features2));
1722 gst_caps_merge_structure_full (dest, istruct,
1723 gst_caps_features_copy_conditional (features1));
1733 * gst_caps_intersect_full:
1734 * @caps1: a #GstCaps to intersect
1735 * @caps2: a #GstCaps to intersect
1736 * @mode: The intersection algorithm/mode to use
1738 * Creates a new #GstCaps that contains all the formats that are common
1739 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1742 * Returns: (transfer full): the new #GstCaps
1745 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1746 GstCapsIntersectMode mode)
1748 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1749 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1751 /* Common fast-path */
1752 /* caps are exactly the same pointers, just copy one caps */
1753 if (G_UNLIKELY (caps1 == caps2))
1754 return gst_caps_ref (caps1);
1756 /* empty caps on either side, return empty */
1757 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1758 return gst_caps_ref (GST_CAPS_NONE);
1760 /* one of the caps is any, just copy the other caps */
1761 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1762 return gst_caps_ref (caps2);
1764 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1765 return gst_caps_ref (caps1);
1768 case GST_CAPS_INTERSECT_FIRST:
1769 return gst_caps_intersect_first (caps1, caps2);
1771 g_warning ("Unknown caps intersect mode: %d", mode);
1773 case GST_CAPS_INTERSECT_ZIG_ZAG:
1774 return gst_caps_intersect_zig_zag (caps1, caps2);
1779 * gst_caps_intersect:
1780 * @caps1: a #GstCaps to intersect
1781 * @caps2: a #GstCaps to intersect
1783 * Creates a new #GstCaps that contains all the formats that are common
1784 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1786 * Returns: (transfer full): the new #GstCaps
1789 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1791 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1794 /* subtract operation */
1798 const GstStructure *subtract_from;
1803 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1806 SubtractionEntry *e = user_data;
1807 GValue subtraction = { 0, };
1808 const GValue *other;
1809 GstStructure *structure;
1811 other = gst_structure_id_get_value (e->subtract_from, field_id);
1817 if (!gst_value_subtract (&subtraction, other, value))
1820 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1821 g_value_unset (&subtraction);
1824 structure = gst_structure_copy (e->subtract_from);
1825 gst_structure_id_take_value (structure, field_id, &subtraction);
1826 e->put_into = g_slist_prepend (e->put_into, structure);
1832 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1833 const GstStructure * subtrahend)
1838 e.subtract_from = minuend;
1840 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1841 gst_caps_structure_subtract_field, &e);
1848 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1849 gst_structure_free (walk->data);
1851 g_slist_free (e.put_into);
1858 * gst_caps_subtract:
1859 * @minuend: #GstCaps to subtract from
1860 * @subtrahend: #GstCaps to subtract
1862 * Subtracts the @subtrahend from the @minuend.
1863 * > This function does not work reliably if optional properties for caps
1864 * > are included on one caps and omitted on the other.
1866 * Returns: (transfer full): the resulting caps
1869 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1874 GstCapsFeatures *min_f, *sub_f;
1875 GstCaps *dest = NULL, *src;
1877 g_return_val_if_fail (minuend != NULL, NULL);
1878 g_return_val_if_fail (subtrahend != NULL, NULL);
1880 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1881 return gst_caps_new_empty ();
1884 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1885 return gst_caps_ref (minuend);
1887 /* FIXME: Do we want this here or above?
1888 The reason we need this is that there is no definition about what
1889 ANY means for specific types, so it's not possible to reduce ANY partially
1890 You can only remove everything or nothing and that is done above.
1891 Note: there's a test that checks this behaviour. */
1893 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1894 sublen = GST_CAPS_LEN (subtrahend);
1895 g_assert (sublen > 0);
1897 src = _gst_caps_copy (minuend);
1898 for (i = 0; i < sublen; i++) {
1901 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1902 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1904 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1906 gst_caps_unref (src);
1909 dest = gst_caps_new_empty ();
1910 srclen = GST_CAPS_LEN (src);
1911 for (j = 0; j < srclen; j++) {
1912 min = gst_caps_get_structure_unchecked (src, j);
1913 min_f = gst_caps_get_features_unchecked (src, j);
1915 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1917 /* Same reason as above for ANY caps */
1918 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1920 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1921 gst_caps_features_is_equal (min_f, sub_f)) {
1924 if (gst_caps_structure_subtract (&list, min, sub)) {
1927 for (walk = list; walk; walk = g_slist_next (walk)) {
1928 gst_caps_append_structure_unchecked (dest,
1929 (GstStructure *) walk->data,
1930 gst_caps_features_copy_conditional (min_f));
1932 g_slist_free (list);
1934 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1935 gst_caps_features_copy_conditional (min_f));
1938 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1939 gst_caps_features_copy_conditional (min_f));
1943 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1944 gst_caps_unref (src);
1949 gst_caps_unref (src);
1950 dest = gst_caps_simplify (dest);
1955 /* normalize/simplify operations */
1957 typedef struct _NormalizeForeach
1960 GstStructure *structure;
1961 GstCapsFeatures *features;
1965 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1967 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1971 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1972 guint len = gst_value_list_get_size (value);
1974 for (i = 1; i < len; i++) {
1975 const GValue *v = gst_value_list_get_value (value, i);
1976 GstStructure *structure = gst_structure_copy (nf->structure);
1978 gst_structure_id_set_value (structure, field_id, v);
1979 gst_caps_append_structure_unchecked (nf->caps, structure,
1980 gst_caps_features_copy_conditional (nf->features));
1983 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1984 gst_structure_id_take_value (nf->structure, field_id, &val);
1992 * gst_caps_normalize:
1993 * @caps: (transfer full): a #GstCaps to normalize
1995 * Returns a #GstCaps that represents the same set of formats as
1996 * @caps, but contains no lists. Each list is expanded into separate
1999 * This function takes ownership of @caps and will call gst_caps_make_writable()
2000 * on it so you must not use @caps afterwards unless you keep an additional
2001 * reference to it with gst_caps_ref().
2003 * Returns: (transfer full): the normalized #GstCaps
2006 gst_caps_normalize (GstCaps * caps)
2008 NormalizeForeach nf;
2011 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2013 caps = gst_caps_make_writable (caps);
2016 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
2017 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
2018 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
2019 while (!gst_structure_foreach (nf.structure,
2020 gst_caps_normalize_foreach, &nf));
2027 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
2030 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
2031 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
2033 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
2034 So what's the best way? */
2035 ret = strcmp (gst_structure_get_name (struct1),
2036 gst_structure_get_name (struct2));
2041 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
2048 GstStructure *compare;
2052 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
2055 UnionField *u = user_data;
2056 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
2060 g_value_unset (&u->value);
2064 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
2068 g_value_unset (&u->value);
2073 gst_value_union (&u->value, val, value);
2079 gst_caps_structure_simplify (GstStructure ** result,
2080 GstStructure * simplify, GstStructure * compare)
2083 UnionField field = { 0, {0,}, NULL };
2085 /* try to subtract to get a real subset */
2086 if (gst_caps_structure_subtract (&list, simplify, compare)) {
2087 if (list == NULL) { /* no result */
2090 } else if (list->next == NULL) { /* one result */
2091 *result = list->data;
2092 g_slist_free (list);
2094 } else { /* multiple results */
2095 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
2096 g_slist_free (list);
2101 /* try to union both structs */
2102 field.compare = compare;
2103 if (gst_structure_foreach (simplify,
2104 gst_caps_structure_figure_out_union, &field)) {
2105 gboolean ret = FALSE;
2107 /* now we know all of simplify's fields are the same in compare
2108 * but at most one field: field.name */
2109 if (G_IS_VALUE (&field.value)) {
2110 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
2111 gst_structure_id_take_value (compare, field.name, &field.value);
2115 g_value_unset (&field.value);
2118 if (gst_structure_n_fields (simplify) <=
2119 gst_structure_n_fields (compare)) {
2120 /* compare is just more specific, will be optimized away later */
2121 /* FIXME: do this here? */
2122 GST_LOG ("found a case that will be optimized later.");
2124 gchar *one = gst_structure_to_string (simplify);
2125 gchar *two = gst_structure_to_string (compare);
2128 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2140 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2141 GstStructure * new, gint i)
2143 gst_structure_set_parent_refcount (old, NULL);
2144 gst_structure_free (old);
2145 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2146 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2150 * gst_caps_simplify:
2151 * @caps: (transfer full): a #GstCaps to simplify
2153 * Converts the given @caps into a representation that represents the
2154 * same set of formats, but in a simpler form. Component structures that are
2155 * identical are merged. Component structures that have values that can be
2156 * merged are also merged.
2158 * This function takes ownership of @caps and will call gst_caps_make_writable()
2159 * on it if necessary, so you must not use @caps afterwards unless you keep an
2160 * additional reference to it with gst_caps_ref().
2162 * This method does not preserve the original order of @caps.
2164 * Returns: (transfer full): The simplified caps.
2167 gst_caps_simplify (GstCaps * caps)
2169 GstStructure *simplify, *compare, *result = NULL;
2170 GstCapsFeatures *simplify_f, *compare_f;
2173 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2175 /* empty/any caps are as simple as can be */
2176 if (GST_CAPS_LEN (caps) == 0)
2179 start = GST_CAPS_LEN (caps) - 1;
2180 /* one caps, already as simple as can be */
2184 caps = gst_caps_make_writable (caps);
2186 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2188 for (i = start; i >= 0; i--) {
2189 simplify = gst_caps_get_structure_unchecked (caps, i);
2190 simplify_f = gst_caps_get_features_unchecked (caps, i);
2192 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2193 compare = gst_caps_get_structure_unchecked (caps, start);
2194 compare_f = gst_caps_get_features_unchecked (caps, start);
2196 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2197 if (gst_structure_get_name_id (simplify) !=
2198 gst_structure_get_name_id (compare) ||
2199 !gst_caps_features_is_equal (simplify_f, compare_f))
2201 for (j = start; j >= 0; j--) {
2204 compare = gst_caps_get_structure_unchecked (caps, j);
2205 compare_f = gst_caps_get_features_unchecked (caps, j);
2207 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2208 if (gst_structure_get_name_id (simplify) !=
2209 gst_structure_get_name_id (compare) ||
2210 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2213 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2215 gst_caps_switch_structures (caps, simplify, result, i);
2218 gst_caps_remove_structure (caps, i);
2230 * @caps: (transfer full): a #GstCaps to fixate
2232 * Modifies the given @caps into a representation with only fixed
2233 * values. First the caps will be truncated and then the first structure will be
2234 * fixated with gst_structure_fixate().
2236 * This function takes ownership of @caps and will call gst_caps_make_writable()
2237 * on it so you must not use @caps afterwards unless you keep an additional
2238 * reference to it with gst_caps_ref().
2240 * Note that it is not guaranteed that the returned caps have exactly one
2241 * structure. If @caps are empty caps then the returned caps will be
2242 * the empty too and contain no structure at all.
2244 * Calling this function with ANY caps is not allowed.
2246 * Returns: (transfer full): the fixated caps
2249 gst_caps_fixate (GstCaps * caps)
2254 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2255 g_return_val_if_fail (!CAPS_IS_ANY (caps), NULL);
2257 /* default fixation */
2258 caps = gst_caps_truncate (caps);
2259 caps = gst_caps_make_writable (caps);
2261 /* need to return early here because empty caps have no structure
2262 * but must return after make_writable() because the documentation
2263 * specifies that it will call make_writable() on the return value
2264 * and callers might assume writable caps.
2266 if (CAPS_IS_EMPTY (caps))
2269 s = gst_caps_get_structure (caps, 0);
2270 gst_structure_fixate (s);
2272 /* Set features to sysmem if they're still ANY */
2273 f = gst_caps_get_features_unchecked (caps, 0);
2274 if (f && gst_caps_features_is_any (f)) {
2275 f = gst_caps_features_new_empty ();
2276 gst_caps_set_features (caps, 0, f);
2285 caps_serialize (const GstCaps * caps, GstSerializeFlags flags)
2287 guint i, slen, clen;
2289 gboolean nested_structs_brackets =
2290 !(flags & GST_SERIALIZE_FLAG_BACKWARD_COMPAT);
2292 /* NOTE: This function is potentially called by the debug system,
2293 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2294 * should be careful to avoid recursion. This includes any functions
2295 * called by gst_caps_to_string. In particular, calls should
2296 * not use the GST_PTR_FORMAT extension. */
2299 return g_strdup ("NULL");
2301 if (CAPS_IS_ANY (caps)) {
2302 return g_strdup ("ANY");
2304 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2305 return g_strdup ("EMPTY");
2308 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2310 clen = GST_CAPS_LEN (caps);
2311 for (i = 0; i < clen; i++) {
2315 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2317 f = gst_caps_get_features_unchecked (caps, i);
2319 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2322 s = g_string_sized_new (slen);
2323 for (i = 0; i < clen; i++) {
2324 GstStructure *structure;
2325 GstCapsFeatures *features;
2328 /* ';' is now added by gst_structure_to_string */
2329 g_string_append_c (s, ' ');
2332 structure = gst_caps_get_structure_unchecked (caps, i);
2333 features = gst_caps_get_features_unchecked (caps, i);
2335 g_string_append (s, gst_structure_get_name (structure));
2336 if (features && (gst_caps_features_is_any (features)
2337 || !gst_caps_features_is_equal (features,
2338 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2339 g_string_append_c (s, '(');
2340 priv_gst_caps_features_append_to_gstring (features, s);
2341 g_string_append_c (s, ')');
2343 priv_gst_structure_append_to_gstring (structure, s,
2344 nested_structs_brackets);
2346 if (s->len && s->str[s->len - 1] == ';') {
2347 /* remove latest ';' */
2348 s->str[--s->len] = '\0';
2350 return g_string_free (s, FALSE);
2354 * gst_caps_to_string:
2357 * Converts @caps to a string representation. This string representation
2358 * can be converted back to a #GstCaps by gst_caps_from_string().
2360 * For debugging purposes its easier to do something like this:
2363 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2366 * This prints the caps in human readable form.
2368 * The implementation of serialization up to 1.20 would lead to unexpected results
2369 * when there were nested #GstCaps / #GstStructure deeper than one level.
2371 * Returns: (transfer full): a newly allocated string representing @caps.
2374 gst_caps_to_string (const GstCaps * caps)
2376 return caps_serialize (caps, GST_SERIALIZE_FLAG_BACKWARD_COMPAT);
2380 * gst_caps_serialize:
2382 * @flags: a #GstSerializeFlags
2384 * Converts @caps to a string representation. This string representation can be
2385 * converted back to a #GstCaps by gst_caps_from_string().
2387 * This prints the caps in human readable form.
2389 * This version of the caps serialization function introduces support for nested
2390 * structures and caps but the resulting strings won't be parsable with
2391 * GStreamer prior to 1.20 unless #GST_SERIALIZE_FLAG_BACKWARD_COMPAT is passed
2394 * Returns: (transfer full): a newly allocated string representing @caps.
2399 gst_caps_serialize (const GstCaps * caps, GstSerializeFlags flags)
2401 return caps_serialize (caps, flags);
2405 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2407 GstStructure *structure;
2408 gchar *s, *copy, *end, *next, save;
2410 if (strcmp ("ANY", string) == 0) {
2411 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2415 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2419 copy = s = g_strdup (string);
2421 GstCapsFeatures *features = NULL;
2423 while (g_ascii_isspace (*s))
2429 if (!priv_gst_structure_parse_name (s, &s, &end, &next, FALSE)) {
2436 structure = gst_structure_new_empty (s);
2439 if (structure == NULL) {
2457 } else if (*end == ')') {
2466 features = gst_caps_features_from_string (s);
2468 gst_structure_free (structure);
2482 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2483 gst_structure_free (structure);
2485 gst_caps_features_free (features);
2491 gst_caps_append_structure_unchecked (caps, structure, features);
2503 * gst_caps_from_string:
2504 * @string: a string to convert to #GstCaps
2506 * Converts @caps from a string representation.
2508 * The implementation of serialization up to 1.20 would lead to unexpected results
2509 * when there were nested #GstCaps / #GstStructure deeper than one level.
2511 * Returns: (transfer full) (nullable): a newly allocated #GstCaps
2514 gst_caps_from_string (const gchar * string)
2518 g_return_val_if_fail (string, NULL);
2520 caps = gst_caps_new_empty ();
2521 if (gst_caps_from_string_inplace (caps, string)) {
2524 gst_caps_unref (caps);
2530 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2532 g_return_if_fail (G_IS_VALUE (src_value));
2533 g_return_if_fail (G_IS_VALUE (dest_value));
2534 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2535 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2536 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2538 g_value_take_string (dest_value,
2539 gst_caps_to_string (gst_value_get_caps (src_value)));
2545 * @func: (scope call): a function to call for each field
2546 * @user_data: (closure): private data
2548 * Calls the provided function once for each structure and caps feature in the
2549 * #GstCaps. The function must not modify the fields.
2550 * Also see gst_caps_map_in_place() and gst_caps_filter_and_map_in_place().
2552 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2558 gst_caps_foreach (const GstCaps * caps, GstCapsForeachFunc func,
2562 GstCapsFeatures *features;
2563 GstStructure *structure;
2566 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2567 g_return_val_if_fail (func != NULL, FALSE);
2569 n = GST_CAPS_LEN (caps);
2571 for (i = 0; i < n; i++) {
2572 features = gst_caps_get_features_unchecked (caps, i);
2573 structure = gst_caps_get_structure_unchecked (caps, i);
2575 ret = func (features, structure, user_data);
2576 if (G_UNLIKELY (!ret))
2584 * gst_caps_map_in_place:
2586 * @func: (scope call): a function to call for each field
2587 * @user_data: (closure): private data
2589 * Calls the provided function once for each structure and caps feature in the
2590 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify but not
2591 * delete the structures and features. The caps must be mutable.
2593 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2599 gst_caps_map_in_place (GstCaps * caps, GstCapsMapFunc func, gpointer user_data)
2602 GstCapsFeatures *features;
2603 GstStructure *structure;
2606 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2607 g_return_val_if_fail (gst_caps_is_writable (caps), FALSE);
2608 g_return_val_if_fail (func != NULL, FALSE);
2610 n = GST_CAPS_LEN (caps);
2612 for (i = 0; i < n; i++) {
2613 features = gst_caps_get_features_unchecked (caps, i);
2614 structure = gst_caps_get_structure_unchecked (caps, i);
2616 /* Provide sysmem features if there are none yet */
2619 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2620 gst_caps_set_features (caps, i, features);
2623 ret = func (features, structure, user_data);
2624 if (G_UNLIKELY (!ret))
2632 * gst_caps_filter_and_map_in_place:
2634 * @func: (scope call): a function to call for each field
2635 * @user_data: (closure): private data
2637 * Calls the provided function once for each structure and caps feature in the
2638 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify the
2639 * structure and features. In contrast to gst_caps_filter_and_map_in_place(),
2640 * the structure and features are removed from the caps if %FALSE is returned
2641 * from the function.
2642 * The caps must be mutable.
2647 gst_caps_filter_and_map_in_place (GstCaps * caps, GstCapsFilterMapFunc func,
2651 GstCapsFeatures *features;
2652 GstStructure *structure;
2655 g_return_if_fail (GST_IS_CAPS (caps));
2656 g_return_if_fail (gst_caps_is_writable (caps));
2657 g_return_if_fail (func != NULL);
2659 n = GST_CAPS_LEN (caps);
2661 for (i = 0; i < n;) {
2662 features = gst_caps_get_features_unchecked (caps, i);
2663 structure = gst_caps_get_structure_unchecked (caps, i);
2665 /* Provide sysmem features if there are none yet */
2668 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2669 gst_caps_set_features (caps, i, features);
2672 ret = func (features, structure, user_data);
2674 GST_CAPS_ARRAY (caps) = g_array_remove_index (GST_CAPS_ARRAY (caps), i);
2676 gst_structure_set_parent_refcount (structure, NULL);
2677 gst_structure_free (structure);
2679 gst_caps_features_set_parent_refcount (features, NULL);
2680 gst_caps_features_free (features);
2683 n = GST_CAPS_LEN (caps);
2692 * @caps: a #GstCaps.
2694 * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
2695 * refcount of 1, owned by the caller. The structures are copied as well.
2697 * Note that this function is the semantic equivalent of a gst_caps_ref()
2698 * followed by a gst_caps_make_writable(). If you only want to hold on to a
2699 * reference to the data, you should use gst_caps_ref().
2701 * Returns: (transfer full): the new #GstCaps
2703 GstCaps *(gst_caps_copy) (const GstCaps * caps)
2705 return GST_CAPS (gst_mini_object_copy (GST_MINI_OBJECT_CAST (caps)));
2709 * gst_caps_ref: (skip)
2710 * @caps: the #GstCaps to reference
2712 * Adds a reference to a #GstCaps object.
2714 * From this point on, until the caller calls gst_caps_unref() or
2715 * gst_caps_make_writable(), it is guaranteed that the caps object will not
2716 * change. This means its structures won't change, etc. To use a #GstCaps
2717 * object, you must always have a refcount on it -- either the one made
2718 * implicitly by e.g. gst_caps_new_simple(), or via taking one explicitly with
2721 * Returns: the same #GstCaps object.
2724 gst_caps_ref (GstCaps * caps)
2726 return (GstCaps *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (caps));
2730 * gst_caps_unref: (skip)
2731 * @caps: a #GstCaps.
2733 * Unrefs a #GstCaps and frees all its structures and the
2734 * structures' values when the refcount reaches 0.
2737 gst_caps_unref (GstCaps * caps)
2739 gst_mini_object_unref (GST_MINI_OBJECT_CAST (caps));
2743 * gst_clear_caps: (skip)
2744 * @caps_ptr: a pointer to a #GstCaps reference
2746 * Clears a reference to a #GstCaps.
2748 * @caps_ptr must not be %NULL.
2750 * If the reference is %NULL then this function does nothing. Otherwise, the
2751 * reference count of the caps is decreased and the pointer is set to %NULL.
2756 gst_clear_caps (GstCaps ** caps_ptr)
2758 gst_clear_mini_object ((GstMiniObject **) caps_ptr);
2762 * gst_caps_replace: (skip)
2763 * @old_caps: (inout) (transfer full) (nullable): pointer to a pointer
2764 * to a #GstCaps to be replaced.
2765 * @new_caps: (transfer none) (allow-none): pointer to a #GstCaps that will
2766 * replace the caps pointed to by @old_caps.
2768 * Modifies a pointer to a #GstCaps to point to a different #GstCaps. The
2769 * modification is done atomically (so this is useful for ensuring thread safety
2770 * in some cases), and the reference counts are updated appropriately (the old
2771 * caps is unreffed, the new is reffed).
2773 * Either @new_caps or the #GstCaps pointed to by @old_caps may be %NULL.
2775 * Returns: %TRUE if @new_caps was different from @old_caps
2778 gst_caps_replace (GstCaps ** old_caps, GstCaps * new_caps)
2780 return gst_mini_object_replace ((GstMiniObject **) old_caps,
2781 (GstMiniObject *) new_caps);
2785 * gst_caps_take: (skip)
2786 * @old_caps: (inout) (transfer full): pointer to a pointer to a #GstCaps to be
2788 * @new_caps: (transfer full) (allow-none): pointer to a #GstCaps that will
2789 * replace the caps pointed to by @old_caps.
2791 * Modifies a pointer to a #GstCaps to point to a different #GstCaps. This
2792 * function is similar to gst_caps_replace() except that it takes ownership
2795 * Returns: %TRUE if @new_caps was different from @old_caps
2798 gst_caps_take (GstCaps ** old_caps, GstCaps * new_caps)
2800 return gst_mini_object_take ((GstMiniObject **) old_caps,
2801 (GstMiniObject *) new_caps);