caps: Use correct size for caps allocation
[platform/upstream/gstreamer.git] / gst / gstcaps.c
index 3bfe62b..225da68 100644 (file)
 
 #define DEBUG_REFCOUNT
 
+typedef struct _GstCapsImpl
+{
+  GstCaps caps;
+
+  GPtrArray *array;
+} GstCapsImpl;
 
-#define GST_CAPS_ARRAY(c) ((GPtrArray *)((c)->priv))
+#define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
 
 #define GST_CAPS_LEN(c)   (GST_CAPS_ARRAY(c)->len)
 
@@ -191,7 +197,7 @@ gst_caps_init (GstCaps * caps, gsize size)
    * in practise
    * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
    */
-  caps->priv = g_ptr_array_new ();
+  GST_CAPS_ARRAY (caps) = g_ptr_array_new ();
 }
 
 /**
@@ -208,9 +214,9 @@ gst_caps_new_empty (void)
 {
   GstCaps *caps;
 
-  caps = g_slice_new (GstCaps);
+  caps = g_slice_new (GstCapsImpl);
 
-  gst_caps_init (caps, sizeof (GstCaps));
+  gst_caps_init (caps, sizeof (GstCapsImpl));
 
 #ifdef DEBUG_REFCOUNT
   GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
@@ -356,7 +362,6 @@ gst_static_caps_get_type (void)
   return staticcaps_type;
 }
 
-
 /**
  * gst_static_caps_get:
  * @static_caps: the #GstStaticCaps to convert
@@ -370,20 +375,19 @@ gst_static_caps_get_type (void)
 GstCaps *
 gst_static_caps_get (GstStaticCaps * static_caps)
 {
-  GstCaps *caps;
+  GstCaps **caps;
 
   g_return_val_if_fail (static_caps != NULL, NULL);
 
-  caps = (GstCaps *) static_caps;
+  caps = &static_caps->caps;
 
   /* refcount is 0 when we need to convert */
-  if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) == 0)) {
+  if (G_UNLIKELY (*caps == NULL)) {
     const char *string;
-    GstCaps temp;
 
     G_LOCK (static_caps_lock);
     /* check if other thread already updated */
-    if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) > 0))
+    if (G_UNLIKELY (*caps != NULL))
       goto done;
 
     string = static_caps->string;
@@ -393,28 +397,21 @@ gst_static_caps_get (GstStaticCaps * static_caps)
 
     GST_CAT_TRACE (GST_CAT_CAPS, "creating %p", static_caps);
 
-    /* we construct the caps on the stack, then copy over the struct into our
-     * real caps, refcount last. We do this because we must leave the refcount
-     * of the result caps to 0 so that other threads don't run away with the
-     * caps while we are constructing it. */
-    gst_caps_init (&temp, sizeof (GstCaps));
+    *caps = gst_caps_from_string (string);
 
     /* convert to string */
-    if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string)))
+    if (G_UNLIKELY (*caps == NULL))
       g_critical ("Could not convert static caps \"%s\"", string);
 
-    GST_MINI_OBJECT_REFCOUNT (&temp) = 0;
-    memcpy (caps, &temp, sizeof (GstCaps));
-    gst_caps_ref (caps);
-
     GST_CAT_TRACE (GST_CAT_CAPS, "created %p", static_caps);
   done:
     G_UNLOCK (static_caps_lock);
   }
   /* ref the caps, makes it not writable */
-  gst_caps_ref (caps);
+  if (G_LIKELY (*caps != NULL))
+    gst_caps_ref (*caps);
 
-  return caps;
+  return *caps;
 
   /* ERRORS */
 no_string:
@@ -427,30 +424,16 @@ no_string:
 
 /**
  * gst_static_caps_cleanup:
- * @static_caps: the #GstStaticCaps to convert
+ * @static_caps: the #GstStaticCaps to clean
  *
- * Clean up the caps contained in @static_caps when the refcount is 0.
+ * Clean up the cached caps contained in @static_caps.
  */
 void
 gst_static_caps_cleanup (GstStaticCaps * static_caps)
 {
-  GstCaps *caps = (GstCaps *) static_caps;
-
-  /* FIXME: this is not threadsafe */
-  if (GST_CAPS_REFCOUNT_VALUE (caps) == 1) {
-    GstStructure *structure;
-    guint i, clen;
-
-    clen = GST_CAPS_LEN (caps);
-
-    for (i = 0; i < clen; i++) {
-      structure = (GstStructure *) gst_caps_get_structure (caps, i);
-      gst_structure_set_parent_refcount (structure, NULL);
-      gst_structure_free (structure);
-    }
-    g_ptr_array_free (GST_CAPS_ARRAY (caps), TRUE);
-    GST_CAPS_REFCOUNT (caps) = 0;
-  }
+  G_LOCK (static_caps_lock);
+  gst_caps_replace (&static_caps->caps, NULL);
+  G_UNLOCK (static_caps_lock);
 }
 
 /* manipulation */