There are many different event types but only two ways they can travel in the pipeline: downstream or upstream. It is very important to understand how both of these methods work because if one element in the pipeline is not handling them correctly the whole event system of the pipeline is broken. We will try to explain here how these methods work and how elements are supposed to implement them.
Downstream events are received through the sink pad's event handler,
as set using gst_pad_set_event_function ()
when
the pad was created.
Downstream events can travel in two ways: they can be in-band (serialised with the buffer flow) or out-of-band (travelling through the pipeline instantly, possibly not in the same thread as the streaming thread that is processing the buffers, skipping ahead of buffers being processed or queued in the pipeline). The most common downstream events (SEGMENT, CAPS, TAG, EOS) are all serialised with the buffer flow.
Here is a typical event function:
static gboolean gst_my_filter_sink_event (GstPad *pad, GstObject * parent, GstEvent * event) { GstMyFilter *filter; gboolean ret; filter = GST_MY_FILTER (parent); ... switch (GST_EVENT_TYPE (event)) { case GST_EVENT_SEGMENT: /* maybe save and/or update the current segment (e.g. for output * clipping) or convert the event into one in a different format * (e.g. BYTES to TIME) or drop it and set a flag to send a segment * event in a different format later */ ret = gst_pad_push_event (filter->src_pad, event); break; case GST_EVENT_EOS: /* end-of-stream, we should close down all stream leftovers here */ gst_my_filter_stop_processing (filter); ret = gst_pad_push_event (filter->src_pad, event); break; case GST_EVENT_FLUSH_STOP: gst_my_filter_clear_temporary_buffers (filter); ret = gst_pad_push_event (filter->src_pad, event); break; default: ret = gst_pad_event_default (pad, parent, event); break; } ... return ret; }
If your element is chain-based, you will almost always have to implement a sink event function, since that is how you are notified about segments, caps and the end of the stream.
If your element is exclusively loop-based, you may or may not want a
sink event function (since the element is driving the pipeline it will
know the length of the stream in advance or be notified by the flow
return value of gst_pad_pull_range()
. In some cases
even loop-based element may receive events from upstream though (for
example audio decoders with an id3demux or apedemux element in front of
them, or demuxers that are being fed input from sources that send
additional information about the stream in custom events, as DVD sources
do).