gstreamer_core/gst/gstcaps.c
branchRCL_3
changeset 30 7e817e7e631c
parent 29 567bb019e3e3
--- a/gstreamer_core/gst/gstcaps.c	Tue Aug 31 15:30:33 2010 +0300
+++ b/gstreamer_core/gst/gstcaps.c	Wed Sep 01 12:16:41 2010 +0100
@@ -95,11 +95,13 @@
 #define IS_WRITABLE(caps) \
   (g_atomic_int_get (&(caps)->refcount) == 1)
 
-/* quick way to get a caps structure at an index without doing a type or array
- * length check */
-#define gst_caps_get_structure_unchecked(caps, index) \
-     ((GstStructure *)g_ptr_array_index ((caps)->structs, (index)))
-
+#if GLIB_CHECK_VERSION (2, 10, 0)
+#define ALLOC_CAPS()    g_slice_new (GstCaps)
+#define FREE_CAPS(caps) g_slice_free (GstCaps, caps)
+#else
+#define ALLOC_CAPS()    g_new (GstCaps, 1)
+#define FREE_CAPS(caps) g_free (caps)
+#endif
 
 /* lock to protect multiple invocations of static caps to caps conversion */
 G_LOCK_DEFINE_STATIC (static_caps_lock);
@@ -149,7 +151,7 @@
 GstCaps *
 gst_caps_new_empty (void)
 {
-  GstCaps *caps = g_slice_new (GstCaps);
+  GstCaps *caps = ALLOC_CAPS ();
 
   caps->type = GST_TYPE_CAPS;
   caps->refcount = 1;
@@ -302,16 +304,15 @@
 {
   GstCaps *newcaps;
   GstStructure *structure;
-  guint i, n;
+  guint i;
 
   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
   newcaps = gst_caps_new_empty ();
   newcaps->flags = caps->flags;
-  n = caps->structs->len;
 
-  for (i = 0; i < n; i++) {
-    structure = gst_caps_get_structure_unchecked (caps, i);
+  for (i = 0; i < caps->structs->len; i++) {
+    structure = gst_caps_get_structure (caps, i);
     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
   }
 
@@ -322,13 +323,13 @@
 _gst_caps_free (GstCaps * caps)
 {
   GstStructure *structure;
-  guint i, len;
+  guint i;
 
   /* The refcount must be 0, but since we're only called by gst_caps_unref,
    * don't bother testing. */
-  len = caps->structs->len;
-  for (i = 0; i < len; i++) {
-    structure = (GstStructure *) gst_caps_get_structure_unchecked (caps, i);
+
+  for (i = 0; i < caps->structs->len; i++) {
+    structure = (GstStructure *) gst_caps_get_structure (caps, i);
     gst_structure_set_parent_refcount (structure, NULL);
     gst_structure_free (structure);
   }
@@ -340,7 +341,7 @@
 #ifdef DEBUG_REFCOUNT
   GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
 #endif
-  g_slice_free (GstCaps, caps);
+  FREE_CAPS (caps);
 }
 
 /**
@@ -512,7 +513,7 @@
 
     /* initialize the caps to a refcount of 1 so the caps can be writable for
      * the next statement */
-    temp.refcount = 1;
+    gst_atomic_int_set (&temp.refcount, 1);
 
     /* convert to string */
     if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string)))
@@ -523,7 +524,7 @@
     caps->flags = temp.flags;
     caps->structs = temp.structs;
     /* and bump the refcount so other threads can now read */
-    g_atomic_int_set (&caps->refcount, 1);
+    gst_atomic_int_set (&caps->refcount, 1);
 
     GST_CAT_LOG (GST_CAT_CAPS, "created %p", static_caps);
   done:
@@ -561,7 +562,7 @@
   GstStructure *struct1 = (GstStructure *) data;
   const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
 
-  if (G_UNLIKELY (val1 == NULL))
+  if (val1 == NULL)
     return FALSE;
   if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
     return TRUE;
@@ -577,43 +578,37 @@
   GstStructure *subtract_from = user_data;
   GValue subtraction = { 0, };
   const GValue *other;
+  gint res;
 
-  if (!(other = gst_structure_id_get_value (subtract_from, field_id)))
+  other = gst_structure_id_get_value (subtract_from, field_id);
+  if (!other) {
     /* field is missing in one set */
     return FALSE;
-
-  /* equal values are subset */
-  if (gst_value_compare (other, value) == GST_VALUE_EQUAL)
-    return TRUE;
-
+  }
   /*
-   * 1 - [1,2] = empty
-   * -> !subset
-   *
    * [1,2] - 1 = 2
-   *  -> 1 - [1,2] = empty
-   *  -> subset
-   *
-   * [1,3] - [1,2] = 3
-   * -> [1,2] - [1,3] = empty
-   * -> subset
-   *
-   * {1,2} - {1,3} = 2
-   * -> {1,3} - {1,2} = 3
-   * -> !subset
-   *
-   *  First caps subtraction needs to return a non-empty set, second
-   *  subtractions needs to give en empty set.
+   * 1 - [1,2] = ???
    */
-  if (gst_value_subtract (&subtraction, other, value)) {
-    g_value_unset (&subtraction);
-    /* !empty result, swapping must be empty */
-    if (!gst_value_subtract (&subtraction, value, other))
+  if (!gst_value_subtract (&subtraction, other, value)) {
+    /* empty result -> values are the same, or first was a value and
+     * second was a list
+     * verify that result is empty by swapping args */
+    if (!gst_value_subtract (&subtraction, value, other)) {
       return TRUE;
-
+    }
     g_value_unset (&subtraction);
+    return FALSE;
   }
-  return FALSE;
+
+  res = gst_value_compare (&subtraction, other);
+  g_value_unset (&subtraction);
+
+  if (res == GST_VALUE_EQUAL) {
+    /* value was empty ? */
+    return FALSE;
+  } else {
+    return TRUE;
+  }
 }
 
 static gboolean
@@ -657,7 +652,7 @@
 #ifdef USE_POISONING
   CAPS_POISON (caps2);
 #endif
-  if (G_UNLIKELY (gst_caps_is_any (caps1) || gst_caps_is_any (caps2))) {
+  if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2)) {
     /* FIXME: this leaks */
     caps1->flags |= GST_CAPS_FLAGS_ANY;
     for (i = caps2->structs->len - 1; i >= 0; i--) {
@@ -665,7 +660,9 @@
       gst_structure_free (structure);
     }
   } else {
-    for (i = caps2->structs->len; i; i--) {
+    int len = caps2->structs->len;
+
+    for (i = 0; i < len; i++) {
       structure = gst_caps_remove_and_get_structure (caps2, 0);
       gst_caps_append_structure (caps1, structure);
     }
@@ -703,19 +700,21 @@
 #ifdef USE_POISONING
   CAPS_POISON (caps2);
 #endif
-  if (G_UNLIKELY (gst_caps_is_any (caps1))) {
+  if (gst_caps_is_any (caps1)) {
     for (i = caps2->structs->len - 1; i >= 0; i--) {
       structure = gst_caps_remove_and_get_structure (caps2, i);
       gst_structure_free (structure);
     }
-  } else if (G_UNLIKELY (gst_caps_is_any (caps2))) {
+  } else if (gst_caps_is_any (caps2)) {
     caps1->flags |= GST_CAPS_FLAGS_ANY;
     for (i = caps1->structs->len - 1; i >= 0; i--) {
       structure = gst_caps_remove_and_get_structure (caps1, i);
       gst_structure_free (structure);
     }
   } else {
-    for (i = caps2->structs->len; i; i--) {
+    int len = caps2->structs->len;
+
+    for (i = 0; i < len; i++) {
       structure = gst_caps_remove_and_get_structure (caps2, 0);
       gst_caps_merge_structure (caps1, structure);
     }
@@ -818,7 +817,7 @@
 #endif
     /* check each structure */
     for (i = caps->structs->len - 1; i >= 0; i--) {
-      structure1 = gst_caps_get_structure_unchecked (caps, i);
+      structure1 = gst_caps_get_structure (caps, i);
       /* if structure is a subset of structure1, then skip it */
       if (gst_caps_structure_is_subset (structure1, structure)) {
         unique = FALSE;
@@ -866,14 +865,7 @@
  * WARNING: This function takes a const GstCaps *, but returns a
  * non-const GstStructure *.  This is for programming convenience --
  * the caller should be aware that structures inside a constant
- * #GstCaps should not be modified. However, if you know the caps
- * are writable, either because you have just copied them or made
- * them writable with gst_caps_make_writable(), you may modify the
- * structure returned in the usual way, e.g. with functions like
- * gst_structure_set_simple().
- *
- * You do not need to free or unref the structure returned, it
- * belongs to the #GstCaps.
+ * #GstCaps should not be modified.
  *
  * Returns: a pointer to the #GstStructure corresponding to @index
  */
@@ -887,7 +879,7 @@
   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
   g_return_val_if_fail (index < caps->structs->len, NULL);
 
-  return gst_caps_get_structure_unchecked (caps, index);
+  return g_ptr_array_index (caps->structs, index);
 }
 
 /**
@@ -915,8 +907,8 @@
   newcaps = gst_caps_new_empty ();
   newcaps->flags = caps->flags;
 
-  if (G_LIKELY (caps->structs->len > nth)) {
-    structure = gst_caps_get_structure_unchecked (caps, nth);
+  if (caps->structs->len > nth) {
+    structure = gst_caps_get_structure (caps, nth);
     gst_caps_append_structure (newcaps, gst_structure_copy (structure));
   }
 
@@ -963,7 +955,7 @@
 #endif
 
 void
-gst_caps_set_simple (GstCaps * caps, const char *field, ...)
+gst_caps_set_simple (GstCaps * caps, char *field, ...)
 {
   GstStructure *structure;
   va_list var_args;
@@ -972,7 +964,7 @@
   g_return_if_fail (caps->structs->len == 1);
   g_return_if_fail (IS_WRITABLE (caps));
 
-  structure = gst_caps_get_structure_unchecked (caps, 0);
+  structure = gst_caps_get_structure (caps, 0);
 
   va_start (var_args, field);
   gst_structure_set_valist (structure, field, var_args);
@@ -994,7 +986,7 @@
 #endif
 
 void
-gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
+gst_caps_set_simple_valist (GstCaps * caps, char *field, va_list varargs)
 {
   GstStructure *structure;
 
@@ -1002,7 +994,7 @@
   g_return_if_fail (caps->structs->len == 1);
   g_return_if_fail (IS_WRITABLE (caps));
 
-  structure = gst_caps_get_structure_unchecked (caps, 0);
+  structure = gst_caps_get_structure (caps, 0);
 
   gst_structure_set_valist (structure, field, varargs);
 }
@@ -1083,7 +1075,7 @@
   if (caps->structs->len != 1)
     return FALSE;
 
-  structure = gst_caps_get_structure_unchecked (caps, 0);
+  structure = gst_caps_get_structure (caps, 0);
 
   return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
 }
@@ -1110,8 +1102,8 @@
   g_return_val_if_fail (gst_caps_is_fixed (caps1), FALSE);
   g_return_val_if_fail (gst_caps_is_fixed (caps2), FALSE);
 
-  struct1 = gst_caps_get_structure_unchecked (caps1, 0);
-  struct2 = gst_caps_get_structure_unchecked (caps2, 0);
+  struct1 = gst_caps_get_structure (caps1, 0);
+  struct2 = gst_caps_get_structure (caps2, 0);
 
   if (struct1->name != struct2->name) {
     return FALSE;
@@ -1203,19 +1195,16 @@
 gboolean
 gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
 {
-  /* FIXME 0.11: NULL pointers are no valid Caps but indicate an error
-   * So there should be an assertion that caps1 and caps2 != NULL */
-
   /* NULL <-> NULL is allowed here */
-  if (G_UNLIKELY (caps1 == caps2))
+  if (caps1 == caps2)
     return TRUE;
 
   /* one of them NULL => they are different (can't be both NULL because
    * we checked that above) */
-  if (G_UNLIKELY (caps1 == NULL || caps2 == NULL))
+  if (caps1 == NULL || caps2 == NULL)
     return FALSE;
 
-  if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
+  if (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2))
     return gst_caps_is_equal_fixed (caps1, caps2);
 
   return gst_caps_is_subset (caps1, caps2) && gst_caps_is_subset (caps2, caps1);
@@ -1237,7 +1226,7 @@
   GValue dest_value = { 0 };
   const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
 
-  if (G_UNLIKELY (val2 == NULL)) {
+  if (val2 == NULL) {
     gst_structure_id_set_value (idata->dest, id, val1);
   } else if (idata->first_run) {
     if (gst_value_intersect (&dest_value, val1, val2)) {
@@ -1260,20 +1249,20 @@
   g_return_val_if_fail (struct1 != NULL, NULL);
   g_return_val_if_fail (struct2 != NULL, NULL);
 
-  if (G_UNLIKELY (struct1->name != struct2->name))
+  if (struct1->name != struct2->name)
     return NULL;
 
   data.dest = gst_structure_id_empty_new (struct1->name);
   data.intersect = struct2;
   data.first_run = TRUE;
-  if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
-              gst_caps_structure_intersect_field, &data)))
+  if (!gst_structure_foreach ((GstStructure *) struct1,
+          gst_caps_structure_intersect_field, &data))
     goto error;
 
   data.intersect = struct1;
   data.first_run = FALSE;
-  if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2,
-              gst_caps_structure_intersect_field, &data)))
+  if (!gst_structure_foreach ((GstStructure *) struct2,
+          gst_caps_structure_intersect_field, &data))
     goto error;
 
   return data.dest;
@@ -1343,7 +1332,7 @@
 gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
 {
   guint64 i;                    /* index can be up to 2 * G_MAX_UINT */
-  guint j, k, len1, len2;
+  guint j, k;
 
   GstStructure *struct1;
   GstStructure *struct2;
@@ -1354,17 +1343,17 @@
   g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
 
   /* caps are exactly the same pointers, just copy one caps */
-  if (G_UNLIKELY (caps1 == caps2))
+  if (caps1 == caps2)
     return gst_caps_copy (caps1);
 
   /* empty caps on either side, return empty */
-  if (G_UNLIKELY (gst_caps_is_empty (caps1) || gst_caps_is_empty (caps2)))
+  if (gst_caps_is_empty (caps1) || gst_caps_is_empty (caps2))
     return gst_caps_new_empty ();
 
   /* one of the caps is any, just copy the other caps */
-  if (G_UNLIKELY (gst_caps_is_any (caps1)))
+  if (gst_caps_is_any (caps1))
     return gst_caps_copy (caps2);
-  if (G_UNLIKELY (gst_caps_is_any (caps2)))
+  if (gst_caps_is_any (caps2))
     return gst_caps_copy (caps1);
 
   dest = gst_caps_new_empty ();
@@ -1385,27 +1374,25 @@
    * the structures diagonally down, then we iterate over the caps2
    * structures.
    */
-  len1 = caps1->structs->len;
-  len2 = caps2->structs->len;
-  for (i = 0; i < len1 + len2 - 1; i++) {
+  for (i = 0; i < caps1->structs->len + caps2->structs->len - 1; i++) {
     /* caps1 index goes from 0 to caps1->structs->len-1 */
-    j = MIN (i, len1 - 1);
+    j = MIN (i, caps1->structs->len - 1);
     /* caps2 index stays 0 until i reaches caps1->structs->len, then it counts
      * up from 1 to caps2->structs->len - 1 */
     k = MAX (0, i - j);
 
     /* now run the diagonal line, end condition is the left or bottom
      * border */
-    while (k < len2) {
-      struct1 = gst_caps_get_structure_unchecked (caps1, j);
-      struct2 = gst_caps_get_structure_unchecked (caps2, k);
+    while (k < caps2->structs->len) {
+      struct1 = gst_caps_get_structure (caps1, j);
+      struct2 = gst_caps_get_structure (caps2, k);
 
       istruct = gst_caps_structure_intersect (struct1, struct2);
 
       gst_caps_append_structure (dest, istruct);
       /* move down left */
       k++;
-      if (G_UNLIKELY (j == 0))
+      if (j == 0)
         break;                  /* so we don't roll back to G_MAXUINT */
       j--;
     }
@@ -1491,7 +1478,7 @@
 GstCaps *
 gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
 {
-  guint i, j, sublen;
+  guint i, j;
   GstStructure *min;
   GstStructure *sub;
   GstCaps *dest = NULL, *src;
@@ -1511,22 +1498,18 @@
      You can only remove everything or nothing and that is done above.
      Note: there's a test that checks this behaviour. */
   g_return_val_if_fail (!gst_caps_is_any (minuend), NULL);
-  sublen = subtrahend->structs->len;
-  g_assert (sublen > 0);
+  g_assert (subtrahend->structs->len > 0);
 
   src = gst_caps_copy (minuend);
-  for (i = 0; i < sublen; i++) {
-    guint srclen;
-
-    sub = gst_caps_get_structure_unchecked (subtrahend, i);
+  for (i = 0; i < subtrahend->structs->len; i++) {
+    sub = gst_caps_get_structure (subtrahend, i);
     if (dest) {
       gst_caps_unref (src);
       src = dest;
     }
     dest = gst_caps_new_empty ();
-    srclen = src->structs->len;
-    for (j = 0; j < srclen; j++) {
-      min = gst_caps_get_structure_unchecked (src, j);
+    for (j = 0; j < src->structs->len; j++) {
+      min = gst_caps_get_structure (src, j);
       if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub)) {
         GSList *list;
 
@@ -1575,16 +1558,6 @@
   GstCaps *dest1;
   GstCaps *dest2;
 
-  /* NULL pointers are no correct GstCaps */
-  g_return_val_if_fail (caps1 != NULL, NULL);
-  g_return_val_if_fail (caps2 != NULL, NULL);
-
-  if (gst_caps_is_empty (caps1))
-    return gst_caps_copy (caps2);
-
-  if (gst_caps_is_empty (caps2))
-    return gst_caps_copy (caps1);
-
   if (gst_caps_is_any (caps1) || gst_caps_is_any (caps2))
     return gst_caps_new_any ();
 
@@ -1611,8 +1584,7 @@
   guint i;
 
   if (G_VALUE_TYPE (value) == GST_TYPE_LIST) {
-    guint len = gst_value_list_get_size (value);
-    for (i = 1; i < len; i++) {
+    for (i = 1; i < gst_value_list_get_size (value); i++) {
       const GValue *v = gst_value_list_get_value (value, i);
       GstStructure *structure = gst_structure_copy (nf->structure);
 
@@ -1648,16 +1620,15 @@
 {
   NormalizeForeach nf;
   GstCaps *newcaps;
-  guint i, nlen;
+  guint i;
 
   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
   newcaps = gst_caps_copy (caps);
   nf.caps = newcaps;
-  nlen = newcaps->structs->len;
 
-  for (i = 0; i < nlen; i++) {
-    nf.structure = gst_caps_get_structure_unchecked (newcaps, i);
+  for (i = 0; i < newcaps->structs->len; i++) {
+    nf.structure = gst_caps_get_structure (newcaps, i);
 
     while (!gst_structure_foreach (nf.structure,
             gst_caps_normalize_foreach, &nf));
@@ -1822,15 +1793,14 @@
 
   start = caps->structs->len - 1;
   for (i = caps->structs->len - 1; i >= 0; i--) {
-    simplify = gst_caps_get_structure_unchecked (caps, i);
+    simplify = gst_caps_get_structure (caps, i);
     if (gst_structure_get_name_id (simplify) !=
-        gst_structure_get_name_id (gst_caps_get_structure_unchecked (caps,
-                start)))
+        gst_structure_get_name_id (gst_caps_get_structure (caps, start)))
       start = i;
     for (j = start; j >= 0; j--) {
       if (j == i)
         continue;
-      compare = gst_caps_get_structure_unchecked (caps, j);
+      compare = gst_caps_get_structure (caps, j);
       if (gst_structure_get_name_id (simplify) !=
           gst_structure_get_name_id (compare)) {
         break;
@@ -1941,9 +1911,9 @@
  * can be converted back to a #GstCaps by gst_caps_from_string().
  *
  * For debugging purposes its easier to do something like this:
- * |[
- * GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
- * ]|
+ * <programlisting>
+ *  GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
+ * </programlisting>
  * This prints the caps in human readble form.
  *
  * Returns: a newly allocated string representing @caps.
@@ -1955,7 +1925,7 @@
 gchar *
 gst_caps_to_string (const GstCaps * caps)
 {
-  guint i, slen, clen;
+  guint i, slen;
   GString *s;
 
   /* NOTE:  This function is potentially called by the debug system,
@@ -1976,15 +1946,12 @@
 
   /* estimate a rough string length to avoid unnecessary reallocs in GString */
   slen = 0;
-  clen = caps->structs->len;
-  for (i = 0; i < clen; i++) {
-    slen +=
-        STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked (caps,
-            i));
+  for (i = 0; i < caps->structs->len; i++) {
+    slen += STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure (caps, i));
   }
 
   s = g_string_sized_new (slen);
-  for (i = 0; i < clen; i++) {
+  for (i = 0; i < caps->structs->len; i++) {
     GstStructure *structure;
 
     if (i > 0) {
@@ -1992,7 +1959,7 @@
       g_string_append_c (s, ' ');
     }
 
-    structure = gst_caps_get_structure_unchecked (caps, i);
+    structure = gst_caps_get_structure (caps, i);
     priv_gst_structure_append_to_gstring (structure, s);
   }
   if (s->len && s->str[s->len - 1] == ';') {