1 <chapter id="chapter-advanced-events">
2 <title>Events: Seeking, Navigation and More</title>
4 There are many different event types but only two ways they can travel in
5 the pipeline: downstream or upstream. It is very important to understand
6 how both of these methods work because if one element in the pipeline is not
7 handling them correctly the whole event system of the pipeline is broken.
8 We will try to explain here how these methods work and how elements are
9 supposed to implement them.
11 <sect1 id="section-events-downstream" xreflabel="Downstream events">
12 <title>Downstream events</title>
14 Downstream events are received through the sink pad's event handler,
15 as set using <function>gst_pad_set_event_function ()</function> when
19 Downstream events can travel in two ways: they can be in-band (serialised
20 with the buffer flow) or out-of-band (travelling through the pipeline
21 instantly, possibly not in the same thread as the streaming thread that
22 is processing the buffers, skipping ahead of buffers being processed
23 or queued in the pipeline). The most common downstream events
24 (NEWSEGMENT, EOS, TAG) are all serialised with the buffer flow.
27 Here is a typical event function:
31 gst_my_filter_sink_event (GstPad *pad, GstEvent * event)
36 filter = GST_MY_FILTER (gst_pad_get_parent (pad));
39 switch (GST_EVENT_TYPE (event)) {
40 case GST_EVENT_NEWSEGMENT:
41 /* maybe save and/or update the current segment (e.g. for output
42 * clipping) or convert the event into one in a different format
43 * (e.g. BYTES to TIME) or drop it and set a flag to send a newsegment
44 * event in a different format later */
45 ret = gst_pad_push_event (filter->src_pad, event);
48 /* end-of-stream, we should close down all stream leftovers here */
49 gst_my_filter_stop_processing (filter);
50 ret = gst_pad_push_event (filter->src_pad, event);
52 case GST_EVENT_FLUSH_STOP:
53 gst_my_filter_clear_temporary_buffers (filter);
54 ret = gst_pad_push_event (filter->src_pad, event);
57 ret = gst_pad_event_default (pad, event);
62 gst_object_unref (filter);
67 If your element is chain-based, you will almost always have to implement
68 a sink event function, since that is how you are notified about
69 new segments and the end of the stream.
72 If your element is exclusively loop-based, you may or may not want a
73 sink event function (since the element is driving the pipeline it will
74 know the length of the stream in advance or be notified by the flow
75 return value of <function>gst_pad_pull_range()</function>. In some cases
76 even loop-based element may receive events from upstream though (for
77 example audio decoders with an id3demux or apedemux element in front of
78 them, or demuxers that are being fed input from sources that send
79 additional information about the stream in custom events, as DVD sources
83 <sect1 id="section-events-upstream" xreflabel="Upstream events">
84 <title>Upstream events</title>
86 Upstream events are generated by an element somewhere downstream in
87 the pipeline (example: a video sink may generate navigation
88 events that informs upstream elements about the current position of
89 the mouse pointer). This may also happen indirectly on request of the
90 application, for example when the application executes a seek on a
91 pipeline this seek request will be passed on to a sink element which
92 will then in turn generate an upstream seek event.
95 The most common upstream events are seek events and Quality-of-Service
99 An upstream event can be sent using the
100 <function>gst_pad_send_event</function> function. This
101 function simply call the default event handler of that pad. The default
102 event handler of pads is <function>gst_pad_event_default</function>, and
103 it basically sends the event to the peer pad. So upstream events always
104 arrive on the src pad of your element and are handled by the default event
105 handler except if you override that handler to handle it yourself. There
106 are some specific cases where you have to do that :
108 <itemizedlist mark="opencircle">
111 If you have multiple sink pads in your element. In that case you will
112 have to decide which one of the sink pads you will send the event to
113 (if not all of them).
118 If you need to handle that event locally. For example a navigation
119 event that you will want to convert before sending it upstream, or
120 a QoS event that you want to handle.
125 The processing you will do in that event handler does not really matter
126 but there are important rules you have to absolutely respect because
127 one broken element event handler is breaking the whole pipeline event
128 handling. Here they are :
130 <itemizedlist mark="opencircle">
133 Always forward events you won't handle upstream using the default
134 <function>gst_pad_event_default</function> method.
139 If you are generating some new event based on the one you received
140 don't forget to gst_event_unref the event you received.
145 Event handler function are supposed to return TRUE or FALSE indicating
146 if the event has been handled or not. Never simply return TRUE/FALSE
147 in that handler except if you really know that you have handled that
153 Remember that the event handler might be called from a different
154 thread than the streaming thread, so make sure you use
155 appropriate locking everywhere and at the beginning of the function
156 obtain a reference to your element via the
157 <function>gst_pad_get_parent()</function> (and release it again at
158 the end of the function with <function>gst_object_unref ()</function>.
164 <sect1 id="section-events-definitions" xreflabel="All Events Together">
165 <title>All Events Together</title>
167 In this chapter follows a list of all defined events that are currently
168 being used, plus how they should be used/interpreted. You can check the
169 what type a certain event is using the GST_EVENT_TYPE macro (or if you
170 need a string for debugging purposes you can use GST_EVENT_TYPE_NAME).
173 In this chapter, we will discuss the following events:
176 <listitem><para><xref linkend="section-events-eos"/></para></listitem>
177 <listitem><para><xref linkend="section-events-flush-start"/></para></listitem>
178 <listitem><para><xref linkend="section-events-flush-stop"/></para></listitem>
179 <listitem><para><xref linkend="section-events-newsegment"/></para></listitem>
180 <listitem><para><xref linkend="section-events-seek"/></para></listitem>
181 <listitem><para><xref linkend="section-events-nav"/></para></listitem>
182 <listitem><para><xref linkend="section-events-tag"/></para></listitem>
185 For more comprehensive information about events and how they should be
186 used correctly in various circumstances please consult the GStreamer
187 design documentation. This section only gives a general overview.
190 <sect2 id="section-events-eos" xreflabel="End of Stream (EOS)">
191 <title>End of Stream (EOS)</title>
193 End-of-stream events are sent if the stream that an element sends out
194 is finished. An element receiving this event (from upstream, so it
195 receives it on its sinkpad) will generally just process any buffered
196 data (if there is any) and then forward the event further downstream.
197 The <function>gst_pad_event_default ()</function> takes care of all
198 this, so most elements do not need to support this event. Exceptions are
199 elements that explicitly need to close a resource down on EOS, and
200 N-to-1 elements. Note that the stream itself is <emphasis>not</emphasis>
201 a resource that should be closed down on EOS! Applications might seek
202 back to a point before EOS and continue playing again.
205 The EOS event has no properties, which makes it one of the simplest
206 events in &GStreamer;. It is created using the
207 <function>gst_event_new_eos()</function> function.
210 It is important to note that <emphasis>only elements driving the
211 pipeline should ever send an EOS event</emphasis>. If your element
212 is chain-based, it is not driving the pipeline. Chain-based elements
213 should just return GST_FLOW_UNEXPECTED from their chain function at
214 the end of the stream (or the configured segment), the upstream
215 element that is driving the pipeline will then take care of
216 sending the EOS event (or alternatively post a SEGMENT_DONE message
217 on the bus depending on the mode of operation). If you are implementing
218 your own source element, you also do not need to ever manually send
219 an EOS event, you should also just return GST_FLOW_UNEXPECTED in
220 your create function (assuming your element derives from GstBaseSrc
225 <sect2 id="section-events-flush-start" xreflabel="Flush Start">
226 <title>Flush Start</title>
228 The flush start event is sent downstream if all buffers and caches
229 in the pipeline should be emptied. <quote>Queue</quote> elements will
230 empty their internal list of buffers when they receive this event, for
231 example. File sink elements (e.g. <quote>filesink</quote>) will flush
232 the kernel-to-disk cache (<function>fdatasync ()</function> or
233 <function>fflush ()</function>) when they receive this event. Normally,
234 elements receiving this event will simply just forward it, since most
235 filter or filter-like elements don't have an internal cache of data.
236 <function>gst_pad_event_default ()</function> does just that, so for
237 most elements, it is enough to forward the event using the default
241 As a side-effect of flushing all data from the pipeline, this event
242 unblocks the streaming thread by making all pads reject data until
243 they receive a <xref linkend="section-events-flush-stop"/> signal
244 (elements trying to push data will get a WRONG_STATE flow return
245 and stop processing data).
248 The flush-start event is created with the
249 <function>gst_event_new_flush_start ()</function>.
250 Like the EOS event, it has no properties. This event is usually
251 only created by elements driving the pipeline, like source elements
252 operating in push-mode or pull-range based demuxers/decoders.
256 <sect2 id="section-events-flush-stop" xreflabel="Flush Stop">
257 <title>Flush Stop</title>
259 The flush-stop event is sent by an element driving the pipeline
260 after a flush-start and tells pads and elements downstream that
261 they should accept events and buffers again (there will be at
262 least a NEWSEGMENT event before any buffers first though).
265 If your element keeps temporary caches of stream data, it should
266 clear them when it receives a FLUSH-STOP event (and also whenever
267 its chain function receives a buffer with the DISCONT flag set).
270 The flush-stop event is created with
271 <function>gst_event_new_flush_stop ()</function>. Like the EOS event,
272 it has no properties.
276 <sect2 id="section-events-newsegment" xreflabel="New Segment">
277 <title>New Segment</title>
279 A new segment event is sent downstream to either announce a new
280 segment of data in the data stream or to update the current segment
281 with new values. A new segment event must always be sent before the
282 first buffer of data and after a flush (see above).
285 The first new segment event is created by the element driving the
286 pipeline, like a source operating in push-mode or a demuxer/decoder
287 operating pull-based. This new segment event then travels down the
288 pipeline and may be transformed on the way (a decoder, for example,
289 might receive a new-segment event in BYTES format and might transform
290 this into a new-segment event in TIMES format based on the average
294 New segment events may also be used to indicate 'gaps' in the stream,
295 like in a subtitle stream for example where there may not be any
296 data at all for a considerable amount of (stream) time. This is done
297 by updating the segment start of the current segment (see the design
298 documentation for more details).
301 Depending on the element type, the event can simply be forwarded using
302 <function>gst_pad_event_default ()</function>, or it should be parsed
303 and a modified event should be sent on. The last is true for demuxers,
304 which generally have a byte-to-time conversion concept. Their input
305 is usually byte-based, so the incoming event will have an offset in
306 byte units (<symbol>GST_FORMAT_BYTES</symbol>), too. Elements
307 downstream, however, expect new segment events in time units, so that
308 it can be used to update the pipeline clock. Therefore, demuxers and
309 similar elements should not forward the event, but parse it, free it
310 and send a new newsegment event (in time units,
311 <symbol>GST_FORMAT_TIME</symbol>) further downstream.
314 The newsegment event is created using the function
315 <function>gst_event_new_new_segment ()</function>. See the API
316 reference and design document for details about its parameters.
319 Elements parsing this event can use gst_event_parse_new_segment_full()
320 to extract the event details. Elements may find the GstSegment
321 API useful to keep track of the current segment (if they want to use
322 it for output clipping, for example).
326 <sect2 id="section-events-seek" xreflabel="Seek Request">
327 <title>Seek Request</title>
329 Seek events are meant to request a new stream position to elements.
330 This new position can be set in several formats (time, bytes or
331 <quote>default units</quote> [a term indicating frames for video,
332 channel-independent samples for audio, etc.]). Seeking can be done with
333 respect to the end-of-file, start-of-file or current position, and
334 usually happens in upstream direction (downstream seeking is done by
335 sending a NEWSEGMENT event with the appropriate offsets for elements
336 that support that, like filesink).
339 Elements receiving seek events should, depending on the element type,
340 either just forward it upstream (filters, decoders), change the
341 format in which the event is given and then forward it (demuxers),
342 or handle the event by changing the file pointer in their internal
343 stream resource (file sources, demuxers/decoders driving the pipeline
344 in pull-mode) or something else.
347 Seek events are built up using positions in specified formats (time,
348 bytes, units). They are created using the function
349 <function>gst_event_new_seek ()</function>. Note that many plugins do
350 not support seeking from the end of the stream or from the current
351 position. An element not driving the pipeline and forwarding a seek
352 request should not assume that the seek succeeded or actually happened,
353 it should operate based on the NEWSEGMENT events it receives.
356 Elements parsing this event can do this using
357 <function>gst_event_parse_seek()</function>.
361 <sect2 id="section-events-nav" xreflabel="Navigation">
362 <title>Navigation</title>
364 Navigation events are sent upstream by video sinks to inform upstream
365 elements of where the mouse pointer is, if and where mouse pointer
366 clicks have happened, or if keys have been pressed or released.
369 All this information is contained in the event structure which can
370 be obtained with <function>gst_event_get_structure ()</function>.
373 Check out the navigationtest element in gst-plugins-good for an idea
374 how to extract navigation information from this event.
378 <sect2 id="section-events-tag" xreflabel="Tag (metadata)">
379 <title>Tag (metadata)</title>
381 Tagging events are being sent downstream to indicate the tags as parsed
382 from the stream data. This is currently used to preserve tags during
383 stream transcoding from one format to the other. Tags are discussed
384 extensively in <xref linkend="chapter-advanced-tagging"/>. Most
385 elements will simply forward the event by calling
386 <function>gst_pad_event_default ()</function>.
389 The tag event is created using the function
390 <function>gst_event_new_tag ()</function>, but more often elements will
391 use either the <function>gst_element_found_tags ()</function> function
392 or the <function>gst_element_found_tags_for_pad ()</function>, which
393 will do both: post a tag message on the bus and send a tag event
394 downstream. All of these functions require a filled-in taglist as
395 argument, which they will take ownership of.
398 Elements parsing this event can use the function
399 <function>gst_event_parse_tag ()</function> to acquire the
400 taglist that the event contains.