|
1 /* GStreamer |
|
2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> |
|
3 * 2000 Wim Taymans <wim.taymans@chello.be> |
|
4 * 2005 Wim Taymans <wim@fluendo.com> |
|
5 * |
|
6 * gstevent.c: GstEvent subsystem |
|
7 * |
|
8 * This library is free software; you can redistribute it and/or |
|
9 * modify it under the terms of the GNU Library General Public |
|
10 * License as published by the Free Software Foundation; either |
|
11 * version 2 of the License, or (at your option) any later version. |
|
12 * |
|
13 * This library is distributed in the hope that it will be useful, |
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
16 * Library General Public License for more details. |
|
17 * |
|
18 * You should have received a copy of the GNU Library General Public |
|
19 * License along with this library; if not, write to the |
|
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
21 * Boston, MA 02111-1307, USA. |
|
22 */ |
|
23 |
|
24 /** |
|
25 * SECTION:gstevent |
|
26 * @short_description: Structure describing events that are passed up and down |
|
27 * a pipeline |
|
28 * @see_also: #GstPad, #GstElement |
|
29 * |
|
30 * The event class provides factory methods to construct and functions query |
|
31 * (parse) events. |
|
32 * |
|
33 * Events are usually created with gst_event_new_*() which takes event-type |
|
34 * specific parameters as arguments. |
|
35 * To send an event application will usually use gst_element_send_event() and |
|
36 * elements will use gst_pad_send_event() or gst_pad_push_event(). |
|
37 * The event should be unreffed with gst_event_unref() if it has not been sent. |
|
38 * |
|
39 * Events that have been received can be parsed with their respective |
|
40 * gst_event_parse_*() functions. It is valid to pass %NULL for unwanted details. |
|
41 * |
|
42 * Events are passed between elements in parallel to the data stream. Some events |
|
43 * are serialized with buffers, others are not. Some events only travel downstream, |
|
44 * others only upstream. Some events can travel both upstream and downstream. |
|
45 * |
|
46 * The events are used to signal special conditions in the datastream such as |
|
47 * EOS (end of stream) or the start of a new stream-segment. |
|
48 * Events are also used to flush the pipeline of any pending data. |
|
49 * |
|
50 * Most of the event API is used inside plugins. Applications usually only |
|
51 * construct and use seek events. |
|
52 * To do that gst_event_new_seek() is used to create a seek event. It takes |
|
53 * the needed parameters to specity seeking time and mode. |
|
54 * <example> |
|
55 * <title>performing a seek on a pipeline</title> |
|
56 * <programlisting> |
|
57 * GstEvent *event; |
|
58 * gboolean result; |
|
59 * ... |
|
60 * // construct a seek event to play the media from second 2 to 5, flush |
|
61 * // the pipeline to decrease latency. |
|
62 * event = gst_event_new_seek (1.0, |
|
63 * GST_FORMAT_TIME, |
|
64 * GST_SEEK_FLAG_FLUSH, |
|
65 * GST_SEEK_TYPE_SET, 2 * GST_SECOND, |
|
66 * GST_SEEK_TYPE_SET, 5 * GST_SECOND); |
|
67 * ... |
|
68 * result = gst_element_send_event (pipeline, event); |
|
69 * if (!result) |
|
70 * g_warning ("seek failed"); |
|
71 * ... |
|
72 * </programlisting> |
|
73 * </example> |
|
74 * |
|
75 * Last reviewed on 2006-09-6 (0.10.10) |
|
76 */ |
|
77 |
|
78 |
|
79 #include "gst_private.h" |
|
80 #include <string.h> /* memcpy */ |
|
81 |
|
82 #include "gstinfo.h" |
|
83 #include "gstevent.h" |
|
84 #include "gstenumtypes.h" |
|
85 #include "gstutils.h" |
|
86 |
|
87 static void gst_event_init (GTypeInstance * instance, gpointer g_class); |
|
88 static void gst_event_class_init (gpointer g_class, gpointer class_data); |
|
89 static void gst_event_finalize (GstEvent * event); |
|
90 static GstEvent *_gst_event_copy (GstEvent * event); |
|
91 |
|
92 static GstMiniObjectClass *parent_class = NULL; |
|
93 #ifdef __SYMBIAN32__ |
|
94 EXPORT_C |
|
95 #endif |
|
96 |
|
97 |
|
98 void |
|
99 _gst_event_initialize (void) |
|
100 { |
|
101 g_type_class_ref (gst_event_get_type ()); |
|
102 g_type_class_ref (gst_seek_flags_get_type ()); |
|
103 g_type_class_ref (gst_seek_type_get_type ()); |
|
104 } |
|
105 |
|
106 typedef struct |
|
107 { |
|
108 const gint type; |
|
109 const gchar *name; |
|
110 GQuark quark; |
|
111 } GstEventQuarks; |
|
112 |
|
113 static GstEventQuarks event_quarks[] = { |
|
114 {GST_EVENT_UNKNOWN, "unknown", 0}, |
|
115 {GST_EVENT_FLUSH_START, "flush-start", 0}, |
|
116 {GST_EVENT_FLUSH_STOP, "flush-stop", 0}, |
|
117 {GST_EVENT_EOS, "eos", 0}, |
|
118 {GST_EVENT_NEWSEGMENT, "newsegment", 0}, |
|
119 {GST_EVENT_TAG, "tag", 0}, |
|
120 {GST_EVENT_BUFFERSIZE, "buffersize", 0}, |
|
121 {GST_EVENT_QOS, "qos", 0}, |
|
122 {GST_EVENT_SEEK, "seek", 0}, |
|
123 {GST_EVENT_NAVIGATION, "navigation", 0}, |
|
124 {GST_EVENT_LATENCY, "latency", 0}, |
|
125 {GST_EVENT_CUSTOM_UPSTREAM, "custom-upstream", 0}, |
|
126 {GST_EVENT_CUSTOM_DOWNSTREAM, "custom-downstream", 0}, |
|
127 {GST_EVENT_CUSTOM_DOWNSTREAM_OOB, "custom-downstream-oob", 0}, |
|
128 {GST_EVENT_CUSTOM_BOTH, "custom-both", 0}, |
|
129 {GST_EVENT_CUSTOM_BOTH_OOB, "custom-both-oob", 0}, |
|
130 |
|
131 {0, NULL, 0} |
|
132 }; |
|
133 |
|
134 /** |
|
135 * gst_event_type_get_name: |
|
136 * @type: the event type |
|
137 * |
|
138 * Get a printable name for the given event type. Do not modify or free. |
|
139 * |
|
140 * Returns: a reference to the static name of the event. |
|
141 */ |
|
142 #ifdef __SYMBIAN32__ |
|
143 EXPORT_C |
|
144 #endif |
|
145 |
|
146 const gchar * |
|
147 gst_event_type_get_name (GstEventType type) |
|
148 { |
|
149 gint i; |
|
150 |
|
151 for (i = 0; event_quarks[i].name; i++) { |
|
152 if (type == event_quarks[i].type) |
|
153 return event_quarks[i].name; |
|
154 } |
|
155 return "unknown"; |
|
156 } |
|
157 |
|
158 /** |
|
159 * gst_event_type_to_quark: |
|
160 * @type: the event type |
|
161 * |
|
162 * Get the unique quark for the given event type. |
|
163 * |
|
164 * Returns: the quark associated with the event type |
|
165 */ |
|
166 #ifdef __SYMBIAN32__ |
|
167 EXPORT_C |
|
168 #endif |
|
169 |
|
170 GQuark |
|
171 gst_event_type_to_quark (GstEventType type) |
|
172 { |
|
173 gint i; |
|
174 |
|
175 for (i = 0; event_quarks[i].name; i++) { |
|
176 if (type == event_quarks[i].type) |
|
177 return event_quarks[i].quark; |
|
178 } |
|
179 return 0; |
|
180 } |
|
181 |
|
182 /** |
|
183 * gst_event_type_get_flags: |
|
184 * @type: a #GstEventType |
|
185 * |
|
186 * Gets the #GstEventTypeFlags associated with @type. |
|
187 * |
|
188 * Returns: a #GstEventTypeFlags. |
|
189 */ |
|
190 #ifdef __SYMBIAN32__ |
|
191 EXPORT_C |
|
192 #endif |
|
193 |
|
194 GstEventTypeFlags |
|
195 gst_event_type_get_flags (GstEventType type) |
|
196 { |
|
197 GstEventTypeFlags ret; |
|
198 |
|
199 ret = type & ((1 << GST_EVENT_TYPE_SHIFT) - 1); |
|
200 |
|
201 return ret; |
|
202 } |
|
203 #ifdef __SYMBIAN32__ |
|
204 EXPORT_C |
|
205 #endif |
|
206 |
|
207 |
|
208 GType |
|
209 gst_event_get_type (void) |
|
210 { |
|
211 static GType _gst_event_type = 0; |
|
212 int i; |
|
213 |
|
214 if (G_UNLIKELY (_gst_event_type == 0)) { |
|
215 static const GTypeInfo event_info = { |
|
216 sizeof (GstEventClass), |
|
217 NULL, |
|
218 NULL, |
|
219 gst_event_class_init, |
|
220 NULL, |
|
221 NULL, |
|
222 sizeof (GstEvent), |
|
223 0, |
|
224 gst_event_init, |
|
225 NULL |
|
226 }; |
|
227 |
|
228 _gst_event_type = g_type_register_static (GST_TYPE_MINI_OBJECT, |
|
229 "GstEvent", &event_info, 0); |
|
230 |
|
231 for (i = 0; event_quarks[i].name; i++) { |
|
232 event_quarks[i].quark = g_quark_from_static_string (event_quarks[i].name); |
|
233 } |
|
234 } |
|
235 |
|
236 return _gst_event_type; |
|
237 } |
|
238 |
|
239 static void |
|
240 gst_event_class_init (gpointer g_class, gpointer class_data) |
|
241 { |
|
242 GstEventClass *event_class = GST_EVENT_CLASS (g_class); |
|
243 |
|
244 parent_class = g_type_class_peek_parent (g_class); |
|
245 |
|
246 event_class->mini_object_class.copy = |
|
247 (GstMiniObjectCopyFunction) _gst_event_copy; |
|
248 event_class->mini_object_class.finalize = |
|
249 (GstMiniObjectFinalizeFunction) gst_event_finalize; |
|
250 } |
|
251 |
|
252 static void |
|
253 gst_event_init (GTypeInstance * instance, gpointer g_class) |
|
254 { |
|
255 GstEvent *event; |
|
256 |
|
257 event = GST_EVENT (instance); |
|
258 |
|
259 GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE; |
|
260 } |
|
261 |
|
262 static void |
|
263 gst_event_finalize (GstEvent * event) |
|
264 { |
|
265 g_return_if_fail (event != NULL); |
|
266 g_return_if_fail (GST_IS_EVENT (event)); |
|
267 |
|
268 GST_CAT_LOG (GST_CAT_EVENT, "freeing event %p type %s", event, |
|
269 GST_EVENT_TYPE_NAME (event)); |
|
270 |
|
271 if (GST_EVENT_SRC (event)) { |
|
272 gst_object_unref (GST_EVENT_SRC (event)); |
|
273 GST_EVENT_SRC (event) = NULL; |
|
274 } |
|
275 if (event->structure) { |
|
276 gst_structure_set_parent_refcount (event->structure, NULL); |
|
277 gst_structure_free (event->structure); |
|
278 } |
|
279 |
|
280 GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (event)); |
|
281 } |
|
282 |
|
283 static GstEvent * |
|
284 _gst_event_copy (GstEvent * event) |
|
285 { |
|
286 GstEvent *copy; |
|
287 |
|
288 copy = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT); |
|
289 |
|
290 GST_EVENT_TYPE (copy) = GST_EVENT_TYPE (event); |
|
291 GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event); |
|
292 |
|
293 if (GST_EVENT_SRC (event)) { |
|
294 GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event)); |
|
295 } |
|
296 if (event->structure) { |
|
297 copy->structure = gst_structure_copy (event->structure); |
|
298 gst_structure_set_parent_refcount (copy->structure, |
|
299 ©->mini_object.refcount); |
|
300 } |
|
301 return copy; |
|
302 } |
|
303 |
|
304 static GstEvent * |
|
305 gst_event_new (GstEventType type) |
|
306 { |
|
307 GstEvent *event; |
|
308 |
|
309 event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT); |
|
310 |
|
311 GST_CAT_DEBUG (GST_CAT_EVENT, "creating new event %p %s %d", event, |
|
312 gst_event_type_get_name (type), type); |
|
313 |
|
314 event->type = type; |
|
315 event->src = NULL; |
|
316 event->structure = NULL; |
|
317 |
|
318 return event; |
|
319 } |
|
320 |
|
321 /** |
|
322 * gst_event_new_custom: |
|
323 * @type: The type of the new event |
|
324 * @structure: The structure for the event. The event will take ownership of |
|
325 * the structure. |
|
326 * |
|
327 * Create a new custom-typed event. This can be used for anything not |
|
328 * handled by other event-specific functions to pass an event to another |
|
329 * element. |
|
330 * |
|
331 * Make sure to allocate an event type with the #GST_EVENT_MAKE_TYPE macro, |
|
332 * assigning a free number and filling in the correct direction and |
|
333 * serialization flags. |
|
334 * |
|
335 * New custom events can also be created by subclassing the event type if |
|
336 * needed. |
|
337 * |
|
338 * Returns: The new custom event. |
|
339 */ |
|
340 #ifdef __SYMBIAN32__ |
|
341 EXPORT_C |
|
342 #endif |
|
343 |
|
344 GstEvent * |
|
345 gst_event_new_custom (GstEventType type, GstStructure * structure) |
|
346 { |
|
347 GstEvent *event; |
|
348 |
|
349 /* structure must not have a parent */ |
|
350 if (structure) |
|
351 g_return_val_if_fail (structure->parent_refcount == NULL, NULL); |
|
352 |
|
353 event = gst_event_new (type); |
|
354 if (structure) { |
|
355 gst_structure_set_parent_refcount (structure, &event->mini_object.refcount); |
|
356 event->structure = structure; |
|
357 } |
|
358 return event; |
|
359 } |
|
360 |
|
361 /** |
|
362 * gst_event_get_structure: |
|
363 * @event: The #GstEvent. |
|
364 * |
|
365 * Access the structure of the event. |
|
366 * |
|
367 * Returns: The structure of the event. The structure is still |
|
368 * owned by the event, which means that you should not free it and |
|
369 * that the pointer becomes invalid when you free the event. |
|
370 * |
|
371 * MT safe. |
|
372 */ |
|
373 #ifdef __SYMBIAN32__ |
|
374 EXPORT_C |
|
375 #endif |
|
376 |
|
377 const GstStructure * |
|
378 gst_event_get_structure (GstEvent * event) |
|
379 { |
|
380 g_return_val_if_fail (GST_IS_EVENT (event), NULL); |
|
381 |
|
382 return event->structure; |
|
383 } |
|
384 |
|
385 /** |
|
386 * gst_event_new_flush_start: |
|
387 * |
|
388 * Allocate a new flush start event. The flush start event can be sent |
|
389 * upstream and downstream and travels out-of-bounds with the dataflow. |
|
390 * |
|
391 * It marks pads as being flushing and will make them return |
|
392 * #GST_FLOW_WRONG_STATE when used for data flow with gst_pad_push(), |
|
393 * gst_pad_chain(), gst_pad_alloc_buffer(), gst_pad_get_range() and |
|
394 * gst_pad_pull_range(). Any event (except a #GST_EVENT_FLUSH_STOP) received |
|
395 * on a flushing pad will return %FALSE immediately. |
|
396 * |
|
397 * Elements should unlock any blocking functions and exit their streaming |
|
398 * functions as fast as possible when this event is received. |
|
399 * |
|
400 * This event is typically generated after a seek to flush out all queued data |
|
401 * in the pipeline so that the new media is played as soon as possible. |
|
402 * |
|
403 * Returns: A new flush start event. |
|
404 */ |
|
405 #ifdef __SYMBIAN32__ |
|
406 EXPORT_C |
|
407 #endif |
|
408 |
|
409 GstEvent * |
|
410 gst_event_new_flush_start (void) |
|
411 { |
|
412 return gst_event_new (GST_EVENT_FLUSH_START); |
|
413 } |
|
414 |
|
415 /** |
|
416 * gst_event_new_flush_stop: |
|
417 * |
|
418 * Allocate a new flush stop event. The flush stop event can be sent |
|
419 * upstream and downstream and travels out-of-bounds with the dataflow. |
|
420 * It is typically sent after sending a FLUSH_START event to make the |
|
421 * pads accept data again. |
|
422 * |
|
423 * Elements can process this event synchronized with the dataflow since |
|
424 * the preceeding FLUSH_START event stopped the dataflow. |
|
425 * |
|
426 * This event is typically generated to complete a seek and to resume |
|
427 * dataflow. |
|
428 * |
|
429 * Returns: A new flush stop event. |
|
430 */ |
|
431 #ifdef __SYMBIAN32__ |
|
432 EXPORT_C |
|
433 #endif |
|
434 |
|
435 GstEvent * |
|
436 gst_event_new_flush_stop (void) |
|
437 { |
|
438 return gst_event_new (GST_EVENT_FLUSH_STOP); |
|
439 } |
|
440 |
|
441 /** |
|
442 * gst_event_new_eos: |
|
443 * |
|
444 * Create a new EOS event. The eos event can only travel downstream |
|
445 * synchronized with the buffer flow. Elements that receive the EOS |
|
446 * event on a pad can return #GST_FLOW_UNEXPECTED as a #GstFlowReturn |
|
447 * when data after the EOS event arrives. |
|
448 * |
|
449 * The EOS event will travel down to the sink elements in the pipeline |
|
450 * which will then post the #GST_MESSAGE_EOS on the bus after they have |
|
451 * finished playing any buffered data. |
|
452 * |
|
453 * When all sinks have posted an EOS message, an EOS message is |
|
454 * forwarded to the application. |
|
455 * |
|
456 * Returns: The new EOS event. |
|
457 */ |
|
458 #ifdef __SYMBIAN32__ |
|
459 EXPORT_C |
|
460 #endif |
|
461 |
|
462 GstEvent * |
|
463 gst_event_new_eos (void) |
|
464 { |
|
465 return gst_event_new (GST_EVENT_EOS); |
|
466 } |
|
467 |
|
468 /** |
|
469 * gst_event_new_new_segment: |
|
470 * @update: is this segment an update to a previous one |
|
471 * @rate: a new rate for playback |
|
472 * @format: The format of the segment values |
|
473 * @start: the start value of the segment |
|
474 * @stop: the stop value of the segment |
|
475 * @position: stream position |
|
476 * |
|
477 * Allocate a new newsegment event with the given format/ |
|
478 #ifdef __SYMBIAN32__ |
|
479 EXPORT_C |
|
480 #endif |
|
481 values tripplets |
|
482 * |
|
483 * This method calls gst_event_new_new_segment_full() passing a default |
|
484 * value of 1.0 for applied_rate |
|
485 * |
|
486 * Returns: A new newsegment event. |
|
487 */ |
|
488 #ifdef __SYMBIAN32__ |
|
489 EXPORT_C |
|
490 #endif |
|
491 |
|
492 GstEvent * |
|
493 gst_event_new_new_segment (gboolean update, gdouble rate, GstFormat format, |
|
494 gint64 start, gint64 stop, gint64 position) |
|
495 { |
|
496 return gst_event_new_new_segment_full (update, rate, 1.0, format, start, |
|
497 stop, position); |
|
498 } |
|
499 |
|
500 /** |
|
501 * gst_event_parse_new_segment: |
|
502 * @event: The event to query |
|
503 * @update: A pointer to the update flag of the segment |
|
504 * @rate: A pointer to the rate of the segment |
|
505 * @format: A pointer to the format of the newsegment values |
|
506 * @start: A pointer to store the start value in |
|
507 * @stop: A pointer to store the stop value in |
|
508 * @position: A pointer to store the stream time in |
|
509 * |
|
510 * Get the update flag, rate, format, start, stop and position in the |
|
511 * newsegment event. In general, gst_event_parse_new_segment_full() should |
|
512 * be used instead of this, to also retrieve the applied_rate value of the |
|
513 * segment. See gst_event_new_new_segment_full() for a full description |
|
514 * of the newsegment event. |
|
515 */ |
|
516 #ifdef __SYMBIAN32__ |
|
517 EXPORT_C |
|
518 #endif |
|
519 |
|
520 void |
|
521 gst_event_parse_new_segment (GstEvent * event, gboolean * update, |
|
522 gdouble * rate, GstFormat * format, gint64 * start, |
|
523 gint64 * stop, gint64 * position) |
|
524 { |
|
525 gst_event_parse_new_segment_full (event, update, rate, NULL, format, start, |
|
526 stop, position); |
|
527 } |
|
528 |
|
529 /** |
|
530 * gst_event_new_new_segment_full: |
|
531 * @update: Whether this segment is an update to a previous one |
|
532 * @rate: A new rate for playback |
|
533 * @applied_rate: The rate factor which has already been applied |
|
534 * @format: The format of the segment values |
|
535 * @start: The start value of the segment |
|
536 * @stop: The stop value of the segment |
|
537 * @position: stream position |
|
538 * |
|
539 * Allocate a new newsegment event with the given format/values triplets. |
|
540 * |
|
541 * The newsegment event marks the range of buffers to be processed. All |
|
542 * data not within the segment range is not to be processed. This can be |
|
543 * used intelligently by plugins to apply more efficient methods of skipping |
|
544 * unneeded data. |
|
545 * |
|
546 * The position value of the segment is used in conjunction with the start |
|
547 * value to convert the buffer timestamps into the stream time. This is |
|
548 * usually done in sinks to report the current stream_time. |
|
549 * @position represents the stream_time of a buffer carrying a timestamp of |
|
550 * @start. @position cannot be -1. |
|
551 * |
|
552 * @start cannot be -1, @stop can be -1. If there |
|
553 * is a valid @stop given, it must be greater or equal the @start, including |
|
554 * when the indicated playback @rate is < 0. |
|
555 * |
|
556 * The @applied_rate value provides information about any rate adjustment that |
|
557 * has already been made to the timestamps and content on the buffers of the |
|
558 * stream. (@rate * @applied_rate) should always equal the rate that has been |
|
559 * requested for playback. For example, if an element has an input segment |
|
560 * with intended playback @rate of 2.0 and applied_rate of 1.0, it can adjust |
|
561 * incoming timestamps and buffer content by half and output a newsegment event |
|
562 * with @rate of 1.0 and @applied_rate of 2.0 |
|
563 * |
|
564 * After a newsegment event, the buffer stream time is calculated with: |
|
565 * |
|
566 * position + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate) |
|
567 * |
|
568 * Returns: A new newsegment event. |
|
569 * |
|
570 * Since: 0.10.6 |
|
571 */ |
|
572 #ifdef __SYMBIAN32__ |
|
573 EXPORT_C |
|
574 #endif |
|
575 GstEvent * |
|
576 gst_event_new_new_segment_full (gboolean update, gdouble rate, |
|
577 gdouble applied_rate, GstFormat format, gint64 start, gint64 stop, |
|
578 gint64 position) |
|
579 { |
|
580 g_return_val_if_fail (rate != 0.0, NULL); |
|
581 g_return_val_if_fail (applied_rate != 0.0, NULL); |
|
582 |
|
583 if (format == GST_FORMAT_TIME) { |
|
584 GST_CAT_INFO (GST_CAT_EVENT, |
|
585 "creating newsegment update %d, rate %lf, format GST_FORMAT_TIME, " |
|
586 "start %" GST_TIME_FORMAT ", stop %" GST_TIME_FORMAT |
|
587 ", position %" GST_TIME_FORMAT, |
|
588 update, rate, GST_TIME_ARGS (start), |
|
589 GST_TIME_ARGS (stop), GST_TIME_ARGS (position)); |
|
590 } else { |
|
591 GST_CAT_INFO (GST_CAT_EVENT, |
|
592 "creating newsegment update %d, rate %lf, format %d, " |
|
593 "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT ", position %" |
|
594 G_GINT64_FORMAT, update, rate, format, start, stop, position); |
|
595 } |
|
596 |
|
597 g_return_val_if_fail (position != -1, NULL); |
|
598 g_return_val_if_fail (start != -1, NULL); |
|
599 if (stop != -1) |
|
600 g_return_val_if_fail (start <= stop, NULL); |
|
601 |
|
602 return gst_event_new_custom (GST_EVENT_NEWSEGMENT, |
|
603 gst_structure_new ("GstEventNewsegment", |
|
604 "update", G_TYPE_BOOLEAN, update, |
|
605 "rate", G_TYPE_DOUBLE, rate, |
|
606 "applied_rate", G_TYPE_DOUBLE, applied_rate, |
|
607 "format", GST_TYPE_FORMAT, format, |
|
608 "start", G_TYPE_INT64, start, |
|
609 "stop", G_TYPE_INT64, stop, |
|
610 "position", G_TYPE_INT64, position, NULL)); |
|
611 } |
|
612 |
|
613 /** |
|
614 * gst_event_parse_new_segment_full: |
|
615 * @event: The event to query |
|
616 * @update: A pointer to the update flag of the segment |
|
617 * @rate: A pointer to the rate of the segment |
|
618 * @applied_rate: A pointer to the applied_rate of the segment |
|
619 * @format: A pointer to the format of the newsegment values |
|
620 * @start: A pointer to store the start value in |
|
621 * @stop: A pointer to store the stop value in |
|
622 * @position: A pointer to store the stream time in |
|
623 * |
|
624 * Get the update, rate, applied_rate, format, start, stop and |
|
625 * position in the newsegment event. See gst_event_new_new_segment_full() |
|
626 * for a full description of the newsegment event. |
|
627 * |
|
628 * Since: 0.10.6 |
|
629 */ |
|
630 #ifdef __SYMBIAN32__ |
|
631 EXPORT_C |
|
632 #endif |
|
633 |
|
634 void |
|
635 gst_event_parse_new_segment_full (GstEvent * event, gboolean * update, |
|
636 gdouble * rate, gdouble * applied_rate, GstFormat * format, |
|
637 gint64 * start, gint64 * stop, gint64 * position) |
|
638 { |
|
639 const GstStructure *structure; |
|
640 |
|
641 g_return_if_fail (GST_IS_EVENT (event)); |
|
642 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT); |
|
643 |
|
644 structure = gst_event_get_structure (event); |
|
645 if (G_LIKELY (update)) |
|
646 *update = |
|
647 g_value_get_boolean (gst_structure_get_value (structure, "update")); |
|
648 if (G_LIKELY (rate)) |
|
649 *rate = g_value_get_double (gst_structure_get_value (structure, "rate")); |
|
650 if (G_LIKELY (applied_rate)) |
|
651 *applied_rate = |
|
652 g_value_get_double (gst_structure_get_value (structure, |
|
653 "applied_rate")); |
|
654 if (G_LIKELY (format)) |
|
655 *format = g_value_get_enum (gst_structure_get_value (structure, "format")); |
|
656 if (G_LIKELY (start)) |
|
657 *start = g_value_get_int64 (gst_structure_get_value (structure, "start")); |
|
658 if (G_LIKELY (stop)) |
|
659 *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop")); |
|
660 if (G_LIKELY (position)) |
|
661 *position = |
|
662 g_value_get_int64 (gst_structure_get_value (structure, "position")); |
|
663 } |
|
664 |
|
665 /** |
|
666 * gst_event_new_tag: |
|
667 * @taglist: metadata list |
|
668 * |
|
669 * Generates a metadata tag event from the given @taglist. |
|
670 * |
|
671 * Returns: a new #GstEvent |
|
672 */ |
|
673 #ifdef __SYMBIAN32__ |
|
674 EXPORT_C |
|
675 #endif |
|
676 |
|
677 GstEvent * |
|
678 gst_event_new_tag (GstTagList * taglist) |
|
679 { |
|
680 g_return_val_if_fail (taglist != NULL, NULL); |
|
681 |
|
682 return gst_event_new_custom (GST_EVENT_TAG, (GstStructure *) taglist); |
|
683 } |
|
684 |
|
685 /** |
|
686 * gst_event_parse_tag: |
|
687 * @event: a tag event |
|
688 * @taglist: pointer to metadata list |
|
689 * |
|
690 * Parses a tag @event and stores the results in the given @taglist location. |
|
691 */ |
|
692 #ifdef __SYMBIAN32__ |
|
693 EXPORT_C |
|
694 #endif |
|
695 |
|
696 void |
|
697 gst_event_parse_tag (GstEvent * event, GstTagList ** taglist) |
|
698 { |
|
699 g_return_if_fail (GST_IS_EVENT (event)); |
|
700 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TAG); |
|
701 |
|
702 if (taglist) |
|
703 *taglist = (GstTagList *) event->structure; |
|
704 } |
|
705 |
|
706 /* buffersize event */ |
|
707 /** |
|
708 * gst_event_new_buffer_size: |
|
709 * @format: buffer format |
|
710 * @minsize: minimum buffer size |
|
711 * @maxsize: maximum buffer size |
|
712 * @async: thread behavior |
|
713 * |
|
714 * Create a new buffersize event. The event is sent downstream and notifies |
|
715 * elements that they should provide a buffer of the specified dimensions. |
|
716 * |
|
717 * When the @async flag is set, a thread boundary is prefered. |
|
718 * |
|
719 * Returns: a new #GstEvent |
|
720 */ |
|
721 #ifdef __SYMBIAN32__ |
|
722 EXPORT_C |
|
723 #endif |
|
724 |
|
725 GstEvent * |
|
726 gst_event_new_buffer_size (GstFormat format, gint64 minsize, |
|
727 gint64 maxsize, gboolean async) |
|
728 { |
|
729 GST_CAT_INFO (GST_CAT_EVENT, |
|
730 "creating buffersize format %d, minsize %" G_GINT64_FORMAT |
|
731 ", maxsize %" G_GINT64_FORMAT ", async %d", format, |
|
732 minsize, maxsize, async); |
|
733 |
|
734 return gst_event_new_custom (GST_EVENT_BUFFERSIZE, |
|
735 gst_structure_new ("GstEventBufferSize", |
|
736 "format", GST_TYPE_FORMAT, format, |
|
737 "minsize", G_TYPE_INT64, minsize, |
|
738 "maxsize", G_TYPE_INT64, maxsize, |
|
739 "async", G_TYPE_BOOLEAN, async, NULL)); |
|
740 } |
|
741 |
|
742 /** |
|
743 * gst_event_parse_buffer_size: |
|
744 * @event: The event to query |
|
745 * @format: A pointer to store the format in |
|
746 * @minsize: A pointer to store the minsize in |
|
747 * @maxsize: A pointer to store the maxsize in |
|
748 * @async: A pointer to store the async-flag in |
|
749 * |
|
750 * Get the format, minsize, maxsize and async-flag in the buffersize event. |
|
751 */ |
|
752 #ifdef __SYMBIAN32__ |
|
753 EXPORT_C |
|
754 #endif |
|
755 |
|
756 void |
|
757 gst_event_parse_buffer_size (GstEvent * event, GstFormat * format, |
|
758 gint64 * minsize, gint64 * maxsize, gboolean * async) |
|
759 { |
|
760 const GstStructure *structure; |
|
761 |
|
762 g_return_if_fail (GST_IS_EVENT (event)); |
|
763 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_BUFFERSIZE); |
|
764 |
|
765 structure = gst_event_get_structure (event); |
|
766 if (format) |
|
767 *format = g_value_get_enum (gst_structure_get_value (structure, "format")); |
|
768 if (minsize) |
|
769 *minsize = |
|
770 g_value_get_int64 (gst_structure_get_value (structure, "minsize")); |
|
771 if (maxsize) |
|
772 *maxsize = |
|
773 g_value_get_int64 (gst_structure_get_value (structure, "maxsize")); |
|
774 if (async) |
|
775 *async = g_value_get_boolean (gst_structure_get_value (structure, "async")); |
|
776 } |
|
777 |
|
778 /** |
|
779 * gst_event_new_qos: |
|
780 * @proportion: the proportion of the qos message |
|
781 * @diff: The time difference of the last Clock sync |
|
782 * @timestamp: The timestamp of the buffer |
|
783 * |
|
784 * Allocate a new qos event with the given values. |
|
785 * The QOS event is generated in an element that wants an upstream |
|
786 * element to either reduce or increase its rate because of |
|
787 * high/low CPU load or other resource usage such as network performance. |
|
788 * Typically sinks generate these events for each buffer they receive. |
|
789 * |
|
790 * @proportion indicates the real-time performance of the streaming in the |
|
791 * element that generated the QoS event (usually the sink). The value is |
|
792 * generally computed based on more long term statistics about the streams |
|
793 * timestamps compared to the clock. |
|
794 * A value < 1.0 indicates that the upstream element is producing data faster |
|
795 * than real-time. A value > 1.0 indicates that the upstream element is not |
|
796 * producing data fast enough. 1.0 is the ideal @proportion value. The |
|
797 * proportion value can safely be used to lower or increase the quality of |
|
798 * the element. |
|
799 * |
|
800 * @diff is the difference against the clock in running time of the last |
|
801 * buffer that caused the element to generate the QOS event. A negative value |
|
802 * means that the buffer with @timestamp arrived in time. A positive value |
|
803 * indicates how late the buffer with @timestamp was. |
|
804 * |
|
805 * @timestamp is the timestamp of the last buffer that cause the element |
|
806 * to generate the QOS event. It is expressed in running time and thus an ever |
|
807 * increasing value. |
|
808 * |
|
809 * The upstream element can use the @diff and @timestamp values to decide |
|
810 * whether to process more buffers. For possitive @diff, all buffers with |
|
811 * timestamp <= @timestamp + @diff will certainly arrive late in the sink |
|
812 * as well. |
|
813 * |
|
814 * The application can use general event probes to intercept the QoS |
|
815 * event and implement custom application specific QoS handling. |
|
816 * |
|
817 * Returns: A new QOS event. |
|
818 */ |
|
819 #ifdef __SYMBIAN32__ |
|
820 EXPORT_C |
|
821 #endif |
|
822 |
|
823 GstEvent * |
|
824 gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff, |
|
825 GstClockTime timestamp) |
|
826 { |
|
827 GST_CAT_INFO (GST_CAT_EVENT, |
|
828 "creating qos proportion %lf, diff %" G_GINT64_FORMAT |
|
829 ", timestamp %" GST_TIME_FORMAT, proportion, |
|
830 diff, GST_TIME_ARGS (timestamp)); |
|
831 |
|
832 return gst_event_new_custom (GST_EVENT_QOS, |
|
833 gst_structure_new ("GstEventQOS", |
|
834 "proportion", G_TYPE_DOUBLE, proportion, |
|
835 "diff", G_TYPE_INT64, diff, |
|
836 "timestamp", G_TYPE_UINT64, timestamp, NULL)); |
|
837 } |
|
838 |
|
839 /** |
|
840 * gst_event_parse_qos: |
|
841 * @event: The event to query |
|
842 * @proportion: A pointer to store the proportion in |
|
843 * @diff: A pointer to store the diff in |
|
844 * @timestamp: A pointer to store the timestamp in |
|
845 * |
|
846 * Get the proportion, diff and timestamp in the qos event. See |
|
847 * gst_event_new_qos() for more information about the different QoS values. |
|
848 */ |
|
849 #ifdef __SYMBIAN32__ |
|
850 EXPORT_C |
|
851 #endif |
|
852 |
|
853 void |
|
854 gst_event_parse_qos (GstEvent * event, gdouble * proportion, |
|
855 GstClockTimeDiff * diff, GstClockTime * timestamp) |
|
856 { |
|
857 const GstStructure *structure; |
|
858 |
|
859 g_return_if_fail (GST_IS_EVENT (event)); |
|
860 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_QOS); |
|
861 |
|
862 structure = gst_event_get_structure (event); |
|
863 if (proportion) |
|
864 *proportion = |
|
865 g_value_get_double (gst_structure_get_value (structure, "proportion")); |
|
866 if (diff) |
|
867 *diff = g_value_get_int64 (gst_structure_get_value (structure, "diff")); |
|
868 if (timestamp) |
|
869 *timestamp = |
|
870 g_value_get_uint64 (gst_structure_get_value (structure, "timestamp")); |
|
871 } |
|
872 |
|
873 /** |
|
874 * gst_event_new_seek: |
|
875 * @rate: The new playback rate |
|
876 * @format: The format of the seek values |
|
877 * @flags: The optional seek flags |
|
878 * @start_type: The type and flags for the new start position |
|
879 * @start: The value of the new start position |
|
880 * @stop_type: The type and flags for the new stop position |
|
881 * @stop: The value of the new stop position |
|
882 * |
|
883 * Allocate a new seek event with the given parameters. |
|
884 * |
|
885 * The seek event configures playback of the pipeline between @start to @stop |
|
886 * at the speed given in @rate, also called a playback segment. |
|
887 * The @start and @stop values are expressed in @format. |
|
888 * |
|
889 * A @rate of 1.0 means normal playback rate, 2.0 means double speed. |
|
890 * Negatives values means backwards playback. A value of 0.0 for the |
|
891 * rate is not allowed and should be accomplished instead by PAUSING the |
|
892 * pipeline. |
|
893 * |
|
894 * A pipeline has a default playback segment configured with a start |
|
895 * position of 0, a stop position of -1 and a rate of 1.0. The currently |
|
896 * configured playback segment can be queried with #GST_QUERY_SEGMENT. |
|
897 * |
|
898 * @start_type and @stop_type specify how to adjust the currently configured |
|
899 * start and stop fields in @segment. Adjustments can be made relative or |
|
900 * absolute to the last configured values. A type of #GST_SEEK_TYPE_NONE means |
|
901 * that the position should not be updated. |
|
902 * |
|
903 * When the rate is positive and @start has been updated, playback will start |
|
904 * from the newly configured start position. |
|
905 * |
|
906 * For negative rates, playback will start from the newly configured stop |
|
907 * position (if any). If the stop position if updated, it must be different from |
|
908 * -1 for negative rates. |
|
909 * |
|
910 * It is not possible to seek relative to the current playback position, to do |
|
911 * this, PAUSE the pipeline, query the current playback position with |
|
912 * #GST_QUERY_POSITION and update the playback segment current position with a |
|
913 * #GST_SEEK_TYPE_SET to the desired position. |
|
914 * |
|
915 * Returns: A new seek event. |
|
916 */ |
|
917 #ifdef __SYMBIAN32__ |
|
918 EXPORT_C |
|
919 #endif |
|
920 GstEvent * |
|
921 gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags, |
|
922 GstSeekType start_type, gint64 start, GstSeekType stop_type, gint64 stop) |
|
923 { |
|
924 g_return_val_if_fail (rate != 0.0, NULL); |
|
925 |
|
926 if (format == GST_FORMAT_TIME) { |
|
927 GST_CAT_INFO (GST_CAT_EVENT, |
|
928 "creating seek rate %lf, format TIME, flags %d, " |
|
929 "start_type %d, start %" GST_TIME_FORMAT ", " |
|
930 "stop_type %d, stop %" GST_TIME_FORMAT, |
|
931 rate, flags, start_type, GST_TIME_ARGS (start), |
|
932 stop_type, GST_TIME_ARGS (stop)); |
|
933 } else { |
|
934 GST_CAT_INFO (GST_CAT_EVENT, |
|
935 "creating seek rate %lf, format %d, flags %d, " |
|
936 "start_type %d, start %" G_GINT64_FORMAT ", " |
|
937 "stop_type %d, stop %" G_GINT64_FORMAT, |
|
938 rate, format, flags, start_type, start, stop_type, stop); |
|
939 } |
|
940 |
|
941 return gst_event_new_custom (GST_EVENT_SEEK, |
|
942 gst_structure_new ("GstEventSeek", "rate", G_TYPE_DOUBLE, rate, |
|
943 "format", GST_TYPE_FORMAT, format, |
|
944 "flags", GST_TYPE_SEEK_FLAGS, flags, |
|
945 "cur_type", GST_TYPE_SEEK_TYPE, start_type, |
|
946 "cur", G_TYPE_INT64, start, |
|
947 "stop_type", GST_TYPE_SEEK_TYPE, stop_type, |
|
948 "stop", G_TYPE_INT64, stop, NULL)); |
|
949 } |
|
950 |
|
951 /** |
|
952 * gst_event_parse_seek: |
|
953 * @event: a seek event |
|
954 * @rate: result location for the rate |
|
955 * @format: result location for the stream format |
|
956 * @flags: result location for the #GstSeekFlags |
|
957 * @start_type: result location for the #GstSeekType of the start position |
|
958 * @start: result location for the start postion expressed in @format |
|
959 * @stop_type: result location for the #GstSeekType of the stop position |
|
960 * @stop: result location for the stop postion expressed in @format |
|
961 * |
|
962 * Parses a seek @event and stores the results in the given result locations. |
|
963 */ |
|
964 #ifdef __SYMBIAN32__ |
|
965 EXPORT_C |
|
966 #endif |
|
967 |
|
968 void |
|
969 gst_event_parse_seek (GstEvent * event, gdouble * rate, |
|
970 GstFormat * format, GstSeekFlags * flags, GstSeekType * start_type, |
|
971 gint64 * start, GstSeekType * stop_type, gint64 * stop) |
|
972 { |
|
973 const GstStructure *structure; |
|
974 |
|
975 g_return_if_fail (GST_IS_EVENT (event)); |
|
976 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEEK); |
|
977 |
|
978 structure = gst_event_get_structure (event); |
|
979 if (rate) |
|
980 *rate = g_value_get_double (gst_structure_get_value (structure, "rate")); |
|
981 if (format) |
|
982 *format = g_value_get_enum (gst_structure_get_value (structure, "format")); |
|
983 if (flags) |
|
984 *flags = g_value_get_flags (gst_structure_get_value (structure, "flags")); |
|
985 if (start_type) |
|
986 *start_type = |
|
987 g_value_get_enum (gst_structure_get_value (structure, "cur_type")); |
|
988 if (start) |
|
989 *start = g_value_get_int64 (gst_structure_get_value (structure, "cur")); |
|
990 if (stop_type) |
|
991 *stop_type = |
|
992 g_value_get_enum (gst_structure_get_value (structure, "stop_type")); |
|
993 if (stop) |
|
994 *stop = g_value_get_int64 (gst_structure_get_value (structure, "stop")); |
|
995 } |
|
996 |
|
997 /** |
|
998 * gst_event_new_navigation: |
|
999 * @structure: description of the event |
|
1000 * |
|
1001 * Create a new navigation event from the given description. |
|
1002 * |
|
1003 * Returns: a new #GstEvent |
|
1004 */ |
|
1005 #ifdef __SYMBIAN32__ |
|
1006 EXPORT_C |
|
1007 #endif |
|
1008 |
|
1009 GstEvent * |
|
1010 gst_event_new_navigation (GstStructure * structure) |
|
1011 { |
|
1012 g_return_val_if_fail (structure != NULL, NULL); |
|
1013 |
|
1014 return gst_event_new_custom (GST_EVENT_NAVIGATION, structure); |
|
1015 } |
|
1016 |
|
1017 /** |
|
1018 * gst_event_new_latency: |
|
1019 * @latency: the new latency value |
|
1020 * |
|
1021 * Create a new latency event. The event is sent upstream from the sinks and |
|
1022 * notifies elements that they should add an additional @latency to the |
|
1023 * timestamps before synchronising against the clock. |
|
1024 * |
|
1025 * The latency is mostly used in live sinks and is always expressed in |
|
1026 * the time format. |
|
1027 * |
|
1028 * Returns: a new #GstEvent |
|
1029 * |
|
1030 * Since: 0.10.12 |
|
1031 */ |
|
1032 #ifdef __SYMBIAN32__ |
|
1033 EXPORT_C |
|
1034 #endif |
|
1035 |
|
1036 GstEvent * |
|
1037 gst_event_new_latency (GstClockTime latency) |
|
1038 { |
|
1039 GST_CAT_INFO (GST_CAT_EVENT, |
|
1040 "creating latency event %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); |
|
1041 |
|
1042 return gst_event_new_custom (GST_EVENT_LATENCY, |
|
1043 gst_structure_new ("GstEventLatency", |
|
1044 "latency", G_TYPE_UINT64, latency, NULL)); |
|
1045 } |
|
1046 |
|
1047 /** |
|
1048 * gst_event_parse_latency: |
|
1049 * @event: The event to query |
|
1050 * @latency: A pointer to store the latency in. |
|
1051 * |
|
1052 * Get the latency in the latency event. |
|
1053 * |
|
1054 * Since: 0.10.12 |
|
1055 */ |
|
1056 #ifdef __SYMBIAN32__ |
|
1057 EXPORT_C |
|
1058 #endif |
|
1059 |
|
1060 void |
|
1061 gst_event_parse_latency (GstEvent * event, GstClockTime * latency) |
|
1062 { |
|
1063 const GstStructure *structure; |
|
1064 |
|
1065 g_return_if_fail (GST_IS_EVENT (event)); |
|
1066 g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_LATENCY); |
|
1067 |
|
1068 structure = gst_event_get_structure (event); |
|
1069 if (latency) |
|
1070 *latency = |
|
1071 g_value_get_uint64 (gst_structure_get_value (structure, "latency")); |
|
1072 } |