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.
22 * @short_description: Structure describing sets of media formats
23 * @see_also: #GstStructure, #GstMiniObject
25 * Caps (capabilities) are lightweight refcounted objects describing media types.
26 * They are composed of an array of #GstStructure.
28 * Caps are exposed on #GstPadTemplate to describe all possible types a
29 * given pad can handle. They are also stored in the #GstRegistry along with
30 * a description of the #GstElement.
32 * Caps are exposed on the element pads using the gst_pad_query_caps() pad
33 * function. This function describes the possible types that the pad can
34 * handle or produce at runtime.
36 * A #GstCaps can be constructed with the following code fragment:
37 * |[<!-- language="C" -->
38 * GstCaps *caps = gst_caps_new_simple ("video/x-raw",
39 * "format", G_TYPE_STRING, "I420",
40 * "framerate", GST_TYPE_FRACTION, 25, 1,
41 * "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
42 * "width", G_TYPE_INT, 320,
43 * "height", G_TYPE_INT, 240,
47 * A #GstCaps is fixed when it has no properties with ranges or lists. Use
48 * gst_caps_is_fixed() to test for fixed caps. Fixed caps can be used in a
49 * caps event to notify downstream elements of the current media type.
51 * Various methods exist to work with the media types such as subtracting
54 * Be aware that the current #GstCaps / #GstStructure serialization into string
55 * has limited support for nested #GstCaps / #GstStructure fields. It can only
56 * support one level of nesting. Using more levels will lead to unexpected
57 * behavior when using serialization features, such as gst_caps_to_string() or
58 * gst_value_serialize() and their counterparts.
67 #include "gst_private.h"
69 #include <gobject/gvaluecollector.h>
71 #define DEBUG_REFCOUNT
73 typedef struct _GstCapsArrayElement
75 GstStructure *structure;
76 GstCapsFeatures *features;
77 } GstCapsArrayElement;
79 typedef struct _GstCapsImpl
86 #define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
88 #define GST_CAPS_LEN(c) (GST_CAPS_ARRAY(c)->len)
90 #define IS_WRITABLE(caps) \
91 (GST_CAPS_REFCOUNT_VALUE (caps) == 1)
93 /* same as gst_caps_is_any () */
94 #define CAPS_IS_ANY(caps) \
95 (!!(GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY))
97 /* same as gst_caps_is_empty () */
98 #define CAPS_IS_EMPTY(caps) \
99 (!CAPS_IS_ANY(caps) && CAPS_IS_EMPTY_SIMPLE(caps))
101 #define CAPS_IS_EMPTY_SIMPLE(caps) \
102 ((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
104 #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)
106 /* quick way to get a caps structure at an index without doing a type or array
108 #define gst_caps_get_structure_unchecked(caps, index) \
109 (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).structure)
110 #define gst_caps_get_features_storage_unchecked(caps, index) \
111 (&g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
112 #define gst_caps_get_features_unchecked(caps, index) \
113 (g_atomic_pointer_get (gst_caps_get_features_storage_unchecked (caps, index)))
114 /* quick way to append a structure without checking the args */
115 #define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
116 GstCapsArrayElement __e={s, f}; \
117 if (gst_structure_set_parent_refcount (__e.structure, &GST_MINI_OBJECT_REFCOUNT(caps)) && \
118 (!__e.features || gst_caps_features_set_parent_refcount (__e.features, &GST_MINI_OBJECT_REFCOUNT(caps)))) \
119 g_array_append_val (GST_CAPS_ARRAY (caps), __e); \
122 /* lock to protect multiple invocations of static caps to caps conversion */
123 G_LOCK_DEFINE_STATIC (static_caps_lock);
125 static void gst_caps_transform_to_string (const GValue * src_value,
126 GValue * dest_value);
127 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
128 const gchar * string);
130 GType _gst_caps_type = 0;
131 GstCaps *_gst_caps_any;
132 GstCaps *_gst_caps_none;
134 GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
137 _priv_gst_caps_initialize (void)
139 _gst_caps_type = gst_caps_get_type ();
141 _gst_caps_any = gst_caps_new_any ();
142 _gst_caps_none = gst_caps_new_empty ();
144 g_value_register_transform_func (_gst_caps_type,
145 G_TYPE_STRING, gst_caps_transform_to_string);
149 _priv_gst_caps_cleanup (void)
151 gst_caps_unref (_gst_caps_any);
152 _gst_caps_any = NULL;
153 gst_caps_unref (_gst_caps_none);
154 _gst_caps_none = NULL;
158 __gst_caps_get_features_unchecked (const GstCaps * caps, guint idx)
160 return gst_caps_get_features_unchecked (caps, idx);
164 _gst_caps_copy (const GstCaps * caps)
167 GstStructure *structure;
168 GstCapsFeatures *features;
171 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
173 newcaps = gst_caps_new_empty ();
174 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
175 n = GST_CAPS_LEN (caps);
177 GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, caps, "doing copy %p -> %p",
180 for (i = 0; i < n; i++) {
181 structure = gst_caps_get_structure_unchecked (caps, i);
182 features = gst_caps_get_features_unchecked (caps, i);
183 gst_caps_append_structure_full (newcaps, gst_structure_copy (structure),
184 gst_caps_features_copy_conditional (features));
190 /* creation/deletion */
192 _gst_caps_free (GstCaps * caps)
194 GstStructure *structure;
195 GstCapsFeatures *features;
198 /* The refcount must be 0, but since we're only called by gst_caps_unref,
199 * don't bother testing. */
200 len = GST_CAPS_LEN (caps);
201 /* This can be used to get statistics about caps sizes */
202 /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
203 for (i = 0; i < len; i++) {
204 structure = gst_caps_get_structure_unchecked (caps, i);
205 gst_structure_set_parent_refcount (structure, NULL);
206 gst_structure_free (structure);
207 features = gst_caps_get_features_unchecked (caps, i);
209 gst_caps_features_set_parent_refcount (features, NULL);
210 gst_caps_features_free (features);
213 g_array_free (GST_CAPS_ARRAY (caps), TRUE);
215 #ifdef DEBUG_REFCOUNT
216 GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
218 g_slice_free1 (sizeof (GstCapsImpl), caps);
222 gst_caps_init (GstCaps * caps)
224 gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
225 (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
226 (GstMiniObjectFreeFunction) _gst_caps_free);
228 /* the 32 has been determined by logging caps sizes in _gst_caps_free
229 * but g_ptr_array uses 16 anyway if it expands once, so this does not help
231 * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
233 GST_CAPS_ARRAY (caps) =
234 g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
238 * gst_caps_new_empty:
240 * Creates a new #GstCaps that is empty. That is, the returned
241 * #GstCaps contains no media formats.
242 * The #GstCaps is guaranteed to be writable.
243 * Caller is responsible for unreffing the returned caps.
245 * Returns: (transfer full): the new #GstCaps
248 gst_caps_new_empty (void)
252 caps = (GstCaps *) g_slice_new (GstCapsImpl);
254 gst_caps_init (caps);
256 #ifdef DEBUG_REFCOUNT
257 GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
266 * Creates a new #GstCaps that indicates that it is compatible with
269 * Returns: (transfer full): the new #GstCaps
272 gst_caps_new_any (void)
274 GstCaps *caps = gst_caps_new_empty ();
276 GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_ANY);
282 * gst_caps_new_empty_simple:
283 * @media_type: the media type of the structure
285 * Creates a new #GstCaps that contains one #GstStructure with name
287 * Caller is responsible for unreffing the returned caps.
289 * Returns: (transfer full): the new #GstCaps
292 gst_caps_new_empty_simple (const char *media_type)
295 GstStructure *structure;
297 caps = gst_caps_new_empty ();
298 structure = gst_structure_new_empty (media_type);
300 gst_caps_append_structure_unchecked (caps, structure, NULL);
306 * gst_caps_new_simple:
307 * @media_type: the media type of the structure
308 * @fieldname: first field to set
309 * @...: additional arguments
311 * Creates a new #GstCaps that contains one #GstStructure. The
312 * structure is defined by the arguments, which have the same format
313 * as gst_structure_new().
314 * Caller is responsible for unreffing the returned caps.
316 * Returns: (transfer full): the new #GstCaps
319 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
322 GstStructure *structure;
325 caps = gst_caps_new_empty ();
327 va_start (var_args, fieldname);
328 structure = gst_structure_new_valist (media_type, fieldname, var_args);
332 gst_caps_append_structure_unchecked (caps, structure, NULL);
334 gst_caps_replace (&caps, NULL);
341 * @struct1: the first structure to add
342 * @...: additional structures to add
344 * Creates a new #GstCaps and adds all the structures listed as
345 * arguments. The list must be %NULL-terminated. The structures
346 * are not copied; the returned #GstCaps owns the structures.
348 * Returns: (transfer full): the new #GstCaps
351 gst_caps_new_full (GstStructure * struct1, ...)
356 va_start (var_args, struct1);
357 caps = gst_caps_new_full_valist (struct1, var_args);
364 * gst_caps_new_full_valist:
365 * @structure: the first structure to add
366 * @var_args: additional structures to add
368 * Creates a new #GstCaps and adds all the structures listed as
369 * arguments. The list must be %NULL-terminated. The structures
370 * are not copied; the returned #GstCaps owns the structures.
372 * Returns: (transfer full): the new #GstCaps
375 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
379 caps = gst_caps_new_empty ();
382 gst_caps_append_structure_unchecked (caps, structure, NULL);
383 structure = va_arg (var_args, GstStructure *);
389 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
392 * gst_static_caps_get:
393 * @static_caps: the #GstStaticCaps to convert
395 * Converts a #GstStaticCaps to a #GstCaps.
397 * Returns: (transfer full): a pointer to the #GstCaps. Unref after usage.
398 * Since the core holds an additional ref to the returned caps,
399 * use gst_caps_make_writable() on the returned caps to modify it.
402 gst_static_caps_get (GstStaticCaps * static_caps)
406 g_return_val_if_fail (static_caps != NULL, NULL);
408 caps = &static_caps->caps;
410 /* refcount is 0 when we need to convert */
411 if (G_UNLIKELY (*caps == NULL)) {
414 G_LOCK (static_caps_lock);
415 /* check if other thread already updated */
416 if (G_UNLIKELY (*caps != NULL))
419 string = static_caps->string;
421 if (G_UNLIKELY (string == NULL))
424 *caps = gst_caps_from_string (string);
426 /* Caps generated from static caps are usually leaked */
427 GST_MINI_OBJECT_FLAG_SET (*caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
429 /* convert to string */
430 if (G_UNLIKELY (*caps == NULL))
431 g_critical ("Could not convert static caps \"%s\"", string);
433 GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
436 G_UNLOCK (static_caps_lock);
438 /* ref the caps, makes it not writable */
439 if (G_LIKELY (*caps != NULL))
440 gst_caps_ref (*caps);
447 G_UNLOCK (static_caps_lock);
448 g_warning ("static caps %p string is NULL", static_caps);
454 * gst_static_caps_cleanup:
455 * @static_caps: the #GstStaticCaps to clean
457 * Clean up the cached caps contained in @static_caps.
460 gst_static_caps_cleanup (GstStaticCaps * static_caps)
462 G_LOCK (static_caps_lock);
463 gst_caps_replace (&static_caps->caps, NULL);
464 G_UNLOCK (static_caps_lock);
470 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
471 GstStructure ** s, GstCapsFeatures ** f)
476 s_ = gst_caps_get_structure_unchecked (caps, idx);
477 f_ = gst_caps_get_features_unchecked (caps, idx);
479 /* don't use index_fast, gst_caps_simplify relies on the order */
480 g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
482 gst_structure_set_parent_refcount (s_, NULL);
484 gst_caps_features_set_parent_refcount (f_, NULL);
491 static GstStructure *
492 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
497 gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
500 gst_caps_features_free (f);
506 * gst_caps_steal_structure:
507 * @caps: the #GstCaps to retrieve from
508 * @index: Index of the structure to retrieve
510 * Retrieves the structure with the given index from the list of structures
511 * contained in @caps. The caller becomes the owner of the returned structure.
513 * Returns: (transfer full): a pointer to the #GstStructure corresponding
517 gst_caps_steal_structure (GstCaps * caps, guint index)
519 g_return_val_if_fail (caps != NULL, NULL);
520 g_return_val_if_fail (IS_WRITABLE (caps), NULL);
522 if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
525 return gst_caps_remove_and_get_structure (caps, index);
530 * @caps1: the #GstCaps that will be appended to
531 * @caps2: (transfer full): the #GstCaps to append
533 * Appends the structures contained in @caps2 to @caps1. The structures in
534 * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
535 * freed. If either caps is ANY, the resulting caps will be ANY.
538 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
540 GstStructure *structure;
541 GstCapsFeatures *features;
544 g_return_if_fail (GST_IS_CAPS (caps1));
545 g_return_if_fail (GST_IS_CAPS (caps2));
546 g_return_if_fail (IS_WRITABLE (caps1));
548 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
549 GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
550 gst_caps_unref (caps2);
552 caps2 = gst_caps_make_writable (caps2);
554 for (i = GST_CAPS_LEN (caps2); i; i--) {
555 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
557 gst_caps_append_structure_unchecked (caps1, structure, features);
559 gst_caps_unref (caps2); /* guaranteed to free it */
565 * @caps1: (transfer full): the #GstCaps that will take the new entries
566 * @caps2: (transfer full): the #GstCaps to merge in
568 * Appends the structures contained in @caps2 to @caps1 if they are not yet
569 * expressed by @caps1. The structures in @caps2 are not copied -- they are
570 * transferred to a writable copy of @caps1, and then @caps2 is freed.
571 * If either caps is ANY, the resulting caps will be ANY.
573 * Returns: (transfer full): the merged caps.
576 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
578 GstStructure *structure;
579 GstCapsFeatures *features;
583 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
584 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
586 if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
587 gst_caps_unref (caps2);
589 } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
590 gst_caps_unref (caps1);
593 caps2 = gst_caps_make_writable (caps2);
595 for (i = GST_CAPS_LEN (caps2); i; i--) {
596 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
598 caps1 = gst_caps_merge_structure_full (caps1, structure, features);
600 gst_caps_unref (caps2);
604 GstCaps *com = gst_caps_intersect (caps1, caps2);
605 GstCaps *add = gst_caps_subtract (caps2, com);
607 GST_DEBUG ("common : %d", gst_caps_get_size (com));
608 GST_DEBUG ("adding : %d", gst_caps_get_size (add));
609 gst_caps_append (caps1, add);
610 gst_caps_unref (com);
618 * gst_caps_append_structure:
619 * @caps: the #GstCaps that will be appended to
620 * @structure: (transfer full): the #GstStructure to append
622 * Appends @structure to @caps. The structure is not copied; @caps
623 * becomes the owner of @structure.
626 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
628 g_return_if_fail (GST_IS_CAPS (caps));
629 g_return_if_fail (IS_WRITABLE (caps));
631 if (G_LIKELY (structure)) {
632 gst_caps_append_structure_unchecked (caps, structure, NULL);
637 * gst_caps_append_structure_full:
638 * @caps: the #GstCaps that will be appended to
639 * @structure: (transfer full): the #GstStructure to append
640 * @features: (transfer full) (allow-none): the #GstCapsFeatures to append
642 * Appends @structure with @features to @caps. The structure is not copied; @caps
643 * becomes the owner of @structure.
648 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
649 GstCapsFeatures * features)
651 g_return_if_fail (GST_IS_CAPS (caps));
652 g_return_if_fail (IS_WRITABLE (caps));
654 if (G_LIKELY (structure)) {
655 gst_caps_append_structure_unchecked (caps, structure, features);
660 * gst_caps_remove_structure:
661 * @caps: the #GstCaps to remove from
662 * @idx: Index of the structure to remove
664 * removes the structure with the given index from the list of structures
665 * contained in @caps.
668 gst_caps_remove_structure (GstCaps * caps, guint idx)
670 GstStructure *structure;
672 g_return_if_fail (caps != NULL);
673 g_return_if_fail (idx <= gst_caps_get_size (caps));
674 g_return_if_fail (IS_WRITABLE (caps));
676 structure = gst_caps_remove_and_get_structure (caps, idx);
677 gst_structure_free (structure);
681 * gst_caps_merge_structure:
682 * @caps: (transfer full): the #GstCaps to merge into
683 * @structure: (transfer full): the #GstStructure to merge
685 * Appends @structure to @caps if its not already expressed by @caps.
687 * Returns: (transfer full): the merged caps.
690 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
692 GstStructure *structure1;
693 GstCapsFeatures *features1;
695 gboolean unique = TRUE;
697 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
699 if (G_UNLIKELY (structure == NULL))
702 /* check each structure */
703 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
704 structure1 = gst_caps_get_structure_unchecked (caps, i);
705 features1 = gst_caps_get_features_unchecked (caps, i);
707 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
709 /* if structure is a subset of structure1 and the
710 * there are no existing features, then skip it */
711 if (gst_caps_features_is_equal (features1,
712 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
713 && gst_structure_is_subset (structure, structure1)) {
719 caps = gst_caps_make_writable (caps);
720 gst_caps_append_structure_unchecked (caps, structure, NULL);
722 gst_structure_free (structure);
728 * gst_caps_merge_structure_full:
729 * @caps: (transfer full): the #GstCaps to merge into
730 * @structure: (transfer full): the #GstStructure to merge
731 * @features: (transfer full) (allow-none): the #GstCapsFeatures to merge
733 * Appends @structure with @features to @caps if its not already expressed by @caps.
735 * Returns: (transfer full): the merged caps.
740 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
741 GstCapsFeatures * features)
743 GstStructure *structure1;
744 GstCapsFeatures *features1, *features_tmp;
746 gboolean unique = TRUE;
748 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
750 if (G_UNLIKELY (structure == NULL))
753 /* To make comparisons easier below */
754 features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
756 /* check each structure */
757 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
758 structure1 = gst_caps_get_structure_unchecked (caps, i);
759 features1 = gst_caps_get_features_unchecked (caps, i);
761 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
762 /* if structure is a subset of structure1 and the
763 * the features are a subset, then skip it */
764 /* FIXME: We only skip if none of the features are
765 * ANY and are still equal. That way all ANY structures
766 * show up in the caps and no non-ANY structures are
767 * swallowed by ANY structures
769 if (((!gst_caps_features_is_any (features_tmp)
770 || gst_caps_features_is_any (features1))
771 && gst_caps_features_is_equal (features_tmp, features1))
772 && gst_structure_is_subset (structure, structure1)) {
778 caps = gst_caps_make_writable (caps);
779 gst_caps_append_structure_unchecked (caps, structure, features);
781 gst_structure_free (structure);
783 gst_caps_features_free (features);
792 * Gets the number of structures contained in @caps.
794 * Returns: the number of structures that @caps contains
797 gst_caps_get_size (const GstCaps * caps)
799 g_return_val_if_fail (GST_IS_CAPS (caps), 0);
801 return GST_CAPS_LEN (caps);
805 * gst_caps_get_structure:
807 * @index: the index of the structure
809 * Finds the structure in @caps that has the index @index, and
812 * WARNING: This function takes a const GstCaps *, but returns a
813 * non-const GstStructure *. This is for programming convenience --
814 * the caller should be aware that structures inside a constant
815 * #GstCaps should not be modified. However, if you know the caps
816 * are writable, either because you have just copied them or made
817 * them writable with gst_caps_make_writable(), you may modify the
818 * structure returned in the usual way, e.g. with functions like
819 * gst_structure_set().
821 * You do not need to free or unref the structure returned, it
822 * belongs to the #GstCaps.
824 * Returns: (transfer none): a pointer to the #GstStructure corresponding
828 gst_caps_get_structure (const GstCaps * caps, guint index)
830 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
831 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
833 return gst_caps_get_structure_unchecked (caps, index);
837 * gst_caps_get_features:
839 * @index: the index of the structure
841 * Finds the features in @caps that has the index @index, and
844 * WARNING: This function takes a const GstCaps *, but returns a
845 * non-const GstCapsFeatures *. This is for programming convenience --
846 * the caller should be aware that structures inside a constant
847 * #GstCaps should not be modified. However, if you know the caps
848 * are writable, either because you have just copied them or made
849 * them writable with gst_caps_make_writable(), you may modify the
850 * features returned in the usual way, e.g. with functions like
851 * gst_caps_features_add().
853 * You do not need to free or unref the structure returned, it
854 * belongs to the #GstCaps.
856 * Returns: (transfer none): a pointer to the #GstCapsFeatures corresponding
862 gst_caps_get_features (const GstCaps * caps, guint index)
864 GstCapsFeatures *features;
866 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
867 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
869 features = gst_caps_get_features_unchecked (caps, index);
871 GstCapsFeatures **storage;
873 /* We have to do some atomic pointer magic here as the caps
874 * might not be writable and someone else calls this function
875 * at the very same time */
876 features = gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
877 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
879 storage = gst_caps_get_features_storage_unchecked (caps, index);
880 if (!g_atomic_pointer_compare_and_exchange (storage, NULL, features)) {
881 /* Someone did the same we just tried in the meantime */
882 gst_caps_features_set_parent_refcount (features, NULL);
883 gst_caps_features_free (features);
885 features = gst_caps_get_features_unchecked (caps, index);
886 g_assert (features != NULL);
894 * gst_caps_set_features:
896 * @index: the index of the structure
897 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
899 * Sets the #GstCapsFeatures @features for the structure at @index.
904 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
906 GstCapsFeatures **storage, *old;
908 g_return_if_fail (caps != NULL);
909 g_return_if_fail (index <= gst_caps_get_size (caps));
910 g_return_if_fail (IS_WRITABLE (caps));
912 storage = gst_caps_get_features_storage_unchecked (caps, index);
913 /* Not much problem here as caps are writable */
914 old = g_atomic_pointer_get (storage);
915 g_atomic_pointer_set (storage, features);
918 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
921 gst_caps_features_set_parent_refcount (old, NULL);
922 gst_caps_features_free (old);
928 * @caps: the #GstCaps to copy
929 * @nth: the nth structure to copy
931 * Creates a new #GstCaps and appends a copy of the nth structure
932 * contained in @caps.
934 * Returns: (transfer full): the new #GstCaps
937 gst_caps_copy_nth (const GstCaps * caps, guint nth)
940 GstStructure *structure;
941 GstCapsFeatures *features;
943 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
945 newcaps = gst_caps_new_empty ();
946 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
948 if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
949 structure = gst_caps_get_structure_unchecked (caps, nth);
950 features = gst_caps_get_features_unchecked (caps, nth);
951 gst_caps_append_structure_unchecked (newcaps,
952 gst_structure_copy (structure),
953 gst_caps_features_copy_conditional (features));
961 * @caps: (transfer full): the #GstCaps to truncate
963 * Discard all but the first structure from @caps. Useful when
966 * This function takes ownership of @caps and will call gst_caps_make_writable()
967 * on it if necessary, so you must not use @caps afterwards unless you keep an
968 * additional reference to it with gst_caps_ref().
970 * Returns: (transfer full): truncated caps
973 gst_caps_truncate (GstCaps * caps)
977 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
979 i = GST_CAPS_LEN (caps) - 1;
983 caps = gst_caps_make_writable (caps);
985 gst_caps_remove_structure (caps, i--);
991 * gst_caps_set_value:
992 * @caps: a writable caps
993 * @field: name of the field to set
994 * @value: value to set the field to
996 * Sets the given @field on all structures of @caps to the given @value.
997 * This is a convenience function for calling gst_structure_set_value() on
998 * all structures of @caps.
1001 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
1005 g_return_if_fail (GST_IS_CAPS (caps));
1006 g_return_if_fail (IS_WRITABLE (caps));
1007 g_return_if_fail (field != NULL);
1008 g_return_if_fail (G_IS_VALUE (value));
1010 len = GST_CAPS_LEN (caps);
1011 for (i = 0; i < len; i++) {
1012 GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
1013 gst_structure_set_value (structure, field, value);
1018 * gst_caps_set_simple_valist:
1019 * @caps: the #GstCaps to set
1020 * @field: first field to set
1021 * @varargs: additional parameters
1023 * Sets fields in a #GstCaps. The arguments must be passed in the same
1024 * manner as gst_structure_set(), and be %NULL-terminated.
1027 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
1029 GValue value = { 0, };
1031 g_return_if_fail (GST_IS_CAPS (caps));
1032 g_return_if_fail (IS_WRITABLE (caps));
1038 type = va_arg (varargs, GType);
1040 G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1041 if (G_UNLIKELY (err)) {
1042 g_critical ("%s", err);
1046 gst_caps_set_value (caps, field, &value);
1048 g_value_unset (&value);
1050 field = va_arg (varargs, const gchar *);
1055 * gst_caps_set_simple:
1056 * @caps: the #GstCaps to set
1057 * @field: first field to set
1058 * @...: additional parameters
1060 * Sets fields in a #GstCaps. The arguments must be passed in the same
1061 * manner as gst_structure_set(), and be %NULL-terminated.
1064 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1068 g_return_if_fail (GST_IS_CAPS (caps));
1069 g_return_if_fail (IS_WRITABLE (caps));
1071 va_start (var_args, field);
1072 gst_caps_set_simple_valist (caps, field, var_args);
1080 * @caps: the #GstCaps to test
1082 * Determines if @caps represents any media format.
1084 * Returns: %TRUE if @caps represents any format.
1087 gst_caps_is_any (const GstCaps * caps)
1089 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1091 return (CAPS_IS_ANY (caps));
1095 * gst_caps_is_empty:
1096 * @caps: the #GstCaps to test
1098 * Determines if @caps represents no media formats.
1100 * Returns: %TRUE if @caps represents no formats.
1103 gst_caps_is_empty (const GstCaps * caps)
1105 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1107 if (CAPS_IS_ANY (caps))
1110 return CAPS_IS_EMPTY_SIMPLE (caps);
1114 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1117 return gst_value_is_fixed (value);
1121 * gst_caps_is_fixed:
1122 * @caps: the #GstCaps to test
1124 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1125 * one structure, and each field in the structure describes a fixed type.
1126 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1128 * Returns: %TRUE if @caps is fixed
1131 gst_caps_is_fixed (const GstCaps * caps)
1133 GstStructure *structure;
1134 GstCapsFeatures *features;
1136 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1138 if (GST_CAPS_LEN (caps) != 1)
1141 features = gst_caps_get_features_unchecked (caps, 0);
1142 if (features && gst_caps_features_is_any (features))
1145 structure = gst_caps_get_structure_unchecked (caps, 0);
1147 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1151 * gst_caps_is_equal_fixed:
1152 * @caps1: the #GstCaps to test
1153 * @caps2: the #GstCaps to test
1155 * Tests if two #GstCaps are equal. This function only works on fixed
1158 * Returns: %TRUE if the arguments represent the same format
1161 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1163 GstStructure *struct1, *struct2;
1164 GstCapsFeatures *features1, *features2;
1166 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1167 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1169 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1170 features1 = gst_caps_get_features_unchecked (caps1, 0);
1172 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1173 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1174 features2 = gst_caps_get_features_unchecked (caps2, 0);
1176 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1178 return gst_structure_is_equal (struct1, struct2) &&
1179 gst_caps_features_is_equal (features1, features2);
1183 * gst_caps_is_always_compatible:
1184 * @caps1: the #GstCaps to test
1185 * @caps2: the #GstCaps to test
1187 * A given #GstCaps structure is always compatible with another if
1188 * every media format that is in the first is also contained in the
1189 * second. That is, @caps1 is a subset of @caps2.
1191 * Returns: %TRUE if @caps1 is a subset of @caps2.
1194 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1196 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1197 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1199 return gst_caps_is_subset (caps1, caps2);
1203 * gst_caps_is_subset:
1204 * @subset: a #GstCaps
1205 * @superset: a potentially greater #GstCaps
1207 * Checks if all caps represented by @subset are also represented by @superset.
1209 * Returns: %TRUE if @subset is a subset of @superset
1212 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1214 GstStructure *s1, *s2;
1215 GstCapsFeatures *f1, *f2;
1216 gboolean ret = TRUE;
1219 g_return_val_if_fail (subset != NULL, FALSE);
1220 g_return_val_if_fail (superset != NULL, FALSE);
1222 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1224 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1227 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1228 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1229 s1 = gst_caps_get_structure_unchecked (subset, i);
1230 f1 = gst_caps_get_features_unchecked (subset, i);
1232 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1233 s2 = gst_caps_get_structure_unchecked (superset, j);
1234 f2 = gst_caps_get_features_unchecked (superset, j);
1236 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1237 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1238 gst_caps_features_is_equal (f1, f2)
1239 && gst_structure_is_subset (s1, s2)) {
1240 /* If we found a superset, continue with the next
1241 * subset structure */
1245 /* If we found no superset for this subset structure
1246 * we return FALSE immediately */
1257 * gst_caps_is_subset_structure:
1259 * @structure: a potential #GstStructure subset of @caps
1261 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1262 * for more information.
1264 * Returns: %TRUE if @structure is a subset of @caps
1267 gst_caps_is_subset_structure (const GstCaps * caps,
1268 const GstStructure * structure)
1273 g_return_val_if_fail (caps != NULL, FALSE);
1274 g_return_val_if_fail (structure != NULL, FALSE);
1276 if (CAPS_IS_ANY (caps))
1278 if (CAPS_IS_EMPTY (caps))
1281 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1282 s = gst_caps_get_structure_unchecked (caps, i);
1283 if (gst_structure_is_subset (structure, s)) {
1284 /* If we found a superset return TRUE */
1293 * gst_caps_is_subset_structure_full:
1295 * @structure: a potential #GstStructure subset of @caps
1296 * @features: (allow-none): a #GstCapsFeatures for @structure
1298 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1299 * for more information.
1301 * Returns: %TRUE if @structure is a subset of @caps
1306 gst_caps_is_subset_structure_full (const GstCaps * caps,
1307 const GstStructure * structure, const GstCapsFeatures * features)
1313 g_return_val_if_fail (caps != NULL, FALSE);
1314 g_return_val_if_fail (structure != NULL, FALSE);
1316 if (CAPS_IS_ANY (caps))
1318 if (CAPS_IS_EMPTY (caps))
1322 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1324 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1325 s = gst_caps_get_structure_unchecked (caps, i);
1326 f = gst_caps_get_features_unchecked (caps, i);
1328 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1329 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1330 && gst_caps_features_is_equal (features, f)
1331 && gst_structure_is_subset (structure, s)) {
1332 /* If we found a superset return TRUE */
1341 * gst_caps_is_equal:
1342 * @caps1: a #GstCaps
1343 * @caps2: another #GstCaps
1345 * Checks if the given caps represent the same set of caps.
1347 * Returns: %TRUE if both caps are equal.
1350 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1352 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1353 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1355 if (G_UNLIKELY (caps1 == caps2))
1358 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1359 return gst_caps_is_equal_fixed (caps1, caps2);
1361 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1365 * gst_caps_is_strictly_equal:
1366 * @caps1: a #GstCaps
1367 * @caps2: another #GstCaps
1369 * Checks if the given caps are exactly the same set of caps.
1371 * Returns: %TRUE if both caps are strictly equal.
1374 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1377 GstStructure *s1, *s2;
1378 GstCapsFeatures *f1, *f2;
1380 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1381 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1383 if (G_UNLIKELY (caps1 == caps2))
1386 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1389 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1390 s1 = gst_caps_get_structure_unchecked (caps1, i);
1391 f1 = gst_caps_get_features_unchecked (caps1, i);
1393 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1394 s2 = gst_caps_get_structure_unchecked (caps2, i);
1395 f2 = gst_caps_get_features_unchecked (caps2, i);
1397 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1399 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1400 !gst_caps_features_is_equal (f1, f2) ||
1401 !gst_structure_is_equal (s1, s2))
1408 /* intersect operation */
1411 * gst_caps_can_intersect:
1412 * @caps1: a #GstCaps to intersect
1413 * @caps2: a #GstCaps to intersect
1415 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1418 * Returns: %TRUE if intersection would be not empty
1421 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1423 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1424 guint j, k, len1, len2;
1425 GstStructure *struct1;
1426 GstStructure *struct2;
1427 GstCapsFeatures *features1;
1428 GstCapsFeatures *features2;
1430 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1431 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1433 /* caps are exactly the same pointers */
1434 if (G_UNLIKELY (caps1 == caps2))
1437 /* empty caps on either side, return empty */
1438 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1441 /* one of the caps is any */
1442 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1445 /* run zigzag on top line then right line, this preserves the caps order
1446 * much better than a simple loop.
1448 * This algorithm zigzags over the caps structures as demonstrated in
1449 * the following matrix:
1452 * +------------- total distance: +-------------
1453 * | 1 2 4 7 0 | 0 1 2 3
1454 * caps2 | 3 5 8 10 1 | 1 2 3 4
1455 * | 6 9 11 12 2 | 2 3 4 5
1457 * First we iterate over the caps1 structures (top line) intersecting
1458 * the structures diagonally down, then we iterate over the caps2
1459 * structures. The result is that the intersections are ordered based on the
1460 * sum of the indexes in the list.
1462 len1 = GST_CAPS_LEN (caps1);
1463 len2 = GST_CAPS_LEN (caps2);
1464 for (i = 0; i < len1 + len2 - 1; i++) {
1465 /* superset index goes from 0 to superset->structs->len-1 */
1466 j = MIN (i, len1 - 1);
1467 /* subset index stays 0 until i reaches superset->structs->len, then it
1468 * counts up from 1 to subset->structs->len - 1 */
1469 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1470 /* now run the diagonal line, end condition is the left or bottom
1473 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1474 features1 = gst_caps_get_features_unchecked (caps1, j);
1476 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1477 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1478 features2 = gst_caps_get_features_unchecked (caps2, k);
1480 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1481 if (gst_caps_features_is_equal (features1, features2) &&
1482 gst_structure_can_intersect (struct1, struct2)) {
1485 /* move down left */
1487 if (G_UNLIKELY (j == 0))
1488 break; /* so we don't roll back to G_MAXUINT */
1497 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1499 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1500 guint j, k, len1, len2;
1501 GstStructure *struct1;
1502 GstStructure *struct2;
1503 GstCapsFeatures *features1;
1504 GstCapsFeatures *features2;
1506 GstStructure *istruct;
1508 /* caps are exactly the same pointers, just copy one caps */
1509 if (G_UNLIKELY (caps1 == caps2))
1510 return gst_caps_ref (caps1);
1512 /* empty caps on either side, return empty */
1513 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1514 return gst_caps_ref (GST_CAPS_NONE);
1516 /* one of the caps is any, just copy the other caps */
1517 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1518 return gst_caps_ref (caps2);
1520 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1521 return gst_caps_ref (caps1);
1523 dest = gst_caps_new_empty ();
1524 /* run zigzag on top line then right line, this preserves the caps order
1525 * much better than a simple loop.
1527 * This algorithm zigzags over the caps structures as demonstrated in
1528 * the following matrix:
1536 * First we iterate over the caps1 structures (top line) intersecting
1537 * the structures diagonally down, then we iterate over the caps2
1540 len1 = GST_CAPS_LEN (caps1);
1541 len2 = GST_CAPS_LEN (caps2);
1542 for (i = 0; i < len1 + len2 - 1; i++) {
1543 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1544 j = MIN (i, len1 - 1);
1545 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1546 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1547 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1548 /* now run the diagonal line, end condition is the left or bottom
1551 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1552 features1 = gst_caps_get_features_unchecked (caps1, j);
1554 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1555 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1556 features2 = gst_caps_get_features_unchecked (caps2, k);
1558 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1559 if (gst_caps_features_is_equal (features1, features2)) {
1560 istruct = gst_structure_intersect (struct1, struct2);
1562 if (gst_caps_features_is_any (features1))
1564 gst_caps_merge_structure_full (dest, istruct,
1565 gst_caps_features_copy_conditional (features2));
1568 gst_caps_merge_structure_full (dest, istruct,
1569 gst_caps_features_copy_conditional (features1));
1572 /* move down left */
1574 if (G_UNLIKELY (j == 0))
1575 break; /* so we don't roll back to G_MAXUINT */
1583 * gst_caps_intersect_first:
1584 * @caps1: a #GstCaps to intersect
1585 * @caps2: a #GstCaps to intersect
1587 * Creates a new #GstCaps that contains all the formats that are common
1588 * to both @caps1 and @caps2.
1590 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1591 * fashion as @caps1.
1593 * Returns: (transfer full): the new #GstCaps
1596 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1599 guint j, len1, len2;
1600 GstStructure *struct1;
1601 GstStructure *struct2;
1602 GstCapsFeatures *features1;
1603 GstCapsFeatures *features2;
1605 GstStructure *istruct;
1607 /* caps are exactly the same pointers, just copy one caps */
1608 if (G_UNLIKELY (caps1 == caps2))
1609 return gst_caps_ref (caps1);
1611 /* empty caps on either side, return empty */
1612 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1613 return gst_caps_ref (GST_CAPS_NONE);
1615 /* one of the caps is any, just copy the other caps */
1616 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1617 return gst_caps_ref (caps2);
1619 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1620 return gst_caps_ref (caps1);
1622 dest = gst_caps_new_empty ();
1623 len1 = GST_CAPS_LEN (caps1);
1624 len2 = GST_CAPS_LEN (caps2);
1625 for (i = 0; i < len1; i++) {
1626 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1627 features1 = gst_caps_get_features_unchecked (caps1, i);
1629 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1630 for (j = 0; j < len2; j++) {
1631 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1632 features2 = gst_caps_get_features_unchecked (caps2, j);
1634 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1635 if (gst_caps_features_is_equal (features1, features2)) {
1636 istruct = gst_structure_intersect (struct1, struct2);
1638 if (gst_caps_features_is_any (features1))
1640 gst_caps_merge_structure_full (dest, istruct,
1641 gst_caps_features_copy_conditional (features2));
1644 gst_caps_merge_structure_full (dest, istruct,
1645 gst_caps_features_copy_conditional (features1));
1655 * gst_caps_intersect_full:
1656 * @caps1: a #GstCaps to intersect
1657 * @caps2: a #GstCaps to intersect
1658 * @mode: The intersection algorithm/mode to use
1660 * Creates a new #GstCaps that contains all the formats that are common
1661 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1664 * Returns: (transfer full): the new #GstCaps
1667 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1668 GstCapsIntersectMode mode)
1670 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1671 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1674 case GST_CAPS_INTERSECT_FIRST:
1675 return gst_caps_intersect_first (caps1, caps2);
1677 g_warning ("Unknown caps intersect mode: %d", mode);
1679 case GST_CAPS_INTERSECT_ZIG_ZAG:
1680 return gst_caps_intersect_zig_zag (caps1, caps2);
1685 * gst_caps_intersect:
1686 * @caps1: a #GstCaps to intersect
1687 * @caps2: a #GstCaps to intersect
1689 * Creates a new #GstCaps that contains all the formats that are common
1690 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1692 * Returns: (transfer full): the new #GstCaps
1695 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1697 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1700 /* subtract operation */
1704 const GstStructure *subtract_from;
1709 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1712 SubtractionEntry *e = user_data;
1713 GValue subtraction = { 0, };
1714 const GValue *other;
1715 GstStructure *structure;
1717 other = gst_structure_id_get_value (e->subtract_from, field_id);
1723 if (!gst_value_subtract (&subtraction, other, value))
1726 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1727 g_value_unset (&subtraction);
1730 structure = gst_structure_copy (e->subtract_from);
1731 gst_structure_id_take_value (structure, field_id, &subtraction);
1732 e->put_into = g_slist_prepend (e->put_into, structure);
1738 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1739 const GstStructure * subtrahend)
1744 e.subtract_from = minuend;
1746 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1747 gst_caps_structure_subtract_field, &e);
1754 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1755 gst_structure_free (walk->data);
1757 g_slist_free (e.put_into);
1764 * gst_caps_subtract:
1765 * @minuend: #GstCaps to subtract from
1766 * @subtrahend: #GstCaps to subtract
1768 * Subtracts the @subtrahend from the @minuend.
1769 * <note>This function does not work reliably if optional properties for caps
1770 * are included on one caps and omitted on the other.</note>
1772 * Returns: (transfer full): the resulting caps
1775 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1780 GstCapsFeatures *min_f, *sub_f;
1781 GstCaps *dest = NULL, *src;
1783 g_return_val_if_fail (minuend != NULL, NULL);
1784 g_return_val_if_fail (subtrahend != NULL, NULL);
1786 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1787 return gst_caps_new_empty ();
1790 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1791 return gst_caps_ref (minuend);
1793 /* FIXME: Do we want this here or above?
1794 The reason we need this is that there is no definition about what
1795 ANY means for specific types, so it's not possible to reduce ANY partially
1796 You can only remove everything or nothing and that is done above.
1797 Note: there's a test that checks this behaviour. */
1799 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1800 sublen = GST_CAPS_LEN (subtrahend);
1801 g_assert (sublen > 0);
1803 src = _gst_caps_copy (minuend);
1804 for (i = 0; i < sublen; i++) {
1807 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1808 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1810 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1812 gst_caps_unref (src);
1815 dest = gst_caps_new_empty ();
1816 srclen = GST_CAPS_LEN (src);
1817 for (j = 0; j < srclen; j++) {
1818 min = gst_caps_get_structure_unchecked (src, j);
1819 min_f = gst_caps_get_features_unchecked (src, j);
1821 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1823 /* Same reason as above for ANY caps */
1824 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1826 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1827 gst_caps_features_is_equal (min_f, sub_f)) {
1830 if (gst_caps_structure_subtract (&list, min, sub)) {
1833 for (walk = list; walk; walk = g_slist_next (walk)) {
1834 gst_caps_append_structure_unchecked (dest,
1835 (GstStructure *) walk->data,
1836 gst_caps_features_copy_conditional (min_f));
1838 g_slist_free (list);
1840 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1841 gst_caps_features_copy_conditional (min_f));
1844 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1845 gst_caps_features_copy_conditional (min_f));
1849 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1850 gst_caps_unref (src);
1855 gst_caps_unref (src);
1856 dest = gst_caps_simplify (dest);
1861 /* normalize/simplify operations */
1863 typedef struct _NormalizeForeach
1866 GstStructure *structure;
1867 GstCapsFeatures *features;
1871 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1873 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1877 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1878 guint len = gst_value_list_get_size (value);
1880 for (i = 1; i < len; i++) {
1881 const GValue *v = gst_value_list_get_value (value, i);
1882 GstStructure *structure = gst_structure_copy (nf->structure);
1884 gst_structure_id_set_value (structure, field_id, v);
1885 gst_caps_append_structure_unchecked (nf->caps, structure,
1886 gst_caps_features_copy_conditional (nf->features));
1889 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1890 gst_structure_id_take_value (nf->structure, field_id, &val);
1898 * gst_caps_normalize:
1899 * @caps: (transfer full): a #GstCaps to normalize
1901 * Returns a #GstCaps that represents the same set of formats as
1902 * @caps, but contains no lists. Each list is expanded into separate
1905 * This function takes ownership of @caps and will call gst_caps_make_writable()
1906 * on it so you must not use @caps afterwards unless you keep an additional
1907 * reference to it with gst_caps_ref().
1909 * Returns: (transfer full): the normalized #GstCaps
1912 gst_caps_normalize (GstCaps * caps)
1914 NormalizeForeach nf;
1917 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1919 caps = gst_caps_make_writable (caps);
1922 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1923 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1924 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1925 while (!gst_structure_foreach (nf.structure,
1926 gst_caps_normalize_foreach, &nf));
1933 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1936 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1937 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1939 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1940 So what's the best way? */
1941 ret = strcmp (gst_structure_get_name (struct1),
1942 gst_structure_get_name (struct2));
1947 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1954 GstStructure *compare;
1958 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1961 UnionField *u = user_data;
1962 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1966 g_value_unset (&u->value);
1970 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1974 g_value_unset (&u->value);
1979 gst_value_union (&u->value, val, value);
1985 gst_caps_structure_simplify (GstStructure ** result,
1986 GstStructure * simplify, GstStructure * compare)
1989 UnionField field = { 0, {0,}, NULL };
1991 /* try to subtract to get a real subset */
1992 if (gst_caps_structure_subtract (&list, simplify, compare)) {
1993 if (list == NULL) { /* no result */
1996 } else if (list->next == NULL) { /* one result */
1997 *result = list->data;
1998 g_slist_free (list);
2000 } else { /* multiple results */
2001 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
2002 g_slist_free (list);
2007 /* try to union both structs */
2008 field.compare = compare;
2009 if (gst_structure_foreach (simplify,
2010 gst_caps_structure_figure_out_union, &field)) {
2011 gboolean ret = FALSE;
2013 /* now we know all of simplify's fields are the same in compare
2014 * but at most one field: field.name */
2015 if (G_IS_VALUE (&field.value)) {
2016 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
2017 gst_structure_id_take_value (compare, field.name, &field.value);
2021 g_value_unset (&field.value);
2024 if (gst_structure_n_fields (simplify) <=
2025 gst_structure_n_fields (compare)) {
2026 /* compare is just more specific, will be optimized away later */
2027 /* FIXME: do this here? */
2028 GST_LOG ("found a case that will be optimized later.");
2030 gchar *one = gst_structure_to_string (simplify);
2031 gchar *two = gst_structure_to_string (compare);
2034 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2046 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2047 GstStructure * new, gint i)
2049 gst_structure_set_parent_refcount (old, NULL);
2050 gst_structure_free (old);
2051 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2052 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2056 * gst_caps_simplify:
2057 * @caps: (transfer full): a #GstCaps to simplify
2059 * Converts the given @caps into a representation that represents the
2060 * same set of formats, but in a simpler form. Component structures that are
2061 * identical are merged. Component structures that have values that can be
2062 * merged are also merged.
2064 * This function takes ownership of @caps and will call gst_caps_make_writable()
2065 * on it if necessary, so you must not use @caps afterwards unless you keep an
2066 * additional reference to it with gst_caps_ref().
2068 * This method does not preserve the original order of @caps.
2070 * Returns: (transfer full): The simplified caps.
2073 gst_caps_simplify (GstCaps * caps)
2075 GstStructure *simplify, *compare, *result = NULL;
2076 GstCapsFeatures *simplify_f, *compare_f;
2079 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2081 start = GST_CAPS_LEN (caps) - 1;
2082 /* one caps, already as simple as can be */
2086 caps = gst_caps_make_writable (caps);
2088 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2090 for (i = start; i >= 0; i--) {
2091 simplify = gst_caps_get_structure_unchecked (caps, i);
2092 simplify_f = gst_caps_get_features_unchecked (caps, i);
2094 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2095 compare = gst_caps_get_structure_unchecked (caps, start);
2096 compare_f = gst_caps_get_features_unchecked (caps, start);
2098 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2099 if (gst_structure_get_name_id (simplify) !=
2100 gst_structure_get_name_id (compare) ||
2101 !gst_caps_features_is_equal (simplify_f, compare_f))
2103 for (j = start; j >= 0; j--) {
2106 compare = gst_caps_get_structure_unchecked (caps, j);
2107 compare_f = gst_caps_get_features_unchecked (caps, j);
2109 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2110 if (gst_structure_get_name_id (simplify) !=
2111 gst_structure_get_name_id (compare) ||
2112 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2115 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2117 gst_caps_switch_structures (caps, simplify, result, i);
2120 gst_caps_remove_structure (caps, i);
2132 * @caps: (transfer full): a #GstCaps to fixate
2134 * Modifies the given @caps into a representation with only fixed
2135 * values. First the caps will be truncated and then the first structure will be
2136 * fixated with gst_structure_fixate().
2138 * This function takes ownership of @caps and will call gst_caps_make_writable()
2139 * on it so you must not use @caps afterwards unless you keep an additional
2140 * reference to it with gst_caps_ref().
2142 * Returns: (transfer full): the fixated caps
2145 gst_caps_fixate (GstCaps * caps)
2150 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2152 /* default fixation */
2153 caps = gst_caps_truncate (caps);
2154 caps = gst_caps_make_writable (caps);
2155 s = gst_caps_get_structure (caps, 0);
2156 gst_structure_fixate (s);
2158 /* Set features to sysmem if they're still ANY */
2159 f = gst_caps_get_features_unchecked (caps, 0);
2160 if (f && gst_caps_features_is_any (f)) {
2161 f = gst_caps_features_new_empty ();
2162 gst_caps_set_features (caps, 0, f);
2171 * gst_caps_to_string:
2174 * Converts @caps to a string representation. This string representation
2175 * can be converted back to a #GstCaps by gst_caps_from_string().
2177 * For debugging purposes its easier to do something like this:
2178 * |[<!-- language="C" -->
2179 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2181 * This prints the caps in human readable form.
2183 * The current implementation of serialization will lead to unexpected results
2184 * when there are nested #GstCaps / #GstStructure deeper than one level.
2186 * Returns: (transfer full): a newly allocated string representing @caps.
2189 gst_caps_to_string (const GstCaps * caps)
2191 guint i, slen, clen;
2194 /* NOTE: This function is potentially called by the debug system,
2195 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2196 * should be careful to avoid recursion. This includes any functions
2197 * called by gst_caps_to_string. In particular, calls should
2198 * not use the GST_PTR_FORMAT extension. */
2201 return g_strdup ("NULL");
2203 if (CAPS_IS_ANY (caps)) {
2204 return g_strdup ("ANY");
2206 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2207 return g_strdup ("EMPTY");
2210 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2212 clen = GST_CAPS_LEN (caps);
2213 for (i = 0; i < clen; i++) {
2217 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2219 f = gst_caps_get_features_unchecked (caps, i);
2221 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2224 s = g_string_sized_new (slen);
2225 for (i = 0; i < clen; i++) {
2226 GstStructure *structure;
2227 GstCapsFeatures *features;
2230 /* ';' is now added by gst_structure_to_string */
2231 g_string_append_c (s, ' ');
2234 structure = gst_caps_get_structure_unchecked (caps, i);
2235 features = gst_caps_get_features_unchecked (caps, i);
2237 g_string_append (s, gst_structure_get_name (structure));
2238 if (features && (gst_caps_features_is_any (features)
2239 || !gst_caps_features_is_equal (features,
2240 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2241 g_string_append_c (s, '(');
2242 priv_gst_caps_features_append_to_gstring (features, s);
2243 g_string_append_c (s, ')');
2245 priv_gst_structure_append_to_gstring (structure, s);
2247 if (s->len && s->str[s->len - 1] == ';') {
2248 /* remove latest ';' */
2249 s->str[--s->len] = '\0';
2251 return g_string_free (s, FALSE);
2255 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2257 GstStructure *structure;
2258 gchar *s, *copy, *end, *next, save;
2260 if (strcmp ("ANY", string) == 0) {
2261 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2265 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2269 copy = s = g_strdup (string);
2271 GstCapsFeatures *features = NULL;
2273 while (g_ascii_isspace (*s))
2279 if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2286 structure = gst_structure_new_empty (s);
2289 if (structure == NULL) {
2307 } else if (*end == ')') {
2316 features = gst_caps_features_from_string (s);
2318 gst_structure_free (structure);
2332 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2333 gst_structure_free (structure);
2335 gst_caps_features_free (features);
2341 gst_caps_append_structure_unchecked (caps, structure, features);
2353 * gst_caps_from_string:
2354 * @string: a string to convert to #GstCaps
2356 * Converts @caps from a string representation.
2358 * The current implementation of serialization will lead to unexpected results
2359 * when there are nested #GstCaps / #GstStructure deeper than one level.
2361 * Returns: (transfer full): a newly allocated #GstCaps
2364 gst_caps_from_string (const gchar * string)
2368 g_return_val_if_fail (string, FALSE);
2370 caps = gst_caps_new_empty ();
2371 if (gst_caps_from_string_inplace (caps, string)) {
2374 gst_caps_unref (caps);
2380 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2382 g_return_if_fail (G_IS_VALUE (src_value));
2383 g_return_if_fail (G_IS_VALUE (dest_value));
2384 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2385 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2386 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2388 g_value_take_string (dest_value,
2389 gst_caps_to_string (gst_value_get_caps (src_value)));
2395 * @func: (scope call): a function to call for each field
2396 * @user_data: (closure): private data
2398 * Calls the provided function once for each structure and caps feature in the
2399 * #GstCaps. The function must not modify the fields.
2400 * Also see gst_caps_map_in_place() and gst_caps_filter_and_map_in_place().
2402 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2408 gst_caps_foreach (const GstCaps * caps, GstCapsForeachFunc func,
2412 GstCapsFeatures *features;
2413 GstStructure *structure;
2416 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2417 g_return_val_if_fail (func != NULL, FALSE);
2419 n = GST_CAPS_LEN (caps);
2421 for (i = 0; i < n; i++) {
2422 features = gst_caps_get_features_unchecked (caps, i);
2423 structure = gst_caps_get_structure_unchecked (caps, i);
2425 ret = func (features, structure, user_data);
2426 if (G_UNLIKELY (!ret))
2434 * gst_caps_map_in_place:
2436 * @func: (scope call): a function to call for each field
2437 * @user_data: (closure): private data
2439 * Calls the provided function once for each structure and caps feature in the
2440 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify but not
2441 * delete the structures and features. The caps must be mutable.
2443 * Returns: %TRUE if the supplied function returns %TRUE for each call,
2449 gst_caps_map_in_place (GstCaps * caps, GstCapsMapFunc func, gpointer user_data)
2452 GstCapsFeatures *features;
2453 GstStructure *structure;
2456 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
2457 g_return_val_if_fail (gst_caps_is_writable (caps), FALSE);
2458 g_return_val_if_fail (func != NULL, FALSE);
2460 n = GST_CAPS_LEN (caps);
2462 for (i = 0; i < n; i++) {
2463 features = gst_caps_get_features_unchecked (caps, i);
2464 structure = gst_caps_get_structure_unchecked (caps, i);
2466 /* Provide sysmem features if there are none yet */
2469 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2470 gst_caps_set_features (caps, i, features);
2473 ret = func (features, structure, user_data);
2474 if (G_UNLIKELY (!ret))
2482 * gst_caps_filter_and_map_in_place:
2484 * @func: (scope call): a function to call for each field
2485 * @user_data: (closure): private data
2487 * Calls the provided function once for each structure and caps feature in the
2488 * #GstCaps. In contrast to gst_caps_foreach(), the function may modify the
2489 * structure and features. In contrast to gst_caps_filter_and_map_in_place(),
2490 * the structure and features are removed from the caps if %FALSE is returned
2491 * from the function.
2492 * The caps must be mutable.
2497 gst_caps_filter_and_map_in_place (GstCaps * caps, GstCapsFilterMapFunc func,
2501 GstCapsFeatures *features;
2502 GstStructure *structure;
2505 g_return_if_fail (GST_IS_CAPS (caps));
2506 g_return_if_fail (gst_caps_is_writable (caps));
2507 g_return_if_fail (func != NULL);
2509 n = GST_CAPS_LEN (caps);
2511 for (i = 0; i < n;) {
2512 features = gst_caps_get_features_unchecked (caps, i);
2513 structure = gst_caps_get_structure_unchecked (caps, i);
2515 /* Provide sysmem features if there are none yet */
2518 gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
2519 gst_caps_set_features (caps, i, features);
2522 ret = func (features, structure, user_data);
2524 GST_CAPS_ARRAY (caps) = g_array_remove_index (GST_CAPS_ARRAY (caps), i);
2526 gst_structure_set_parent_refcount (structure, NULL);
2527 gst_structure_free (structure);
2529 gst_caps_features_set_parent_refcount (features, NULL);
2530 gst_caps_features_free (features);
2533 n = GST_CAPS_LEN (caps);