mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +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 ref_data (GstCollectData2 * data);
|
||||||
static void unref_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
|
/* Some properties are protected by LOCK, others by STREAM_LOCK
|
||||||
* However, manipulating either of these partitions may require
|
* However, manipulating either of these partitions may require
|
||||||
* to signal/wake a _WAIT, so use a separate (sort of) event to prevent races
|
* 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_data = NULL;
|
||||||
pads->priv->earliest_time = GST_CLOCK_TIME_NONE;
|
pads->priv->earliest_time = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
|
pads->priv->event_func = gst_collect_pads2_event_default_internal;
|
||||||
|
|
||||||
/* members to manage the pad list */
|
/* members to manage the pad list */
|
||||||
pads->priv->pad_cookie = 0;
|
pads->priv->pad_cookie = 0;
|
||||||
pads->priv->pad_list = NULL;
|
pads->priv->pad_list = NULL;
|
||||||
|
@ -424,8 +430,8 @@ unref_data (GstCollectData2 * data)
|
||||||
* @func: the function to set
|
* @func: the function to set
|
||||||
* @user_data: user data passed to the function
|
* @user_data: user data passed to the function
|
||||||
*
|
*
|
||||||
* Set the event callback function and user data that will be called after
|
* Set the event callback function and user data that will be called when
|
||||||
* collectpads has processed and event originating from one of the collected
|
* collectpads has received an event originating from one of the collected
|
||||||
* pads. If the event being processed is a serialized one, this callback is
|
* 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
|
* 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
|
* held when calling a number of CollectPads functions, it should be acquired
|
||||||
|
@ -1640,50 +1646,44 @@ gst_collect_pads2_default_compare_func (GstCollectPads2 * pads,
|
||||||
return 0;
|
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;
|
gboolean res = TRUE;
|
||||||
GstCollectData2 *data;
|
|
||||||
GstCollectPads2 *pads;
|
|
||||||
GstCollectPads2EventFunction event_func;
|
|
||||||
GstCollectPads2BufferFunction buffer_func;
|
GstCollectPads2BufferFunction buffer_func;
|
||||||
gpointer event_user_data;
|
GstObject *parent;
|
||||||
|
GstPad *pad;
|
||||||
/* 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);
|
GST_OBJECT_LOCK (pads);
|
||||||
event_func = pads->priv->event_func;
|
|
||||||
event_user_data = pads->priv->event_user_data;
|
|
||||||
buffer_func = pads->priv->buffer_func;
|
buffer_func = pads->priv->buffer_func;
|
||||||
GST_OBJECT_UNLOCK (pads);
|
GST_OBJECT_UNLOCK (pads);
|
||||||
|
|
||||||
|
pad = data->pad;
|
||||||
|
parent = GST_OBJECT_PARENT (pad);
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_FLUSH_START:
|
case GST_EVENT_FLUSH_START:
|
||||||
{
|
{
|
||||||
/* forward event to unblock check_collected */
|
/* forward event to unblock check_collected */
|
||||||
if (event_func) {
|
GST_DEBUG_OBJECT (pad, "forwarding flush start");
|
||||||
res = event_func (pads, data, event, event_user_data);
|
res = gst_pad_event_default (pad, parent, event);
|
||||||
} else {
|
|
||||||
GST_DEBUG_OBJECT (pad, "forwarding flush start");
|
|
||||||
res = gst_pad_event_default (pad, parent, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now unblock the chain function.
|
/* now unblock the chain function.
|
||||||
* no cond per pad, so they all unblock,
|
* no cond per pad, so they all unblock,
|
||||||
* non-flushing block again */
|
* non-flushing block again */
|
||||||
GST_COLLECT_PADS2_STREAM_LOCK (pads);
|
GST_COLLECT_PADS2_STREAM_LOCK (pads);
|
||||||
GST_COLLECT_PADS2_STATE_SET (data, GST_COLLECT_PADS2_STATE_FLUSHING);
|
GST_COLLECT_PADS2_STATE_SET (data, GST_COLLECT_PADS2_STATE_FLUSHING);
|
||||||
|
@ -1703,9 +1703,7 @@ gst_collect_pads2_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
|
|
||||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||||
|
|
||||||
/* event already cleaned up by forwarding */
|
goto eat;
|
||||||
res = TRUE;
|
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
case GST_EVENT_FLUSH_STOP:
|
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);
|
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||||
|
|
||||||
/* forward event */
|
goto forward;
|
||||||
goto forward_or_default;
|
|
||||||
}
|
}
|
||||||
case GST_EVENT_EOS:
|
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_check_collected (pads);
|
||||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||||
|
|
||||||
goto forward_or_eat;
|
goto eat;
|
||||||
}
|
}
|
||||||
case GST_EVENT_SEGMENT:
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
|
@ -1796,48 +1793,76 @@ gst_collect_pads2_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
||||||
/* we must not forward this event since multiple segments will be
|
/* we must not forward this event since multiple segments will be
|
||||||
* accumulated and this is certainly not what we want. */
|
* accumulated and this is certainly not what we want. */
|
||||||
goto forward_or_eat;
|
goto eat;
|
||||||
}
|
}
|
||||||
case GST_EVENT_CAPS:
|
case GST_EVENT_CAPS:
|
||||||
case GST_EVENT_STREAM_START:
|
case GST_EVENT_STREAM_START:
|
||||||
case GST_EVENT_STREAM_CONFIG:
|
case GST_EVENT_STREAM_CONFIG:
|
||||||
goto forward_or_eat;
|
goto eat;
|
||||||
default:
|
default:
|
||||||
/* forward other events */
|
/* forward other events */
|
||||||
goto forward_or_default;
|
goto forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_or_default:
|
eat:
|
||||||
|
gst_event_unref (event);
|
||||||
|
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)) {
|
if (GST_EVENT_IS_SERIALIZED (event)) {
|
||||||
GST_COLLECT_PADS2_STREAM_LOCK (pads);
|
GST_COLLECT_PADS2_STREAM_LOCK (pads);
|
||||||
need_unlock = TRUE;
|
need_unlock = TRUE;
|
||||||
}
|
}
|
||||||
if (event_func) {
|
|
||||||
|
if (G_LIKELY (event_func)) {
|
||||||
res = event_func (pads, data, event, event_user_data);
|
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)
|
if (need_unlock)
|
||||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
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 {
|
|
||||||
gst_event_unref (event);
|
|
||||||
res = TRUE;
|
|
||||||
}
|
|
||||||
if (need_unlock)
|
|
||||||
GST_COLLECT_PADS2_STREAM_UNLOCK (pads);
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
done:
|
|
||||||
unref_data (data);
|
unref_data (data);
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
|
@ -207,11 +207,9 @@ typedef gint (*GstCollectPads2CompareFunction) (GstCollectPads2 *pads,
|
||||||
* @user_data: user data passed to gst_collect_pads2_set_event_function()
|
* @user_data: user data passed to gst_collect_pads2_set_event_function()
|
||||||
*
|
*
|
||||||
* A function that will be called while processing an event. It takes
|
* A function that will be called while processing an event. It takes
|
||||||
* ownership of the event and is responsible for forwarding
|
* ownership of the event and is responsible for chaining up (to
|
||||||
* events downstream (with gst_pad_event_default()) or dropping events.
|
* gst_collect_pads2_event_default()) or dropping events (such typical cases
|
||||||
*
|
* being handled by the default handler).
|
||||||
* The STREAM_START, CAPS, STREAM_CONFIG, SEGMENT and EOS events should
|
|
||||||
* usually be dropped by this function.
|
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the pad could handle the event
|
* 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,
|
GstCollectData2 * cdata, GstBuffer * buf, GstBuffer ** outbuf,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
|
/* default handler */
|
||||||
|
gboolean gst_collect_pads2_event_default (GstCollectPads2 * pads2, GstCollectData2 * data,
|
||||||
|
GstEvent * event, gboolean discard);
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue