pad: Add gst_pad_sticky_events_iterate() function
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 24 May 2011 14:08:41 +0000 (16:08 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 24 May 2011 14:17:53 +0000 (16:17 +0200)
gst/gstpad.c
gst/gstpad.h

index b4ad5fb..715ec63 100644 (file)
@@ -5129,6 +5129,68 @@ gst_pad_get_sticky_event (GstPad * pad, GstEventType event_type)
   return event;
 }
 
+/**
+ * gst_pad_sticky_events_foreach:
+ * @pad: the #GstPad that should be used for iteration.
+ * @foreach_func: (scope call): the #GstPadStickyEventsForeachFunction that should be called for every event.
+ * @user_data: (closure): the optional user data.
+ *
+ * Iterates all active sticky events on @pad and calls @foreach_func for every
+ * event. If @foreach_func returns something else than GST_FLOW_OK the iteration
+ * is immediately stopped.
+ *
+ * Returns: GST_FLOW_OK if iteration was successful
+ */
+GstFlowReturn
+gst_pad_sticky_events_foreach (GstPad * pad,
+    GstPadStickyEventsForeachFunction foreach_func, gpointer user_data)
+{
+  GstFlowReturn ret = GST_FLOW_OK;
+  guint i;
+  GstEvent *event;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (foreach_func != NULL, GST_FLOW_ERROR);
+
+  GST_OBJECT_LOCK (pad);
+
+restart:
+  for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
+    gboolean res;
+    PadEvent *ev;
+
+    ev = &pad->priv->events[i];
+
+    /* skip without active event */
+    if ((event = ev->event) == NULL)
+      continue;
+
+    gst_event_ref (event);
+    GST_OBJECT_UNLOCK (pad);
+
+    res = foreach_func (pad, event, user_data);
+
+    GST_OBJECT_LOCK (pad);
+    gst_event_unref (event);
+
+    if (res != GST_FLOW_OK) {
+      ret = res;
+      break;
+    }
+
+    /* things could have changed while we release the lock, check if we still
+     * are handling the same event, if we don't something changed and we have
+     * to try again. FIXME. we need a cookie here. */
+    if (event != ev->event) {
+      GST_DEBUG_OBJECT (pad, "events changed, restarting");
+      goto restart;
+    }
+  }
+  GST_OBJECT_UNLOCK (pad);
+
+  return ret;
+}
+
 static void
 do_stream_status (GstPad * pad, GstStreamStatusType type,
     GThread * thread, GstTask * task)
index b145887..f451066 100644 (file)
@@ -496,6 +496,18 @@ typedef gboolean           (*GstPadDispatcherFunction)     (GstPad *pad, gpointer data);
 typedef void                   (*GstPadBlockCallback)          (GstPad *pad, gboolean blocked, gpointer user_data);
 
 /**
+ * GstPadStickyEventsForeachFunction:
+ * @pad: the #GstPad.
+ * @event: the sticky #GstEvent.
+ * @user_data: the #gpointer to optional user data.
+ *
+ * Callback used by gst_pad_sticky_events_foreach().
+ *
+ * Returns: GST_FLOW_OK if the iteration should continue
+ */
+typedef GstFlowReturn           (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEvent *event, gpointer user_data);
+
+/**
  * GstPadDirection:
  * @GST_PAD_UNKNOWN: direction is unknown.
  * @GST_PAD_SRC: the pad is a source pad.
@@ -822,6 +834,7 @@ gpointer            gst_pad_get_element_private             (GstPad *pad);
 GstPadTemplate*                gst_pad_get_pad_template                (GstPad *pad);
 
 GstEvent*               gst_pad_get_sticky_event                (GstPad *pad, GstEventType event_type);
+GstFlowReturn           gst_pad_sticky_events_foreach           (GstPad *pad, GstPadStickyEventsForeachFunction foreach_func, gpointer user_data);
 
 /* data passing setup functions */
 void                   gst_pad_set_activate_function           (GstPad *pad, GstPadActivateFunction activate);