{
guint i;
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
GstEvent **eventp = &pad->sticky[i];
gst_event_replace (eventp, NULL);
}
GST_DEBUG_OBJECT (pad, "activating pad from none");
ret = (GST_PAD_ACTIVATEFUNC (pad)) (pad);
break;
+ default:
+ GST_DEBUG_OBJECT (pad, "unknown activation mode!");
+ break;
}
} else {
switch (old) {
GST_DEBUG_OBJECT (pad, "deactivating pad from none");
ret = TRUE;
break;
+ default:
+ GST_DEBUG_OBJECT (pad, "unknown activation mode!");
+ break;
}
}
GST_PAD_PEER (srcpad) = NULL;
GST_PAD_PEER (sinkpad) = NULL;
+ /* clear the events on the sinkpad */
+ clear_sticky_events (sinkpad);
+
GST_OBJECT_UNLOCK (sinkpad);
GST_OBJECT_UNLOCK (srcpad);
{
GstPadLinkReturn result;
GstElement *parent;
+ guint i;
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);
GST_PAD_PEER (srcpad) = sinkpad;
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 (srcpad);
GST_PAD_STREAM_LOCK (pad);
+again:
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
caps_changed = caps && caps != GST_PAD_CAPS (pad);
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);
/* see if the signal should be emited, we emit before caps nego as
/* 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));
+ guint idx = GST_EVENT_STICKY_IDX (event);
+ GstEvent **eventp = &pad->sticky[idx];
+ GST_LOG_OBJECT (pad, "storing sticky event %s at index %u",
+ GST_EVENT_TYPE_NAME (event), idx);
gst_event_replace (eventp, event);
}
* @GST_PAD_IN_GETCAPS: GstPadGetCapsFunction() 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_STICKY_PENDING: sticky events should be pushed
* @GST_PAD_FLAG_LAST: offset to define more flags
*
* Pad state flags
*/
typedef enum {
- GST_PAD_BLOCKED = (GST_OBJECT_FLAG_LAST << 0),
- GST_PAD_FLUSHING = (GST_OBJECT_FLAG_LAST << 1),
- GST_PAD_IN_GETCAPS = (GST_OBJECT_FLAG_LAST << 2),
- GST_PAD_IN_SETCAPS = (GST_OBJECT_FLAG_LAST << 3),
- GST_PAD_BLOCKING = (GST_OBJECT_FLAG_LAST << 4),
+ GST_PAD_BLOCKED = (GST_OBJECT_FLAG_LAST << 0),
+ GST_PAD_FLUSHING = (GST_OBJECT_FLAG_LAST << 1),
+ GST_PAD_IN_GETCAPS = (GST_OBJECT_FLAG_LAST << 2),
+ GST_PAD_IN_SETCAPS = (GST_OBJECT_FLAG_LAST << 3),
+ GST_PAD_BLOCKING = (GST_OBJECT_FLAG_LAST << 4),
+ GST_PAD_STICKY_PENDING = (GST_OBJECT_FLAG_LAST << 5),
/* padding */
- GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 8)
+ GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 16)
} GstPadFlags;
/* FIXME: this awful circular dependency need to be resolved properly (see padtemplate.h) */
GstPadCheckGetRangeFunction checkgetrangefunc;
GstPadGetRangeFunction getrangefunc;
GstPadEventFunction eventfunc;
- GstEvent *sticky[16];
+ GstEvent *sticky[GST_EVENT_MAX_STICKY];
GstActivateMode mode;
#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_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_SINK(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)