2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wim.taymans@chello.be>
5 * gstevent.c: GstEvent subsystem
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.
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.
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.
24 * @short_description: Structure describing events that are passed up and down a pipeline
25 * @see_also: #GstPad, #GstElement
27 * The event classes are used to construct and query events.
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().
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.
36 * gst_event_new_flush() creates a new flush event.
39 #include <string.h> /* memcpy */
41 #include "gst_private.h"
45 #include "gstenumtypes.h"
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);
54 _gst_event_initialize (void)
56 gst_event_get_type ();
60 gst_event_get_type (void)
62 static GType _gst_event_type;
64 if (G_UNLIKELY (_gst_event_type == 0)) {
65 static const GTypeInfo event_info = {
66 sizeof (GstEventClass),
78 _gst_event_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
79 "GstEvent", &event_info, 0);
82 return _gst_event_type;
86 gst_event_class_init (gpointer g_class, gpointer class_data)
88 GstEventClass *event_class = GST_EVENT_CLASS (g_class);
90 event_class->mini_object_class.copy =
91 (GstMiniObjectCopyFunction) _gst_event_copy;
92 event_class->mini_object_class.finalize =
93 (GstMiniObjectFinalizeFunction) gst_event_finalize;
97 gst_event_init (GTypeInstance * instance, gpointer g_class)
101 event = GST_EVENT (instance);
103 GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE;
107 gst_event_finalize (GstEvent * event)
109 g_return_if_fail (event != NULL);
110 g_return_if_fail (GST_IS_EVENT (event));
112 GST_CAT_INFO (GST_CAT_EVENT, "freeing event %p", event);
114 if (GST_EVENT_SRC (event)) {
115 gst_object_unref (GST_EVENT_SRC (event));
116 GST_EVENT_SRC (event) = NULL;
118 if (event->structure) {
119 gst_structure_set_parent_refcount (event->structure, NULL);
120 gst_structure_free (event->structure);
125 _gst_event_copy (GstEvent * event)
129 copy = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
131 GST_EVENT_TYPE (copy) = GST_EVENT_TYPE (event);
132 GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event);
134 if (GST_EVENT_SRC (event)) {
135 GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event));
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);
146 gst_event_new (GstEventType type)
150 event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
152 GST_CAT_INFO (GST_CAT_EVENT, "creating new event %p %d", event, type);
156 event->structure = NULL;
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
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
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.
175 * New custom events can also be created by subclassing the event type if
178 * Returns: The new custom event.
181 gst_event_new_custom (GstEventType type, GstStructure * structure)
185 event = gst_event_new (type);
187 gst_structure_set_parent_refcount (structure, &event->mini_object.refcount);
188 event->structure = structure;
194 * gst_event_get_structure:
195 * @event: The #GstEvent.
197 * Access the structure of the event.
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.
206 gst_event_get_structure (GstEvent * event)
208 g_return_val_if_fail (GST_IS_EVENT (event), NULL);
210 return event->structure;
214 * gst_event_new_flush_start:
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.
220 * Elements unlock and blocking functions and exit their streaming functions
221 * as fast as possible.
223 * This event is typically generated after a seek to minimize the latency
226 * Returns: A new flush start event.
229 gst_event_new_flush_start (void)
231 return gst_event_new (GST_EVENT_FLUSH_START);
235 * gst_event_new_flush_stop:
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.
242 * Elements can process this event synchronized with the dataflow since
243 * the preceeding FLUSH_START event stopped the dataflow.
245 * This event is typically generated to complete a seek and to resume
248 * Returns: A new flush stop event.
251 gst_event_new_flush_stop (void)
253 return gst_event_new (GST_EVENT_FLUSH_STOP);
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.
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.
267 * When all sinks have posted an EOS message, the EOS message is
268 * forwarded to the application.
270 * Returns: The new EOS event.
273 gst_event_new_eos (void)
275 return gst_event_new (GST_EVENT_EOS);
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.
286 * Allocate a new newsegment event with the given format/values tripplets.
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.
291 * The base time of the segment is used to convert the buffer timestamps
292 * into the stream time again.
294 * After a newsegment event, the buffer stream time is calculated with:
296 * TIMESTAMP(buf) - start_time + base
298 * Returns: A new newsegment event.
301 gst_event_new_newsegment (gdouble rate, GstFormat format,
302 gint64 start_val, gint64 stop_val, gint64 base)
304 if (format == GST_FORMAT_TIME) {
305 GST_CAT_INFO (GST_CAT_EVENT,
306 "creating newsegment rate %lf, format GST_FORMAT_TIME, "
307 "start %" GST_TIME_FORMAT ", stop %" GST_TIME_FORMAT
308 ", base %" GST_TIME_FORMAT,
309 rate, GST_TIME_ARGS (start_val),
310 GST_TIME_ARGS (stop_val), GST_TIME_ARGS (base));
312 GST_CAT_INFO (GST_CAT_EVENT,
313 "creating newsegment rate %lf, format %d, "
314 "start %lld, stop %lld, base %lld",
315 rate, format, start_val, stop_val, base);
318 if (start_val != -1 && stop_val != -1)
319 g_return_val_if_fail (start_val < stop_val, NULL);
321 return gst_event_new_custom (GST_EVENT_NEWSEGMENT,
322 gst_structure_new ("GstEventNewsegment", "rate", G_TYPE_DOUBLE, rate,
323 "format", GST_TYPE_FORMAT, format,
324 "start_val", G_TYPE_INT64, start_val,
325 "stop_val", G_TYPE_INT64, stop_val,
326 "base", G_TYPE_INT64, base, NULL));
330 * gst_event_parse_newsegment:
331 * @event: The event to query
332 * @rate: A pointer to the rate of the segment
333 * @format: A pointer to the format of the newsegment values
334 * @start_value: A pointer to store the start value in
335 * @stop_value: A pointer to store the stop value in
336 * @base: A pointer to store the base time in
338 * Get the start, stop and format in the newsegment event.
341 gst_event_parse_newsegment (GstEvent * event, gdouble * rate,
342 GstFormat * format, gint64 * start_value, gint64 * stop_value,
345 const GstStructure *structure;
347 g_return_if_fail (GST_IS_EVENT (event));
348 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
350 structure = gst_event_get_structure (event);
352 *rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
354 *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
357 g_value_get_int64 (gst_structure_get_value (structure, "start_val"));
360 g_value_get_int64 (gst_structure_get_value (structure, "stop_val"));
362 *base = g_value_get_int64 (gst_structure_get_value (structure, "base"));
367 * @taglist: metadata list
369 * Generates a metadata tag event from the given @taglist.
371 * Returns: a new #GstEvent
374 gst_event_new_tag (GstTagList * taglist)
376 g_return_val_if_fail (taglist != NULL, NULL);
378 return gst_event_new_custom (GST_EVENT_TAG, (GstStructure *) taglist);
382 * gst_event_parse_tag:
383 * @event: a tag event
384 * @taglist: pointer to metadata list
386 * Parses a tag @event and stores the results in the given @taglist location.
389 gst_event_parse_tag (GstEvent * event, GstTagList ** taglist)
391 g_return_if_fail (GST_IS_EVENT (event));
392 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
395 *taglist = (GstTagList *) event->structure;
400 * gst_event_new_filler:
402 * Create a new dummy event that should be ignored.
404 * Returns: a new #GstEvent
407 gst_event_new_filler (void)
409 return gst_event_new (GST_EVENT_FILLER);
414 * @proportion: the proportion of the qos message
415 * @diff: The time difference of the last Clock sync
416 * @timestamp: The timestamp of the buffer
418 * Allocate a new qos event with the given values.
419 * The QOS event is generated in an element that wants an upstream
420 * element to either reduce or increase its rate because of
423 * proportion is the requested adjustment in datarate, 1.0 is the normal
424 * datarate, 0.75 means increase datarate by 75%, 1.5 is 150%. Negative
425 * values request a slow down, so -0.75 means a decrease by 75%.
427 * diff is the difference against the clock in stream time of the last
428 * buffer that caused the element to generate the QOS event.
430 * timestamp is the timestamp of the last buffer that cause the element
431 * to generate the QOS event.
433 * Returns: A new QOS event.
436 gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
437 GstClockTime timestamp)
439 GST_CAT_INFO (GST_CAT_EVENT,
440 "creating qos proportion %lf, diff %" GST_TIME_FORMAT
441 ", timestamp %" GST_TIME_FORMAT, proportion,
442 GST_TIME_ARGS (diff), GST_TIME_ARGS (timestamp));
444 return gst_event_new_custom (GST_EVENT_QOS,
445 gst_structure_new ("GstEventQOS",
446 "proportion", G_TYPE_DOUBLE, proportion,
447 "diff", G_TYPE_INT64, diff,
448 "timestamp", G_TYPE_UINT64, timestamp, NULL));
452 * gst_event_parse_qos:
453 * @event: The event to query
454 * @proportion: A pointer to store the proportion in
455 * @diff: A pointer to store the diff in
456 * @timestamp: A pointer to store the timestamp in
458 * Get the proportion, diff and timestamp in the qos event.
461 gst_event_parse_qos (GstEvent * event, gdouble * proportion,
462 GstClockTimeDiff * diff, GstClockTime * timestamp)
464 const GstStructure *structure;
466 g_return_if_fail (GST_IS_EVENT (event));
467 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_QOS);
469 structure = gst_event_get_structure (event);
472 g_value_get_double (gst_structure_get_value (structure, "proportion"));
474 *diff = g_value_get_int64 (gst_structure_get_value (structure, "diff"));
477 g_value_get_uint64 (gst_structure_get_value (structure, "timestamp"));
481 * gst_event_new_seek:
482 * @rate: The new playback rate
483 * @format: The format of the seek values
484 * @flags: The optional seek flags.
485 * @cur_type: The type and flags for the new current position
486 * @cur: The value of the new current position
487 * @stop_type: The type and flags for the new stop position
488 * @stop: The value of the new stop position
490 * Allocate a new seek event with the given parameters.
492 * The seek event configures playback of the pipeline from
493 * @cur to @stop at the speed given in @rate.
494 * The @cur and @stop values are expressed in format @format.
496 * A @rate of 1.0 means normal playback rate, 2.0 means double speed.
497 * Negatives values means backwards playback. A value of 0.0 for the
498 * rate is not allowed.
500 * @cur_type and @stop_type specify how to adjust the current and stop
501 * time, relative or absolute. A type of #GST_EVENT_TYPE_NONE means that
502 * the position should not be updated.
504 * Returns: A new seek event.
507 gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
508 GstSeekType cur_type, gint64 cur, GstSeekType stop_type, gint64 stop)
510 if (format == GST_FORMAT_TIME) {
511 GST_CAT_INFO (GST_CAT_EVENT,
512 "creating seek rate %lf, format TIME, flags %d, "
513 "cur_type %d, cur %" GST_TIME_FORMAT ", "
514 "stop_type %d, stop %" GST_TIME_FORMAT,
515 rate, flags, cur_type, GST_TIME_ARGS (cur),
516 stop_type, GST_TIME_ARGS (stop));
518 GST_CAT_INFO (GST_CAT_EVENT,
519 "creating seek rate %lf, format %d, flags %d, "
520 "cur_type %d, cur %" G_GINT64_FORMAT ", "
521 "stop_type %d, stop %" G_GINT64_FORMAT,
522 rate, format, flags, cur_type, cur, stop_type, stop);
525 return gst_event_new_custom (GST_EVENT_SEEK,
526 gst_structure_new ("GstEventSeek", "rate", G_TYPE_DOUBLE, rate,
527 "format", GST_TYPE_FORMAT, format,
528 "flags", GST_TYPE_SEEK_FLAGS, flags,
529 "cur_type", GST_TYPE_SEEK_TYPE, cur_type,
530 "cur", G_TYPE_INT64, cur,
531 "stop_type", GST_TYPE_SEEK_TYPE, stop_type,
532 "stop", G_TYPE_INT64, stop, NULL));
536 * gst_event_parse_seek:
537 * @event: a seek event
538 * @rate: result location for the rate
539 * @format: result location for the stream format
540 * @flags: result location for the #GstSeekFlags
541 * @cur_type: result location for the #GstSeekType of the current position
542 * @cur: result location for the current postion expressed in @format
543 * @stop_type: result location for the #GstSeekType of the stop position
544 * @stop: result location for the stop postion expressed in @format
546 * Parses a seek @event and stores the results in the given result locations.
549 gst_event_parse_seek (GstEvent * event, gdouble * rate, GstFormat * format,
550 GstSeekFlags * flags,
551 GstSeekType * cur_type, gint64 * cur,
552 GstSeekType * stop_type, gint64 * stop)
554 const GstStructure *structure;
556 g_return_if_fail (GST_IS_EVENT (event));
557 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEEK);
559 structure = gst_event_get_structure (event);
561 *rate = g_value_get_double (gst_structure_get_value (structure, "rate"));
563 *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
565 *flags = g_value_get_flags (gst_structure_get_value (structure, "flags"));
568 g_value_get_enum (gst_structure_get_value (structure, "cur_type"));
570 *cur = g_value_get_int64 (gst_structure_get_value (structure, "cur"));
573 g_value_get_enum (gst_structure_get_value (structure, "stop_type"));
575 *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop"));
579 * gst_event_new_navigation:
580 * @structure: description of the event
582 * Create a new navigation event from the given description.
584 * Returns: a new #GstEvent
587 gst_event_new_navigation (GstStructure * structure)
589 g_return_val_if_fail (structure != NULL, NULL);
591 return gst_event_new_custom (GST_EVENT_NAVIGATION, structure);