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:
39 * <title>Creating caps</title>
42 * caps = gst_caps_new_simple ("video/x-raw",
43 * "format", G_TYPE_STRING, "I420",
44 * "framerate", GST_TYPE_FRACTION, 25, 1,
45 * "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
46 * "width", G_TYPE_INT, 320,
47 * "height", G_TYPE_INT, 240,
52 * A #GstCaps is fixed when it has no properties with ranges or lists. Use
53 * gst_caps_is_fixed() to test for fixed caps. Fixed caps can be used in a
54 * caps event to notify downstream elements of the current media type.
56 * Various methods exist to work with the media types such as subtracting
59 * Be aware that the current #GstCaps / #GstStructure serialization into string
60 * has limited support for nested #GstCaps / #GstStructure fields. It can only
61 * support one level of nesting. Using more levels will lead to unexpected
62 * behavior when using serialization features, such as gst_caps_to_string() or
63 * gst_value_serialize() and their counterparts.
65 * Last reviewed on 2011-03-28 (0.11.3)
74 #include "gst_private.h"
76 #include <gobject/gvaluecollector.h>
78 #define DEBUG_REFCOUNT
80 typedef struct _GstCapsArrayElement
82 GstStructure *structure;
83 GstCapsFeatures *features;
84 } GstCapsArrayElement;
86 typedef struct _GstCapsImpl
93 #define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
95 #define GST_CAPS_LEN(c) (GST_CAPS_ARRAY(c)->len)
97 #define IS_WRITABLE(caps) \
98 (GST_CAPS_REFCOUNT_VALUE (caps) == 1)
100 /* same as gst_caps_is_any () */
101 #define CAPS_IS_ANY(caps) \
102 (GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY)
104 /* same as gst_caps_is_empty () */
105 #define CAPS_IS_EMPTY(caps) \
106 (!CAPS_IS_ANY(caps) && CAPS_IS_EMPTY_SIMPLE(caps))
108 #define CAPS_IS_EMPTY_SIMPLE(caps) \
109 ((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
111 #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)
113 /* quick way to get a caps structure at an index without doing a type or array
115 #define gst_caps_get_structure_unchecked(caps, index) \
116 (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).structure)
117 #define gst_caps_get_features_storage_unchecked(caps, index) \
118 (&g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
119 #define gst_caps_get_features_unchecked(caps, index) \
120 (g_atomic_pointer_get (gst_caps_get_features_storage_unchecked (caps, index)))
121 /* quick way to append a structure without checking the args */
122 #define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
123 GstCapsArrayElement __e={s, f}; \
124 if (gst_structure_set_parent_refcount (__e.structure, &GST_MINI_OBJECT_REFCOUNT(caps)) && \
125 (!__e.features || gst_caps_features_set_parent_refcount (__e.features, &GST_MINI_OBJECT_REFCOUNT(caps)))) \
126 g_array_append_val (GST_CAPS_ARRAY (caps), __e); \
129 /* lock to protect multiple invocations of static caps to caps conversion */
130 G_LOCK_DEFINE_STATIC (static_caps_lock);
132 static void gst_caps_transform_to_string (const GValue * src_value,
133 GValue * dest_value);
134 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
135 const gchar * string);
137 GType _gst_caps_type = 0;
138 GstCaps *_gst_caps_any;
139 GstCaps *_gst_caps_none;
141 GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
144 _priv_gst_caps_initialize (void)
146 _gst_caps_type = gst_caps_get_type ();
148 _gst_caps_any = gst_caps_new_any ();
149 _gst_caps_none = gst_caps_new_empty ();
151 g_value_register_transform_func (_gst_caps_type,
152 G_TYPE_STRING, gst_caps_transform_to_string);
156 _gst_caps_copy (const GstCaps * caps)
159 GstStructure *structure;
160 GstCapsFeatures *features;
163 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
165 newcaps = gst_caps_new_empty ();
166 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
167 n = GST_CAPS_LEN (caps);
169 GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, caps, "doing copy %p -> %p",
172 for (i = 0; i < n; i++) {
173 structure = gst_caps_get_structure_unchecked (caps, i);
174 features = gst_caps_get_features_unchecked (caps, i);
175 gst_caps_append_structure_full (newcaps, gst_structure_copy (structure),
176 gst_caps_features_copy_conditional (features));
182 /* creation/deletion */
184 _gst_caps_free (GstCaps * caps)
186 GstStructure *structure;
187 GstCapsFeatures *features;
190 /* The refcount must be 0, but since we're only called by gst_caps_unref,
191 * don't bother testing. */
192 len = GST_CAPS_LEN (caps);
193 /* This can be used to get statistics about caps sizes */
194 /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
195 for (i = 0; i < len; i++) {
196 structure = gst_caps_get_structure_unchecked (caps, i);
197 gst_structure_set_parent_refcount (structure, NULL);
198 gst_structure_free (structure);
199 features = gst_caps_get_features_unchecked (caps, i);
201 gst_caps_features_set_parent_refcount (features, NULL);
202 gst_caps_features_free (features);
205 g_array_free (GST_CAPS_ARRAY (caps), TRUE);
207 #ifdef DEBUG_REFCOUNT
208 GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
210 g_slice_free1 (sizeof (GstCapsImpl), caps);
214 gst_caps_init (GstCaps * caps)
216 gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
217 (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
218 (GstMiniObjectFreeFunction) _gst_caps_free);
220 /* the 32 has been determined by logging caps sizes in _gst_caps_free
221 * but g_ptr_array uses 16 anyway if it expands once, so this does not help
223 * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
225 GST_CAPS_ARRAY (caps) =
226 g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
230 * gst_caps_new_empty:
232 * Creates a new #GstCaps that is empty. That is, the returned
233 * #GstCaps contains no media formats.
234 * The #GstCaps is guaranteed to be writable.
235 * Caller is responsible for unreffing the returned caps.
237 * Returns: (transfer full): the new #GstCaps
240 gst_caps_new_empty (void)
244 caps = (GstCaps *) g_slice_new (GstCapsImpl);
246 gst_caps_init (caps);
248 #ifdef DEBUG_REFCOUNT
249 GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
258 * Creates a new #GstCaps that indicates that it is compatible with
261 * Returns: (transfer full): the new #GstCaps
264 gst_caps_new_any (void)
266 GstCaps *caps = gst_caps_new_empty ();
268 GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_ANY);
274 * gst_caps_new_empty_simple:
275 * @media_type: the media type of the structure
277 * Creates a new #GstCaps that contains one #GstStructure with name
279 * Caller is responsible for unreffing the returned caps.
281 * Returns: (transfer full): the new #GstCaps
284 gst_caps_new_empty_simple (const char *media_type)
287 GstStructure *structure;
289 caps = gst_caps_new_empty ();
290 structure = gst_structure_new_empty (media_type);
292 gst_caps_append_structure_unchecked (caps, structure, NULL);
298 * gst_caps_new_simple:
299 * @media_type: the media type of the structure
300 * @fieldname: first field to set
301 * @...: additional arguments
303 * Creates a new #GstCaps that contains one #GstStructure. The
304 * structure is defined by the arguments, which have the same format
305 * as gst_structure_new().
306 * Caller is responsible for unreffing the returned caps.
308 * Returns: (transfer full): the new #GstCaps
311 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
314 GstStructure *structure;
317 caps = gst_caps_new_empty ();
319 va_start (var_args, fieldname);
320 structure = gst_structure_new_valist (media_type, fieldname, var_args);
324 gst_caps_append_structure_unchecked (caps, structure, NULL);
326 gst_caps_replace (&caps, NULL);
333 * @struct1: the first structure to add
334 * @...: additional structures to add
336 * Creates a new #GstCaps and adds all the structures listed as
337 * arguments. The list must be NULL-terminated. The structures
338 * are not copied; the returned #GstCaps owns the structures.
340 * Returns: (transfer full): the new #GstCaps
343 gst_caps_new_full (GstStructure * struct1, ...)
348 va_start (var_args, struct1);
349 caps = gst_caps_new_full_valist (struct1, var_args);
356 * gst_caps_new_full_valist:
357 * @structure: the first structure to add
358 * @var_args: additional structures to add
360 * Creates a new #GstCaps and adds all the structures listed as
361 * arguments. The list must be NULL-terminated. The structures
362 * are not copied; the returned #GstCaps owns the structures.
364 * Returns: (transfer full): the new #GstCaps
367 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
371 caps = gst_caps_new_empty ();
374 gst_caps_append_structure_unchecked (caps, structure, NULL);
375 structure = va_arg (var_args, GstStructure *);
381 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
384 * gst_static_caps_get:
385 * @static_caps: the #GstStaticCaps to convert
387 * Converts a #GstStaticCaps to a #GstCaps.
389 * Returns: (transfer full): a pointer to the #GstCaps. Unref after usage.
390 * Since the core holds an additional ref to the returned caps,
391 * use gst_caps_make_writable() on the returned caps to modify it.
394 gst_static_caps_get (GstStaticCaps * static_caps)
398 g_return_val_if_fail (static_caps != NULL, NULL);
400 caps = &static_caps->caps;
402 /* refcount is 0 when we need to convert */
403 if (G_UNLIKELY (*caps == NULL)) {
406 G_LOCK (static_caps_lock);
407 /* check if other thread already updated */
408 if (G_UNLIKELY (*caps != NULL))
411 string = static_caps->string;
413 if (G_UNLIKELY (string == NULL))
416 *caps = gst_caps_from_string (string);
418 /* convert to string */
419 if (G_UNLIKELY (*caps == NULL))
420 g_critical ("Could not convert static caps \"%s\"", string);
422 GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
425 G_UNLOCK (static_caps_lock);
427 /* ref the caps, makes it not writable */
428 if (G_LIKELY (*caps != NULL))
429 gst_caps_ref (*caps);
436 G_UNLOCK (static_caps_lock);
437 g_warning ("static caps %p string is NULL", static_caps);
443 * gst_static_caps_cleanup:
444 * @static_caps: the #GstStaticCaps to clean
446 * Clean up the cached caps contained in @static_caps.
449 gst_static_caps_cleanup (GstStaticCaps * static_caps)
451 G_LOCK (static_caps_lock);
452 gst_caps_replace (&static_caps->caps, NULL);
453 G_UNLOCK (static_caps_lock);
459 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
460 GstStructure ** s, GstCapsFeatures ** f)
465 s_ = gst_caps_get_structure_unchecked (caps, idx);
466 f_ = gst_caps_get_features_unchecked (caps, idx);
468 /* don't use index_fast, gst_caps_simplify relies on the order */
469 g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
471 gst_structure_set_parent_refcount (s_, NULL);
473 gst_caps_features_set_parent_refcount (f_, NULL);
480 static GstStructure *
481 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
486 gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
489 gst_caps_features_free (f);
497 * gst_caps_steal_structure:
498 * @caps: the #GstCaps to retrieve from
499 * @index: Index of the structure to retrieve
501 * Retrieves the structure with the given index from the list of structures
502 * contained in @caps. The caller becomes the owner of the returned structure.
504 * Returns: (transfer full): a pointer to the #GstStructure corresponding
508 gst_caps_steal_structure (GstCaps * caps, guint index)
510 g_return_val_if_fail (caps != NULL, NULL);
511 g_return_val_if_fail (IS_WRITABLE (caps), NULL);
513 if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
516 return gst_caps_remove_and_get_structure (caps, index);
521 * @caps1: the #GstCaps that will be appended to
522 * @caps2: (transfer full): the #GstCaps to append
524 * Appends the structures contained in @caps2 to @caps1. The structures in
525 * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
526 * freed. If either caps is ANY, the resulting caps will be ANY.
529 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
531 GstStructure *structure;
532 GstCapsFeatures *features;
535 g_return_if_fail (GST_IS_CAPS (caps1));
536 g_return_if_fail (GST_IS_CAPS (caps2));
537 g_return_if_fail (IS_WRITABLE (caps1));
539 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
540 GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
541 gst_caps_unref (caps2);
543 caps2 = gst_caps_make_writable (caps2);
545 for (i = GST_CAPS_LEN (caps2); i; i--) {
546 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
548 gst_caps_append_structure_unchecked (caps1, structure, features);
550 gst_caps_unref (caps2); /* guaranteed to free it */
556 * @caps1: (transfer full): the #GstCaps that will take the new entries
557 * @caps2: (transfer full): the #GstCaps to merge in
559 * Appends the structures contained in @caps2 to @caps1 if they are not yet
560 * expressed by @caps1. The structures in @caps2 are not copied -- they are
561 * transferred to a writable copy of @caps1, and then @caps2 is freed.
562 * If either caps is ANY, the resulting caps will be ANY.
564 * Returns: (transfer full): the merged caps.
567 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
569 GstStructure *structure;
570 GstCapsFeatures *features;
574 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
575 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
577 if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
578 gst_caps_unref (caps2);
580 } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
581 gst_caps_unref (caps1);
584 caps2 = gst_caps_make_writable (caps2);
586 for (i = GST_CAPS_LEN (caps2); i; i--) {
587 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
589 caps1 = gst_caps_merge_structure_full (caps1, structure, features);
591 gst_caps_unref (caps2);
595 GstCaps *com = gst_caps_intersect (caps1, caps2);
596 GstCaps *add = gst_caps_subtract (caps2, com);
598 GST_DEBUG ("common : %d", gst_caps_get_size (com));
599 GST_DEBUG ("adding : %d", gst_caps_get_size (add));
600 gst_caps_append (caps1, add);
601 gst_caps_unref (com);
609 * gst_caps_append_structure:
610 * @caps: the #GstCaps that will be appended to
611 * @structure: (transfer full): the #GstStructure to append
613 * Appends @structure to @caps. The structure is not copied; @caps
614 * becomes the owner of @structure.
617 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
619 g_return_if_fail (GST_IS_CAPS (caps));
620 g_return_if_fail (IS_WRITABLE (caps));
622 if (G_LIKELY (structure)) {
623 gst_caps_append_structure_unchecked (caps, structure, NULL);
628 * gst_caps_append_structure_full:
629 * @caps: the #GstCaps that will be appended to
630 * @structure: (transfer full): the #GstStructure to append
631 * @features: (transfer full) (allow-none): the #GstCapsFeatures to append
633 * Appends @structure with @features to @caps. The structure is not copied; @caps
634 * becomes the owner of @structure.
639 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
640 GstCapsFeatures * features)
642 g_return_if_fail (GST_IS_CAPS (caps));
643 g_return_if_fail (IS_WRITABLE (caps));
645 if (G_LIKELY (structure)) {
646 gst_caps_append_structure_unchecked (caps, structure, features);
651 * gst_caps_remove_structure:
652 * @caps: the #GstCaps to remove from
653 * @idx: Index of the structure to remove
655 * removes the structure with the given index from the list of structures
656 * contained in @caps.
659 gst_caps_remove_structure (GstCaps * caps, guint idx)
661 GstStructure *structure;
663 g_return_if_fail (caps != NULL);
664 g_return_if_fail (idx <= gst_caps_get_size (caps));
665 g_return_if_fail (IS_WRITABLE (caps));
667 structure = gst_caps_remove_and_get_structure (caps, idx);
668 gst_structure_free (structure);
672 * gst_caps_merge_structure:
673 * @caps: (transfer full): the #GstCaps to merge into
674 * @structure: (transfer full): the #GstStructure to merge
676 * Appends @structure to @caps if its not already expressed by @caps.
678 * Returns: (transfer full): the merged caps.
681 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
683 GstStructure *structure1;
684 GstCapsFeatures *features1;
686 gboolean unique = TRUE;
688 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
690 if (G_UNLIKELY (structure == NULL))
693 /* check each structure */
694 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
695 structure1 = gst_caps_get_structure_unchecked (caps, i);
696 features1 = gst_caps_get_features_unchecked (caps, i);
698 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
700 /* if structure is a subset of structure1 and the
701 * there are no existing features, then skip it */
702 if (gst_caps_features_is_equal (features1,
703 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
704 && gst_structure_is_subset (structure, structure1)) {
710 caps = gst_caps_make_writable (caps);
711 gst_caps_append_structure_unchecked (caps, structure, NULL);
713 gst_structure_free (structure);
719 * gst_caps_merge_structure_full:
720 * @caps: (transfer full): the #GstCaps to merge into
721 * @structure: (transfer full): the #GstStructure to merge
722 * @features: (transfer full) (allow-none): the #GstCapsFeatures to merge
724 * Appends @structure with @features to @caps if its not already expressed by @caps.
726 * Returns: (transfer full): the merged caps.
731 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
732 GstCapsFeatures * features)
734 GstStructure *structure1;
735 GstCapsFeatures *features1, *features_tmp;
737 gboolean unique = TRUE;
739 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
741 if (G_UNLIKELY (structure == NULL))
744 /* To make comparisons easier below */
745 features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
747 /* check each structure */
748 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
749 structure1 = gst_caps_get_structure_unchecked (caps, i);
750 features1 = gst_caps_get_features_unchecked (caps, i);
752 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
753 /* if structure is a subset of structure1 and the
754 * the features are a subset, then skip it */
755 /* FIXME: We only skip if none of the features are
756 * ANY and are still equal. That way all ANY structures
757 * show up in the caps and no non-ANY structures are
758 * swallowed by ANY structures
760 if (((!gst_caps_features_is_any (features_tmp)
761 || gst_caps_features_is_any (features1))
762 && gst_caps_features_is_equal (features_tmp, features1))
763 && gst_structure_is_subset (structure, structure1)) {
769 caps = gst_caps_make_writable (caps);
770 gst_caps_append_structure_unchecked (caps, structure, features);
772 gst_structure_free (structure);
774 gst_caps_features_free (features);
783 * Gets the number of structures contained in @caps.
785 * Returns: the number of structures that @caps contains
788 gst_caps_get_size (const GstCaps * caps)
790 g_return_val_if_fail (GST_IS_CAPS (caps), 0);
792 return GST_CAPS_LEN (caps);
796 * gst_caps_get_structure:
798 * @index: the index of the structure
800 * Finds the structure in @caps that has the index @index, and
803 * WARNING: This function takes a const GstCaps *, but returns a
804 * non-const GstStructure *. This is for programming convenience --
805 * the caller should be aware that structures inside a constant
806 * #GstCaps should not be modified. However, if you know the caps
807 * are writable, either because you have just copied them or made
808 * them writable with gst_caps_make_writable(), you may modify the
809 * structure returned in the usual way, e.g. with functions like
810 * gst_structure_set().
812 * You do not need to free or unref the structure returned, it
813 * belongs to the #GstCaps.
815 * Returns: (transfer none): a pointer to the #GstStructure corresponding
819 gst_caps_get_structure (const GstCaps * caps, guint index)
821 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
822 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
824 return gst_caps_get_structure_unchecked (caps, index);
828 * gst_caps_get_features:
830 * @index: the index of the structure
832 * Finds the features in @caps that has the index @index, and
835 * WARNING: This function takes a const GstCaps *, but returns a
836 * non-const GstCapsFeatures *. This is for programming convenience --
837 * the caller should be aware that structures inside a constant
838 * #GstCaps should not be modified. However, if you know the caps
839 * are writable, either because you have just copied them or made
840 * them writable with gst_caps_make_writable(), you may modify the
841 * features returned in the usual way, e.g. with functions like
842 * gst_caps_features_add().
844 * You do not need to free or unref the structure returned, it
845 * belongs to the #GstCaps.
847 * Returns: (transfer none): a pointer to the #GstCapsFeatures corresponding
853 gst_caps_get_features (const GstCaps * caps, guint index)
855 GstCapsFeatures *features;
857 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
858 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
860 features = gst_caps_get_features_unchecked (caps, index);
862 GstCapsFeatures **storage;
864 /* We have to do some atomic pointer magic here as the caps
865 * might not be writable and someone else calls this function
866 * at the very same time */
867 features = gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
868 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
870 storage = gst_caps_get_features_storage_unchecked (caps, index);
871 if (!g_atomic_pointer_compare_and_exchange (storage, NULL, features)) {
872 /* Someone did the same we just tried in the meantime */
873 gst_caps_features_set_parent_refcount (features, NULL);
874 gst_caps_features_free (features);
876 features = gst_caps_get_features_unchecked (caps, index);
877 g_assert (features != NULL);
885 * gst_caps_set_features:
887 * @index: the index of the structure
888 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
890 * Sets the #GstCapsFeatures @features for the structure at @index.
895 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
897 GstCapsFeatures **storage, *old;
899 g_return_if_fail (caps != NULL);
900 g_return_if_fail (index <= gst_caps_get_size (caps));
901 g_return_if_fail (IS_WRITABLE (caps));
903 storage = gst_caps_get_features_storage_unchecked (caps, index);
904 /* Not much problem here as caps are writable */
905 old = g_atomic_pointer_get (storage);
906 g_atomic_pointer_set (storage, features);
909 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
912 gst_caps_features_free (old);
917 * @caps: the #GstCaps to copy
918 * @nth: the nth structure to copy
920 * Creates a new #GstCaps and appends a copy of the nth structure
921 * contained in @caps.
923 * Returns: (transfer full): the new #GstCaps
926 gst_caps_copy_nth (const GstCaps * caps, guint nth)
929 GstStructure *structure;
930 GstCapsFeatures *features;
932 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
934 newcaps = gst_caps_new_empty ();
935 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
937 if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
938 structure = gst_caps_get_structure_unchecked (caps, nth);
939 features = gst_caps_get_features_unchecked (caps, nth);
940 gst_caps_append_structure_unchecked (newcaps,
941 gst_structure_copy (structure),
942 gst_caps_features_copy_conditional (features));
950 * @caps: (transfer full): the #GstCaps to truncate
952 * Discard all but the first structure from @caps. Useful when
955 * Returns: (transfer full): truncated caps
958 gst_caps_truncate (GstCaps * caps)
962 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
964 i = GST_CAPS_LEN (caps) - 1;
968 caps = gst_caps_make_writable (caps);
970 gst_caps_remove_structure (caps, i--);
976 * gst_caps_set_value:
977 * @caps: a writable caps
978 * @field: name of the field to set
979 * @value: value to set the field to
981 * Sets the given @field on all structures of @caps to the given @value.
982 * This is a convenience function for calling gst_structure_set_value() on
983 * all structures of @caps.
986 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
990 g_return_if_fail (GST_IS_CAPS (caps));
991 g_return_if_fail (IS_WRITABLE (caps));
992 g_return_if_fail (field != NULL);
993 g_return_if_fail (G_IS_VALUE (value));
995 len = GST_CAPS_LEN (caps);
996 for (i = 0; i < len; i++) {
997 GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
998 gst_structure_set_value (structure, field, value);
1003 * gst_caps_set_simple_valist:
1004 * @caps: the #GstCaps to set
1005 * @field: first field to set
1006 * @varargs: additional parameters
1008 * Sets fields in a #GstCaps. The arguments must be passed in the same
1009 * manner as gst_structure_set(), and be NULL-terminated.
1012 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
1014 GValue value = { 0, };
1016 g_return_if_fail (GST_IS_CAPS (caps));
1017 g_return_if_fail (IS_WRITABLE (caps));
1023 type = va_arg (varargs, GType);
1025 G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1026 if (G_UNLIKELY (err)) {
1027 g_critical ("%s", err);
1031 gst_caps_set_value (caps, field, &value);
1033 g_value_unset (&value);
1035 field = va_arg (varargs, const gchar *);
1040 * gst_caps_set_simple:
1041 * @caps: the #GstCaps to set
1042 * @field: first field to set
1043 * @...: additional parameters
1045 * Sets fields in a #GstCaps. The arguments must be passed in the same
1046 * manner as gst_structure_set(), and be NULL-terminated.
1049 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1053 g_return_if_fail (GST_IS_CAPS (caps));
1054 g_return_if_fail (IS_WRITABLE (caps));
1056 va_start (var_args, field);
1057 gst_caps_set_simple_valist (caps, field, var_args);
1065 * @caps: the #GstCaps to test
1067 * Determines if @caps represents any media format.
1069 * Returns: TRUE if @caps represents any format.
1072 gst_caps_is_any (const GstCaps * caps)
1074 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1076 return (CAPS_IS_ANY (caps));
1080 * gst_caps_is_empty:
1081 * @caps: the #GstCaps to test
1083 * Determines if @caps represents no media formats.
1085 * Returns: TRUE if @caps represents no formats.
1088 gst_caps_is_empty (const GstCaps * caps)
1090 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1092 if (CAPS_IS_ANY (caps))
1095 return CAPS_IS_EMPTY_SIMPLE (caps);
1099 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1102 return gst_value_is_fixed (value);
1106 * gst_caps_is_fixed:
1107 * @caps: the #GstCaps to test
1109 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1110 * one structure, and each field in the structure describes a fixed type.
1111 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1113 * Returns: TRUE if @caps is fixed
1116 gst_caps_is_fixed (const GstCaps * caps)
1118 GstStructure *structure;
1119 GstCapsFeatures *features;
1121 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1123 if (GST_CAPS_LEN (caps) != 1)
1126 features = gst_caps_get_features_unchecked (caps, 0);
1127 if (features && gst_caps_features_is_any (features))
1130 structure = gst_caps_get_structure_unchecked (caps, 0);
1132 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1136 * gst_caps_is_equal_fixed:
1137 * @caps1: the #GstCaps to test
1138 * @caps2: the #GstCaps to test
1140 * Tests if two #GstCaps are equal. This function only works on fixed
1143 * Returns: TRUE if the arguments represent the same format
1146 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1148 GstStructure *struct1, *struct2;
1149 GstCapsFeatures *features1, *features2;
1151 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1152 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1154 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1155 features1 = gst_caps_get_features_unchecked (caps1, 0);
1157 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1158 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1159 features2 = gst_caps_get_features_unchecked (caps2, 0);
1161 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1163 return gst_structure_is_equal (struct1, struct2) &&
1164 gst_caps_features_is_equal (features1, features2);
1168 * gst_caps_is_always_compatible:
1169 * @caps1: the #GstCaps to test
1170 * @caps2: the #GstCaps to test
1172 * A given #GstCaps structure is always compatible with another if
1173 * every media format that is in the first is also contained in the
1174 * second. That is, @caps1 is a subset of @caps2.
1176 * Returns: TRUE if @caps1 is a subset of @caps2.
1179 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1181 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1182 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1184 return gst_caps_is_subset (caps1, caps2);
1188 * gst_caps_is_subset:
1189 * @subset: a #GstCaps
1190 * @superset: a potentially greater #GstCaps
1192 * Checks if all caps represented by @subset are also represented by @superset.
1194 * Returns: %TRUE if @subset is a subset of @superset
1197 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1199 GstStructure *s1, *s2;
1200 GstCapsFeatures *f1, *f2;
1201 gboolean ret = TRUE;
1204 g_return_val_if_fail (subset != NULL, FALSE);
1205 g_return_val_if_fail (superset != NULL, FALSE);
1207 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1209 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1212 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1213 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1214 s1 = gst_caps_get_structure_unchecked (subset, i);
1215 f1 = gst_caps_get_features_unchecked (subset, i);
1217 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1218 s2 = gst_caps_get_structure_unchecked (superset, j);
1219 f2 = gst_caps_get_features_unchecked (superset, j);
1221 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1222 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1223 gst_caps_features_is_equal (f1, f2)
1224 && gst_structure_is_subset (s1, s2)) {
1225 /* If we found a superset, continue with the next
1226 * subset structure */
1230 /* If we found no superset for this subset structure
1231 * we return FALSE immediately */
1242 * gst_caps_is_subset_structure:
1244 * @structure: a potential #GstStructure subset of @caps
1246 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1247 * for more information.
1249 * Returns: %TRUE if @structure is a subset of @caps
1252 gst_caps_is_subset_structure (const GstCaps * caps,
1253 const GstStructure * structure)
1258 g_return_val_if_fail (caps != NULL, FALSE);
1259 g_return_val_if_fail (structure != NULL, FALSE);
1261 if (CAPS_IS_ANY (caps))
1263 if (CAPS_IS_EMPTY (caps))
1266 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1267 s = gst_caps_get_structure_unchecked (caps, i);
1268 if (gst_structure_is_subset (structure, s)) {
1269 /* If we found a superset return TRUE */
1278 * gst_caps_is_subset_structure_full:
1280 * @structure: a potential #GstStructure subset of @caps
1281 * @features: (allow-none): a #GstCapsFeatures for @structure
1283 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1284 * for more information.
1286 * Returns: %TRUE if @structure is a subset of @caps
1291 gst_caps_is_subset_structure_full (const GstCaps * caps,
1292 const GstStructure * structure, const GstCapsFeatures * features)
1298 g_return_val_if_fail (caps != NULL, FALSE);
1299 g_return_val_if_fail (structure != NULL, FALSE);
1301 if (CAPS_IS_ANY (caps))
1303 if (CAPS_IS_EMPTY (caps))
1307 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1309 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1310 s = gst_caps_get_structure_unchecked (caps, i);
1311 f = gst_caps_get_features_unchecked (caps, i);
1313 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1314 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1315 && gst_caps_features_is_equal (features, f)
1316 && gst_structure_is_subset (structure, s)) {
1317 /* If we found a superset return TRUE */
1326 * gst_caps_is_equal:
1327 * @caps1: a #GstCaps
1328 * @caps2: another #GstCaps
1330 * Checks if the given caps represent the same set of caps.
1332 * Returns: TRUE if both caps are equal.
1335 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1337 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1338 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1340 if (G_UNLIKELY (caps1 == caps2))
1343 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1344 return gst_caps_is_equal_fixed (caps1, caps2);
1346 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1350 * gst_caps_is_strictly_equal:
1351 * @caps1: a #GstCaps
1352 * @caps2: another #GstCaps
1354 * Checks if the given caps are exactly the same set of caps.
1356 * Returns: TRUE if both caps are strictly equal.
1359 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1362 GstStructure *s1, *s2;
1363 GstCapsFeatures *f1, *f2;
1365 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1366 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1368 if (G_UNLIKELY (caps1 == caps2))
1371 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1374 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1375 s1 = gst_caps_get_structure_unchecked (caps1, i);
1376 f1 = gst_caps_get_features_unchecked (caps1, i);
1378 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1379 s2 = gst_caps_get_structure_unchecked (caps2, i);
1380 f2 = gst_caps_get_features_unchecked (caps2, i);
1382 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1384 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1385 !gst_caps_features_is_equal (f1, f2) ||
1386 !gst_structure_is_equal (s1, s2))
1393 /* intersect operation */
1396 * gst_caps_can_intersect:
1397 * @caps1: a #GstCaps to intersect
1398 * @caps2: a #GstCaps to intersect
1400 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1403 * Returns: %TRUE if intersection would be not empty
1406 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1408 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1409 guint j, k, len1, len2;
1410 GstStructure *struct1;
1411 GstStructure *struct2;
1412 GstCapsFeatures *features1;
1413 GstCapsFeatures *features2;
1415 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1416 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1418 /* caps are exactly the same pointers */
1419 if (G_UNLIKELY (caps1 == caps2))
1422 /* empty caps on either side, return empty */
1423 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1426 /* one of the caps is any */
1427 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1430 /* run zigzag on top line then right line, this preserves the caps order
1431 * much better than a simple loop.
1433 * This algorithm zigzags over the caps structures as demonstrated in
1434 * the following matrix:
1437 * +------------- total distance: +-------------
1438 * | 1 2 4 7 0 | 0 1 2 3
1439 * caps2 | 3 5 8 10 1 | 1 2 3 4
1440 * | 6 9 11 12 2 | 2 3 4 5
1442 * First we iterate over the caps1 structures (top line) intersecting
1443 * the structures diagonally down, then we iterate over the caps2
1444 * structures. The result is that the intersections are ordered based on the
1445 * sum of the indexes in the list.
1447 len1 = GST_CAPS_LEN (caps1);
1448 len2 = GST_CAPS_LEN (caps2);
1449 for (i = 0; i < len1 + len2 - 1; i++) {
1450 /* superset index goes from 0 to sgst_caps_structure_intersectuperset->structs->len-1 */
1451 j = MIN (i, len1 - 1);
1452 /* subset index stays 0 until i reaches superset->structs->len, then it
1453 * counts up from 1 to subset->structs->len - 1 */
1454 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1455 /* now run the diagonal line, end condition is the left or bottom
1458 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1459 features1 = gst_caps_get_features_unchecked (caps1, j);
1461 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1462 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1463 features2 = gst_caps_get_features_unchecked (caps2, k);
1465 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1466 if (gst_caps_features_is_equal (features1, features2) &&
1467 gst_structure_can_intersect (struct1, struct2)) {
1470 /* move down left */
1472 if (G_UNLIKELY (j == 0))
1473 break; /* so we don't roll back to G_MAXUINT */
1482 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1484 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1485 guint j, k, len1, len2;
1486 GstStructure *struct1;
1487 GstStructure *struct2;
1488 GstCapsFeatures *features1;
1489 GstCapsFeatures *features2;
1491 GstStructure *istruct;
1493 /* caps are exactly the same pointers, just copy one caps */
1494 if (G_UNLIKELY (caps1 == caps2))
1495 return gst_caps_ref (caps1);
1497 /* empty caps on either side, return empty */
1498 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1499 return gst_caps_ref (GST_CAPS_NONE);
1501 /* one of the caps is any, just copy the other caps */
1502 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1503 return gst_caps_ref (caps2);
1505 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1506 return gst_caps_ref (caps1);
1508 dest = gst_caps_new_empty ();
1509 /* run zigzag on top line then right line, this preserves the caps order
1510 * much better than a simple loop.
1512 * This algorithm zigzags over the caps structures as demonstrated in
1513 * the following matrix:
1521 * First we iterate over the caps1 structures (top line) intersecting
1522 * the structures diagonally down, then we iterate over the caps2
1525 len1 = GST_CAPS_LEN (caps1);
1526 len2 = GST_CAPS_LEN (caps2);
1527 for (i = 0; i < len1 + len2 - 1; i++) {
1528 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1529 j = MIN (i, len1 - 1);
1530 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1531 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1532 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1533 /* now run the diagonal line, end condition is the left or bottom
1536 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1537 features1 = gst_caps_get_features_unchecked (caps1, j);
1539 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1540 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1541 features2 = gst_caps_get_features_unchecked (caps2, k);
1543 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1544 if (gst_caps_features_is_equal (features1, features2)) {
1545 istruct = gst_structure_intersect (struct1, struct2);
1547 if (gst_caps_features_is_any (features1))
1549 gst_caps_merge_structure_full (dest, istruct,
1550 gst_caps_features_copy_conditional (features2));
1553 gst_caps_merge_structure_full (dest, istruct,
1554 gst_caps_features_copy_conditional (features1));
1557 /* move down left */
1559 if (G_UNLIKELY (j == 0))
1560 break; /* so we don't roll back to G_MAXUINT */
1568 * gst_caps_intersect_first:
1569 * @caps1: a #GstCaps to intersect
1570 * @caps2: a #GstCaps to intersect
1572 * Creates a new #GstCaps that contains all the formats that are common
1573 * to both @caps1 and @caps2.
1575 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1576 * fashion as @caps1.
1578 * Returns: the new #GstCaps
1581 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1584 guint j, len1, len2;
1585 GstStructure *struct1;
1586 GstStructure *struct2;
1587 GstCapsFeatures *features1;
1588 GstCapsFeatures *features2;
1590 GstStructure *istruct;
1592 /* caps are exactly the same pointers, just copy one caps */
1593 if (G_UNLIKELY (caps1 == caps2))
1594 return gst_caps_ref (caps1);
1596 /* empty caps on either side, return empty */
1597 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1598 return gst_caps_ref (GST_CAPS_NONE);
1600 /* one of the caps is any, just copy the other caps */
1601 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1602 return gst_caps_ref (caps2);
1604 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1605 return gst_caps_ref (caps1);
1607 dest = gst_caps_new_empty ();
1608 len1 = GST_CAPS_LEN (caps1);
1609 len2 = GST_CAPS_LEN (caps2);
1610 for (i = 0; i < len1; i++) {
1611 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1612 features1 = gst_caps_get_features_unchecked (caps1, i);
1614 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1615 for (j = 0; j < len2; j++) {
1616 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1617 features2 = gst_caps_get_features_unchecked (caps2, j);
1619 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1620 if (gst_caps_features_is_equal (features1, features2)) {
1621 istruct = gst_structure_intersect (struct1, struct2);
1623 if (gst_caps_features_is_any (features1))
1625 gst_caps_merge_structure_full (dest, istruct,
1626 gst_caps_features_copy_conditional (features2));
1629 gst_caps_merge_structure_full (dest, istruct,
1630 gst_caps_features_copy_conditional (features1));
1640 * gst_caps_intersect_full:
1641 * @caps1: a #GstCaps to intersect
1642 * @caps2: a #GstCaps to intersect
1643 * @mode: The intersection algorithm/mode to use
1645 * Creates a new #GstCaps that contains all the formats that are common
1646 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1649 * Returns: the new #GstCaps
1652 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1653 GstCapsIntersectMode mode)
1655 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1656 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1659 case GST_CAPS_INTERSECT_FIRST:
1660 return gst_caps_intersect_first (caps1, caps2);
1662 g_warning ("Unknown caps intersect mode: %d", mode);
1664 case GST_CAPS_INTERSECT_ZIG_ZAG:
1665 return gst_caps_intersect_zig_zag (caps1, caps2);
1670 * gst_caps_intersect:
1671 * @caps1: a #GstCaps to intersect
1672 * @caps2: a #GstCaps to intersect
1674 * Creates a new #GstCaps that contains all the formats that are common
1675 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1677 * Returns: the new #GstCaps
1680 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1682 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1685 /* subtract operation */
1689 const GstStructure *subtract_from;
1694 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1697 SubtractionEntry *e = user_data;
1698 GValue subtraction = { 0, };
1699 const GValue *other;
1700 GstStructure *structure;
1702 other = gst_structure_id_get_value (e->subtract_from, field_id);
1708 if (!gst_value_subtract (&subtraction, other, value))
1711 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1712 g_value_unset (&subtraction);
1715 structure = gst_structure_copy (e->subtract_from);
1716 gst_structure_id_take_value (structure, field_id, &subtraction);
1717 e->put_into = g_slist_prepend (e->put_into, structure);
1723 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1724 const GstStructure * subtrahend)
1729 e.subtract_from = minuend;
1731 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1732 gst_caps_structure_subtract_field, &e);
1739 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1740 gst_structure_free (walk->data);
1742 g_slist_free (e.put_into);
1749 * gst_caps_subtract:
1750 * @minuend: #GstCaps to subtract from
1751 * @subtrahend: #GstCaps to subtract
1753 * Subtracts the @subtrahend from the @minuend.
1754 * <note>This function does not work reliably if optional properties for caps
1755 * are included on one caps and omitted on the other.</note>
1757 * Returns: the resulting caps
1760 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1765 GstCapsFeatures *min_f, *sub_f;
1766 GstCaps *dest = NULL, *src;
1768 g_return_val_if_fail (minuend != NULL, NULL);
1769 g_return_val_if_fail (subtrahend != NULL, NULL);
1771 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1772 return gst_caps_new_empty ();
1775 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1776 return gst_caps_ref (minuend);
1778 /* FIXME: Do we want this here or above?
1779 The reason we need this is that there is no definition about what
1780 ANY means for specific types, so it's not possible to reduce ANY partially
1781 You can only remove everything or nothing and that is done above.
1782 Note: there's a test that checks this behaviour. */
1784 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1785 sublen = GST_CAPS_LEN (subtrahend);
1786 g_assert (sublen > 0);
1788 src = _gst_caps_copy (minuend);
1789 for (i = 0; i < sublen; i++) {
1792 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1793 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1795 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1797 gst_caps_unref (src);
1800 dest = gst_caps_new_empty ();
1801 srclen = GST_CAPS_LEN (src);
1802 for (j = 0; j < srclen; j++) {
1803 min = gst_caps_get_structure_unchecked (src, j);
1804 min_f = gst_caps_get_features_unchecked (src, j);
1806 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1808 /* Same reason as above for ANY caps */
1809 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1811 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1812 gst_caps_features_is_equal (min_f, sub_f)) {
1815 if (gst_caps_structure_subtract (&list, min, sub)) {
1818 for (walk = list; walk; walk = g_slist_next (walk)) {
1819 gst_caps_append_structure_unchecked (dest,
1820 (GstStructure *) walk->data,
1821 gst_caps_features_copy_conditional (min_f));
1823 g_slist_free (list);
1825 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1826 gst_caps_features_copy_conditional (min_f));
1829 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1830 gst_caps_features_copy_conditional (min_f));
1834 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1835 gst_caps_unref (src);
1840 gst_caps_unref (src);
1841 dest = gst_caps_simplify (dest);
1846 /* normalize/simplify operations */
1848 typedef struct _NormalizeForeach
1851 GstStructure *structure;
1852 GstCapsFeatures *features;
1856 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1858 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1862 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1863 guint len = gst_value_list_get_size (value);
1865 for (i = 1; i < len; i++) {
1866 const GValue *v = gst_value_list_get_value (value, i);
1867 GstStructure *structure = gst_structure_copy (nf->structure);
1869 gst_structure_id_set_value (structure, field_id, v);
1870 gst_caps_append_structure_unchecked (nf->caps, structure,
1871 gst_caps_features_copy_conditional (nf->features));
1874 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1875 gst_structure_id_take_value (nf->structure, field_id, &val);
1883 * gst_caps_normalize:
1884 * @caps: (transfer full): a #GstCaps to normalize
1886 * Returns a #GstCaps that represents the same set of formats as
1887 * @caps, but contains no lists. Each list is expanded into separate
1890 * This function takes ownership of @caps.
1892 * Returns: (transfer full): the normalized #GstCaps
1895 gst_caps_normalize (GstCaps * caps)
1897 NormalizeForeach nf;
1900 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1902 caps = gst_caps_make_writable (caps);
1905 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1906 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1907 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1908 while (!gst_structure_foreach (nf.structure,
1909 gst_caps_normalize_foreach, &nf));
1916 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1919 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1920 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1922 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1923 So what's the best way? */
1924 ret = strcmp (gst_structure_get_name (struct1),
1925 gst_structure_get_name (struct2));
1930 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1937 GstStructure *compare;
1941 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1944 UnionField *u = user_data;
1945 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1949 g_value_unset (&u->value);
1953 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1957 g_value_unset (&u->value);
1962 gst_value_union (&u->value, val, value);
1968 gst_caps_structure_simplify (GstStructure ** result,
1969 GstStructure * simplify, GstStructure * compare)
1972 UnionField field = { 0, {0,}, NULL };
1974 /* try to subtract to get a real subset */
1975 if (gst_caps_structure_subtract (&list, simplify, compare)) {
1976 if (list == NULL) { /* no result */
1979 } else if (list->next == NULL) { /* one result */
1980 *result = list->data;
1981 g_slist_free (list);
1983 } else { /* multiple results */
1984 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
1985 g_slist_free (list);
1990 /* try to union both structs */
1991 field.compare = compare;
1992 if (gst_structure_foreach (simplify,
1993 gst_caps_structure_figure_out_union, &field)) {
1994 gboolean ret = FALSE;
1996 /* now we know all of simplify's fields are the same in compare
1997 * but at most one field: field.name */
1998 if (G_IS_VALUE (&field.value)) {
1999 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
2000 gst_structure_id_take_value (compare, field.name, &field.value);
2004 g_value_unset (&field.value);
2007 if (gst_structure_n_fields (simplify) <=
2008 gst_structure_n_fields (compare)) {
2009 /* compare is just more specific, will be optimized away later */
2010 /* FIXME: do this here? */
2011 GST_LOG ("found a case that will be optimized later.");
2013 gchar *one = gst_structure_to_string (simplify);
2014 gchar *two = gst_structure_to_string (compare);
2017 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2029 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2030 GstStructure * new, gint i)
2032 gst_structure_set_parent_refcount (old, NULL);
2033 gst_structure_free (old);
2034 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2035 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2039 * gst_caps_simplify:
2040 * @caps: (transfer full): a #GstCaps to simplify
2042 * Converts the given @caps into a representation that represents the
2043 * same set of formats, but in a simpler form. Component structures that are
2044 * identical are merged. Component structures that have values that can be
2045 * merged are also merged.
2047 * This method does not preserve the original order of @caps.
2049 * Returns: The simplified caps.
2052 gst_caps_simplify (GstCaps * caps)
2054 GstStructure *simplify, *compare, *result = NULL;
2055 GstCapsFeatures *simplify_f, *compare_f;
2058 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2060 start = GST_CAPS_LEN (caps) - 1;
2061 /* one caps, already as simple as can be */
2065 caps = gst_caps_make_writable (caps);
2067 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2069 for (i = start; i >= 0; i--) {
2070 simplify = gst_caps_get_structure_unchecked (caps, i);
2071 simplify_f = gst_caps_get_features_unchecked (caps, i);
2073 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2074 compare = gst_caps_get_structure_unchecked (caps, start);
2075 compare_f = gst_caps_get_features_unchecked (caps, start);
2077 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2078 if (gst_structure_get_name_id (simplify) !=
2079 gst_structure_get_name_id (compare) ||
2080 !gst_caps_features_is_equal (simplify_f, compare_f))
2082 for (j = start; j >= 0; j--) {
2085 compare = gst_caps_get_structure_unchecked (caps, j);
2086 compare_f = gst_caps_get_features_unchecked (caps, j);
2088 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2089 if (gst_structure_get_name_id (simplify) !=
2090 gst_structure_get_name_id (compare) ||
2091 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2094 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2096 gst_caps_switch_structures (caps, simplify, result, i);
2099 gst_caps_remove_structure (caps, i);
2111 * @caps: (transfer full): a #GstCaps to fixate
2113 * Modifies the given @caps into a representation with only fixed
2114 * values. First the caps will be truncated and then the first structure will be
2115 * fixated with gst_structure_fixate().
2117 * Returns: (transfer full): the fixated caps
2120 gst_caps_fixate (GstCaps * caps)
2125 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2127 /* default fixation */
2128 caps = gst_caps_truncate (caps);
2129 caps = gst_caps_make_writable (caps);
2130 s = gst_caps_get_structure (caps, 0);
2131 gst_structure_fixate (s);
2133 /* Set features to sysmem if they're still ANY */
2134 f = gst_caps_get_features_unchecked (caps, 0);
2135 if (f && gst_caps_features_is_any (f)) {
2136 f = gst_caps_features_new_empty ();
2137 gst_caps_set_features (caps, 0, f);
2146 * gst_caps_to_string:
2149 * Converts @caps to a string representation. This string representation
2150 * can be converted back to a #GstCaps by gst_caps_from_string().
2152 * For debugging purposes its easier to do something like this:
2154 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2156 * This prints the caps in human readable form.
2158 * The current implementation of serialization will lead to unexpected results
2159 * when there are nested #GstCaps / #GstStructure deeper than one level.
2161 * Returns: (transfer full): a newly allocated string representing @caps.
2164 gst_caps_to_string (const GstCaps * caps)
2166 guint i, slen, clen;
2169 /* NOTE: This function is potentially called by the debug system,
2170 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2171 * should be careful to avoid recursion. This includes any functions
2172 * called by gst_caps_to_string. In particular, calls should
2173 * not use the GST_PTR_FORMAT extension. */
2176 return g_strdup ("NULL");
2178 if (CAPS_IS_ANY (caps)) {
2179 return g_strdup ("ANY");
2181 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2182 return g_strdup ("EMPTY");
2185 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2187 clen = GST_CAPS_LEN (caps);
2188 for (i = 0; i < clen; i++) {
2192 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2194 f = gst_caps_get_features_unchecked (caps, i);
2196 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2199 s = g_string_sized_new (slen);
2200 for (i = 0; i < clen; i++) {
2201 GstStructure *structure;
2202 GstCapsFeatures *features;
2205 /* ';' is now added by gst_structure_to_string */
2206 g_string_append_c (s, ' ');
2209 structure = gst_caps_get_structure_unchecked (caps, i);
2210 features = gst_caps_get_features_unchecked (caps, i);
2212 g_string_append (s, gst_structure_get_name (structure));
2213 if (features && (gst_caps_features_is_any (features)
2214 || !gst_caps_features_is_equal (features,
2215 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2216 g_string_append_c (s, '(');
2217 priv_gst_caps_features_append_to_gstring (features, s);
2218 g_string_append_c (s, ')');
2220 priv_gst_structure_append_to_gstring (structure, s);
2222 if (s->len && s->str[s->len - 1] == ';') {
2223 /* remove latest ';' */
2224 s->str[--s->len] = '\0';
2226 return g_string_free (s, FALSE);
2230 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2232 GstStructure *structure;
2233 gchar *s, *copy, *end, *next, save;
2235 if (strcmp ("ANY", string) == 0) {
2236 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2240 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2244 copy = s = g_strdup (string);
2246 GstCapsFeatures *features = NULL;
2248 while (g_ascii_isspace (*s))
2254 if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2261 structure = gst_structure_new_empty (s);
2264 if (structure == NULL) {
2282 } else if (*end == ')') {
2291 features = gst_caps_features_from_string (s);
2293 gst_structure_free (structure);
2307 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2308 gst_structure_free (structure);
2314 gst_caps_append_structure_unchecked (caps, structure, features);
2325 * gst_caps_from_string:
2326 * @string: a string to convert to #GstCaps
2328 * Converts @caps from a string representation.
2330 * The current implementation of serialization will lead to unexpected results
2331 * when there are nested #GstCaps / #GstStructure deeper than one level.
2333 * Returns: (transfer full): a newly allocated #GstCaps
2336 gst_caps_from_string (const gchar * string)
2340 g_return_val_if_fail (string, FALSE);
2342 caps = gst_caps_new_empty ();
2343 if (gst_caps_from_string_inplace (caps, string)) {
2346 gst_caps_unref (caps);
2352 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2354 g_return_if_fail (G_IS_VALUE (src_value));
2355 g_return_if_fail (G_IS_VALUE (dest_value));
2356 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2357 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2358 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2360 g_value_take_string (dest_value,
2361 gst_caps_to_string (gst_value_get_caps (src_value)));