typedef struct
{
GstPad *pad;
- GstPadProbeType mask;
- gpointer type_data;
+ GstPadProbeInfo *info;
gboolean dropped;
gboolean pass;
gboolean marshalled;
"pad is in use, delay idle callback");
GST_OBJECT_UNLOCK (pad);
} else {
+ GstPadProbeInfo info = { GST_PAD_PROBE_TYPE_IDLE, };
+
/* the pad is idle now, we can signal the idle callback now */
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"pad is idle, trigger idle callback");
GST_OBJECT_UNLOCK (pad);
- callback (pad, GST_PAD_PROBE_TYPE_IDLE, NULL, user_data);
+ callback (pad, &info, user_data);
}
} else {
GST_OBJECT_UNLOCK (pad);
probe_hook_marshal (GHook * hook, ProbeMarshall * data)
{
GstPad *pad = data->pad;
- GstPadProbeType flags;
+ GstPadProbeInfo *info = data->info;
+ GstPadProbeType type, flags;
GstPadProbeCallback callback;
GstPadProbeReturn ret;
PROBE_COOKIE (hook) = data->cookie;
flags = hook->flags >> G_HOOK_FLAG_USER_SHIFT;
+ type = info->type;
/* one of the data types */
- if ((flags & GST_PAD_PROBE_TYPE_DATA_BOTH & data->mask) == 0)
+ if ((flags & GST_PAD_PROBE_TYPE_DATA_BOTH & type) == 0)
goto no_match;
/* one of the scheduling types */
- if ((flags & GST_PAD_PROBE_TYPE_SCHEDULING & data->mask) == 0)
+ if ((flags & GST_PAD_PROBE_TYPE_SCHEDULING & type) == 0)
goto no_match;
/* all of the blocking types must match */
if ((flags & GST_PAD_PROBE_TYPE_BLOCKING) !=
- (data->mask & GST_PAD_PROBE_TYPE_BLOCKING))
+ (type & GST_PAD_PROBE_TYPE_BLOCKING))
goto no_match;
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
GST_OBJECT_UNLOCK (pad);
- ret = callback (pad, data->mask, data->type_data, hook->data);
+ ret = callback (pad, info, hook->data);
GST_OBJECT_LOCK (pad);
data->marshalled = TRUE;
/* need to drop the data, make sure other probes don't get called
* anymore */
GST_DEBUG_OBJECT (pad, "asked to drop item");
- data->mask = GST_PAD_PROBE_TYPE_INVALID;
+ info->type = GST_PAD_PROBE_TYPE_INVALID;
data->dropped = TRUE;
break;
case GST_PAD_PROBE_PASS:
{
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"hook %lu with flags 0x%08x does not match %08x", hook->hook_id,
- flags, data->mask);
+ flags, info->type);
return;
}
}
-#define PROBE_FULL(pad,mask,data,label,defaultval) \
+#define PROBE_ND_FULL(pad,mask,label,defaultval) \
+ G_STMT_START { \
+ if (G_UNLIKELY (pad->num_probes)) { \
+ GstPadProbeInfo info = { mask, NULL }; \
+ ret = do_probe_callbacks (pad, &info, defaultval); \
+ if (G_UNLIKELY (ret != defaultval && ret != GST_FLOW_OK)) \
+ goto label; \
+ } \
+ } G_STMT_END
+
+#define PROBE_FULL(pad,mask,data,label,defaultval) \
G_STMT_START { \
if (G_UNLIKELY (pad->num_probes)) { \
- ret = do_probe_callbacks (pad, mask, data, defaultval); \
+ GstPadProbeInfo info = { mask, data }; \
+ ret = do_probe_callbacks (pad, &info, defaultval); \
+ data = GST_PAD_PROBE_INFO_DATA (&info); \
if (G_UNLIKELY (ret != defaultval && ret != GST_FLOW_OK)) \
goto label; \
} \
#define PROBE(pad,mask,data,label) \
PROBE_FULL(pad, mask, data, label, GST_FLOW_OK);
+#define PROBE_ND(pad,mask,label) \
+ PROBE_ND_FULL(pad, mask, label, GST_FLOW_OK);
static GstFlowReturn
-do_probe_callbacks (GstPad * pad, GstPadProbeType mask, gpointer type_data,
+do_probe_callbacks (GstPad * pad, GstPadProbeInfo * info,
GstFlowReturn defaultval)
{
ProbeMarshall data;
guint cookie;
gboolean is_block;
- is_block = (mask & GST_PAD_PROBE_TYPE_BLOCK) == GST_PAD_PROBE_TYPE_BLOCK;
-
data.pad = pad;
- data.mask = mask;
- data.type_data = type_data;
+ data.info = info;
data.pass = FALSE;
data.marshalled = FALSE;
data.dropped = FALSE;
data.cookie = ++pad->priv->probe_cookie;
+ is_block =
+ (info->type & GST_PAD_PROBE_TYPE_BLOCK) == GST_PAD_PROBE_TYPE_BLOCK;
+
again:
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"do probes cookie %u", data.cookie);
pad->priv->using--;
if (pad->priv->using == 0) {
/* pad is not active anymore, trigger idle callbacks */
- PROBE_FULL (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE, NULL,
+ PROBE_ND_FULL (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE,
probe_stopped, ret);
}
GST_OBJECT_UNLOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
- PROBE (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BLOCK, NULL,
+ PROBE_ND (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BLOCK,
probe_stopped);
GST_OBJECT_UNLOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
- PROBE (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BLOCK, NULL,
+ PROBE_ND (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_BLOCK,
pre_probe_stopped);
if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
pad->priv->using--;
if (pad->priv->using == 0) {
/* pad is not active anymore, trigger idle callbacks */
- PROBE (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_IDLE, NULL,
+ PROBE_ND (pad, GST_PAD_PROBE_TYPE_PULL | GST_PAD_PROBE_TYPE_IDLE,
post_probe_stopped);
}
pad->priv->using--;
if (pad->priv->using == 0) {
/* pad is not active anymore, trigger idle callbacks */
- PROBE (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE, NULL,
+ PROBE_ND (pad, GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_IDLE,
probe_stopped);
}
GST_OBJECT_UNLOCK (pad);
GST_PAD_PROBE_PASS,
} GstPadProbeReturn;
+
+/**
+ * GstPadProbeInfo:
+ * @type: the current probe type
+ * @data: type specific data
+ *
+ * Info passed in the #GstPadProbeCallback.
+ */
+typedef struct
+{
+ GstPadProbeType type;
+ gpointer data;
+} GstPadProbeInfo;
+
+#define GST_PAD_PROBE_INFO_TYPE(d) ((d)->type)
+#define GST_PAD_PROBE_INFO_DATA(d) ((d)->data)
+
+#define GST_PAD_PROBE_INFO_BUFFER(d) GST_BUFFER_CAST(GST_PAD_PROBE_INFO_DATA(d))
+#define GST_PAD_PROBE_INFO_BUFFER_LIST(d) GST_BUFFER_LIST_CAST(GST_PAD_PROBE_INFO_DATA(d))
+#define GST_PAD_PROBE_INFO_EVENT(d) GST_EVENT_CAST(GST_PAD_PROBE_INFO_DATA(d))
+
/**
* GstPadProbeCallback
* @pad: the #GstPad that is blocked
- * @type: the current probe type
- * @type_data: type specific data
+ * @info: #GstPadProbeInfo
* @user_data: the gpointer to optional user data.
*
* Callback used by gst_pad_add_probe(). Gets called to notify about the current
* blocking type.
*/
-typedef GstPadProbeReturn (*GstPadProbeCallback) (GstPad *pad, GstPadProbeType type,
- gpointer type_data, gpointer user_data);
+typedef GstPadProbeReturn (*GstPadProbeCallback) (GstPad *pad, GstPadProbeInfo *info,
+ gpointer user_data);
/**
* GstPadStickyEventsForeachFunction:
/* called for every buffer. Waits until the global "buf" variable is unset,
* then sets it to the buffer received, and signals. */
-static gboolean
-buffer_probe (GstPad * pad, GstPadProbeType type, GstBuffer * buffer,
- gpointer unused)
+static GstPadProbeReturn
+buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer unused)
{
+ GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
+
g_mutex_lock (lock);
while (buf != NULL)
g_mutex_unlock (lock);
- return TRUE;
+ return GST_PAD_PROBE_OK;
}
/**
GstStateChangeReturn ret;
id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER,
- (GstPadProbeCallback) buffer_probe, NULL, NULL);
+ buffer_probe, NULL, NULL);
cond = g_cond_new ();
lock = g_mutex_new ();
};
static gboolean
-source_pad_data_cb (GstPad * pad, GstPadProbeType type, GstMiniObject * data,
+source_pad_data_cb (GstPad * pad, GstPadProbeInfo * info,
GstStreamConsistency * consist)
{
+ GstMiniObject *data = GST_PAD_PROBE_INFO_DATA (info);
+
if (GST_IS_BUFFER (data)) {
GST_DEBUG_OBJECT (pad,
"Buffer pts %" GST_TIME_FORMAT ", dts %" GST_TIME_FORMAT,
/* Data probe cb to drop everything but count buffers and events */
static GstPadProbeReturn
-probe_cb (GstPad * pad, GstPadProbeType type, GstMiniObject * obj,
- gpointer user_data)
+probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
gint count = 0;
const gchar *count_type = NULL;
+ GstMiniObject *obj = GST_PAD_PROBE_INFO_DATA (info);
GST_LOG_OBJECT (pad, "got data");
static GCond *blocked_cond;
static GstPadProbeReturn
-pad_blocked_cb (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer user_data)
+pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
g_mutex_lock (blocked_lock);
- GST_DEBUG ("srcpad blocked: %d, sending signal", type);
+ GST_DEBUG ("srcpad blocked: %d, sending signal", info->type);
g_cond_signal (blocked_cond);
g_mutex_unlock (blocked_lock);
static GTimeVal got_event_time;
static GstPadProbeReturn
-event_probe (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer user_data)
+event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
- GstMiniObject *data = type_data;
+ GstMiniObject *data = GST_PAD_PROBE_INFO_DATA (info);
gboolean before_q = (gboolean) GPOINTER_TO_INT (user_data);
GST_DEBUG ("event probe called %p", data);
}
static GstPadProbeReturn
-signal_blocked (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer user_data)
+signal_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
SignalData *data = (SignalData *) user_data;
signal_data_signal (data);
GST_DEBUG ("signal done %p", data);
- if (GST_IS_EVENT (type_data) && GST_EVENT_IS_UPSTREAM (type_data))
- return GST_PAD_PROBE_PASS;
-
return GST_PAD_PROBE_OK;
}
signal_data_init (&data);
/* We block the pad so the stream lock is released and we can send the event */
- id = gst_pad_add_probe (fake_srcpad, GST_PAD_PROBE_TYPE_BLOCK,
+ id = gst_pad_add_probe (fake_srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
signal_blocked, &data, NULL);
fail_unless (id != 0);
} BlockData;
static GstPadProbeReturn
-block_callback (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer user_data)
+block_callback (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
BlockData *block_data = (BlockData *) user_data;
GST_END_TEST;
static GstPadProbeReturn
-_probe_handler (GstPad * pad, GstPadProbeType type, GstBuffer * buffer,
- gpointer userdata)
+_probe_handler (GstPad * pad, GstPadProbeInfo * info, gpointer userdata)
{
gint ret = GPOINTER_TO_INT (userdata);
static gulong id;
static GstPadProbeReturn
-block_async_cb (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer user_data)
+block_async_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
gboolean *bool_user_data = (gboolean *) user_data;
- fail_unless ((type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
+ fail_unless ((info->type & GST_PAD_PROBE_TYPE_BLOCK) != 0);
/* here we should have blocked == 0 unblocked == 0 */
fail_unless (bool_user_data[0] == FALSE);
}
static GstPadProbeReturn
-block_async_full_cb (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer user_data)
+block_async_full_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
*(gint *) user_data = (gint) TRUE;
#endif
static GstPadProbeReturn
-block_async_second_no_flush (GstPad * pad, GstPadProbeType type,
- gpointer type_data, gpointer user_data)
+block_async_second_no_flush (GstPad * pad, GstPadProbeInfo * info,
+ gpointer user_data)
{
gboolean *bool_user_data = (gboolean *) user_data;
GST_DEBUG ("second probe called");
- fail_unless (type & GST_PAD_PROBE_TYPE_BLOCK);
+ fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
fail_unless (bool_user_data[0] == TRUE);
fail_unless (bool_user_data[1] == FALSE);
}
static GstPadProbeReturn
-block_async_first_no_flush (GstPad * pad, GstPadProbeType type,
- gpointer type_data, gpointer user_data)
+block_async_first_no_flush (GstPad * pad, GstPadProbeInfo * info,
+ gpointer user_data)
{
static int n_calls = 0;
gboolean *bool_user_data = (gboolean *) user_data;
- fail_unless (type & GST_PAD_PROBE_TYPE_BLOCK);
+ fail_unless (info->type & GST_PAD_PROBE_TYPE_BLOCK);
GST_DEBUG ("first probe called");
static int n_event_probes = 0;
static GstPadProbeReturn
-probe_do_nothing (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer data)
+probe_do_nothing (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
- GstMiniObject *obj = type_data;
+ GstMiniObject *obj = GST_PAD_PROBE_INFO_DATA (info);
GST_DEBUG_OBJECT (pad, "is buffer:%d", GST_IS_BUFFER (obj));
return GST_PAD_PROBE_OK;
}
static GstPadProbeReturn
-data_probe (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer data)
+data_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
- GstMiniObject *obj = type_data;
+ GstMiniObject *obj = GST_PAD_PROBE_INFO_DATA (info);
n_data_probes++;
GST_DEBUG_OBJECT (pad, "data probe %d", n_data_probes);
g_assert (GST_IS_BUFFER (obj) || GST_IS_EVENT (obj));
}
static GstPadProbeReturn
-buffer_probe (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer data)
+buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
- GstBuffer *obj = type_data;
+ GstBuffer *obj = GST_PAD_PROBE_INFO_BUFFER (info);
n_buffer_probes++;
GST_DEBUG_OBJECT (pad, "buffer probe %d", n_buffer_probes);
g_assert (GST_IS_BUFFER (obj));
}
static GstPadProbeReturn
-event_probe (GstPad * pad, GstPadProbeType type, gpointer type_data,
- gpointer data)
+event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
- GstEvent *obj = type_data;
+ GstEvent *obj = GST_PAD_PROBE_INFO_EVENT (info);
n_event_probes++;
GST_DEBUG_OBJECT (pad, "event probe %d [%s]",
n_event_probes, GST_EVENT_TYPE_NAME (obj));
static int n_event_probes_once = 0;
static GstPadProbeReturn
-data_probe_once (GstPad * pad, GstPadProbeType type, GstMiniObject * obj,
- guint * data)
+data_probe_once (GstPad * pad, GstPadProbeInfo * info, guint * data)
{
+ GstMiniObject *obj = GST_PAD_PROBE_INFO_DATA (info);
+
n_data_probes_once++;
g_assert (GST_IS_BUFFER (obj) || GST_IS_EVENT (obj));
}
static GstPadProbeReturn
-buffer_probe_once (GstPad * pad, GstPadProbeType type, GstBuffer * obj,
- guint * data)
+buffer_probe_once (GstPad * pad, GstPadProbeInfo * info, guint * data)
{
+ GstBuffer *obj = GST_PAD_PROBE_INFO_BUFFER (info);
+
n_buffer_probes_once++;
g_assert (GST_IS_BUFFER (obj));
}
static GstPadProbeReturn
-event_probe_once (GstPad * pad, GstPadProbeType type, GstEvent * obj,
- guint * data)
+event_probe_once (GstPad * pad, GstPadProbeInfo * info, guint * data)
{
+ GstEvent *obj = GST_PAD_PROBE_INFO_EVENT (info);
+
n_event_probes_once++;
g_assert (GST_IS_EVENT (obj));
#include <gst/base/gstbasesrc.h>
static GstPadProbeReturn
-eos_event_counter (GstObject * pad, GstPadProbeType type, GstEvent * event,
- guint * p_num_eos)
+eos_event_counter (GstObject * pad, GstPadProbeInfo * info, guint * p_num_eos)
{
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+
fail_unless (event != NULL);
fail_unless (GST_IS_EVENT (event));
static GstPadProbeReturn
-segment_event_catcher (GstObject * pad, GstPadProbeType type, GstEvent * event,
+segment_event_catcher (GstObject * pad, GstPadProbeInfo * info,
gpointer * user_data)
{
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
GstEvent **last_event = (GstEvent **) user_data;
fail_unless (event != NULL);
fail_unless (GST_IS_EVENT (event));
#include <gst/gst.h>
static GstPadProbeReturn
-modify_caps (GstObject * pad, GstPadProbeType type, GstEvent * event,
- gpointer data)
+modify_caps (GstObject * pad, GstPadProbeInfo * info, gpointer data)
{
+ GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
GstElement *filter = GST_ELEMENT (data);
GstCaps *caps;