caps: avoid using in-place oprations
authorWim Taymans <wim.taymans@collabora.co.uk>
Sun, 11 Mar 2012 17:57:44 +0000 (18:57 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Sun, 11 Mar 2012 17:57:44 +0000 (18:57 +0100)
Rework some caps operations so they don't rely on writable caps but instead take
ownership of the input caps and do _make_writable() only when needed.
Remove some const from caps functions, it does not make much sense for
refcounted objects and does not allow us to return a refcount to the const input
caps.
Rework the base classes fixate vmethods to not operate on the caps in-place.
All this saves us around 30% of caps and structure copy and new operations.

12 files changed:
docs/manual/advanced-autoplugging.xml
gst/gstcaps.c
gst/gstcaps.h
gst/gstpadtemplate.c
gst/gstutils.c
gst/gstutils.h
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesink.h
libs/gst/base/gstbasesrc.c
libs/gst/base/gstbasesrc.h
libs/gst/base/gstbasetransform.c
tests/check/gst/gstcaps.c

index dbdb5ea..9186985 100644 (file)
@@ -333,7 +333,7 @@ init_factories (void)
       which will continue with the above approach.
     </para>
     <programlisting><!-- example-begin dynamic.c c -->
-static void try_to_plug (GstPad *pad, const GstCaps *caps);
+static void try_to_plug (GstPad *pad, GstCaps *caps);
 
 static GstElement *audiosink;
 
@@ -413,7 +413,7 @@ close_link (GstPad      *srcpad,
 
 static void
 try_to_plug (GstPad        *pad,
-            const GstCaps *caps)
+            GstCaps       *caps)
 {
   GstObject *parent = GST_OBJECT (GST_OBJECT_PARENT (pad));
   const gchar *mime;
index d40bd0f..bd40eda 100644 (file)
@@ -208,6 +208,7 @@ gst_caps_init (GstCaps * caps, gsize size)
  *
  * Creates a new #GstCaps that is empty.  That is, the returned
  * #GstCaps contains no media formats.
+ * The #GstCaps is guaranteed to be writable.
  * Caller is responsible for unreffing the returned caps.
  *
  * Returns: (transfer full): the new #GstCaps
@@ -485,64 +486,60 @@ gst_caps_append (GstCaps * caps1, GstCaps * caps2)
   g_return_if_fail (GST_IS_CAPS (caps2));
   g_return_if_fail (IS_WRITABLE (caps1));
 
-  caps2 = gst_caps_make_writable (caps2);
-
   if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
-    /* FIXME: this leaks */
     GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
-    for (i = GST_CAPS_LEN (caps2) - 1; i >= 0; i--) {
-      structure = gst_caps_remove_and_get_structure (caps2, i);
-      gst_structure_free (structure);
-    }
+    gst_caps_unref (caps2);
   } else {
+    caps2 = gst_caps_make_writable (caps2);
+
     for (i = GST_CAPS_LEN (caps2); i; i--) {
       structure = gst_caps_remove_and_get_structure (caps2, 0);
       gst_caps_append_structure_unchecked (caps1, structure);
     }
+    gst_caps_unref (caps2);     /* guaranteed to free it */
   }
-  gst_caps_unref (caps2);       /* guaranteed to free it */
 }
 
 /**
  * gst_caps_merge:
- * @caps1: the #GstCaps that will take the new entries
+ * @caps1: (transfer full): the #GstCaps that will take the new entries
  * @caps2: (transfer full): the #GstCaps to merge in
  *
  * Appends the structures contained in @caps2 to @caps1 if they are not yet
  * expressed by @caps1. The structures in @caps2 are not copied -- they are
- * transferred to @caps1, and then @caps2 is freed.
+ * transferred to a writable copy of @caps1, and then @caps2 is freed.
  * If either caps is ANY, the resulting caps will be ANY.
  *
+ * Returns: (transfer full): the merged caps.
+ *
  * Since: 0.10.10
  */
-void
+GstCaps *
 gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
 {
   GstStructure *structure;
   int i;
+  GstCaps *result;
 
-  g_return_if_fail (GST_IS_CAPS (caps1));
-  g_return_if_fail (GST_IS_CAPS (caps2));
-  g_return_if_fail (IS_WRITABLE (caps1));
-
-  caps2 = gst_caps_make_writable (caps2);
+  g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
+  g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
 
   if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
-    for (i = GST_CAPS_LEN (caps2) - 1; i >= 0; i--) {
-      structure = gst_caps_remove_and_get_structure (caps2, i);
-      gst_structure_free (structure);
-    }
+    gst_caps_unref (caps2);
+    result = caps1;
   } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
-    GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
-    for (i = GST_CAPS_LEN (caps1) - 1; i >= 0; i--) {
-      structure = gst_caps_remove_and_get_structure (caps1, i);
-      gst_structure_free (structure);
-    }
+    gst_caps_unref (caps1);
+    result = caps2;
   } else {
+    caps2 = gst_caps_make_writable (caps2);
+
     for (i = GST_CAPS_LEN (caps2); i; i--) {
       structure = gst_caps_remove_and_get_structure (caps2, 0);
-      gst_caps_merge_structure (caps1, structure);
+      caps1 = gst_caps_merge_structure (caps1, structure);
     }
+    gst_caps_unref (caps2);
+    result = caps1;
+
     /* this is too naive
        GstCaps *com = gst_caps_intersect (caps1, caps2);
        GstCaps *add = gst_caps_subtract (caps2, com);
@@ -553,7 +550,8 @@ gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
        gst_caps_unref (com);
      */
   }
-  gst_caps_unref (caps2);       /* guaranteed to free it */
+
+  return result;
 }
 
 /**
@@ -598,17 +596,17 @@ gst_caps_remove_structure (GstCaps * caps, guint idx)
 
 /**
  * gst_caps_merge_structure:
- * @caps: the #GstCaps that will the new structure
+ * @caps: (transfer full): the #GstCaps to merge into
  * @structure: (transfer full): the #GstStructure to merge
  *
- * Appends @structure to @caps if its not already expressed by @caps.  The
- * structure is not copied; @caps becomes the owner of @structure.
+ * Appends @structure to @caps if its not already expressed by @caps.
+ *
+ * Returns: (transfer full): the merged caps.
  */
-void
+GstCaps *
 gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
 {
-  g_return_if_fail (GST_IS_CAPS (caps));
-  g_return_if_fail (IS_WRITABLE (caps));
+  g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
   if (G_LIKELY (structure)) {
     GstStructure *structure1;
@@ -625,11 +623,13 @@ gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
       }
     }
     if (unique) {
+      caps = gst_caps_make_writable (caps);
       gst_caps_append_structure_unchecked (caps, structure);
     } else {
       gst_structure_free (structure);
     }
   }
+  return caps;
 }
 
 /**
@@ -712,23 +712,29 @@ gst_caps_copy_nth (const GstCaps * caps, guint nth)
 
 /**
  * gst_caps_truncate:
- * @caps: the #GstCaps to truncate
+ * @caps: (transfer full): the #GstCaps to truncate
+ *
+ * Discard all but the first structure from @caps. Useful when
+ * fixating.
  *
- * Destructively discard all but the first structure from @caps. Useful when
- * fixating. @caps must be writable.
+ * Returns: (transfer full): truncated caps
  */
-void
+GstCaps *
 gst_caps_truncate (GstCaps * caps)
 {
   gint i;
 
-  g_return_if_fail (GST_IS_CAPS (caps));
-  g_return_if_fail (IS_WRITABLE (caps));
+  g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
   i = GST_CAPS_LEN (caps) - 1;
+  if (i == 0)
+    return caps;
 
+  caps = gst_caps_make_writable (caps);
   while (i > 0)
     gst_caps_remove_structure (caps, i--);
+
+  return caps;
 }
 
 /**
@@ -1183,7 +1189,7 @@ gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
 }
 
 static GstCaps *
-gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
+gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
 {
   guint64 i;                    /* index can be up to 2 * G_MAX_UINT */
   guint j, k, len1, len2;
@@ -1195,17 +1201,17 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
 
   /* caps are exactly the same pointers, just copy one caps */
   if (G_UNLIKELY (caps1 == caps2))
-    return _gst_caps_copy (caps1);
+    return gst_caps_ref (caps1);
 
   /* empty caps on either side, return empty */
   if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
-    return gst_caps_new_empty ();
+    return gst_caps_ref (GST_CAPS_NONE);
 
   /* one of the caps is any, just copy the other caps */
   if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
-    return _gst_caps_copy (caps2);
+    return gst_caps_ref (caps2);
   if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
-    return _gst_caps_copy (caps1);
+    return gst_caps_ref (caps1);
 
   dest = gst_caps_new_empty ();
 
@@ -1242,7 +1248,7 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
 
       istruct = gst_structure_intersect (struct1, struct2);
 
-      gst_caps_merge_structure (dest, istruct);
+      dest = gst_caps_merge_structure (dest, istruct);
       /* move down left */
       k++;
       if (G_UNLIKELY (j == 0))
@@ -1267,7 +1273,7 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
  * Returns: the new #GstCaps
  */
 static GstCaps *
-gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2)
+gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
 {
   guint i;
   guint j, len1, len2;
@@ -1279,17 +1285,17 @@ gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2)
 
   /* caps are exactly the same pointers, just copy one caps */
   if (G_UNLIKELY (caps1 == caps2))
-    return gst_caps_copy (caps1);
+    return gst_caps_ref (caps1);
 
   /* empty caps on either side, return empty */
   if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
-    return gst_caps_new_empty ();
+    return gst_caps_ref (GST_CAPS_NONE);
 
   /* one of the caps is any, just copy the other caps */
   if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
-    return gst_caps_copy (caps2);
+    return gst_caps_ref (caps2);
   if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
-    return gst_caps_copy (caps1);
+    return gst_caps_ref (caps1);
 
   dest = gst_caps_new_empty ();
 
@@ -1301,7 +1307,7 @@ gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2)
       struct2 = gst_caps_get_structure_unchecked (caps2, j);
       istruct = gst_structure_intersect (struct1, struct2);
       if (istruct)
-        gst_caps_merge_structure (dest, istruct);
+        dest = gst_caps_merge_structure (dest, istruct);
     }
   }
 
@@ -1322,7 +1328,7 @@ gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2)
  * Since: 0.10.33
  */
 GstCaps *
-gst_caps_intersect_full (const GstCaps * caps1, const GstCaps * caps2,
+gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
     GstCapsIntersectMode mode)
 {
   g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
@@ -1350,7 +1356,7 @@ gst_caps_intersect_full (const GstCaps * caps1, const GstCaps * caps2,
  * Returns: the new #GstCaps
  */
 GstCaps *
-gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
+gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
 {
   return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
 }
@@ -1429,7 +1435,7 @@ gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
  * Returns: the resulting caps
  */
 GstCaps *
-gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
+gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
 {
   guint i, j, sublen;
   GstStructure *min;
@@ -1443,7 +1449,7 @@ gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
     return gst_caps_new_empty ();
   }
   if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
-    return _gst_caps_copy (minuend);
+    return gst_caps_ref (minuend);
 
   /* FIXME: Do we want this here or above?
      The reason we need this is that there is no definition about what
@@ -1549,27 +1555,25 @@ gst_caps_structure_union (const GstStructure * struct1,
  * Returns: the new #GstCaps
  */
 GstCaps *
-gst_caps_union (const GstCaps * caps1, const GstCaps * caps2)
+gst_caps_union (GstCaps * caps1, GstCaps * caps2)
 {
   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 (CAPS_IS_EMPTY (caps1))
-    return _gst_caps_copy (caps2);
+    return gst_caps_ref (caps2);
 
   if (CAPS_IS_EMPTY (caps2))
-    return _gst_caps_copy (caps1);
+    return gst_caps_ref (caps1);
 
   if (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))
-    return gst_caps_new_any ();
+    return gst_caps_ref (caps1);
 
   dest1 = _gst_caps_copy (caps1);
-  dest2 = _gst_caps_copy (caps2);
-  gst_caps_append (dest1, dest2);
+  gst_caps_append (dest1, gst_caps_ref (caps2));
 
   gst_caps_do_simplify (dest1);
   return dest1;
@@ -1621,7 +1625,7 @@ gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
  * Returns: the new #GstCaps
  */
 GstCaps *
-gst_caps_normalize (const GstCaps * caps)
+gst_caps_normalize (GstCaps * caps)
 {
   NormalizeForeach nf;
   GstCaps *newcaps;
@@ -1823,24 +1827,28 @@ gst_caps_do_simplify (GstCaps * caps)
 
 /**
  * gst_caps_fixate:
- * @caps: a #GstCaps to fixate
+ * @caps: (transfer full): a #GstCaps to fixate
  *
- * Modifies the given @caps inplace into a representation with only fixed
+ * Modifies the given @caps into a representation with only fixed
  * values. First the caps will be truncated and then the first structure will be
- * fixated with gst_structure_fixate(). @caps should be writable.
+ * fixated with gst_structure_fixate().
+ *
+ * Returns: (transfer full): the fixated caps
  */
-void
+GstCaps *
 gst_caps_fixate (GstCaps * caps)
 {
   GstStructure *s;
 
-  g_return_if_fail (GST_IS_CAPS (caps));
-  g_return_if_fail (IS_WRITABLE (caps));
+  g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
   /* default fixation */
-  gst_caps_truncate (caps);
+  caps = gst_caps_truncate (caps);
+  caps = gst_caps_make_writable (caps);
   s = gst_caps_get_structure (caps, 0);
   gst_structure_fixate (s);
+
+  return caps;
 }
 
 /* utility */
index 4603182..4420835 100644 (file)
@@ -384,20 +384,20 @@ void              gst_static_caps_cleanup          (GstStaticCaps *static_caps);
 /* manipulation */
 void              gst_caps_append                  (GstCaps       *caps1,
                                                     GstCaps       *caps2);
-void              gst_caps_merge                   (GstCaps       *caps1,
-                                                    GstCaps       *caps2);
 void              gst_caps_append_structure        (GstCaps       *caps,
                                                     GstStructure  *structure);
 void              gst_caps_remove_structure        (GstCaps       *caps, guint idx);
-void              gst_caps_merge_structure         (GstCaps       *caps,
-                                                    GstStructure  *structure);
+GstCaps *         gst_caps_merge                   (GstCaps       *caps1,
+                                                    GstCaps       *caps2) G_GNUC_WARN_UNUSED_RESULT;
+GstCaps *         gst_caps_merge_structure         (GstCaps       *caps,
+                                                    GstStructure  *structure) G_GNUC_WARN_UNUSED_RESULT;
 guint             gst_caps_get_size                (const GstCaps *caps);
 GstStructure *    gst_caps_get_structure           (const GstCaps *caps,
                                                     guint          index);
-GstStructure *    gst_caps_steal_structure         (GstCaps *caps,
+GstStructure *    gst_caps_steal_structure         (GstCaps       *caps,
                                                     guint          index) G_GNUC_WARN_UNUSED_RESULT;
 GstCaps *         gst_caps_copy_nth                (const GstCaps *caps, guint nth) G_GNUC_WARN_UNUSED_RESULT;
-void              gst_caps_truncate                (GstCaps       *caps);
+GstCaps *         gst_caps_truncate                (GstCaps       *caps) G_GNUC_WARN_UNUSED_RESULT;
 void              gst_caps_set_value               (GstCaps       *caps,
                                                     const char    *field,
                                                     const GValue  *value);
@@ -428,19 +428,19 @@ gboolean          gst_caps_is_strictly_equal         (const GstCaps *caps1,
 
 
 /* operations */
-GstCaps *         gst_caps_intersect               (const GstCaps *caps1,
-                                                   const GstCaps *caps2) G_GNUC_WARN_UNUSED_RESULT;
-GstCaps *         gst_caps_intersect_full          (const GstCaps *caps1,
-                                                   const GstCaps *caps2,
+GstCaps *         gst_caps_intersect               (GstCaps *caps1,
+                                                   GstCaps *caps2) G_GNUC_WARN_UNUSED_RESULT;
+GstCaps *         gst_caps_intersect_full          (GstCaps *caps1,
+                                                   GstCaps *caps2,
                                                     GstCapsIntersectMode mode) G_GNUC_WARN_UNUSED_RESULT;
-GstCaps *         gst_caps_subtract               (const GstCaps *minuend,
-                                                   const GstCaps *subtrahend) G_GNUC_WARN_UNUSED_RESULT;
-GstCaps *         gst_caps_union                   (const GstCaps *caps1,
-                                                   const GstCaps *caps2) G_GNUC_WARN_UNUSED_RESULT;
-GstCaps *         gst_caps_normalize               (const GstCaps *caps) G_GNUC_WARN_UNUSED_RESULT;
-gboolean          gst_caps_do_simplify             (GstCaps       *caps);
-
-void              gst_caps_fixate                  (GstCaps       *caps);
+GstCaps *         gst_caps_subtract               (GstCaps *minuend,
+                                                   GstCaps *subtrahend) G_GNUC_WARN_UNUSED_RESULT;
+GstCaps *         gst_caps_union                   (GstCaps *caps1,
+                                                   GstCaps *caps2) G_GNUC_WARN_UNUSED_RESULT;
+GstCaps *         gst_caps_normalize               (GstCaps *caps) G_GNUC_WARN_UNUSED_RESULT;
+gboolean          gst_caps_do_simplify             (GstCaps *caps);
+
+GstCaps *         gst_caps_fixate                  (GstCaps *caps) G_GNUC_WARN_UNUSED_RESULT;
 
 /* utility */
 gchar *           gst_caps_to_string               (const GstCaps *caps) G_GNUC_MALLOC;
index ece7f71..ab516a9 100644 (file)
@@ -356,7 +356,7 @@ gst_static_pad_template_get_caps (GstStaticPadTemplate * templ)
 {
   g_return_val_if_fail (templ, NULL);
 
-  return (GstCaps *) gst_static_caps_get (&templ->static_caps);
+  return gst_static_caps_get (&templ->static_caps);
 }
 
 /**
index 4bd804f..4872971 100644 (file)
@@ -1083,7 +1083,7 @@ gst_pad_check_link (GstPad * srcpad, GstPad * sinkpad)
  */
 GstPad *
 gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
-    const GstCaps * caps)
+    GstCaps * caps)
 {
   GstIterator *pads;
   GstPadTemplate *templ;
index e970786..18e4616 100644 (file)
@@ -839,7 +839,7 @@ void                    gst_object_default_error        (GstObject    * source,
 /* element functions */
 void                    gst_element_create_all_pads     (GstElement *element);
 GstPad*                 gst_element_get_compatible_pad  (GstElement *element, GstPad *pad,
-                                                         const GstCaps *caps);
+                                                         GstCaps *caps);
 
 GstPadTemplate*         gst_element_get_compatible_pad_template (GstElement *element, GstPadTemplate *compattempl);
 
index 0c1dc44..6dcdb91 100644 (file)
@@ -388,8 +388,9 @@ static gboolean gst_base_sink_default_query (GstBaseSink * sink,
     GstQuery * query);
 
 static gboolean gst_base_sink_negotiate_pull (GstBaseSink * basesink);
-static void gst_base_sink_default_fixate (GstBaseSink * bsink, GstCaps * caps);
-static void gst_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps);
+static GstCaps *gst_base_sink_default_fixate (GstBaseSink * bsink,
+    GstCaps * caps);
+static GstCaps *gst_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps);
 
 /* check if an object was too late */
 static gboolean gst_base_sink_is_too_late (GstBaseSink * basesink,
@@ -593,14 +594,14 @@ gst_base_sink_query_caps (GstBaseSink * bsink, GstPad * pad, GstCaps * filter)
   return caps;
 }
 
-static void
+static GstCaps *
 gst_base_sink_default_fixate (GstBaseSink * bsink, GstCaps * caps)
 {
   GST_DEBUG_OBJECT (bsink, "using default caps fixate function");
-  gst_caps_fixate (caps);
+  return gst_caps_fixate (caps);
 }
 
-static void
+static GstCaps *
 gst_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps)
 {
   GstBaseSinkClass *bclass;
@@ -608,7 +609,9 @@ gst_base_sink_fixate (GstBaseSink * bsink, GstCaps * caps)
   bclass = GST_BASE_SINK_GET_CLASS (bsink);
 
   if (bclass->fixate)
-    bclass->fixate (bsink, caps);
+    caps = bclass->fixate (bsink, caps);
+
+  return caps;
 }
 
 static void
@@ -2000,8 +2003,8 @@ gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
   /* FIXME: Casting to GstClockEntry only works because the types
    * are the same */
   if (G_LIKELY (sink->priv->cached_clock_id != NULL
-          && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->
-              priv->cached_clock_id) == clock)) {
+          && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv->
+              cached_clock_id) == clock)) {
     if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id,
             time)) {
       gst_clock_id_unref (sink->priv->cached_clock_id);
@@ -3922,9 +3925,8 @@ gst_base_sink_negotiate_pull (GstBaseSink * basesink)
        pull() without setcaps() */
     result = TRUE;
   } else {
-    caps = gst_caps_make_writable (caps);
     /* try to fixate */
-    gst_base_sink_fixate (basesink, caps);
+    caps = gst_base_sink_fixate (basesink, caps);
     GST_DEBUG_OBJECT (basesink, "fixated to: %" GST_PTR_FORMAT, caps);
 
     if (gst_caps_is_fixed (caps)) {
index 5c4755c..f4ab7e6 100644 (file)
@@ -109,8 +109,7 @@ struct _GstBaseSink {
  * @parent_class: Element parent class
  * @get_caps: Called to get sink pad caps from the subclass
  * @set_caps: Notify subclass of changed caps
- * @fixate: Only useful in pull mode, this vmethod will be called in response to
- *     gst_pad_fixate_caps() being called on the sink pad. Implement if you have
+ * @fixate: Only useful in pull mode. Implement if you have
  *     ideas about what should be the default values for the caps you support.
  * @activate_pull: Subclasses should override this when they can provide an
  *     alternate method of spawning a thread to drive the pipeline in pull mode.
@@ -149,7 +148,7 @@ struct _GstBaseSinkClass {
   gboolean      (*set_caps)     (GstBaseSink *sink, GstCaps *caps);
 
   /* fixate sink caps during pull-mode negotiation */
-  void          (*fixate)       (GstBaseSink *sink, GstCaps *caps);
+  GstCaps *     (*fixate)       (GstBaseSink *sink, GstCaps *caps);
   /* start or stop a pulling thread */
   gboolean      (*activate_pull)(GstBaseSink *sink, gboolean active);
 
index 48cd113..1113405 100644 (file)
@@ -285,8 +285,8 @@ gst_base_src_get_type (void)
 
 static GstCaps *gst_base_src_default_get_caps (GstBaseSrc * bsrc,
     GstCaps * filter);
-static void gst_base_src_default_fixate (GstBaseSrc * src, GstCaps * caps);
-static void gst_base_src_fixate (GstBaseSrc * src, GstCaps * caps);
+static GstCaps *gst_base_src_default_fixate (GstBaseSrc * src, GstCaps * caps);
+static GstCaps *gst_base_src_fixate (GstBaseSrc * src, GstCaps * caps);
 
 static gboolean gst_base_src_is_random_access (GstBaseSrc * src);
 static gboolean gst_base_src_activate_mode (GstPad * pad, GstObject * parent,
@@ -898,14 +898,14 @@ gst_base_src_default_get_caps (GstBaseSrc * bsrc, GstCaps * filter)
   return caps;
 }
 
-static void
+static GstCaps *
 gst_base_src_default_fixate (GstBaseSrc * bsrc, GstCaps * caps)
 {
   GST_DEBUG_OBJECT (bsrc, "using default caps fixate function");
-  gst_caps_fixate (caps);
+  return gst_caps_fixate (caps);
 }
 
-static void
+static GstCaps *
 gst_base_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
 {
   GstBaseSrcClass *bclass;
@@ -913,7 +913,9 @@ gst_base_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
   bclass = GST_BASE_SRC_GET_CLASS (bsrc);
 
   if (bclass->fixate)
-    bclass->fixate (bsrc, caps);
+    caps = bclass->fixate (bsrc, caps);
+
+  return caps;
 }
 
 static gboolean
@@ -2866,8 +2868,7 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
        * nego is not needed */
       result = TRUE;
     } else {
-      caps = gst_caps_make_writable (caps);
-      gst_base_src_fixate (basesrc, caps);
+      caps = gst_base_src_fixate (basesrc, caps);
       GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
       if (gst_caps_is_fixed (caps)) {
         /* yay, fixed caps, use those then, it's possible that the subclass does
index cddc69c..36c2044 100644 (file)
@@ -172,7 +172,7 @@ struct _GstBaseSrcClass {
   /* decide on caps */
   gboolean      (*negotiate)    (GstBaseSrc *src);
   /* called if, in negotiation, caps need fixating */
-  void          (*fixate)       (GstBaseSrc *src, GstCaps *caps);
+  GstCaps *     (*fixate)       (GstBaseSrc *src, GstCaps *caps);
   /* notify the subclass of new caps */
   gboolean      (*set_caps)     (GstBaseSrc *src, GstCaps *caps);
 
index b3d6a8c..f2bcc0a 100644 (file)
@@ -720,8 +720,7 @@ gst_base_transform_query_caps (GstBaseTransform * trans, GstPad * pad,
     /* Now try if we can put the untransformed downstream caps first */
     temp = gst_caps_intersect_full (peercaps, caps, GST_CAPS_INTERSECT_FIRST);
     if (!gst_caps_is_empty (temp)) {
-      gst_caps_merge (temp, caps);
-      caps = temp;
+      caps = gst_caps_merge (temp, caps);
     } else {
       gst_caps_unref (temp);
     }
@@ -963,8 +962,7 @@ static GstCaps *
 gst_base_transform_default_fixate_caps (GstBaseTransform * trans,
     GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
 {
-  othercaps = gst_caps_make_writable (othercaps);
-  gst_caps_fixate (othercaps);
+  othercaps = gst_caps_fixate (othercaps);
   GST_DEBUG_OBJECT (trans, "fixated to %" GST_PTR_FORMAT, othercaps);
 
   return othercaps;
index e5af97e..cede2cd 100644 (file)
@@ -272,7 +272,7 @@ GST_START_TEST (test_truncate)
   fail_unless (caps != NULL,
       "gst_caps_from_string (non_simple_caps_string) failed");
   fail_unless_equals_int (gst_caps_get_size (caps), 4);
-  gst_caps_truncate (caps);
+  caps = gst_caps_truncate (caps);
   fail_unless_equals_int (gst_caps_get_size (caps), 1);
   gst_caps_unref (caps);
 }
@@ -325,7 +325,7 @@ GST_START_TEST (test_merge_fundamental)
   /* ANY + specific = ANY */
   c1 = gst_caps_from_string ("audio/x-raw,rate=44100");
   c2 = gst_caps_new_any ();
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 0, NULL);
   fail_unless (gst_caps_is_any (c2), NULL);
@@ -334,7 +334,7 @@ GST_START_TEST (test_merge_fundamental)
   /* specific + ANY = ANY */
   c2 = gst_caps_from_string ("audio/x-raw,rate=44100");
   c1 = gst_caps_new_any ();
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 0, NULL);
   fail_unless (gst_caps_is_any (c2), NULL);
@@ -343,7 +343,7 @@ GST_START_TEST (test_merge_fundamental)
   /* EMPTY + specific = specific */
   c1 = gst_caps_from_string ("audio/x-raw,rate=44100");
   c2 = gst_caps_new_empty ();
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   fail_if (gst_caps_is_empty (c2), NULL);
@@ -352,7 +352,7 @@ GST_START_TEST (test_merge_fundamental)
   /* specific + EMPTY = specific */
   c2 = gst_caps_from_string ("audio/x-raw,rate=44100");
   c1 = gst_caps_new_empty ();
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   fail_if (gst_caps_is_empty (c2), NULL);
@@ -368,7 +368,7 @@ GST_START_TEST (test_merge_same)
   /* this is the same */
   c1 = gst_caps_from_string ("audio/x-raw,rate=44100,channels=1");
   c2 = gst_caps_from_string ("audio/x-raw,rate=44100,channels=1");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   test = gst_caps_from_string ("audio/x-raw,rate=44100,channels=1");
@@ -379,35 +379,35 @@ GST_START_TEST (test_merge_same)
   /* and so is this */
   c1 = gst_caps_from_string ("audio/x-raw,rate=44100,channels=1");
   c2 = gst_caps_from_string ("audio/x-raw,channels=1,rate=44100");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   gst_caps_unref (c2);
 
   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AABB");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   gst_caps_unref (c2);
 
   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AABB");
   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   gst_caps_unref (c2);
 
   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
   c2 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   gst_caps_unref (c2);
 
   c1 = gst_caps_from_string ("video/x-foo, data=(buffer)AA");
   c2 = gst_caps_from_string ("video/x-bar, data=(buffer)AA");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   gst_caps_unref (c2);
@@ -422,7 +422,7 @@ GST_START_TEST (test_merge_subset)
   /* the 2nd is already covered */
   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
   c1 = gst_caps_from_string ("audio/x-raw,channels=1");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
@@ -433,7 +433,7 @@ GST_START_TEST (test_merge_subset)
   /* here it is not */
   c2 = gst_caps_from_string ("audio/x-raw,channels=1,rate=44100");
   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,2],rate=44100");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels=[1,2],rate=44100");
@@ -444,7 +444,7 @@ GST_START_TEST (test_merge_subset)
   /* second one was already contained in the first one */
   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,3]");
   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels=[1,3]");
@@ -455,7 +455,7 @@ GST_START_TEST (test_merge_subset)
   /* second one was already contained in the first one */
   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,4]");
   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels=[1,4]");
@@ -466,7 +466,7 @@ GST_START_TEST (test_merge_subset)
   /* second one was already contained in the first one */
   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,4]");
   c1 = gst_caps_from_string ("audio/x-raw,channels=[2,4]");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels=[1,4]");
@@ -477,7 +477,7 @@ GST_START_TEST (test_merge_subset)
   /* second one was already contained in the first one */
   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,4]");
   c1 = gst_caps_from_string ("audio/x-raw,channels=[2,3]");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels=[1,4]");
@@ -488,7 +488,7 @@ GST_START_TEST (test_merge_subset)
   /* these caps cannot be merged */
   c2 = gst_caps_from_string ("audio/x-raw,channels=[2,3]");
   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,4]");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   test =
@@ -501,7 +501,7 @@ GST_START_TEST (test_merge_subset)
   /* these caps cannot be merged */
   c2 = gst_caps_from_string ("audio/x-raw,channels=[1,2]");
   c1 = gst_caps_from_string ("audio/x-raw,channels=[1,3]");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   test =
@@ -513,7 +513,7 @@ GST_START_TEST (test_merge_subset)
 
   c2 = gst_caps_from_string ("audio/x-raw,channels={1,2}");
   c1 = gst_caps_from_string ("audio/x-raw,channels={1,2,3,4}");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels={1,2};"
@@ -524,7 +524,7 @@ GST_START_TEST (test_merge_subset)
 
   c2 = gst_caps_from_string ("audio/x-raw,channels={1,2}");
   c1 = gst_caps_from_string ("audio/x-raw,channels={1,3}");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels={1,2};"
@@ -536,7 +536,7 @@ GST_START_TEST (test_merge_subset)
   c2 = gst_caps_from_string ("video/x-raw, framerate=(fraction){ 15/2, 5/1 }");
   c1 = gst_caps_from_string ("video/x-raw, framerate=(fraction){ 15/1, 5/1 }");
   test = gst_caps_copy (c1);
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_is_subset (test, c2));
   gst_caps_unref (test);
@@ -544,7 +544,7 @@ GST_START_TEST (test_merge_subset)
 
   c2 = gst_caps_from_string ("audio/x-raw");
   c1 = gst_caps_from_string ("audio/x-raw,channels=1");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 1, NULL);
   test = gst_caps_from_string ("audio/x-raw");
@@ -554,7 +554,7 @@ GST_START_TEST (test_merge_subset)
 
   c2 = gst_caps_from_string ("audio/x-raw,channels=1");
   c1 = gst_caps_from_string ("audio/x-raw");
-  gst_caps_merge (c2, c1);
+  c2 = gst_caps_merge (c2, c1);
   GST_DEBUG ("merged: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (c2), c2);
   fail_unless (gst_caps_get_size (c2) == 2, NULL);
   test = gst_caps_from_string ("audio/x-raw,channels=1; audio/x-raw");