mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
collectpads2: modify event handling using a default event handler
... that elements should "chain up" to.
This commit is contained in:
parent
d342871907
commit
994357a16a
2 changed files with 96 additions and 69 deletions
|
@ -155,6 +155,10 @@ static gboolean gst_collect_pads2_recalculate_full (GstCollectPads2 * pads);
|
|||
static void ref_data (GstCollectData2 * data);
|
||||
static void unref_data (GstCollectData2 * data);
|
||||
|
||||
static gboolean gst_collect_pads2_event_default_internal (GstCollectPads2 *
|
||||
pads, GstCollectData2 * data, GstEvent * event, gpointer user_data);
|
||||
|
||||
|
||||
/* Some properties are protected by LOCK, others by STREAM_LOCK
|
||||
* However, manipulating either of these partitions may require
|
||||
* to signal/wake a _WAIT, so use a separate (sort of) event to prevent races
|
||||
|
@ -241,6 +245,8 @@ gst_collect_pads2_init (GstCollectPads2 * pads)
|
|||
pads->priv->earliest_data = NULL;
|
||||
pads->priv->earliest_time = GST_CLOCK_TIME_NONE;
|
||||
|
||||
pads->priv->event_func = gst_collect_pads2_event_default_internal;
|
||||
|
||||
/* members to manage the pad list */
|
||||
pads->priv->pad_cookie = 0;
|
||||
pads->priv->pad_list = NULL;
|
||||
|
@ -424,8 +430,8 @@ unref_data (GstCollectData2 * data)
|
|||
* @func: the function to set
|
||||
* @user_data: user data passed to the function
|
||||
*
|
||||
* Set the event callback function and user data that will be called after
|
||||
* collectpads has processed and event originating from one of the collected
|
||||
* Set the event callback function and user data that will be called when
|
||||
* collectpads has received an event originating from one of the collected
|
||||
* pads. If the event being processed is a serialized one, this callback is
|
||||
* called with @pads STREAM_LOCK held, otherwise not. As this lock should be
|
||||
* held when calling a number of CollectPads functions, it should be acquired
|
||||
|
@ -1640,47 +1646,41 @@ gst_collect_pads2_default_compare_func (GstCollectPads2 * pads,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_collect_pads2_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||
/**
|
||||
* gst_collect_pads2_event_default:
|
||||
* @pads: the collectspads to use
|
||||
* @data: collect data of corresponding pad
|
||||
* @event: event being processed
|
||||
* @discard: process but do not send event downstream
|
||||
*
|
||||
* Default GstCollectPads2 event handling that elements should always
|
||||
* chain up to to ensure proper operation. Element might however indicate
|
||||
* event should not be forwarded downstream.
|
||||
*
|
||||
* Since: 0.11.x
|
||||
*/
|
||||
gboolean
|
||||
gst_collect_pads2_event_default (GstCollectPads2 * pads, GstCollectData2 * data,
|
||||
GstEvent * event, gboolean discard)
|
||||
{
|
||||
gboolean res = FALSE, need_unlock = FALSE;
|
||||
GstCollectData2 *data;
|
||||
GstCollectPads2 *pads;
|
||||
GstCollectPads2EventFunction event_func;
|
||||
gboolean res = TRUE;
|
||||
GstCollectPads2BufferFunction buffer_func;
|
||||
gpointer event_user_data;
|
||||
|
||||
/* some magic to get the managing collect_pads2 */
|
||||
GST_OBJECT_LOCK (pad);
|
||||
data = (GstCollectData2 *) gst_pad_get_element_private (pad);
|
||||
if (G_UNLIKELY (data == NULL))
|
||||
goto pad_removed;
|
||||
ref_data (data);
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
res = FALSE;
|
||||
|
||||
pads = data->collect;
|
||||
|
||||
GST_DEBUG_OBJECT (data->pad, "Got %s event on sink pad",
|
||||
GST_EVENT_TYPE_NAME (event));
|
||||
GstObject *parent;
|
||||
GstPad *pad;
|
||||
|
||||
GST_OBJECT_LOCK (pads);
|
||||
event_func = pads->priv->event_func;
|
||||
event_user_data = pads->priv->event_user_data;
|
||||
buffer_func = pads->priv->buffer_func;
|
||||
GST_OBJECT_UNLOCK (pads);
|
||||
|
||||
pad = data->pad;
|
||||
parent = GST_OBJECT_PARENT (pad);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_FLUSH_START:
|
||||
{
|
||||
/* forward event to unblock check_collected */
|
||||
if (event_func) {
|
||||
res = event_func (pads, data, event, event_user_data);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (pad, "forwarding flush start");
|
||||
res = gst_pad_event_default (pad, parent, event);
|
||||
}
|
||||
|
||||
/* now unblock the chain function.
|
||||
* no cond per pad, so they all unblock,
|
||||
|
@ -1703,9 +1703,7 @@ gst_collect_pads2_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
|
||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||
|
||||
/* event already cleaned up by forwarding */
|
||||
res = TRUE;
|
||||
goto done;
|
||||
goto eat;
|
||||
}
|
||||
case GST_EVENT_FLUSH_STOP:
|
||||
{
|
||||
|
@ -1728,8 +1726,7 @@ gst_collect_pads2_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
}
|
||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||
|
||||
/* forward event */
|
||||
goto forward_or_default;
|
||||
goto forward;
|
||||
}
|
||||
case GST_EVENT_EOS:
|
||||
{
|
||||
|
@ -1748,7 +1745,7 @@ gst_collect_pads2_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
gst_collect_pads2_check_collected (pads);
|
||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||
|
||||
goto forward_or_eat;
|
||||
goto eat;
|
||||
}
|
||||
case GST_EVENT_SEGMENT:
|
||||
{
|
||||
|
@ -1796,48 +1793,76 @@ gst_collect_pads2_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||
/* we must not forward this event since multiple segments will be
|
||||
* accumulated and this is certainly not what we want. */
|
||||
goto forward_or_eat;
|
||||
goto eat;
|
||||
}
|
||||
case GST_EVENT_CAPS:
|
||||
case GST_EVENT_STREAM_START:
|
||||
case GST_EVENT_STREAM_CONFIG:
|
||||
goto forward_or_eat;
|
||||
goto eat;
|
||||
default:
|
||||
/* forward other events */
|
||||
goto forward_or_default;
|
||||
goto forward;
|
||||
}
|
||||
|
||||
forward_or_default:
|
||||
if (GST_EVENT_IS_SERIALIZED (event)) {
|
||||
GST_COLLECT_PADS2_STREAM_LOCK (pads);
|
||||
need_unlock = TRUE;
|
||||
}
|
||||
if (event_func) {
|
||||
res = event_func (pads, data, event, event_user_data);
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (pad, "forwarding %s", GST_EVENT_TYPE_NAME (event));
|
||||
res = gst_pad_event_default (pad, parent, event);
|
||||
}
|
||||
if (need_unlock)
|
||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||
goto done;
|
||||
|
||||
forward_or_eat:
|
||||
if (GST_EVENT_IS_SERIALIZED (event)) {
|
||||
GST_COLLECT_PADS2_STREAM_LOCK (pads);
|
||||
need_unlock = TRUE;
|
||||
}
|
||||
if (event_func) {
|
||||
res = event_func (pads, data, event, event_user_data);
|
||||
} else {
|
||||
eat:
|
||||
gst_event_unref (event);
|
||||
res = TRUE;
|
||||
return res;
|
||||
|
||||
forward:
|
||||
if (discard)
|
||||
goto eat;
|
||||
else
|
||||
return gst_pad_event_default (pad, parent, event);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_collect_pads2_event_default_internal (GstCollectPads2 * pads,
|
||||
GstCollectData2 * data, GstEvent * event, gpointer user_data)
|
||||
{
|
||||
return gst_collect_pads2_event_default (pads, data, event, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_collect_pads2_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||
{
|
||||
gboolean res = FALSE, need_unlock = FALSE;
|
||||
GstCollectData2 *data;
|
||||
GstCollectPads2 *pads;
|
||||
GstCollectPads2EventFunction event_func;
|
||||
gpointer event_user_data;
|
||||
|
||||
/* some magic to get the managing collect_pads2 */
|
||||
GST_OBJECT_LOCK (pad);
|
||||
data = (GstCollectData2 *) gst_pad_get_element_private (pad);
|
||||
if (G_UNLIKELY (data == NULL))
|
||||
goto pad_removed;
|
||||
ref_data (data);
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
res = FALSE;
|
||||
|
||||
pads = data->collect;
|
||||
|
||||
GST_DEBUG_OBJECT (data->pad, "Got %s event on sink pad",
|
||||
GST_EVENT_TYPE_NAME (event));
|
||||
|
||||
GST_OBJECT_LOCK (pads);
|
||||
event_func = pads->priv->event_func;
|
||||
event_user_data = pads->priv->event_user_data;
|
||||
GST_OBJECT_UNLOCK (pads);
|
||||
|
||||
if (GST_EVENT_IS_SERIALIZED (event)) {
|
||||
GST_COLLECT_PADS2_STREAM_LOCK (pads);
|
||||
need_unlock = TRUE;
|
||||
}
|
||||
|
||||
if (G_LIKELY (event_func)) {
|
||||
res = event_func (pads, data, event, event_user_data);
|
||||
}
|
||||
|
||||
if (need_unlock)
|
||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||
goto done;
|
||||
|
||||
done:
|
||||
unref_data (data);
|
||||
return res;
|
||||
|
||||
|
|
|
@ -207,11 +207,9 @@ typedef gint (*GstCollectPads2CompareFunction) (GstCollectPads2 *pads,
|
|||
* @user_data: user data passed to gst_collect_pads2_set_event_function()
|
||||
*
|
||||
* A function that will be called while processing an event. It takes
|
||||
* ownership of the event and is responsible for forwarding
|
||||
* events downstream (with gst_pad_event_default()) or dropping events.
|
||||
*
|
||||
* The STREAM_START, CAPS, STREAM_CONFIG, SEGMENT and EOS events should
|
||||
* usually be dropped by this function.
|
||||
* ownership of the event and is responsible for chaining up (to
|
||||
* gst_collect_pads2_event_default()) or dropping events (such typical cases
|
||||
* being handled by the default handler).
|
||||
*
|
||||
* Returns: %TRUE if the pad could handle the event
|
||||
*
|
||||
|
@ -365,6 +363,10 @@ GstFlowReturn gst_collect_pads2_clip_running_time (GstCollectPads2 * pads,
|
|||
GstCollectData2 * cdata, GstBuffer * buf, GstBuffer ** outbuf,
|
||||
gpointer user_data);
|
||||
|
||||
/* default handler */
|
||||
gboolean gst_collect_pads2_event_default (GstCollectPads2 * pads2, GstCollectData2 * data,
|
||||
GstEvent * event, gboolean discard);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
Loading…
Reference in a new issue