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

View file

@ -688,11 +688,9 @@ gst_debug_print_object (gpointer ptr)
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_EVENT_TYPE_NAME (event), (event->src != NULL) ?
GST_OBJECT_NAME (event->src) : "(NULL)",
GST_TIME_ARGS (event->timestamp), s);
GST_EVENT_TYPE_NAME (event), GST_TIME_ARGS (event->timestamp), s);
g_free (s);
return ret;
}

View file

@ -373,6 +373,17 @@ gst_pad_init (GstPad * pad)
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
gst_pad_dispose (GObject * object)
{
@ -404,6 +415,8 @@ gst_pad_dispose (GObject * object)
pad->block_data = NULL;
}
clear_sticky_events (pad);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@ -614,6 +627,7 @@ post_activate (GstPad * pad, GstActivateMode new_mode)
/* ensures that streaming stops */
GST_PAD_STREAM_LOCK (pad);
GST_DEBUG_OBJECT (pad, "stopped streaming");
clear_sticky_events (pad);
GST_PAD_STREAM_UNLOCK (pad);
break;
}
@ -4438,11 +4452,6 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
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)) {
GST_OBJECT_UNLOCK (pad);
@ -4451,6 +4460,15 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
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);
if (peerpad == NULL)
goto not_linked;
@ -4544,11 +4562,6 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
} else
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 */
if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
GST_OBJECT_UNLOCK (pad);

View file

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