pad: Add GstPadProbeInfo

Make a new GstPadProbeInfo structure and pass this in the probe callback. This
allows us to add more things later and also allow the callback to replace or
modify the passed object.
This commit is contained in:
Wim Taymans 2011-11-08 11:04:19 +01:00
parent 1713aaa4c5
commit ba3028aeeb
12 changed files with 115 additions and 84 deletions

View file

@ -125,8 +125,7 @@ typedef struct
typedef struct
{
GstPad *pad;
GstPadProbeType mask;
gpointer type_data;
GstPadProbeInfo *info;
gboolean dropped;
gboolean pass;
gboolean marshalled;
@ -1118,12 +1117,14 @@ gst_pad_add_probe (GstPad * pad, GstPadProbeType mask,
"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);
@ -3320,7 +3321,8 @@ static void
probe_hook_marshal (GHook * hook, ProbeMarshall * data)
{
GstPad *pad = data->pad;
GstPadProbeType flags;
GstPadProbeInfo *info = data->info;
GstPadProbeType type, flags;
GstPadProbeCallback callback;
GstPadProbeReturn ret;
@ -3338,16 +3340,17 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data)
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,
@ -3359,7 +3362,7 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data)
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;
@ -3374,7 +3377,7 @@ probe_hook_marshal (GHook * hook, ProbeMarshall * data)
/* 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:
@ -3392,15 +3395,27 @@ no_match:
{
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)) { \
ret = do_probe_callbacks (pad, mask, data, defaultval); \
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)) { \
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; \
} \
@ -3408,25 +3423,27 @@ no_match:
#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);
@ -3848,7 +3865,7 @@ gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
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);
@ -3974,7 +3991,7 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
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);
@ -4122,7 +4139,7 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
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))
@ -4140,7 +4157,7 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
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);
}
@ -4378,7 +4395,7 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
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);

View file

@ -527,18 +527,38 @@ typedef enum
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:

View file

@ -37,10 +37,11 @@ static gulong id;
/* 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)
@ -53,7 +54,7 @@ buffer_probe (GstPad * pad, GstPadProbeType type, GstBuffer * buffer,
g_mutex_unlock (lock);
return TRUE;
return GST_PAD_PROBE_OK;
}
/**
@ -83,7 +84,7 @@ gst_buffer_straw_start_pipeline (GstElement * bin, GstPad * pad)
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 ();

View file

@ -42,9 +42,11 @@ struct _GstStreamConsistency
};
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,

View file

@ -35,11 +35,11 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
/* 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");

View file

@ -764,11 +764,10 @@ static GMutex *blocked_lock;
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);

View file

@ -270,10 +270,9 @@ static GstEvent *got_event_before_q, *got_event_after_q;
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);
@ -361,8 +360,7 @@ signal_data_wait (SignalData * 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;
@ -370,9 +368,6 @@ signal_blocked (GstPad * pad, GstPadProbeType type, gpointer type_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;
}
@ -403,7 +398,7 @@ static void test_event
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);

View file

@ -479,8 +479,7 @@ typedef struct
} 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;

View file

@ -251,8 +251,7 @@ GST_START_TEST (test_name_is_valid)
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);
@ -690,12 +689,11 @@ GST_END_TEST;
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);
@ -799,8 +797,7 @@ block_async_full_destroy (gpointer user_data)
}
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;
@ -896,14 +893,14 @@ unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
#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);
@ -918,13 +915,13 @@ block_async_second_no_flush (GstPad * pad, GstPadProbeType type,
}
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");

View file

@ -33,19 +33,17 @@ static int n_buffer_probes = 0;
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));
@ -54,10 +52,9 @@ data_probe (GstPad * pad, GstPadProbeType type, gpointer type_data,
}
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));
@ -66,10 +63,9 @@ buffer_probe (GstPad * pad, GstPadProbeType type, gpointer type_data,
}
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));
@ -140,9 +136,10 @@ static int n_buffer_probes_once = 0;
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));
@ -152,9 +149,10 @@ data_probe_once (GstPad * pad, GstPadProbeType type, GstMiniObject * 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));
@ -164,9 +162,10 @@ buffer_probe_once (GstPad * pad, GstPadProbeType type, GstBuffer * 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));

View file

@ -28,9 +28,10 @@
#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));
@ -483,9 +484,10 @@ GST_END_TEST;
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));

View file

@ -24,9 +24,9 @@
#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;