Add gst_pad_add_*_probe_full() functions with a notify callback that lets the caller...
authorJosé Alburquerque <jaalburqu@svn.gnome.org>
Thu, 10 Apr 2008 20:46:51 +0000 (20:46 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Thu, 10 Apr 2008 20:46:51 +0000 (20:46 +0000)
Original commit message from CVS:
Based on patch by: José Alburquerque <jaalburqu at svn dot gnome dot org>
* gst/gstutils.c: (gst_pad_add_data_probe),
(gst_pad_add_data_probe_full), (gst_pad_add_event_probe),
(gst_pad_add_event_probe_full), (gst_pad_add_buffer_probe),
(gst_pad_add_buffer_probe_full):
* gst/gstutils.h:
* docs/gst/gstreamer-sections.txt:
* win32/common/libgstreamer.def:
Add gst_pad_add_*_probe_full() functions with a notify callback that
lets the caller free the data it passes to the probe functions. This
is useful for bindings such as gst-python or gstreamermm (#526814).
API: gst_pad_add_data_probe_full
API: gst_pad_add_buffer_probe_full
API: gst_pad_add_event_probe_full
* tests/check/gst/gstutils.c:
Add minimal unit test to make sure freeing the data actually works
as expected.
* tests/benchmarks/.cvsignore:
Random cvsignore addendum.

ChangeLog
docs/gst/gstreamer-sections.txt
gst/gstutils.c
gst/gstutils.h
tests/benchmarks/.gitignore
tests/check/gst/gstutils.c
win32/common/libgstreamer.def

index 68e2b28..f2049f1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
 2008-04-10  Tim-Philipp Müller  <tim at centricular dot net>
 
+       Based on patch by: José Alburquerque <jaalburqu at svn dot gnome dot org>
+
+       * gst/gstutils.c: (gst_pad_add_data_probe),
+         (gst_pad_add_data_probe_full), (gst_pad_add_event_probe),
+         (gst_pad_add_event_probe_full), (gst_pad_add_buffer_probe),
+         (gst_pad_add_buffer_probe_full):
+       * gst/gstutils.h:
+       * docs/gst/gstreamer-sections.txt:
+       * win32/common/libgstreamer.def:
+         Add gst_pad_add_*_probe_full() functions with a notify callback that
+         lets the caller free the data it passes to the probe functions. This
+         is useful for bindings such as gst-python or gstreamermm (#526814).
+         API: gst_pad_add_data_probe_full
+         API: gst_pad_add_buffer_probe_full
+         API: gst_pad_add_event_probe_full
+
+       * tests/check/gst/gstutils.c:
+         Add minimal unit test to make sure freeing the data actually works
+         as expected.
+
+       * tests/benchmarks/.cvsignore:
+         Random cvsignore addendum.
+
+2008-04-10  Tim-Philipp Müller  <tim at centricular dot net>
+
        * gst/gstdebugutils.h: (GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS),
          (GST_DEBUG_BIN_TO_DOT_FILE):
          Mention GstDebugGraphDetails enum type in doc blurb so we get a link
index e29d214..3998f80 100644 (file)
@@ -1236,8 +1236,11 @@ gst_pad_is_blocked
 gst_pad_is_blocking
 
 gst_pad_add_data_probe
+gst_pad_add_data_probe_full
 gst_pad_add_buffer_probe
+gst_pad_add_buffer_probe_full
 gst_pad_add_event_probe
+gst_pad_add_event_probe_full
 gst_pad_remove_data_probe
 gst_pad_remove_buffer_probe
 gst_pad_remove_event_probe
index dd2a407..7998c21 100644 (file)
@@ -2872,13 +2872,60 @@ gst_atomic_int_set (gint * atomic_int, gint value)
 gulong
 gst_pad_add_data_probe (GstPad * pad, GCallback handler, gpointer data)
 {
+  return gst_pad_add_data_probe_full (pad, handler, data, NULL);
+}
+
+/**
+ * gst_pad_add_data_probe_full:
+ * @pad: pad to add the data probe handler to
+ * @handler: function to call when data is passed over pad
+ * @data: data to pass along with the handler
+ * @notify: function to call when the probe is disconnected, or NULL
+ *
+ * Adds a "data probe" to a pad. This function will be called whenever data
+ * passes through a pad. In this case data means both events and buffers. The
+ * probe will be called with the data as an argument, meaning @handler should
+ * have the same callback signature as the #GstPad::have-data signal.
+ * Note that the data will have a reference count greater than 1, so it will
+ * be immutable -- you must not change it.
+ *
+ * For source pads, the probe will be called after the blocking function, if any
+ * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
+ * to. For sink pads, the probe function will be called before configuring the
+ * sink with new caps, if any, and before calling the pad's chain function.
+ *
+ * Your data probe should return TRUE to let the data continue to flow, or FALSE
+ * to drop it. Dropping data is rarely useful, but occasionally comes in handy
+ * with events.
+ *
+ * Although probes are implemented internally by connecting @handler to the
+ * have-data signal on the pad, if you want to remove a probe it is insufficient
+ * to only call g_signal_handler_disconnect on the returned handler id. To
+ * remove a probe, use the appropriate function, such as
+ * gst_pad_remove_data_probe().
+ *
+ * The @notify function is called when the probe is disconnected and usually
+ * used to free @data.
+ *
+ * Returns: The handler id.
+ *
+ * Since: 0.10.20
+ */
+gulong
+gst_pad_add_data_probe_full (GstPad * pad, GCallback handler,
+    gpointer data, GDestroyNotify notify)
+{
   gulong sigid;
 
   g_return_val_if_fail (GST_IS_PAD (pad), 0);
   g_return_val_if_fail (handler != NULL, 0);
 
   GST_OBJECT_LOCK (pad);
-  sigid = g_signal_connect (pad, "have-data", handler, data);
+
+  /* we only expose a GDestroyNotify in our API because that's less confusing */
+  sigid = g_signal_connect_data (pad, "have-data", handler, data,
+      (GClosureNotify) notify, 0);
+
   GST_PAD_DO_EVENT_SIGNALS (pad)++;
   GST_PAD_DO_BUFFER_SIGNALS (pad)++;
   GST_DEBUG ("adding data probe to pad %s:%s, now %d data, %d event probes",
@@ -2903,13 +2950,41 @@ gst_pad_add_data_probe (GstPad * pad, GCallback handler, gpointer data)
 gulong
 gst_pad_add_event_probe (GstPad * pad, GCallback handler, gpointer data)
 {
+  return gst_pad_add_event_probe_full (pad, handler, data, NULL);
+}
+
+/**
+ * gst_pad_add_event_probe_full:
+ * @pad: pad to add the event probe handler to
+ * @handler: function to call when events are passed over pad
+ * @data: data to pass along with the handler, or NULL
+ * @notify: function to call when probe is disconnected, or NULL
+ *
+ * Adds a probe that will be called for all events passing through a pad. See
+ * gst_pad_add_data_probe() for more information.
+ *
+ * The @notify function is called when the probe is disconnected and usually
+ * used to free @data.
+ *
+ * Returns: The handler id
+ *
+ * Since: 0.10.20
+ */
+gulong
+gst_pad_add_event_probe_full (GstPad * pad, GCallback handler,
+    gpointer data, GDestroyNotify notify)
+{
   gulong sigid;
 
   g_return_val_if_fail (GST_IS_PAD (pad), 0);
   g_return_val_if_fail (handler != NULL, 0);
 
   GST_OBJECT_LOCK (pad);
-  sigid = g_signal_connect (pad, "have-data::event", handler, data);
+
+  /* we only expose a GDestroyNotify in our API because that's less confusing */
+  sigid = g_signal_connect_data (pad, "have-data::event", handler, data,
+      (GClosureNotify) notify, 0);
+
   GST_PAD_DO_EVENT_SIGNALS (pad)++;
   GST_DEBUG ("adding event probe to pad %s:%s, now %d probes",
       GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
@@ -2932,13 +3007,41 @@ gst_pad_add_event_probe (GstPad * pad, GCallback handler, gpointer data)
 gulong
 gst_pad_add_buffer_probe (GstPad * pad, GCallback handler, gpointer data)
 {
+  return gst_pad_add_buffer_probe_full (pad, handler, data, NULL);
+}
+
+/**
+ * gst_pad_add_buffer_probe_full:
+ * @pad: pad to add the buffer probe handler to
+ * @handler: function to call when buffer are passed over pad
+ * @data: data to pass along with the handler
+ * @notify: function to call when the probe is disconnected, or NULL
+ *
+ * Adds a probe that will be called for all buffers passing through a pad. See
+ * gst_pad_add_data_probe() for more information.
+ *
+ * The @notify function is called when the probe is disconnected and usually
+ * used to free @data.
+ *
+ * Returns: The handler id
+ *
+ * Since: 0.10.20
+ */
+gulong
+gst_pad_add_buffer_probe_full (GstPad * pad, GCallback handler,
+    gpointer data, GDestroyNotify notify)
+{
   gulong sigid;
 
   g_return_val_if_fail (GST_IS_PAD (pad), 0);
   g_return_val_if_fail (handler != NULL, 0);
 
   GST_OBJECT_LOCK (pad);
-  sigid = g_signal_connect (pad, "have-data::buffer", handler, data);
+
+  /* we only expose a GDestroyNotify in our API because that's less confusing */
+  sigid = g_signal_connect_data (pad, "have-data::buffer", handler, data,
+      (GClosureNotify) notify, 0);
+
   GST_PAD_DO_BUFFER_SIGNALS (pad)++;
   GST_DEBUG ("adding buffer probe to pad %s:%s, now %d probes",
       GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_BUFFER_SIGNALS (pad));
index cf1aded..3685709 100644 (file)
@@ -664,17 +664,37 @@ void                      gst_buffer_stamp                (GstBuffer * dest, const GstBuffer * src);
 void                    gst_atomic_int_set              (gint * atomic_int, gint value);
 
 /* probes */
-gulong                 gst_pad_add_data_probe          (GstPad * pad,
-                                                        GCallback handler,
-                                                        gpointer data);
+gulong                 gst_pad_add_data_probe          (GstPad   * pad,
+                                                        GCallback  handler,
+                                                        gpointer   data);
+
+gulong                 gst_pad_add_data_probe_full     (GstPad       * pad,
+                                                        GCallback      handler,
+                                                        gpointer       data,
+                                                        GDestroyNotify notify);
+
 void                   gst_pad_remove_data_probe       (GstPad * pad, guint handler_id);
-gulong                 gst_pad_add_event_probe         (GstPad * pad,
-                                                        GCallback handler,
-                                                        gpointer data);
+
+gulong                 gst_pad_add_event_probe         (GstPad   * pad,
+                                                        GCallback  handler,
+                                                        gpointer   data);
+
+gulong                 gst_pad_add_event_probe_full    (GstPad       * pad,
+                                                        GCallback      handler,
+                                                        gpointer       data,
+                                                        GDestroyNotify notify);
+
 void                   gst_pad_remove_event_probe      (GstPad * pad, guint handler_id);
-gulong                 gst_pad_add_buffer_probe        (GstPad * pad,
-                                                        GCallback handler,
-                                                        gpointer data);
+
+gulong                 gst_pad_add_buffer_probe        (GstPad   * pad,
+                                                        GCallback  handler,
+                                                        gpointer   data);
+
+gulong                 gst_pad_add_buffer_probe_full   (GstPad       * pad,
+                                                        GCallback      handler,
+                                                        gpointer       data,
+                                                        GDestroyNotify notify);
+
 void                   gst_pad_remove_buffer_probe     (GstPad * pad, guint handler_id);
 
 /* tag emission utility functions */
index 8e9eced..710923c 100644 (file)
@@ -2,5 +2,6 @@ Makefile
 Makefile.in
 caps
 complexity
+gstpollstress
 mass-elements
 *.gcno
index 933a567..e1aebb2 100644 (file)
@@ -29,6 +29,12 @@ static int n_buffer_probes = 0;
 static int n_event_probes = 0;
 
 static gboolean
+probe_do_nothing (GstPad * pad, GstMiniObject * obj, gpointer data)
+{
+  return TRUE;
+}
+
+static gboolean
 data_probe (GstPad * pad, GstMiniObject * obj, gpointer data)
 {
   n_data_probes++;
@@ -75,10 +81,22 @@ GST_START_TEST (test_buffer_probe_n_times)
   gst_element_link (fakesrc, fakesink);
 
   pad = gst_element_get_pad (fakesink, "sink");
+
+  /* add the probes we need for the test */
   gst_pad_add_data_probe (pad, G_CALLBACK (data_probe), SPECIAL_POINTER (0));
   gst_pad_add_buffer_probe (pad, G_CALLBACK (buffer_probe),
       SPECIAL_POINTER (1));
   gst_pad_add_event_probe (pad, G_CALLBACK (event_probe), SPECIAL_POINTER (2));
+
+  /* add some probes just to test that _full works and the data is free'd
+   * properly as it should be */
+  gst_pad_add_data_probe_full (pad, G_CALLBACK (probe_do_nothing),
+      g_strdup ("data probe string"), (GDestroyNotify) g_free);
+  gst_pad_add_buffer_probe_full (pad, G_CALLBACK (probe_do_nothing),
+      g_strdup ("buffer probe string"), (GDestroyNotify) g_free);
+  gst_pad_add_event_probe_full (pad, G_CALLBACK (probe_do_nothing),
+      g_strdup ("event probe string"), (GDestroyNotify) g_free);
+
   gst_object_unref (pad);
 
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
index b3bc93f..0121c32 100644 (file)
@@ -509,8 +509,11 @@ EXPORTS
        gst_pad_activate_pull
        gst_pad_activate_push
        gst_pad_add_buffer_probe
+       gst_pad_add_buffer_probe_full
        gst_pad_add_data_probe
+       gst_pad_add_data_probe_full
        gst_pad_add_event_probe
+       gst_pad_add_event_probe_full
        gst_pad_alloc_buffer
        gst_pad_alloc_buffer_and_set_caps
        gst_pad_can_link