pad: Don't accept any buffers or events after EOS

This commit is contained in:
Sebastian Dröge 2012-06-04 11:46:42 +02:00
parent 584892bf79
commit 8cc12b05fc
2 changed files with 71 additions and 9 deletions

View file

@ -3187,7 +3187,7 @@ push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
/* not linked is not a problem, we are sticky so the event will be
* sent later but only for non-EOS events */
GST_DEBUG_OBJECT (pad, "pad was not linked");
if (GST_EVENT_TYPE (ev) != GST_FLOW_EOS)
if (GST_EVENT_TYPE (ev) != GST_EVENT_EOS)
data->ret = GST_FLOW_OK;
/* fallthrough */
default:
@ -3504,6 +3504,9 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
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;
@ -3565,6 +3568,14 @@ flushing:
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",
@ -3713,6 +3724,9 @@ gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
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;
@ -3758,6 +3772,13 @@ flushing:
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",
@ -4320,6 +4341,7 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
/* 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;
@ -4328,6 +4350,11 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
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
@ -4465,12 +4492,17 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
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
@ -4515,6 +4547,13 @@ flushed:
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 */
@ -4584,6 +4623,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * 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 */
@ -4603,6 +4643,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
goto flushing;
if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
goto eos;
if (serialized) {
/* lock order: STREAM_LOCK, LOCK, recheck flushing. */
GST_OBJECT_UNLOCK (pad);
@ -4611,6 +4654,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
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)) {
@ -4665,6 +4711,8 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * 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);
}
@ -4685,6 +4733,16 @@ flushing:
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);

View file

@ -590,7 +590,8 @@ typedef gboolean (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEvent **
/**
* GstPadFlags:
* @GST_PAD_FLAG_BLOCKED: is dataflow on a pad blocked
* @GST_PAD_FLAG_FLUSHING: is pad refusing buffers
* @GST_PAD_FLAG_FLUSHING: is pad flushing
* @GST_PAD_FLAG_EOS: is pad in EOS state
* @GST_PAD_FLAG_BLOCKING: is pad currently blocking on a buffer or event
* @GST_PAD_FLAG_NEED_PARENT: ensure that there is a parent object before calling
* into the pad callbacks.
@ -614,13 +615,14 @@ typedef gboolean (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEvent **
typedef enum {
GST_PAD_FLAG_BLOCKED = (GST_OBJECT_FLAG_LAST << 0),
GST_PAD_FLAG_FLUSHING = (GST_OBJECT_FLAG_LAST << 1),
GST_PAD_FLAG_BLOCKING = (GST_OBJECT_FLAG_LAST << 2),
GST_PAD_FLAG_NEED_PARENT = (GST_OBJECT_FLAG_LAST << 3),
GST_PAD_FLAG_NEED_RECONFIGURE = (GST_OBJECT_FLAG_LAST << 4),
GST_PAD_FLAG_PENDING_EVENTS = (GST_OBJECT_FLAG_LAST << 5),
GST_PAD_FLAG_FIXED_CAPS = (GST_OBJECT_FLAG_LAST << 6),
GST_PAD_FLAG_PROXY_CAPS = (GST_OBJECT_FLAG_LAST << 7),
GST_PAD_FLAG_PROXY_ALLOCATION = (GST_OBJECT_FLAG_LAST << 8),
GST_PAD_FLAG_EOS = (GST_OBJECT_FLAG_LAST << 2),
GST_PAD_FLAG_BLOCKING = (GST_OBJECT_FLAG_LAST << 3),
GST_PAD_FLAG_NEED_PARENT = (GST_OBJECT_FLAG_LAST << 4),
GST_PAD_FLAG_NEED_RECONFIGURE = (GST_OBJECT_FLAG_LAST << 5),
GST_PAD_FLAG_PENDING_EVENTS = (GST_OBJECT_FLAG_LAST << 6),
GST_PAD_FLAG_FIXED_CAPS = (GST_OBJECT_FLAG_LAST << 7),
GST_PAD_FLAG_PROXY_CAPS = (GST_OBJECT_FLAG_LAST << 8),
GST_PAD_FLAG_PROXY_ALLOCATION = (GST_OBJECT_FLAG_LAST << 9),
/* padding */
GST_PAD_FLAG_LAST = (GST_OBJECT_FLAG_LAST << 16)
} GstPadFlags;
@ -755,6 +757,8 @@ struct _GstPadClass {
#define GST_PAD_SET_FLUSHING(pad) (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_FLUSHING))
#define GST_PAD_UNSET_FLUSHING(pad) (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_FLUSHING))
#define GST_PAD_IS_EOS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_EOS))
#define GST_PAD_NEEDS_RECONFIGURE(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_NEED_RECONFIGURE))
#define GST_PAD_HAS_PENDING_EVENTS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_PENDING_EVENTS))
#define GST_PAD_IS_FIXED_CAPS(pad) (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_FIXED_CAPS))