gst: Add some more Since: 1.2
[platform/upstream/gstreamer.git] / gst / gstcaps.c
1 /* GStreamer
2  * Copyright (C) <2003> David A. Schleef <ds@schleef.org>
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 /**
21  * SECTION:gstcaps
22  * @short_description: Structure describing sets of media formats
23  * @see_also: #GstStructure, #GstMiniObject
24  *
25  * Caps (capabilities) are lightweight refcounted objects describing media types.
26  * They are composed of an array of #GstStructure.
27  *
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.
31  *
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.
35  *
36  * A #GstCaps can be constructed with the following code fragment:
37  *
38  * <example>
39  *  <title>Creating caps</title>
40  *  <programlisting>
41  *  GstCaps *caps;
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,
48  *       NULL);
49  *  </programlisting>
50  * </example>
51  *
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.
55  *
56  * Various methods exist to work with the media types such as subtracting
57  * or intersecting.
58  *
59  * Last reviewed on 2011-03-28 (0.11.3)
60  */
61
62 #ifdef HAVE_CONFIG_H
63 #include "config.h"
64 #endif
65 #include <string.h>
66 #include <signal.h>
67
68 #include "gst_private.h"
69 #include <gst/gst.h>
70 #include <gobject/gvaluecollector.h>
71
72 #define DEBUG_REFCOUNT
73
74 typedef struct _GstCapsArrayElement
75 {
76   GstStructure *structure;
77   GstCapsFeatures *features;
78 } GstCapsArrayElement;
79
80 typedef struct _GstCapsImpl
81 {
82   GstCaps caps;
83
84   GArray *array;
85 } GstCapsImpl;
86
87 #define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
88
89 #define GST_CAPS_LEN(c)   (GST_CAPS_ARRAY(c)->len)
90
91 #define IS_WRITABLE(caps) \
92   (GST_CAPS_REFCOUNT_VALUE (caps) == 1)
93
94 /* same as gst_caps_is_any () */
95 #define CAPS_IS_ANY(caps)                               \
96   (GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY)
97
98 /* same as gst_caps_is_empty () */
99 #define CAPS_IS_EMPTY(caps)                             \
100   (!CAPS_IS_ANY(caps) && CAPS_IS_EMPTY_SIMPLE(caps))
101
102 #define CAPS_IS_EMPTY_SIMPLE(caps)                                      \
103   ((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
104
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)
106
107 /* quick way to get a caps structure at an index without doing a type or array
108  * length check */
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);                             \
119 }G_STMT_END
120
121 /* lock to protect multiple invocations of static caps to caps conversion */
122 G_LOCK_DEFINE_STATIC (static_caps_lock);
123
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);
128
129 GType _gst_caps_type = 0;
130 GstCaps *_gst_caps_any;
131 GstCaps *_gst_caps_none;
132
133 GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
134
135 void
136 _priv_gst_caps_initialize (void)
137 {
138   _gst_caps_type = gst_caps_get_type ();
139
140   _gst_caps_any = gst_caps_new_any ();
141   _gst_caps_none = gst_caps_new_empty ();
142
143   g_value_register_transform_func (_gst_caps_type,
144       G_TYPE_STRING, gst_caps_transform_to_string);
145 }
146
147 static GstCaps *
148 _gst_caps_copy (const GstCaps * caps)
149 {
150   GstCaps *newcaps;
151   GstStructure *structure;
152   GstCapsFeatures *features;
153   guint i, n;
154
155   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
156
157   newcaps = gst_caps_new_empty ();
158   GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
159   n = GST_CAPS_LEN (caps);
160
161   GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, caps, "doing copy %p -> %p",
162       caps, newcaps);
163
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));
169   }
170
171   return newcaps;
172 }
173
174 /* creation/deletion */
175 static void
176 _gst_caps_free (GstCaps * caps)
177 {
178   GstStructure *structure;
179   GstCapsFeatures *features;
180   guint i, len;
181
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);
192     if (features) {
193       gst_caps_features_set_parent_refcount (features, NULL);
194       gst_caps_features_free (features);
195     }
196   }
197   g_array_free (GST_CAPS_ARRAY (caps), TRUE);
198
199 #ifdef DEBUG_REFCOUNT
200   GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
201 #endif
202   g_slice_free1 (sizeof (GstCapsImpl), caps);
203 }
204
205 static void
206 gst_caps_init (GstCaps * caps)
207 {
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);
211
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
214    * in practice
215    * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
216    */
217   GST_CAPS_ARRAY (caps) =
218       g_array_new (FALSE, TRUE, sizeof (GstCapsArrayElement));
219 }
220
221 /**
222  * gst_caps_new_empty:
223  *
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.
228  *
229  * Returns: (transfer full): the new #GstCaps
230  */
231 GstCaps *
232 gst_caps_new_empty (void)
233 {
234   GstCaps *caps;
235
236   caps = (GstCaps *) g_slice_new (GstCapsImpl);
237
238   gst_caps_init (caps);
239
240 #ifdef DEBUG_REFCOUNT
241   GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
242 #endif
243
244   return caps;
245 }
246
247 /**
248  * gst_caps_new_any:
249  *
250  * Creates a new #GstCaps that indicates that it is compatible with
251  * any media format.
252  *
253  * Returns: (transfer full): the new #GstCaps
254  */
255 GstCaps *
256 gst_caps_new_any (void)
257 {
258   GstCaps *caps = gst_caps_new_empty ();
259
260   GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_ANY);
261
262   return caps;
263 }
264
265 /**
266  * gst_caps_new_empty_simple:
267  * @media_type: the media type of the structure
268  *
269  * Creates a new #GstCaps that contains one #GstStructure with name
270  * @media_type.
271  * Caller is responsible for unreffing the returned caps.
272  *
273  * Returns: (transfer full): the new #GstCaps
274  */
275 GstCaps *
276 gst_caps_new_empty_simple (const char *media_type)
277 {
278   GstCaps *caps;
279   GstStructure *structure;
280
281   caps = gst_caps_new_empty ();
282   structure = gst_structure_new_empty (media_type);
283   if (structure)
284     gst_caps_append_structure_unchecked (caps, structure, NULL);
285
286   return caps;
287 }
288
289 /**
290  * gst_caps_new_simple:
291  * @media_type: the media type of the structure
292  * @fieldname: first field to set
293  * @...: additional arguments
294  *
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.
299  *
300  * Returns: (transfer full): the new #GstCaps
301  */
302 GstCaps *
303 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
304 {
305   GstCaps *caps;
306   GstStructure *structure;
307   va_list var_args;
308
309   caps = gst_caps_new_empty ();
310
311   va_start (var_args, fieldname);
312   structure = gst_structure_new_valist (media_type, fieldname, var_args);
313   va_end (var_args);
314
315   if (structure)
316     gst_caps_append_structure_unchecked (caps, structure, NULL);
317   else
318     gst_caps_replace (&caps, NULL);
319
320   return caps;
321 }
322
323 /**
324  * gst_caps_new_full:
325  * @struct1: the first structure to add
326  * @...: additional structures to add
327  *
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.
331  *
332  * Returns: (transfer full): the new #GstCaps
333  */
334 GstCaps *
335 gst_caps_new_full (GstStructure * struct1, ...)
336 {
337   GstCaps *caps;
338   va_list var_args;
339
340   va_start (var_args, struct1);
341   caps = gst_caps_new_full_valist (struct1, var_args);
342   va_end (var_args);
343
344   return caps;
345 }
346
347 /**
348  * gst_caps_new_full_valist:
349  * @structure: the first structure to add
350  * @var_args: additional structures to add
351  *
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.
355  *
356  * Returns: (transfer full): the new #GstCaps
357  */
358 GstCaps *
359 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
360 {
361   GstCaps *caps;
362
363   caps = gst_caps_new_empty ();
364
365   while (structure) {
366     gst_caps_append_structure_unchecked (caps, structure, NULL);
367     structure = va_arg (var_args, GstStructure *);
368   }
369
370   return caps;
371 }
372
373 G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
374
375 /**
376  * gst_static_caps_get:
377  * @static_caps: the #GstStaticCaps to convert
378  *
379  * Converts a #GstStaticCaps to a #GstCaps.
380  *
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.
384  */
385 GstCaps *
386 gst_static_caps_get (GstStaticCaps * static_caps)
387 {
388   GstCaps **caps;
389
390   g_return_val_if_fail (static_caps != NULL, NULL);
391
392   caps = &static_caps->caps;
393
394   /* refcount is 0 when we need to convert */
395   if (G_UNLIKELY (*caps == NULL)) {
396     const char *string;
397
398     G_LOCK (static_caps_lock);
399     /* check if other thread already updated */
400     if (G_UNLIKELY (*caps != NULL))
401       goto done;
402
403     string = static_caps->string;
404
405     if (G_UNLIKELY (string == NULL))
406       goto no_string;
407
408     *caps = gst_caps_from_string (string);
409
410     /* convert to string */
411     if (G_UNLIKELY (*caps == NULL))
412       g_critical ("Could not convert static caps \"%s\"", string);
413
414     GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
415         string);
416   done:
417     G_UNLOCK (static_caps_lock);
418   }
419   /* ref the caps, makes it not writable */
420   if (G_LIKELY (*caps != NULL))
421     gst_caps_ref (*caps);
422
423   return *caps;
424
425   /* ERRORS */
426 no_string:
427   {
428     G_UNLOCK (static_caps_lock);
429     g_warning ("static caps %p string is NULL", static_caps);
430     return NULL;
431   }
432 }
433
434 /**
435  * gst_static_caps_cleanup:
436  * @static_caps: the #GstStaticCaps to clean
437  *
438  * Clean up the cached caps contained in @static_caps.
439  */
440 void
441 gst_static_caps_cleanup (GstStaticCaps * static_caps)
442 {
443   G_LOCK (static_caps_lock);
444   gst_caps_replace (&static_caps->caps, NULL);
445   G_UNLOCK (static_caps_lock);
446 }
447
448 /* manipulation */
449
450 static void
451 gst_caps_remove_and_get_structure_and_features (GstCaps * caps, guint idx,
452     GstStructure ** s, GstCapsFeatures ** f)
453 {
454   GstStructure *s_;
455   GstCapsFeatures *f_;
456
457   s_ = gst_caps_get_structure_unchecked (caps, idx);
458   f_ = gst_caps_get_features_unchecked (caps, idx);
459
460   /* don't use index_fast, gst_caps_simplify relies on the order */
461   g_array_remove_index (GST_CAPS_ARRAY (caps), idx);
462
463   gst_structure_set_parent_refcount (s_, NULL);
464   if (f_) {
465     gst_caps_features_set_parent_refcount (f_, NULL);
466   }
467
468   *s = s_;
469   *f = f_;
470 }
471
472 static GstStructure *
473 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
474 {
475   GstStructure *s;
476   GstCapsFeatures *f;
477
478   gst_caps_remove_and_get_structure_and_features (caps, idx, &s, &f);
479
480   if (f)
481     gst_caps_features_free (f);
482
483   return s;
484 }
485
486
487
488 /**
489  * gst_caps_steal_structure:
490  * @caps: the #GstCaps to retrieve from
491  * @index: Index of the structure to retrieve
492  *
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.
495  *
496  * Returns: (transfer full): a pointer to the #GstStructure corresponding
497  *     to @index.
498  */
499 GstStructure *
500 gst_caps_steal_structure (GstCaps * caps, guint index)
501 {
502   g_return_val_if_fail (caps != NULL, NULL);
503   g_return_val_if_fail (IS_WRITABLE (caps), NULL);
504
505   if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
506     return NULL;
507
508   return gst_caps_remove_and_get_structure (caps, index);
509 }
510
511 /**
512  * gst_caps_append:
513  * @caps1: the #GstCaps that will be appended to
514  * @caps2: (transfer full): the #GstCaps to append
515  *
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.
519  */
520 void
521 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
522 {
523   GstStructure *structure;
524   GstCapsFeatures *features;
525   int i;
526
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));
530
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);
534   } else {
535     caps2 = gst_caps_make_writable (caps2);
536
537     for (i = GST_CAPS_LEN (caps2); i; i--) {
538       gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
539           &features);
540       gst_caps_append_structure_unchecked (caps1, structure, features);
541     }
542     gst_caps_unref (caps2);     /* guaranteed to free it */
543   }
544 }
545
546 /**
547  * gst_caps_merge:
548  * @caps1: (transfer full): the #GstCaps that will take the new entries
549  * @caps2: (transfer full): the #GstCaps to merge in
550  *
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.
555  *
556  * Returns: (transfer full): the merged caps.
557  */
558 GstCaps *
559 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
560 {
561   GstStructure *structure;
562   GstCapsFeatures *features;
563   int i;
564   GstCaps *result;
565
566   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
567   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
568
569   if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
570     gst_caps_unref (caps2);
571     result = caps1;
572   } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
573     gst_caps_unref (caps1);
574     result = caps2;
575   } else {
576     caps2 = gst_caps_make_writable (caps2);
577
578     for (i = GST_CAPS_LEN (caps2); i; i--) {
579       gst_caps_remove_and_get_structure_and_features (caps2, 0, &structure,
580           &features);
581       caps1 = gst_caps_merge_structure_full (caps1, structure, features);
582     }
583     gst_caps_unref (caps2);
584     result = caps1;
585
586     /* this is too naive
587        GstCaps *com = gst_caps_intersect (caps1, caps2);
588        GstCaps *add = gst_caps_subtract (caps2, com);
589
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);
594      */
595   }
596
597   return result;
598 }
599
600 /**
601  * gst_caps_append_structure:
602  * @caps: the #GstCaps that will be appended to
603  * @structure: (transfer full): the #GstStructure to append
604  *
605  * Appends @structure to @caps.  The structure is not copied; @caps
606  * becomes the owner of @structure.
607  */
608 void
609 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
610 {
611   g_return_if_fail (GST_IS_CAPS (caps));
612   g_return_if_fail (IS_WRITABLE (caps));
613
614   if (G_LIKELY (structure)) {
615     gst_caps_append_structure_unchecked (caps, structure, NULL);
616   }
617 }
618
619 /**
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
624  *
625  * Appends @structure with @features to @caps.  The structure is not copied; @caps
626  * becomes the owner of @structure.
627  *
628  * Since: 1.2
629  */
630 void
631 gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
632     GstCapsFeatures * features)
633 {
634   g_return_if_fail (GST_IS_CAPS (caps));
635   g_return_if_fail (IS_WRITABLE (caps));
636
637   if (G_LIKELY (structure)) {
638     gst_caps_append_structure_unchecked (caps, structure, features);
639   }
640 }
641
642 /**
643  * gst_caps_remove_structure:
644  * @caps: the #GstCaps to remove from
645  * @idx: Index of the structure to remove
646  *
647  * removes the stucture with the given index from the list of structures
648  * contained in @caps.
649  */
650 void
651 gst_caps_remove_structure (GstCaps * caps, guint idx)
652 {
653   GstStructure *structure;
654
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));
658
659   structure = gst_caps_remove_and_get_structure (caps, idx);
660   gst_structure_free (structure);
661 }
662
663 /**
664  * gst_caps_merge_structure:
665  * @caps: (transfer full): the #GstCaps to merge into
666  * @structure: (transfer full): the #GstStructure to merge
667  *
668  * Appends @structure to @caps if its not already expressed by @caps.
669  *
670  * Returns: (transfer full): the merged caps.
671  */
672 GstCaps *
673 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
674 {
675   GstStructure *structure1;
676   GstCapsFeatures *features1;
677   int i;
678   gboolean unique = TRUE;
679
680   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
681
682   if (G_UNLIKELY (structure == NULL))
683     return caps;
684
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);
689     if (!features1)
690       features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
691
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)) {
697       unique = FALSE;
698       break;
699     }
700   }
701   if (unique) {
702     caps = gst_caps_make_writable (caps);
703     gst_caps_append_structure_unchecked (caps, structure, NULL);
704   } else {
705     gst_structure_free (structure);
706   }
707   return caps;
708 }
709
710 /**
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
715  *
716  * Appends @structure with @features to @caps if its not already expressed by @caps.
717  *
718  * Returns: (transfer full): the merged caps.
719  *
720  * Since: 1.2
721  */
722 GstCaps *
723 gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
724     GstCapsFeatures * features)
725 {
726   GstStructure *structure1;
727   GstCapsFeatures *features1, *features_tmp;
728   int i;
729   gboolean unique = TRUE;
730
731   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
732
733   if (G_UNLIKELY (structure == NULL))
734     return caps;
735
736   /* To make comparisons easier below */
737   features_tmp = features ? features : GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
738
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);
743     if (!features1)
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
751      */
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)) {
756       unique = FALSE;
757       break;
758     }
759   }
760   if (unique) {
761     caps = gst_caps_make_writable (caps);
762     gst_caps_append_structure_unchecked (caps, structure, features);
763   } else {
764     gst_structure_free (structure);
765     if (features)
766       gst_caps_features_free (features);
767   }
768   return caps;
769 }
770
771 /**
772  * gst_caps_get_size:
773  * @caps: a #GstCaps
774  *
775  * Gets the number of structures contained in @caps.
776  *
777  * Returns: the number of structures that @caps contains
778  */
779 guint
780 gst_caps_get_size (const GstCaps * caps)
781 {
782   g_return_val_if_fail (GST_IS_CAPS (caps), 0);
783
784   return GST_CAPS_LEN (caps);
785 }
786
787 /**
788  * gst_caps_get_structure:
789  * @caps: a #GstCaps
790  * @index: the index of the structure
791  *
792  * Finds the structure in @caps that has the index @index, and
793  * returns it.
794  *
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().
803  *
804  * You do not need to free or unref the structure returned, it
805  * belongs to the #GstCaps.
806  *
807  * Returns: (transfer none): a pointer to the #GstStructure corresponding
808  *     to @index
809  */
810 GstStructure *
811 gst_caps_get_structure (const GstCaps * caps, guint index)
812 {
813   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
814   g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
815
816   return gst_caps_get_structure_unchecked (caps, index);
817 }
818
819 /**
820  * gst_caps_get_features:
821  * @caps: a #GstCaps
822  * @index: the index of the structure
823  *
824  * Finds the features in @caps that has the index @index, and
825  * returns it.
826  *
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().
835  *
836  * You do not need to free or unref the structure returned, it
837  * belongs to the #GstCaps.
838  *
839  * Returns: (transfer none): a pointer to the #GstCapsFeatures corresponding
840  *     to @index
841  *
842  * Since: 1.2
843  */
844 GstCapsFeatures *
845 gst_caps_get_features (const GstCaps * caps, guint index)
846 {
847   GstCapsFeatures *features;
848
849   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
850   g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
851
852   features = gst_caps_get_features_unchecked (caps, index);
853   if (!features)
854     features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
855
856   return features;
857 }
858
859 /**
860  * gst_caps_set_features:
861  * @caps: a #GstCaps
862  * @index: the index of the structure
863  * @features: (allow-none) (transfer full): the #GstFeatures to set
864  *
865  * Sets the #GstCapsFeatures @features for the structure at @index.
866  *
867  * Since: 1.2
868  */
869 void
870 gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
871 {
872   GstCapsFeatures **storage, *old;
873
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));
877
878   storage = &gst_caps_get_features_unchecked (caps, index);
879   old = *storage;
880   *storage = features;
881
882   if (features)
883     gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
884
885   if (old)
886     gst_caps_features_free (old);
887 }
888
889 /**
890  * gst_caps_copy_nth:
891  * @caps: the #GstCaps to copy
892  * @nth: the nth structure to copy
893  *
894  * Creates a new #GstCaps and appends a copy of the nth structure
895  * contained in @caps.
896  *
897  * Returns: (transfer full): the new #GstCaps
898  */
899 GstCaps *
900 gst_caps_copy_nth (const GstCaps * caps, guint nth)
901 {
902   GstCaps *newcaps;
903   GstStructure *structure;
904   GstCapsFeatures *features;
905
906   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
907
908   newcaps = gst_caps_new_empty ();
909   GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
910
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));
917   }
918
919   return newcaps;
920 }
921
922 /**
923  * gst_caps_truncate:
924  * @caps: (transfer full): the #GstCaps to truncate
925  *
926  * Discard all but the first structure from @caps. Useful when
927  * fixating.
928  *
929  * Returns: (transfer full): truncated caps
930  */
931 GstCaps *
932 gst_caps_truncate (GstCaps * caps)
933 {
934   gint i;
935
936   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
937
938   i = GST_CAPS_LEN (caps) - 1;
939   if (i == 0)
940     return caps;
941
942   caps = gst_caps_make_writable (caps);
943   while (i > 0)
944     gst_caps_remove_structure (caps, i--);
945
946   return caps;
947 }
948
949 /**
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
954  *
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.
958  **/
959 void
960 gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
961 {
962   guint i, len;
963
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));
968
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);
973   }
974 }
975
976 /**
977  * gst_caps_set_simple_valist:
978  * @caps: the #GstCaps to set
979  * @field: first field to set
980  * @varargs: additional parameters
981  *
982  * Sets fields in a #GstCaps.  The arguments must be passed in the same
983  * manner as gst_structure_set(), and be NULL-terminated.
984  */
985 void
986 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
987 {
988   GValue value = { 0, };
989
990   g_return_if_fail (GST_IS_CAPS (caps));
991   g_return_if_fail (IS_WRITABLE (caps));
992
993   while (field) {
994     GType type;
995     char *err;
996
997     type = va_arg (varargs, GType);
998
999     G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
1000     if (G_UNLIKELY (err)) {
1001       g_critical ("%s", err);
1002       return;
1003     }
1004
1005     gst_caps_set_value (caps, field, &value);
1006
1007     g_value_unset (&value);
1008
1009     field = va_arg (varargs, const gchar *);
1010   }
1011 }
1012
1013 /**
1014  * gst_caps_set_simple:
1015  * @caps: the #GstCaps to set
1016  * @field: first field to set
1017  * @...: additional parameters
1018  *
1019  * Sets fields in a #GstCaps.  The arguments must be passed in the same
1020  * manner as gst_structure_set(), and be NULL-terminated.
1021  */
1022 void
1023 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
1024 {
1025   va_list var_args;
1026
1027   g_return_if_fail (GST_IS_CAPS (caps));
1028   g_return_if_fail (IS_WRITABLE (caps));
1029
1030   va_start (var_args, field);
1031   gst_caps_set_simple_valist (caps, field, var_args);
1032   va_end (var_args);
1033 }
1034
1035 /* tests */
1036
1037 /**
1038  * gst_caps_is_any:
1039  * @caps: the #GstCaps to test
1040  *
1041  * Determines if @caps represents any media format.
1042  *
1043  * Returns: TRUE if @caps represents any format.
1044  */
1045 gboolean
1046 gst_caps_is_any (const GstCaps * caps)
1047 {
1048   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1049
1050   return (CAPS_IS_ANY (caps));
1051 }
1052
1053 /**
1054  * gst_caps_is_empty:
1055  * @caps: the #GstCaps to test
1056  *
1057  * Determines if @caps represents no media formats.
1058  *
1059  * Returns: TRUE if @caps represents no formats.
1060  */
1061 gboolean
1062 gst_caps_is_empty (const GstCaps * caps)
1063 {
1064   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1065
1066   if (CAPS_IS_ANY (caps))
1067     return FALSE;
1068
1069   return CAPS_IS_EMPTY_SIMPLE (caps);
1070 }
1071
1072 static gboolean
1073 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
1074     gpointer unused)
1075 {
1076   return gst_value_is_fixed (value);
1077 }
1078
1079 /**
1080  * gst_caps_is_fixed:
1081  * @caps: the #GstCaps to test
1082  *
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.
1086  *
1087  * Returns: TRUE if @caps is fixed
1088  */
1089 gboolean
1090 gst_caps_is_fixed (const GstCaps * caps)
1091 {
1092   GstStructure *structure;
1093   GstCapsFeatures *features;
1094
1095   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1096
1097   if (GST_CAPS_LEN (caps) != 1)
1098     return FALSE;
1099
1100   features = gst_caps_get_features (caps, 0);
1101   if (features && gst_caps_features_is_any (features))
1102     return FALSE;
1103
1104   structure = gst_caps_get_structure_unchecked (caps, 0);
1105
1106   return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
1107 }
1108
1109 /**
1110  * gst_caps_is_equal_fixed:
1111  * @caps1: the #GstCaps to test
1112  * @caps2: the #GstCaps to test
1113  *
1114  * Tests if two #GstCaps are equal.  This function only works on fixed
1115  * #GstCaps.
1116  *
1117  * Returns: TRUE if the arguments represent the same format
1118  */
1119 gboolean
1120 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
1121 {
1122   GstStructure *struct1, *struct2;
1123   GstCapsFeatures *features1, *features2;
1124
1125   g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
1126   g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
1127
1128   struct1 = gst_caps_get_structure_unchecked (caps1, 0);
1129   features1 = gst_caps_get_features_unchecked (caps1, 0);
1130   if (!features1)
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);
1134   if (!features2)
1135     features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1136
1137   return gst_structure_is_equal (struct1, struct2) &&
1138       gst_caps_features_is_equal (features1, features2);
1139 }
1140
1141 /**
1142  * gst_caps_is_always_compatible:
1143  * @caps1: the #GstCaps to test
1144  * @caps2: the #GstCaps to test
1145  *
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.
1149  *
1150  * Returns: TRUE if @caps1 is a subset of @caps2.
1151  */
1152 gboolean
1153 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
1154 {
1155   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1156   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1157
1158   return gst_caps_is_subset (caps1, caps2);
1159 }
1160
1161 /**
1162  * gst_caps_is_subset:
1163  * @subset: a #GstCaps
1164  * @superset: a potentially greater #GstCaps
1165  *
1166  * Checks if all caps represented by @subset are also represented by @superset.
1167  *
1168  * Returns: %TRUE if @subset is a subset of @superset
1169  */
1170 gboolean
1171 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
1172 {
1173   GstStructure *s1, *s2;
1174   GstCapsFeatures *f1, *f2;
1175   gboolean ret = TRUE;
1176   gint i, j;
1177
1178   g_return_val_if_fail (subset != NULL, FALSE);
1179   g_return_val_if_fail (superset != NULL, FALSE);
1180
1181   if (CAPS_IS_EMPTY (subset) || CAPS_IS_ANY (superset))
1182     return TRUE;
1183   if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
1184     return FALSE;
1185
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);
1190       if (!f1)
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);
1194       if (!f2)
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 */
1201         break;
1202       }
1203     }
1204     /* If we found no superset for this subset structure
1205      * we return FALSE immediately */
1206     if (j == -1) {
1207       ret = FALSE;
1208       break;
1209     }
1210   }
1211
1212   return ret;
1213 }
1214
1215 /**
1216  * gst_caps_is_subset_structure:
1217  * @caps: a #GstCaps
1218  * @structure: a potential #GstStructure subset of @caps
1219  *
1220  * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1221  * for more information.
1222  *
1223  * Returns: %TRUE if @structure is a subset of @caps
1224  */
1225 gboolean
1226 gst_caps_is_subset_structure (const GstCaps * caps,
1227     const GstStructure * structure)
1228 {
1229   GstStructure *s;
1230   gint i;
1231
1232   g_return_val_if_fail (caps != NULL, FALSE);
1233   g_return_val_if_fail (structure != NULL, FALSE);
1234
1235   if (CAPS_IS_ANY (caps))
1236     return TRUE;
1237   if (CAPS_IS_EMPTY (caps))
1238     return FALSE;
1239
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 */
1244       return TRUE;
1245     }
1246   }
1247
1248   return FALSE;
1249 }
1250
1251 /**
1252  * gst_caps_is_subset_structure_full:
1253  * @caps: a #GstCaps
1254  * @structure: a potential #GstStructure subset of @caps
1255  * @features: (allow-none): a #GstCapsFeatures for @structure
1256  *
1257  * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
1258  * for more information.
1259  *
1260  * Returns: %TRUE if @structure is a subset of @caps
1261  *
1262  * Since: 1.2
1263  */
1264 gboolean
1265 gst_caps_is_subset_structure_full (const GstCaps * caps,
1266     const GstStructure * structure, const GstCapsFeatures * features)
1267 {
1268   GstStructure *s;
1269   GstCapsFeatures *f;
1270   gint i;
1271
1272   g_return_val_if_fail (caps != NULL, FALSE);
1273   g_return_val_if_fail (structure != NULL, FALSE);
1274
1275   if (CAPS_IS_ANY (caps))
1276     return TRUE;
1277   if (CAPS_IS_EMPTY (caps))
1278     return FALSE;
1279
1280   if (!features)
1281     features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1282
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);
1286     if (!f)
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 */
1292       return TRUE;
1293     }
1294   }
1295
1296   return FALSE;
1297 }
1298
1299 /**
1300  * gst_caps_is_equal:
1301  * @caps1: a #GstCaps
1302  * @caps2: another #GstCaps
1303  *
1304  * Checks if the given caps represent the same set of caps.
1305  *
1306  * Returns: TRUE if both caps are equal.
1307  */
1308 gboolean
1309 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
1310 {
1311   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1312   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1313
1314   if (G_UNLIKELY (caps1 == caps2))
1315     return TRUE;
1316
1317   if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
1318     return gst_caps_is_equal_fixed (caps1, caps2);
1319
1320   return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
1321 }
1322
1323 /**
1324  * gst_caps_is_strictly_equal:
1325  * @caps1: a #GstCaps
1326  * @caps2: another #GstCaps
1327  *
1328  * Checks if the given caps are exactly the same set of caps.
1329  *
1330  * Returns: TRUE if both caps are strictly equal.
1331  */
1332 gboolean
1333 gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
1334 {
1335   int i;
1336   GstStructure *s1, *s2;
1337   GstCapsFeatures *f1, *f2;
1338
1339   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1340   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1341
1342   if (G_UNLIKELY (caps1 == caps2))
1343     return TRUE;
1344
1345   if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
1346     return FALSE;
1347
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);
1351     if (!f1)
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);
1355     if (!f2)
1356       f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1357
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))
1361       return FALSE;
1362   }
1363
1364   return TRUE;
1365 }
1366
1367 /* intersect operation */
1368
1369 /**
1370  * gst_caps_can_intersect:
1371  * @caps1: a #GstCaps to intersect
1372  * @caps2: a #GstCaps to intersect
1373  *
1374  * Tries intersecting @caps1 and @caps2 and reports whether the result would not
1375  * be empty
1376  *
1377  * Returns: %TRUE if intersection would be not empty
1378  */
1379 gboolean
1380 gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
1381 {
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;
1388
1389   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
1390   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
1391
1392   /* caps are exactly the same pointers */
1393   if (G_UNLIKELY (caps1 == caps2))
1394     return TRUE;
1395
1396   /* empty caps on either side, return empty */
1397   if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
1398     return FALSE;
1399
1400   /* one of the caps is any */
1401   if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)))
1402     return TRUE;
1403
1404   /* run zigzag on top line then right line, this preserves the caps order
1405    * much better than a simple loop.
1406    *
1407    * This algorithm zigzags over the caps structures as demonstrated in
1408    * the following matrix:
1409    *
1410    *          caps1                              0  1  2  3
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
1415    *
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.
1420    */
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
1430      * border */
1431     while (k < len2) {
1432       struct1 = gst_caps_get_structure_unchecked (caps1, j);
1433       features1 = gst_caps_get_features_unchecked (caps1, j);
1434       if (!features1)
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);
1438       if (!features2)
1439         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1440       if (gst_caps_features_is_equal (features1, features2) &&
1441           gst_structure_can_intersect (struct1, struct2)) {
1442         return TRUE;
1443       }
1444       /* move down left */
1445       k++;
1446       if (G_UNLIKELY (j == 0))
1447         break;                  /* so we don't roll back to G_MAXUINT */
1448       j--;
1449     }
1450   }
1451
1452   return FALSE;
1453 }
1454
1455 static GstCaps *
1456 gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
1457 {
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;
1464   GstCaps *dest;
1465   GstStructure *istruct;
1466
1467   /* caps are exactly the same pointers, just copy one caps */
1468   if (G_UNLIKELY (caps1 == caps2))
1469     return gst_caps_ref (caps1);
1470
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);
1474
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);
1478
1479   if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1480     return gst_caps_ref (caps1);
1481
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.
1485    *
1486    * This algorithm zigzags over the caps structures as demonstrated in
1487    * the following matrix:
1488    *
1489    *          caps1
1490    *       +-------------
1491    *       | 1  2  4  7
1492    * caps2 | 3  5  8 10
1493    *       | 6  9 11 12
1494    *
1495    * First we iterate over the caps1 structures (top line) intersecting
1496    * the structures diagonally down, then we iterate over the caps2
1497    * structures.
1498    */
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
1508      * border */
1509     while (k < len2) {
1510       struct1 = gst_caps_get_structure_unchecked (caps1, j);
1511       features1 = gst_caps_get_features_unchecked (caps1, j);
1512       if (!features1)
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);
1516       if (!features2)
1517         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1518       if (gst_caps_features_is_equal (features1, features2)) {
1519         istruct = gst_structure_intersect (struct1, struct2);
1520         if (istruct) {
1521           if (gst_caps_features_is_any (features1))
1522             dest =
1523                 gst_caps_merge_structure_full (dest, istruct,
1524                 gst_caps_features_copy_conditional (features2));
1525           else
1526             dest =
1527                 gst_caps_merge_structure_full (dest, istruct,
1528                 gst_caps_features_copy_conditional (features1));
1529         }
1530       }
1531       /* move down left */
1532       k++;
1533       if (G_UNLIKELY (j == 0))
1534         break;                  /* so we don't roll back to G_MAXUINT */
1535       j--;
1536     }
1537   }
1538   return dest;
1539 }
1540
1541 /**
1542  * gst_caps_intersect_first:
1543  * @caps1: a #GstCaps to intersect
1544  * @caps2: a #GstCaps to intersect
1545  *
1546  * Creates a new #GstCaps that contains all the formats that are common
1547  * to both @caps1 and @caps2.
1548  *
1549  * Unlike @gst_caps_intersect, the returned caps will be ordered in a similar
1550  * fashion as @caps1.
1551  *
1552  * Returns: the new #GstCaps
1553  */
1554 static GstCaps *
1555 gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
1556 {
1557   guint i;
1558   guint j, len1, len2;
1559   GstStructure *struct1;
1560   GstStructure *struct2;
1561   GstCapsFeatures *features1;
1562   GstCapsFeatures *features2;
1563   GstCaps *dest;
1564   GstStructure *istruct;
1565
1566   /* caps are exactly the same pointers, just copy one caps */
1567   if (G_UNLIKELY (caps1 == caps2))
1568     return gst_caps_ref (caps1);
1569
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);
1573
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);
1577
1578   if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
1579     return gst_caps_ref (caps1);
1580
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);
1587     if (!features1)
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);
1592       if (!features2)
1593         features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1594       if (gst_caps_features_is_equal (features1, features2)) {
1595         istruct = gst_structure_intersect (struct1, struct2);
1596         if (istruct) {
1597           if (gst_caps_features_is_any (features1))
1598             dest =
1599                 gst_caps_merge_structure_full (dest, istruct,
1600                 gst_caps_features_copy_conditional (features2));
1601           else
1602             dest =
1603                 gst_caps_merge_structure_full (dest, istruct,
1604                 gst_caps_features_copy_conditional (features1));
1605         }
1606       }
1607     }
1608   }
1609
1610   return dest;
1611 }
1612
1613 /**
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
1618  *
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
1621  * used.
1622  *
1623  * Returns: the new #GstCaps
1624  */
1625 GstCaps *
1626 gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
1627     GstCapsIntersectMode mode)
1628 {
1629   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
1630   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
1631
1632   switch (mode) {
1633     case GST_CAPS_INTERSECT_FIRST:
1634       return gst_caps_intersect_first (caps1, caps2);
1635     default:
1636       g_warning ("Unknown caps intersect mode: %d", mode);
1637       /* fallthrough */
1638     case GST_CAPS_INTERSECT_ZIG_ZAG:
1639       return gst_caps_intersect_zig_zag (caps1, caps2);
1640   }
1641 }
1642
1643 /**
1644  * gst_caps_intersect:
1645  * @caps1: a #GstCaps to intersect
1646  * @caps2: a #GstCaps to intersect
1647  *
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.
1650  *
1651  * Returns: the new #GstCaps
1652  */
1653 GstCaps *
1654 gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
1655 {
1656   return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
1657 }
1658
1659 /* subtract operation */
1660
1661 typedef struct
1662 {
1663   const GstStructure *subtract_from;
1664   GSList *put_into;
1665 } SubtractionEntry;
1666
1667 static gboolean
1668 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
1669     gpointer user_data)
1670 {
1671   SubtractionEntry *e = user_data;
1672   GValue subtraction = { 0, };
1673   const GValue *other;
1674   GstStructure *structure;
1675
1676   other = gst_structure_id_get_value (e->subtract_from, field_id);
1677
1678   if (!other) {
1679     return FALSE;
1680   }
1681
1682   if (!gst_value_subtract (&subtraction, other, value))
1683     return TRUE;
1684
1685   if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
1686     g_value_unset (&subtraction);
1687     return FALSE;
1688   } else {
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);
1692     return TRUE;
1693   }
1694 }
1695
1696 static gboolean
1697 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
1698     const GstStructure * subtrahend)
1699 {
1700   SubtractionEntry e;
1701   gboolean ret;
1702
1703   e.subtract_from = minuend;
1704   e.put_into = NULL;
1705   ret = gst_structure_foreach ((GstStructure *) subtrahend,
1706       gst_caps_structure_subtract_field, &e);
1707
1708   if (ret) {
1709     *into = e.put_into;
1710   } else {
1711     GSList *walk;
1712
1713     for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
1714       gst_structure_free (walk->data);
1715     }
1716     g_slist_free (e.put_into);
1717   }
1718
1719   return ret;
1720 }
1721
1722 /**
1723  * gst_caps_subtract:
1724  * @minuend: #GstCaps to subtract from
1725  * @subtrahend: #GstCaps to subtract
1726  *
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>
1730  *
1731  * Returns: the resulting caps
1732  */
1733 GstCaps *
1734 gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
1735 {
1736   guint i, j, sublen;
1737   GstStructure *min;
1738   GstStructure *sub;
1739   GstCapsFeatures *min_f, *sub_f;
1740   GstCaps *dest = NULL, *src;
1741
1742   g_return_val_if_fail (minuend != NULL, NULL);
1743   g_return_val_if_fail (subtrahend != NULL, NULL);
1744
1745   if (CAPS_IS_EMPTY (minuend) || CAPS_IS_ANY (subtrahend)) {
1746     return gst_caps_new_empty ();
1747   }
1748
1749   if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
1750     return gst_caps_ref (minuend);
1751
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. */
1757
1758   g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
1759   sublen = GST_CAPS_LEN (subtrahend);
1760   g_assert (sublen > 0);
1761
1762   src = _gst_caps_copy (minuend);
1763   for (i = 0; i < sublen; i++) {
1764     guint srclen;
1765
1766     sub = gst_caps_get_structure_unchecked (subtrahend, i);
1767     sub_f = gst_caps_get_features_unchecked (subtrahend, i);
1768     if (!sub_f)
1769       sub_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1770     if (dest) {
1771       gst_caps_unref (src);
1772       src = dest;
1773     }
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);
1779       if (!min_f)
1780         min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
1781
1782       /* Same reason as above for ANY caps */
1783       g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
1784
1785       if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
1786           gst_caps_features_is_equal (min_f, sub_f)) {
1787         GSList *list;
1788
1789         if (gst_caps_structure_subtract (&list, min, sub)) {
1790           GSList *walk;
1791
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));
1796           }
1797           g_slist_free (list);
1798         } else {
1799           gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1800               gst_caps_features_copy_conditional (min_f));
1801         }
1802       } else {
1803         gst_caps_append_structure_unchecked (dest, gst_structure_copy (min),
1804             gst_caps_features_copy_conditional (min_f));
1805       }
1806     }
1807
1808     if (CAPS_IS_EMPTY_SIMPLE (dest)) {
1809       gst_caps_unref (src);
1810       return dest;
1811     }
1812   }
1813
1814   gst_caps_unref (src);
1815   dest = gst_caps_simplify (dest);
1816
1817   return dest;
1818 }
1819
1820 /* normalize/simplify operations */
1821
1822 typedef struct _NormalizeForeach
1823 {
1824   GstCaps *caps;
1825   GstStructure *structure;
1826   GstCapsFeatures *features;
1827 } NormalizeForeach;
1828
1829 static gboolean
1830 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
1831 {
1832   NormalizeForeach *nf = (NormalizeForeach *) ptr;
1833   GValue val = { 0 };
1834   guint i;
1835
1836   if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
1837     guint len = gst_value_list_get_size (value);
1838
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);
1842
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));
1846     }
1847
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);
1850     return FALSE;
1851   }
1852
1853   return TRUE;
1854 }
1855
1856 /**
1857  * gst_caps_normalize:
1858  * @caps: (transfer full): a #GstCaps to normalize
1859  *
1860  * Returns a #GstCaps that represents the same set of formats as
1861  * @caps, but contains no lists.  Each list is expanded into separate
1862  * @GstStructures.
1863  *
1864  * This function takes ownership of @caps.
1865  *
1866  * Returns: (transfer full): the normalized #GstCaps
1867  */
1868 GstCaps *
1869 gst_caps_normalize (GstCaps * caps)
1870 {
1871   NormalizeForeach nf;
1872   guint i;
1873
1874   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
1875
1876   caps = gst_caps_make_writable (caps);
1877   nf.caps = caps;
1878
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));
1884   }
1885
1886   return nf.caps;
1887 }
1888
1889 static gint
1890 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
1891 {
1892   gint ret;
1893   const GstStructure *struct1 = ((const GstCapsArrayElement *) one)->structure;
1894   const GstStructure *struct2 = ((const GstCapsArrayElement *) two)->structure;
1895
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));
1900
1901   if (ret)
1902     return ret;
1903
1904   return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
1905 }
1906
1907 typedef struct
1908 {
1909   GQuark name;
1910   GValue value;
1911   GstStructure *compare;
1912 } UnionField;
1913
1914 static gboolean
1915 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
1916     gpointer user_data)
1917 {
1918   UnionField *u = user_data;
1919   const GValue *val = gst_structure_id_get_value (u->compare, field_id);
1920
1921   if (!val) {
1922     if (u->name)
1923       g_value_unset (&u->value);
1924     return FALSE;
1925   }
1926
1927   if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
1928     return TRUE;
1929
1930   if (u->name) {
1931     g_value_unset (&u->value);
1932     return FALSE;
1933   }
1934
1935   u->name = field_id;
1936   gst_value_union (&u->value, val, value);
1937
1938   return TRUE;
1939 }
1940
1941 static gboolean
1942 gst_caps_structure_simplify (GstStructure ** result,
1943     GstStructure * simplify, GstStructure * compare)
1944 {
1945   GSList *list;
1946   UnionField field = { 0, {0,}, NULL };
1947
1948   /* try to subtract to get a real subset */
1949   if (gst_caps_structure_subtract (&list, simplify, compare)) {
1950     if (list == NULL) {         /* no result */
1951       *result = NULL;
1952       return TRUE;
1953     } else if (list->next == NULL) {    /* one result */
1954       *result = list->data;
1955       g_slist_free (list);
1956       return TRUE;
1957     } else {                    /* multiple results */
1958       g_slist_foreach (list, (GFunc) gst_structure_free, NULL);
1959       g_slist_free (list);
1960       list = NULL;
1961     }
1962   }
1963
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;
1969
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);
1975         *result = NULL;
1976         ret = TRUE;
1977       } else {
1978         g_value_unset (&field.value);
1979       }
1980     } else
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.");
1986     } else {
1987       gchar *one = gst_structure_to_string (simplify);
1988       gchar *two = gst_structure_to_string (compare);
1989
1990       GST_ERROR
1991           ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
1992           one, two);
1993       g_free (one);
1994       g_free (two);
1995     }
1996     return ret;
1997   }
1998
1999   return FALSE;
2000 }
2001
2002 static void
2003 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
2004     GstStructure * new, gint i)
2005 {
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;
2010 }
2011
2012 /**
2013  * gst_caps_simplify:
2014  * @caps: (transfer full): a #GstCaps to simplify
2015  *
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.
2020  *
2021  * This method does not preserve the original order of @caps.
2022  *
2023  * Returns: The simplified caps.
2024  */
2025 GstCaps *
2026 gst_caps_simplify (GstCaps * caps)
2027 {
2028   GstStructure *simplify, *compare, *result = NULL;
2029   GstCapsFeatures *simplify_f, *compare_f;
2030   gint i, j, start;
2031
2032   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2033
2034   start = GST_CAPS_LEN (caps) - 1;
2035   /* one caps, already as simple as can be */
2036   if (start == 0)
2037     return caps;
2038
2039   caps = gst_caps_make_writable (caps);
2040
2041   g_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
2042
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);
2046     if (!simplify_f)
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);
2050     if (!compare_f)
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))
2055       start = i;
2056     for (j = start; j >= 0; j--) {
2057       if (j == i)
2058         continue;
2059       compare = gst_caps_get_structure_unchecked (caps, j);
2060       compare_f = gst_caps_get_features_unchecked (caps, j);
2061       if (!compare_f)
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)) {
2066         break;
2067       }
2068       if (gst_caps_structure_simplify (&result, simplify, compare)) {
2069         if (result) {
2070           gst_caps_switch_structures (caps, simplify, result, i);
2071           simplify = result;
2072         } else {
2073           gst_caps_remove_structure (caps, i);
2074           start--;
2075           break;
2076         }
2077       }
2078     }
2079   }
2080   return caps;
2081 }
2082
2083 /**
2084  * gst_caps_fixate:
2085  * @caps: (transfer full): a #GstCaps to fixate
2086  *
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().
2090  *
2091  * Returns: (transfer full): the fixated caps
2092  */
2093 GstCaps *
2094 gst_caps_fixate (GstCaps * caps)
2095 {
2096   GstStructure *s;
2097   GstCapsFeatures *f;
2098
2099   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
2100
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);
2106
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);
2112   }
2113
2114   return caps;
2115 }
2116
2117 /* utility */
2118
2119 /**
2120  * gst_caps_to_string:
2121  * @caps: a #GstCaps
2122  *
2123  * Converts @caps to a string representation.  This string representation
2124  * can be converted back to a #GstCaps by gst_caps_from_string().
2125  *
2126  * For debugging purposes its easier to do something like this:
2127  * |[
2128  * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
2129  * ]|
2130  * This prints the caps in human readable form.
2131  *
2132  * Returns: (transfer full): a newly allocated string representing @caps.
2133  */
2134 gchar *
2135 gst_caps_to_string (const GstCaps * caps)
2136 {
2137   guint i, slen, clen;
2138   GString *s;
2139
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.  */
2145
2146   if (caps == NULL) {
2147     return g_strdup ("NULL");
2148   }
2149   if (CAPS_IS_ANY (caps)) {
2150     return g_strdup ("ANY");
2151   }
2152   if (CAPS_IS_EMPTY_SIMPLE (caps)) {
2153     return g_strdup ("EMPTY");
2154   }
2155
2156   /* estimate a rough string length to avoid unnecessary reallocs in GString */
2157   slen = 0;
2158   clen = GST_CAPS_LEN (caps);
2159   for (i = 0; i < clen; i++) {
2160     GstCapsFeatures *f;
2161
2162     slen +=
2163         STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked
2164         (caps, i));
2165     f = gst_caps_get_features_unchecked (caps, i);
2166     if (f)
2167       slen += FEATURES_ESTIMATED_STRING_LEN (f);
2168   }
2169
2170   s = g_string_sized_new (slen);
2171   for (i = 0; i < clen; i++) {
2172     GstStructure *structure;
2173     GstCapsFeatures *features;
2174
2175     if (i > 0) {
2176       /* ';' is now added by gst_structure_to_string */
2177       g_string_append_c (s, ' ');
2178     }
2179
2180     structure = gst_caps_get_structure_unchecked (caps, i);
2181     features = gst_caps_get_features_unchecked (caps, i);
2182
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, ')');
2190     }
2191     priv_gst_structure_append_to_gstring (structure, s);
2192   }
2193   if (s->len && s->str[s->len - 1] == ';') {
2194     /* remove latest ';' */
2195     s->str[--s->len] = '\0';
2196   }
2197   return g_string_free (s, FALSE);
2198 }
2199
2200 static gboolean
2201 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
2202 {
2203   GstStructure *structure;
2204   gchar *s, *copy, *end, *next, save;
2205
2206   if (strcmp ("ANY", string) == 0) {
2207     GST_CAPS_FLAGS (caps) = GST_CAPS_FLAG_ANY;
2208     return TRUE;
2209   }
2210
2211   if (strcmp ("EMPTY", string) == 0 || strcmp ("NONE", string) == 0) {
2212     return TRUE;
2213   }
2214
2215   copy = s = g_strdup (string);
2216   do {
2217     GstCapsFeatures *features = NULL;
2218
2219     while (g_ascii_isspace (*s))
2220       s++;
2221     if (*s == '\0') {
2222       break;
2223     }
2224
2225     if (!priv_gst_structure_parse_name (s, &s, &end, &next)) {
2226       g_free (copy);
2227       return FALSE;
2228     }
2229
2230     save = *end;
2231     *end = '\0';
2232     structure = gst_structure_new_empty (s);
2233     *end = save;
2234
2235     if (structure == NULL) {
2236       g_free (copy);
2237       return FALSE;
2238     }
2239
2240     s = next;
2241
2242     if (*s == '\0') {
2243       goto append;
2244     }
2245
2246     if (*s == '(') {
2247       s++;
2248       end = s;
2249
2250       while (TRUE) {
2251         if (*end == '\0') {
2252           break;
2253         } else if (*end == ')') {
2254           break;
2255         } else {
2256           end++;
2257         }
2258       }
2259
2260       save = *end;
2261       *end = '\0';
2262       features = gst_caps_features_from_string (s);
2263       if (!features) {
2264         gst_structure_free (structure);
2265         g_free (copy);
2266         return FALSE;
2267       }
2268       *end = save;
2269       s = end;
2270       if (save == ')')
2271         s++;
2272     }
2273
2274     if (*s == '\0') {
2275       goto append;
2276     }
2277
2278     if (!priv_gst_structure_parse_fields (s, &s, structure)) {
2279       gst_structure_free (structure);
2280       g_free (copy);
2281       return FALSE;
2282     }
2283
2284   append:
2285     gst_caps_append_structure_unchecked (caps, structure, features);
2286     if (*s == '\0')
2287       break;
2288   } while (TRUE);
2289
2290   g_free (copy);
2291
2292   return TRUE;
2293 }
2294
2295 /**
2296  * gst_caps_from_string:
2297  * @string: a string to convert to #GstCaps
2298  *
2299  * Converts @caps from a string representation.
2300  *
2301  * Returns: (transfer full): a newly allocated #GstCaps
2302  */
2303 GstCaps *
2304 gst_caps_from_string (const gchar * string)
2305 {
2306   GstCaps *caps;
2307
2308   g_return_val_if_fail (string, FALSE);
2309
2310   caps = gst_caps_new_empty ();
2311   if (gst_caps_from_string_inplace (caps, string)) {
2312     return caps;
2313   } else {
2314     gst_caps_unref (caps);
2315     return NULL;
2316   }
2317 }
2318
2319 static void
2320 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
2321 {
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));
2327
2328   g_value_take_string (dest_value,
2329       gst_caps_to_string (gst_value_get_caps (src_value)));
2330 }