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 (SEGMENT, CAPS, TAG, EOS) are all serialised with the buffer flow.
27 Here is a typical event function:
31 gst_my_filter_sink_event (GstPad *pad, GstObject * parent, GstEvent * event)
36 filter = GST_MY_FILTER (parent);
39 switch (GST_EVENT_TYPE (event)) {
40 case GST_EVENT_SEGMENT:
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 segment
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, parent, event);
66 If your element is chain-based, you will almost always have to implement
67 a sink event function, since that is how you are notified about
68 segments, caps and the end of the stream.
71 If your element is exclusively loop-based, you may or may not want a
72 sink event function (since the element is driving the pipeline it will
73 know the length of the stream in advance or be notified by the flow
74 return value of <function>gst_pad_pull_range()</function>. In some cases
75 even loop-based element may receive events from upstream though (for
76 example audio decoders with an id3demux or apedemux element in front of
77 them, or demuxers that are being fed input from sources that send
78 additional information about the stream in custom events, as DVD sources
82 <sect1 id="section-events-upstream" xreflabel="Upstream events">
83 <title>Upstream events</title>
85 Upstream events are generated by an element somewhere downstream in
86 the pipeline (example: a video sink may generate navigation
87 events that informs upstream elements about the current position of
88 the mouse pointer). This may also happen indirectly on request of the
89 application, for example when the application executes a seek on a
90 pipeline this seek request will be passed on to a sink element which
91 will then in turn generate an upstream seek event.
94 The most common upstream events are seek events, Quality-of-Service
95 (QoS) and reconfigure events.
98 An upstream event can be sent using the
99 <function>gst_pad_send_event</function> function. This
100 function simply call the default event handler of that pad. The default
101 event handler of pads is <function>gst_pad_event_default</function>, and
102 it basically sends the event to the peer of the internally linked pad.
103 So upstream events always arrive on the src pad of your element and are
104 handled by the default event handler except if you override that handler
105 to handle it yourself. There are some specific cases where you have to
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 handle events you won't handle using the default
134 <function>gst_pad_event_default</function> method. This method will
135 depending on the event, forward the event or drop it.
140 If you are generating some new event based on the one you received
141 don't forget to gst_event_unref the event you received.
146 Event handler function are supposed to return TRUE or FALSE indicating
147 if the event has been handled or not. Never simply return TRUE/FALSE
148 in that handler except if you really know that you have handled that
154 Remember that the event handler might be called from a different
155 thread than the streaming thread, so make sure you use
156 appropriate locking everywhere.
162 <sect1 id="section-events-definitions" xreflabel="All Events Together">
163 <title>All Events Together</title>
165 In this chapter follows a list of all defined events that are currently
166 being used, plus how they should be used/interpreted. You can check the
167 what type a certain event is using the GST_EVENT_TYPE macro (or if you
168 need a string for debugging purposes you can use GST_EVENT_TYPE_NAME).
171 In this chapter, we will discuss the following events:
174 <listitem><para><xref linkend="section-events-stream-start"/></para></listitem>
175 <listitem><para><xref linkend="section-events-caps"/></para></listitem>
176 <listitem><para><xref linkend="section-events-segment"/></para></listitem>
177 <listitem><para><xref linkend="section-events-tag"/></para></listitem>
178 <listitem><para><xref linkend="section-events-eos"/></para></listitem>
179 <listitem><para><xref linkend="section-events-toc"/></para></listitem>
180 <listitem><para><xref linkend="section-events-gap"/></para></listitem>
181 <listitem><para><xref linkend="section-events-flush-start"/></para></listitem>
182 <listitem><para><xref linkend="section-events-flush-stop"/></para></listitem>
183 <listitem><para><xref linkend="section-events-qos"/></para></listitem>
184 <listitem><para><xref linkend="section-events-seek"/></para></listitem>
185 <listitem><para><xref linkend="section-events-nav"/></para></listitem>
188 For more comprehensive information about events and how they should be
189 used correctly in various circumstances please consult the GStreamer
190 design documentation. This section only gives a general overview.
193 <sect2 id="section-events-stream-start" xreflabel="Stream Start">
194 <title>Stream Start</title>
200 <sect2 id="section-events-caps" xreflabel="Caps">
203 The CAPS event contains the format description of the following
204 buffers. See <xref linkend="chapter-negotiation"/> for more
205 information about negotiation.
209 <sect2 id="section-events-segment" xreflabel="Segment">
210 <title>Segment</title>
212 A segment event is sent downstream to announce the range of valid
213 timestamps in the stream and how they should be transformed into
214 running-time and stream-time. A segment event must always be sent
215 before the first buffer of data and after a flush (see above).
218 The first segment event is created by the element driving the
219 pipeline, like a source operating in push-mode or a demuxer/decoder
220 operating pull-based. This segment event then travels down the
221 pipeline and may be transformed on the way (a decoder, for example,
222 might receive a segment event in BYTES format and might transform
223 this into a segment event in TIMES format based on the average
227 Depending on the element type, the event can simply be forwarded using
228 <function>gst_pad_event_default ()</function>, or it should be parsed
229 and a modified event should be sent on. The last is true for demuxers,
230 which generally have a byte-to-time conversion concept. Their input
231 is usually byte-based, so the incoming event will have an offset in
232 byte units (<symbol>GST_FORMAT_BYTES</symbol>), too. Elements
233 downstream, however, expect segment events in time units, so that
234 it can be used to synchronize against the pipeline clock. Therefore,
235 demuxers and similar elements should not forward the event, but parse
236 it, free it and send a segment event (in time units,
237 <symbol>GST_FORMAT_TIME</symbol>) further downstream.
240 The segment event is created using the function
241 <function>gst_event_new_segment ()</function>. See the API
242 reference and design document for details about its parameters.
245 Elements parsing this event can use gst_event_parse_segment()
246 to extract the event details. Elements may find the GstSegment
247 API useful to keep track of the current segment (if they want to use
248 it for output clipping, for example).
252 <sect2 id="section-events-tag" xreflabel="Tag (metadata)">
253 <title>Tag (metadata)</title>
255 Tagging events are being sent downstream to indicate the tags as parsed
256 from the stream data. This is currently used to preserve tags during
257 stream transcoding from one format to the other. Tags are discussed
258 extensively in <xref linkend="chapter-advanced-tagging"/>. Most
259 elements will simply forward the event by calling
260 <function>gst_pad_event_default ()</function>.
263 The tag event is created using the function
264 <function>gst_event_new_tag ()</function>, but more often elements will
265 send a tag event downstream that will be converted into a message
266 on the bus by sink elements.
267 All of these functions require a filled-in taglist as
268 argument, which they will take ownership of.
271 Elements parsing this event can use the function
272 <function>gst_event_parse_tag ()</function> to acquire the
273 taglist that the event contains.
277 <sect2 id="section-events-eos" xreflabel="End of Stream (EOS)">
278 <title>End of Stream (EOS)</title>
280 End-of-stream events are sent if the stream that an element sends out
281 is finished. An element receiving this event (from upstream, so it
282 receives it on its sinkpad) will generally just process any buffered
283 data (if there is any) and then forward the event further downstream.
284 The <function>gst_pad_event_default ()</function> takes care of all
285 this, so most elements do not need to support this event. Exceptions are
286 elements that explicitly need to close a resource down on EOS, and
287 N-to-1 elements. Note that the stream itself is <emphasis>not</emphasis>
288 a resource that should be closed down on EOS! Applications might seek
289 back to a point before EOS and continue playing again.
292 The EOS event has no properties, which makes it one of the simplest
293 events in &GStreamer;. It is created using the
294 <function>gst_event_new_eos()</function> function.
297 It is important to note that <emphasis>only elements driving the
298 pipeline should ever send an EOS event</emphasis>. If your element
299 is chain-based, it is not driving the pipeline. Chain-based elements
300 should just return GST_FLOW_EOS from their chain function at
301 the end of the stream (or the configured segment), the upstream
302 element that is driving the pipeline will then take care of
303 sending the EOS event (or alternatively post a SEGMENT_DONE message
304 on the bus depending on the mode of operation). If you are implementing
305 your own source element, you also do not need to ever manually send
306 an EOS event, you should also just return GST_FLOW_EOS in
307 your create or fill function (assuming your element derives from
308 GstBaseSrc or GstPushSrc).
312 <sect2 id="section-events-toc" xreflabel="Table Of Contents">
313 <title>Table Of Contents</title>
319 <sect2 id="section-events-gap" xreflabel="Gap">
326 <sect2 id="section-events-flush-start" xreflabel="Flush Start">
327 <title>Flush Start</title>
329 The flush start event is sent downstream (in push mode) or upstream
330 (in pull mode) if all buffers and caches in the pipeline should be
331 emptied. <quote>Queue</quote> elements will
332 empty their internal list of buffers when they receive this event, for
333 example. File sink elements (e.g. <quote>filesink</quote>) will flush
334 the kernel-to-disk cache (<function>fdatasync ()</function> or
335 <function>fflush ()</function>) when they receive this event. Normally,
336 elements receiving this event will simply just forward it, since most
337 filter or filter-like elements don't have an internal cache of data.
338 <function>gst_pad_event_default ()</function> does just that, so for
339 most elements, it is enough to forward the event using the default
343 As a side-effect of flushing all data from the pipeline, this event
344 unblocks the streaming thread by making all pads reject data until
345 they receive a <xref linkend="section-events-flush-stop"/> signal
346 (elements trying to push data will get a FLUSHING flow return
347 and stop processing data).
350 The flush-start event is created with the
351 <function>gst_event_new_flush_start ()</function>.
352 Like the EOS event, it has no properties. This event is usually
353 only created by elements driving the pipeline, like source elements
354 operating in push-mode or pull-range based demuxers/decoders.
358 <sect2 id="section-events-flush-stop" xreflabel="Flush Stop">
359 <title>Flush Stop</title>
361 The flush-stop event is sent by an element driving the pipeline
362 after a flush-start and tells pads and elements downstream that
363 they should accept events and buffers again (there will be at
364 least a SEGMENT event before any buffers first though).
367 If your element keeps temporary caches of stream data, it should
368 clear them when it receives a FLUSH-STOP event (and also whenever
369 its chain function receives a buffer with the DISCONT flag set).
372 The flush-stop event is created with
373 <function>gst_event_new_flush_stop ()</function>. It has one
374 parameter that controls if the running-time of the pipeline should
375 be reset to 0 or not. Normally after a flushing seek, the
376 running_time is set back to 0.
380 <sect2 id="section-events-qos" xreflabel="Quality Of Service (QOS)">
381 <title>Quality Of Service (QOS)</title>
383 The QOS event contains a report about the current real-time
384 performance of the stream. See more info in
385 <xref linkend="chapter-advanced-qos"/>.
389 <sect2 id="section-events-seek" xreflabel="Seek Request">
390 <title>Seek Request</title>
392 Seek events are meant to request a new stream position to elements.
393 This new position can be set in several formats (time, bytes or
394 <quote>default units</quote> [a term indicating frames for video,
395 channel-independent samples for audio, etc.]). Seeking can be done with
396 respect to the end-of-file or start-of-file, and
397 usually happens in upstream direction (downstream seeking is done by
398 sending a SEGMENT event with the appropriate offsets for elements
399 that support that, like filesink).
402 Elements receiving seek events should, depending on the element type,
403 either just forward it upstream (filters, decoders), change the
404 format in which the event is given and then forward it (demuxers),
405 or handle the event by changing the file pointer in their internal
406 stream resource (file sources, demuxers/decoders driving the pipeline
407 in pull-mode) or something else.
410 Seek events are built up using positions in specified formats (time,
411 bytes, units). They are created using the function
412 <function>gst_event_new_seek ()</function>. Note that many plugins do
413 not support seeking from the end of the stream.
414 An element not driving the pipeline and forwarding a seek
415 request should not assume that the seek succeeded or actually happened,
416 it should operate based on the SEGMENT events it receives.
419 Elements parsing this event can do this using
420 <function>gst_event_parse_seek()</function>.
424 <sect2 id="section-events-nav" xreflabel="Navigation">
425 <title>Navigation</title>
427 Navigation events are sent upstream by video sinks to inform upstream
428 elements of where the mouse pointer is, if and where mouse pointer
429 clicks have happened, or if keys have been pressed or released.
432 All this information is contained in the event structure which can
433 be obtained with <function>gst_event_get_structure ()</function>.
436 Check out the navigationtest element in gst-plugins-good for an idea
437 how to extract navigation information from this event.