buffer: fix resize function some more
[platform/upstream/gstreamer.git] / gst / gstmessage.c
1 /* GStreamer
2  * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
3  *
4  * gstmessage.c: GstMessage subsystem
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:gstmessage
24  * @short_description: Lightweight objects to signal the application of
25  *                     pipeline events
26  * @see_also: #GstBus, #GstMiniObject, #GstElement
27  *
28  * Messages are implemented as a subclass of #GstMiniObject with a generic
29  * #GstStructure as the content. This allows for writing custom messages without
30  * requiring an API change while allowing a wide range of different types
31  * of messages.
32  *
33  * Messages are posted by objects in the pipeline and are passed to the
34  * application using the #GstBus.
35
36  * The basic use pattern of posting a message on a #GstBus is as follows:
37  *
38  * <example>
39  * <title>Posting a #GstMessage</title>
40  *   <programlisting>
41  *    gst_bus_post (bus, gst_message_new_eos());
42  *   </programlisting>
43  * </example>
44  *
45  * A #GstElement usually posts messages on the bus provided by the parent
46  * container using gst_element_post_message().
47  *
48  * Last reviewed on 2005-11-09 (0.9.4)
49  */
50
51
52 #include "gst_private.h"
53 #include <string.h>             /* memcpy */
54 #include "gsterror.h"
55 #include "gstenumtypes.h"
56 #include "gstinfo.h"
57 #include "gstmessage.h"
58 #include "gsttaglist.h"
59 #include "gstutils.h"
60 #include "gstquark.h"
61
62
63 static GType _gst_message_type = 0;
64
65 typedef struct
66 {
67   GstMessage message;
68
69   GstStructure *structure;
70 } GstMessageImpl;
71
72 #define GST_MESSAGE_STRUCTURE(m) (((GstMessageImpl *)(m))->structure)
73
74 typedef struct
75 {
76   const gint type;
77   const gchar *name;
78   GQuark quark;
79 } GstMessageQuarks;
80
81 static GstMessageQuarks message_quarks[] = {
82   {GST_MESSAGE_UNKNOWN, "unknown", 0},
83   {GST_MESSAGE_EOS, "eos", 0},
84   {GST_MESSAGE_ERROR, "error", 0},
85   {GST_MESSAGE_WARNING, "warning", 0},
86   {GST_MESSAGE_INFO, "info", 0},
87   {GST_MESSAGE_TAG, "tag", 0},
88   {GST_MESSAGE_BUFFERING, "buffering", 0},
89   {GST_MESSAGE_STATE_CHANGED, "state-changed", 0},
90   {GST_MESSAGE_STATE_DIRTY, "state-dirty", 0},
91   {GST_MESSAGE_STEP_DONE, "step-done", 0},
92   {GST_MESSAGE_CLOCK_PROVIDE, "clock-provide", 0},
93   {GST_MESSAGE_CLOCK_LOST, "clock-lost", 0},
94   {GST_MESSAGE_NEW_CLOCK, "new-clock", 0},
95   {GST_MESSAGE_STRUCTURE_CHANGE, "structure-change", 0},
96   {GST_MESSAGE_STREAM_STATUS, "stream-status", 0},
97   {GST_MESSAGE_APPLICATION, "application", 0},
98   {GST_MESSAGE_ELEMENT, "element", 0},
99   {GST_MESSAGE_SEGMENT_START, "segment-start", 0},
100   {GST_MESSAGE_SEGMENT_DONE, "segment-done", 0},
101   {GST_MESSAGE_DURATION, "duration", 0},
102   {GST_MESSAGE_LATENCY, "latency", 0},
103   {GST_MESSAGE_ASYNC_START, "async-start", 0},
104   {GST_MESSAGE_ASYNC_DONE, "async-done", 0},
105   {GST_MESSAGE_REQUEST_STATE, "request-state", 0},
106   {GST_MESSAGE_STEP_START, "step-start", 0},
107   {GST_MESSAGE_QOS, "qos", 0},
108   {GST_MESSAGE_PROGRESS, "progress", 0},
109   {0, NULL, 0}
110 };
111
112 void
113 _gst_message_initialize (void)
114 {
115   gint i;
116
117   GST_CAT_INFO (GST_CAT_GST_INIT, "init messages");
118
119   /* the GstMiniObject types need to be class_ref'd once before it can be
120    * done from multiple threads;
121    * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
122   gst_message_get_type ();
123
124   for (i = 0; message_quarks[i].name; i++) {
125     message_quarks[i].quark =
126         g_quark_from_static_string (message_quarks[i].name);
127   }
128 }
129
130 /**
131  * gst_message_type_get_name:
132  * @type: the message type
133  *
134  * Get a printable name for the given message type. Do not modify or free.
135  *
136  * Returns: a reference to the static name of the message.
137  */
138 const gchar *
139 gst_message_type_get_name (GstMessageType type)
140 {
141   gint i;
142
143   for (i = 0; message_quarks[i].name; i++) {
144     if (type == message_quarks[i].type)
145       return message_quarks[i].name;
146   }
147   return "unknown";
148 }
149
150 /**
151  * gst_message_type_to_quark:
152  * @type: the message type
153  *
154  * Get the unique quark for the given message type.
155  *
156  * Returns: the quark associated with the message type
157  */
158 GQuark
159 gst_message_type_to_quark (GstMessageType type)
160 {
161   gint i;
162
163   for (i = 0; message_quarks[i].name; i++) {
164     if (type == message_quarks[i].type)
165       return message_quarks[i].quark;
166   }
167   return 0;
168 }
169
170 GType
171 gst_message_get_type (void)
172 {
173   if (G_UNLIKELY (_gst_message_type == 0)) {
174     _gst_message_type = gst_mini_object_register ("GstMessage");
175   }
176   return _gst_message_type;
177 }
178
179
180 static void
181 _gst_message_free (GstMessage * message)
182 {
183   GstStructure *structure;
184
185   g_return_if_fail (message != NULL);
186
187   GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p", message);
188
189   if (GST_MESSAGE_SRC (message)) {
190     gst_object_unref (GST_MESSAGE_SRC (message));
191     GST_MESSAGE_SRC (message) = NULL;
192   }
193
194   if (message->lock) {
195     GST_MESSAGE_LOCK (message);
196     GST_MESSAGE_SIGNAL (message);
197     GST_MESSAGE_UNLOCK (message);
198   }
199
200   structure = GST_MESSAGE_STRUCTURE (message);
201   if (structure) {
202     gst_structure_set_parent_refcount (structure, NULL);
203     gst_structure_free (structure);
204   }
205
206   g_slice_free1 (GST_MINI_OBJECT_SIZE (message), message);
207 }
208
209 static GstMessage *
210 _gst_message_copy (GstMessage * message)
211 {
212   GstMessageImpl *copy;
213   GstStructure *structure;
214
215   GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p", message);
216
217   copy = g_slice_new0 (GstMessageImpl);
218
219   gst_mini_object_init (GST_MINI_OBJECT_CAST (copy),
220       _gst_message_type, sizeof (GstMessageImpl));
221
222   copy->message.mini_object.copy =
223       (GstMiniObjectCopyFunction) _gst_message_copy;
224   copy->message.mini_object.free =
225       (GstMiniObjectFreeFunction) _gst_message_free;
226
227   GST_MESSAGE_TYPE (copy) = GST_MESSAGE_TYPE (message);
228   GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
229   GST_MESSAGE_SEQNUM (copy) = GST_MESSAGE_SEQNUM (message);
230   if (GST_MESSAGE_SRC (message)) {
231     GST_MESSAGE_SRC (copy) = gst_object_ref (GST_MESSAGE_SRC (message));
232   }
233
234   GST_MESSAGE_GET_LOCK (copy) = GST_MESSAGE_GET_LOCK (message);
235   GST_MESSAGE_COND (copy) = GST_MESSAGE_COND (message);
236
237   structure = GST_MESSAGE_STRUCTURE (message);
238   if (structure) {
239     copy->structure = gst_structure_copy (structure);
240     gst_structure_set_parent_refcount (copy->structure,
241         &copy->message.mini_object.refcount);
242   }
243
244   return GST_MESSAGE_CAST (copy);
245 }
246
247 /**
248  * gst_message_new_custom:
249  * @type: The #GstMessageType to distinguish messages
250  * @src: The object originating the message.
251  * @structure: (transfer full): the structure for the message. The message
252  *     will take ownership of the structure.
253  *
254  * Create a new custom-typed message. This can be used for anything not
255  * handled by other message-specific functions to pass a message to the
256  * app. The structure field can be NULL.
257  *
258  * Returns: (transfer full): The new message.
259  *
260  * MT safe.
261  */
262 GstMessage *
263 gst_message_new_custom (GstMessageType type, GstObject * src,
264     GstStructure * structure)
265 {
266   GstMessageImpl *message;
267
268   message = g_slice_new0 (GstMessageImpl);
269
270   gst_mini_object_init (GST_MINI_OBJECT_CAST (message),
271       _gst_message_type, sizeof (GstMessageImpl));
272
273   message->message.mini_object.copy =
274       (GstMiniObjectCopyFunction) _gst_message_copy;
275   message->message.mini_object.free =
276       (GstMiniObjectFreeFunction) _gst_message_free;
277
278   GST_CAT_LOG (GST_CAT_MESSAGE, "source %s: creating new message %p %s",
279       (src ? GST_OBJECT_NAME (src) : "NULL"), message,
280       gst_message_type_get_name (type));
281
282   GST_MESSAGE_TYPE (message) = type;
283   if (src)
284     gst_object_ref (src);
285   GST_MESSAGE_SRC (message) = src;
286   GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
287   GST_MESSAGE_SEQNUM (message) = gst_util_seqnum_next ();
288
289   if (structure) {
290     gst_structure_set_parent_refcount (structure,
291         &message->message.mini_object.refcount);
292   }
293   message->structure = structure;
294
295   return GST_MESSAGE_CAST (message);
296 }
297
298 /**
299  * gst_message_get_seqnum:
300  * @message: A #GstMessage.
301  *
302  * Retrieve the sequence number of a message.
303  *
304  * Messages have ever-incrementing sequence numbers, which may also be set
305  * explicitly via gst_message_set_seqnum(). Sequence numbers are typically used
306  * to indicate that a message corresponds to some other set of messages or
307  * events, for example a SEGMENT_DONE message corresponding to a SEEK event. It
308  * is considered good practice to make this correspondence when possible, though
309  * it is not required.
310  *
311  * Note that events and messages share the same sequence number incrementor;
312  * two events or messages will never not have the same sequence number unless
313  * that correspondence was made explicitly.
314  *
315  * Returns: The message's sequence number.
316  *
317  * MT safe.
318  *
319  * Since: 0.10.22
320  */
321 guint32
322 gst_message_get_seqnum (GstMessage * message)
323 {
324   g_return_val_if_fail (GST_IS_MESSAGE (message), -1);
325
326   return GST_MESSAGE_SEQNUM (message);
327 }
328
329 /**
330  * gst_message_set_seqnum:
331  * @message: A #GstMessage.
332  * @seqnum: A sequence number.
333  *
334  * Set the sequence number of a message.
335  *
336  * This function might be called by the creator of a message to indicate that
337  * the message relates to other messages or events. See gst_message_get_seqnum()
338  * for more information.
339  *
340  * MT safe.
341  *
342  * Since: 0.10.22
343  */
344 void
345 gst_message_set_seqnum (GstMessage * message, guint32 seqnum)
346 {
347   g_return_if_fail (GST_IS_MESSAGE (message));
348
349   GST_MESSAGE_SEQNUM (message) = seqnum;
350 }
351
352 /**
353  * gst_message_new_eos:
354  * @src: (transfer none): The object originating the message.
355  *
356  * Create a new eos message. This message is generated and posted in
357  * the sink elements of a GstBin. The bin will only forward the EOS
358  * message to the application if all sinks have posted an EOS message.
359  *
360  * Returns: (transfer full): The new eos message.
361  *
362  * MT safe.
363  */
364 GstMessage *
365 gst_message_new_eos (GstObject * src)
366 {
367   GstMessage *message;
368
369   message = gst_message_new_custom (GST_MESSAGE_EOS, src, NULL);
370
371   return message;
372 }
373
374 /**
375  * gst_message_new_error:
376  * @src: (transfer none): The object originating the message.
377  * @error: (transfer none): The GError for this message.
378  * @debug: A debugging string.
379  *
380  * Create a new error message. The message will copy @error and
381  * @debug. This message is posted by element when a fatal event
382  * occured. The pipeline will probably (partially) stop. The application
383  * receiving this message should stop the pipeline.
384  *
385  * Returns: (transfer full): the new error message.
386  *
387  * MT safe.
388  */
389 GstMessage *
390 gst_message_new_error (GstObject * src, GError * error, const gchar * debug)
391 {
392   GstMessage *message;
393   GstStructure *structure;
394
395   structure = gst_structure_id_new (GST_QUARK (MESSAGE_ERROR),
396       GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
397       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
398   message = gst_message_new_custom (GST_MESSAGE_ERROR, src, structure);
399
400   return message;
401 }
402
403 /**
404  * gst_message_new_warning:
405  * @src: (transfer none): The object originating the message.
406  * @error: (transfer none): The GError for this message.
407  * @debug: A debugging string.
408  *
409  * Create a new warning message. The message will make copies of @error and
410  * @debug.
411  *
412  * Returns: (transfer full): The new warning message.
413  *
414  * MT safe.
415  */
416 GstMessage *
417 gst_message_new_warning (GstObject * src, GError * error, const gchar * debug)
418 {
419   GstMessage *message;
420   GstStructure *structure;
421
422   structure = gst_structure_id_new (GST_QUARK (MESSAGE_WARNING),
423       GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
424       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
425   message = gst_message_new_custom (GST_MESSAGE_WARNING, src, structure);
426
427   return message;
428 }
429
430 /**
431  * gst_message_new_info:
432  * @src: (transfer none): The object originating the message.
433  * @error: (transfer none): The GError for this message.
434  * @debug: A debugging string.
435  *
436  * Create a new info message. The message will make copies of @error and
437  * @debug.
438  *
439  * MT safe.
440  *
441  * Returns: (transfer full): the new info message.
442  *
443  * Since: 0.10.12
444  */
445 GstMessage *
446 gst_message_new_info (GstObject * src, GError * error, const gchar * debug)
447 {
448   GstMessage *message;
449   GstStructure *structure;
450
451   structure = gst_structure_id_new (GST_QUARK (MESSAGE_INFO),
452       GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
453       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
454   message = gst_message_new_custom (GST_MESSAGE_INFO, src, structure);
455
456   return message;
457 }
458
459 /**
460  * gst_message_new_tag:
461  * @src: (transfer none): The object originating the message.
462  * @tag_list: (transfer full): the tag list for the message.
463  *
464  * Create a new tag message. The message will take ownership of the tag list.
465  * The message is posted by elements that discovered a new taglist.
466  *
467  * Returns: (transfer full): the new tag message.
468  *
469  * MT safe.
470  */
471 GstMessage *
472 gst_message_new_tag (GstObject * src, GstTagList * tag_list)
473 {
474   GstMessage *message;
475
476   g_return_val_if_fail (GST_IS_STRUCTURE (tag_list), NULL);
477
478   message =
479       gst_message_new_custom (GST_MESSAGE_TAG, src, (GstStructure *) tag_list);
480
481   return message;
482 }
483
484 /**
485  * gst_message_new_buffering:
486  * @src: (transfer none): The object originating the message.
487  * @percent: The buffering percent
488  *
489  * Create a new buffering message. This message can be posted by an element that
490  * needs to buffer data before it can continue processing. @percent should be a
491  * value between 0 and 100. A value of 100 means that the buffering completed.
492  *
493  * When @percent is < 100 the application should PAUSE a PLAYING pipeline. When
494  * @percent is 100, the application can set the pipeline (back) to PLAYING.
495  * The application must be prepared to receive BUFFERING messages in the
496  * PREROLLING state and may only set the pipeline to PLAYING after receiving a
497  * message with @percent set to 100, which can happen after the pipeline
498  * completed prerolling. 
499  *
500  * MT safe.
501  *
502  * Returns: (transfer full): The new buffering message.
503  *
504  * Since: 0.10.11
505  */
506 GstMessage *
507 gst_message_new_buffering (GstObject * src, gint percent)
508 {
509   GstMessage *message;
510   GstStructure *structure;
511
512   g_return_val_if_fail (percent >= 0 && percent <= 100, NULL);
513
514   structure = gst_structure_id_new (GST_QUARK (MESSAGE_BUFFERING),
515       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent,
516       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
517       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
518       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
519       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
520       GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
521   message = gst_message_new_custom (GST_MESSAGE_BUFFERING, src, structure);
522
523   return message;
524 }
525
526 /**
527  * gst_message_new_state_changed:
528  * @src: (transfer none): the object originating the message
529  * @oldstate: the previous state
530  * @newstate: the new (current) state
531  * @pending: the pending (target) state
532  *
533  * Create a state change message. This message is posted whenever an element
534  * changed its state.
535  *
536  * Returns: (transfer full): the new state change message.
537  *
538  * MT safe.
539  */
540 GstMessage *
541 gst_message_new_state_changed (GstObject * src,
542     GstState oldstate, GstState newstate, GstState pending)
543 {
544   GstMessage *message;
545   GstStructure *structure;
546
547   structure = gst_structure_id_new (GST_QUARK (MESSAGE_STATE),
548       GST_QUARK (OLD_STATE), GST_TYPE_STATE, (gint) oldstate,
549       GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) newstate,
550       GST_QUARK (PENDING_STATE), GST_TYPE_STATE, (gint) pending, NULL);
551   message = gst_message_new_custom (GST_MESSAGE_STATE_CHANGED, src, structure);
552
553   return message;
554 }
555
556 /**
557  * gst_message_new_state_dirty:
558  * @src: (transfer none): the object originating the message
559  *
560  * Create a state dirty message. This message is posted whenever an element
561  * changed its state asynchronously and is used internally to update the
562  * states of container objects.
563  *
564  * Returns: (transfer full): the new state dirty message.
565  *
566  * MT safe.
567  */
568 GstMessage *
569 gst_message_new_state_dirty (GstObject * src)
570 {
571   GstMessage *message;
572
573   message = gst_message_new_custom (GST_MESSAGE_STATE_DIRTY, src, NULL);
574
575   return message;
576 }
577
578 /**
579  * gst_message_new_clock_provide:
580  * @src: (transfer none): the object originating the message.
581  * @clock: (transfer none): the clock it provides
582  * @ready: TRUE if the sender can provide a clock
583  *
584  * Create a clock provide message. This message is posted whenever an
585  * element is ready to provide a clock or lost its ability to provide
586  * a clock (maybe because it paused or became EOS).
587  *
588  * This message is mainly used internally to manage the clock
589  * selection.
590  *
591  * Returns: (transfer full): the new provide clock message.
592  *
593  * MT safe.
594  */
595 GstMessage *
596 gst_message_new_clock_provide (GstObject * src, GstClock * clock,
597     gboolean ready)
598 {
599   GstMessage *message;
600   GstStructure *structure;
601
602   structure = gst_structure_id_new (GST_QUARK (MESSAGE_CLOCK_PROVIDE),
603       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock,
604       GST_QUARK (READY), G_TYPE_BOOLEAN, ready, NULL);
605   message = gst_message_new_custom (GST_MESSAGE_CLOCK_PROVIDE, src, structure);
606
607   return message;
608 }
609
610 /**
611  * gst_message_new_clock_lost:
612  * @src: (transfer none): the object originating the message.
613  * @clock: (transfer none): the clock that was lost
614  *
615  * Create a clock lost message. This message is posted whenever the
616  * clock is not valid anymore.
617  *
618  * If this message is posted by the pipeline, the pipeline will
619  * select a new clock again when it goes to PLAYING. It might therefore
620  * be needed to set the pipeline to PAUSED and PLAYING again.
621  *
622  * Returns: (transfer full): The new clock lost message.
623  *
624  * MT safe.
625  */
626 GstMessage *
627 gst_message_new_clock_lost (GstObject * src, GstClock * clock)
628 {
629   GstMessage *message;
630   GstStructure *structure;
631
632   structure = gst_structure_id_new (GST_QUARK (MESSAGE_CLOCK_LOST),
633       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
634   message = gst_message_new_custom (GST_MESSAGE_CLOCK_LOST, src, structure);
635
636   return message;
637 }
638
639 /**
640  * gst_message_new_new_clock:
641  * @src: (transfer none): The object originating the message.
642  * @clock: (transfer none): the new selected clock
643  *
644  * Create a new clock message. This message is posted whenever the
645  * pipeline selectes a new clock for the pipeline.
646  *
647  * Returns: (transfer full): The new new clock message.
648  *
649  * MT safe.
650  */
651 GstMessage *
652 gst_message_new_new_clock (GstObject * src, GstClock * clock)
653 {
654   GstMessage *message;
655   GstStructure *structure;
656
657   structure = gst_structure_id_new (GST_QUARK (MESSAGE_NEW_CLOCK),
658       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
659   message = gst_message_new_custom (GST_MESSAGE_NEW_CLOCK, src, structure);
660
661   return message;
662 }
663
664 /**
665  * gst_message_new_structure_change:
666  * @src: (transfer none): The object originating the message.
667  * @type: The change type.
668  * @owner: (transfer none): The owner element of @src.
669  * @busy: Whether the structure change is busy.
670  *
671  * Create a new structure change message. This message is posted when the
672  * structure of a pipeline is in the process of being changed, for example
673  * when pads are linked or unlinked.
674  *
675  * @src should be the sinkpad that unlinked or linked.
676  *
677  * Returns: (transfer full): the new structure change message.
678  *
679  * MT safe.
680  *
681  * Since: 0.10.22.
682  */
683 GstMessage *
684 gst_message_new_structure_change (GstObject * src, GstStructureChangeType type,
685     GstElement * owner, gboolean busy)
686 {
687   GstMessage *message;
688   GstStructure *structure;
689
690   g_return_val_if_fail (GST_IS_PAD (src), NULL);
691   /* g_return_val_if_fail (GST_PAD_DIRECTION (src) == GST_PAD_SINK, NULL); */
692   g_return_val_if_fail (GST_IS_ELEMENT (owner), NULL);
693
694   structure = gst_structure_id_new (GST_QUARK (MESSAGE_STRUCTURE_CHANGE),
695       GST_QUARK (TYPE), GST_TYPE_STRUCTURE_CHANGE_TYPE, type,
696       GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner,
697       GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy, NULL);
698
699   message = gst_message_new_custom (GST_MESSAGE_STRUCTURE_CHANGE, src,
700       structure);
701
702   return message;
703 }
704
705 /**
706  * gst_message_new_segment_start:
707  * @src: (transfer none): The object originating the message.
708  * @format: The format of the position being played
709  * @position: The position of the segment being played
710  *
711  * Create a new segment message. This message is posted by elements that
712  * start playback of a segment as a result of a segment seek. This message
713  * is not received by the application but is used for maintenance reasons in
714  * container elements.
715  *
716  * Returns: (transfer full): the new segment start message.
717  *
718  * MT safe.
719  */
720 GstMessage *
721 gst_message_new_segment_start (GstObject * src, GstFormat format,
722     gint64 position)
723 {
724   GstMessage *message;
725   GstStructure *structure;
726
727   structure = gst_structure_id_new (GST_QUARK (MESSAGE_SEGMENT_START),
728       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
729       GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
730   message = gst_message_new_custom (GST_MESSAGE_SEGMENT_START, src, structure);
731
732   return message;
733 }
734
735 /**
736  * gst_message_new_segment_done:
737  * @src: (transfer none): the object originating the message.
738  * @format: The format of the position being done
739  * @position: The position of the segment being done
740  *
741  * Create a new segment done message. This message is posted by elements that
742  * finish playback of a segment as a result of a segment seek. This message
743  * is received by the application after all elements that posted a segment_start
744  * have posted the segment_done.
745  *
746  * Returns: (transfer full): the new segment done message.
747  *
748  * MT safe.
749  */
750 GstMessage *
751 gst_message_new_segment_done (GstObject * src, GstFormat format,
752     gint64 position)
753 {
754   GstMessage *message;
755   GstStructure *structure;
756
757   structure = gst_structure_id_new (GST_QUARK (MESSAGE_SEGMENT_DONE),
758       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
759       GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
760   message = gst_message_new_custom (GST_MESSAGE_SEGMENT_DONE, src, structure);
761
762   return message;
763 }
764
765 /**
766  * gst_message_new_application:
767  * @src: (transfer none): the object originating the message.
768  * @structure: (transfer full): the structure for the message. The message
769  *     will take ownership of the structure.
770  *
771  * Create a new application-typed message. GStreamer will never create these
772  * messages; they are a gift from us to you. Enjoy.
773  *
774  * Returns: (transfer full): The new application message.
775  *
776  * MT safe.
777  */
778 GstMessage *
779 gst_message_new_application (GstObject * src, GstStructure * structure)
780 {
781   return gst_message_new_custom (GST_MESSAGE_APPLICATION, src, structure);
782 }
783
784 /**
785  * gst_message_new_element:
786  * @src: (transfer none): The object originating the message.
787  * @structure: (transfer full): The structure for the message. The message
788  *     will take ownership of the structure.
789  *
790  * Create a new element-specific message. This is meant as a generic way of
791  * allowing one-way communication from an element to an application, for example
792  * "the firewire cable was unplugged". The format of the message should be
793  * documented in the element's documentation. The structure field can be NULL.
794  *
795  * Returns: (transfer full): The new element message.
796  *
797  * MT safe.
798  */
799 GstMessage *
800 gst_message_new_element (GstObject * src, GstStructure * structure)
801 {
802   return gst_message_new_custom (GST_MESSAGE_ELEMENT, src, structure);
803 }
804
805 /**
806  * gst_message_new_duration:
807  * @src: (transfer none): The object originating the message.
808  * @format: The format of the duration
809  * @duration: The new duration 
810  *
811  * Create a new duration message. This message is posted by elements that
812  * know the duration of a stream in a specific format. This message
813  * is received by bins and is used to calculate the total duration of a
814  * pipeline. Elements may post a duration message with a duration of
815  * GST_CLOCK_TIME_NONE to indicate that the duration has changed and the 
816  * cached duration should be discarded. The new duration can then be 
817  * retrieved via a query.
818  *
819  * Returns: (transfer full): The new duration message.
820  *
821  * MT safe.
822  */
823 GstMessage *
824 gst_message_new_duration (GstObject * src, GstFormat format, gint64 duration)
825 {
826   GstMessage *message;
827   GstStructure *structure;
828
829   structure = gst_structure_id_new (GST_QUARK (MESSAGE_DURATION),
830       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
831       GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL);
832   message = gst_message_new_custom (GST_MESSAGE_DURATION, src, structure);
833
834   return message;
835 }
836
837 /**
838  * gst_message_new_async_start:
839  * @src: (transfer none): The object originating the message.
840  *
841  * This message is posted by elements when they start an ASYNC state change.
842  *
843  * Returns: (transfer full): The new async_start message.
844  *
845  * MT safe.
846  */
847 GstMessage *
848 gst_message_new_async_start (GstObject * src)
849 {
850   GstMessage *message;
851
852   message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src, NULL);
853
854   return message;
855 }
856
857 /**
858  * gst_message_new_async_done:
859  * @src: (transfer none): The object originating the message.
860  * @reset_time: if the running_time should be reset
861  *
862  * The message is posted when elements completed an ASYNC state change.
863  * @reset_time is set to TRUE when the element requests a new running_time
864  * before going to PLAYING.
865  *
866  * Returns: (transfer full): The new async_done message.
867  *
868  * MT safe.
869  */
870 GstMessage *
871 gst_message_new_async_done (GstObject * src, gboolean reset_time)
872 {
873   GstMessage *message;
874   GstStructure *structure;
875
876   structure = gst_structure_id_new (GST_QUARK (MESSAGE_ASYNC_DONE),
877       GST_QUARK (RESET_TIME), G_TYPE_BOOLEAN, reset_time, NULL);
878   message = gst_message_new_custom (GST_MESSAGE_ASYNC_DONE, src, structure);
879
880   return message;
881 }
882
883 /**
884  * gst_message_new_latency:
885  * @src: (transfer none): The object originating the message.
886  *
887  * This message can be posted by elements when their latency requirements have
888  * changed.
889  *
890  * Returns: (transfer full): The new latency message.
891  *
892  * MT safe.
893  *
894  * Since: 0.10.12
895  */
896 GstMessage *
897 gst_message_new_latency (GstObject * src)
898 {
899   GstMessage *message;
900
901   message = gst_message_new_custom (GST_MESSAGE_LATENCY, src, NULL);
902
903   return message;
904 }
905
906 /**
907  * gst_message_new_request_state:
908  * @src: (transfer none): the object originating the message.
909  * @state: The new requested state
910  *
911  * This message can be posted by elements when they want to have their state
912  * changed. A typical use case would be an audio server that wants to pause the
913  * pipeline because a higher priority stream is being played.
914  *
915  * Returns: (transfer full): the new requst state message.
916  *
917  * MT safe.
918  *
919  * Since: 0.10.23
920  */
921 GstMessage *
922 gst_message_new_request_state (GstObject * src, GstState state)
923 {
924   GstMessage *message;
925   GstStructure *structure;
926
927   structure = gst_structure_id_new (GST_QUARK (MESSAGE_REQUEST_STATE),
928       GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) state, NULL);
929   message = gst_message_new_custom (GST_MESSAGE_REQUEST_STATE, src, structure);
930
931   return message;
932 }
933
934 /**
935  * gst_message_get_structure:
936  * @message: The #GstMessage.
937  *
938  * Access the structure of the message.
939  *
940  * Returns: (transfer none): The structure of the message. The structure is
941  * still owned by the message, which means that you should not free it and
942  * that the pointer becomes invalid when you free the message.
943  *
944  * MT safe.
945  */
946 const GstStructure *
947 gst_message_get_structure (GstMessage * message)
948 {
949   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
950
951   return GST_MESSAGE_STRUCTURE (message);
952 }
953
954 /**
955  * gst_message_has_name:
956  * @message: The #GstMessage.
957  * @name: name to check
958  *
959  * Checks if @message has the given @name. This function is usually used to
960  * check the name of a custom message.
961  *
962  * Returns: %TRUE if @name matches the name of the message structure.
963  *
964  * Since: 0.10.20
965  */
966 gboolean
967 gst_message_has_name (GstMessage * message, const gchar * name)
968 {
969   GstStructure *structure;
970
971   g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
972
973   structure = GST_MESSAGE_STRUCTURE (message);
974   if (structure == NULL)
975     return FALSE;
976
977   return gst_structure_has_name (structure, name);
978 }
979
980 /**
981  * gst_message_parse_tag:
982  * @message: A valid #GstMessage of type GST_MESSAGE_TAG.
983  * @tag_list: (out callee-allocates): return location for the tag-list.
984  *
985  * Extracts the tag list from the GstMessage. The tag list returned in the
986  * output argument is a copy; the caller must free it when done.
987  *
988  * Typical usage of this function might be:
989  * |[
990  *   ...
991  *   switch (GST_MESSAGE_TYPE (msg)) {
992  *     case GST_MESSAGE_TAG: {
993  *       GstTagList *tags = NULL;
994  *       
995  *       gst_message_parse_tag (msg, &amp;tags);
996  *       g_print ("Got tags from element %s\n", GST_OBJECT_NAME (msg->src));
997  *       handle_tags (tags);
998  *       gst_tag_list_free (tags);
999  *       break;
1000  *     }
1001  *     ...
1002  *   }
1003  *   ...
1004  * ]|
1005  *
1006  * MT safe.
1007  */
1008 void
1009 gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list)
1010 {
1011   GstStructure *ret;
1012
1013   g_return_if_fail (GST_IS_MESSAGE (message));
1014   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
1015   g_return_if_fail (tag_list != NULL);
1016
1017   ret = gst_structure_copy (GST_MESSAGE_STRUCTURE (message));
1018   gst_structure_remove_field (ret, "source-pad");
1019
1020   *tag_list = (GstTagList *) ret;
1021 }
1022
1023 /**
1024  * gst_message_parse_buffering:
1025  * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
1026  * @percent: (out) (allow-none): Return location for the percent.
1027  *
1028  * Extracts the buffering percent from the GstMessage. see also
1029  * gst_message_new_buffering().
1030  *
1031  * MT safe.
1032  *
1033  * Since: 0.10.11
1034  */
1035 void
1036 gst_message_parse_buffering (GstMessage * message, gint * percent)
1037 {
1038   g_return_if_fail (GST_IS_MESSAGE (message));
1039   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1040
1041   if (percent)
1042     *percent =
1043         g_value_get_int (gst_structure_id_get_value (GST_MESSAGE_STRUCTURE
1044             (message), GST_QUARK (BUFFER_PERCENT)));
1045 }
1046
1047 /**
1048  * gst_message_set_buffering_stats:
1049  * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
1050  * @mode: a buffering mode 
1051  * @avg_in: the average input rate
1052  * @avg_out: the average output rate
1053  * @buffering_left: amount of buffering time left in milliseconds
1054  *
1055  * Configures the buffering stats values in @message.
1056  *
1057  * Since: 0.10.20
1058  */
1059 void
1060 gst_message_set_buffering_stats (GstMessage * message, GstBufferingMode mode,
1061     gint avg_in, gint avg_out, gint64 buffering_left)
1062 {
1063   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1064
1065   gst_structure_id_set (GST_MESSAGE_STRUCTURE (message),
1066       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
1067       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
1068       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
1069       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
1070 }
1071
1072 /**
1073  * gst_message_parse_buffering_stats:
1074  * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
1075  * @mode: (out) (allow-none): a buffering mode, or NULL
1076  * @avg_in: (out) (allow-none): the average input rate, or NULL
1077  * @avg_out: (out) (allow-none): the average output rate, or NULL
1078  * @buffering_left: (out) (allow-none): amount of buffering time left in
1079  *     milliseconds, or NULL
1080  *
1081  * Extracts the buffering stats values from @message.
1082  *
1083  * Since: 0.10.20
1084  */
1085 void
1086 gst_message_parse_buffering_stats (GstMessage * message,
1087     GstBufferingMode * mode, gint * avg_in, gint * avg_out,
1088     gint64 * buffering_left)
1089 {
1090   GstStructure *structure;
1091
1092   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1093
1094   structure = GST_MESSAGE_STRUCTURE (message);
1095   if (mode)
1096     *mode = g_value_get_enum (gst_structure_id_get_value (structure,
1097             GST_QUARK (BUFFERING_MODE)));
1098   if (avg_in)
1099     *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
1100             GST_QUARK (AVG_IN_RATE)));
1101   if (avg_out)
1102     *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
1103             GST_QUARK (AVG_OUT_RATE)));
1104   if (buffering_left)
1105     *buffering_left =
1106         g_value_get_int64 (gst_structure_id_get_value (structure,
1107             GST_QUARK (BUFFERING_LEFT)));
1108 }
1109
1110 /**
1111  * gst_message_parse_state_changed:
1112  * @message: a valid #GstMessage of type GST_MESSAGE_STATE_CHANGED
1113  * @oldstate: (out) (allow-none): the previous state, or NULL
1114  * @newstate: (out) (allow-none): the new (current) state, or NULL
1115  * @pending: (out) (allow-none): the pending (target) state, or NULL
1116  *
1117  * Extracts the old and new states from the GstMessage.
1118  *
1119  * Typical usage of this function might be:
1120  * |[
1121  *   ...
1122  *   switch (GST_MESSAGE_TYPE (msg)) {
1123  *     case GST_MESSAGE_STATE_CHANGED: {
1124  *       GstState old_state, new_state;
1125  *       
1126  *       gst_message_parse_state_changed (msg, &amp;old_state, &amp;new_state, NULL);
1127  *       g_print ("Element %s changed state from %s to %s.\n",
1128  *           GST_OBJECT_NAME (msg->src),
1129  *           gst_element_state_get_name (old_state),
1130  *           gst_element_state_get_name (new_state));
1131  *       break;
1132  *     }
1133  *     ...
1134  *   }
1135  *   ...
1136  * ]|
1137  *
1138  * MT safe.
1139  */
1140 void
1141 gst_message_parse_state_changed (GstMessage * message,
1142     GstState * oldstate, GstState * newstate, GstState * pending)
1143 {
1144   GstStructure *structure;
1145
1146   g_return_if_fail (GST_IS_MESSAGE (message));
1147   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STATE_CHANGED);
1148
1149   structure = GST_MESSAGE_STRUCTURE (message);
1150   if (oldstate)
1151     *oldstate =
1152         g_value_get_enum (gst_structure_id_get_value (structure,
1153             GST_QUARK (OLD_STATE)));
1154   if (newstate)
1155     *newstate =
1156         g_value_get_enum (gst_structure_id_get_value (structure,
1157             GST_QUARK (NEW_STATE)));
1158   if (pending)
1159     *pending = g_value_get_enum (gst_structure_id_get_value (structure,
1160             GST_QUARK (PENDING_STATE)));
1161 }
1162
1163 /**
1164  * gst_message_parse_clock_provide:
1165  * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_PROVIDE.
1166  * @clock: (out) (allow-none) (transfer none): a pointer to  hold a clock
1167  *     object, or NULL
1168  * @ready: (out) (allow-none): a pointer to hold the ready flag, or NULL
1169  *
1170  * Extracts the clock and ready flag from the GstMessage.
1171  * The clock object returned remains valid until the message is freed.
1172  *
1173  * MT safe.
1174  */
1175 void
1176 gst_message_parse_clock_provide (GstMessage * message, GstClock ** clock,
1177     gboolean * ready)
1178 {
1179   const GValue *clock_gvalue;
1180   GstStructure *structure;
1181
1182   g_return_if_fail (GST_IS_MESSAGE (message));
1183   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_PROVIDE);
1184
1185   structure = GST_MESSAGE_STRUCTURE (message);
1186   clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
1187   g_return_if_fail (clock_gvalue != NULL);
1188   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1189
1190   if (ready)
1191     *ready =
1192         g_value_get_boolean (gst_structure_id_get_value (structure,
1193             GST_QUARK (READY)));
1194   if (clock)
1195     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1196 }
1197
1198 /**
1199  * gst_message_parse_clock_lost:
1200  * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_LOST.
1201  * @clock: (out) (allow-none) (transfer none): a pointer to hold the lost clock
1202  *
1203  * Extracts the lost clock from the GstMessage.
1204  * The clock object returned remains valid until the message is freed.
1205  *
1206  * MT safe.
1207  */
1208 void
1209 gst_message_parse_clock_lost (GstMessage * message, GstClock ** clock)
1210 {
1211   const GValue *clock_gvalue;
1212   GstStructure *structure;
1213
1214   g_return_if_fail (GST_IS_MESSAGE (message));
1215   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_LOST);
1216
1217   structure = GST_MESSAGE_STRUCTURE (message);
1218   clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
1219   g_return_if_fail (clock_gvalue != NULL);
1220   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1221
1222   if (clock)
1223     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1224 }
1225
1226 /**
1227  * gst_message_parse_new_clock:
1228  * @message: A valid #GstMessage of type GST_MESSAGE_NEW_CLOCK.
1229  * @clock: (out) (allow-none) (transfer none): a pointer to hold the selected
1230  *     new clock
1231  *
1232  * Extracts the new clock from the GstMessage.
1233  * The clock object returned remains valid until the message is freed.
1234  *
1235  * MT safe.
1236  */
1237 void
1238 gst_message_parse_new_clock (GstMessage * message, GstClock ** clock)
1239 {
1240   const GValue *clock_gvalue;
1241   GstStructure *structure;
1242
1243   g_return_if_fail (GST_IS_MESSAGE (message));
1244   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEW_CLOCK);
1245
1246   structure = GST_MESSAGE_STRUCTURE (message);
1247   clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
1248   g_return_if_fail (clock_gvalue != NULL);
1249   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1250
1251   if (clock)
1252     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1253 }
1254
1255 /**
1256  * gst_message_parse_structure_change:
1257  * @message: A valid #GstMessage of type GST_MESSAGE_STRUCTURE_CHANGE.
1258  * @type: (out): A pointer to hold the change type
1259  * @owner: (out) (allow-none) (transfer none): The owner element of the
1260  *     message source
1261  * @busy: (out) (allow-none): a pointer to hold whether the change is in
1262  *     progress or has been completed
1263  *
1264  * Extracts the change type and completion status from the GstMessage.
1265  *
1266  * MT safe.
1267  *
1268  * Since: 0.10.22
1269  */
1270 void
1271 gst_message_parse_structure_change (GstMessage * message,
1272     GstStructureChangeType * type, GstElement ** owner, gboolean * busy)
1273 {
1274   const GValue *owner_gvalue;
1275   GstStructure *structure;
1276
1277   g_return_if_fail (GST_IS_MESSAGE (message));
1278   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STRUCTURE_CHANGE);
1279
1280   structure = GST_MESSAGE_STRUCTURE (message);
1281   owner_gvalue = gst_structure_id_get_value (structure, GST_QUARK (OWNER));
1282   g_return_if_fail (owner_gvalue != NULL);
1283   g_return_if_fail (G_VALUE_TYPE (owner_gvalue) == GST_TYPE_ELEMENT);
1284
1285   if (type)
1286     *type = g_value_get_enum (gst_structure_id_get_value (structure,
1287             GST_QUARK (TYPE)));
1288   if (owner)
1289     *owner = (GstElement *) g_value_get_object (owner_gvalue);
1290   if (busy)
1291     *busy =
1292         g_value_get_boolean (gst_structure_id_get_value (structure,
1293             GST_QUARK (BUSY)));
1294 }
1295
1296 /**
1297  * gst_message_parse_error:
1298  * @message: A valid #GstMessage of type GST_MESSAGE_ERROR.
1299  * @gerror: (out) (allow-none) (transfer full): location for the GError
1300  * @debug: (out) (allow-none) (transfer full): location for the debug message,
1301  *     or NULL
1302  *
1303  * Extracts the GError and debug string from the GstMessage. The values returned
1304  * in the output arguments are copies; the caller must free them when done.
1305  *
1306  * Typical usage of this function might be:
1307  * |[
1308  *   ...
1309  *   switch (GST_MESSAGE_TYPE (msg)) {
1310  *     case GST_MESSAGE_ERROR: {
1311  *       GError *err = NULL;
1312  *       gchar *dbg_info = NULL;
1313  *       
1314  *       gst_message_parse_error (msg, &amp;err, &amp;dbg_info);
1315  *       g_printerr ("ERROR from element %s: %s\n",
1316  *           GST_OBJECT_NAME (msg->src), err->message);
1317  *       g_printerr ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
1318  *       g_error_free (err);
1319  *       g_free (dbg_info);
1320  *       break;
1321  *     }
1322  *     ...
1323  *   }
1324  *   ...
1325  * ]|
1326  *
1327  * MT safe.
1328  */
1329 void
1330 gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug)
1331 {
1332   const GValue *error_gvalue;
1333   GError *error_val;
1334   GstStructure *structure;
1335
1336   g_return_if_fail (GST_IS_MESSAGE (message));
1337   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
1338
1339   structure = GST_MESSAGE_STRUCTURE (message);
1340   error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR));
1341   g_return_if_fail (error_gvalue != NULL);
1342   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
1343
1344   error_val = (GError *) g_value_get_boxed (error_gvalue);
1345   if (error_val)
1346     *gerror = g_error_copy (error_val);
1347   else
1348     *gerror = NULL;
1349
1350   if (debug)
1351     *debug =
1352         g_value_dup_string (gst_structure_id_get_value (structure,
1353             GST_QUARK (DEBUG)));
1354 }
1355
1356 /**
1357  * gst_message_parse_warning:
1358  * @message: A valid #GstMessage of type GST_MESSAGE_WARNING.
1359  * @gerror: (out) (allow-none) (transfer full): location for the GError
1360  * @debug: (out) (allow-none) (transfer full): location for the debug message,
1361  *     or NULL
1362  *
1363  * Extracts the GError and debug string from the GstMessage. The values returned
1364  * in the output arguments are copies; the caller must free them when done.
1365  *
1366  * MT safe.
1367  */
1368 void
1369 gst_message_parse_warning (GstMessage * message, GError ** gerror,
1370     gchar ** debug)
1371 {
1372   const GValue *error_gvalue;
1373   GError *error_val;
1374   GstStructure *structure;
1375
1376   g_return_if_fail (GST_IS_MESSAGE (message));
1377   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);
1378
1379   structure = GST_MESSAGE_STRUCTURE (message);
1380   error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR));
1381   g_return_if_fail (error_gvalue != NULL);
1382   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
1383
1384   error_val = (GError *) g_value_get_boxed (error_gvalue);
1385   if (error_val)
1386     *gerror = g_error_copy (error_val);
1387   else
1388     *gerror = NULL;
1389
1390   if (debug)
1391     *debug =
1392         g_value_dup_string (gst_structure_id_get_value (structure,
1393             GST_QUARK (DEBUG)));
1394 }
1395
1396 /**
1397  * gst_message_parse_info:
1398  * @message: A valid #GstMessage of type GST_MESSAGE_INFO.
1399  * @gerror: (out) (allow-none) (transfer full): location for the GError
1400  * @debug: (out) (allow-none) (transfer full): location for the debug message,
1401  *     or NULL
1402  *
1403  * Extracts the GError and debug string from the GstMessage. The values returned
1404  * in the output arguments are copies; the caller must free them when done.
1405  *
1406  * MT safe.
1407  *
1408  * Since: 0.10.12
1409  */
1410 void
1411 gst_message_parse_info (GstMessage * message, GError ** gerror, gchar ** debug)
1412 {
1413   const GValue *error_gvalue;
1414   GError *error_val;
1415   GstStructure *structure;
1416
1417   g_return_if_fail (GST_IS_MESSAGE (message));
1418   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO);
1419
1420   structure = GST_MESSAGE_STRUCTURE (message);
1421   error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR));
1422   g_return_if_fail (error_gvalue != NULL);
1423   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
1424
1425   error_val = (GError *) g_value_get_boxed (error_gvalue);
1426   if (error_val)
1427     *gerror = g_error_copy (error_val);
1428   else
1429     *gerror = NULL;
1430
1431   if (debug)
1432     *debug =
1433         g_value_dup_string (gst_structure_id_get_value (structure,
1434             GST_QUARK (DEBUG)));
1435 }
1436
1437 /**
1438  * gst_message_parse_segment_start:
1439  * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_START.
1440  * @format: (out): Result location for the format, or NULL
1441  * @position: (out): Result location for the position, or NULL
1442  *
1443  * Extracts the position and format from the segment start message.
1444  *
1445  * MT safe.
1446  */
1447 void
1448 gst_message_parse_segment_start (GstMessage * message, GstFormat * format,
1449     gint64 * position)
1450 {
1451   GstStructure *structure;
1452
1453   g_return_if_fail (GST_IS_MESSAGE (message));
1454   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_START);
1455
1456   structure = GST_MESSAGE_STRUCTURE (message);
1457   if (format)
1458     *format =
1459         g_value_get_enum (gst_structure_id_get_value (structure,
1460             GST_QUARK (FORMAT)));
1461   if (position)
1462     *position =
1463         g_value_get_int64 (gst_structure_id_get_value (structure,
1464             GST_QUARK (POSITION)));
1465 }
1466
1467 /**
1468  * gst_message_parse_segment_done:
1469  * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_DONE.
1470  * @format: (out): Result location for the format, or NULL
1471  * @position: (out): Result location for the position, or NULL
1472  *
1473  * Extracts the position and format from the segment start message.
1474  *
1475  * MT safe.
1476  */
1477 void
1478 gst_message_parse_segment_done (GstMessage * message, GstFormat * format,
1479     gint64 * position)
1480 {
1481   GstStructure *structure;
1482
1483   g_return_if_fail (GST_IS_MESSAGE (message));
1484   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_DONE);
1485
1486   structure = GST_MESSAGE_STRUCTURE (message);
1487   if (format)
1488     *format =
1489         g_value_get_enum (gst_structure_id_get_value (structure,
1490             GST_QUARK (FORMAT)));
1491   if (position)
1492     *position =
1493         g_value_get_int64 (gst_structure_id_get_value (structure,
1494             GST_QUARK (POSITION)));
1495 }
1496
1497 /**
1498  * gst_message_parse_duration:
1499  * @message: A valid #GstMessage of type GST_MESSAGE_DURATION.
1500  * @format: (out): Result location for the format, or NULL
1501  * @duration: (out): Result location for the duration, or NULL
1502  *
1503  * Extracts the duration and format from the duration message. The duration
1504  * might be GST_CLOCK_TIME_NONE, which indicates that the duration has
1505  * changed. Applications should always use a query to retrieve the duration
1506  * of a pipeline.
1507  *
1508  * MT safe.
1509  */
1510 void
1511 gst_message_parse_duration (GstMessage * message, GstFormat * format,
1512     gint64 * duration)
1513 {
1514   GstStructure *structure;
1515
1516   g_return_if_fail (GST_IS_MESSAGE (message));
1517   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION);
1518
1519   structure = GST_MESSAGE_STRUCTURE (message);
1520   if (format)
1521     *format =
1522         g_value_get_enum (gst_structure_id_get_value (structure,
1523             GST_QUARK (FORMAT)));
1524   if (duration)
1525     *duration =
1526         g_value_get_int64 (gst_structure_id_get_value (structure,
1527             GST_QUARK (DURATION)));
1528 }
1529
1530 /**
1531  * gst_message_parse_async_done:
1532  * @message: A valid #GstMessage of type GST_MESSAGE_ASYNC_DONE.
1533  * @reset_time: (out): Result location for the reset_time or NULL
1534  *
1535  * Extract the reset_time from the async_done message.
1536  *
1537  * MT safe.
1538  */
1539 void
1540 gst_message_parse_async_done (GstMessage * message, gboolean * reset_time)
1541 {
1542   GstStructure *structure;
1543
1544   g_return_if_fail (GST_IS_MESSAGE (message));
1545   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ASYNC_DONE);
1546
1547   structure = GST_MESSAGE_STRUCTURE (message);
1548   if (reset_time)
1549     *reset_time =
1550         g_value_get_boolean (gst_structure_id_get_value (structure,
1551             GST_QUARK (RESET_TIME)));
1552 }
1553
1554 /**
1555  * gst_message_parse_request_state:
1556  * @message: A valid #GstMessage of type GST_MESSAGE_REQUEST_STATE.
1557  * @state: (out): Result location for the requested state or NULL
1558  *
1559  * Extract the requested state from the request_state message.
1560  *
1561  * MT safe.
1562  *
1563  * Since: 0.10.23
1564  */
1565 void
1566 gst_message_parse_request_state (GstMessage * message, GstState * state)
1567 {
1568   GstStructure *structure;
1569
1570   g_return_if_fail (GST_IS_MESSAGE (message));
1571   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REQUEST_STATE);
1572
1573   structure = GST_MESSAGE_STRUCTURE (message);
1574   if (state)
1575     *state = g_value_get_enum (gst_structure_id_get_value (structure,
1576             GST_QUARK (NEW_STATE)));
1577 }
1578
1579 /**
1580  * gst_message_new_stream_status:
1581  * @src: The object originating the message.
1582  * @type: The stream status type.
1583  * @owner: (transfer none): the owner element of @src.
1584  *
1585  * Create a new stream status message. This message is posted when a streaming
1586  * thread is created/destroyed or when the state changed.
1587  * 
1588  * Returns: (transfer full): the new stream status message.
1589  *
1590  * MT safe.
1591  *
1592  * Since: 0.10.24.
1593  */
1594 GstMessage *
1595 gst_message_new_stream_status (GstObject * src, GstStreamStatusType type,
1596     GstElement * owner)
1597 {
1598   GstMessage *message;
1599   GstStructure *structure;
1600
1601   structure = gst_structure_id_new (GST_QUARK (MESSAGE_STREAM_STATUS),
1602       GST_QUARK (TYPE), GST_TYPE_STREAM_STATUS_TYPE, (gint) type,
1603       GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner, NULL);
1604   message = gst_message_new_custom (GST_MESSAGE_STREAM_STATUS, src, structure);
1605
1606   return message;
1607 }
1608
1609 /**
1610  * gst_message_parse_stream_status:
1611  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1612  * @type: (out): A pointer to hold the status type
1613  * @owner: (out) (transfer none): The owner element of the message source
1614  *
1615  * Extracts the stream status type and owner the GstMessage. The returned
1616  * owner remains valid for as long as the reference to @message is valid and
1617  * should thus not be unreffed.
1618  *
1619  * MT safe.
1620  *
1621  * Since: 0.10.24.
1622  */
1623 void
1624 gst_message_parse_stream_status (GstMessage * message,
1625     GstStreamStatusType * type, GstElement ** owner)
1626 {
1627   const GValue *owner_gvalue;
1628   GstStructure *structure;
1629
1630   g_return_if_fail (GST_IS_MESSAGE (message));
1631   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
1632
1633   structure = GST_MESSAGE_STRUCTURE (message);
1634   owner_gvalue = gst_structure_id_get_value (structure, GST_QUARK (OWNER));
1635   g_return_if_fail (owner_gvalue != NULL);
1636
1637   if (type)
1638     *type = g_value_get_enum (gst_structure_id_get_value (structure,
1639             GST_QUARK (TYPE)));
1640   if (owner)
1641     *owner = (GstElement *) g_value_get_object (owner_gvalue);
1642 }
1643
1644 /**
1645  * gst_message_set_stream_status_object:
1646  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1647  * @object: the object controlling the streaming
1648  *
1649  * Configures the object handling the streaming thread. This is usually a
1650  * GstTask object but other objects might be added in the future.
1651  *
1652  * Since: 0.10.24
1653  */
1654 void
1655 gst_message_set_stream_status_object (GstMessage * message,
1656     const GValue * object)
1657 {
1658   GstStructure *structure;
1659
1660   g_return_if_fail (GST_IS_MESSAGE (message));
1661   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
1662
1663   structure = GST_MESSAGE_STRUCTURE (message);
1664   gst_structure_id_set_value (structure, GST_QUARK (OBJECT), object);
1665 }
1666
1667 /**
1668  * gst_message_get_stream_status_object:
1669  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1670  *
1671  * Extracts the object managing the streaming thread from @message.
1672  *
1673  * Returns: a GValue containing the object that manages the streaming thread.
1674  * This object is usually of type GstTask but other types can be added in the
1675  * future. The object remains valid as long as @message is valid.
1676  *
1677  * Since: 0.10.24
1678  */
1679 const GValue *
1680 gst_message_get_stream_status_object (GstMessage * message)
1681 {
1682   const GValue *result;
1683   GstStructure *structure;
1684
1685   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
1686   g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS,
1687       NULL);
1688
1689   structure = GST_MESSAGE_STRUCTURE (message);
1690   result = gst_structure_id_get_value (structure, GST_QUARK (OBJECT));
1691
1692   return result;
1693 }
1694
1695 /**
1696  * gst_message_new_step_done:
1697  * @src: The object originating the message.
1698  * @format: the format of @amount
1699  * @amount: the amount of stepped data
1700  * @rate: the rate of the stepped amount
1701  * @flush: is this an flushing step
1702  * @intermediate: is this an intermediate step
1703  * @duration: the duration of the data
1704  * @eos: the step caused EOS
1705  *
1706  * This message is posted by elements when they complete a part, when @intermediate set
1707  * to TRUE, or a complete step operation.
1708  *
1709  * @duration will contain the amount of time (in GST_FORMAT_TIME) of the stepped
1710  * @amount of media in format @format.
1711  *
1712  * Returns: (transfer full): the new step_done message.
1713  *
1714  * MT safe.
1715  *
1716  * Since: 0.10.24
1717  */
1718 GstMessage *
1719 gst_message_new_step_done (GstObject * src, GstFormat format, guint64 amount,
1720     gdouble rate, gboolean flush, gboolean intermediate, guint64 duration,
1721     gboolean eos)
1722 {
1723   GstMessage *message;
1724   GstStructure *structure;
1725
1726   structure = gst_structure_id_new (GST_QUARK (MESSAGE_STEP_DONE),
1727       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1728       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
1729       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
1730       GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
1731       GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate,
1732       GST_QUARK (DURATION), G_TYPE_UINT64, duration,
1733       GST_QUARK (EOS), G_TYPE_BOOLEAN, eos, NULL);
1734   message = gst_message_new_custom (GST_MESSAGE_STEP_DONE, src, structure);
1735
1736   return message;
1737 }
1738
1739 /**
1740  * gst_message_parse_step_done:
1741  * @message: A valid #GstMessage of type GST_MESSAGE_STEP_DONE.
1742  * @format: (out) (allow-none): result location for the format
1743  * @amount: (out) (allow-none): result location for the amount
1744  * @rate: (out) (allow-none): result location for the rate
1745  * @flush: (out) (allow-none): result location for the flush flag
1746  * @intermediate: (out) (allow-none): result location for the intermediate flag
1747  * @duration: (out) (allow-none): result location for the duration
1748  * @eos: (out) (allow-none): result location for the EOS flag
1749  *
1750  * Extract the values the step_done message.
1751  *
1752  * MT safe.
1753  *
1754  * Since: 0.10.24
1755  */
1756 void
1757 gst_message_parse_step_done (GstMessage * message, GstFormat * format,
1758     guint64 * amount, gdouble * rate, gboolean * flush, gboolean * intermediate,
1759     guint64 * duration, gboolean * eos)
1760 {
1761   GstStructure *structure;
1762
1763   g_return_if_fail (GST_IS_MESSAGE (message));
1764   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_DONE);
1765
1766   structure = GST_MESSAGE_STRUCTURE (message);
1767   gst_structure_id_get (structure,
1768       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1769       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
1770       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
1771       GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
1772       GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate,
1773       GST_QUARK (DURATION), G_TYPE_UINT64, duration,
1774       GST_QUARK (EOS), G_TYPE_BOOLEAN, eos, NULL);
1775 }
1776
1777 /**
1778  * gst_message_new_step_start:
1779  * @src: The object originating the message.
1780  * @active: if the step is active or queued
1781  * @format: the format of @amount
1782  * @amount: the amount of stepped data
1783  * @rate: the rate of the stepped amount
1784  * @flush: is this an flushing step
1785  * @intermediate: is this an intermediate step
1786  *
1787  * This message is posted by elements when they accept or activate a new step
1788  * event for @amount in @format. 
1789  *
1790  * @active is set to FALSE when the element accepted the new step event and has
1791  * queued it for execution in the streaming threads.
1792  *
1793  * @active is set to TRUE when the element has activated the step operation and
1794  * is now ready to start executing the step in the streaming thread. After this
1795  * message is emited, the application can queue a new step operation in the
1796  * element.
1797  *
1798  * Returns: (transfer full): The new step_start message. 
1799  *
1800  * MT safe.
1801  *
1802  * Since: 0.10.24
1803  */
1804 GstMessage *
1805 gst_message_new_step_start (GstObject * src, gboolean active, GstFormat format,
1806     guint64 amount, gdouble rate, gboolean flush, gboolean intermediate)
1807 {
1808   GstMessage *message;
1809   GstStructure *structure;
1810
1811   structure = gst_structure_id_new (GST_QUARK (MESSAGE_STEP_START),
1812       GST_QUARK (ACTIVE), G_TYPE_BOOLEAN, active,
1813       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1814       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
1815       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
1816       GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
1817       GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate, NULL);
1818   message = gst_message_new_custom (GST_MESSAGE_STEP_START, src, structure);
1819
1820   return message;
1821 }
1822
1823 /**
1824  * gst_message_parse_step_start:
1825  * @message: A valid #GstMessage of type GST_MESSAGE_STEP_DONE.
1826  * @active: (out) (allow-none): result location for the active flag
1827  * @format: (out) (allow-none): result location for the format
1828  * @amount: (out) (allow-none): result location for the amount
1829  * @rate: (out) (allow-none): result location for the rate
1830  * @flush: (out) (allow-none): result location for the flush flag
1831  * @intermediate: (out) (allow-none): result location for the intermediate flag
1832  *
1833  * Extract the values from step_start message.
1834  *
1835  * MT safe.
1836  *
1837  * Since: 0.10.24
1838  */
1839 void
1840 gst_message_parse_step_start (GstMessage * message, gboolean * active,
1841     GstFormat * format, guint64 * amount, gdouble * rate, gboolean * flush,
1842     gboolean * intermediate)
1843 {
1844   GstStructure *structure;
1845
1846   g_return_if_fail (GST_IS_MESSAGE (message));
1847   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_START);
1848
1849   structure = GST_MESSAGE_STRUCTURE (message);
1850   gst_structure_id_get (structure,
1851       GST_QUARK (ACTIVE), G_TYPE_BOOLEAN, active,
1852       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1853       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
1854       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
1855       GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
1856       GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate, NULL);
1857 }
1858
1859 /**
1860  * gst_message_new_qos:
1861  * @src: The object originating the message.
1862  * @live: if the message was generated by a live element
1863  * @running_time: the running time of the buffer that generated the message
1864  * @stream_time: the stream time of the buffer that generated the message
1865  * @timestamp: the timestamps of the buffer that generated the message
1866  * @duration: the duration of the buffer that generated the message
1867  *
1868  * A QOS message is posted on the bus whenever an element decides to drop a
1869  * buffer because of QoS reasons or whenever it changes its processing strategy
1870  * because of QoS reasons (quality adjustments such as processing at lower
1871  * accuracy).
1872  *
1873  * This message can be posted by an element that performs synchronisation against the
1874  * clock (live) or it could be dropped by an element that performs QoS because of QOS
1875  * events received from a downstream element (!live).
1876  *
1877  * @running_time, @stream_time, @timestamp, @duration should be set to the
1878  * respective running-time, stream-time, timestamp and duration of the (dropped)
1879  * buffer that generated the QoS event. Values can be left to
1880  * GST_CLOCK_TIME_NONE when unknown.
1881  *
1882  * Returns: (transfer full): The new qos message.
1883  *
1884  * MT safe.
1885  *
1886  * Since: 0.10.29
1887  */
1888 GstMessage *
1889 gst_message_new_qos (GstObject * src, gboolean live, guint64 running_time,
1890     guint64 stream_time, guint64 timestamp, guint64 duration)
1891 {
1892   GstMessage *message;
1893   GstStructure *structure;
1894
1895   structure = gst_structure_id_new (GST_QUARK (MESSAGE_QOS),
1896       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
1897       GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time,
1898       GST_QUARK (STREAM_TIME), G_TYPE_UINT64, stream_time,
1899       GST_QUARK (TIMESTAMP), G_TYPE_UINT64, timestamp,
1900       GST_QUARK (DURATION), G_TYPE_UINT64, duration,
1901       GST_QUARK (JITTER), G_TYPE_INT64, (gint64) 0,
1902       GST_QUARK (PROPORTION), G_TYPE_DOUBLE, (gdouble) 1.0,
1903       GST_QUARK (QUALITY), G_TYPE_INT, (gint) 1000000,
1904       GST_QUARK (FORMAT), GST_TYPE_FORMAT, GST_FORMAT_UNDEFINED,
1905       GST_QUARK (PROCESSED), G_TYPE_UINT64, (guint64) - 1,
1906       GST_QUARK (DROPPED), G_TYPE_UINT64, (guint64) - 1, NULL);
1907   message = gst_message_new_custom (GST_MESSAGE_QOS, src, structure);
1908
1909   return message;
1910 }
1911
1912 /**
1913  * gst_message_set_qos_values:
1914  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
1915  * @jitter: The difference of the running-time against the deadline.
1916  * @proportion: Long term prediction of the ideal rate relative to normal rate
1917  * to get optimal quality.
1918  * @quality: An element dependent integer value that specifies the current
1919  * quality level of the element. The default maximum quality is 1000000.
1920  *
1921  * Set the QoS values that have been calculated/analysed from the QoS data
1922  *
1923  * MT safe.
1924  *
1925  * Since: 0.10.29
1926  */
1927 void
1928 gst_message_set_qos_values (GstMessage * message, gint64 jitter,
1929     gdouble proportion, gint quality)
1930 {
1931   GstStructure *structure;
1932
1933   g_return_if_fail (GST_IS_MESSAGE (message));
1934   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
1935
1936   structure = GST_MESSAGE_STRUCTURE (message);
1937   gst_structure_id_set (structure,
1938       GST_QUARK (JITTER), G_TYPE_INT64, jitter,
1939       GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
1940       GST_QUARK (QUALITY), G_TYPE_INT, quality, NULL);
1941 }
1942
1943 /**
1944  * gst_message_set_qos_stats:
1945  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
1946  * @format: Units of the 'processed' and 'dropped' fields. Video sinks and video
1947  * filters will use GST_FORMAT_BUFFERS (frames). Audio sinks and audio filters
1948  * will likely use GST_FORMAT_DEFAULT (samples).
1949  * @processed: Total number of units correctly processed since the last state
1950  * change to READY or a flushing operation.
1951  * @dropped: Total number of units dropped since the last state change to READY
1952  * or a flushing operation.
1953  *
1954  * Set the QoS stats representing the history of the current continuous pipeline
1955  * playback period.
1956  *
1957  * When @format is @GST_FORMAT_UNDEFINED both @dropped and @processed are
1958  * invalid. Values of -1 for either @processed or @dropped mean unknown values.
1959  *
1960  * MT safe.
1961  *
1962  * Since: 0.10.29
1963  */
1964 void
1965 gst_message_set_qos_stats (GstMessage * message, GstFormat format,
1966     guint64 processed, guint64 dropped)
1967 {
1968   GstStructure *structure;
1969
1970   g_return_if_fail (GST_IS_MESSAGE (message));
1971   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
1972
1973   structure = GST_MESSAGE_STRUCTURE (message);
1974   gst_structure_id_set (structure,
1975       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1976       GST_QUARK (PROCESSED), G_TYPE_UINT64, processed,
1977       GST_QUARK (DROPPED), G_TYPE_UINT64, dropped, NULL);
1978 }
1979
1980 /**
1981  * gst_message_parse_qos:
1982  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
1983  * @live: (out) (allow-none): if the message was generated by a live element
1984  * @running_time: (out) (allow-none): the running time of the buffer that
1985  *     generated the message
1986  * @stream_time: (out) (allow-none): the stream time of the buffer that
1987  *     generated the message
1988  * @timestamp: (out) (allow-none): the timestamps of the buffer that
1989  *     generated the message
1990  * @duration: (out) (allow-none): the duration of the buffer that
1991  *     generated the message
1992  *
1993  * Extract the timestamps and live status from the QoS message.
1994  *
1995  * The returned values give the running_time, stream_time, timestamp and
1996  * duration of the dropped buffer. Values of GST_CLOCK_TIME_NONE mean unknown
1997  * values.
1998  *
1999  * MT safe.
2000  *
2001  * Since: 0.10.29
2002  */
2003 void
2004 gst_message_parse_qos (GstMessage * message, gboolean * live,
2005     guint64 * running_time, guint64 * stream_time, guint64 * timestamp,
2006     guint64 * duration)
2007 {
2008   GstStructure *structure;
2009
2010   g_return_if_fail (GST_IS_MESSAGE (message));
2011   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
2012
2013   structure = GST_MESSAGE_STRUCTURE (message);
2014   gst_structure_id_get (structure,
2015       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
2016       GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time,
2017       GST_QUARK (STREAM_TIME), G_TYPE_UINT64, stream_time,
2018       GST_QUARK (TIMESTAMP), G_TYPE_UINT64, timestamp,
2019       GST_QUARK (DURATION), G_TYPE_UINT64, duration, NULL);
2020 }
2021
2022 /**
2023  * gst_message_parse_qos_values:
2024  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
2025  * @jitter: (out) (allow-none): The difference of the running-time against
2026  *     the deadline.
2027  * @proportion: (out) (allow-none): Long term prediction of the ideal rate
2028  *     relative to normal rate to get optimal quality.
2029  * @quality: (out) (allow-none): An element dependent integer value that
2030  *     specifies the current quality level of the element. The default
2031  *     maximum quality is 1000000.
2032  *
2033  * Extract the QoS values that have been calculated/analysed from the QoS data
2034  *
2035  * MT safe.
2036  *
2037  * Since: 0.10.29
2038  */
2039 void
2040 gst_message_parse_qos_values (GstMessage * message, gint64 * jitter,
2041     gdouble * proportion, gint * quality)
2042 {
2043   GstStructure *structure;
2044
2045   g_return_if_fail (GST_IS_MESSAGE (message));
2046   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
2047
2048   structure = GST_MESSAGE_STRUCTURE (message);
2049   gst_structure_id_get (structure,
2050       GST_QUARK (JITTER), G_TYPE_INT64, jitter,
2051       GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
2052       GST_QUARK (QUALITY), G_TYPE_INT, quality, NULL);
2053 }
2054
2055 /**
2056  * gst_message_parse_qos_stats:
2057  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
2058  * @format: (out) (allow-none): Units of the 'processed' and 'dropped' fields.
2059  *     Video sinks and video filters will use GST_FORMAT_BUFFERS (frames).
2060  *     Audio sinks and audio filters will likely use GST_FORMAT_DEFAULT
2061  *     (samples).
2062  * @processed: (out) (allow-none): Total number of units correctly processed
2063  *     since the last state change to READY or a flushing operation.
2064  * @dropped: (out) (allow-none): Total number of units dropped since the last
2065  *     state change to READY or a flushing operation.
2066  *
2067  * Extract the QoS stats representing the history of the current continuous
2068  * pipeline playback period.
2069  *
2070  * When @format is @GST_FORMAT_UNDEFINED both @dropped and @processed are
2071  * invalid. Values of -1 for either @processed or @dropped mean unknown values.
2072  *
2073  * MT safe.
2074  *
2075  * Since: 0.10.29
2076  */
2077 void
2078 gst_message_parse_qos_stats (GstMessage * message, GstFormat * format,
2079     guint64 * processed, guint64 * dropped)
2080 {
2081   GstStructure *structure;
2082
2083   g_return_if_fail (GST_IS_MESSAGE (message));
2084   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
2085
2086   structure = GST_MESSAGE_STRUCTURE (message);
2087   gst_structure_id_get (structure,
2088       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
2089       GST_QUARK (PROCESSED), G_TYPE_UINT64, processed,
2090       GST_QUARK (DROPPED), G_TYPE_UINT64, dropped, NULL);
2091 }
2092
2093 /**
2094  * gst_message_new_progress:
2095  * @src: The object originating the message.
2096  * @type: a #GstProgressType
2097  * @code: a progress code
2098  * @text: free, user visible text describing the progress
2099  *
2100  * Progress messages are posted by elements when they use an asynchronous task
2101  * to perform actions triggered by a state change.
2102  *
2103  * @code contains a well defined string describing the action.
2104  * @test should contain a user visible string detailing the current action.
2105  *
2106  * Returns: (transfer full): The new qos message.
2107  *
2108  * Since: 0.10.33
2109  */
2110 GstMessage *
2111 gst_message_new_progress (GstObject * src, GstProgressType type,
2112     const gchar * code, const gchar * text)
2113 {
2114   GstMessage *message;
2115   GstStructure *structure;
2116   gint percent = 100, timeout = -1;
2117
2118   g_return_val_if_fail (code != NULL, NULL);
2119   g_return_val_if_fail (text != NULL, NULL);
2120
2121   if (type == GST_PROGRESS_TYPE_START || type == GST_PROGRESS_TYPE_CONTINUE)
2122     percent = 0;
2123
2124   structure = gst_structure_id_new (GST_QUARK (MESSAGE_PROGRESS),
2125       GST_QUARK (TYPE), GST_TYPE_PROGRESS_TYPE, type,
2126       GST_QUARK (CODE), G_TYPE_STRING, code,
2127       GST_QUARK (TEXT), G_TYPE_STRING, text,
2128       GST_QUARK (PERCENT), G_TYPE_INT, percent,
2129       GST_QUARK (TIMEOUT), G_TYPE_INT, timeout, NULL);
2130   message = gst_message_new_custom (GST_MESSAGE_PROGRESS, src, structure);
2131
2132   return message;
2133 }
2134
2135 /**
2136  * gst_message_parse_progress:
2137  * @message: A valid #GstMessage of type GST_MESSAGE_PROGRESS.
2138  * @type: (out) (allow-none): location for the type
2139  * @code: (out) (allow-none) (transfer full): location for the code
2140  * @text: (out) (allow-none) (transfer full): location for the text
2141  *
2142  * Parses the progress @type, @code and @text.
2143  *
2144  * Since: 0.10.33
2145  */
2146 void
2147 gst_message_parse_progress (GstMessage * message, GstProgressType * type,
2148     gchar ** code, gchar ** text)
2149 {
2150   GstStructure *structure;
2151
2152   g_return_if_fail (GST_IS_MESSAGE (message));
2153   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_PROGRESS);
2154
2155   structure = GST_MESSAGE_STRUCTURE (message);
2156   gst_structure_id_get (structure,
2157       GST_QUARK (TYPE), GST_TYPE_PROGRESS_TYPE, type,
2158       GST_QUARK (CODE), G_TYPE_STRING, code,
2159       GST_QUARK (TEXT), G_TYPE_STRING, text, NULL);
2160 }