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 * Last reviewed on 2011-03-28 (0.11.3)
68 #include "gst_private.h"
70 #include <gobject/gvaluecollector.h>
72 #define DEBUG_REFCOUNT
74 typedef struct _GstCapsArrayElement
76 GstStructure *structure;
77 GstCapsFeatures *features;
78 } GstCapsArrayElement;
80 typedef struct _GstCapsImpl
87 #define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
89 #define GST_CAPS_LEN(c) (GST_CAPS_ARRAY(c)->len)
91 #define IS_WRITABLE(caps) \
92 (GST_CAPS_REFCOUNT_VALUE (caps) == 1)
94 /* same as gst_caps_is_any () */
95 #define CAPS_IS_ANY(caps) \
96 (GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY)
98 /* same as gst_caps_is_empty () */
99 #define CAPS_IS_EMPTY(caps) \
100 (!CAPS_IS_ANY(caps) && CAPS_IS_EMPTY_SIMPLE(caps))
102 #define CAPS_IS_EMPTY_SIMPLE(caps) \
103 ((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
105 #define gst_caps_features_copy_conditional(f) ((f && (gst_caps_features_is_any (f) || !gst_caps_features_is_equal (f, GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) ? gst_caps_features_copy (f) : NULL)
107 /* quick way to get a caps structure at an index without doing a type or array
109 #define gst_caps_get_structure_unchecked(caps, index) \
110 (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).structure)
111 #define gst_caps_get_features_unchecked(caps, index) \
112 (g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, (index)).features)
113 /* quick way to append a structure without checking the args */
114 #define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
115 GstCapsArrayElement __e={s, f}; \
116 if (gst_structure_set_parent_refcount (__e.structure, &GST_MINI_OBJECT_REFCOUNT(caps)) && \
117 (!__e.features || gst_caps_features_set_parent_refcount (__e.features, &GST_MINI_OBJECT_REFCOUNT(caps)))) \
118 g_array_append_val (GST_CAPS_ARRAY (caps), __e); \
121 /* lock to protect multiple invocations of static caps to caps conversion */
122 G_LOCK_DEFINE_STATIC (static_caps_lock);
124 static void gst_caps_transform_to_string (const GValue * src_value,
125 GValue * dest_value);
126 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
127 const gchar * string);
129 GType _gst_caps_type = 0;
130 GstCaps *_gst_caps_any;
131 GstCaps *_gst_caps_none;
133 GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
136 _priv_gst_caps_initialize (void)
138 _gst_caps_type = gst_caps_get_type ();
140 _gst_caps_any = gst_caps_new_any ();
141 _gst_caps_none = gst_caps_new_empty ();
143 g_value_register_transform_func (_gst_caps_type,
144 G_TYPE_STRING, gst_caps_transform_to_string);
148 _gst_caps_copy (const GstCaps * caps)
151 GstStructure *structure;
152 GstCapsFeatures *features;
155 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
157 newcaps = gst_caps_new_empty ();
158 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
159 n = GST_CAPS_LEN (caps);
161 GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, caps, "doing copy %p -> %p",
164 for (i = 0; i < n; i++) {
165 structure = gst_caps_get_structure_unchecked (caps, i);
166 features = gst_caps_get_features_unchecked (caps, i);
167 gst_caps_append_structure_full (newcaps, gst_structure_copy (structure),
168 gst_caps_features_copy_conditional (features));
174 /* creation/deletion */
176 _gst_caps_free (GstCaps * caps)
178 GstStructure *structure;
179 GstCapsFeatures *features;
182 /* The refcount must be 0, but since we're only called by gst_caps_unref,
183 * don't bother testing. */
184 len = GST_CAPS_LEN (caps);
185 /* This can be used to get statistics about caps sizes */
186 /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
187 for (i = 0; i < len; i++) {
188 structure = gst_caps_get_structure_unchecked (caps, i);
189 gst_structure_set_parent_refcount (structure, NULL);
190 gst_structure_free (structure);
191 features = gst_caps_get_features_unchecked (caps, i);
193 gst_caps_features_set_parent_refcount (features, NULL);
194 gst_caps_features_free (features);
197 g_array_free (GST_CAPS_ARRAY (caps), TRUE);
199 #ifdef DEBUG_REFCOUNT
200 GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
202 g_slice_free1 (sizeof (GstCapsImpl), caps);
206 gst_caps_init (GstCaps * caps)
208 gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
209 (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
210 (GstMiniObjectFreeFunction) _gst_caps_free);
212 /* the 32 has been determined by logging caps sizes in _gst_caps_free
213 * but g_ptr_array uses 16 anyway if it expands once, so this does not help
215 * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
217 GST_CAPS_ARRAY (caps) =
218 g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
222 * gst_caps_new_empty:
224 * Creates a new #GstCaps that is empty. That is, the returned
225 * #GstCaps contains no media formats.
226 * The #GstCaps is guaranteed to be writable.
227 * Caller is responsible for unreffing the returned caps.
229 * Returns: (transfer full): the new #GstCaps
232 gst_caps_new_empty (void)
236 caps = (GstCaps *) g_slice_new (GstCapsImpl);
238 gst_caps_init (caps);
240 #ifdef DEBUG_REFCOUNT
241 GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
250 * Creates a new #GstCaps that indicates that it is compatible with
253 * Returns: (transfer full): the new #GstCaps
256 gst_caps_new_any (void)
258 GstCaps *caps = gst_caps_new_empty ();
260 GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_ANY);
266 * gst_caps_new_empty_simple:
267 * @media_type: the media type of the structure
269 * Creates a new #GstCaps that contains one #GstStructure with name
271 * Caller is responsible for unreffing the returned caps.
273 * Returns: (transfer full): the new #GstCaps
276 gst_caps_new_empty_simple (const char *media_type)
279 GstStructure *structure;
281 caps = gst_caps_new_empty ();
282 structure = gst_structure_new_empty (media_type);
284 gst_caps_append_structure_unchecked (caps, structure, NULL);
290 * gst_caps_new_simple:
291 * @media_type: the media type of the structure
292 * @fieldname: first field to set
293 * @...: additional arguments
295 * Creates a new #GstCaps that contains one #GstStructure. The
296 * structure is defined by the arguments, which have the same format
297 * as gst_structure_new().
298 * Caller is responsible for unreffing the returned caps.
300 * Returns: (transfer full): the new #GstCaps
303 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
306 GstStructure *structure;
309 caps = gst_caps_new_empty ();
311 va_start (var_args, fieldname);
312 structure = gst_structure_new_valist (media_type, fieldname, var_args);
316 gst_caps_append_structure_unchecked (caps, structure, NULL);
318 gst_caps_replace (&caps, NULL);
325 * @struct1: the first structure to add
326 * @...: additional structures to add
328 * Creates a new #GstCaps and adds all the structures listed as
329 * arguments. The list must be NULL-terminated. The structures
330 * are not copied; the returned #GstCaps owns the structures.
332 * Returns: (transfer full): the new #GstCaps
335 gst_caps_new_full (GstStructure * struct1, ...)
340 va_start (var_args, struct1);
341 caps = gst_caps_new_full_valist (struct1, var_args);
348 * gst_caps_new_full_valist:
349 * @structure: the first structure to add
350 * @var_args: additional structures to add
352 * Creates a new #GstCaps and adds all the structures listed as
353 * arguments. The list must be NULL-terminated. The structures
354 * are not copied; the returned #GstCaps owns the structures.
356 * Returns: (transfer full): the new #GstCaps
359 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
363 caps = gst_caps_new_empty ();
366 gst_caps_append_structure_unchecked (caps, structure, NULL);
367 structure = va_arg (var_args, GstStructure *);
373 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
376 * gst_static_caps_get:
377 * @static_caps: the #GstStaticCaps to convert
379 * Converts a #GstStaticCaps to a #GstCaps.
381 * Returns: (transfer full): a pointer to the #GstCaps. Unref after usage.
382 * Since the core holds an additional ref to the returned caps,
383 * use gst_caps_make_writable() on the returned caps to modify it.
386 gst_static_caps_get (GstStaticCaps * static_caps)
390 g_return_val_if_fail (static_caps != NULL, NULL);
392 caps = &static_caps->caps;
394 /* refcount is 0 when we need to convert */
395 if (G_UNLIKELY (*caps == NULL)) {
398 G_LOCK (static_caps_lock);
399 /* check if other thread already updated */
400 if (G_UNLIKELY (*caps != NULL))
403 string = static_caps->string;
405 if (G_UNLIKELY (string == NULL))
408 *caps = gst_caps_from_string (string);
410 /* convert to string */
411 if (G_UNLIKELY (*caps == NULL))
412 g_critical ("Could not convert static caps \"%s\"", string);
414 GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
417 G_UNLOCK (static_caps_lock);
419 /* ref the caps, makes it not writable */
420 if (G_LIKELY (*caps != NULL))
421 gst_caps_ref (*caps);
428 G_UNLOCK (static_caps_lock);
429 g_warning ("static caps %p string is NULL", static_caps);
435 * gst_static_caps_cleanup:
436 * @static_caps: the #GstStaticCaps to clean
438 * Clean up the cached caps contained in @static_caps.
441 gst_static_caps_cleanup (GstStaticCaps * static_caps)
443 G_LOCK (static_caps_lock);
444 gst_caps_replace (&static_caps->caps, NULL);
445 G_UNLOCK (static_caps_lock);
451 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
452 GstStructure ** s, GstCapsFeatures ** f)
457 s_ = gst_caps_get_structure_unchecked (caps, idx);
458 f_ = gst_caps_get_features_unchecked (caps, idx);
460 /* don't use index_fast, gst_caps_simplify relies on the order */
461 g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
463 gst_structure_set_parent_refcount (s_, NULL);
465 gst_caps_features_set_parent_refcount (f_, NULL);
472 static GstStructure *
473 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
478 gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
481 gst_caps_features_free (f);
489 * gst_caps_steal_structure:
490 * @caps: the #GstCaps to retrieve from
491 * @index: Index of the structure to retrieve
493 * Retrieves the structure with the given index from the list of structures
494 * contained in @caps. The caller becomes the owner of the returned structure.
496 * Returns: (transfer full): a pointer to the #GstStructure corresponding
500 gst_caps_steal_structure (GstCaps * caps, guint index)
502 g_return_val_if_fail (caps != NULL, NULL);
503 g_return_val_if_fail (IS_WRITABLE (caps), NULL);
505 if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
508 return gst_caps_remove_and_get_structure (caps, index);
513 * @caps1: the #GstCaps that will be appended to
514 * @caps2: (transfer full): the #GstCaps to append
516 * Appends the structures contained in @caps2 to @caps1. The structures in
517 * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
518 * freed. If either caps is ANY, the resulting caps will be ANY.
521 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
523 GstStructure *structure;
524 GstCapsFeatures *features;
527 g_return_if_fail (GST_IS_CAPS (caps1));
528 g_return_if_fail (GST_IS_CAPS (caps2));
529 g_return_if_fail (IS_WRITABLE (caps1));
531 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
532 GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
533 gst_caps_unref (caps2);
535 caps2 = gst_caps_make_writable (caps2);
537 for (i = GST_CAPS_LEN (caps2); i; i--) {
538 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
540 gst_caps_append_structure_unchecked (caps1, structure, features);
542 gst_caps_unref (caps2); /* guaranteed to free it */
548 * @caps1: (transfer full): the #GstCaps that will take the new entries
549 * @caps2: (transfer full): the #GstCaps to merge in
551 * Appends the structures contained in @caps2 to @caps1 if they are not yet
552 * expressed by @caps1. The structures in @caps2 are not copied -- they are
553 * transferred to a writable copy of @caps1, and then @caps2 is freed.
554 * If either caps is ANY, the resulting caps will be ANY.
556 * Returns: (transfer full): the merged caps.
559 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
561 GstStructure *structure;
562 GstCapsFeatures *features;
566 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
567 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
569 if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
570 gst_caps_unref (caps2);
572 } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
573 gst_caps_unref (caps1);
576 caps2 = gst_caps_make_writable (caps2);
578 for (i = GST_CAPS_LEN (caps2); i; i--) {
579 gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
581 caps1 = gst_caps_merge_structure_full (caps1, structure, features);
583 gst_caps_unref (caps2);
587 GstCaps *com = gst_caps_intersect (caps1, caps2);
588 GstCaps *add = gst_caps_subtract (caps2, com);
590 GST_DEBUG ("common : %d", gst_caps_get_size (com));
591 GST_DEBUG ("adding : %d", gst_caps_get_size (add));
592 gst_caps_append (caps1, add);
593 gst_caps_unref (com);
601 * gst_caps_append_structure:
602 * @caps: the #GstCaps that will be appended to
603 * @structure: (transfer full): the #GstStructure to append
605 * Appends @structure to @caps. The structure is not copied; @caps
606 * becomes the owner of @structure.
609 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
611 g_return_if_fail (GST_IS_CAPS (caps));
612 g_return_if_fail (IS_WRITABLE (caps));
614 if (G_LIKELY (structure)) {
615 gst_caps_append_structure_unchecked (caps, structure, NULL);
620 * gst_caps_append_structure_full:
621 * @caps: the #GstCaps that will be appended to
622 * @structure: (transfer full): the #GstStructure to append
623 * @features: (transfer full) (allow-none): the #GstCapsFeatures to append
625 * Appends @structure with @features to @caps. The structure is not copied; @caps
626 * becomes the owner of @structure.
631 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
632 GstCapsFeatures * features)
634 g_return_if_fail (GST_IS_CAPS (caps));
635 g_return_if_fail (IS_WRITABLE (caps));
637 if (G_LIKELY (structure)) {
638 gst_caps_append_structure_unchecked (caps, structure, features);
643 * gst_caps_remove_structure:
644 * @caps: the #GstCaps to remove from
645 * @idx: Index of the structure to remove
647 * removes the stucture with the given index from the list of structures
648 * contained in @caps.
651 gst_caps_remove_structure (GstCaps * caps, guint idx)
653 GstStructure *structure;
655 g_return_if_fail (caps != NULL);
656 g_return_if_fail (idx <= gst_caps_get_size (caps));
657 g_return_if_fail (IS_WRITABLE (caps));
659 structure = gst_caps_remove_and_get_structure (caps, idx);
660 gst_structure_free (structure);
664 * gst_caps_merge_structure:
665 * @caps: (transfer full): the #GstCaps to merge into
666 * @structure: (transfer full): the #GstStructure to merge
668 * Appends @structure to @caps if its not already expressed by @caps.
670 * Returns: (transfer full): the merged caps.
673 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
675 GstStructure *structure1;
676 GstCapsFeatures *features1;
678 gboolean unique = TRUE;
680 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
682 if (G_UNLIKELY (structure == NULL))
685 /* check each structure */
686 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
687 structure1 = gst_caps_get_structure_unchecked (caps, i);
688 features1 = gst_caps_get_features_unchecked (caps, i);
690 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
692 /* if structure is a subset of structure1 and the
693 * there are no existing features, then skip it */
694 if (gst_caps_features_is_equal (features1,
695 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
696 && gst_structure_is_subset (structure, structure1)) {
702 caps = gst_caps_make_writable (caps);
703 gst_caps_append_structure_unchecked (caps, structure, NULL);
705 gst_structure_free (structure);
711 * gst_caps_merge_structure_full:
712 * @caps: (transfer full): the #GstCaps to merge into
713 * @structure: (transfer full): the #GstStructure to merge
714 * @features: (transfer full) (allow-none): the #GstCapsFeatures to merge
716 * Appends @structure with @features to @caps if its not already expressed by @caps.
718 * Returns: (transfer full): the merged caps.
723 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
724 GstCapsFeatures * features)
726 GstStructure *structure1;
727 GstCapsFeatures *features1, *features_tmp;
729 gboolean unique = TRUE;
731 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
733 if (G_UNLIKELY (structure == NULL))
736 /* To make comparisons easier below */
737 features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
739 /* check each structure */
740 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
741 structure1 = gst_caps_get_structure_unchecked (caps, i);
742 features1 = gst_caps_get_features_unchecked (caps, i);
744 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
745 /* if structure is a subset of structure1 and the
746 * the features are a subset, then skip it */
747 /* FIXME: We only skip if none of the features are
748 * ANY and are still equal. That way all ANY structures
749 * show up in the caps and no non-ANY structures are
750 * swallowed by ANY structures
752 if (((!gst_caps_features_is_any (features_tmp)
753 || gst_caps_features_is_any (features1))
754 && gst_caps_features_is_equal (features_tmp, features1))
755 && gst_structure_is_subset (structure, structure1)) {
761 caps = gst_caps_make_writable (caps);
762 gst_caps_append_structure_unchecked (caps, structure, features);
764 gst_structure_free (structure);
766 gst_caps_features_free (features);
775 * Gets the number of structures contained in @caps.
777 * Returns: the number of structures that @caps contains
780 gst_caps_get_size (const GstCaps * caps)
782 g_return_val_if_fail (GST_IS_CAPS (caps), 0);
784 return GST_CAPS_LEN (caps);
788 * gst_caps_get_structure:
790 * @index: the index of the structure
792 * Finds the structure in @caps that has the index @index, and
795 * WARNING: This function takes a const GstCaps *, but returns a
796 * non-const GstStructure *. This is for programming convenience --
797 * the caller should be aware that structures inside a constant
798 * #GstCaps should not be modified. However, if you know the caps
799 * are writable, either because you have just copied them or made
800 * them writable with gst_caps_make_writable(), you may modify the
801 * structure returned in the usual way, e.g. with functions like
802 * gst_structure_set().
804 * You do not need to free or unref the structure returned, it
805 * belongs to the #GstCaps.
807 * Returns: (transfer none): a pointer to the #GstStructure corresponding
811 gst_caps_get_structure (const GstCaps * caps, guint index)
813 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
814 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
816 return gst_caps_get_structure_unchecked (caps, index);
820 * gst_caps_get_features:
822 * @index: the index of the structure
824 * Finds the features in @caps that has the index @index, and
827 * WARNING: This function takes a const GstCaps *, but returns a
828 * non-const GstCapsFeatures *. This is for programming convenience --
829 * the caller should be aware that structures inside a constant
830 * #GstCaps should not be modified. However, if you know the caps
831 * are writable, either because you have just copied them or made
832 * them writable with gst_caps_make_writable(), you may modify the
833 * features returned in the usual way, e.g. with functions like
834 * gst_caps_features_add().
836 * You do not need to free or unref the structure returned, it
837 * belongs to the #GstCaps.
839 * Returns: (transfer none): a pointer to the #GstCapsFeatures corresponding
845 gst_caps_get_features (const GstCaps * caps, guint index)
847 GstCapsFeatures *features;
849 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
850 g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
852 features = gst_caps_get_features_unchecked (caps, index);
854 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
860 * gst_caps_set_features:
862 * @index: the index of the structure
863 * @features: (allow-none) (transfer full): the #GstFeatures to set
865 * Sets the #GstCapsFeatures @features for the structure at @index.
870 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
872 GstCapsFeatures **storage, *old;
874 g_return_if_fail (caps != NULL);
875 g_return_if_fail (index <= gst_caps_get_size (caps));
876 g_return_if_fail (IS_WRITABLE (caps));
878 storage = &gst_caps_get_features_unchecked (caps, index);
883 gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
886 gst_caps_features_free (old);
891 * @caps: the #GstCaps to copy
892 * @nth: the nth structure to copy
894 * Creates a new #GstCaps and appends a copy of the nth structure
895 * contained in @caps.
897 * Returns: (transfer full): the new #GstCaps
900 gst_caps_copy_nth (const GstCaps * caps, guint nth)
903 GstStructure *structure;
904 GstCapsFeatures *features;
906 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
908 newcaps = gst_caps_new_empty ();
909 GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
911 if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
912 structure = gst_caps_get_structure_unchecked (caps, nth);
913 features = gst_caps_get_features_unchecked (caps, nth);
914 gst_caps_append_structure_unchecked (newcaps,
915 gst_structure_copy (structure),
916 gst_caps_features_copy_conditional (features));
924 * @caps: (transfer full): the #GstCaps to truncate
926 * Discard all but the first structure from @caps. Useful when
929 * Returns: (transfer full): truncated caps
932 gst_caps_truncate (GstCaps * caps)
936 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
938 i = GST_CAPS_LEN (caps) - 1;
942 caps = gst_caps_make_writable (caps);
944 gst_caps_remove_structure (caps, i--);
950 * gst_caps_set_value:
951 * @caps: a writable caps
952 * @field: name of the field to set
953 * @value: value to set the field to
955 * Sets the given @field on all structures of @caps to the given @value.
956 * This is a convenience function for calling gst_structure_set_value() on
957 * all structures of @caps.
960 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
964 g_return_if_fail (GST_IS_CAPS (caps));
965 g_return_if_fail (IS_WRITABLE (caps));
966 g_return_if_fail (field != NULL);
967 g_return_if_fail (G_IS_VALUE (value));
969 len = GST_CAPS_LEN (caps);
970 for (i = 0; i < len; i++) {
971 GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
972 gst_structure_set_value (structure, field, value);
977 * gst_caps_set_simple_valist:
978 * @caps: the #GstCaps to set
979 * @field: first field to set
980 * @varargs: additional parameters
982 * Sets fields in a #GstCaps. The arguments must be passed in the same
983 * manner as gst_structure_set(), and be NULL-terminated.
986 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
988 GValue value = { 0, };
990 g_return_if_fail (GST_IS_CAPS (caps));
991 g_return_if_fail (IS_WRITABLE (caps));
997 type = va_arg (varargs, GType);
999 G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1000 if (G_UNLIKELY (err)) {
1001 g_critical ("%s", err);
1005 gst_caps_set_value (caps, field, &value);
1007 g_value_unset (&value);
1009 field = va_arg (varargs, const gchar *);
1014 * gst_caps_set_simple:
1015 * @caps: the #GstCaps to set
1016 * @field: first field to set
1017 * @...: additional parameters
1019 * Sets fields in a #GstCaps. The arguments must be passed in the same
1020 * manner as gst_structure_set(), and be NULL-terminated.
1023 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1027 g_return_if_fail (GST_IS_CAPS (caps));
1028 g_return_if_fail (IS_WRITABLE (caps));
1030 va_start (var_args, field);
1031 gst_caps_set_simple_valist (caps, field, var_args);
1039 * @caps: the #GstCaps to test
1041 * Determines if @caps represents any media format.
1043 * Returns: TRUE if @caps represents any format.
1046 gst_caps_is_any (const GstCaps * caps)
1048 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1050 return (CAPS_IS_ANY (caps));
1054 * gst_caps_is_empty:
1055 * @caps: the #GstCaps to test
1057 * Determines if @caps represents no media formats.
1059 * Returns: TRUE if @caps represents no formats.
1062 gst_caps_is_empty (const GstCaps * caps)
1064 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1066 if (CAPS_IS_ANY (caps))
1069 return CAPS_IS_EMPTY_SIMPLE (caps);
1073 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1076 return gst_value_is_fixed (value);
1080 * gst_caps_is_fixed:
1081 * @caps: the #GstCaps to test
1083 * Fixed #GstCaps describe exactly one format, that is, they have exactly
1084 * one structure, and each field in the structure describes a fixed type.
1085 * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
1087 * Returns: TRUE if @caps is fixed
1090 gst_caps_is_fixed (const GstCaps * caps)
1092 GstStructure *structure;
1093 GstCapsFeatures *features;
1095 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1097 if (GST_CAPS_LEN (caps) != 1)
1100 features = gst_caps_get_features (caps, 0);
1101 if (features && gst_caps_features_is_any (features))
1104 structure = gst_caps_get_structure_unchecked (caps, 0);
1106 return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1110 * gst_caps_is_equal_fixed:
1111 * @caps1: the #GstCaps to test
1112 * @caps2: the #GstCaps to test
1114 * Tests if two #GstCaps are equal. This function only works on fixed
1117 * Returns: TRUE if the arguments represent the same format
1120 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1122 GstStructure *struct1, *struct2;
1123 GstCapsFeatures *features1, *features2;
1125 g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1126 g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1128 struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1129 features1 = gst_caps_get_features_unchecked (caps1, 0);
1131 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1132 struct2 = gst_caps_get_structure_unchecked (caps2, 0);
1133 features2 = gst_caps_get_features_unchecked (caps2, 0);
1135 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1137 return gst_structure_is_equal (struct1, struct2) &&
1138 gst_caps_features_is_equal (features1, features2);
1142 * gst_caps_is_always_compatible:
1143 * @caps1: the #GstCaps to test
1144 * @caps2: the #GstCaps to test
1146 * A given #GstCaps structure is always compatible with another if
1147 * every media format that is in the first is also contained in the
1148 * second. That is, @caps1 is a subset of @caps2.
1150 * Returns: TRUE if @caps1 is a subset of @caps2.
1153 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1155 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1156 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1158 return gst_caps_is_subset (caps1, caps2);
1162 * gst_caps_is_subset:
1163 * @subset: a #GstCaps
1164 * @superset: a potentially greater #GstCaps
1166 * Checks if all caps represented by @subset are also represented by @superset.
1168 * Returns: %TRUE if @subset is a subset of @superset
1171 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1173 GstStructure *s1, *s2;
1174 GstCapsFeatures *f1, *f2;
1175 gboolean ret = TRUE;
1178 g_return_val_if_fail (subset != NULL, FALSE);
1179 g_return_val_if_fail (superset != NULL, FALSE);
1181 if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1183 if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1186 for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
1187 for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
1188 s1 = gst_caps_get_structure_unchecked (subset, i);
1189 f1 = gst_caps_get_features_unchecked (subset, i);
1191 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1192 s2 = gst_caps_get_structure_unchecked (superset, j);
1193 f2 = gst_caps_get_features_unchecked (superset, j);
1195 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1196 if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
1197 gst_caps_features_is_equal (f1, f2)
1198 && gst_structure_is_subset (s1, s2)) {
1199 /* If we found a superset, continue with the next
1200 * subset structure */
1204 /* If we found no superset for this subset structure
1205 * we return FALSE immediately */
1216 * gst_caps_is_subset_structure:
1218 * @structure: a potential #GstStructure subset of @caps
1220 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1221 * for more information.
1223 * Returns: %TRUE if @structure is a subset of @caps
1226 gst_caps_is_subset_structure (const GstCaps * caps,
1227 const GstStructure * structure)
1232 g_return_val_if_fail (caps != NULL, FALSE);
1233 g_return_val_if_fail (structure != NULL, FALSE);
1235 if (CAPS_IS_ANY (caps))
1237 if (CAPS_IS_EMPTY (caps))
1240 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1241 s = gst_caps_get_structure_unchecked (caps, i);
1242 if (gst_structure_is_subset (structure, s)) {
1243 /* If we found a superset return TRUE */
1252 * gst_caps_is_subset_structure_full:
1254 * @structure: a potential #GstStructure subset of @caps
1255 * @features: (allow-none): a #GstCapsFeatures for @structure
1257 * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1258 * for more information.
1260 * Returns: %TRUE if @structure is a subset of @caps
1265 gst_caps_is_subset_structure_full (const GstCaps * caps,
1266 const GstStructure * structure, const GstCapsFeatures * features)
1272 g_return_val_if_fail (caps != NULL, FALSE);
1273 g_return_val_if_fail (structure != NULL, FALSE);
1275 if (CAPS_IS_ANY (caps))
1277 if (CAPS_IS_EMPTY (caps))
1281 features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1283 for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
1284 s = gst_caps_get_structure_unchecked (caps, i);
1285 f = gst_caps_get_features_unchecked (caps, i);
1287 f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1288 if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
1289 && gst_caps_features_is_equal (features, f)
1290 && gst_structure_is_subset (structure, s)) {
1291 /* If we found a superset return TRUE */
1300 * gst_caps_is_equal:
1301 * @caps1: a #GstCaps
1302 * @caps2: another #GstCaps
1304 * Checks if the given caps represent the same set of caps.
1306 * Returns: TRUE if both caps are equal.
1309 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1311 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1312 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1314 if (G_UNLIKELY (caps1 == caps2))
1317 if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1318 return gst_caps_is_equal_fixed (caps1, caps2);
1320 return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1324 * gst_caps_is_strictly_equal:
1325 * @caps1: a #GstCaps
1326 * @caps2: another #GstCaps
1328 * Checks if the given caps are exactly the same set of caps.
1330 * Returns: TRUE if both caps are strictly equal.
1333 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1336 GstStructure *s1, *s2;
1337 GstCapsFeatures *f1, *f2;
1339 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1340 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1342 if (G_UNLIKELY (caps1 == caps2))
1345 if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1348 for (i = 0; i < GST_CAPS_LEN (caps1); i++) {
1349 s1 = gst_caps_get_structure_unchecked (caps1, i);
1350 f1 = gst_caps_get_features_unchecked (caps1, i);
1352 f1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1353 s2 = gst_caps_get_structure_unchecked (caps2, i);
1354 f2 = gst_caps_get_features_unchecked (caps2, i);
1356 f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1358 if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
1359 !gst_caps_features_is_equal (f1, f2) ||
1360 !gst_structure_is_equal (s1, s2))
1367 /* intersect operation */
1370 * gst_caps_can_intersect:
1371 * @caps1: a #GstCaps to intersect
1372 * @caps2: a #GstCaps to intersect
1374 * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1377 * Returns: %TRUE if intersection would be not empty
1380 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1382 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1383 guint j, k, len1, len2;
1384 GstStructure *struct1;
1385 GstStructure *struct2;
1386 GstCapsFeatures *features1;
1387 GstCapsFeatures *features2;
1389 g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1390 g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1392 /* caps are exactly the same pointers */
1393 if (G_UNLIKELY (caps1 == caps2))
1396 /* empty caps on either side, return empty */
1397 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1400 /* one of the caps is any */
1401 if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1404 /* run zigzag on top line then right line, this preserves the caps order
1405 * much better than a simple loop.
1407 * This algorithm zigzags over the caps structures as demonstrated in
1408 * the following matrix:
1411 * +------------- total distance: +-------------
1412 * | 1 2 4 7 0 | 0 1 2 3
1413 * caps2 | 3 5 8 10 1 | 1 2 3 4
1414 * | 6 9 11 12 2 | 2 3 4 5
1416 * First we iterate over the caps1 structures (top line) intersecting
1417 * the structures diagonally down, then we iterate over the caps2
1418 * structures. The result is that the intersections are ordered based on the
1419 * sum of the indexes in the list.
1421 len1 = GST_CAPS_LEN (caps1);
1422 len2 = GST_CAPS_LEN (caps2);
1423 for (i = 0; i < len1 + len2 - 1; i++) {
1424 /* superset index goes from 0 to sgst_caps_structure_intersectuperset->structs->len-1 */
1425 j = MIN (i, len1 - 1);
1426 /* subset index stays 0 until i reaches superset->structs->len, then it
1427 * counts up from 1 to subset->structs->len - 1 */
1428 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1429 /* now run the diagonal line, end condition is the left or bottom
1432 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1433 features1 = gst_caps_get_features_unchecked (caps1, j);
1435 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1436 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1437 features2 = gst_caps_get_features_unchecked (caps2, k);
1439 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1440 if (gst_caps_features_is_equal (features1, features2) &&
1441 gst_structure_can_intersect (struct1, struct2)) {
1444 /* move down left */
1446 if (G_UNLIKELY (j == 0))
1447 break; /* so we don't roll back to G_MAXUINT */
1456 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1458 guint64 i; /* index can be up to 2 * G_MAX_UINT */
1459 guint j, k, len1, len2;
1460 GstStructure *struct1;
1461 GstStructure *struct2;
1462 GstCapsFeatures *features1;
1463 GstCapsFeatures *features2;
1465 GstStructure *istruct;
1467 /* caps are exactly the same pointers, just copy one caps */
1468 if (G_UNLIKELY (caps1 == caps2))
1469 return gst_caps_ref (caps1);
1471 /* empty caps on either side, return empty */
1472 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1473 return gst_caps_ref (GST_CAPS_NONE);
1475 /* one of the caps is any, just copy the other caps */
1476 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1477 return gst_caps_ref (caps2);
1479 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1480 return gst_caps_ref (caps1);
1482 dest = gst_caps_new_empty ();
1483 /* run zigzag on top line then right line, this preserves the caps order
1484 * much better than a simple loop.
1486 * This algorithm zigzags over the caps structures as demonstrated in
1487 * the following matrix:
1495 * First we iterate over the caps1 structures (top line) intersecting
1496 * the structures diagonally down, then we iterate over the caps2
1499 len1 = GST_CAPS_LEN (caps1);
1500 len2 = GST_CAPS_LEN (caps2);
1501 for (i = 0; i < len1 + len2 - 1; i++) {
1502 /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
1503 j = MIN (i, len1 - 1);
1504 /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
1505 * up from 1 to GST_CAPS_LEN (caps2) - 1 */
1506 k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
1507 /* now run the diagonal line, end condition is the left or bottom
1510 struct1 = gst_caps_get_structure_unchecked (caps1, j);
1511 features1 = gst_caps_get_features_unchecked (caps1, j);
1513 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1514 struct2 = gst_caps_get_structure_unchecked (caps2, k);
1515 features2 = gst_caps_get_features_unchecked (caps2, k);
1517 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1518 if (gst_caps_features_is_equal (features1, features2)) {
1519 istruct = gst_structure_intersect (struct1, struct2);
1521 if (gst_caps_features_is_any (features1))
1523 gst_caps_merge_structure_full (dest, istruct,
1524 gst_caps_features_copy_conditional (features2));
1527 gst_caps_merge_structure_full (dest, istruct,
1528 gst_caps_features_copy_conditional (features1));
1531 /* move down left */
1533 if (G_UNLIKELY (j == 0))
1534 break; /* so we don't roll back to G_MAXUINT */
1542 * gst_caps_intersect_first:
1543 * @caps1: a #GstCaps to intersect
1544 * @caps2: a #GstCaps to intersect
1546 * Creates a new #GstCaps that contains all the formats that are common
1547 * to both @caps1 and @caps2.
1549 * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1550 * fashion as @caps1.
1552 * Returns: the new #GstCaps
1555 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1558 guint j, len1, len2;
1559 GstStructure *struct1;
1560 GstStructure *struct2;
1561 GstCapsFeatures *features1;
1562 GstCapsFeatures *features2;
1564 GstStructure *istruct;
1566 /* caps are exactly the same pointers, just copy one caps */
1567 if (G_UNLIKELY (caps1 == caps2))
1568 return gst_caps_ref (caps1);
1570 /* empty caps on either side, return empty */
1571 if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1572 return gst_caps_ref (GST_CAPS_NONE);
1574 /* one of the caps is any, just copy the other caps */
1575 if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
1576 return gst_caps_ref (caps2);
1578 if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1579 return gst_caps_ref (caps1);
1581 dest = gst_caps_new_empty ();
1582 len1 = GST_CAPS_LEN (caps1);
1583 len2 = GST_CAPS_LEN (caps2);
1584 for (i = 0; i < len1; i++) {
1585 struct1 = gst_caps_get_structure_unchecked (caps1, i);
1586 features1 = gst_caps_get_features_unchecked (caps1, i);
1588 features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1589 for (j = 0; j < len2; j++) {
1590 struct2 = gst_caps_get_structure_unchecked (caps2, j);
1591 features2 = gst_caps_get_features_unchecked (caps2, j);
1593 features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1594 if (gst_caps_features_is_equal (features1, features2)) {
1595 istruct = gst_structure_intersect (struct1, struct2);
1597 if (gst_caps_features_is_any (features1))
1599 gst_caps_merge_structure_full (dest, istruct,
1600 gst_caps_features_copy_conditional (features2));
1603 gst_caps_merge_structure_full (dest, istruct,
1604 gst_caps_features_copy_conditional (features1));
1614 * gst_caps_intersect_full:
1615 * @caps1: a #GstCaps to intersect
1616 * @caps2: a #GstCaps to intersect
1617 * @mode: The intersection algorithm/mode to use
1619 * Creates a new #GstCaps that contains all the formats that are common
1620 * to both @caps1 and @caps2, the order is defined by the #GstCapsIntersectMode
1623 * Returns: the new #GstCaps
1626 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1627 GstCapsIntersectMode mode)
1629 g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1630 g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1633 case GST_CAPS_INTERSECT_FIRST:
1634 return gst_caps_intersect_first (caps1, caps2);
1636 g_warning ("Unknown caps intersect mode: %d", mode);
1638 case GST_CAPS_INTERSECT_ZIG_ZAG:
1639 return gst_caps_intersect_zig_zag (caps1, caps2);
1644 * gst_caps_intersect:
1645 * @caps1: a #GstCaps to intersect
1646 * @caps2: a #GstCaps to intersect
1648 * Creates a new #GstCaps that contains all the formats that are common
1649 * to both @caps1 and @caps2. Defaults to %GST_CAPS_INTERSECT_ZIG_ZAG mode.
1651 * Returns: the new #GstCaps
1654 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1656 return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1659 /* subtract operation */
1663 const GstStructure *subtract_from;
1668 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1671 SubtractionEntry *e = user_data;
1672 GValue subtraction = { 0, };
1673 const GValue *other;
1674 GstStructure *structure;
1676 other = gst_structure_id_get_value (e->subtract_from, field_id);
1682 if (!gst_value_subtract (&subtraction, other, value))
1685 if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1686 g_value_unset (&subtraction);
1689 structure = gst_structure_copy (e->subtract_from);
1690 gst_structure_id_take_value (structure, field_id, &subtraction);
1691 e->put_into = g_slist_prepend (e->put_into, structure);
1697 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1698 const GstStructure * subtrahend)
1703 e.subtract_from = minuend;
1705 ret = gst_structure_foreach ((GstStructure *) subtrahend,
1706 gst_caps_structure_subtract_field, &e);
1713 for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1714 gst_structure_free (walk->data);
1716 g_slist_free (e.put_into);
1723 * gst_caps_subtract:
1724 * @minuend: #GstCaps to subtract from
1725 * @subtrahend: #GstCaps to subtract
1727 * Subtracts the @subtrahend from the @minuend.
1728 * <note>This function does not work reliably if optional properties for caps
1729 * are included on one caps and omitted on the other.</note>
1731 * Returns: the resulting caps
1734 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1739 GstCapsFeatures *min_f, *sub_f;
1740 GstCaps *dest = NULL, *src;
1742 g_return_val_if_fail (minuend != NULL, NULL);
1743 g_return_val_if_fail (subtrahend != NULL, NULL);
1745 if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1746 return gst_caps_new_empty ();
1749 if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1750 return gst_caps_ref (minuend);
1752 /* FIXME: Do we want this here or above?
1753 The reason we need this is that there is no definition about what
1754 ANY means for specific types, so it's not possible to reduce ANY partially
1755 You can only remove everything or nothing and that is done above.
1756 Note: there's a test that checks this behaviour. */
1758 g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1759 sublen = GST_CAPS_LEN (subtrahend);
1760 g_assert (sublen > 0);
1762 src = _gst_caps_copy (minuend);
1763 for (i = 0; i < sublen; i++) {
1766 sub = gst_caps_get_structure_unchecked (subtrahend, i);
1767 sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1769 sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1771 gst_caps_unref (src);
1774 dest = gst_caps_new_empty ();
1775 srclen = GST_CAPS_LEN (src);
1776 for (j = 0; j < srclen; j++) {
1777 min = gst_caps_get_structure_unchecked (src, j);
1778 min_f = gst_caps_get_features_unchecked (src, j);
1780 min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1782 /* Same reason as above for ANY caps */
1783 g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1785 if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1786 gst_caps_features_is_equal (min_f, sub_f)) {
1789 if (gst_caps_structure_subtract (&list, min, sub)) {
1792 for (walk = list; walk; walk = g_slist_next (walk)) {
1793 gst_caps_append_structure_unchecked (dest,
1794 (GstStructure *) walk->data,
1795 gst_caps_features_copy_conditional (min_f));
1797 g_slist_free (list);
1799 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1800 gst_caps_features_copy_conditional (min_f));
1803 gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1804 gst_caps_features_copy_conditional (min_f));
1808 if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1809 gst_caps_unref (src);
1814 gst_caps_unref (src);
1815 dest = gst_caps_simplify (dest);
1820 /* normalize/simplify operations */
1822 typedef struct _NormalizeForeach
1825 GstStructure *structure;
1826 GstCapsFeatures *features;
1830 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1832 NormalizeForeach *nf = (NormalizeForeach *) ptr;
1836 if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1837 guint len = gst_value_list_get_size (value);
1839 for (i = 1; i < len; i++) {
1840 const GValue *v = gst_value_list_get_value (value, i);
1841 GstStructure *structure = gst_structure_copy (nf->structure);
1843 gst_structure_id_set_value (structure, field_id, v);
1844 gst_caps_append_structure_unchecked (nf->caps, structure,
1845 gst_caps_features_copy_conditional (nf->features));
1848 gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
1849 gst_structure_id_take_value (nf->structure, field_id, &val);
1857 * gst_caps_normalize:
1858 * @caps: (transfer full): a #GstCaps to normalize
1860 * Returns a #GstCaps that represents the same set of formats as
1861 * @caps, but contains no lists. Each list is expanded into separate
1864 * This function takes ownership of @caps.
1866 * Returns: (transfer full): the normalized #GstCaps
1869 gst_caps_normalize (GstCaps * caps)
1871 NormalizeForeach nf;
1874 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1876 caps = gst_caps_make_writable (caps);
1879 for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
1880 nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
1881 nf.features = gst_caps_get_features_unchecked (nf.caps, i);
1882 while (!gst_structure_foreach (nf.structure,
1883 gst_caps_normalize_foreach, &nf));
1890 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1893 const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1894 const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1896 /* FIXME: this orders alphabetically, but ordering the quarks might be faster
1897 So what's the best way? */
1898 ret = strcmp (gst_structure_get_name (struct1),
1899 gst_structure_get_name (struct2));
1904 return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1911 GstStructure *compare;
1915 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1918 UnionField *u = user_data;
1919 const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1923 g_value_unset (&u->value);
1927 if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1931 g_value_unset (&u->value);
1936 gst_value_union (&u->value, val, value);
1942 gst_caps_structure_simplify (GstStructure ** result,
1943 GstStructure * simplify, GstStructure * compare)
1946 UnionField field = { 0, {0,}, NULL };
1948 /* try to subtract to get a real subset */
1949 if (gst_caps_structure_subtract (&list, simplify, compare)) {
1950 if (list == NULL) { /* no result */
1953 } else if (list->next == NULL) { /* one result */
1954 *result = list->data;
1955 g_slist_free (list);
1957 } else { /* multiple results */
1958 g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
1959 g_slist_free (list);
1964 /* try to union both structs */
1965 field.compare = compare;
1966 if (gst_structure_foreach (simplify,
1967 gst_caps_structure_figure_out_union, &field)) {
1968 gboolean ret = FALSE;
1970 /* now we know all of simplify's fields are the same in compare
1971 * but at most one field: field.name */
1972 if (G_IS_VALUE (&field.value)) {
1973 if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
1974 gst_structure_id_take_value (compare, field.name, &field.value);
1978 g_value_unset (&field.value);
1981 if (gst_structure_n_fields (simplify) <=
1982 gst_structure_n_fields (compare)) {
1983 /* compare is just more specific, will be optimized away later */
1984 /* FIXME: do this here? */
1985 GST_LOG ("found a case that will be optimized later.");
1987 gchar *one = gst_structure_to_string (simplify);
1988 gchar *two = gst_structure_to_string (compare);
1991 ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
2003 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2004 GstStructure * new, gint i)
2006 gst_structure_set_parent_refcount (old, NULL);
2007 gst_structure_free (old);
2008 gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
2009 g_array_index (GST_CAPS_ARRAY (caps), GstCapsArrayElement, i).structure = new;
2013 * gst_caps_simplify:
2014 * @caps: (transfer full): a #GstCaps to simplify
2016 * Converts the given @caps into a representation that represents the
2017 * same set of formats, but in a simpler form. Component structures that are
2018 * identical are merged. Component structures that have values that can be
2019 * merged are also merged.
2021 * This method does not preserve the original order of @caps.
2023 * Returns: The simplified caps.
2026 gst_caps_simplify (GstCaps * caps)
2028 GstStructure *simplify, *compare, *result = NULL;
2029 GstCapsFeatures *simplify_f, *compare_f;
2032 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2034 start = GST_CAPS_LEN (caps) - 1;
2035 /* one caps, already as simple as can be */
2039 caps = gst_caps_make_writable (caps);
2041 g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2043 for (i = start; i >= 0; i--) {
2044 simplify = gst_caps_get_structure_unchecked (caps, i);
2045 simplify_f = gst_caps_get_features_unchecked (caps, i);
2047 simplify_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2048 compare = gst_caps_get_structure_unchecked (caps, start);
2049 compare_f = gst_caps_get_features_unchecked (caps, start);
2051 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2052 if (gst_structure_get_name_id (simplify) !=
2053 gst_structure_get_name_id (compare) ||
2054 !gst_caps_features_is_equal (simplify_f, compare_f))
2056 for (j = start; j >= 0; j--) {
2059 compare = gst_caps_get_structure_unchecked (caps, j);
2060 compare_f = gst_caps_get_features_unchecked (caps, j);
2062 compare_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
2063 if (gst_structure_get_name_id (simplify) !=
2064 gst_structure_get_name_id (compare) ||
2065 !gst_caps_features_is_equal (simplify_f, compare_f)) {
2068 if (gst_caps_structure_simplify (&result, simplify, compare)) {
2070 gst_caps_switch_structures (caps, simplify, result, i);
2073 gst_caps_remove_structure (caps, i);
2085 * @caps: (transfer full): a #GstCaps to fixate
2087 * Modifies the given @caps into a representation with only fixed
2088 * values. First the caps will be truncated and then the first structure will be
2089 * fixated with gst_structure_fixate().
2091 * Returns: (transfer full): the fixated caps
2094 gst_caps_fixate (GstCaps * caps)
2099 g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2101 /* default fixation */
2102 caps = gst_caps_truncate (caps);
2103 caps = gst_caps_make_writable (caps);
2104 s = gst_caps_get_structure (caps, 0);
2105 gst_structure_fixate (s);
2107 /* Set features to sysmem if they're still ANY */
2108 f = gst_caps_get_features (caps, 0);
2109 if (f && gst_caps_features_is_any (f)) {
2110 f = gst_caps_features_new_empty ();
2111 gst_caps_set_features (caps, 0, f);
2120 * gst_caps_to_string:
2123 * Converts @caps to a string representation. This string representation
2124 * can be converted back to a #GstCaps by gst_caps_from_string().
2126 * For debugging purposes its easier to do something like this:
2128 * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2130 * This prints the caps in human readable form.
2132 * Returns: (transfer full): a newly allocated string representing @caps.
2135 gst_caps_to_string (const GstCaps * caps)
2137 guint i, slen, clen;
2140 /* NOTE: This function is potentially called by the debug system,
2141 * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
2142 * should be careful to avoid recursion. This includes any functions
2143 * called by gst_caps_to_string. In particular, calls should
2144 * not use the GST_PTR_FORMAT extension. */
2147 return g_strdup ("NULL");
2149 if (CAPS_IS_ANY (caps)) {
2150 return g_strdup ("ANY");
2152 if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2153 return g_strdup ("EMPTY");
2156 /* estimate a rough string length to avoid unnecessary reallocs in GString */
2158 clen = GST_CAPS_LEN (caps);
2159 for (i = 0; i < clen; i++) {
2163 STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2165 f = gst_caps_get_features_unchecked (caps, i);
2167 slen += FEATURES_ESTIMATED_STRING_LEN (f);
2170 s = g_string_sized_new (slen);
2171 for (i = 0; i < clen; i++) {
2172 GstStructure *structure;
2173 GstCapsFeatures *features;
2176 /* ';' is now added by gst_structure_to_string */
2177 g_string_append_c (s, ' ');
2180 structure = gst_caps_get_structure_unchecked (caps, i);
2181 features = gst_caps_get_features_unchecked (caps, i);
2183 g_string_append (s, gst_structure_get_name (structure));
2184 if (features && (gst_caps_features_is_any (features)
2185 || !gst_caps_features_is_equal (features,
2186 GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
2187 g_string_append_c (s, '(');
2188 priv_gst_caps_features_append_to_gstring (features, s);
2189 g_string_append_c (s, ')');
2191 priv_gst_structure_append_to_gstring (structure, s);
2193 if (s->len && s->str[s->len - 1] == ';') {
2194 /* remove latest ';' */
2195 s->str[--s->len] = '\0';
2197 return g_string_free (s, FALSE);
2201 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2203 GstStructure *structure;
2204 gchar *s, *copy, *end, *next, save;
2206 if (strcmp ("ANY", string) == 0) {
2207 GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2211 if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2215 copy = s = g_strdup (string);
2217 GstCapsFeatures *features = NULL;
2219 while (g_ascii_isspace (*s))
2225 if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2232 structure = gst_structure_new_empty (s);
2235 if (structure == NULL) {
2253 } else if (*end == ')') {
2262 features = gst_caps_features_from_string (s);
2264 gst_structure_free (structure);
2278 if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2279 gst_structure_free (structure);
2285 gst_caps_append_structure_unchecked (caps, structure, features);
2296 * gst_caps_from_string:
2297 * @string: a string to convert to #GstCaps
2299 * Converts @caps from a string representation.
2301 * Returns: (transfer full): a newly allocated #GstCaps
2304 gst_caps_from_string (const gchar * string)
2308 g_return_val_if_fail (string, FALSE);
2310 caps = gst_caps_new_empty ();
2311 if (gst_caps_from_string_inplace (caps, string)) {
2314 gst_caps_unref (caps);
2320 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2322 g_return_if_fail (G_IS_VALUE (src_value));
2323 g_return_if_fail (G_IS_VALUE (dest_value));
2324 g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
2325 g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
2326 || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
2328 g_value_take_string (dest_value,
2329 gst_caps_to_string (gst_value_get_caps (src_value)));