gstreamer_core/gst/gstcaps.c
changeset 16 8e837d1bf446
parent 0 0e761a78d257
child 30 7e817e7e631c
equal deleted inserted replaced
15:4b0c6ed43234 16:8e837d1bf446
    93   } \
    93   } \
    94 } G_STMT_END
    94 } G_STMT_END
    95 #define IS_WRITABLE(caps) \
    95 #define IS_WRITABLE(caps) \
    96   (g_atomic_int_get (&(caps)->refcount) == 1)
    96   (g_atomic_int_get (&(caps)->refcount) == 1)
    97 
    97 
    98 #if GLIB_CHECK_VERSION (2, 10, 0)
    98 /* quick way to get a caps structure at an index without doing a type or array
    99 #define ALLOC_CAPS()    g_slice_new (GstCaps)
    99  * length check */
   100 #define FREE_CAPS(caps) g_slice_free (GstCaps, caps)
   100 #define gst_caps_get_structure_unchecked(caps, index) \
   101 #else
   101      ((GstStructure *)g_ptr_array_index ((caps)->structs, (index)))
   102 #define ALLOC_CAPS()    g_new (GstCaps, 1)
   102 
   103 #define FREE_CAPS(caps) g_free (caps)
       
   104 #endif
       
   105 
   103 
   106 /* lock to protect multiple invocations of static caps to caps conversion */
   104 /* lock to protect multiple invocations of static caps to caps conversion */
   107 G_LOCK_DEFINE_STATIC (static_caps_lock);
   105 G_LOCK_DEFINE_STATIC (static_caps_lock);
   108 
   106 
   109 static void gst_caps_transform_to_string (const GValue * src_value,
   107 static void gst_caps_transform_to_string (const GValue * src_value,
   149 #endif
   147 #endif
   150 
   148 
   151 GstCaps *
   149 GstCaps *
   152 gst_caps_new_empty (void)
   150 gst_caps_new_empty (void)
   153 {
   151 {
   154   GstCaps *caps = ALLOC_CAPS ();
   152   GstCaps *caps = g_slice_new (GstCaps);
   155 
   153 
   156   caps->type = GST_TYPE_CAPS;
   154   caps->type = GST_TYPE_CAPS;
   157   caps->refcount = 1;
   155   caps->refcount = 1;
   158   caps->flags = 0;
   156   caps->flags = 0;
   159   caps->structs = g_ptr_array_new ();
   157   caps->structs = g_ptr_array_new ();
   302 GstCaps *
   300 GstCaps *
   303 gst_caps_copy (const GstCaps * caps)
   301 gst_caps_copy (const GstCaps * caps)
   304 {
   302 {
   305   GstCaps *newcaps;
   303   GstCaps *newcaps;
   306   GstStructure *structure;
   304   GstStructure *structure;
   307   guint i;
   305   guint i, n;
   308 
   306 
   309   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
   307   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
   310 
   308 
   311   newcaps = gst_caps_new_empty ();
   309   newcaps = gst_caps_new_empty ();
   312   newcaps->flags = caps->flags;
   310   newcaps->flags = caps->flags;
   313 
   311   n = caps->structs->len;
   314   for (i = 0; i < caps->structs->len; i++) {
   312 
   315     structure = gst_caps_get_structure (caps, i);
   313   for (i = 0; i < n; i++) {
       
   314     structure = gst_caps_get_structure_unchecked (caps, i);
   316     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
   315     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
   317   }
   316   }
   318 
   317 
   319   return newcaps;
   318   return newcaps;
   320 }
   319 }
   321 
   320 
   322 static void
   321 static void
   323 _gst_caps_free (GstCaps * caps)
   322 _gst_caps_free (GstCaps * caps)
   324 {
   323 {
   325   GstStructure *structure;
   324   GstStructure *structure;
   326   guint i;
   325   guint i, len;
   327 
   326 
   328   /* The refcount must be 0, but since we're only called by gst_caps_unref,
   327   /* The refcount must be 0, but since we're only called by gst_caps_unref,
   329    * don't bother testing. */
   328    * don't bother testing. */
   330 
   329   len = caps->structs->len;
   331   for (i = 0; i < caps->structs->len; i++) {
   330   for (i = 0; i < len; i++) {
   332     structure = (GstStructure *) gst_caps_get_structure (caps, i);
   331     structure = (GstStructure *) gst_caps_get_structure_unchecked (caps, i);
   333     gst_structure_set_parent_refcount (structure, NULL);
   332     gst_structure_set_parent_refcount (structure, NULL);
   334     gst_structure_free (structure);
   333     gst_structure_free (structure);
   335   }
   334   }
   336   g_ptr_array_free (caps->structs, TRUE);
   335   g_ptr_array_free (caps->structs, TRUE);
   337 #ifdef USE_POISONING
   336 #ifdef USE_POISONING
   339 #endif
   338 #endif
   340 
   339 
   341 #ifdef DEBUG_REFCOUNT
   340 #ifdef DEBUG_REFCOUNT
   342   GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
   341   GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
   343 #endif
   342 #endif
   344   FREE_CAPS (caps);
   343   g_slice_free (GstCaps, caps);
   345 }
   344 }
   346 
   345 
   347 /**
   346 /**
   348  * gst_caps_make_writable:
   347  * gst_caps_make_writable:
   349  * @caps: the #GstCaps to make writable
   348  * @caps: the #GstCaps to make writable
   511     temp.flags = 0;
   510     temp.flags = 0;
   512     temp.structs = g_ptr_array_new ();
   511     temp.structs = g_ptr_array_new ();
   513 
   512 
   514     /* initialize the caps to a refcount of 1 so the caps can be writable for
   513     /* initialize the caps to a refcount of 1 so the caps can be writable for
   515      * the next statement */
   514      * the next statement */
   516     gst_atomic_int_set (&temp.refcount, 1);
   515     temp.refcount = 1;
   517 
   516 
   518     /* convert to string */
   517     /* convert to string */
   519     if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string)))
   518     if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string)))
   520       g_critical ("Could not convert static caps \"%s\"", string);
   519       g_critical ("Could not convert static caps \"%s\"", string);
   521 
   520 
   522     /* now copy stuff over to the real caps. */
   521     /* now copy stuff over to the real caps. */
   523     caps->type = temp.type;
   522     caps->type = temp.type;
   524     caps->flags = temp.flags;
   523     caps->flags = temp.flags;
   525     caps->structs = temp.structs;
   524     caps->structs = temp.structs;
   526     /* and bump the refcount so other threads can now read */
   525     /* and bump the refcount so other threads can now read */
   527     gst_atomic_int_set (&caps->refcount, 1);
   526     g_atomic_int_set (&caps->refcount, 1);
   528 
   527 
   529     GST_CAT_LOG (GST_CAT_CAPS, "created %p", static_caps);
   528     GST_CAT_LOG (GST_CAT_CAPS, "created %p", static_caps);
   530   done:
   529   done:
   531     G_UNLOCK (static_caps_lock);
   530     G_UNLOCK (static_caps_lock);
   532   }
   531   }
   560     gpointer data)
   559     gpointer data)
   561 {
   560 {
   562   GstStructure *struct1 = (GstStructure *) data;
   561   GstStructure *struct1 = (GstStructure *) data;
   563   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
   562   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
   564 
   563 
   565   if (val1 == NULL)
   564   if (G_UNLIKELY (val1 == NULL))
   566     return FALSE;
   565     return FALSE;
   567   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
   566   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
   568     return TRUE;
   567     return TRUE;
   569   }
   568   }
   570 
   569 
   576     gpointer user_data)
   575     gpointer user_data)
   577 {
   576 {
   578   GstStructure *subtract_from = user_data;
   577   GstStructure *subtract_from = user_data;
   579   GValue subtraction = { 0, };
   578   GValue subtraction = { 0, };
   580   const GValue *other;
   579   const GValue *other;
   581   gint res;
   580 
   582 
   581   if (!(other = gst_structure_id_get_value (subtract_from, field_id)))
   583   other = gst_structure_id_get_value (subtract_from, field_id);
       
   584   if (!other) {
       
   585     /* field is missing in one set */
   582     /* field is missing in one set */
   586     return FALSE;
   583     return FALSE;
   587   }
   584 
       
   585   /* equal values are subset */
       
   586   if (gst_value_compare (other, value) == GST_VALUE_EQUAL)
       
   587     return TRUE;
       
   588 
   588   /*
   589   /*
       
   590    * 1 - [1,2] = empty
       
   591    * -> !subset
       
   592    *
   589    * [1,2] - 1 = 2
   593    * [1,2] - 1 = 2
   590    * 1 - [1,2] = ???
   594    *  -> 1 - [1,2] = empty
       
   595    *  -> subset
       
   596    *
       
   597    * [1,3] - [1,2] = 3
       
   598    * -> [1,2] - [1,3] = empty
       
   599    * -> subset
       
   600    *
       
   601    * {1,2} - {1,3} = 2
       
   602    * -> {1,3} - {1,2} = 3
       
   603    * -> !subset
       
   604    *
       
   605    *  First caps subtraction needs to return a non-empty set, second
       
   606    *  subtractions needs to give en empty set.
   591    */
   607    */
   592   if (!gst_value_subtract (&subtraction, other, value)) {
   608   if (gst_value_subtract (&subtraction, other, value)) {
   593     /* empty result -> values are the same, or first was a value and
   609     g_value_unset (&subtraction);
   594      * second was a list
   610     /* !empty result, swapping must be empty */
   595      * verify that result is empty by swapping args */
   611     if (!gst_value_subtract (&subtraction, value, other))
   596     if (!gst_value_subtract (&subtraction, value, other)) {
       
   597       return TRUE;
   612       return TRUE;
   598     }
   613 
   599     g_value_unset (&subtraction);
   614     g_value_unset (&subtraction);
   600     return FALSE;
   615   }
   601   }
   616   return FALSE;
   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 }
   617 }
   613 
   618 
   614 static gboolean
   619 static gboolean
   615 gst_caps_structure_is_subset (const GstStructure * minuend,
   620 gst_caps_structure_is_subset (const GstStructure * minuend,
   616     const GstStructure * subtrahend)
   621     const GstStructure * subtrahend)
   650   g_return_if_fail (IS_WRITABLE (caps2));
   655   g_return_if_fail (IS_WRITABLE (caps2));
   651 
   656 
   652 #ifdef USE_POISONING
   657 #ifdef USE_POISONING
   653   CAPS_POISON (caps2);
   658   CAPS_POISON (caps2);
   654 #endif
   659 #endif
   655   if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2)) {
   660   if (G_UNLIKELY (gst_caps_is_any (caps1) || gst_caps_is_any (caps2))) {
   656     /* FIXME: this leaks */
   661     /* FIXME: this leaks */
   657     caps1->flags |= GST_CAPS_FLAGS_ANY;
   662     caps1->flags |= GST_CAPS_FLAGS_ANY;
   658     for (i = caps2->structs->len - 1; i >= 0; i--) {
   663     for (i = caps2->structs->len - 1; i >= 0; i--) {
   659       structure = gst_caps_remove_and_get_structure (caps2, i);
   664       structure = gst_caps_remove_and_get_structure (caps2, i);
   660       gst_structure_free (structure);
   665       gst_structure_free (structure);
   661     }
   666     }
   662   } else {
   667   } else {
   663     int len = caps2->structs->len;
   668     for (i = caps2->structs->len; i; i--) {
   664 
       
   665     for (i = 0; i < len; i++) {
       
   666       structure = gst_caps_remove_and_get_structure (caps2, 0);
   669       structure = gst_caps_remove_and_get_structure (caps2, 0);
   667       gst_caps_append_structure (caps1, structure);
   670       gst_caps_append_structure (caps1, structure);
   668     }
   671     }
   669   }
   672   }
   670   gst_caps_unref (caps2);       /* guaranteed to free it */
   673   gst_caps_unref (caps2);       /* guaranteed to free it */
   698   g_return_if_fail (IS_WRITABLE (caps2));
   701   g_return_if_fail (IS_WRITABLE (caps2));
   699 
   702 
   700 #ifdef USE_POISONING
   703 #ifdef USE_POISONING
   701   CAPS_POISON (caps2);
   704   CAPS_POISON (caps2);
   702 #endif
   705 #endif
   703   if (gst_caps_is_any (caps1)) {
   706   if (G_UNLIKELY (gst_caps_is_any (caps1))) {
   704     for (i = caps2->structs->len - 1; i >= 0; i--) {
   707     for (i = caps2->structs->len - 1; i >= 0; i--) {
   705       structure = gst_caps_remove_and_get_structure (caps2, i);
   708       structure = gst_caps_remove_and_get_structure (caps2, i);
   706       gst_structure_free (structure);
   709       gst_structure_free (structure);
   707     }
   710     }
   708   } else if (gst_caps_is_any (caps2)) {
   711   } else if (G_UNLIKELY (gst_caps_is_any (caps2))) {
   709     caps1->flags |= GST_CAPS_FLAGS_ANY;
   712     caps1->flags |= GST_CAPS_FLAGS_ANY;
   710     for (i = caps1->structs->len - 1; i >= 0; i--) {
   713     for (i = caps1->structs->len - 1; i >= 0; i--) {
   711       structure = gst_caps_remove_and_get_structure (caps1, i);
   714       structure = gst_caps_remove_and_get_structure (caps1, i);
   712       gst_structure_free (structure);
   715       gst_structure_free (structure);
   713     }
   716     }
   714   } else {
   717   } else {
   715     int len = caps2->structs->len;
   718     for (i = caps2->structs->len; i; i--) {
   716 
       
   717     for (i = 0; i < len; i++) {
       
   718       structure = gst_caps_remove_and_get_structure (caps2, 0);
   719       structure = gst_caps_remove_and_get_structure (caps2, 0);
   719       gst_caps_merge_structure (caps1, structure);
   720       gst_caps_merge_structure (caps1, structure);
   720     }
   721     }
   721     /* this is too naive
   722     /* this is too naive
   722        GstCaps *com = gst_caps_intersect (caps1, caps2);
   723        GstCaps *com = gst_caps_intersect (caps1, caps2);
   815     STRUCTURE_POISON (structure);
   816     STRUCTURE_POISON (structure);
   816 #endif
   817 #endif
   817 #endif
   818 #endif
   818     /* check each structure */
   819     /* check each structure */
   819     for (i = caps->structs->len - 1; i >= 0; i--) {
   820     for (i = caps->structs->len - 1; i >= 0; i--) {
   820       structure1 = gst_caps_get_structure (caps, i);
   821       structure1 = gst_caps_get_structure_unchecked (caps, i);
   821       /* if structure is a subset of structure1, then skip it */
   822       /* if structure is a subset of structure1, then skip it */
   822       if (gst_caps_structure_is_subset (structure1, structure)) {
   823       if (gst_caps_structure_is_subset (structure1, structure)) {
   823         unique = FALSE;
   824         unique = FALSE;
   824         break;
   825         break;
   825       }
   826       }
   863  * returns it.
   864  * returns it.
   864  *
   865  *
   865  * WARNING: This function takes a const GstCaps *, but returns a
   866  * WARNING: This function takes a const GstCaps *, but returns a
   866  * non-const GstStructure *.  This is for programming convenience --
   867  * non-const GstStructure *.  This is for programming convenience --
   867  * the caller should be aware that structures inside a constant
   868  * the caller should be aware that structures inside a constant
   868  * #GstCaps should not be modified.
   869  * #GstCaps should not be modified. However, if you know the caps
       
   870  * are writable, either because you have just copied them or made
       
   871  * them writable with gst_caps_make_writable(), you may modify the
       
   872  * structure returned in the usual way, e.g. with functions like
       
   873  * gst_structure_set_simple().
       
   874  *
       
   875  * You do not need to free or unref the structure returned, it
       
   876  * belongs to the #GstCaps.
   869  *
   877  *
   870  * Returns: a pointer to the #GstStructure corresponding to @index
   878  * Returns: a pointer to the #GstStructure corresponding to @index
   871  */
   879  */
   872 #ifdef __SYMBIAN32__
   880 #ifdef __SYMBIAN32__
   873 EXPORT_C
   881 EXPORT_C
   877 gst_caps_get_structure (const GstCaps * caps, guint index)
   885 gst_caps_get_structure (const GstCaps * caps, guint index)
   878 {
   886 {
   879   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
   887   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
   880   g_return_val_if_fail (index < caps->structs->len, NULL);
   888   g_return_val_if_fail (index < caps->structs->len, NULL);
   881 
   889 
   882   return g_ptr_array_index (caps->structs, index);
   890   return gst_caps_get_structure_unchecked (caps, index);
   883 }
   891 }
   884 
   892 
   885 /**
   893 /**
   886  * gst_caps_copy_nth:
   894  * gst_caps_copy_nth:
   887  * @caps: the #GstCaps to copy
   895  * @caps: the #GstCaps to copy
   905   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
   913   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
   906 
   914 
   907   newcaps = gst_caps_new_empty ();
   915   newcaps = gst_caps_new_empty ();
   908   newcaps->flags = caps->flags;
   916   newcaps->flags = caps->flags;
   909 
   917 
   910   if (caps->structs->len > nth) {
   918   if (G_LIKELY (caps->structs->len > nth)) {
   911     structure = gst_caps_get_structure (caps, nth);
   919     structure = gst_caps_get_structure_unchecked (caps, nth);
   912     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
   920     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
   913   }
   921   }
   914 
   922 
   915   return newcaps;
   923   return newcaps;
   916 }
   924 }
   953 #ifdef __SYMBIAN32__
   961 #ifdef __SYMBIAN32__
   954 EXPORT_C
   962 EXPORT_C
   955 #endif
   963 #endif
   956 
   964 
   957 void
   965 void
   958 gst_caps_set_simple (GstCaps * caps, char *field, ...)
   966 gst_caps_set_simple (GstCaps * caps, const char *field, ...)
   959 {
   967 {
   960   GstStructure *structure;
   968   GstStructure *structure;
   961   va_list var_args;
   969   va_list var_args;
   962 
   970 
   963   g_return_if_fail (GST_IS_CAPS (caps));
   971   g_return_if_fail (GST_IS_CAPS (caps));
   964   g_return_if_fail (caps->structs->len == 1);
   972   g_return_if_fail (caps->structs->len == 1);
   965   g_return_if_fail (IS_WRITABLE (caps));
   973   g_return_if_fail (IS_WRITABLE (caps));
   966 
   974 
   967   structure = gst_caps_get_structure (caps, 0);
   975   structure = gst_caps_get_structure_unchecked (caps, 0);
   968 
   976 
   969   va_start (var_args, field);
   977   va_start (var_args, field);
   970   gst_structure_set_valist (structure, field, var_args);
   978   gst_structure_set_valist (structure, field, var_args);
   971   va_end (var_args);
   979   va_end (var_args);
   972 }
   980 }
   984 #ifdef __SYMBIAN32__
   992 #ifdef __SYMBIAN32__
   985 EXPORT_C
   993 EXPORT_C
   986 #endif
   994 #endif
   987 
   995 
   988 void
   996 void
   989 gst_caps_set_simple_valist (GstCaps * caps, char *field, va_list varargs)
   997 gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
   990 {
   998 {
   991   GstStructure *structure;
   999   GstStructure *structure;
   992 
  1000 
   993   g_return_if_fail (GST_IS_CAPS (caps));
  1001   g_return_if_fail (GST_IS_CAPS (caps));
   994   g_return_if_fail (caps->structs->len == 1);
  1002   g_return_if_fail (caps->structs->len == 1);
   995   g_return_if_fail (IS_WRITABLE (caps));
  1003   g_return_if_fail (IS_WRITABLE (caps));
   996 
  1004 
   997   structure = gst_caps_get_structure (caps, 0);
  1005   structure = gst_caps_get_structure_unchecked (caps, 0);
   998 
  1006 
   999   gst_structure_set_valist (structure, field, varargs);
  1007   gst_structure_set_valist (structure, field, varargs);
  1000 }
  1008 }
  1001 
  1009 
  1002 /* tests */
  1010 /* tests */
  1073   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
  1081   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
  1074 
  1082 
  1075   if (caps->structs->len != 1)
  1083   if (caps->structs->len != 1)
  1076     return FALSE;
  1084     return FALSE;
  1077 
  1085 
  1078   structure = gst_caps_get_structure (caps, 0);
  1086   structure = gst_caps_get_structure_unchecked (caps, 0);
  1079 
  1087 
  1080   return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
  1088   return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
  1081 }
  1089 }
  1082 
  1090 
  1083 /**
  1091 /**
  1100   GstStructure *struct1, *struct2;
  1108   GstStructure *struct1, *struct2;
  1101 
  1109 
  1102   g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
  1110   g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
  1103   g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
  1111   g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
  1104 
  1112 
  1105   struct1 = gst_caps_get_structure (caps1, 0);
  1113   struct1 = gst_caps_get_structure_unchecked (caps1, 0);
  1106   struct2 = gst_caps_get_structure (caps2, 0);
  1114   struct2 = gst_caps_get_structure_unchecked (caps2, 0);
  1107 
  1115 
  1108   if (struct1->name != struct2->name) {
  1116   if (struct1->name != struct2->name) {
  1109     return FALSE;
  1117     return FALSE;
  1110   }
  1118   }
  1111   if (struct1->fields->len != struct2->fields->len) {
  1119   if (struct1->fields->len != struct2->fields->len) {
  1193 #endif
  1201 #endif
  1194 
  1202 
  1195 gboolean
  1203 gboolean
  1196 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
  1204 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
  1197 {
  1205 {
       
  1206   /* FIXME 0.11: NULL pointers are no valid Caps but indicate an error
       
  1207    * So there should be an assertion that caps1 and caps2 != NULL */
       
  1208 
  1198   /* NULL <-> NULL is allowed here */
  1209   /* NULL <-> NULL is allowed here */
  1199   if (caps1 == caps2)
  1210   if (G_UNLIKELY (caps1 == caps2))
  1200     return TRUE;
  1211     return TRUE;
  1201 
  1212 
  1202   /* one of them NULL => they are different (can't be both NULL because
  1213   /* one of them NULL => they are different (can't be both NULL because
  1203    * we checked that above) */
  1214    * we checked that above) */
  1204   if (caps1 == NULL || caps2 == NULL)
  1215   if (G_UNLIKELY (caps1 == NULL || caps2 == NULL))
  1205     return FALSE;
  1216     return FALSE;
  1206 
  1217 
  1207   if (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2))
  1218   if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
  1208     return gst_caps_is_equal_fixed (caps1, caps2);
  1219     return gst_caps_is_equal_fixed (caps1, caps2);
  1209 
  1220 
  1210   return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
  1221   return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
  1211 }
  1222 }
  1212 
  1223 
  1224 {
  1235 {
  1225   IntersectData *idata = (IntersectData *) data;
  1236   IntersectData *idata = (IntersectData *) data;
  1226   GValue dest_value = { 0 };
  1237   GValue dest_value = { 0 };
  1227   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
  1238   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
  1228 
  1239 
  1229   if (val2 == NULL) {
  1240   if (G_UNLIKELY (val2 == NULL)) {
  1230     gst_structure_id_set_value (idata->dest, id, val1);
  1241     gst_structure_id_set_value (idata->dest, id, val1);
  1231   } else if (idata->first_run) {
  1242   } else if (idata->first_run) {
  1232     if (gst_value_intersect (&dest_value, val1, val2)) {
  1243     if (gst_value_intersect (&dest_value, val1, val2)) {
  1233       gst_structure_id_set_value (idata->dest, id, &dest_value);
  1244       gst_structure_id_set_value (idata->dest, id, &dest_value);
  1234       g_value_unset (&dest_value);
  1245       g_value_unset (&dest_value);
  1247   IntersectData data;
  1258   IntersectData data;
  1248 
  1259 
  1249   g_return_val_if_fail (struct1 != NULL, NULL);
  1260   g_return_val_if_fail (struct1 != NULL, NULL);
  1250   g_return_val_if_fail (struct2 != NULL, NULL);
  1261   g_return_val_if_fail (struct2 != NULL, NULL);
  1251 
  1262 
  1252   if (struct1->name != struct2->name)
  1263   if (G_UNLIKELY (struct1->name != struct2->name))
  1253     return NULL;
  1264     return NULL;
  1254 
  1265 
  1255   data.dest = gst_structure_id_empty_new (struct1->name);
  1266   data.dest = gst_structure_id_empty_new (struct1->name);
  1256   data.intersect = struct2;
  1267   data.intersect = struct2;
  1257   data.first_run = TRUE;
  1268   data.first_run = TRUE;
  1258   if (!gst_structure_foreach ((GstStructure *) struct1,
  1269   if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
  1259           gst_caps_structure_intersect_field, &data))
  1270               gst_caps_structure_intersect_field, &data)))
  1260     goto error;
  1271     goto error;
  1261 
  1272 
  1262   data.intersect = struct1;
  1273   data.intersect = struct1;
  1263   data.first_run = FALSE;
  1274   data.first_run = FALSE;
  1264   if (!gst_structure_foreach ((GstStructure *) struct2,
  1275   if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2,
  1265           gst_caps_structure_intersect_field, &data))
  1276               gst_caps_structure_intersect_field, &data)))
  1266     goto error;
  1277     goto error;
  1267 
  1278 
  1268   return data.dest;
  1279   return data.dest;
  1269 
  1280 
  1270 error:
  1281 error:
  1330 
  1341 
  1331 GstCaps *
  1342 GstCaps *
  1332 gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
  1343 gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
  1333 {
  1344 {
  1334   guint64 i;                    /* index can be up to 2 * G_MAX_UINT */
  1345   guint64 i;                    /* index can be up to 2 * G_MAX_UINT */
  1335   guint j, k;
  1346   guint j, k, len1, len2;
  1336 
  1347 
  1337   GstStructure *struct1;
  1348   GstStructure *struct1;
  1338   GstStructure *struct2;
  1349   GstStructure *struct2;
  1339   GstCaps *dest;
  1350   GstCaps *dest;
  1340   GstStructure *istruct;
  1351   GstStructure *istruct;
  1341 
  1352 
  1342   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
  1353   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
  1343   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
  1354   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
  1344 
  1355 
  1345   /* caps are exactly the same pointers, just copy one caps */
  1356   /* caps are exactly the same pointers, just copy one caps */
  1346   if (caps1 == caps2)
  1357   if (G_UNLIKELY (caps1 == caps2))
  1347     return gst_caps_copy (caps1);
  1358     return gst_caps_copy (caps1);
  1348 
  1359 
  1349   /* empty caps on either side, return empty */
  1360   /* empty caps on either side, return empty */
  1350   if (gst_caps_is_empty (caps1) || gst_caps_is_empty (caps2))
  1361   if (G_UNLIKELY (gst_caps_is_empty (caps1) || gst_caps_is_empty (caps2)))
  1351     return gst_caps_new_empty ();
  1362     return gst_caps_new_empty ();
  1352 
  1363 
  1353   /* one of the caps is any, just copy the other caps */
  1364   /* one of the caps is any, just copy the other caps */
  1354   if (gst_caps_is_any (caps1))
  1365   if (G_UNLIKELY (gst_caps_is_any (caps1)))
  1355     return gst_caps_copy (caps2);
  1366     return gst_caps_copy (caps2);
  1356   if (gst_caps_is_any (caps2))
  1367   if (G_UNLIKELY (gst_caps_is_any (caps2)))
  1357     return gst_caps_copy (caps1);
  1368     return gst_caps_copy (caps1);
  1358 
  1369 
  1359   dest = gst_caps_new_empty ();
  1370   dest = gst_caps_new_empty ();
  1360 
  1371 
  1361   /* run zigzag on top line then right line, this preserves the caps order
  1372   /* run zigzag on top line then right line, this preserves the caps order
  1372    *
  1383    *
  1373    * First we iterate over the caps1 structures (top line) intersecting
  1384    * First we iterate over the caps1 structures (top line) intersecting
  1374    * the structures diagonally down, then we iterate over the caps2
  1385    * the structures diagonally down, then we iterate over the caps2
  1375    * structures.
  1386    * structures.
  1376    */
  1387    */
  1377   for (i = 0; i < caps1->structs->len + caps2->structs->len - 1; i++) {
  1388   len1 = caps1->structs->len;
       
  1389   len2 = caps2->structs->len;
       
  1390   for (i = 0; i < len1 + len2 - 1; i++) {
  1378     /* caps1 index goes from 0 to caps1->structs->len-1 */
  1391     /* caps1 index goes from 0 to caps1->structs->len-1 */
  1379     j = MIN (i, caps1->structs->len - 1);
  1392     j = MIN (i, len1 - 1);
  1380     /* caps2 index stays 0 until i reaches caps1->structs->len, then it counts
  1393     /* caps2 index stays 0 until i reaches caps1->structs->len, then it counts
  1381      * up from 1 to caps2->structs->len - 1 */
  1394      * up from 1 to caps2->structs->len - 1 */
  1382     k = MAX (0, i - j);
  1395     k = MAX (0, i - j);
  1383 
  1396 
  1384     /* now run the diagonal line, end condition is the left or bottom
  1397     /* now run the diagonal line, end condition is the left or bottom
  1385      * border */
  1398      * border */
  1386     while (k < caps2->structs->len) {
  1399     while (k < len2) {
  1387       struct1 = gst_caps_get_structure (caps1, j);
  1400       struct1 = gst_caps_get_structure_unchecked (caps1, j);
  1388       struct2 = gst_caps_get_structure (caps2, k);
  1401       struct2 = gst_caps_get_structure_unchecked (caps2, k);
  1389 
  1402 
  1390       istruct = gst_caps_structure_intersect (struct1, struct2);
  1403       istruct = gst_caps_structure_intersect (struct1, struct2);
  1391 
  1404 
  1392       gst_caps_append_structure (dest, istruct);
  1405       gst_caps_append_structure (dest, istruct);
  1393       /* move down left */
  1406       /* move down left */
  1394       k++;
  1407       k++;
  1395       if (j == 0)
  1408       if (G_UNLIKELY (j == 0))
  1396         break;                  /* so we don't roll back to G_MAXUINT */
  1409         break;                  /* so we don't roll back to G_MAXUINT */
  1397       j--;
  1410       j--;
  1398     }
  1411     }
  1399   }
  1412   }
  1400   return dest;
  1413   return dest;
  1476 #endif
  1489 #endif
  1477 
  1490 
  1478 GstCaps *
  1491 GstCaps *
  1479 gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
  1492 gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
  1480 {
  1493 {
  1481   guint i, j;
  1494   guint i, j, sublen;
  1482   GstStructure *min;
  1495   GstStructure *min;
  1483   GstStructure *sub;
  1496   GstStructure *sub;
  1484   GstCaps *dest = NULL, *src;
  1497   GstCaps *dest = NULL, *src;
  1485 
  1498 
  1486   g_return_val_if_fail (minuend != NULL, NULL);
  1499   g_return_val_if_fail (minuend != NULL, NULL);
  1496      The reason we need this is that there is no definition about what
  1509      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
  1510      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.
  1511      You can only remove everything or nothing and that is done above.
  1499      Note: there's a test that checks this behaviour. */
  1512      Note: there's a test that checks this behaviour. */
  1500   g_return_val_if_fail (!gst_caps_is_any (minuend), NULL);
  1513   g_return_val_if_fail (!gst_caps_is_any (minuend), NULL);
  1501   g_assert (subtrahend->structs->len > 0);
  1514   sublen = subtrahend->structs->len;
       
  1515   g_assert (sublen > 0);
  1502 
  1516 
  1503   src = gst_caps_copy (minuend);
  1517   src = gst_caps_copy (minuend);
  1504   for (i = 0; i < subtrahend->structs->len; i++) {
  1518   for (i = 0; i < sublen; i++) {
  1505     sub = gst_caps_get_structure (subtrahend, i);
  1519     guint srclen;
       
  1520 
       
  1521     sub = gst_caps_get_structure_unchecked (subtrahend, i);
  1506     if (dest) {
  1522     if (dest) {
  1507       gst_caps_unref (src);
  1523       gst_caps_unref (src);
  1508       src = dest;
  1524       src = dest;
  1509     }
  1525     }
  1510     dest = gst_caps_new_empty ();
  1526     dest = gst_caps_new_empty ();
  1511     for (j = 0; j < src->structs->len; j++) {
  1527     srclen = src->structs->len;
  1512       min = gst_caps_get_structure (src, j);
  1528     for (j = 0; j < srclen; j++) {
       
  1529       min = gst_caps_get_structure_unchecked (src, j);
  1513       if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub)) {
  1530       if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub)) {
  1514         GSList *list;
  1531         GSList *list;
  1515 
  1532 
  1516         if (gst_caps_structure_subtract (&list, min, sub)) {
  1533         if (gst_caps_structure_subtract (&list, min, sub)) {
  1517           GSList *walk;
  1534           GSList *walk;
  1556 gst_caps_union (const GstCaps * caps1, const GstCaps * caps2)
  1573 gst_caps_union (const GstCaps * caps1, const GstCaps * caps2)
  1557 {
  1574 {
  1558   GstCaps *dest1;
  1575   GstCaps *dest1;
  1559   GstCaps *dest2;
  1576   GstCaps *dest2;
  1560 
  1577 
       
  1578   /* NULL pointers are no correct GstCaps */
       
  1579   g_return_val_if_fail (caps1 != NULL, NULL);
       
  1580   g_return_val_if_fail (caps2 != NULL, NULL);
       
  1581 
       
  1582   if (gst_caps_is_empty (caps1))
       
  1583     return gst_caps_copy (caps2);
       
  1584 
       
  1585   if (gst_caps_is_empty (caps2))
       
  1586     return gst_caps_copy (caps1);
       
  1587 
  1561   if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2))
  1588   if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2))
  1562     return gst_caps_new_any ();
  1589     return gst_caps_new_any ();
  1563 
  1590 
  1564   dest1 = gst_caps_copy (caps1);
  1591   dest1 = gst_caps_copy (caps1);
  1565   dest2 = gst_caps_copy (caps2);
  1592   dest2 = gst_caps_copy (caps2);
  1582   NormalizeForeach *nf = (NormalizeForeach *) ptr;
  1609   NormalizeForeach *nf = (NormalizeForeach *) ptr;
  1583   GValue val = { 0 };
  1610   GValue val = { 0 };
  1584   guint i;
  1611   guint i;
  1585 
  1612 
  1586   if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
  1613   if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
  1587     for (i = 1; i < gst_value_list_get_size (value); i++) {
  1614     guint len = gst_value_list_get_size (value);
       
  1615     for (i = 1; i < len; i++) {
  1588       const GValue *v = gst_value_list_get_value (value, i);
  1616       const GValue *v = gst_value_list_get_value (value, i);
  1589       GstStructure *structure = gst_structure_copy (nf->structure);
  1617       GstStructure *structure = gst_structure_copy (nf->structure);
  1590 
  1618 
  1591       gst_structure_id_set_value (structure, field_id, v);
  1619       gst_structure_id_set_value (structure, field_id, v);
  1592       gst_caps_append_structure (nf->caps, structure);
  1620       gst_caps_append_structure (nf->caps, structure);
  1618 GstCaps *
  1646 GstCaps *
  1619 gst_caps_normalize (const GstCaps * caps)
  1647 gst_caps_normalize (const GstCaps * caps)
  1620 {
  1648 {
  1621   NormalizeForeach nf;
  1649   NormalizeForeach nf;
  1622   GstCaps *newcaps;
  1650   GstCaps *newcaps;
  1623   guint i;
  1651   guint i, nlen;
  1624 
  1652 
  1625   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
  1653   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
  1626 
  1654 
  1627   newcaps = gst_caps_copy (caps);
  1655   newcaps = gst_caps_copy (caps);
  1628   nf.caps = newcaps;
  1656   nf.caps = newcaps;
  1629 
  1657   nlen = newcaps->structs->len;
  1630   for (i = 0; i < newcaps->structs->len; i++) {
  1658 
  1631     nf.structure = gst_caps_get_structure (newcaps, i);
  1659   for (i = 0; i < nlen; i++) {
       
  1660     nf.structure = gst_caps_get_structure_unchecked (newcaps, i);
  1632 
  1661 
  1633     while (!gst_structure_foreach (nf.structure,
  1662     while (!gst_structure_foreach (nf.structure,
  1634             gst_caps_normalize_foreach, &nf));
  1663             gst_caps_normalize_foreach, &nf));
  1635   }
  1664   }
  1636 
  1665 
  1791 
  1820 
  1792   g_ptr_array_sort (caps->structs, gst_caps_compare_structures);
  1821   g_ptr_array_sort (caps->structs, gst_caps_compare_structures);
  1793 
  1822 
  1794   start = caps->structs->len - 1;
  1823   start = caps->structs->len - 1;
  1795   for (i = caps->structs->len - 1; i >= 0; i--) {
  1824   for (i = caps->structs->len - 1; i >= 0; i--) {
  1796     simplify = gst_caps_get_structure (caps, i);
  1825     simplify = gst_caps_get_structure_unchecked (caps, i);
  1797     if (gst_structure_get_name_id (simplify) !=
  1826     if (gst_structure_get_name_id (simplify) !=
  1798         gst_structure_get_name_id (gst_caps_get_structure (caps, start)))
  1827         gst_structure_get_name_id (gst_caps_get_structure_unchecked (caps,
       
  1828                 start)))
  1799       start = i;
  1829       start = i;
  1800     for (j = start; j >= 0; j--) {
  1830     for (j = start; j >= 0; j--) {
  1801       if (j == i)
  1831       if (j == i)
  1802         continue;
  1832         continue;
  1803       compare = gst_caps_get_structure (caps, j);
  1833       compare = gst_caps_get_structure_unchecked (caps, j);
  1804       if (gst_structure_get_name_id (simplify) !=
  1834       if (gst_structure_get_name_id (simplify) !=
  1805           gst_structure_get_name_id (compare)) {
  1835           gst_structure_get_name_id (compare)) {
  1806         break;
  1836         break;
  1807       }
  1837       }
  1808       if (gst_caps_structure_simplify (&result, simplify, compare)) {
  1838       if (gst_caps_structure_simplify (&result, simplify, compare)) {
  1909  *
  1939  *
  1910  * Converts @caps to a string representation.  This string representation
  1940  * Converts @caps to a string representation.  This string representation
  1911  * can be converted back to a #GstCaps by gst_caps_from_string().
  1941  * can be converted back to a #GstCaps by gst_caps_from_string().
  1912  *
  1942  *
  1913  * For debugging purposes its easier to do something like this:
  1943  * For debugging purposes its easier to do something like this:
  1914  * <programlisting>
  1944  * |[
  1915  *  GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
  1945  * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
  1916  * </programlisting>
  1946  * ]|
  1917  * This prints the caps in human readble form.
  1947  * This prints the caps in human readble form.
  1918  *
  1948  *
  1919  * Returns: a newly allocated string representing @caps.
  1949  * Returns: a newly allocated string representing @caps.
  1920  */
  1950  */
  1921 #ifdef __SYMBIAN32__
  1951 #ifdef __SYMBIAN32__
  1923 #endif
  1953 #endif
  1924 
  1954 
  1925 gchar *
  1955 gchar *
  1926 gst_caps_to_string (const GstCaps * caps)
  1956 gst_caps_to_string (const GstCaps * caps)
  1927 {
  1957 {
  1928   guint i, slen;
  1958   guint i, slen, clen;
  1929   GString *s;
  1959   GString *s;
  1930 
  1960 
  1931   /* NOTE:  This function is potentially called by the debug system,
  1961   /* NOTE:  This function is potentially called by the debug system,
  1932    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
  1962    * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.)
  1933    * should be careful to avoid recursion.  This includes any functions
  1963    * should be careful to avoid recursion.  This includes any functions
  1944     return g_strdup ("EMPTY");
  1974     return g_strdup ("EMPTY");
  1945   }
  1975   }
  1946 
  1976 
  1947   /* estimate a rough string length to avoid unnecessary reallocs in GString */
  1977   /* estimate a rough string length to avoid unnecessary reallocs in GString */
  1948   slen = 0;
  1978   slen = 0;
  1949   for (i = 0; i < caps->structs->len; i++) {
  1979   clen = caps->structs->len;
  1950     slen += STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure (caps, i));
  1980   for (i = 0; i < clen; i++) {
       
  1981     slen +=
       
  1982         STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked (caps,
       
  1983             i));
  1951   }
  1984   }
  1952 
  1985 
  1953   s = g_string_sized_new (slen);
  1986   s = g_string_sized_new (slen);
  1954   for (i = 0; i < caps->structs->len; i++) {
  1987   for (i = 0; i < clen; i++) {
  1955     GstStructure *structure;
  1988     GstStructure *structure;
  1956 
  1989 
  1957     if (i > 0) {
  1990     if (i > 0) {
  1958       /* ';' is now added by gst_structure_to_string */
  1991       /* ';' is now added by gst_structure_to_string */
  1959       g_string_append_c (s, ' ');
  1992       g_string_append_c (s, ' ');
  1960     }
  1993     }
  1961 
  1994 
  1962     structure = gst_caps_get_structure (caps, i);
  1995     structure = gst_caps_get_structure_unchecked (caps, i);
  1963     priv_gst_structure_append_to_gstring (structure, s);
  1996     priv_gst_structure_append_to_gstring (structure, s);
  1964   }
  1997   }
  1965   if (s->len && s->str[s->len - 1] == ';') {
  1998   if (s->len && s->str[s->len - 1] == ';') {
  1966     /* remove latest ';' */
  1999     /* remove latest ';' */
  1967     s->str[--s->len] = '\0';
  2000     s->str[--s->len] = '\0';