gstreamer_core/gst/gstcaps.c
changeset 0 0e761a78d257
child 8 4a7fac7dd34a
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     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., 59 Temple Place - Suite 330,
       
    17  * Boston, MA 02111-1307, USA.
       
    18  */
       
    19 
       
    20 /**
       
    21  * SECTION:gstcaps
       
    22  * @short_description: Structure describing sets of media formats
       
    23  * @see_also: #GstStructure
       
    24  *
       
    25  * Caps (capabilities) are lighweight 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_get_caps() pad
       
    33  * function. This function describes the possible types that the pad can
       
    34  * handle or produce at runtime.
       
    35  *
       
    36  * Caps are also attached to buffers to describe to content of the data
       
    37  * pointed to by the buffer with gst_buffer_set_caps(). Caps attached to
       
    38  * a #GstBuffer allow for format negotiation upstream and downstream.
       
    39  *
       
    40  * A #GstCaps can be constructed with the following code fragment:
       
    41  *
       
    42  * <example>
       
    43  *  <title>Creating caps</title>
       
    44  *  <programlisting>
       
    45  *  GstCaps *caps;
       
    46  *  caps = gst_caps_new_simple ("video/x-raw-yuv",
       
    47  *       "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
       
    48  *       "framerate", GST_TYPE_FRACTION, 25, 1,
       
    49  *       "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
       
    50  *       "width", G_TYPE_INT, 320,
       
    51  *       "height", G_TYPE_INT, 240,
       
    52  *       NULL);
       
    53  *  </programlisting>
       
    54  * </example>
       
    55  *
       
    56  * A #GstCaps is fixed when it has no properties with ranges or lists. Use
       
    57  * gst_caps_is_fixed() to test for fixed caps. Only fixed caps can be
       
    58  * set on a #GstPad or #GstBuffer.
       
    59  *
       
    60  * Various methods exist to work with the media types such as subtracting
       
    61  * or intersecting.
       
    62  *
       
    63  * Last reviewed on 2007-02-13 (0.10.10)
       
    64  */
       
    65 
       
    66 #ifdef HAVE_CONFIG_H
       
    67 #include "config.h"
       
    68 #endif
       
    69 #include <string.h>
       
    70 #include <signal.h>
       
    71 
       
    72 #include "gst_private.h"
       
    73 #include <gst/gst.h>
       
    74 
       
    75 #ifdef __SYMBIAN32__
       
    76 #include <glib_global.h>
       
    77 #endif
       
    78 
       
    79 #define DEBUG_REFCOUNT
       
    80 
       
    81 #define CAPS_POISON(caps) G_STMT_START{ \
       
    82   if (caps) { \
       
    83     GstCaps *_newcaps = gst_caps_copy (caps); \
       
    84     gst_caps_unref(caps); \
       
    85     caps = _newcaps; \
       
    86   } \
       
    87 } G_STMT_END
       
    88 #define STRUCTURE_POISON(structure) G_STMT_START{ \
       
    89   if (structure) { \
       
    90     GstStructure *_newstruct = gst_structure_copy (structure); \
       
    91     gst_structure_free(structure); \
       
    92     structure = _newstruct; \
       
    93   } \
       
    94 } G_STMT_END
       
    95 #define IS_WRITABLE(caps) \
       
    96   (g_atomic_int_get (&(caps)->refcount) == 1)
       
    97 
       
    98 #if GLIB_CHECK_VERSION (2, 10, 0)
       
    99 #define ALLOC_CAPS()    g_slice_new (GstCaps)
       
   100 #define FREE_CAPS(caps) g_slice_free (GstCaps, caps)
       
   101 #else
       
   102 #define ALLOC_CAPS()    g_new (GstCaps, 1)
       
   103 #define FREE_CAPS(caps) g_free (caps)
       
   104 #endif
       
   105 
       
   106 /* lock to protect multiple invocations of static caps to caps conversion */
       
   107 G_LOCK_DEFINE_STATIC (static_caps_lock);
       
   108 
       
   109 static void gst_caps_transform_to_string (const GValue * src_value,
       
   110     GValue * dest_value);
       
   111 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
       
   112     const gchar * string);
       
   113 static GstCaps *gst_caps_copy_conditional (GstCaps * src);
       
   114 #ifdef __SYMBIAN32__
       
   115 EXPORT_C
       
   116 #endif
       
   117 
       
   118 
       
   119 GType
       
   120 gst_caps_get_type (void)
       
   121 {
       
   122   static GType gst_caps_type = 0;
       
   123 
       
   124   if (G_UNLIKELY (gst_caps_type == 0)) {
       
   125     gst_caps_type = g_boxed_type_register_static ("GstCaps",
       
   126         (GBoxedCopyFunc) gst_caps_copy_conditional,
       
   127         (GBoxedFreeFunc) gst_caps_unref);
       
   128 
       
   129     g_value_register_transform_func (gst_caps_type,
       
   130         G_TYPE_STRING, gst_caps_transform_to_string);
       
   131   }
       
   132 
       
   133   return gst_caps_type;
       
   134 }
       
   135 
       
   136 /* creation/deletion */
       
   137 
       
   138 /**
       
   139  * gst_caps_new_empty:
       
   140  *
       
   141  * Creates a new #GstCaps that is empty.  That is, the returned
       
   142  * #GstCaps contains no media formats.
       
   143  * Caller is responsible for unreffing the returned caps.
       
   144  *
       
   145  * Returns: the new #GstCaps
       
   146  */
       
   147 #ifdef __SYMBIAN32__
       
   148 EXPORT_C
       
   149 #endif
       
   150 
       
   151 GstCaps *
       
   152 gst_caps_new_empty (void)
       
   153 {
       
   154   GstCaps *caps = ALLOC_CAPS ();
       
   155 
       
   156   caps->type = GST_TYPE_CAPS;
       
   157   caps->refcount = 1;
       
   158   caps->flags = 0;
       
   159   caps->structs = g_ptr_array_new ();
       
   160 
       
   161 #ifdef DEBUG_REFCOUNT
       
   162   GST_CAT_LOG (GST_CAT_CAPS, "created caps %p", caps);
       
   163 #endif
       
   164 
       
   165   return caps;
       
   166 }
       
   167 
       
   168 /**
       
   169  * gst_caps_new_any:
       
   170  *
       
   171  * Creates a new #GstCaps that indicates that it is compatible with
       
   172  * any media format.
       
   173  *
       
   174  * Returns: the new #GstCaps
       
   175  */
       
   176 #ifdef __SYMBIAN32__
       
   177 EXPORT_C
       
   178 #endif
       
   179 
       
   180 GstCaps *
       
   181 gst_caps_new_any (void)
       
   182 {
       
   183   GstCaps *caps = gst_caps_new_empty ();
       
   184 
       
   185   caps->flags = GST_CAPS_FLAGS_ANY;
       
   186 
       
   187   return caps;
       
   188 }
       
   189 
       
   190 /**
       
   191  * gst_caps_new_simple:
       
   192  * @media_type: the media type of the structure
       
   193  * @fieldname: first field to set
       
   194  * @...: additional arguments
       
   195  *
       
   196  * Creates a new #GstCaps that contains one #GstStructure.  The
       
   197  * structure is defined by the arguments, which have the same format
       
   198  * as gst_structure_new().
       
   199  * Caller is responsible for unreffing the returned caps.
       
   200  *
       
   201  * Returns: the new #GstCaps
       
   202  */
       
   203 #ifdef __SYMBIAN32__
       
   204 EXPORT_C
       
   205 #endif
       
   206 
       
   207 GstCaps *
       
   208 gst_caps_new_simple (const char *media_type, const char *fieldname, ...)
       
   209 {
       
   210   GstCaps *caps;
       
   211   GstStructure *structure;
       
   212   va_list var_args;
       
   213 
       
   214   caps = gst_caps_new_empty ();
       
   215 
       
   216   va_start (var_args, fieldname);
       
   217   structure = gst_structure_new_valist (media_type, fieldname, var_args);
       
   218   va_end (var_args);
       
   219 
       
   220   gst_caps_append_structure (caps, structure);
       
   221 
       
   222   return caps;
       
   223 }
       
   224 
       
   225 /**
       
   226  * gst_caps_new_full:
       
   227  * @struct1: the first structure to add
       
   228  * @...: additional structures to add
       
   229  *
       
   230  * Creates a new #GstCaps and adds all the structures listed as
       
   231  * arguments.  The list must be NULL-terminated.  The structures
       
   232  * are not copied; the returned #GstCaps owns the structures.
       
   233  *
       
   234  * Returns: the new #GstCaps
       
   235  */
       
   236 #ifdef __SYMBIAN32__
       
   237 EXPORT_C
       
   238 #endif
       
   239 
       
   240 GstCaps *
       
   241 gst_caps_new_full (GstStructure * struct1, ...)
       
   242 {
       
   243   GstCaps *caps;
       
   244   va_list var_args;
       
   245 
       
   246   va_start (var_args, struct1);
       
   247   caps = gst_caps_new_full_valist (struct1, var_args);
       
   248   va_end (var_args);
       
   249 
       
   250   return caps;
       
   251 }
       
   252 
       
   253 /**
       
   254  * gst_caps_new_full_valist:
       
   255  * @structure: the first structure to add
       
   256  * @var_args: additional structures to add
       
   257  *
       
   258  * Creates a new #GstCaps and adds all the structures listed as
       
   259  * arguments.  The list must be NULL-terminated.  The structures
       
   260  * are not copied; the returned #GstCaps owns the structures.
       
   261  *
       
   262  * Returns: the new #GstCaps
       
   263  */
       
   264 #ifdef __SYMBIAN32__
       
   265 EXPORT_C
       
   266 #endif
       
   267 
       
   268 GstCaps *
       
   269 gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
       
   270 {
       
   271   GstCaps *caps;
       
   272 
       
   273   caps = gst_caps_new_empty ();
       
   274 
       
   275   while (structure) {
       
   276     gst_caps_append_structure (caps, structure);
       
   277     structure = va_arg (var_args, GstStructure *);
       
   278   }
       
   279 
       
   280   return caps;
       
   281 }
       
   282 
       
   283 /**
       
   284  * gst_caps_copy:
       
   285  * @caps: the #GstCaps to copy
       
   286  *
       
   287  * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
       
   288  * refcount of 1, owned by the caller. The structures are copied as well.
       
   289  *
       
   290  * Note that this function is the semantic equivalent of a gst_caps_ref()
       
   291  * followed by a gst_caps_make_writable(). If you only want to hold on to a
       
   292  * reference to the data, you should use gst_caps_ref().
       
   293  *
       
   294  * When you are finished with the caps, call gst_caps_unref() on it.
       
   295  *
       
   296  * Returns: the new #GstCaps
       
   297  */
       
   298 #ifdef __SYMBIAN32__
       
   299 EXPORT_C
       
   300 #endif
       
   301 
       
   302 GstCaps *
       
   303 gst_caps_copy (const GstCaps * caps)
       
   304 {
       
   305   GstCaps *newcaps;
       
   306   GstStructure *structure;
       
   307   guint i;
       
   308 
       
   309   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
       
   310 
       
   311   newcaps = gst_caps_new_empty ();
       
   312   newcaps->flags = caps->flags;
       
   313 
       
   314   for (i = 0; i < caps->structs->len; i++) {
       
   315     structure = gst_caps_get_structure (caps, i);
       
   316     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
       
   317   }
       
   318 
       
   319   return newcaps;
       
   320 }
       
   321 
       
   322 static void
       
   323 _gst_caps_free (GstCaps * caps)
       
   324 {
       
   325   GstStructure *structure;
       
   326   guint i;
       
   327 
       
   328   /* The refcount must be 0, but since we're only called by gst_caps_unref,
       
   329    * don't bother testing. */
       
   330 
       
   331   for (i = 0; i < caps->structs->len; i++) {
       
   332     structure = (GstStructure *) gst_caps_get_structure (caps, i);
       
   333     gst_structure_set_parent_refcount (structure, NULL);
       
   334     gst_structure_free (structure);
       
   335   }
       
   336   g_ptr_array_free (caps->structs, TRUE);
       
   337 #ifdef USE_POISONING
       
   338   memset (caps, 0xff, sizeof (GstCaps));
       
   339 #endif
       
   340 
       
   341 #ifdef DEBUG_REFCOUNT
       
   342   GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
       
   343 #endif
       
   344   FREE_CAPS (caps);
       
   345 }
       
   346 
       
   347 /**
       
   348  * gst_caps_make_writable:
       
   349  * @caps: the #GstCaps to make writable
       
   350  *
       
   351  * Returns a writable copy of @caps.
       
   352  *
       
   353  * If there is only one reference count on @caps, the caller must be the owner,
       
   354  * and so this function will return the caps object unchanged. If on the other
       
   355  * hand there is more than one reference on the object, a new caps object will
       
   356  * be returned. The caller's reference on @caps will be removed, and instead the
       
   357  * caller will own a reference to the returned object.
       
   358  *
       
   359  * In short, this function unrefs the caps in the argument and refs the caps
       
   360  * that it returns. Don't access the argument after calling this function. See
       
   361  * also: gst_caps_ref().
       
   362  *
       
   363  * Returns: the same #GstCaps object.
       
   364  */
       
   365 #ifdef __SYMBIAN32__
       
   366 EXPORT_C
       
   367 #endif
       
   368 
       
   369 GstCaps *
       
   370 gst_caps_make_writable (GstCaps * caps)
       
   371 {
       
   372   GstCaps *copy;
       
   373 
       
   374   g_return_val_if_fail (caps != NULL, NULL);
       
   375 
       
   376   /* we are the only instance reffing this caps */
       
   377   if (g_atomic_int_get (&caps->refcount) == 1)
       
   378     return caps;
       
   379 
       
   380   /* else copy */
       
   381   copy = gst_caps_copy (caps);
       
   382   gst_caps_unref (caps);
       
   383 
       
   384   return copy;
       
   385 }
       
   386 
       
   387 /**
       
   388  * gst_caps_ref:
       
   389  * @caps: the #GstCaps to reference
       
   390  *
       
   391  * Add a reference to a #GstCaps object.
       
   392  *
       
   393  * From this point on, until the caller calls gst_caps_unref() or
       
   394  * gst_caps_make_writable(), it is guaranteed that the caps object will not
       
   395  * change. This means its structures won't change, etc. To use a #GstCaps
       
   396  * object, you must always have a refcount on it -- either the one made
       
   397  * implicitly by gst_caps_new(), or via taking one explicitly with this
       
   398  * function.
       
   399  *
       
   400  * Returns: the same #GstCaps object.
       
   401  */
       
   402 #ifdef __SYMBIAN32__
       
   403 EXPORT_C
       
   404 #endif
       
   405 
       
   406 GstCaps *
       
   407 gst_caps_ref (GstCaps * caps)
       
   408 {
       
   409   g_return_val_if_fail (caps != NULL, NULL);
       
   410 
       
   411 #ifdef DEBUG_REFCOUNT
       
   412   GST_CAT_LOG (GST_CAT_REFCOUNTING, "%p %d->%d", caps,
       
   413       GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) + 1);
       
   414 #endif
       
   415   g_return_val_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0, NULL);
       
   416 
       
   417   g_atomic_int_inc (&caps->refcount);
       
   418 
       
   419   return caps;
       
   420 }
       
   421 
       
   422 /**
       
   423  * gst_caps_unref:
       
   424  * @caps: the #GstCaps to unref
       
   425  *
       
   426  * Unref a #GstCaps and and free all its structures and the
       
   427  * structures' values when the refcount reaches 0.
       
   428  */
       
   429 #ifdef __SYMBIAN32__
       
   430 EXPORT_C
       
   431 #endif
       
   432 
       
   433 void
       
   434 gst_caps_unref (GstCaps * caps)
       
   435 {
       
   436   g_return_if_fail (caps != NULL);
       
   437 
       
   438 #ifdef DEBUG_REFCOUNT
       
   439   GST_CAT_LOG (GST_CAT_REFCOUNTING, "%p %d->%d", caps,
       
   440       GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) - 1);
       
   441 #endif
       
   442 
       
   443   g_return_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0);
       
   444 
       
   445   /* if we ended up with the refcount at zero, free the caps */
       
   446   if (G_UNLIKELY (g_atomic_int_dec_and_test (&caps->refcount)))
       
   447     _gst_caps_free (caps);
       
   448 }
       
   449 #ifdef __SYMBIAN32__
       
   450 EXPORT_C
       
   451 #endif
       
   452 
       
   453 
       
   454 GType
       
   455 gst_static_caps_get_type (void)
       
   456 {
       
   457   static GType staticcaps_type = 0;
       
   458 
       
   459   if (G_UNLIKELY (staticcaps_type == 0)) {
       
   460     staticcaps_type = g_pointer_type_register_static ("GstStaticCaps");
       
   461   }
       
   462   return staticcaps_type;
       
   463 }
       
   464 
       
   465 
       
   466 /**
       
   467  * gst_static_caps_get:
       
   468  * @static_caps: the #GstStaticCaps to convert
       
   469  *
       
   470  * Converts a #GstStaticCaps to a #GstCaps.
       
   471  *
       
   472  * Returns: A pointer to the #GstCaps. Unref after usage. Since the
       
   473  * core holds an additional ref to the returned caps,
       
   474  * use gst_caps_make_writable() on the returned caps to modify it.
       
   475  */
       
   476 #ifdef __SYMBIAN32__
       
   477 EXPORT_C
       
   478 #endif
       
   479 
       
   480 GstCaps *
       
   481 gst_static_caps_get (GstStaticCaps * static_caps)
       
   482 {
       
   483   GstCaps *caps;
       
   484 
       
   485   g_return_val_if_fail (static_caps != NULL, NULL);
       
   486 
       
   487   caps = (GstCaps *) static_caps;
       
   488 
       
   489   /* refcount is 0 when we need to convert */
       
   490   if (G_UNLIKELY (g_atomic_int_get (&caps->refcount) == 0)) {
       
   491     const char *string;
       
   492     GstCaps temp;
       
   493 
       
   494     G_LOCK (static_caps_lock);
       
   495     /* check if other thread already updated */
       
   496     if (G_UNLIKELY (g_atomic_int_get (&caps->refcount) > 0))
       
   497       goto done;
       
   498 
       
   499     string = static_caps->string;
       
   500 
       
   501     if (G_UNLIKELY (string == NULL))
       
   502       goto no_string;
       
   503 
       
   504     GST_CAT_LOG (GST_CAT_CAPS, "creating %p", static_caps);
       
   505 
       
   506     /* we construct the caps on the stack, then copy over the struct into our
       
   507      * real caps, refcount last. We do this because we must leave the refcount
       
   508      * of the result caps to 0 so that other threads don't run away with the
       
   509      * caps while we are constructing it. */
       
   510     temp.type = GST_TYPE_CAPS;
       
   511     temp.flags = 0;
       
   512     temp.structs = g_ptr_array_new ();
       
   513 
       
   514     /* initialize the caps to a refcount of 1 so the caps can be writable for
       
   515      * the next statement */
       
   516     gst_atomic_int_set (&temp.refcount, 1);
       
   517 
       
   518     /* convert to string */
       
   519     if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string)))
       
   520       g_critical ("Could not convert static caps \"%s\"", string);
       
   521 
       
   522     /* now copy stuff over to the real caps. */
       
   523     caps->type = temp.type;
       
   524     caps->flags = temp.flags;
       
   525     caps->structs = temp.structs;
       
   526     /* and bump the refcount so other threads can now read */
       
   527     gst_atomic_int_set (&caps->refcount, 1);
       
   528 
       
   529     GST_CAT_LOG (GST_CAT_CAPS, "created %p", static_caps);
       
   530   done:
       
   531     G_UNLOCK (static_caps_lock);
       
   532   }
       
   533   /* ref the caps, makes it not writable */
       
   534   gst_caps_ref (caps);
       
   535 
       
   536   return caps;
       
   537 
       
   538   /* ERRORS */
       
   539 no_string:
       
   540   {
       
   541     G_UNLOCK (static_caps_lock);
       
   542     g_warning ("static caps %p string is NULL", static_caps);
       
   543     return NULL;
       
   544   }
       
   545 }
       
   546 
       
   547 /* manipulation */
       
   548 static GstStructure *
       
   549 gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
       
   550 {
       
   551   /* don't use index_fast, gst_caps_do_simplify relies on the order */
       
   552   GstStructure *s = g_ptr_array_remove_index (caps->structs, idx);
       
   553 
       
   554   gst_structure_set_parent_refcount (s, NULL);
       
   555   return s;
       
   556 }
       
   557 
       
   558 static gboolean
       
   559 gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
       
   560     gpointer data)
       
   561 {
       
   562   GstStructure *struct1 = (GstStructure *) data;
       
   563   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
       
   564 
       
   565   if (val1 == NULL)
       
   566     return FALSE;
       
   567   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
       
   568     return TRUE;
       
   569   }
       
   570 
       
   571   return FALSE;
       
   572 }
       
   573 
       
   574 static gboolean
       
   575 gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
       
   576     gpointer user_data)
       
   577 {
       
   578   GstStructure *subtract_from = user_data;
       
   579   GValue subtraction = { 0, };
       
   580   const GValue *other;
       
   581   gint res;
       
   582 
       
   583   other = gst_structure_id_get_value (subtract_from, field_id);
       
   584   if (!other) {
       
   585     /* field is missing in one set */
       
   586     return FALSE;
       
   587   }
       
   588   /*
       
   589    * [1,2] - 1 = 2
       
   590    * 1 - [1,2] = ???
       
   591    */
       
   592   if (!gst_value_subtract (&subtraction, other, value)) {
       
   593     /* empty result -> values are the same, or first was a value and
       
   594      * second was a list
       
   595      * verify that result is empty by swapping args */
       
   596     if (!gst_value_subtract (&subtraction, value, other)) {
       
   597       return TRUE;
       
   598     }
       
   599     g_value_unset (&subtraction);
       
   600     return FALSE;
       
   601   }
       
   602 
       
   603   res = gst_value_compare (&subtraction, other);
       
   604   g_value_unset (&subtraction);
       
   605 
       
   606   if (res == GST_VALUE_EQUAL) {
       
   607     /* value was empty ? */
       
   608     return FALSE;
       
   609   } else {
       
   610     return TRUE;
       
   611   }
       
   612 }
       
   613 
       
   614 static gboolean
       
   615 gst_caps_structure_is_subset (const GstStructure * minuend,
       
   616     const GstStructure * subtrahend)
       
   617 {
       
   618   if ((minuend->name != subtrahend->name) ||
       
   619       (gst_structure_n_fields (minuend) !=
       
   620           gst_structure_n_fields (subtrahend))) {
       
   621     return FALSE;
       
   622   }
       
   623 
       
   624   return gst_structure_foreach ((GstStructure *) subtrahend,
       
   625       gst_caps_structure_is_subset_field, (gpointer) minuend);
       
   626 }
       
   627 
       
   628 /**
       
   629  * gst_caps_append:
       
   630  * @caps1: the #GstCaps that will be appended to
       
   631  * @caps2: the #GstCaps to append
       
   632  *
       
   633  * Appends the structures contained in @caps2 to @caps1. The structures in
       
   634  * @caps2 are not copied -- they are transferred to @caps1, and then @caps2 is
       
   635  * freed. If either caps is ANY, the resulting caps will be ANY.
       
   636  */
       
   637 #ifdef __SYMBIAN32__
       
   638 EXPORT_C
       
   639 #endif
       
   640 
       
   641 void
       
   642 gst_caps_append (GstCaps * caps1, GstCaps * caps2)
       
   643 {
       
   644   GstStructure *structure;
       
   645   int i;
       
   646 
       
   647   g_return_if_fail (GST_IS_CAPS (caps1));
       
   648   g_return_if_fail (GST_IS_CAPS (caps2));
       
   649   g_return_if_fail (IS_WRITABLE (caps1));
       
   650   g_return_if_fail (IS_WRITABLE (caps2));
       
   651 
       
   652 #ifdef USE_POISONING
       
   653   CAPS_POISON (caps2);
       
   654 #endif
       
   655   if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2)) {
       
   656     /* FIXME: this leaks */
       
   657     caps1->flags |= GST_CAPS_FLAGS_ANY;
       
   658     for (i = caps2->structs->len - 1; i >= 0; i--) {
       
   659       structure = gst_caps_remove_and_get_structure (caps2, i);
       
   660       gst_structure_free (structure);
       
   661     }
       
   662   } else {
       
   663     int len = caps2->structs->len;
       
   664 
       
   665     for (i = 0; i < len; i++) {
       
   666       structure = gst_caps_remove_and_get_structure (caps2, 0);
       
   667       gst_caps_append_structure (caps1, structure);
       
   668     }
       
   669   }
       
   670   gst_caps_unref (caps2);       /* guaranteed to free it */
       
   671 }
       
   672 
       
   673 /**
       
   674  * gst_caps_merge:
       
   675  * @caps1: the #GstCaps that will take the new entries
       
   676  * @caps2: the #GstCaps to merge in
       
   677  *
       
   678  * Appends the structures contained in @caps2 to @caps1 if they are not yet
       
   679  * expressed by @caps1. The structures in @caps2 are not copied -- they are
       
   680  * transferred to @caps1, and then @caps2 is freed.
       
   681  * If either caps is ANY, the resulting caps will be ANY.
       
   682  *
       
   683  * Since: 0.10.10
       
   684  */
       
   685 #ifdef __SYMBIAN32__
       
   686 EXPORT_C
       
   687 #endif
       
   688 
       
   689 void
       
   690 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
       
   691 {
       
   692   GstStructure *structure;
       
   693   int i;
       
   694 
       
   695   g_return_if_fail (GST_IS_CAPS (caps1));
       
   696   g_return_if_fail (GST_IS_CAPS (caps2));
       
   697   g_return_if_fail (IS_WRITABLE (caps1));
       
   698   g_return_if_fail (IS_WRITABLE (caps2));
       
   699 
       
   700 #ifdef USE_POISONING
       
   701   CAPS_POISON (caps2);
       
   702 #endif
       
   703   if (gst_caps_is_any (caps1)) {
       
   704     for (i = caps2->structs->len - 1; i >= 0; i--) {
       
   705       structure = gst_caps_remove_and_get_structure (caps2, i);
       
   706       gst_structure_free (structure);
       
   707     }
       
   708   } else if (gst_caps_is_any (caps2)) {
       
   709     caps1->flags |= GST_CAPS_FLAGS_ANY;
       
   710     for (i = caps1->structs->len - 1; i >= 0; i--) {
       
   711       structure = gst_caps_remove_and_get_structure (caps1, i);
       
   712       gst_structure_free (structure);
       
   713     }
       
   714   } else {
       
   715     int len = caps2->structs->len;
       
   716 
       
   717     for (i = 0; i < len; i++) {
       
   718       structure = gst_caps_remove_and_get_structure (caps2, 0);
       
   719       gst_caps_merge_structure (caps1, structure);
       
   720     }
       
   721     /* this is too naive
       
   722        GstCaps *com = gst_caps_intersect (caps1, caps2);
       
   723        GstCaps *add = gst_caps_subtract (caps2, com);
       
   724 
       
   725        GST_DEBUG ("common : %d", gst_caps_get_size (com));
       
   726        GST_DEBUG ("adding : %d", gst_caps_get_size (add));
       
   727        gst_caps_append (caps1, add);
       
   728        gst_caps_unref (com);
       
   729      */
       
   730   }
       
   731   gst_caps_unref (caps2);       /* guaranteed to free it */
       
   732 }
       
   733 
       
   734 /**
       
   735  * gst_caps_append_structure:
       
   736  * @caps: the #GstCaps that will be appended to
       
   737  * @structure: the #GstStructure to append
       
   738  *
       
   739  * Appends @structure to @caps.  The structure is not copied; @caps
       
   740  * becomes the owner of @structure.
       
   741  */
       
   742 #ifdef __SYMBIAN32__
       
   743 EXPORT_C
       
   744 #endif
       
   745 
       
   746 void
       
   747 gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
       
   748 {
       
   749   g_return_if_fail (GST_IS_CAPS (caps));
       
   750   g_return_if_fail (IS_WRITABLE (caps));
       
   751 
       
   752   if (G_LIKELY (structure)) {
       
   753     g_return_if_fail (structure->parent_refcount == NULL);
       
   754 #if 0
       
   755 #ifdef USE_POISONING
       
   756     STRUCTURE_POISON (structure);
       
   757 #endif
       
   758 #endif
       
   759     gst_structure_set_parent_refcount (structure, &caps->refcount);
       
   760     g_ptr_array_add (caps->structs, structure);
       
   761   }
       
   762 }
       
   763 
       
   764 /**
       
   765  * gst_caps_remove_structure:
       
   766  * @caps: the #GstCaps to remove from
       
   767  * @idx: Index of the structure to remove
       
   768  *
       
   769  * removes the stucture with the given index from the list of structures
       
   770  * contained in @caps.
       
   771  */
       
   772 #ifdef __SYMBIAN32__
       
   773 EXPORT_C
       
   774 #endif
       
   775 
       
   776 void
       
   777 gst_caps_remove_structure (GstCaps * caps, guint idx)
       
   778 {
       
   779   GstStructure *structure;
       
   780 
       
   781   g_return_if_fail (caps != NULL);
       
   782   g_return_if_fail (idx <= gst_caps_get_size (caps));
       
   783   g_return_if_fail (IS_WRITABLE (caps));
       
   784 
       
   785   structure = gst_caps_remove_and_get_structure (caps, idx);
       
   786   gst_structure_free (structure);
       
   787 }
       
   788 
       
   789 /**
       
   790  * gst_caps_merge_structure:
       
   791  * @caps: the #GstCaps that will the the new structure
       
   792  * @structure: the #GstStructure to merge
       
   793  *
       
   794  * Appends @structure to @caps if its not already expressed by @caps.  The
       
   795  * structure is not copied; @caps becomes the owner of @structure.
       
   796  */
       
   797 #ifdef __SYMBIAN32__
       
   798 EXPORT_C
       
   799 #endif
       
   800 
       
   801 void
       
   802 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
       
   803 {
       
   804   g_return_if_fail (GST_IS_CAPS (caps));
       
   805   g_return_if_fail (IS_WRITABLE (caps));
       
   806 
       
   807   if (G_LIKELY (structure)) {
       
   808     GstStructure *structure1;
       
   809     int i;
       
   810     gboolean unique = TRUE;
       
   811 
       
   812     g_return_if_fail (structure->parent_refcount == NULL);
       
   813 #if 0
       
   814 #ifdef USE_POISONING
       
   815     STRUCTURE_POISON (structure);
       
   816 #endif
       
   817 #endif
       
   818     /* check each structure */
       
   819     for (i = caps->structs->len - 1; i >= 0; i--) {
       
   820       structure1 = gst_caps_get_structure (caps, i);
       
   821       /* if structure is a subset of structure1, then skip it */
       
   822       if (gst_caps_structure_is_subset (structure1, structure)) {
       
   823         unique = FALSE;
       
   824         break;
       
   825       }
       
   826     }
       
   827     if (unique) {
       
   828       gst_structure_set_parent_refcount (structure, &caps->refcount);
       
   829       g_ptr_array_add (caps->structs, structure);
       
   830     } else {
       
   831       gst_structure_free (structure);
       
   832     }
       
   833   }
       
   834 }
       
   835 
       
   836 
       
   837 /**
       
   838  * gst_caps_get_size:
       
   839  * @caps: a #GstCaps
       
   840  *
       
   841  * Gets the number of structures contained in @caps.
       
   842  *
       
   843  * Returns: the number of structures that @caps contains
       
   844  */
       
   845 #ifdef __SYMBIAN32__
       
   846 EXPORT_C
       
   847 #endif
       
   848 
       
   849 guint
       
   850 gst_caps_get_size (const GstCaps * caps)
       
   851 {
       
   852   g_return_val_if_fail (GST_IS_CAPS (caps), 0);
       
   853 
       
   854   return caps->structs->len;
       
   855 }
       
   856 
       
   857 /**
       
   858  * gst_caps_get_structure:
       
   859  * @caps: a #GstCaps
       
   860  * @index: the index of the structure
       
   861  *
       
   862  * Finds the structure in @caps that has the index @index, and
       
   863  * returns it.
       
   864  *
       
   865  * WARNING: This function takes a const GstCaps *, but returns a
       
   866  * non-const GstStructure *.  This is for programming convenience --
       
   867  * the caller should be aware that structures inside a constant
       
   868  * #GstCaps should not be modified.
       
   869  *
       
   870  * Returns: a pointer to the #GstStructure corresponding to @index
       
   871  */
       
   872 #ifdef __SYMBIAN32__
       
   873 EXPORT_C
       
   874 #endif
       
   875 
       
   876 GstStructure *
       
   877 gst_caps_get_structure (const GstCaps * caps, guint index)
       
   878 {
       
   879   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
       
   880   g_return_val_if_fail (index < caps->structs->len, NULL);
       
   881 
       
   882   return g_ptr_array_index (caps->structs, index);
       
   883 }
       
   884 
       
   885 /**
       
   886  * gst_caps_copy_nth:
       
   887  * @caps: the #GstCaps to copy
       
   888  * @nth: the nth structure to copy
       
   889  *
       
   890  * Creates a new #GstCaps and appends a copy of the nth structure
       
   891  * contained in @caps.
       
   892  *
       
   893  * Returns: the new #GstCaps
       
   894  */
       
   895 #ifdef __SYMBIAN32__
       
   896 EXPORT_C
       
   897 #endif
       
   898 
       
   899 GstCaps *
       
   900 gst_caps_copy_nth (const GstCaps * caps, guint nth)
       
   901 {
       
   902   GstCaps *newcaps;
       
   903   GstStructure *structure;
       
   904 
       
   905   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
       
   906 
       
   907   newcaps = gst_caps_new_empty ();
       
   908   newcaps->flags = caps->flags;
       
   909 
       
   910   if (caps->structs->len > nth) {
       
   911     structure = gst_caps_get_structure (caps, nth);
       
   912     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
       
   913   }
       
   914 
       
   915   return newcaps;
       
   916 }
       
   917 
       
   918 /**
       
   919  * gst_caps_truncate:
       
   920  * @caps: the #GstCaps to truncate
       
   921  *
       
   922  * Destructively discard all but the first structure from @caps. Useful when
       
   923  * fixating. @caps must be writable.
       
   924  */
       
   925 #ifdef __SYMBIAN32__
       
   926 EXPORT_C
       
   927 #endif
       
   928 
       
   929 void
       
   930 gst_caps_truncate (GstCaps * caps)
       
   931 {
       
   932   gint i;
       
   933 
       
   934   g_return_if_fail (GST_IS_CAPS (caps));
       
   935   g_return_if_fail (IS_WRITABLE (caps));
       
   936 
       
   937   i = caps->structs->len - 1;
       
   938 
       
   939   while (i > 0)
       
   940     gst_caps_remove_structure (caps, i--);
       
   941 }
       
   942 
       
   943 /**
       
   944  * gst_caps_set_simple:
       
   945  * @caps: the #GstCaps to set
       
   946  * @field: first field to set
       
   947  * @...: additional parameters
       
   948  *
       
   949  * Sets fields in a simple #GstCaps.  A simple #GstCaps is one that
       
   950  * only has one structure.  The arguments must be passed in the same
       
   951  * manner as gst_structure_set(), and be NULL-terminated.
       
   952  */
       
   953 #ifdef __SYMBIAN32__
       
   954 EXPORT_C
       
   955 #endif
       
   956 
       
   957 void
       
   958 gst_caps_set_simple (GstCaps * caps, char *field, ...)
       
   959 {
       
   960   GstStructure *structure;
       
   961   va_list var_args;
       
   962 
       
   963   g_return_if_fail (GST_IS_CAPS (caps));
       
   964   g_return_if_fail (caps->structs->len == 1);
       
   965   g_return_if_fail (IS_WRITABLE (caps));
       
   966 
       
   967   structure = gst_caps_get_structure (caps, 0);
       
   968 
       
   969   va_start (var_args, field);
       
   970   gst_structure_set_valist (structure, field, var_args);
       
   971   va_end (var_args);
       
   972 }
       
   973 
       
   974 /**
       
   975  * gst_caps_set_simple_valist:
       
   976  * @caps: the #GstCaps to copy
       
   977  * @field: first field to set
       
   978  * @varargs: additional parameters
       
   979  *
       
   980  * Sets fields in a simple #GstCaps.  A simple #GstCaps is one that
       
   981  * only has one structure.  The arguments must be passed in the same
       
   982  * manner as gst_structure_set(), and be NULL-terminated.
       
   983  */
       
   984 #ifdef __SYMBIAN32__
       
   985 EXPORT_C
       
   986 #endif
       
   987 
       
   988 void
       
   989 gst_caps_set_simple_valist (GstCaps * caps, char *field, va_list varargs)
       
   990 {
       
   991   GstStructure *structure;
       
   992 
       
   993   g_return_if_fail (GST_IS_CAPS (caps));
       
   994   g_return_if_fail (caps->structs->len == 1);
       
   995   g_return_if_fail (IS_WRITABLE (caps));
       
   996 
       
   997   structure = gst_caps_get_structure (caps, 0);
       
   998 
       
   999   gst_structure_set_valist (structure, field, varargs);
       
  1000 }
       
  1001 
       
  1002 /* tests */
       
  1003 
       
  1004 /**
       
  1005  * gst_caps_is_any:
       
  1006  * @caps: the #GstCaps to test
       
  1007  *
       
  1008  * Determines if @caps represents any media format.
       
  1009  *
       
  1010  * Returns: TRUE if @caps represents any format.
       
  1011  */
       
  1012 #ifdef __SYMBIAN32__
       
  1013 EXPORT_C
       
  1014 #endif
       
  1015 
       
  1016 gboolean
       
  1017 gst_caps_is_any (const GstCaps * caps)
       
  1018 {
       
  1019   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
       
  1020 
       
  1021   return (caps->flags & GST_CAPS_FLAGS_ANY);
       
  1022 }
       
  1023 
       
  1024 /**
       
  1025  * gst_caps_is_empty:
       
  1026  * @caps: the #GstCaps to test
       
  1027  *
       
  1028  * Determines if @caps represents no media formats.
       
  1029  *
       
  1030  * Returns: TRUE if @caps represents no formats.
       
  1031  */
       
  1032 #ifdef __SYMBIAN32__
       
  1033 EXPORT_C
       
  1034 #endif
       
  1035 
       
  1036 gboolean
       
  1037 gst_caps_is_empty (const GstCaps * caps)
       
  1038 {
       
  1039   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
       
  1040 
       
  1041   if (caps->flags & GST_CAPS_FLAGS_ANY)
       
  1042     return FALSE;
       
  1043 
       
  1044   return (caps->structs == NULL) || (caps->structs->len == 0);
       
  1045 }
       
  1046 
       
  1047 static gboolean
       
  1048 gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value,
       
  1049     gpointer unused)
       
  1050 {
       
  1051   return gst_value_is_fixed (value);
       
  1052 }
       
  1053 
       
  1054 /**
       
  1055  * gst_caps_is_fixed:
       
  1056  * @caps: the #GstCaps to test
       
  1057  *
       
  1058  * Fixed #GstCaps describe exactly one format, that is, they have exactly
       
  1059  * one structure, and each field in the structure describes a fixed type.
       
  1060  * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST.
       
  1061  *
       
  1062  * Returns: TRUE if @caps is fixed
       
  1063  */
       
  1064 #ifdef __SYMBIAN32__
       
  1065 EXPORT_C
       
  1066 #endif
       
  1067 
       
  1068 gboolean
       
  1069 gst_caps_is_fixed (const GstCaps * caps)
       
  1070 {
       
  1071   GstStructure *structure;
       
  1072 
       
  1073   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
       
  1074 
       
  1075   if (caps->structs->len != 1)
       
  1076     return FALSE;
       
  1077 
       
  1078   structure = gst_caps_get_structure (caps, 0);
       
  1079 
       
  1080   return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
       
  1081 }
       
  1082 
       
  1083 /**
       
  1084  * gst_caps_is_equal_fixed:
       
  1085  * @caps1: the #GstCaps to test
       
  1086  * @caps2: the #GstCaps to test
       
  1087  *
       
  1088  * Tests if two #GstCaps are equal.  This function only works on fixed
       
  1089  * #GstCaps.
       
  1090  *
       
  1091  * Returns: TRUE if the arguments represent the same format
       
  1092  */
       
  1093 #ifdef __SYMBIAN32__
       
  1094 EXPORT_C
       
  1095 #endif
       
  1096 
       
  1097 gboolean
       
  1098 gst_caps_is_equal_fixed (const GstCaps * caps1, const GstCaps * caps2)
       
  1099 {
       
  1100   GstStructure *struct1, *struct2;
       
  1101 
       
  1102   g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
       
  1103   g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
       
  1104 
       
  1105   struct1 = gst_caps_get_structure (caps1, 0);
       
  1106   struct2 = gst_caps_get_structure (caps2, 0);
       
  1107 
       
  1108   if (struct1->name != struct2->name) {
       
  1109     return FALSE;
       
  1110   }
       
  1111   if (struct1->fields->len != struct2->fields->len) {
       
  1112     return FALSE;
       
  1113   }
       
  1114 
       
  1115   return gst_structure_foreach (struct1, gst_structure_is_equal_foreach,
       
  1116       struct2);
       
  1117 }
       
  1118 
       
  1119 /**
       
  1120  * gst_caps_is_always_compatible:
       
  1121  * @caps1: the #GstCaps to test
       
  1122  * @caps2: the #GstCaps to test
       
  1123  *
       
  1124  * A given #GstCaps structure is always compatible with another if
       
  1125  * every media format that is in the first is also contained in the
       
  1126  * second.  That is, @caps1 is a subset of @caps2.
       
  1127  *
       
  1128  * Returns: TRUE if @caps1 is a subset of @caps2.
       
  1129  */
       
  1130 #ifdef __SYMBIAN32__
       
  1131 EXPORT_C
       
  1132 #endif
       
  1133 
       
  1134 gboolean
       
  1135 gst_caps_is_always_compatible (const GstCaps * caps1, const GstCaps * caps2)
       
  1136 {
       
  1137   g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
       
  1138   g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
       
  1139 
       
  1140   return gst_caps_is_subset (caps1, caps2);
       
  1141 }
       
  1142 
       
  1143 /**
       
  1144  * gst_caps_is_subset:
       
  1145  * @subset: a #GstCaps
       
  1146  * @superset: a potentially greater #GstCaps
       
  1147  *
       
  1148  * Checks if all caps represented by @subset are also represented by @superset.
       
  1149  * <note>This function does not work reliably if optional properties for caps
       
  1150  * are included on one caps and omitted on the other.</note>
       
  1151  *
       
  1152  * Returns: %TRUE if @subset is a subset of @superset
       
  1153  */
       
  1154 #ifdef __SYMBIAN32__
       
  1155 EXPORT_C
       
  1156 #endif
       
  1157 
       
  1158 gboolean
       
  1159 gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
       
  1160 {
       
  1161   GstCaps *caps;
       
  1162   gboolean ret;
       
  1163 
       
  1164   g_return_val_if_fail (subset != NULL, FALSE);
       
  1165   g_return_val_if_fail (superset != NULL, FALSE);
       
  1166 
       
  1167   if (gst_caps_is_empty (subset) || gst_caps_is_any (superset))
       
  1168     return TRUE;
       
  1169   if (gst_caps_is_any (subset) || gst_caps_is_empty (superset))
       
  1170     return FALSE;
       
  1171 
       
  1172   caps = gst_caps_subtract (subset, superset);
       
  1173   ret = gst_caps_is_empty (caps);
       
  1174   gst_caps_unref (caps);
       
  1175   return ret;
       
  1176 }
       
  1177 
       
  1178 /**
       
  1179  * gst_caps_is_equal:
       
  1180  * @caps1: a #GstCaps
       
  1181  * @caps2: another #GstCaps
       
  1182  *
       
  1183  * Checks if the given caps represent the same set of caps.
       
  1184  * <note>This function does not work reliably if optional properties for caps
       
  1185  * are included on one caps and omitted on the other.</note>
       
  1186  *
       
  1187  * This function deals correctly with passing NULL for any of the caps.
       
  1188  *
       
  1189  * Returns: TRUE if both caps are equal.
       
  1190  */
       
  1191 #ifdef __SYMBIAN32__
       
  1192 EXPORT_C
       
  1193 #endif
       
  1194 
       
  1195 gboolean
       
  1196 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
       
  1197 {
       
  1198   /* NULL <-> NULL is allowed here */
       
  1199   if (caps1 == caps2)
       
  1200     return TRUE;
       
  1201 
       
  1202   /* one of them NULL => they are different (can't be both NULL because
       
  1203    * we checked that above) */
       
  1204   if (caps1 == NULL || caps2 == NULL)
       
  1205     return FALSE;
       
  1206 
       
  1207   if (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2))
       
  1208     return gst_caps_is_equal_fixed (caps1, caps2);
       
  1209 
       
  1210   return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
       
  1211 }
       
  1212 
       
  1213 typedef struct
       
  1214 {
       
  1215   GstStructure *dest;
       
  1216   const GstStructure *intersect;
       
  1217   gboolean first_run;
       
  1218 }
       
  1219 IntersectData;
       
  1220 
       
  1221 static gboolean
       
  1222 gst_caps_structure_intersect_field (GQuark id, const GValue * val1,
       
  1223     gpointer data)
       
  1224 {
       
  1225   IntersectData *idata = (IntersectData *) data;
       
  1226   GValue dest_value = { 0 };
       
  1227   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
       
  1228 
       
  1229   if (val2 == NULL) {
       
  1230     gst_structure_id_set_value (idata->dest, id, val1);
       
  1231   } else if (idata->first_run) {
       
  1232     if (gst_value_intersect (&dest_value, val1, val2)) {
       
  1233       gst_structure_id_set_value (idata->dest, id, &dest_value);
       
  1234       g_value_unset (&dest_value);
       
  1235     } else {
       
  1236       return FALSE;
       
  1237     }
       
  1238   }
       
  1239 
       
  1240   return TRUE;
       
  1241 }
       
  1242 
       
  1243 static GstStructure *
       
  1244 gst_caps_structure_intersect (const GstStructure * struct1,
       
  1245     const GstStructure * struct2)
       
  1246 {
       
  1247   IntersectData data;
       
  1248 
       
  1249   g_return_val_if_fail (struct1 != NULL, NULL);
       
  1250   g_return_val_if_fail (struct2 != NULL, NULL);
       
  1251 
       
  1252   if (struct1->name != struct2->name)
       
  1253     return NULL;
       
  1254 
       
  1255   data.dest = gst_structure_id_empty_new (struct1->name);
       
  1256   data.intersect = struct2;
       
  1257   data.first_run = TRUE;
       
  1258   if (!gst_structure_foreach ((GstStructure *) struct1,
       
  1259           gst_caps_structure_intersect_field, &data))
       
  1260     goto error;
       
  1261 
       
  1262   data.intersect = struct1;
       
  1263   data.first_run = FALSE;
       
  1264   if (!gst_structure_foreach ((GstStructure *) struct2,
       
  1265           gst_caps_structure_intersect_field, &data))
       
  1266     goto error;
       
  1267 
       
  1268   return data.dest;
       
  1269 
       
  1270 error:
       
  1271   gst_structure_free (data.dest);
       
  1272   return NULL;
       
  1273 }
       
  1274 
       
  1275 #if 0
       
  1276 static GstStructure *
       
  1277 gst_caps_structure_union (const GstStructure * struct1,
       
  1278     const GstStructure * struct2)
       
  1279 {
       
  1280   int i;
       
  1281   GstStructure *dest;
       
  1282   const GstStructureField *field1;
       
  1283   const GstStructureField *field2;
       
  1284   int ret;
       
  1285 
       
  1286   /* FIXME this doesn't actually work */
       
  1287 
       
  1288   if (struct1->name != struct2->name)
       
  1289     return NULL;
       
  1290 
       
  1291   dest = gst_structure_id_empty_new (struct1->name);
       
  1292 
       
  1293   for (i = 0; i < struct1->fields->len; i++) {
       
  1294     GValue dest_value = { 0 };
       
  1295 
       
  1296     field1 = GST_STRUCTURE_FIELD (struct1, i);
       
  1297     field2 = gst_structure_id_get_field (struct2, field1->name);
       
  1298 
       
  1299     if (field2 == NULL) {
       
  1300       continue;
       
  1301     } else {
       
  1302       if (gst_value_union (&dest_value, &field1->value, &field2->value)) {
       
  1303         gst_structure_set_value (dest, g_quark_to_string (field1->name),
       
  1304             &dest_value);
       
  1305       } else {
       
  1306         ret = gst_value_compare (&field1->value, &field2->value);
       
  1307       }
       
  1308     }
       
  1309   }
       
  1310 
       
  1311   return dest;
       
  1312 }
       
  1313 #endif
       
  1314 
       
  1315 /* operations */
       
  1316 
       
  1317 /**
       
  1318  * gst_caps_intersect:
       
  1319  * @caps1: a #GstCaps to intersect
       
  1320  * @caps2: a #GstCaps to intersect
       
  1321  *
       
  1322  * Creates a new #GstCaps that contains all the formats that are common
       
  1323  * to both @caps1 and @caps2.
       
  1324  *
       
  1325  * Returns: the new #GstCaps
       
  1326  */
       
  1327 #ifdef __SYMBIAN32__
       
  1328 EXPORT_C
       
  1329 #endif
       
  1330 
       
  1331 GstCaps *
       
  1332 gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
       
  1333 {
       
  1334   guint64 i;                    /* index can be up to 2 * G_MAX_UINT */
       
  1335   guint j, k;
       
  1336 
       
  1337   GstStructure *struct1;
       
  1338   GstStructure *struct2;
       
  1339   GstCaps *dest;
       
  1340   GstStructure *istruct;
       
  1341 
       
  1342   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
       
  1343   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
       
  1344 
       
  1345   /* caps are exactly the same pointers, just copy one caps */
       
  1346   if (caps1 == caps2)
       
  1347     return gst_caps_copy (caps1);
       
  1348 
       
  1349   /* empty caps on either side, return empty */
       
  1350   if (gst_caps_is_empty (caps1) || gst_caps_is_empty (caps2))
       
  1351     return gst_caps_new_empty ();
       
  1352 
       
  1353   /* one of the caps is any, just copy the other caps */
       
  1354   if (gst_caps_is_any (caps1))
       
  1355     return gst_caps_copy (caps2);
       
  1356   if (gst_caps_is_any (caps2))
       
  1357     return gst_caps_copy (caps1);
       
  1358 
       
  1359   dest = gst_caps_new_empty ();
       
  1360 
       
  1361   /* run zigzag on top line then right line, this preserves the caps order
       
  1362    * much better than a simple loop.
       
  1363    *
       
  1364    * This algorithm zigzags over the caps structures as demonstrated in
       
  1365    * the folowing matrix:
       
  1366    *
       
  1367    *          caps1
       
  1368    *       +-------------
       
  1369    *       | 1  2  4  7
       
  1370    * caps2 | 3  5  8 10
       
  1371    *       | 6  9 11 12
       
  1372    *
       
  1373    * First we iterate over the caps1 structures (top line) intersecting
       
  1374    * the structures diagonally down, then we iterate over the caps2
       
  1375    * structures.
       
  1376    */
       
  1377   for (i = 0; i < caps1->structs->len + caps2->structs->len - 1; i++) {
       
  1378     /* caps1 index goes from 0 to caps1->structs->len-1 */
       
  1379     j = MIN (i, caps1->structs->len - 1);
       
  1380     /* caps2 index stays 0 until i reaches caps1->structs->len, then it counts
       
  1381      * up from 1 to caps2->structs->len - 1 */
       
  1382     k = MAX (0, i - j);
       
  1383 
       
  1384     /* now run the diagonal line, end condition is the left or bottom
       
  1385      * border */
       
  1386     while (k < caps2->structs->len) {
       
  1387       struct1 = gst_caps_get_structure (caps1, j);
       
  1388       struct2 = gst_caps_get_structure (caps2, k);
       
  1389 
       
  1390       istruct = gst_caps_structure_intersect (struct1, struct2);
       
  1391 
       
  1392       gst_caps_append_structure (dest, istruct);
       
  1393       /* move down left */
       
  1394       k++;
       
  1395       if (j == 0)
       
  1396         break;                  /* so we don't roll back to G_MAXUINT */
       
  1397       j--;
       
  1398     }
       
  1399   }
       
  1400   return dest;
       
  1401 }
       
  1402 
       
  1403 typedef struct
       
  1404 {
       
  1405   const GstStructure *subtract_from;
       
  1406   GSList *put_into;
       
  1407 }
       
  1408 SubtractionEntry;
       
  1409 
       
  1410 
       
  1411 static gboolean
       
  1412 gst_caps_structure_subtract_field (GQuark field_id, const GValue * value,
       
  1413     gpointer user_data)
       
  1414 {
       
  1415   SubtractionEntry *e = user_data;
       
  1416   GValue subtraction = { 0, };
       
  1417   const GValue *other;
       
  1418   GstStructure *structure;
       
  1419 
       
  1420   other = gst_structure_id_get_value (e->subtract_from, field_id);
       
  1421   if (!other) {
       
  1422     return FALSE;
       
  1423   }
       
  1424   if (!gst_value_subtract (&subtraction, other, value))
       
  1425     return TRUE;
       
  1426   if (gst_value_compare (&subtraction, other) == GST_VALUE_EQUAL) {
       
  1427     g_value_unset (&subtraction);
       
  1428     return FALSE;
       
  1429   } else {
       
  1430     structure = gst_structure_copy (e->subtract_from);
       
  1431     gst_structure_id_set_value (structure, field_id, &subtraction);
       
  1432     g_value_unset (&subtraction);
       
  1433     e->put_into = g_slist_prepend (e->put_into, structure);
       
  1434     return TRUE;
       
  1435   }
       
  1436 }
       
  1437 
       
  1438 static gboolean
       
  1439 gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
       
  1440     const GstStructure * subtrahend)
       
  1441 {
       
  1442   SubtractionEntry e;
       
  1443   gboolean ret;
       
  1444 
       
  1445   e.subtract_from = minuend;
       
  1446   e.put_into = NULL;
       
  1447 
       
  1448   ret = gst_structure_foreach ((GstStructure *) subtrahend,
       
  1449       gst_caps_structure_subtract_field, &e);
       
  1450   if (ret) {
       
  1451     *into = e.put_into;
       
  1452   } else {
       
  1453     GSList *walk;
       
  1454 
       
  1455     for (walk = e.put_into; walk; walk = g_slist_next (walk)) {
       
  1456       gst_structure_free (walk->data);
       
  1457     }
       
  1458     g_slist_free (e.put_into);
       
  1459   }
       
  1460   return ret;
       
  1461 }
       
  1462 
       
  1463 /**
       
  1464  * gst_caps_subtract:
       
  1465  * @minuend: #GstCaps to substract from
       
  1466  * @subtrahend: #GstCaps to substract
       
  1467  *
       
  1468  * Subtracts the @subtrahend from the @minuend.
       
  1469  * <note>This function does not work reliably if optional properties for caps
       
  1470  * are included on one caps and omitted on the other.</note>
       
  1471  *
       
  1472  * Returns: the resulting caps
       
  1473  */
       
  1474 #ifdef __SYMBIAN32__
       
  1475 EXPORT_C
       
  1476 #endif
       
  1477 
       
  1478 GstCaps *
       
  1479 gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
       
  1480 {
       
  1481   guint i, j;
       
  1482   GstStructure *min;
       
  1483   GstStructure *sub;
       
  1484   GstCaps *dest = NULL, *src;
       
  1485 
       
  1486   g_return_val_if_fail (minuend != NULL, NULL);
       
  1487   g_return_val_if_fail (subtrahend != NULL, NULL);
       
  1488 
       
  1489   if (gst_caps_is_empty (minuend) || gst_caps_is_any (subtrahend)) {
       
  1490     return gst_caps_new_empty ();
       
  1491   }
       
  1492   if (gst_caps_is_empty (subtrahend))
       
  1493     return gst_caps_copy (minuend);
       
  1494 
       
  1495   /* FIXME: Do we want this here or above?
       
  1496      The reason we need this is that there is no definition about what
       
  1497      ANY means for specific types, so it's not possible to reduce ANY partially
       
  1498      You can only remove everything or nothing and that is done above.
       
  1499      Note: there's a test that checks this behaviour. */
       
  1500   g_return_val_if_fail (!gst_caps_is_any (minuend), NULL);
       
  1501   g_assert (subtrahend->structs->len > 0);
       
  1502 
       
  1503   src = gst_caps_copy (minuend);
       
  1504   for (i = 0; i < subtrahend->structs->len; i++) {
       
  1505     sub = gst_caps_get_structure (subtrahend, i);
       
  1506     if (dest) {
       
  1507       gst_caps_unref (src);
       
  1508       src = dest;
       
  1509     }
       
  1510     dest = gst_caps_new_empty ();
       
  1511     for (j = 0; j < src->structs->len; j++) {
       
  1512       min = gst_caps_get_structure (src, j);
       
  1513       if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub)) {
       
  1514         GSList *list;
       
  1515 
       
  1516         if (gst_caps_structure_subtract (&list, min, sub)) {
       
  1517           GSList *walk;
       
  1518 
       
  1519           for (walk = list; walk; walk = g_slist_next (walk)) {
       
  1520             gst_caps_append_structure (dest, (GstStructure *) walk->data);
       
  1521           }
       
  1522           g_slist_free (list);
       
  1523         } else {
       
  1524           gst_caps_append_structure (dest, gst_structure_copy (min));
       
  1525         }
       
  1526       } else {
       
  1527         gst_caps_append_structure (dest, gst_structure_copy (min));
       
  1528       }
       
  1529     }
       
  1530     if (gst_caps_is_empty (dest)) {
       
  1531       gst_caps_unref (src);
       
  1532       return dest;
       
  1533     }
       
  1534   }
       
  1535 
       
  1536   gst_caps_unref (src);
       
  1537   gst_caps_do_simplify (dest);
       
  1538   return dest;
       
  1539 }
       
  1540 
       
  1541 /**
       
  1542  * gst_caps_union:
       
  1543  * @caps1: a #GstCaps to union
       
  1544  * @caps2: a #GstCaps to union
       
  1545  *
       
  1546  * Creates a new #GstCaps that contains all the formats that are in
       
  1547  * either @caps1 and @caps2.
       
  1548  *
       
  1549  * Returns: the new #GstCaps
       
  1550  */
       
  1551 #ifdef __SYMBIAN32__
       
  1552 EXPORT_C
       
  1553 #endif
       
  1554 
       
  1555 GstCaps *
       
  1556 gst_caps_union (const GstCaps * caps1, const GstCaps * caps2)
       
  1557 {
       
  1558   GstCaps *dest1;
       
  1559   GstCaps *dest2;
       
  1560 
       
  1561   if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2))
       
  1562     return gst_caps_new_any ();
       
  1563 
       
  1564   dest1 = gst_caps_copy (caps1);
       
  1565   dest2 = gst_caps_copy (caps2);
       
  1566   gst_caps_append (dest1, dest2);
       
  1567 
       
  1568   gst_caps_do_simplify (dest1);
       
  1569   return dest1;
       
  1570 }
       
  1571 
       
  1572 typedef struct _NormalizeForeach
       
  1573 {
       
  1574   GstCaps *caps;
       
  1575   GstStructure *structure;
       
  1576 }
       
  1577 NormalizeForeach;
       
  1578 
       
  1579 static gboolean
       
  1580 gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
       
  1581 {
       
  1582   NormalizeForeach *nf = (NormalizeForeach *) ptr;
       
  1583   GValue val = { 0 };
       
  1584   guint i;
       
  1585 
       
  1586   if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
       
  1587     for (i = 1; i < gst_value_list_get_size (value); i++) {
       
  1588       const GValue *v = gst_value_list_get_value (value, i);
       
  1589       GstStructure *structure = gst_structure_copy (nf->structure);
       
  1590 
       
  1591       gst_structure_id_set_value (structure, field_id, v);
       
  1592       gst_caps_append_structure (nf->caps, structure);
       
  1593     }
       
  1594 
       
  1595     gst_value_init_and_copy (&val, gst_value_list_get_value (value, 0));
       
  1596     gst_structure_id_set_value (nf->structure, field_id, &val);
       
  1597     g_value_unset (&val);
       
  1598 
       
  1599     return FALSE;
       
  1600   }
       
  1601   return TRUE;
       
  1602 }
       
  1603 
       
  1604 /**
       
  1605  * gst_caps_normalize:
       
  1606  * @caps: a #GstCaps to normalize
       
  1607  *
       
  1608  * Creates a new #GstCaps that represents the same set of formats as
       
  1609  * @caps, but contains no lists.  Each list is expanded into separate
       
  1610  * @GstStructures.
       
  1611  *
       
  1612  * Returns: the new #GstCaps
       
  1613  */
       
  1614 #ifdef __SYMBIAN32__
       
  1615 EXPORT_C
       
  1616 #endif
       
  1617 
       
  1618 GstCaps *
       
  1619 gst_caps_normalize (const GstCaps * caps)
       
  1620 {
       
  1621   NormalizeForeach nf;
       
  1622   GstCaps *newcaps;
       
  1623   guint i;
       
  1624 
       
  1625   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
       
  1626 
       
  1627   newcaps = gst_caps_copy (caps);
       
  1628   nf.caps = newcaps;
       
  1629 
       
  1630   for (i = 0; i < newcaps->structs->len; i++) {
       
  1631     nf.structure = gst_caps_get_structure (newcaps, i);
       
  1632 
       
  1633     while (!gst_structure_foreach (nf.structure,
       
  1634             gst_caps_normalize_foreach, &nf));
       
  1635   }
       
  1636 
       
  1637   return newcaps;
       
  1638 }
       
  1639 
       
  1640 static gint
       
  1641 gst_caps_compare_structures (gconstpointer one, gconstpointer two)
       
  1642 {
       
  1643   gint ret;
       
  1644   const GstStructure *struct1 = *((const GstStructure **) one);
       
  1645   const GstStructure *struct2 = *((const GstStructure **) two);
       
  1646 
       
  1647   /* FIXME: this orders alphabetically, but ordering the quarks might be faster
       
  1648      So what's the best way? */
       
  1649   ret = strcmp (gst_structure_get_name (struct1),
       
  1650       gst_structure_get_name (struct2));
       
  1651   if (ret)
       
  1652     return ret;
       
  1653 
       
  1654   return gst_structure_n_fields (struct2) - gst_structure_n_fields (struct1);
       
  1655 }
       
  1656 
       
  1657 typedef struct
       
  1658 {
       
  1659   GQuark name;
       
  1660   GValue value;
       
  1661   GstStructure *compare;
       
  1662 }
       
  1663 UnionField;
       
  1664 
       
  1665 static gboolean
       
  1666 gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
       
  1667     gpointer user_data)
       
  1668 {
       
  1669   UnionField *u = user_data;
       
  1670   const GValue *val = gst_structure_id_get_value (u->compare, field_id);
       
  1671 
       
  1672   if (!val) {
       
  1673     if (u->name)
       
  1674       g_value_unset (&u->value);
       
  1675     return FALSE;
       
  1676   }
       
  1677   if (gst_value_compare (val, value) == GST_VALUE_EQUAL)
       
  1678     return TRUE;
       
  1679   if (u->name) {
       
  1680     g_value_unset (&u->value);
       
  1681     return FALSE;
       
  1682   }
       
  1683   u->name = field_id;
       
  1684   gst_value_union (&u->value, val, value);
       
  1685   return TRUE;
       
  1686 }
       
  1687 
       
  1688 static gboolean
       
  1689 gst_caps_structure_simplify (GstStructure ** result,
       
  1690     const GstStructure * simplify, GstStructure * compare)
       
  1691 {
       
  1692   GSList *list;
       
  1693   UnionField field = { 0, {0,}, NULL };
       
  1694 
       
  1695   /* try to subtract to get a real subset */
       
  1696   if (gst_caps_structure_subtract (&list, simplify, compare)) {
       
  1697     switch (g_slist_length (list)) {
       
  1698       case 0:
       
  1699         *result = NULL;
       
  1700         return TRUE;
       
  1701       case 1:
       
  1702         *result = list->data;
       
  1703         g_slist_free (list);
       
  1704         return TRUE;
       
  1705       default:
       
  1706       {
       
  1707         GSList *walk;
       
  1708 
       
  1709         for (walk = list; walk; walk = g_slist_next (walk)) {
       
  1710           gst_structure_free (walk->data);
       
  1711         }
       
  1712         g_slist_free (list);
       
  1713         break;
       
  1714       }
       
  1715     }
       
  1716   }
       
  1717 
       
  1718   /* try to union both structs */
       
  1719   field.compare = compare;
       
  1720   if (gst_structure_foreach ((GstStructure *) simplify,
       
  1721           gst_caps_structure_figure_out_union, &field)) {
       
  1722     gboolean ret = FALSE;
       
  1723 
       
  1724     /* now we know all of simplify's fields are the same in compare
       
  1725      * but at most one field: field.name */
       
  1726     if (G_IS_VALUE (&field.value)) {
       
  1727       if (gst_structure_n_fields (simplify) == gst_structure_n_fields (compare)) {
       
  1728         gst_structure_id_set_value (compare, field.name, &field.value);
       
  1729         *result = NULL;
       
  1730         ret = TRUE;
       
  1731       }
       
  1732       g_value_unset (&field.value);
       
  1733     } else if (gst_structure_n_fields (simplify) <=
       
  1734         gst_structure_n_fields (compare)) {
       
  1735       /* compare is just more specific, will be optimized away later */
       
  1736       /* FIXME: do this here? */
       
  1737       GST_LOG ("found a case that will be optimized later.");
       
  1738     } else {
       
  1739       gchar *one = gst_structure_to_string (simplify);
       
  1740       gchar *two = gst_structure_to_string (compare);
       
  1741 
       
  1742       GST_ERROR
       
  1743           ("caps mismatch: structures %s and %s claim to be possible to unify, but aren't",
       
  1744           one, two);
       
  1745       g_free (one);
       
  1746       g_free (two);
       
  1747     }
       
  1748     return ret;
       
  1749   }
       
  1750 
       
  1751   return FALSE;
       
  1752 }
       
  1753 
       
  1754 static void
       
  1755 gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
       
  1756     GstStructure * new, gint i)
       
  1757 {
       
  1758   gst_structure_set_parent_refcount (old, NULL);
       
  1759   gst_structure_free (old);
       
  1760   gst_structure_set_parent_refcount (new, &caps->refcount);
       
  1761   g_ptr_array_index (caps->structs, i) = new;
       
  1762 }
       
  1763 
       
  1764 /**
       
  1765  * gst_caps_do_simplify:
       
  1766  * @caps: a #GstCaps to simplify
       
  1767  *
       
  1768  * Modifies the given @caps inplace into a representation that represents the
       
  1769  * same set of formats, but in a simpler form.  Component structures that are
       
  1770  * identical are merged.  Component structures that have values that can be
       
  1771  * merged are also merged.
       
  1772  *
       
  1773  * Returns: TRUE, if the caps could be simplified
       
  1774  */
       
  1775 #ifdef __SYMBIAN32__
       
  1776 EXPORT_C
       
  1777 #endif
       
  1778 
       
  1779 gboolean
       
  1780 gst_caps_do_simplify (GstCaps * caps)
       
  1781 {
       
  1782   GstStructure *simplify, *compare, *result = NULL;
       
  1783   gint i, j, start;
       
  1784   gboolean changed = FALSE;
       
  1785 
       
  1786   g_return_val_if_fail (caps != NULL, FALSE);
       
  1787   g_return_val_if_fail (IS_WRITABLE (caps), FALSE);
       
  1788 
       
  1789   if (gst_caps_get_size (caps) < 2)
       
  1790     return FALSE;
       
  1791 
       
  1792   g_ptr_array_sort (caps->structs, gst_caps_compare_structures);
       
  1793 
       
  1794   start = caps->structs->len - 1;
       
  1795   for (i = caps->structs->len - 1; i >= 0; i--) {
       
  1796     simplify = gst_caps_get_structure (caps, i);
       
  1797     if (gst_structure_get_name_id (simplify) !=
       
  1798         gst_structure_get_name_id (gst_caps_get_structure (caps, start)))
       
  1799       start = i;
       
  1800     for (j = start; j >= 0; j--) {
       
  1801       if (j == i)
       
  1802         continue;
       
  1803       compare = gst_caps_get_structure (caps, j);
       
  1804       if (gst_structure_get_name_id (simplify) !=
       
  1805           gst_structure_get_name_id (compare)) {
       
  1806         break;
       
  1807       }
       
  1808       if (gst_caps_structure_simplify (&result, simplify, compare)) {
       
  1809         if (result) {
       
  1810           gst_caps_switch_structures (caps, simplify, result, i);
       
  1811           simplify = result;
       
  1812         } else {
       
  1813           gst_caps_remove_structure (caps, i);
       
  1814           start--;
       
  1815           break;
       
  1816         }
       
  1817         changed = TRUE;
       
  1818       }
       
  1819     }
       
  1820   }
       
  1821 
       
  1822   if (!changed)
       
  1823     return FALSE;
       
  1824 
       
  1825   /* gst_caps_do_simplify (caps); */
       
  1826   return TRUE;
       
  1827 }
       
  1828 
       
  1829 #ifndef GST_DISABLE_LOADSAVE
       
  1830 /**
       
  1831  * gst_caps_save_thyself:
       
  1832  * @caps: a #GstCaps structure
       
  1833  * @parent: a XML parent node
       
  1834  *
       
  1835  * Serializes a #GstCaps to XML and adds it as a child node of @parent.
       
  1836  *
       
  1837  * Returns: a XML node pointer
       
  1838  */
       
  1839 xmlNodePtr
       
  1840 gst_caps_save_thyself (const GstCaps * caps, xmlNodePtr parent)
       
  1841 {
       
  1842   char *s = gst_caps_to_string (caps);
       
  1843 
       
  1844   xmlNewChild (parent, NULL, (xmlChar *) "caps", (xmlChar *) s);
       
  1845   g_free (s);
       
  1846   return parent;
       
  1847 }
       
  1848 
       
  1849 /**
       
  1850  * gst_caps_load_thyself:
       
  1851  * @parent: a XML node
       
  1852  *
       
  1853  * Creates a #GstCaps from its XML serialization.
       
  1854  *
       
  1855  * Returns: a new #GstCaps structure
       
  1856  */
       
  1857 GstCaps *
       
  1858 gst_caps_load_thyself (xmlNodePtr parent)
       
  1859 {
       
  1860   if (strcmp ("caps", (char *) parent->name) == 0) {
       
  1861     return gst_caps_from_string ((gchar *) xmlNodeGetContent (parent));
       
  1862   }
       
  1863 
       
  1864   return NULL;
       
  1865 }
       
  1866 #endif
       
  1867 
       
  1868 /* utility */
       
  1869 
       
  1870 /**
       
  1871  * gst_caps_replace:
       
  1872  * @caps: a pointer to #GstCaps
       
  1873  * @newcaps: a #GstCaps to replace *caps
       
  1874  *
       
  1875  * Replaces *caps with @newcaps.  Unrefs the #GstCaps in the location
       
  1876  * pointed to by @caps, if applicable, then modifies @caps to point to
       
  1877  * @newcaps. An additional ref on @newcaps is taken.
       
  1878  *
       
  1879  * This function does not take any locks so you might want to lock
       
  1880  * the object owning @caps pointer.
       
  1881  */
       
  1882 #ifdef __SYMBIAN32__
       
  1883 EXPORT_C
       
  1884 #endif
       
  1885 
       
  1886 void
       
  1887 gst_caps_replace (GstCaps ** caps, GstCaps * newcaps)
       
  1888 {
       
  1889   GstCaps *oldcaps;
       
  1890 
       
  1891   g_return_if_fail (caps != NULL);
       
  1892 
       
  1893   oldcaps = *caps;
       
  1894 
       
  1895   if (newcaps != oldcaps) {
       
  1896     if (newcaps)
       
  1897       gst_caps_ref (newcaps);
       
  1898 
       
  1899     *caps = newcaps;
       
  1900 
       
  1901     if (oldcaps)
       
  1902       gst_caps_unref (oldcaps);
       
  1903   }
       
  1904 }
       
  1905 
       
  1906 /**
       
  1907  * gst_caps_to_string:
       
  1908  * @caps: a #GstCaps
       
  1909  *
       
  1910  * Converts @caps to a string representation.  This string representation
       
  1911  * can be converted back to a #GstCaps by gst_caps_from_string().
       
  1912  *
       
  1913  * For debugging purposes its easier to do something like this:
       
  1914  * <programlisting>
       
  1915  *  GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
       
  1916  * </programlisting>
       
  1917  * This prints the caps in human readble form.
       
  1918  *
       
  1919  * Returns: a newly allocated string representing @caps.
       
  1920  */
       
  1921 #ifdef __SYMBIAN32__
       
  1922 EXPORT_C
       
  1923 #endif
       
  1924 
       
  1925 gchar *
       
  1926 gst_caps_to_string (const GstCaps * caps)
       
  1927 {
       
  1928   guint i, slen;
       
  1929   GString *s;
       
  1930 
       
  1931   /* NOTE:  This function is potentially called by the debug system,
       
  1932    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
       
  1933    * should be careful to avoid recursion.  This includes any functions
       
  1934    * called by gst_caps_to_string.  In particular, calls should
       
  1935    * not use the GST_PTR_FORMAT extension.  */
       
  1936 
       
  1937   if (caps == NULL) {
       
  1938     return g_strdup ("NULL");
       
  1939   }
       
  1940   if (gst_caps_is_any (caps)) {
       
  1941     return g_strdup ("ANY");
       
  1942   }
       
  1943   if (gst_caps_is_empty (caps)) {
       
  1944     return g_strdup ("EMPTY");
       
  1945   }
       
  1946 
       
  1947   /* estimate a rough string length to avoid unnecessary reallocs in GString */
       
  1948   slen = 0;
       
  1949   for (i = 0; i < caps->structs->len; i++) {
       
  1950     slen += STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure (caps, i));
       
  1951   }
       
  1952 
       
  1953   s = g_string_sized_new (slen);
       
  1954   for (i = 0; i < caps->structs->len; i++) {
       
  1955     GstStructure *structure;
       
  1956 
       
  1957     if (i > 0) {
       
  1958       /* ';' is now added by gst_structure_to_string */
       
  1959       g_string_append_c (s, ' ');
       
  1960     }
       
  1961 
       
  1962     structure = gst_caps_get_structure (caps, i);
       
  1963     priv_gst_structure_append_to_gstring (structure, s);
       
  1964   }
       
  1965   if (s->len && s->str[s->len - 1] == ';') {
       
  1966     /* remove latest ';' */
       
  1967     s->str[--s->len] = '\0';
       
  1968   }
       
  1969   return g_string_free (s, FALSE);
       
  1970 }
       
  1971 
       
  1972 static gboolean
       
  1973 gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
       
  1974 {
       
  1975   GstStructure *structure;
       
  1976   gchar *s;
       
  1977 
       
  1978   g_return_val_if_fail (string, FALSE);
       
  1979   if (strcmp ("ANY", string) == 0) {
       
  1980     caps->flags = GST_CAPS_FLAGS_ANY;
       
  1981     return TRUE;
       
  1982   }
       
  1983   if (strcmp ("EMPTY", string) == 0) {
       
  1984     return TRUE;
       
  1985   }
       
  1986 
       
  1987   structure = gst_structure_from_string (string, &s);
       
  1988   if (structure == NULL) {
       
  1989     return FALSE;
       
  1990   }
       
  1991   gst_caps_append_structure (caps, structure);
       
  1992 
       
  1993   do {
       
  1994 
       
  1995     while (g_ascii_isspace (*s))
       
  1996       s++;
       
  1997     if (*s == '\0') {
       
  1998       break;
       
  1999     }
       
  2000     structure = gst_structure_from_string (s, &s);
       
  2001     if (structure == NULL) {
       
  2002       return FALSE;
       
  2003     }
       
  2004     gst_caps_append_structure (caps, structure);
       
  2005 
       
  2006   } while (TRUE);
       
  2007 
       
  2008   return TRUE;
       
  2009 }
       
  2010 
       
  2011 /**
       
  2012  * gst_caps_from_string:
       
  2013  * @string: a string to convert to #GstCaps
       
  2014  *
       
  2015  * Converts @caps from a string representation.
       
  2016  *
       
  2017  * Returns: a newly allocated #GstCaps
       
  2018  */
       
  2019 #ifdef __SYMBIAN32__
       
  2020 EXPORT_C
       
  2021 #endif
       
  2022 
       
  2023 GstCaps *
       
  2024 gst_caps_from_string (const gchar * string)
       
  2025 {
       
  2026   GstCaps *caps;
       
  2027 
       
  2028   caps = gst_caps_new_empty ();
       
  2029   if (gst_caps_from_string_inplace (caps, string)) {
       
  2030     return caps;
       
  2031   } else {
       
  2032     gst_caps_unref (caps);
       
  2033     return NULL;
       
  2034   }
       
  2035 }
       
  2036 
       
  2037 static void
       
  2038 gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
       
  2039 {
       
  2040   g_return_if_fail (G_IS_VALUE (src_value));
       
  2041   g_return_if_fail (G_IS_VALUE (dest_value));
       
  2042   g_return_if_fail (G_VALUE_HOLDS (src_value, GST_TYPE_CAPS));
       
  2043   g_return_if_fail (G_VALUE_HOLDS (dest_value, G_TYPE_STRING)
       
  2044       || G_VALUE_HOLDS (dest_value, G_TYPE_POINTER));
       
  2045 
       
  2046   dest_value->data[0].v_pointer =
       
  2047       gst_caps_to_string (src_value->data[0].v_pointer);
       
  2048 }
       
  2049 
       
  2050 static GstCaps *
       
  2051 gst_caps_copy_conditional (GstCaps * src)
       
  2052 {
       
  2053   if (src) {
       
  2054     return gst_caps_ref (src);
       
  2055   } else {
       
  2056     return NULL;
       
  2057   }
       
  2058 }