}
/**
+ * gst_pad_set_activate_function:
+ * @p: a #GstPad.
+ * @f: the #GstPadActivateFunction to set.
+ *
+ * Calls gst_pad_set_activate_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
* gst_pad_set_activate_function_full:
* @pad: a #GstPad.
* @activate: the #GstPadActivateFunction to set.
}
/**
+ * gst_pad_set_activatemode_function:
+ * @p: a #GstPad.
+ * @f: the #GstPadActivateModeFunction to set.
+ *
+ * Calls gst_pad_set_activatemode_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
* gst_pad_set_activatemode_function_full:
* @pad: a #GstPad.
* @activatemode: the #GstPadActivateModeFunction to set.
}
/**
+ * gst_pad_set_chain_function:
+ * @p: a sink #GstPad.
+ * @f: the #GstPadChainFunction to set.
+ *
+ * Calls gst_pad_set_chain_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
* gst_pad_set_chain_function_full:
* @pad: a sink #GstPad.
* @chain: the #GstPadChainFunction to set.
}
/**
+ * gst_pad_set_chain_list_function:
+ * @p: a sink #GstPad.
+ * @f: the #GstPadChainListFunction to set.
+ *
+ * Calls gst_pad_set_chain_list_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
* gst_pad_set_chain_list_function_full:
* @pad: a sink #GstPad.
* @chainlist: the #GstPadChainListFunction to set.
}
/**
+ * gst_pad_set_getrange_function:
+ * @p: a source #GstPad.
+ * @f: the #GstPadGetRangeFunction to set.
+ *
+ * Calls gst_pad_set_getrange_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
* gst_pad_set_getrange_function_full:
* @pad: a source #GstPad.
* @get: the #GstPadGetRangeFunction to set.
}
/**
+ * gst_pad_set_event_function:
+ * @p: a #GstPad of either direction.
+ * @f: the #GstPadEventFunction to set.
+ *
+ * Calls gst_pad_set_event_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
* gst_pad_set_event_function_full:
* @pad: a #GstPad of either direction.
* @event: the #GstPadEventFunction to set.
}
/**
+ * gst_pad_set_query_function:
+ * @p: a #GstPad of either direction.
+ * @f: the #GstPadQueryFunction to set.
+ *
+ * Calls gst_pad_set_query_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
* gst_pad_set_query_function_full:
* @pad: a #GstPad of either direction.
* @query: the #GstPadQueryFunction to set.
}
/**
+ * gst_pad_set_iterate_internal_links_function:
+ * @p: a #GstPad of either direction.
+ * @f: the #GstPadIterIntLinkFunction to set.
+ *
+ * Calls gst_pad_set_iterate_internal_links_function_full() with NULL
+ * for the user_data and notify.
+ */
+/**
* gst_pad_set_iterate_internal_links_function_full:
* @pad: a #GstPad of either direction.
* @iterintlink: the #GstPadIterIntLinkFunction to set.
}
/**
+ * gst_pad_set_link_function:
+ * @p: a #GstPad.
+ * @f: the #GstPadLinkFunction to set.
+ *
+ * Calls gst_pad_set_link_function_full() with NULL
+ * for the user_data and notify.
+ */
+/**
* gst_pad_set_link_function_full:
* @pad: a #GstPad.
* @link: the #GstPadLinkFunction to set.
}
/**
+ * gst_pad_set_unlink_function:
+ * @p: a #GstPad.
+ * @f: the #GstPadUnlinkFunction to set.
+ *
+ * Calls gst_pad_set_unlink_function_full() with NULL
+ * for the user_data and notify.
+ */
+/**
* gst_pad_set_unlink_function_full:
* @pad: a #GstPad.
* @unlink: the #GstPadUnlinkFunction to set.
GST_LOG_OBJECT (pad, "default event handler");
switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- {
- GST_DEBUG_OBJECT (pad, "pausing task because of eos");
- gst_pad_pause_task (pad);
- break;
- }
case GST_EVENT_CAPS:
forward = GST_PAD_IS_PROXY_CAPS (pad);
result = TRUE;
break;
case GST_FLOW_NOT_LINKED:
/* not linked is not a problem, we are sticky so the event will be
- * sent later */
+ * sent later but only for non-EOS events */
GST_DEBUG_OBJECT (pad, "pad was not linked");
- data->ret = GST_FLOW_OK;
+ if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
+ data->ret = GST_FLOW_OK;
/* fallthrough */
default:
GST_DEBUG_OBJECT (pad, "mark pending events");
* event failed.
*/
if (data.ret != GST_FLOW_OK && !data.was_eos) {
- GArray *events = pad->priv->events;
- gint i, len;
-
- len = events->len;
- for (i = 0; i < len; i++) {
- PadEvent *ev = &g_array_index (events, PadEvent, i);
-
- if (G_UNLIKELY (ev->event == NULL) || ev->received)
- continue;
-
- if (GST_EVENT_TYPE (ev->event) == GST_EVENT_EOS) {
- gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event),
- GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
+ PadEvent *ev = find_event_by_type (pad, GST_EVENT_EOS, 0);
- break;
- }
+ if (ev && !ev->received) {
+ data.ret = gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event),
+ GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
}
}
}
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
+
if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH))
goto wrong_mode;
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_FLUSHING;
}
+eos:
+ {
+ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "chaining, but pad was EOS");
+ GST_OBJECT_UNLOCK (pad);
+ GST_PAD_STREAM_UNLOCK (pad);
+ gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+ return GST_FLOW_EOS;
+ }
wrong_mode:
{
g_critical ("chain on pad %s:%s but it was not in push mode",
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
+
if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH))
goto wrong_mode;
gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
return GST_FLOW_FLUSHING;
}
+eos:
+ {
+ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but pad was EOS");
+ GST_OBJECT_UNLOCK (pad);
+ gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+ return GST_FLOW_EOS;
+ }
wrong_mode:
{
g_critical ("pushing on pad %s:%s but it was not activated in push mode",
/* Remove sticky EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS events");
remove_event_by_type (pad, GST_EVENT_EOS);
+ GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH;
break;
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushed;
+ /* No need to check for EOS here as either the caller (gst_pad_push_event())
+ * checked already or this is called as part of pushing sticky events,
+ * in which case we still want to forward the EOS event downstream.
+ */
+
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEGMENT:
/* pass the adjusted segment event on. We need to do this even if
GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked");
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
gst_event_unref (event);
+
+ /* unlinked pads should not influence latency configuration */
+ if (event_type == GST_EVENT_LATENCY)
+ return GST_FLOW_OK;
+
return GST_FLOW_NOT_LINKED;
}
idle_probe_stopped:
gboolean
gst_pad_push_event (GstPad * pad, GstEvent * event)
{
- gboolean res;
+ gboolean res = FALSE;
GstPadProbeType type;
gboolean sticky, serialized;
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushed;
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
+
/* srcpad sticky events are store immediately, the received flag is set
* to FALSE and will be set to TRUE when we can successfully push the
* event to the peer pad */
if (gst_pad_store_sticky_event (pad, event, TRUE)) {
GST_DEBUG_OBJECT (pad, "event %s updated", GST_EVENT_TYPE_NAME (event));
}
+ if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
+ GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
}
if (GST_PAD_IS_SRC (pad) && (serialized || sticky)) {
/* all serialized or sticky events on the srcpad trigger push of
/* other events are pushed right away */
res = (gst_pad_push_event_unchecked (pad, event, type) == GST_FLOW_OK);
} else {
+ /* Errors in sticky event pushing are no problem and ignored here
+ * as they will cause more meaningful errors during data flow.
+ * For EOS events, that are not followed by data flow, we still
+ * return FALSE here though.
+ */
+ if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
+ res = TRUE;
gst_event_unref (event);
- res = TRUE;
}
GST_OBJECT_UNLOCK (pad);
gst_event_unref (event);
return FALSE;
}
+eos:
+ {
+ GST_DEBUG_OBJECT (pad, "We're EOS");
+ GST_OBJECT_UNLOCK (pad);
+ gst_event_unref (event);
+ return FALSE;
+ }
}
/* Check if we can call the event function with the given event */
/* Remove pending EOS events */
GST_LOG_OBJECT (pad, "Removing pending EOS events");
remove_event_by_type (pad, GST_EVENT_EOS);
+ GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
GST_OBJECT_UNLOCK (pad);
/* grab stream lock */
goto flushing;
if (serialized) {
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
+
/* lock order: STREAM_LOCK, LOCK, recheck flushing. */
GST_OBJECT_UNLOCK (pad);
GST_PAD_STREAM_LOCK (pad);
GST_OBJECT_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
+
+ if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+ goto eos;
}
switch (GST_EVENT_TYPE (event)) {
/* after the event function accepted the event, we can store the sticky
* event on the pad */
gst_pad_store_sticky_event (pad, event, FALSE);
+ if (event_type == GST_EVENT_EOS)
+ GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
}
gst_event_unref (event);
}
gst_event_unref (event);
return GST_FLOW_FLUSHING;
}
+eos:
+ {
+ GST_OBJECT_UNLOCK (pad);
+ if (need_unlock)
+ GST_PAD_STREAM_UNLOCK (pad);
+ GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad,
+ "Received event on EOS pad. Discarding");
+ gst_event_unref (event);
+ return GST_FLOW_EOS;
+ }
probe_stopped:
{
GST_OBJECT_UNLOCK (pad);