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