mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 00:06:36 +00:00
pad: more sticky events work
Copy the sticky events from the srcpad to the sinkpad when linking pads. Set the STICKY_PENDING flag to make sure that the sticky events are dispatched before pushing the next buffer to the element.
This commit is contained in:
parent
9c48af743c
commit
bc9cffda90
3 changed files with 71 additions and 13 deletions
|
@ -61,8 +61,9 @@ typedef enum {
|
||||||
#define GST_EVENT_TYPE_BOTH \
|
#define GST_EVENT_TYPE_BOTH \
|
||||||
(GST_EVENT_TYPE_UPSTREAM | GST_EVENT_TYPE_DOWNSTREAM)
|
(GST_EVENT_TYPE_UPSTREAM | GST_EVENT_TYPE_DOWNSTREAM)
|
||||||
|
|
||||||
|
#define GST_EVENT_MAX_STICKY 16
|
||||||
#define GST_EVENT_STICKY_SHIFT 8
|
#define GST_EVENT_STICKY_SHIFT 8
|
||||||
#define GST_EVENT_NUM_SHIFT 16
|
#define GST_EVENT_NUM_SHIFT (GST_EVENT_STICKY_SHIFT + 4)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GST_EVENT_MAKE_TYPE:
|
* GST_EVENT_MAKE_TYPE:
|
||||||
|
@ -78,7 +79,8 @@ typedef enum {
|
||||||
|
|
||||||
#define FLAG(name) GST_EVENT_TYPE_##name
|
#define FLAG(name) GST_EVENT_TYPE_##name
|
||||||
|
|
||||||
#define GST_EVENT_STICKY_IDX(ev) ((GST_EVENT_TYPE(ev) >> GST_EVENT_STICKY_SHIFT) & 0xff)
|
|
||||||
|
#define GST_EVENT_STICKY_IDX(ev) ((GST_EVENT_TYPE(ev) >> GST_EVENT_STICKY_SHIFT) & 0xf)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstEventType:
|
* GstEventType:
|
||||||
|
|
61
gst/gstpad.c
61
gst/gstpad.c
|
@ -378,7 +378,7 @@ clear_sticky_events (GstPad * pad)
|
||||||
{
|
{
|
||||||
guint i;
|
guint i;
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
|
||||||
GstEvent **eventp = &pad->sticky[i];
|
GstEvent **eventp = &pad->sticky[i];
|
||||||
gst_event_replace (eventp, NULL);
|
gst_event_replace (eventp, NULL);
|
||||||
}
|
}
|
||||||
|
@ -679,6 +679,9 @@ gst_pad_set_active (GstPad * pad, gboolean active)
|
||||||
GST_DEBUG_OBJECT (pad, "activating pad from none");
|
GST_DEBUG_OBJECT (pad, "activating pad from none");
|
||||||
ret = (GST_PAD_ACTIVATEFUNC (pad)) (pad);
|
ret = (GST_PAD_ACTIVATEFUNC (pad)) (pad);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
GST_DEBUG_OBJECT (pad, "unknown activation mode!");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (old) {
|
switch (old) {
|
||||||
|
@ -694,6 +697,9 @@ gst_pad_set_active (GstPad * pad, gboolean active)
|
||||||
GST_DEBUG_OBJECT (pad, "deactivating pad from none");
|
GST_DEBUG_OBJECT (pad, "deactivating pad from none");
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
GST_DEBUG_OBJECT (pad, "unknown activation mode!");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1687,6 +1693,9 @@ gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
|
||||||
GST_PAD_PEER (srcpad) = NULL;
|
GST_PAD_PEER (srcpad) = NULL;
|
||||||
GST_PAD_PEER (sinkpad) = NULL;
|
GST_PAD_PEER (sinkpad) = NULL;
|
||||||
|
|
||||||
|
/* clear the events on the sinkpad */
|
||||||
|
clear_sticky_events (sinkpad);
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (sinkpad);
|
GST_OBJECT_UNLOCK (sinkpad);
|
||||||
GST_OBJECT_UNLOCK (srcpad);
|
GST_OBJECT_UNLOCK (srcpad);
|
||||||
|
|
||||||
|
@ -2004,6 +2013,7 @@ gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
|
||||||
{
|
{
|
||||||
GstPadLinkReturn result;
|
GstPadLinkReturn result;
|
||||||
GstElement *parent;
|
GstElement *parent;
|
||||||
|
guint i;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
|
g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
|
||||||
g_return_val_if_fail (GST_PAD_IS_SRC (srcpad), GST_PAD_LINK_WRONG_DIRECTION);
|
g_return_val_if_fail (GST_PAD_IS_SRC (srcpad), GST_PAD_LINK_WRONG_DIRECTION);
|
||||||
|
@ -2033,6 +2043,15 @@ gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
|
||||||
GST_PAD_PEER (srcpad) = sinkpad;
|
GST_PAD_PEER (srcpad) = sinkpad;
|
||||||
GST_PAD_PEER (sinkpad) = srcpad;
|
GST_PAD_PEER (sinkpad) = srcpad;
|
||||||
|
|
||||||
|
/* copy the events */
|
||||||
|
for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
|
||||||
|
GstEvent **eventp = &sinkpad->sticky[i], *event;
|
||||||
|
|
||||||
|
if ((event = srcpad->sticky[i]))
|
||||||
|
GST_OBJECT_FLAG_SET (sinkpad, GST_PAD_STICKY_PENDING);
|
||||||
|
gst_event_replace (eventp, event);
|
||||||
|
}
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (sinkpad);
|
GST_OBJECT_UNLOCK (sinkpad);
|
||||||
GST_OBJECT_UNLOCK (srcpad);
|
GST_OBJECT_UNLOCK (srcpad);
|
||||||
|
|
||||||
|
@ -3440,6 +3459,7 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
|
||||||
|
|
||||||
GST_PAD_STREAM_LOCK (pad);
|
GST_PAD_STREAM_LOCK (pad);
|
||||||
|
|
||||||
|
again:
|
||||||
GST_OBJECT_LOCK (pad);
|
GST_OBJECT_LOCK (pad);
|
||||||
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
|
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
@ -3448,6 +3468,38 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
|
||||||
caps_changed = caps && caps != GST_PAD_CAPS (pad);
|
caps_changed = caps && caps != GST_PAD_CAPS (pad);
|
||||||
|
|
||||||
emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
|
emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (GST_PAD_IS_STICKY_PENDING (pad))) {
|
||||||
|
GstPadEventFunction eventfunc;
|
||||||
|
|
||||||
|
if (G_LIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)))) {
|
||||||
|
GstEvent *events[GST_EVENT_MAX_STICKY];
|
||||||
|
GstEvent *event;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
/* need to make a copy because when we release the object lock, things
|
||||||
|
* could just change */
|
||||||
|
for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
|
||||||
|
if ((event = pad->sticky[i]))
|
||||||
|
events[i] = gst_event_ref (event);
|
||||||
|
else
|
||||||
|
events[i] = NULL;
|
||||||
|
}
|
||||||
|
/* clear the flag */
|
||||||
|
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_STICKY_PENDING);
|
||||||
|
GST_OBJECT_UNLOCK (pad);
|
||||||
|
|
||||||
|
/* and push */
|
||||||
|
GST_DEBUG_OBJECT (pad, "pushing sticky events");
|
||||||
|
for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
|
||||||
|
if ((event = events[i]))
|
||||||
|
eventfunc (pad, event);
|
||||||
|
}
|
||||||
|
/* and restart, we released the lock things might have changed */
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (pad);
|
GST_OBJECT_UNLOCK (pad);
|
||||||
|
|
||||||
/* see if the signal should be emited, we emit before caps nego as
|
/* see if the signal should be emited, we emit before caps nego as
|
||||||
|
@ -4463,9 +4515,10 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
|
||||||
|
|
||||||
/* store the event on the pad, but only on srcpads */
|
/* store the event on the pad, but only on srcpads */
|
||||||
if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) {
|
if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) {
|
||||||
GstEvent **eventp = &pad->sticky[GST_EVENT_STICKY_IDX (event)];
|
guint idx = GST_EVENT_STICKY_IDX (event);
|
||||||
GST_LOG_OBJECT (pad, "storing sticky event %s",
|
GstEvent **eventp = &pad->sticky[idx];
|
||||||
GST_EVENT_TYPE_NAME (event));
|
GST_LOG_OBJECT (pad, "storing sticky event %s at index %u",
|
||||||
|
GST_EVENT_TYPE_NAME (event), idx);
|
||||||
gst_event_replace (eventp, event);
|
gst_event_replace (eventp, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -509,6 +509,7 @@ typedef enum {
|
||||||
* @GST_PAD_IN_GETCAPS: GstPadGetCapsFunction() is running now
|
* @GST_PAD_IN_GETCAPS: GstPadGetCapsFunction() is running now
|
||||||
* @GST_PAD_IN_SETCAPS: GstPadSetCapsFunction() is running now
|
* @GST_PAD_IN_SETCAPS: GstPadSetCapsFunction() is running now
|
||||||
* @GST_PAD_BLOCKING: is pad currently blocking on a buffer or event
|
* @GST_PAD_BLOCKING: is pad currently blocking on a buffer or event
|
||||||
|
* @GST_PAD_STICKY_PENDING: sticky events should be pushed
|
||||||
* @GST_PAD_FLAG_LAST: offset to define more flags
|
* @GST_PAD_FLAG_LAST: offset to define more flags
|
||||||
*
|
*
|
||||||
* Pad state flags
|
* Pad state flags
|
||||||
|
@ -519,8 +520,9 @@ typedef enum {
|
||||||
GST_PAD_IN_GETCAPS = (GST_OBJECT_FLAG_LAST << 2),
|
GST_PAD_IN_GETCAPS = (GST_OBJECT_FLAG_LAST << 2),
|
||||||
GST_PAD_IN_SETCAPS = (GST_OBJECT_FLAG_LAST << 3),
|
GST_PAD_IN_SETCAPS = (GST_OBJECT_FLAG_LAST << 3),
|
||||||
GST_PAD_BLOCKING = (GST_OBJECT_FLAG_LAST << 4),
|
GST_PAD_BLOCKING = (GST_OBJECT_FLAG_LAST << 4),
|
||||||
|
GST_PAD_STICKY_PENDING = (GST_OBJECT_FLAG_LAST << 5),
|
||||||
/* padding */
|
/* padding */
|
||||||
GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 8)
|
GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 16)
|
||||||
} GstPadFlags;
|
} GstPadFlags;
|
||||||
|
|
||||||
/* FIXME: this awful circular dependency need to be resolved properly (see padtemplate.h) */
|
/* FIXME: this awful circular dependency need to be resolved properly (see padtemplate.h) */
|
||||||
|
@ -614,7 +616,7 @@ struct _GstPad {
|
||||||
GstPadCheckGetRangeFunction checkgetrangefunc;
|
GstPadCheckGetRangeFunction checkgetrangefunc;
|
||||||
GstPadGetRangeFunction getrangefunc;
|
GstPadGetRangeFunction getrangefunc;
|
||||||
GstPadEventFunction eventfunc;
|
GstPadEventFunction eventfunc;
|
||||||
GstEvent *sticky[16];
|
GstEvent *sticky[GST_EVENT_MAX_STICKY];
|
||||||
|
|
||||||
GstActivateMode mode;
|
GstActivateMode mode;
|
||||||
|
|
||||||
|
@ -697,6 +699,7 @@ struct _GstPadClass {
|
||||||
#define GST_PAD_IS_FLUSHING(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLUSHING))
|
#define GST_PAD_IS_FLUSHING(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLUSHING))
|
||||||
#define GST_PAD_IS_IN_GETCAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS))
|
#define GST_PAD_IS_IN_GETCAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS))
|
||||||
#define GST_PAD_IS_IN_SETCAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_SETCAPS))
|
#define GST_PAD_IS_IN_SETCAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_SETCAPS))
|
||||||
|
#define GST_PAD_IS_STICKY_PENDING(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_STICKY_PENDING))
|
||||||
#define GST_PAD_IS_SRC(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SRC)
|
#define GST_PAD_IS_SRC(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SRC)
|
||||||
#define GST_PAD_IS_SINK(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)
|
#define GST_PAD_IS_SINK(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue