inlined remaining docs, added missing doc comments
[platform/upstream/gstreamer.git] / gst / gstevent.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wim.taymans@chello.be>
4  *
5  * gstevent.c: GstEvent subsystem
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 /**
23  * SECTION:gstevent
24  * @short_description: Structure describing events that are passed up and down a pipeline
25  * @see_also: #GstPad, #GstElement
26  *
27  * The event classes are used to construct and query events.
28  *
29  * Events are usually created with gst_event_new() which takes the event type as
30  * an argument. Properties specific to the event can be set afterwards with the
31  * provided macros. The event should be unreferenced with gst_event_unref().
32  *
33  * gst_event_new_seek() is a usually used to create a seek event and it takes
34  * the needed parameters for a seek event. 
35  *
36  * gst_event_new_flush() creates a new flush event.
37  */
38
39 #include <string.h>             /* memcpy */
40
41 #include "gst_private.h"
42
43 #include "gstinfo.h"
44 #include "gstevent.h"
45 #include "gstenumtypes.h"
46 #include "gstutils.h"
47
48 static void gst_event_init (GTypeInstance * instance, gpointer g_class);
49 static void gst_event_class_init (gpointer g_class, gpointer class_data);
50 static void gst_event_finalize (GstEvent * event);
51 static GstEvent *_gst_event_copy (GstEvent * event);
52
53 void
54 _gst_event_initialize (void)
55 {
56   gst_event_get_type ();
57 }
58
59 GType
60 gst_event_get_type (void)
61 {
62   static GType _gst_event_type;
63
64   if (G_UNLIKELY (_gst_event_type == 0)) {
65     static const GTypeInfo event_info = {
66       sizeof (GstEventClass),
67       NULL,
68       NULL,
69       gst_event_class_init,
70       NULL,
71       NULL,
72       sizeof (GstEvent),
73       0,
74       gst_event_init,
75       NULL
76     };
77
78     _gst_event_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
79         "GstEvent", &event_info, 0);
80   }
81
82   return _gst_event_type;
83 }
84
85 static void
86 gst_event_class_init (gpointer g_class, gpointer class_data)
87 {
88   GstEventClass *event_class = GST_EVENT_CLASS (g_class);
89
90   event_class->mini_object_class.copy =
91       (GstMiniObjectCopyFunction) _gst_event_copy;
92   event_class->mini_object_class.finalize =
93       (GstMiniObjectFinalizeFunction) gst_event_finalize;
94 }
95
96 static void
97 gst_event_init (GTypeInstance * instance, gpointer g_class)
98 {
99   GstEvent *event;
100
101   event = GST_EVENT (instance);
102
103   GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE;
104 }
105
106 static void
107 gst_event_finalize (GstEvent * event)
108 {
109   g_return_if_fail (event != NULL);
110   g_return_if_fail (GST_IS_EVENT (event));
111
112   GST_CAT_INFO (GST_CAT_EVENT, "freeing event %p", event);
113
114   if (GST_EVENT_SRC (event)) {
115     gst_object_unref (GST_EVENT_SRC (event));
116     GST_EVENT_SRC (event) = NULL;
117   }
118   if (event->structure) {
119     gst_structure_set_parent_refcount (event->structure, NULL);
120     gst_structure_free (event->structure);
121   }
122 }
123
124 static GstEvent *
125 _gst_event_copy (GstEvent * event)
126 {
127   GstEvent *copy;
128
129   copy = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
130
131   GST_EVENT_TYPE (copy) = GST_EVENT_TYPE (event);
132   GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event);
133
134   if (GST_EVENT_SRC (event)) {
135     GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event));
136   }
137   if (event->structure) {
138     copy->structure = gst_structure_copy (event->structure);
139     gst_structure_set_parent_refcount (copy->structure,
140         &event->mini_object.refcount);
141   }
142   return copy;
143 }
144
145 static GstEvent *
146 gst_event_new (GstEventType type)
147 {
148   GstEvent *event;
149
150   event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
151
152   GST_CAT_INFO (GST_CAT_EVENT, "creating new event %p %d", event, type);
153
154   event->type = type;
155   event->src = NULL;
156   event->structure = NULL;
157
158   return event;
159 }
160
161 /**
162  * gst_event_new_custom:
163  * @type: The type of the new event
164  * @structure: The structure for the event. The event will take ownership of
165  * the structure.
166  *
167  * Create a new custom-typed event. This can be used for anything not
168  * handled by other event-specific functions to pass an event to another
169  * element.
170  *
171  * Make sure to allocate an event type with the #GST_EVENT_MAKE_TYPE macro,
172  * assigning a free number and filling in the correct direction and
173  * serialization flags.
174  *
175  * New custom events can also be created by subclassing the event type if
176  * needed.
177  *
178  * Returns: The new custom event.
179  */
180 GstEvent *
181 gst_event_new_custom (GstEventType type, GstStructure * structure)
182 {
183   GstEvent *event;
184
185   event = gst_event_new (type);
186   if (structure) {
187     gst_structure_set_parent_refcount (structure, &event->mini_object.refcount);
188     event->structure = structure;
189   }
190   return event;
191 }
192
193 /**
194  * gst_event_get_structure:
195  * @event: The #GstEvent.
196  *
197  * Access the structure of the event.
198  *
199  * Returns: The structure of the event. The structure is still
200  * owned by the event, which means that you should not free it and
201  * that the pointer becomes invalid when you free the event.
202  *
203  * MT safe.
204  */
205 const GstStructure *
206 gst_event_get_structure (GstEvent * event)
207 {
208   g_return_val_if_fail (GST_IS_EVENT (event), NULL);
209
210   return event->structure;
211 }
212
213 /**
214  * gst_event_new_flush_start:
215  *
216  * Allocate a new flush start event. The flush start event can be send
217  * upstream and downstream and travels out-of-bounds with the dataflow.
218  * It marks pads as being in a WRONG_STATE to process more data.
219  *
220  * Elements unlock and blocking functions and exit their streaming functions
221  * as fast as possible. 
222  *
223  * This event is typically generated after a seek to minimize the latency
224  * after the seek.
225  *
226  * Returns: A new flush start event.
227  */
228 GstEvent *
229 gst_event_new_flush_start (void)
230 {
231   return gst_event_new (GST_EVENT_FLUSH_START);
232 }
233
234 /**
235  * gst_event_new_flush_stop:
236  *
237  * Allocate a new flush stop event. The flush start event can be send
238  * upstream and downstream and travels out-of-bounds with the dataflow.
239  * It is typically send after sending a FLUSH_START event to make the
240  * pads accept data again.
241  *
242  * Elements can process this event synchronized with the dataflow since
243  * the preceeding FLUSH_START event stopped the dataflow.
244  *
245  * This event is typically generated to complete a seek and to resume
246  * dataflow.
247  *
248  * Returns: A new flush stop event.
249  */
250 GstEvent *
251 gst_event_new_flush_stop (void)
252 {
253   return gst_event_new (GST_EVENT_FLUSH_STOP);
254 }
255
256 /**
257  * gst_event_new_eos:
258  *
259  * Create a new EOS event. The eos event can only travel downstream
260  * synchronized with the buffer flow. Elements that receive the EOS
261  * event on a pad can return UNEXPECTED as a GstFlowReturn when data
262  * after the EOS event arrives.
263  *
264  * The EOS event will travel up to the sink elements in the pipeline
265  * which will then post the GST_MESSAGE_EOS on the bus.
266  *
267  * When all sinks have posted an EOS message, the EOS message is
268  * forwarded to the application.
269  *
270  * Returns: The new EOS event.
271  */
272 GstEvent *
273 gst_event_new_eos (void)
274 {
275   return gst_event_new (GST_EVENT_EOS);
276 }
277
278 /**
279  * gst_event_new_newsegment:
280  * @rate: a new rate for playback
281  * @format: The format of the segment values
282  * @start_val: the start value of the segment
283  * @stop_val: the stop value of the segment
284  * @base: base value for buffer timestamps.
285  *
286  * Allocate a new newsegment event with the given format/values tripplets.
287  *
288  * The newsegment event marks the range of buffers to be processed. All
289  * data not within the segment range is not to be processed.
290  *
291  * The base time of the segment is used to convert the buffer timestamps
292  * into the stream time again.
293  *
294  * After a newsegment event, the buffer stream time is calculated with:
295  *
296  *   TIMESTAMP(buf) - start_time + base
297  *
298  * Returns: A new newsegment event.
299  */
300 GstEvent *
301 gst_event_new_newsegment (gdouble rate, GstFormat format,
302     gint64 start_val, gint64 stop_val, gint64 base)
303 {
304   return gst_event_new_custom (GST_EVENT_NEWSEGMENT,
305       gst_structure_new ("GstEventNewsegment", "rate", G_TYPE_DOUBLE, rate,
306           "format", GST_TYPE_FORMAT, format,
307           "start_val", G_TYPE_INT64, start_val,
308           "stop_val", G_TYPE_INT64, stop_val,
309           "base", G_TYPE_INT64, base, NULL));
310 }
311
312 /**
313  * gst_event_parse_newsegment:
314  * @event: The event to query
315  * @rate: A pointer to the rate of the segment
316  * @format: A pointer to the format of the newsegment values
317  * @start_value: A pointer to store the start value in
318  * @stop_value: A pointer to store the stop value in
319  * @base: A pointer to store the base time in
320  *
321  * Get the start, stop and format in the newsegment event.
322  */
323 void
324 gst_event_parse_newsegment (GstEvent * event, gdouble * rate,
325     GstFormat * format, gint64 * start_value, gint64 * stop_value,
326     gint64 * base)
327 {
328   const GstStructure *structure;
329
330   g_return_if_fail (GST_IS_EVENT (event));
331   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
332
333   structure = gst_event_get_structure (event);
334   if (rate)
335     *rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
336   if (format)
337     *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
338   if (start_value)
339     *start_value =
340         g_value_get_int64 (gst_structure_get_value (structure, "start_val"));
341   if (stop_value)
342     *stop_value =
343         g_value_get_int64 (gst_structure_get_value (structure, "stop_val"));
344   if (base)
345     *base = g_value_get_int64 (gst_structure_get_value (structure, "base"));
346 }
347
348 /* tag event */
349 /**
350  * gst_event_new_tag:
351  * @taglist: metadata list
352  *
353  * Generates a metadata tag event from the given @taglist.
354  * 
355  * Returns: a new #GstEvent
356  */
357 GstEvent *
358 gst_event_new_tag (GstTagList * taglist)
359 {
360   g_return_val_if_fail (taglist != NULL, NULL);
361
362   return gst_event_new_custom (GST_EVENT_TAG, (GstStructure *) taglist);
363 }
364
365 /**
366  * gst_event_parse_tag:
367  * @event: a tag event
368  * @taglist: pointer to metadata list
369  *
370  * Parses a tag @event and stores the results in the given @taglist location.
371  */
372 void
373 gst_event_parse_tag (GstEvent * event, GstTagList ** taglist)
374 {
375   g_return_if_fail (GST_IS_EVENT (event));
376   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
377
378   if (taglist)
379     *taglist = (GstTagList *) event->structure;
380 }
381
382 /* filler event */
383 /**
384  * gst_event_new_filler:
385  *
386  * Create a new dummy event that should be ignored.
387  *
388  * Returns: a new #GstEvent
389  */
390 GstEvent *
391 gst_event_new_filler (void)
392 {
393   return gst_event_new (GST_EVENT_FILLER);
394 }
395
396 /**
397  * gst_event_new_qos:
398  * @proportion: the proportion of the qos message
399  * @diff: The time difference of the last Clock sync
400  * @timestamp: The timestamp of the buffer
401  *
402  * Allocate a new qos event with the given values.
403  * The QOS event is generated in an element that wants an upstream
404  * element to either reduce or increase its rate because of
405  * high/low CPU load.
406  *
407  * proportion is the requested adjustment in datarate, 1.0 is the normal
408  * datarate, 0.75 means increase datarate by 75%, 1.5 is 150%. Negative
409  * values request a slow down, so -0.75 means a decrease by 75%.
410  *
411  * diff is the difference against the clock in stream time of the last 
412  * buffer that caused the element to generate the QOS event.
413  *
414  * timestamp is the timestamp of the last buffer that cause the element
415  * to generate the QOS event.
416  *
417  * Returns: A new QOS event.
418  */
419 GstEvent *
420 gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
421     GstClockTime timestamp)
422 {
423   return gst_event_new_custom (GST_EVENT_QOS,
424       gst_structure_new ("GstEventQOS",
425           "proportion", G_TYPE_DOUBLE, proportion,
426           "diff", G_TYPE_INT64, diff,
427           "timestamp", G_TYPE_UINT64, timestamp, NULL));
428 }
429
430 /**
431  * gst_event_parse_qos:
432  * @event: The event to query
433  * @proportion: A pointer to store the proportion in
434  * @diff: A pointer to store the diff in
435  * @timestamp: A pointer to store the timestamp in
436  *
437  * Get the proportion, diff and timestamp in the qos event.
438  */
439 void
440 gst_event_parse_qos (GstEvent * event, gdouble * proportion,
441     GstClockTimeDiff * diff, GstClockTime * timestamp)
442 {
443   const GstStructure *structure;
444
445   g_return_if_fail (GST_IS_EVENT (event));
446   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_QOS);
447
448   structure = gst_event_get_structure (event);
449   if (proportion)
450     *proportion =
451         g_value_get_double (gst_structure_get_value (structure, "proportion"));
452   if (diff)
453     *diff = g_value_get_int64 (gst_structure_get_value (structure, "diff"));
454   if (timestamp)
455     *timestamp =
456         g_value_get_uint64 (gst_structure_get_value (structure, "timestamp"));
457 }
458
459 /**
460  * gst_event_new_seek:
461  * @rate: The new playback rate
462  * @format: The format of the seek values
463  * @flags: The optional seek flags.
464  * @cur_type: The type and flags for the new current position
465  * @cur: The value of the new current position
466  * @stop_type: The type and flags for the new stop position
467  * @stop: The value of the new stop position
468  *
469  * Allocate a new seek event with the given parameters.
470  *
471  * The seek event configures playback of the pipeline from 
472  * @cur to @stop at the speed given in @rate.
473  * The @cur and @stop values are expressed in format @format.
474  *
475  * A @rate of 1.0 means normal playback rate, 2.0 means double speed.
476  * Negatives values means backwards playback. A value of 0.0 for the
477  * rate is not allowed.
478  *
479  * @cur_type and @stop_type specify how to adjust the current and stop
480  * time, relative or absolute. A type of #GST_EVENT_TYPE_NONE means that
481  * the position should not be updated.
482  *
483  * Returns: A new seek event.
484  */
485 GstEvent *
486 gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
487     GstSeekType cur_type, gint64 cur, GstSeekType stop_type, gint64 stop)
488 {
489   return gst_event_new_custom (GST_EVENT_SEEK,
490       gst_structure_new ("GstEventSeek", "rate", G_TYPE_DOUBLE, rate,
491           "format", GST_TYPE_FORMAT, format,
492           "flags", GST_TYPE_SEEK_FLAGS, flags,
493           "cur_type", GST_TYPE_SEEK_TYPE, cur_type,
494           "cur", G_TYPE_INT64, cur,
495           "stop_type", GST_TYPE_SEEK_TYPE, stop_type,
496           "stop", G_TYPE_INT64, stop, NULL));
497 }
498
499 /**
500  * gst_event_parse_seek:
501  * @event: a seek event
502  * @rate: result location for the rate
503  * @format: result location for the stream format
504  * @flags:  result location for the #GstSeekFlags
505  * @cur_type: result location for the #GstSeekType of the current position
506  * @cur: result location for the current postion expressed in @format
507  * @stop_type:  result location for the #GstSeekType of the stop position
508  * @stop: result location for the stop postion expressed in @format
509  *
510  * Parses a seek @event and stores the results in the given result locations.
511  */
512 void
513 gst_event_parse_seek (GstEvent * event, gdouble * rate, GstFormat * format,
514     GstSeekFlags * flags,
515     GstSeekType * cur_type, gint64 * cur,
516     GstSeekType * stop_type, gint64 * stop)
517 {
518   const GstStructure *structure;
519
520   g_return_if_fail (GST_IS_EVENT (event));
521   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEEK);
522
523   structure = gst_event_get_structure (event);
524   if (rate)
525     *rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
526   if (format)
527     *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
528   if (flags)
529     *flags = g_value_get_flags (gst_structure_get_value (structure, "flags"));
530   if (cur_type)
531     *cur_type =
532         g_value_get_enum (gst_structure_get_value (structure, "cur_type"));
533   if (cur)
534     *cur = g_value_get_int64 (gst_structure_get_value (structure, "cur"));
535   if (stop_type)
536     *stop_type =
537         g_value_get_enum (gst_structure_get_value (structure, "stop_type"));
538   if (stop)
539     *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop"));
540 }
541
542 /* navigation event */
543 /**
544  * gst_event_new_navigation:
545  * @structure: description of the event
546  *
547  * Create a new navigation event from the given description.
548  *
549  * Returns: a new #GstEvent
550  */
551 GstEvent *
552 gst_event_new_navigation (GstStructure * structure)
553 {
554   g_return_val_if_fail (structure != NULL, NULL);
555
556   return gst_event_new_custom (GST_EVENT_NAVIGATION, structure);
557 }