event: add sticky flags to events

Add the sticky flag to events and a sticky index.
Keep sticky events in an array on each pad.
Remove GST_EVENT_SRC(), it is causing refcycles with sticky events, was not used
and is not very interesting anyway.
This commit is contained in:
Wim Taymans 2011-05-02 18:34:18 +02:00
parent 9d80fbac23
commit 2243adffa1
5 changed files with 62 additions and 54 deletions

View file

@ -184,7 +184,7 @@ gst_event_type_get_flags (GstEventType type)
{ {
GstEventTypeFlags ret; GstEventTypeFlags ret;
ret = type & ((1 << GST_EVENT_TYPE_SHIFT) - 1); ret = type & ((1 << GST_EVENT_STICKY_SHIFT) - 1);
return ret; return ret;
} }
@ -207,10 +207,6 @@ _gst_event_free (GstEvent * event)
GST_CAT_LOG (GST_CAT_EVENT, "freeing event %p type %s", event, GST_CAT_LOG (GST_CAT_EVENT, "freeing event %p type %s", event,
GST_EVENT_TYPE_NAME (event)); GST_EVENT_TYPE_NAME (event));
if (GST_EVENT_SRC (event)) {
gst_object_unref (GST_EVENT_SRC (event));
GST_EVENT_SRC (event) = NULL;
}
if (event->structure) { if (event->structure) {
gst_structure_set_parent_refcount (event->structure, NULL); gst_structure_set_parent_refcount (event->structure, NULL);
gst_structure_free (event->structure); gst_structure_free (event->structure);
@ -233,9 +229,6 @@ _gst_event_copy (GstEvent * event)
GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event); GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event);
GST_EVENT_SEQNUM (copy) = GST_EVENT_SEQNUM (event); GST_EVENT_SEQNUM (copy) = GST_EVENT_SEQNUM (event);
if (GST_EVENT_SRC (event)) {
GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event));
}
if (event->structure) { if (event->structure) {
copy->structure = gst_structure_copy (event->structure); copy->structure = gst_structure_copy (event->structure);
gst_structure_set_parent_refcount (copy->structure, gst_structure_set_parent_refcount (copy->structure,

View file

@ -40,6 +40,7 @@ G_BEGIN_DECLS
* @GST_EVENT_TYPE_DOWNSTREAM: Set if the event can travel downstream. * @GST_EVENT_TYPE_DOWNSTREAM: Set if the event can travel downstream.
* @GST_EVENT_TYPE_SERIALIZED: Set if the event should be serialized with data * @GST_EVENT_TYPE_SERIALIZED: Set if the event should be serialized with data
* flow. * flow.
* @GST_EVENT_TYPE_STICKY: Set if the event is sticky on the pads.
* *
* #GstEventTypeFlags indicate the aspects of the different #GstEventType * #GstEventTypeFlags indicate the aspects of the different #GstEventType
* values. You can get the type flags of a #GstEventType with the * values. You can get the type flags of a #GstEventType with the
@ -48,7 +49,8 @@ G_BEGIN_DECLS
typedef enum { typedef enum {
GST_EVENT_TYPE_UPSTREAM = 1 << 0, GST_EVENT_TYPE_UPSTREAM = 1 << 0,
GST_EVENT_TYPE_DOWNSTREAM = 1 << 1, GST_EVENT_TYPE_DOWNSTREAM = 1 << 1,
GST_EVENT_TYPE_SERIALIZED = 1 << 2 GST_EVENT_TYPE_SERIALIZED = 1 << 2,
GST_EVENT_TYPE_STICKY = 1 << 3
} GstEventTypeFlags; } GstEventTypeFlags;
/** /**
@ -59,21 +61,25 @@ 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_TYPE_SHIFT 4 #define GST_EVENT_STICKY_SHIFT 8
#define GST_EVENT_NUM_SHIFT 16
/** /**
* GST_EVENT_MAKE_TYPE: * GST_EVENT_MAKE_TYPE:
* @num: the event number to create * @num: the event number to create
* @idx: the index in the sticky array
* @flags: the event flags * @flags: the event flags
* *
* when making custom event types, use this macro with the num and * when making custom event types, use this macro with the num and
* the given flags * the given flags
*/ */
#define GST_EVENT_MAKE_TYPE(num,flags) \ #define GST_EVENT_MAKE_TYPE(num,idx,flags) \
(((num) << GST_EVENT_TYPE_SHIFT) | (flags)) (((num) << GST_EVENT_NUM_SHIFT) | ((idx) << GST_EVENT_STICKY_SHIFT) | (flags))
#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)
/** /**
* GstEventType: * GstEventType:
* @GST_EVENT_UNKNOWN: unknown event. * @GST_EVENT_UNKNOWN: unknown event.
@ -124,29 +130,29 @@ typedef enum {
*/ */
/* NOTE: keep in sync with quark registration in gstevent.c */ /* NOTE: keep in sync with quark registration in gstevent.c */
typedef enum { typedef enum {
GST_EVENT_UNKNOWN = GST_EVENT_MAKE_TYPE (0, 0), GST_EVENT_UNKNOWN = GST_EVENT_MAKE_TYPE (0, 0, 0),
/* bidirectional events */ /* bidirectional events */
GST_EVENT_FLUSH_START = GST_EVENT_MAKE_TYPE (1, FLAG(BOTH)), GST_EVENT_FLUSH_START = GST_EVENT_MAKE_TYPE (1, 0, FLAG(BOTH)),
GST_EVENT_FLUSH_STOP = GST_EVENT_MAKE_TYPE (2, FLAG(BOTH) | FLAG(SERIALIZED)), GST_EVENT_FLUSH_STOP = GST_EVENT_MAKE_TYPE (2, 0, FLAG(BOTH) | FLAG(SERIALIZED)),
/* downstream serialized events */ /* downstream serialized events */
GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_EOS = GST_EVENT_MAKE_TYPE (5, 0, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_NEWSEGMENT = GST_EVENT_MAKE_TYPE (6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_NEWSEGMENT = GST_EVENT_MAKE_TYPE (6, 1, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (7, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_TAG = GST_EVENT_MAKE_TYPE (7, 2, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (8, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_BUFFERSIZE = GST_EVENT_MAKE_TYPE (8, 3, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (9, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_SINK_MESSAGE = GST_EVENT_MAKE_TYPE (9, 4, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
/* upstream events */ /* upstream events */
GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (15, FLAG(UPSTREAM)), GST_EVENT_QOS = GST_EVENT_MAKE_TYPE (15, 0, FLAG(UPSTREAM)),
GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (16, FLAG(UPSTREAM)), GST_EVENT_SEEK = GST_EVENT_MAKE_TYPE (16, 0, FLAG(UPSTREAM)),
GST_EVENT_NAVIGATION = GST_EVENT_MAKE_TYPE (17, FLAG(UPSTREAM)), GST_EVENT_NAVIGATION = GST_EVENT_MAKE_TYPE (17, 0, FLAG(UPSTREAM)),
GST_EVENT_LATENCY = GST_EVENT_MAKE_TYPE (18, FLAG(UPSTREAM)), GST_EVENT_LATENCY = GST_EVENT_MAKE_TYPE (18, 0, FLAG(UPSTREAM)),
GST_EVENT_STEP = GST_EVENT_MAKE_TYPE (19, FLAG(UPSTREAM)), GST_EVENT_STEP = GST_EVENT_MAKE_TYPE (19, 0, FLAG(UPSTREAM)),
/* custom events start here */ /* custom events start here */
GST_EVENT_CUSTOM_UPSTREAM = GST_EVENT_MAKE_TYPE (32, FLAG(UPSTREAM)), GST_EVENT_CUSTOM_UPSTREAM = GST_EVENT_MAKE_TYPE (32, 0, FLAG(UPSTREAM)),
GST_EVENT_CUSTOM_DOWNSTREAM = GST_EVENT_MAKE_TYPE (32, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)), GST_EVENT_CUSTOM_DOWNSTREAM = GST_EVENT_MAKE_TYPE (32, 0, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
GST_EVENT_CUSTOM_DOWNSTREAM_OOB = GST_EVENT_MAKE_TYPE (32, FLAG(DOWNSTREAM)), GST_EVENT_CUSTOM_DOWNSTREAM_OOB = GST_EVENT_MAKE_TYPE (32, 0, FLAG(DOWNSTREAM)),
GST_EVENT_CUSTOM_BOTH = GST_EVENT_MAKE_TYPE (32, FLAG(BOTH) | FLAG(SERIALIZED)), GST_EVENT_CUSTOM_BOTH = GST_EVENT_MAKE_TYPE (32, 0, FLAG(BOTH) | FLAG(SERIALIZED)),
GST_EVENT_CUSTOM_BOTH_OOB = GST_EVENT_MAKE_TYPE (32, FLAG(BOTH)) GST_EVENT_CUSTOM_BOTH_OOB = GST_EVENT_MAKE_TYPE (32, 0, FLAG(BOTH))
} GstEventType; } GstEventType;
#undef FLAG #undef FLAG
@ -189,14 +195,6 @@ typedef struct _GstEvent GstEvent;
*/ */
#define GST_EVENT_TIMESTAMP(event) (GST_EVENT_CAST(event)->timestamp) #define GST_EVENT_TIMESTAMP(event) (GST_EVENT_CAST(event)->timestamp)
/**
* GST_EVENT_SRC:
* @event: the event to query
*
* The source #GstObject that generated this event.
*/
#define GST_EVENT_SRC(event) (GST_EVENT_CAST(event)->src)
/** /**
* GST_EVENT_SEQNUM: * GST_EVENT_SEQNUM:
* @event: the event to query * @event: the event to query
@ -226,6 +224,13 @@ typedef struct _GstEvent GstEvent;
* Check if an event is serialized with the data stream. * Check if an event is serialized with the data stream.
*/ */
#define GST_EVENT_IS_SERIALIZED(ev) !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_SERIALIZED) #define GST_EVENT_IS_SERIALIZED(ev) !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_SERIALIZED)
/**
* GST_EVENT_IS_STICKY:
* @ev: the event to query
*
* Check if an event is sticky on the pads.
*/
#define GST_EVENT_IS_STICKY(ev) !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_STICKY)
/** /**
* gst_event_replace: * gst_event_replace:
@ -345,7 +350,6 @@ typedef enum {
* @mini_object: the parent structure * @mini_object: the parent structure
* @type: the #GstEventType of the event * @type: the #GstEventType of the event
* @timestamp: the timestamp of the event * @timestamp: the timestamp of the event
* @src: the src of the event
* @structure: the #GstStructure containing the event info. * @structure: the #GstStructure containing the event info.
* *
* A #GstEvent. * A #GstEvent.
@ -356,7 +360,6 @@ struct _GstEvent {
/*< public >*/ /* with COW */ /*< public >*/ /* with COW */
GstEventType type; GstEventType type;
guint64 timestamp; guint64 timestamp;
GstObject *src;
guint32 seqnum; guint32 seqnum;
GstStructure *structure; GstStructure *structure;

View file

@ -688,11 +688,9 @@ gst_debug_print_object (gpointer ptr)
s = g_strdup ("(NULL)"); s = g_strdup ("(NULL)");
} }
ret = g_strdup_printf ("%s event from '%s' at time %" ret = g_strdup_printf ("%s event at time %"
GST_TIME_FORMAT ": %s", GST_TIME_FORMAT ": %s",
GST_EVENT_TYPE_NAME (event), (event->src != NULL) ? GST_EVENT_TYPE_NAME (event), GST_TIME_ARGS (event->timestamp), s);
GST_OBJECT_NAME (event->src) : "(NULL)",
GST_TIME_ARGS (event->timestamp), s);
g_free (s); g_free (s);
return ret; return ret;
} }

View file

@ -373,6 +373,17 @@ gst_pad_init (GstPad * pad)
pad->block_cond = g_cond_new (); pad->block_cond = g_cond_new ();
} }
static void
clear_sticky_events (GstPad * pad)
{
guint i;
for (i = 0; i < 16; i++) {
GstEvent **eventp = &pad->sticky[i];
gst_event_replace (eventp, NULL);
}
}
static void static void
gst_pad_dispose (GObject * object) gst_pad_dispose (GObject * object)
{ {
@ -404,6 +415,8 @@ gst_pad_dispose (GObject * object)
pad->block_data = NULL; pad->block_data = NULL;
} }
clear_sticky_events (pad);
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
@ -614,6 +627,7 @@ post_activate (GstPad * pad, GstActivateMode new_mode)
/* ensures that streaming stops */ /* ensures that streaming stops */
GST_PAD_STREAM_LOCK (pad); GST_PAD_STREAM_LOCK (pad);
GST_DEBUG_OBJECT (pad, "stopped streaming"); GST_DEBUG_OBJECT (pad, "stopped streaming");
clear_sticky_events (pad);
GST_PAD_STREAM_UNLOCK (pad); GST_PAD_STREAM_UNLOCK (pad);
break; break;
} }
@ -4438,11 +4452,6 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
break; break;
} }
if (G_UNLIKELY (GST_EVENT_SRC (event) == NULL)) {
GST_LOG_OBJECT (pad, "event had no source, setting pad as event source");
GST_EVENT_SRC (event) = gst_object_ref (pad);
}
if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) { if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
GST_OBJECT_UNLOCK (pad); GST_OBJECT_UNLOCK (pad);
@ -4451,6 +4460,15 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
GST_OBJECT_LOCK (pad); GST_OBJECT_LOCK (pad);
} }
/* store the event on the pad, but only on srcpads */
if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) {
GstEvent **eventp = &pad->sticky[GST_EVENT_STICKY_IDX (event)];
GST_LOG_OBJECT (pad, "storing sticky event %s",
GST_EVENT_TYPE_NAME (event));
gst_event_replace (eventp, event);
}
peerpad = GST_PAD_PEER (pad); peerpad = GST_PAD_PEER (pad);
if (peerpad == NULL) if (peerpad == NULL)
goto not_linked; goto not_linked;
@ -4544,11 +4562,6 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
} else } else
goto unknown_direction; goto unknown_direction;
if (G_UNLIKELY (GST_EVENT_SRC (event) == NULL)) {
GST_LOG_OBJECT (pad, "event had no source, setting pad as event source");
GST_EVENT_SRC (event) = gst_object_ref (pad);
}
/* pad signals */ /* pad signals */
if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) { if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
GST_OBJECT_UNLOCK (pad); GST_OBJECT_UNLOCK (pad);

View file

@ -614,6 +614,7 @@ struct _GstPad {
GstPadCheckGetRangeFunction checkgetrangefunc; GstPadCheckGetRangeFunction checkgetrangefunc;
GstPadGetRangeFunction getrangefunc; GstPadGetRangeFunction getrangefunc;
GstPadEventFunction eventfunc; GstPadEventFunction eventfunc;
GstEvent *sticky[16];
GstActivateMode mode; GstActivateMode mode;