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_unchecked(caps, index) \
118 (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
119 /* quick way to append a structure without checking the args */
120 #define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
121 GstCapsArrayElement __e={s, f}; \
122 if (gst_structure_set_parent_refcount (__e.structure, &GST_MINI_OBJECT_REFCOUNT(caps)) && \
123 (!__e.features || gst_caps_features_set_parent_refcount (__e.features, &GST_MINI_OBJECT_REFCOUNT(caps)))) \
124 g_array_append_val (GST_CAPS_ARRAY (caps), __e); \
127 /* lock to protect multiple invocations of static caps to caps conversion */
128 G_LOCK_DEFINE_STATIC (static_caps_lock);
130 static void gst_caps_transform_to_string (const GValue * src_value,
131 GValue * dest_value);
132 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
133 const gchar * string);
135 GType _gst_caps_type = 0;
136 GstCaps *_gst_caps_any;
137 GstCaps *_gst_caps_none;
139 GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
142 _priv_gst_caps_initialize (void)
144 _gst_caps_type = gst_caps_get_type ();
146 _gst_caps_any = gst_caps_new_any ();
147 _gst_caps_none = gst_caps_new_empty ();
149 g_value_register_transform_func (_gst_caps_type,
150 G_TYPE_STRING, gst_caps_transform_to_string);
154 _gst_caps_copy (const GstCaps * caps)
157 GstStructure *structure;
158 GstCapsFeatures *features;
161 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
163 newcaps = gst_caps_new_empty ();
164 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
165 n = GST_CAPS_LEN (caps);
167 GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, caps, "doing copy %p -> %p",
170 for (i = 0; i < n; i++) {
171 structure = gst_caps_get_structure_unchecked (caps, i);
172 features = gst_caps_get_features_unchecked (caps, i);
173 gst_caps_append_structure_full (newcaps, gst_structure_copy (structure),
174 gst_caps_features_copy_conditional (features));
180 /* creation/deletion */
182 _gst_caps_free (GstCaps * caps)
184 GstStructure *structure;
185 GstCapsFeatures *features;
188 /* The refcount must be 0, but since we're only called by gst_caps_unref,
189 * don't bother testing. */
190 len = GST_CAPS_LEN (caps);
191 /* This can be used to get statistics about caps sizes */
192 /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
193 for (i = 0; i < len; i++) {
194 structure = gst_caps_get_structure_unchecked (caps, i);
195 gst_structure_set_parent_refcount (structure, NULL);
196 gst_structure_free (structure);
197 features = gst_caps_get_features_unchecked (caps, i);
199 gst_caps_features_set_parent_refcount (features, NULL);
200 gst_caps_features_free (features);
203 g_array_free (GST_CAPS_ARRAY (caps), TRUE);
205 #ifdef DEBUG_REFCOUNT
206 GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
208 g_slice_free1 (sizeof (GstCapsImpl), caps);
212 gst_caps_init (GstCaps * caps)
214 gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
215 (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
216 (GstMiniObjectFreeFunction) _gst_caps_free);
218 /* the 32 has been determined by logging caps sizes in _gst_caps_free
219 * but g_ptr_array uses 16 anyway if it expands once, so this does not help
221 * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
223 GST_CAPS_ARRAY (caps) =
224 g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
228 * gst_caps_new_empty:
230 * Creates a new #GstCaps that is empty. That is, the returned
231 * #GstCaps contains no media formats.
232 * The #GstCaps is guaranteed to be writable.
233 * Caller is responsible for unreffing the returned caps.
235 * Returns: (transfer full): the new #GstCaps
238 gst_caps_new_empty (void)
242 caps = (GstCaps *) g_slice_new (GstCapsImpl);
244 gst_caps_init (caps);
246 #ifdef DEBUG_REFCOUNT
247 GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
256 * Creates a new #GstCaps that indicates that it is compatible with
259 * Returns: (transfer full): the new #GstCaps
262 gst_caps_new_any (void)
264 GstCaps *caps = gst_caps_new_empty ();
266 GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_ANY);
272 * gst_caps_new_empty_simple:
273 * @media_type: the media type of the structure
275 * Creates a new #GstCaps that contains one #GstStructure with name
277 * Caller is responsible for unreffing the returned caps.
279 * Returns: (transfer full): the new #GstCaps
282 gst_caps_new_empty_simple (const char *media_type)
285 GstStructure *structure;
287 caps = gst_caps_new_empty ();
288 structure = gst_structure_new_empty (media_type);
290 gst_caps_append_structure_unchecked (caps, structure, NULL);
296 * gst_caps_new_simple:
297 * @media_type: the media type of the structure
298 * @fieldname: first field to set
299 * @...: additional arguments
301 * Creates a new #GstCaps that contains one #GstStructure. The
302 * structure is defined by the arguments, which have the same format
303 * as gst_structure_new().
304 * Caller is responsible for unreffing the returned caps.
306 * Returns: (transfer full): the new #GstCaps
309 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
312 GstStructure *structure;
315 caps = gst_caps_new_empty ();
317 va_start (var_args, fieldname);
318 structure = gst_structure_new_valist (media_type, fieldname, var_args);
322 gst_caps_append_structure_unchecked (caps, structure, NULL);
324 gst_caps_replace (&caps, NULL);
331 * @struct1: the first structure to add
332 * @...: additional structures to add
334 * Creates a new #GstCaps and adds all the structures listed as
335 * arguments. The list must be NULL-terminated. The structures
336 * are not copied; the returned #GstCaps owns the structures.
338 * Returns: (transfer full): the new #GstCaps
341 gst_caps_new_full (GstStructure * struct1, ...)
346 va_start (var_args, struct1);
347 caps = gst_caps_new_full_valist (struct1, var_args);
354 * gst_caps_new_full_valist:
355 * @structure: the first structure to add
356 * @var_args: additional structures to add
358 * Creates a new #GstCaps and adds all the structures listed as
359 * arguments. The list must be NULL-terminated. The structures
360 * are not copied; the returned #GstCaps owns the structures.
362 * Returns: (transfer full): the new #GstCaps
365 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
369 caps = gst_caps_new_empty ();
372 gst_caps_append_structure_unchecked (caps, structure, NULL);
373 structure = va_arg (var_args, GstStructure *);
379 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
382 * gst_static_caps_get:
383 * @static_caps: the #GstStaticCaps to convert
385 * Converts a #GstStaticCaps to a #GstCaps.
387 * Returns: (transfer full): a pointer to the #GstCaps. Unref after usage.
388 * Since the core holds an additional ref to the returned caps,
389 * use gst_caps_make_writable() on the returned caps to modify it.
392 gst_static_caps_get (GstStaticCaps * static_caps)
396 g_return_val_if_fail (static_caps != NULL, NULL);
398 caps = &static_caps->caps;
400 /* refcount is 0 when we need to convert */
401 if (G_UNLIKELY (*caps == NULL)) {
404 G_LOCK (static_caps_lock);
405 /* check if other thread already updated */
406 if (G_UNLIKELY (*caps != NULL))
409 string = static_caps->string;
411 if (G_UNLIKELY (string == NULL))
414 *caps = gst_caps_from_string (string);
416 /* convert to string */
417 if (G_UNLIKELY (*caps == NULL))
418 g_critical ("Could not convert static caps \"%s\"", string);
420 GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
423 G_UNLOCK (static_caps_lock);
425 /* ref the caps, makes it not writable */
426 if (G_LIKELY (*caps != NULL))
427 gst_caps_ref (*caps);
434 G_UNLOCK (static_caps_lock);
435 g_warning ("static caps %p string is NULL", static_caps);
441 * gst_static_caps_cleanup:
442 * @static_caps: the #GstStaticCaps to clean
444 * Clean up the cached caps contained in @static_caps.
447 gst_static_caps_cleanup (GstStaticCaps * static_caps)
449 G_LOCK (static_caps_lock);
450 gst_caps_replace (&static_caps->caps, NULL);
451 G_UNLOCK (static_caps_lock);
457 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
458 GstStructure ** s, GstCapsFeatures ** f)
463 s_ = gst_caps_get_structure_unchecked (caps, idx);
464 f_ = gst_caps_get_features_unchecked (caps, idx);
466 /* don't use index_fast, gst_caps_simplify relies on the order */
467 g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
469 gst_structure_set_parent_refcount (s_, NULL);
471 gst_caps_features_set_parent_refcount (f_, NULL);
478 static GstStructure *
479 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
484 gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
487 gst_caps_features_free (f);
495 * gst_caps_steal_structure:
496 * @caps: the #GstCaps to retrieve from
497 * @index: Index of the structure to retrieve
499 * Retrieves the structure with the given index from the list of structures
500 * contained in @caps. The caller becomes the owner of the returned structure.
502 * Returns: (transfer full): a pointer to the #GstStructure corresponding
506 gst_caps_steal_structure (GstCaps * caps, guint index)
508 g_return_val_if_fail (caps != NULL, NULL);
509 g_return_val_if_fail (IS_WRITABLE (caps), NULL);
511 if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
514 return gst_caps_remove_and_get_structure (caps, index);
519 * @caps1: the #GstCaps that will be appended to
520 * @caps2: (transfer full): the #GstCaps to append
522 * Appends the structures contained in @caps2 to @caps1. The structures in
523 * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
524 * freed. If either caps is ANY, the resulting caps will be ANY.
527 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
529 GstStructure *structure;
530 GstCapsFeatures *features;
533 g_return_if_fail (GST_IS_CAPS (caps1));
534 g_return_if_fail (GST_IS_CAPS (caps2));
535 g_return_if_fail (IS_WRITABLE (caps1));
537 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
538 GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
539 gst_caps_unref (caps2);
541 caps2 = gst_caps_make_writable (caps2);
543 for (i = GST_CAPS_LEN (caps2); i; i--) {
544 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
546 gst_caps_append_structure_unchecked (caps1, structure, features);
548 gst_caps_unref (caps2); /* guaranteed to free it */
554 * @caps1: (transfer full): the #GstCaps that will take the new entries
555 * @caps2: (transfer full): the #GstCaps to merge in
557 * Appends the structures contained in @caps2 to @caps1 if they are not yet
558 * expressed by @caps1. The structures in @caps2 are not copied -- they are
559 * transferred to a writable copy of @caps1, and then @caps2 is freed.
560 * If either caps is ANY, the resulting caps will be ANY.
562 * Returns: (transfer full): the merged caps.
565 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
567 GstStructure *structure;
568 GstCapsFeatures *features;
572 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
573 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
575 if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
576 gst_caps_unref (caps2);
578 } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
579 gst_caps_unref (caps1);
582 caps2 = gst_caps_make_writable (caps2);
584 for (i = GST_CAPS_LEN (caps2); i; i--) {
585 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
587 caps1 = gst_caps_merge_structure_full (caps1, structure, features);
589 gst_caps_unref (caps2);
593 GstCaps *com = gst_caps_intersect (caps1, caps2);
594 GstCaps *add = gst_caps_subtract (caps2, com);
596 GST_DEBUG ("common : %d", gst_caps_get_size (com));
597 GST_DEBUG ("adding : %d", gst_caps_get_size (add));
598 gst_caps_append (caps1, add);
599 gst_caps_unref (com);
607 * gst_caps_append_structure:
608 * @caps: the #GstCaps that will be appended to
609 * @structure: (transfer full): the #GstStructure to append
611 * Appends @structure to @caps. The structure is not copied; @caps
612 * becomes the owner of @structure.
615 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
617 g_return_if_fail (GST_IS_CAPS (caps));
618 g_return_if_fail (IS_WRITABLE (caps));
620 if (G_LIKELY (structure)) {
621 gst_caps_append_structure_unchecked (caps, structure, NULL);
626 * gst_caps_append_structure_full:
627 * @caps: the #GstCaps that will be appended to
628 * @structure: (transfer full): the #GstStructure to append
629 * @features: (transfer full) (allow-none): the #GstCapsFeatures to append
631 * Appends @structure with @features to @caps. The structure is not copied; @caps
632 * becomes the owner of @structure.
637 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
638 GstCapsFeatures * features)
640 g_return_if_fail (GST_IS_CAPS (caps));
641 g_return_if_fail (IS_WRITABLE (caps));
643 if (G_LIKELY (structure)) {
644 gst_caps_append_structure_unchecked (caps, structure, features);
649 * gst_caps_remove_structure:
650 * @caps: the #GstCaps to remove from
651 * @idx: Index of the structure to remove
653 * removes the stucture with the given index from the list of structures
654 * contained in @caps.
657 gst_caps_remove_structure (GstCaps * caps, guint idx)
659 GstStructure *structure;
661 g_return_if_fail (caps != NULL);
662 g_return_if_fail (idx <= gst_caps_get_size (caps));
663 g_return_if_fail (IS_WRITABLE (caps));
665 structure = gst_caps_remove_and_get_structure (caps, idx);
666 gst_structure_free (structure);
670 * gst_caps_merge_structure:
671 * @caps: (transfer full): the #GstCaps to merge into
672 * @structure: (transfer full): the #GstStructure to merge
674 * Appends @structure to @caps if its not already expressed by @caps.
676 * Returns: (transfer full): the merged caps.
679 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
681 GstStructure *structure1;
682 GstCapsFeatures *features1;
684 gboolean unique = TRUE;
686 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
688 if (G_UNLIKELY (structure == NULL))
691 /* check each structure */
692 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
693 structure1 = gst_caps_get_structure_unchecked (caps, i);
694 features1 = gst_caps_get_features_unchecked (caps, i);
696 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
698 /* if structure is a subset of structure1 and the
699 * there are no existing features, then skip it */
700 if (gst_caps_features_is_equal (features1,
701 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
702 && gst_structure_is_subset (structure, structure1)) {
708 caps = gst_caps_make_writable (caps);
709 gst_caps_append_structure_unchecked (caps, structure, NULL);
711 gst_structure_free (structure);
717 * gst_caps_merge_structure_full:
718 * @caps: (transfer full): the #GstCaps to merge into
719 * @structure: (transfer full): the #GstStructure to merge
720 * @features: (transfer full) (allow-none): the #GstCapsFeatures to merge
722 * Appends @structure with @features to @caps if its not already expressed by @caps.
724 * Returns: (transfer full): the merged caps.
729 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
730 GstCapsFeatures * features)
732 GstStructure *structure1;
733 GstCapsFeatures *features1, *features_tmp;
735 gboolean unique = TRUE;
737 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
739 if (G_UNLIKELY (structure == NULL))
742 /* To make comparisons easier below */
743 features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
745 /* check each structure */
746 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
747 structure1 = gst_caps_get_structure_unchecked (caps, i);
748 features1 = gst_caps_get_features_unchecked (caps, i);
750 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
751 /* if structure is a subset of structure1 and the
752 * the features are a subset, then skip it */
753 /* FIXME: We only skip if none of the features are
754 * ANY and are still equal. That way all ANY structures
755 * show up in the caps and no non-ANY structures are
756 * swallowed by ANY structures
758 if (((!gst_caps_features_is_any (features_tmp)
759 || gst_caps_features_is_any (features1))
760 && gst_caps_features_is_equal (features_tmp, features1))
761 && gst_structure_is_subset (structure, structure1)) {
767 caps = gst_caps_make_writable (caps);
768 gst_caps_append_structure_unchecked (caps, structure, features);
770 gst_structure_free (structure);
772 gst_caps_features_free (features);
781 * Gets the number of structures contained in @caps.
783 * Returns: the number of structures that @caps contains
786 gst_caps_get_size (const GstCaps * caps)
788 g_return_val_if_fail (GST_IS_CAPS (caps), 0);
790 return GST_CAPS_LEN (caps);
794 * gst_caps_get_structure:
796 * @index: the index of the structure
798 * Finds the structure in @caps that has the index @index, and
801 * WARNING: This function takes a const GstCaps *, but returns a
802 * non-const GstStructure *. This is for programming convenience --
803 * the caller should be aware that structures inside a constant
804 * #GstCaps should not be modified. However, if you know the caps
805 * are writable, either because you have just copied them or made
806 * them writable with gst_caps_make_writable(), you may modify the
807 * structure returned in the usual way, e.g. with functions like
808 * gst_structure_set().
810 * You do not need to free or unref the structure returned, it
811 * belongs to the #GstCaps.
813 * Returns: (transfer none): a pointer to the #GstStructure corresponding
817 gst_caps_get_structure (const GstCaps * caps, guint index)
819 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
820 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
822 return gst_caps_get_structure_unchecked (caps, index);
826 * gst_caps_get_features:
828 * @index: the index of the structure
830 * Finds the features in @caps that has the index @index, and
833 * WARNING: This function takes a const GstCaps *, but returns a
834 * non-const GstCapsFeatures *. This is for programming convenience --
835 * the caller should be aware that structures inside a constant
836 * #GstCaps should not be modified. However, if you know the caps
837 * are writable, either because you have just copied them or made
838 * them writable with gst_caps_make_writable(), you may modify the
839 * features returned in the usual way, e.g. with functions like
840 * gst_caps_features_add().
842 * You do not need to free or unref the structure returned, it
843 * belongs to the #GstCaps.
845 * Returns: (transfer none): a pointer to the #GstCapsFeatures corresponding
851 gst_caps_get_features (const GstCaps * caps, guint index)
853 GstCapsFeatures *features;
855 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
856 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
858 features = gst_caps_get_features_unchecked (caps, index);
860 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
866 * gst_caps_set_features:
868 * @index: the index of the structure
869 * @features: (allow-none) (transfer full): the #GstCapsFeatures to set
871 * Sets the #GstCapsFeatures @features for the structure at @index.
876 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
878 GstCapsFeatures **storage, *old;
880 g_return_if_fail (caps != NULL);
881 g_return_if_fail (index <= gst_caps_get_size (caps));
882 g_return_if_fail (IS_WRITABLE (caps));
884 storage = &gst_caps_get_features_unchecked (caps, index);
889 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
892 gst_caps_features_free (old);
897 * @caps: the #GstCaps to copy
898 * @nth: the nth structure to copy
900 * Creates a new #GstCaps and appends a copy of the nth structure
901 * contained in @caps.
903 * Returns: (transfer full): the new #GstCaps
906 gst_caps_copy_nth (const GstCaps * caps, guint nth)
909 GstStructure *structure;
910 GstCapsFeatures *features;
912 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
914 newcaps = gst_caps_new_empty ();
915 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
917 if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
918 structure = gst_caps_get_structure_unchecked (caps, nth);
919 features = gst_caps_get_features_unchecked (caps, nth);
920 gst_caps_append_structure_unchecked (newcaps,
921 gst_structure_copy (structure),
922 gst_caps_features_copy_conditional (features));
930 * @caps: (transfer full): the #GstCaps to truncate
932 * Discard all but the first structure from @caps. Useful when
935 * Returns: (transfer full): truncated caps
938 gst_caps_truncate (GstCaps * caps)
942 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
944 i = GST_CAPS_LEN (caps) - 1;
948 caps = gst_caps_make_writable (caps);
950 gst_caps_remove_structure (caps, i--);
956 * gst_caps_set_value:
957 * @caps: a writable caps
958 * @field: name of the field to set
959 * @value: value to set the field to
961 * Sets the given @field on all structures of @caps to the given @value.
962 * This is a convenience function for calling gst_structure_set_value() on
963 * all structures of @caps.
966 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
970 g_return_if_fail (GST_IS_CAPS (caps));
971 g_return_if_fail (IS_WRITABLE (caps));
972 g_return_if_fail (field != NULL);
973 g_return_if_fail (G_IS_VALUE (value));
975 len = GST_CAPS_LEN (caps);
976 for (i = 0; i < len; i++) {
977 GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
978 gst_structure_set_value (structure, field, value);
983 * gst_caps_set_simple_valist:
984 * @caps: the #GstCaps to set
985 * @field: first field to set
986 * @varargs: additional parameters
988 * Sets fields in a #GstCaps. The arguments must be passed in the same
989 * manner as gst_structure_set(), and be NULL-terminated.
992 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
994 GValue value = { 0, };
996 g_return_if_fail (GST_IS_CAPS (caps));
997 g_return_if_fail (IS_WRITABLE (caps));
1003 type = va_arg (varargs, GType);
1005 G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1006 if (G_UNLIKELY (err)) {
1007 g_critical ("%s", err);
1011 gst_caps_set_value (caps, field, &value);
1013 g_value_unset (&value);
1015 field = va_arg (varargs, const gchar *);
1020 * gst_caps_set_simple:
1021 * @caps: the #GstCaps to set
1022 * @field: first field to set
1023 * @...: additional parameters
1025 * Sets fields in a #GstCaps. The arguments must be passed in the same
1026 * manner as gst_structure_set(), and be NULL-terminated.
1029 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1033 g_return_if_fail (GST_IS_CAPS (caps));
1034 g_return_if_fail (IS_WRITABLE (caps));
1036 va_start (var_args, field);
1037 gst_caps_set_simple_valist (caps, field, var_args);
1045 * @caps: the #GstCaps to test
1047 * Determines if @caps represents any media format.
1049 * Returns: TRUE if @caps represents any format.
1052 gst_caps_is_any (const GstCaps * caps)
1054 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1056 return (CAPS_IS_ANY (caps));
1060 * gst_caps_is_empty:
1061 * @caps: the #GstCaps to test
1063 * Determines if @caps represents no media formats.
1065 * Returns: TRUE if @caps represents no formats.
1068 gst_caps_is_empty (const GstCaps * caps)
1070 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1072 if (CAPS_IS_ANY (caps))
1075 return CAPS_IS_EMPTY_SIMPLE (caps);
1079 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1082 return gst_value_is_fixed (value);
1086 * gst_caps_is_fixed:
1087 * @caps: the #GstCaps to test
1089 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1090 * one structure, and each field in the structure describes a fixed type.
1091 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1093 * Returns: TRUE if @caps is fixed
1096 gst_caps_is_fixed (const GstCaps * caps)
1098 GstStructure *structure;
1099 GstCapsFeatures *features;
1101 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1103 if (GST_CAPS_LEN (caps) != 1)
1106 features = gst_caps_get_features (caps, 0);
1107 if (features && gst_caps_features_is_any (features))
1110 structure = gst_caps_get_structure_unchecked (caps, 0);
1112 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1116 * gst_caps_is_equal_fixed:
1117 * @caps1: the #GstCaps to test
1118 * @caps2: the #GstCaps to test
1120 * Tests if two #GstCaps are equal. This function only works on fixed
1123 * Returns: TRUE if the arguments represent the same format
1126 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1128 GstStructure *struct1, *struct2;
1129 GstCapsFeatures *features1, *features2;
1131 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1132 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1134 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1135 features1 = gst_caps_get_features_unchecked (caps1, 0);
1137 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1138 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1139 features2 = gst_caps_get_features_unchecked (caps2, 0);
1141 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1143 return gst_structure_is_equal (struct1, struct2) &&
1144 gst_caps_features_is_equal (features1, features2);
1148 * gst_caps_is_always_compatible:
1149 * @caps1: the #GstCaps to test
1150 * @caps2: the #GstCaps to test
1152 * A given #GstCaps structure is always compatible with another if
1153 * every media format that is in the first is also contained in the
1154 * second. That is, @caps1 is a subset of @caps2.
1156 * Returns: TRUE if @caps1 is a subset of @caps2.
1159 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1161 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1162 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1164 return gst_caps_is_subset (caps1, caps2);
1168 * gst_caps_is_subset:
1169 * @subset: a #GstCaps
1170 * @superset: a potentially greater #GstCaps
1172 * Checks if all caps represented by @subset are also represented by @superset.
1174 * Returns: %TRUE if @subset is a subset of @superset
1177 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1179 GstStructure *s1, *s2;
1180 GstCapsFeatures *f1, *f2;
1181 gboolean ret = TRUE;
1184 g_return_val_if_fail (subset != NULL, FALSE);
1185 g_return_val_if_fail (superset != NULL, FALSE);
1187 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1189 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1192 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1193 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1194 s1 = gst_caps_get_structure_unchecked (subset, i);
1195 f1 = gst_caps_get_features_unchecked (subset, i);
1197 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1198 s2 = gst_caps_get_structure_unchecked (superset, j);
1199 f2 = gst_caps_get_features_unchecked (superset, j);
1201 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1202 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1203 gst_caps_features_is_equal (f1, f2)
1204 && gst_structure_is_subset (s1, s2)) {
1205 /* If we found a superset, continue with the next
1206 * subset structure */
1210 /* If we found no superset for this subset structure
1211 * we return FALSE immediately */
1222 * gst_caps_is_subset_structure:
1224 * @structure: a potential #GstStructure subset of @caps
1226 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1227 * for more information.
1229 * Returns: %TRUE if @structure is a subset of @caps
1232 gst_caps_is_subset_structure (const GstCaps * caps,
1233 const GstStructure * structure)
1238 g_return_val_if_fail (caps != NULL, FALSE);
1239 g_return_val_if_fail (structure != NULL, FALSE);
1241 if (CAPS_IS_ANY (caps))
1243 if (CAPS_IS_EMPTY (caps))
1246 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1247 s = gst_caps_get_structure_unchecked (caps, i);
1248 if (gst_structure_is_subset (structure, s)) {
1249 /* If we found a superset return TRUE */
1258 * gst_caps_is_subset_structure_full:
1260 * @structure: a potential #GstStructure subset of @caps
1261 * @features: (allow-none): a #GstCapsFeatures for @structure
1263 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1264 * for more information.
1266 * Returns: %TRUE if @structure is a subset of @caps
1271 gst_caps_is_subset_structure_full (const GstCaps * caps,
1272 const GstStructure * structure, const GstCapsFeatures * features)
1278 g_return_val_if_fail (caps != NULL, FALSE);
1279 g_return_val_if_fail (structure != NULL, FALSE);
1281 if (CAPS_IS_ANY (caps))
1283 if (CAPS_IS_EMPTY (caps))
1287 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1289 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1290 s = gst_caps_get_structure_unchecked (caps, i);
1291 f = gst_caps_get_features_unchecked (caps, i);
1293 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1294 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1295 && gst_caps_features_is_equal (features, f)
1296 && gst_structure_is_subset (structure, s)) {
1297 /* If we found a superset return TRUE */
1306 * gst_caps_is_equal:
1307 * @caps1: a #GstCaps
1308 * @caps2: another #GstCaps
1310 * Checks if the given caps represent the same set of caps.
1312 * Returns: TRUE if both caps are equal.
1315 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1317 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1318 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1320 if (G_UNLIKELY (caps1 == caps2))
1323 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1324 return gst_caps_is_equal_fixed (caps1, caps2);
1326 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1330 * gst_caps_is_strictly_equal:
1331 * @caps1: a #GstCaps
1332 * @caps2: another #GstCaps
1334 * Checks if the given caps are exactly the same set of caps.
1336 * Returns: TRUE if both caps are strictly equal.
1339 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1342 GstStructure *s1, *s2;
1343 GstCapsFeatures *f1, *f2;
1345 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1346 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1348 if (G_UNLIKELY (caps1 == caps2))
1351 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1354 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1355 s1 = gst_caps_get_structure_unchecked (caps1, i);
1356 f1 = gst_caps_get_features_unchecked (caps1, i);
1358 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1359 s2 = gst_caps_get_structure_unchecked (caps2, i);
1360 f2 = gst_caps_get_features_unchecked (caps2, i);
1362 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1364 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1365 !gst_caps_features_is_equal (f1, f2) ||
1366 !gst_structure_is_equal (s1, s2))
1373 /* intersect operation */
1376 * gst_caps_can_intersect:
1377 * @caps1: a #GstCaps to intersect
1378 * @caps2: a #GstCaps to intersect
1380 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1383 * Returns: %TRUE if intersection would be not empty
1386 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1388 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1389 guint j, k, len1, len2;
1390 GstStructure *struct1;
1391 GstStructure *struct2;
1392 GstCapsFeatures *features1;
1393 GstCapsFeatures *features2;
1395 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1396 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1398 /* caps are exactly the same pointers */
1399 if (G_UNLIKELY (caps1 == caps2))
1402 /* empty caps on either side, return empty */
1403 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1406 /* one of the caps is any */
1407 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1410 /* run zigzag on top line then right line, this preserves the caps order
1411 * much better than a simple loop.
1413 * This algorithm zigzags over the caps structures as demonstrated in
1414 * the following matrix:
1417 * +------------- total distance: +-------------
1418 * | 1 2 4 7 0 | 0 1 2 3
1419 * caps2 | 3 5 8 10 1 | 1 2 3 4
1420 * | 6 9 11 12 2 | 2 3 4 5
1422 * First we iterate over the caps1 structures (top line) intersecting
1423 * the structures diagonally down, then we iterate over the caps2
1424 * structures. The result is that the intersections are ordered based on the
1425 * sum of the indexes in the list.
1427 len1 = GST_CAPS_LEN (caps1);
1428 len2 = GST_CAPS_LEN (caps2);
1429 for (i = 0; i < len1 + len2 - 1; i++) {
1430 /* superset index goes from 0 to sgst_caps_structure_intersectuperset->structs->len-1 */
1431 j = MIN (i, len1 - 1);
1432 /* subset index stays 0 until i reaches superset->structs->len, then it
1433 * counts up from 1 to subset->structs->len - 1 */
1434 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1435 /* now run the diagonal line, end condition is the left or bottom
1438 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1439 features1 = gst_caps_get_features_unchecked (caps1, j);
1441 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1442 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1443 features2 = gst_caps_get_features_unchecked (caps2, k);
1445 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1446 if (gst_caps_features_is_equal (features1, features2) &&
1447 gst_structure_can_intersect (struct1, struct2)) {
1450 /* move down left */
1452 if (G_UNLIKELY (j == 0))
1453 break; /* so we don't roll back to G_MAXUINT */
1462 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1464 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1465 guint j, k, len1, len2;
1466 GstStructure *struct1;
1467 GstStructure *struct2;
1468 GstCapsFeatures *features1;
1469 GstCapsFeatures *features2;
1471 GstStructure *istruct;
1473 /* caps are exactly the same pointers, just copy one caps */
1474 if (G_UNLIKELY (caps1 == caps2))
1475 return gst_caps_ref (caps1);
1477 /* empty caps on either side, return empty */
1478 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1479 return gst_caps_ref (GST_CAPS_NONE);
1481 /* one of the caps is any, just copy the other caps */
1482 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1483 return gst_caps_ref (caps2);
1485 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1486 return gst_caps_ref (caps1);
1488 dest = gst_caps_new_empty ();
1489 /* run zigzag on top line then right line, this preserves the caps order
1490 * much better than a simple loop.
1492 * This algorithm zigzags over the caps structures as demonstrated in
1493 * the following matrix:
1501 * First we iterate over the caps1 structures (top line) intersecting
1502 * the structures diagonally down, then we iterate over the caps2
1505 len1 = GST_CAPS_LEN (caps1);
1506 len2 = GST_CAPS_LEN (caps2);
1507 for (i = 0; i < len1 + len2 - 1; i++) {
1508 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1509 j = MIN (i, len1 - 1);
1510 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1511 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1512 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1513 /* now run the diagonal line, end condition is the left or bottom
1516 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1517 features1 = gst_caps_get_features_unchecked (caps1, j);
1519 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1520 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1521 features2 = gst_caps_get_features_unchecked (caps2, k);
1523 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1524 if (gst_caps_features_is_equal (features1, features2)) {
1525 istruct = gst_structure_intersect (struct1, struct2);
1527 if (gst_caps_features_is_any (features1))
1529 gst_caps_merge_structure_full (dest, istruct,
1530 gst_caps_features_copy_conditional (features2));
1533 gst_caps_merge_structure_full (dest, istruct,
1534 gst_caps_features_copy_conditional (features1));
1537 /* move down left */
1539 if (G_UNLIKELY (j == 0))
1540 break; /* so we don't roll back to G_MAXUINT */
1548 * gst_caps_intersect_first:
1549 * @caps1: a #GstCaps to intersect
1550 * @caps2: a #GstCaps to intersect
1552 * Creates a new #GstCaps that contains all the formats that are common
1553 * to both @caps1 and @caps2.
1555 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1556 * fashion as @caps1.
1558 * Returns: the new #GstCaps
1561 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1564 guint j, len1, len2;
1565 GstStructure *struct1;
1566 GstStructure *struct2;
1567 GstCapsFeatures *features1;
1568 GstCapsFeatures *features2;
1570 GstStructure *istruct;
1572 /* caps are exactly the same pointers, just copy one caps */
1573 if (G_UNLIKELY (caps1 == caps2))
1574 return gst_caps_ref (caps1);
1576 /* empty caps on either side, return empty */
1577 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1578 return gst_caps_ref (GST_CAPS_NONE);
1580 /* one of the caps is any, just copy the other caps */
1581 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1582 return gst_caps_ref (caps2);
1584 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1585 return gst_caps_ref (caps1);
1587 dest = gst_caps_new_empty ();
1588 len1 = GST_CAPS_LEN (caps1);
1589 len2 = GST_CAPS_LEN (caps2);
1590 for (i = 0; i < len1; i++) {
1591 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1592 features1 = gst_caps_get_features_unchecked (caps1, i);
1594 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1595 for (j = 0; j < len2; j++) {
1596 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1597 features2 = gst_caps_get_features_unchecked (caps2, j);
1599 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1600 if (gst_caps_features_is_equal (features1, features2)) {
1601 istruct = gst_structure_intersect (struct1, struct2);
1603 if (gst_caps_features_is_any (features1))
1605 gst_caps_merge_structure_full (dest, istruct,
1606 gst_caps_features_copy_conditional (features2));
1609 gst_caps_merge_structure_full (dest, istruct,
1610 gst_caps_features_copy_conditional (features1));
1620 * gst_caps_intersect_full:
1621 * @caps1: a #GstCaps to intersect
1622 * @caps2: a #GstCaps to intersect
1623 * @mode: The intersection algorithm/mode to use
1625 * Creates a new #GstCaps that contains all the formats that are common
1626 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1629 * Returns: the new #GstCaps
1632 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1633 GstCapsIntersectMode mode)
1635 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1636 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1639 case GST_CAPS_INTERSECT_FIRST:
1640 return gst_caps_intersect_first (caps1, caps2);
1642 g_warning ("Unknown caps intersect mode: %d", mode);
1644 case GST_CAPS_INTERSECT_ZIG_ZAG:
1645 return gst_caps_intersect_zig_zag (caps1, caps2);
1650 * gst_caps_intersect:
1651 * @caps1: a #GstCaps to intersect
1652 * @caps2: a #GstCaps to intersect
1654 * Creates a new #GstCaps that contains all the formats that are common
1655 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1657 * Returns: the new #GstCaps
1660 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1662 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1665 /* subtract operation */
1669 const GstStructure *subtract_from;
1674 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1677 SubtractionEntry *e = user_data;
1678 GValue subtraction = { 0, };
1679 const GValue *other;
1680 GstStructure *structure;
1682 other = gst_structure_id_get_value (e->subtract_from, field_id);
1688 if (!gst_value_subtract (&subtraction, other, value))
1691 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1692 g_value_unset (&subtraction);
1695 structure = gst_structure_copy (e->subtract_from);
1696 gst_structure_id_take_value (structure, field_id, &subtraction);
1697 e->put_into = g_slist_prepend (e->put_into, structure);
1703 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1704 const GstStructure * subtrahend)
1709 e.subtract_from = minuend;
1711 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1712 gst_caps_structure_subtract_field, &e);
1719 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1720 gst_structure_free (walk->data);
1722 g_slist_free (e.put_into);
1729 * gst_caps_subtract:
1730 * @minuend: #GstCaps to subtract from
1731 * @subtrahend: #GstCaps to subtract
1733 * Subtracts the @subtrahend from the @minuend.
1734 * <note>This function does not work reliably if optional properties for caps
1735 * are included on one caps and omitted on the other.</note>
1737 * Returns: the resulting caps
1740 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1745 GstCapsFeatures *min_f, *sub_f;
1746 GstCaps *dest = NULL, *src;
1748 g_return_val_if_fail (minuend != NULL, NULL);
1749 g_return_val_if_fail (subtrahend != NULL, NULL);
1751 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1752 return gst_caps_new_empty ();
1755 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1756 return gst_caps_ref (minuend);
1758 /* FIXME: Do we want this here or above?
1759 The reason we need this is that there is no definition about what
1760 ANY means for specific types, so it's not possible to reduce ANY partially
1761 You can only remove everything or nothing and that is done above.
1762 Note: there's a test that checks this behaviour. */
1764 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1765 sublen = GST_CAPS_LEN (subtrahend);
1766 g_assert (sublen > 0);
1768 src = _gst_caps_copy (minuend);
1769 for (i = 0; i < sublen; i++) {
1772 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1773 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1775 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1777 gst_caps_unref (src);
1780 dest = gst_caps_new_empty ();
1781 srclen = GST_CAPS_LEN (src);
1782 for (j = 0; j < srclen; j++) {
1783 min = gst_caps_get_structure_unchecked (src, j);
1784 min_f = gst_caps_get_features_unchecked (src, j);
1786 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1788 /* Same reason as above for ANY caps */
1789 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1791 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1792 gst_caps_features_is_equal (min_f, sub_f)) {
1795 if (gst_caps_structure_subtract (&list, min, sub)) {
1798 for (walk = list; walk; walk = g_slist_next (walk)) {
1799 gst_caps_append_structure_unchecked (dest,
1800 (GstStructure *) walk->data,
1801 gst_caps_features_copy_conditional (min_f));
1803 g_slist_free (list);
1805 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1806 gst_caps_features_copy_conditional (min_f));
1809 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1810 gst_caps_features_copy_conditional (min_f));
1814 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1815 gst_caps_unref (src);
1820 gst_caps_unref (src);
1821 dest = gst_caps_simplify (dest);
1826 /* normalize/simplify operations */
1828 typedef struct _NormalizeForeach
1831 GstStructure *structure;
1832 GstCapsFeatures *features;
1836 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1838 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1842 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1843 guint len = gst_value_list_get_size (value);
1845 for (i = 1; i < len; i++) {
1846 const GValue *v = gst_value_list_get_value (value, i);
1847 GstStructure *structure = gst_structure_copy (nf->structure);
1849 gst_structure_id_set_value (structure, field_id, v);
1850 gst_caps_append_structure_unchecked (nf->caps, structure,
1851 gst_caps_features_copy_conditional (nf->features));
1854 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1855 gst_structure_id_take_value (nf->structure, field_id, &val);
1863 * gst_caps_normalize:
1864 * @caps: (transfer full): a #GstCaps to normalize
1866 * Returns a #GstCaps that represents the same set of formats as
1867 * @caps, but contains no lists. Each list is expanded into separate
1870 * This function takes ownership of @caps.
1872 * Returns: (transfer full): the normalized #GstCaps
1875 gst_caps_normalize (GstCaps * caps)
1877 NormalizeForeach nf;
1880 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1882 caps = gst_caps_make_writable (caps);
1885 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1886 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1887 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1888 while (!gst_structure_foreach (nf.structure,
1889 gst_caps_normalize_foreach, &nf));
1896 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1899 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1900 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1902 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1903 So what's the best way? */
1904 ret = strcmp (gst_structure_get_name (struct1),
1905 gst_structure_get_name (struct2));
1910 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1917 GstStructure *compare;
1921 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1924 UnionField *u = user_data;
1925 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1929 g_value_unset (&u->value);
1933 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1937 g_value_unset (&u->value);
1942 gst_value_union (&u->value, val, value);
1948 gst_caps_structure_simplify (GstStructure ** result,
1949 GstStructure * simplify, GstStructure * compare)
1952 UnionField field = { 0, {0,}, NULL };
1954 /* try to subtract to get a real subset */
1955 if (gst_caps_structure_subtract (&list, simplify, compare)) {
1956 if (list == NULL) { /* no result */
1959 } else if (list->next == NULL) { /* one result */
1960 *result = list->data;
1961 g_slist_free (list);
1963 } else { /* multiple results */
1964 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
1965 g_slist_free (list);
1970 /* try to union both structs */
1971 field.compare = compare;
1972 if (gst_structure_foreach (simplify,
1973 gst_caps_structure_figure_out_union, &field)) {
1974 gboolean ret = FALSE;
1976 /* now we know all of simplify's fields are the same in compare
1977 * but at most one field: field.name */
1978 if (G_IS_VALUE (&field.value)) {
1979 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
1980 gst_structure_id_take_value (compare, field.name, &field.value);
1984 g_value_unset (&field.value);
1987 if (gst_structure_n_fields (simplify) <=
1988 gst_structure_n_fields (compare)) {
1989 /* compare is just more specific, will be optimized away later */
1990 /* FIXME: do this here? */
1991 GST_LOG ("found a case that will be optimized later.");
1993 gchar *one = gst_structure_to_string (simplify);
1994 gchar *two = gst_structure_to_string (compare);
1997 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2009 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2010 GstStructure * new, gint i)
2012 gst_structure_set_parent_refcount (old, NULL);
2013 gst_structure_free (old);
2014 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2015 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2019 * gst_caps_simplify:
2020 * @caps: (transfer full): a #GstCaps to simplify
2022 * Converts the given @caps into a representation that represents the
2023 * same set of formats, but in a simpler form. Component structures that are
2024 * identical are merged. Component structures that have values that can be
2025 * merged are also merged.
2027 * This method does not preserve the original order of @caps.
2029 * Returns: The simplified caps.
2032 gst_caps_simplify (GstCaps * caps)
2034 GstStructure *simplify, *compare, *result = NULL;
2035 GstCapsFeatures *simplify_f, *compare_f;
2038 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2040 start = GST_CAPS_LEN (caps) - 1;
2041 /* one caps, already as simple as can be */
2045 caps = gst_caps_make_writable (caps);
2047 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2049 for (i = start; i >= 0; i--) {
2050 simplify = gst_caps_get_structure_unchecked (caps, i);
2051 simplify_f = gst_caps_get_features_unchecked (caps, i);
2053 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2054 compare = gst_caps_get_structure_unchecked (caps, start);
2055 compare_f = gst_caps_get_features_unchecked (caps, start);
2057 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2058 if (gst_structure_get_name_id (simplify) !=
2059 gst_structure_get_name_id (compare) ||
2060 !gst_caps_features_is_equal (simplify_f, compare_f))
2062 for (j = start; j >= 0; j--) {
2065 compare = gst_caps_get_structure_unchecked (caps, j);
2066 compare_f = gst_caps_get_features_unchecked (caps, j);
2068 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2069 if (gst_structure_get_name_id (simplify) !=
2070 gst_structure_get_name_id (compare) ||
2071 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2074 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2076 gst_caps_switch_structures (caps, simplify, result, i);
2079 gst_caps_remove_structure (caps, i);
2091 * @caps: (transfer full): a #GstCaps to fixate
2093 * Modifies the given @caps into a representation with only fixed
2094 * values. First the caps will be truncated and then the first structure will be
2095 * fixated with gst_structure_fixate().
2097 * Returns: (transfer full): the fixated caps
2100 gst_caps_fixate (GstCaps * caps)
2105 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2107 /* default fixation */
2108 caps = gst_caps_truncate (caps);
2109 caps = gst_caps_make_writable (caps);
2110 s = gst_caps_get_structure (caps, 0);
2111 gst_structure_fixate (s);
2113 /* Set features to sysmem if they're still ANY */
2114 f = gst_caps_get_features (caps, 0);
2115 if (f && gst_caps_features_is_any (f)) {
2116 f = gst_caps_features_new_empty ();
2117 gst_caps_set_features (caps, 0, f);
2126 * gst_caps_to_string:
2129 * Converts @caps to a string representation. This string representation
2130 * can be converted back to a #GstCaps by gst_caps_from_string().
2132 * For debugging purposes its easier to do something like this:
2134 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2136 * This prints the caps in human readable form.
2138 * The current implementation of serialization will lead to unexpected results
2139 * when there are nested #GstCaps / #GstStructure deeper than one level.
2141 * Returns: (transfer full): a newly allocated string representing @caps.
2144 gst_caps_to_string (const GstCaps * caps)
2146 guint i, slen, clen;
2149 /* NOTE: This function is potentially called by the debug system,
2150 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2151 * should be careful to avoid recursion. This includes any functions
2152 * called by gst_caps_to_string. In particular, calls should
2153 * not use the GST_PTR_FORMAT extension. */
2156 return g_strdup ("NULL");
2158 if (CAPS_IS_ANY (caps)) {
2159 return g_strdup ("ANY");
2161 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2162 return g_strdup ("EMPTY");
2165 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2167 clen = GST_CAPS_LEN (caps);
2168 for (i = 0; i < clen; i++) {
2172 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2174 f = gst_caps_get_features_unchecked (caps, i);
2176 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2179 s = g_string_sized_new (slen);
2180 for (i = 0; i < clen; i++) {
2181 GstStructure *structure;
2182 GstCapsFeatures *features;
2185 /* ';' is now added by gst_structure_to_string */
2186 g_string_append_c (s, ' ');
2189 structure = gst_caps_get_structure_unchecked (caps, i);
2190 features = gst_caps_get_features_unchecked (caps, i);
2192 g_string_append (s, gst_structure_get_name (structure));
2193 if (features && (gst_caps_features_is_any (features)
2194 || !gst_caps_features_is_equal (features,
2195 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2196 g_string_append_c (s, '(');
2197 priv_gst_caps_features_append_to_gstring (features, s);
2198 g_string_append_c (s, ')');
2200 priv_gst_structure_append_to_gstring (structure, s);
2202 if (s->len && s->str[s->len - 1] == ';') {
2203 /* remove latest ';' */
2204 s->str[--s->len] = '\0';
2206 return g_string_free (s, FALSE);
2210 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2212 GstStructure *structure;
2213 gchar *s, *copy, *end, *next, save;
2215 if (strcmp ("ANY", string) == 0) {
2216 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2220 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2224 copy = s = g_strdup (string);
2226 GstCapsFeatures *features = NULL;
2228 while (g_ascii_isspace (*s))
2234 if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2241 structure = gst_structure_new_empty (s);
2244 if (structure == NULL) {
2262 } else if (*end == ')') {
2271 features = gst_caps_features_from_string (s);
2273 gst_structure_free (structure);
2287 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2288 gst_structure_free (structure);
2294 gst_caps_append_structure_unchecked (caps, structure, features);
2305 * gst_caps_from_string:
2306 * @string: a string to convert to #GstCaps
2308 * Converts @caps from a string representation.
2310 * The current implementation of serialization will lead to unexpected results
2311 * when there are nested #GstCaps / #GstStructure deeper than one level.
2313 * Returns: (transfer full): a newly allocated #GstCaps
2316 gst_caps_from_string (const gchar * string)
2320 g_return_val_if_fail (string, FALSE);
2322 caps = gst_caps_new_empty ();
2323 if (gst_caps_from_string_inplace (caps, string)) {
2326 gst_caps_unref (caps);
2332 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2334 g_return_if_fail (G_IS_VALUE (src_value));
2335 g_return_if_fail (G_IS_VALUE (dest_value));
2336 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2337 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2338 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2340 g_value_take_string (dest_value,
2341 gst_caps_to_string (gst_value_get_caps (src_value)));