message: fix annotation of parse_stream_{collection,streams_selected}
[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., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, 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  * |[<!-- language="C" -->
38  *   gst_bus_post (bus, gst_message_new_eos());
39  * ]|
40  *
41  * A #GstElement usually posts messages on the bus provided by the parent
42  * container using gst_element_post_message().
43  */
44
45
46 #include "gst_private.h"
47 #include <string.h>             /* memcpy */
48 #include "gsterror.h"
49 #include "gstenumtypes.h"
50 #include "gstinfo.h"
51 #include "gstmessage.h"
52 #include "gsttaglist.h"
53 #include "gstutils.h"
54 #include "gstquark.h"
55 #include "gstvalue.h"
56
57
58 typedef struct
59 {
60   GstMessage message;
61
62   GstStructure *structure;
63 } GstMessageImpl;
64
65 #define GST_MESSAGE_STRUCTURE(m)  (((GstMessageImpl *)(m))->structure)
66
67 typedef struct
68 {
69   const gint type;
70   const gchar *name;
71   GQuark quark;
72 } GstMessageQuarks;
73
74 static GstMessageQuarks message_quarks[] = {
75   {GST_MESSAGE_UNKNOWN, "unknown", 0},
76   {GST_MESSAGE_EOS, "eos", 0},
77   {GST_MESSAGE_ERROR, "error", 0},
78   {GST_MESSAGE_WARNING, "warning", 0},
79   {GST_MESSAGE_INFO, "info", 0},
80   {GST_MESSAGE_TAG, "tag", 0},
81   {GST_MESSAGE_BUFFERING, "buffering", 0},
82   {GST_MESSAGE_STATE_CHANGED, "state-changed", 0},
83   {GST_MESSAGE_STATE_DIRTY, "state-dirty", 0},
84   {GST_MESSAGE_STEP_DONE, "step-done", 0},
85   {GST_MESSAGE_CLOCK_PROVIDE, "clock-provide", 0},
86   {GST_MESSAGE_CLOCK_LOST, "clock-lost", 0},
87   {GST_MESSAGE_NEW_CLOCK, "new-clock", 0},
88   {GST_MESSAGE_STRUCTURE_CHANGE, "structure-change", 0},
89   {GST_MESSAGE_STREAM_STATUS, "stream-status", 0},
90   {GST_MESSAGE_APPLICATION, "application", 0},
91   {GST_MESSAGE_ELEMENT, "element", 0},
92   {GST_MESSAGE_SEGMENT_START, "segment-start", 0},
93   {GST_MESSAGE_SEGMENT_DONE, "segment-done", 0},
94   {GST_MESSAGE_DURATION_CHANGED, "duration-changed", 0},
95   {GST_MESSAGE_LATENCY, "latency", 0},
96   {GST_MESSAGE_ASYNC_START, "async-start", 0},
97   {GST_MESSAGE_ASYNC_DONE, "async-done", 0},
98   {GST_MESSAGE_REQUEST_STATE, "request-state", 0},
99   {GST_MESSAGE_STEP_START, "step-start", 0},
100   {GST_MESSAGE_QOS, "qos", 0},
101   {GST_MESSAGE_PROGRESS, "progress", 0},
102   {GST_MESSAGE_TOC, "toc", 0},
103   {GST_MESSAGE_RESET_TIME, "reset-time", 0},
104   {GST_MESSAGE_STREAM_START, "stream-start", 0},
105   {GST_MESSAGE_NEED_CONTEXT, "need-context", 0},
106   {GST_MESSAGE_HAVE_CONTEXT, "have-context", 0},
107   {GST_MESSAGE_DEVICE_ADDED, "device-added", 0},
108   {GST_MESSAGE_DEVICE_REMOVED, "device-removed", 0},
109   {GST_MESSAGE_PROPERTY_NOTIFY, "property-notify", 0},
110   {GST_MESSAGE_STREAM_COLLECTION, "stream-collection", 0},
111   {GST_MESSAGE_STREAMS_SELECTED, "streams-selected", 0},
112   {0, NULL, 0}
113 };
114
115 GType _gst_message_type = 0;
116 GST_DEFINE_MINI_OBJECT_TYPE (GstMessage, gst_message);
117
118 void
119 _priv_gst_message_initialize (void)
120 {
121   gint i;
122
123   GST_CAT_INFO (GST_CAT_GST_INIT, "init messages");
124
125   for (i = 0; message_quarks[i].name; i++) {
126     message_quarks[i].quark =
127         g_quark_from_static_string (message_quarks[i].name);
128   }
129
130   _gst_message_type = gst_message_get_type ();
131 }
132
133 /**
134  * gst_message_type_get_name:
135  * @type: the message type
136  *
137  * Get a printable name for the given message type. Do not modify or free.
138  *
139  * Returns: a reference to the static name of the message.
140  */
141 const gchar *
142 gst_message_type_get_name (GstMessageType type)
143 {
144   gint i;
145
146   for (i = 0; message_quarks[i].name; i++) {
147     if (type == message_quarks[i].type)
148       return message_quarks[i].name;
149   }
150   return "unknown";
151 }
152
153 /**
154  * gst_message_type_to_quark:
155  * @type: the message type
156  *
157  * Get the unique quark for the given message type.
158  *
159  * Returns: the quark associated with the message type
160  */
161 GQuark
162 gst_message_type_to_quark (GstMessageType type)
163 {
164   gint i;
165
166   for (i = 0; message_quarks[i].name; i++) {
167     if (type == message_quarks[i].type)
168       return message_quarks[i].quark;
169   }
170   return 0;
171 }
172
173 static gboolean
174 _gst_message_dispose (GstMessage * message)
175 {
176   gboolean do_free = TRUE;
177
178   if (GST_MINI_OBJECT_FLAG_IS_SET (message, GST_MESSAGE_FLAG_ASYNC_DELIVERY)) {
179     /* revive message, so bus can finish with it and clean it up */
180     gst_message_ref (message);
181
182     GST_INFO ("[msg %p] signalling async free", message);
183
184     GST_MESSAGE_LOCK (message);
185     GST_MESSAGE_SIGNAL (message);
186     GST_MESSAGE_UNLOCK (message);
187
188     /* don't free it yet, let bus finish with it first */
189     do_free = FALSE;
190   }
191
192   return do_free;
193 }
194
195 static void
196 _gst_message_free (GstMessage * message)
197 {
198   GstStructure *structure;
199
200   g_return_if_fail (message != NULL);
201
202   GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p, %s from %s", message,
203       GST_MESSAGE_TYPE_NAME (message), GST_MESSAGE_SRC_NAME (message));
204
205   if (GST_MESSAGE_SRC (message)) {
206     gst_object_unref (GST_MESSAGE_SRC (message));
207     GST_MESSAGE_SRC (message) = NULL;
208   }
209
210   structure = GST_MESSAGE_STRUCTURE (message);
211   if (structure) {
212     gst_structure_set_parent_refcount (structure, NULL);
213     gst_structure_free (structure);
214   }
215
216   g_slice_free1 (sizeof (GstMessageImpl), message);
217 }
218
219 static void
220 gst_message_init (GstMessageImpl * message, GstMessageType type,
221     GstObject * src);
222
223 static GstMessage *
224 _gst_message_copy (GstMessage * message)
225 {
226   GstMessageImpl *copy;
227   GstStructure *structure;
228
229   GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p, %s from %s", message,
230       GST_MESSAGE_TYPE_NAME (message),
231       GST_OBJECT_NAME (GST_MESSAGE_SRC (message)));
232
233   copy = g_slice_new0 (GstMessageImpl);
234
235   gst_message_init (copy, GST_MESSAGE_TYPE (message),
236       GST_MESSAGE_SRC (message));
237
238   GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
239   GST_MESSAGE_SEQNUM (copy) = GST_MESSAGE_SEQNUM (message);
240
241   structure = GST_MESSAGE_STRUCTURE (message);
242   if (structure) {
243     GST_MESSAGE_STRUCTURE (copy) = gst_structure_copy (structure);
244     gst_structure_set_parent_refcount (GST_MESSAGE_STRUCTURE (copy),
245         &copy->message.mini_object.refcount);
246   } else {
247     GST_MESSAGE_STRUCTURE (copy) = NULL;
248   }
249
250   return GST_MESSAGE_CAST (copy);
251 }
252
253 static void
254 gst_message_init (GstMessageImpl * message, GstMessageType type,
255     GstObject * src)
256 {
257   gst_mini_object_init (GST_MINI_OBJECT_CAST (message), 0, _gst_message_type,
258       (GstMiniObjectCopyFunction) _gst_message_copy,
259       (GstMiniObjectDisposeFunction) _gst_message_dispose,
260       (GstMiniObjectFreeFunction) _gst_message_free);
261
262   GST_MESSAGE_TYPE (message) = type;
263   if (src)
264     gst_object_ref (src);
265   GST_MESSAGE_SRC (message) = src;
266   GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
267   GST_MESSAGE_SEQNUM (message) = gst_util_seqnum_next ();
268 }
269
270
271 /**
272  * gst_message_new_custom:
273  * @type: The #GstMessageType to distinguish messages
274  * @src: (transfer none) (allow-none): The object originating the message.
275  * @structure: (transfer full) (allow-none): the structure for the
276  *     message. The message will take ownership of the structure.
277  *
278  * Create a new custom-typed message. This can be used for anything not
279  * handled by other message-specific functions to pass a message to the
280  * app. The structure field can be %NULL.
281  *
282  * Returns: (transfer full): The new message.
283  *
284  * MT safe.
285  */
286 GstMessage *
287 gst_message_new_custom (GstMessageType type, GstObject * src,
288     GstStructure * structure)
289 {
290   GstMessageImpl *message;
291
292   message = g_slice_new0 (GstMessageImpl);
293
294   GST_CAT_LOG (GST_CAT_MESSAGE, "source %s: creating new message %p %s",
295       (src ? GST_OBJECT_NAME (src) : "NULL"), message,
296       gst_message_type_get_name (type));
297
298   if (structure) {
299     /* structure must not have a parent */
300     if (!gst_structure_set_parent_refcount (structure,
301             &message->message.mini_object.refcount))
302       goto had_parent;
303   }
304   gst_message_init (message, type, src);
305
306   GST_MESSAGE_STRUCTURE (message) = structure;
307
308   return GST_MESSAGE_CAST (message);
309
310   /* ERRORS */
311 had_parent:
312   {
313     g_slice_free1 (sizeof (GstMessageImpl), message);
314     g_warning ("structure is already owned by another object");
315     return NULL;
316   }
317 }
318
319 /**
320  * gst_message_get_seqnum:
321  * @message: A #GstMessage.
322  *
323  * Retrieve the sequence number of a message.
324  *
325  * Messages have ever-incrementing sequence numbers, which may also be set
326  * explicitly via gst_message_set_seqnum(). Sequence numbers are typically used
327  * to indicate that a message corresponds to some other set of messages or
328  * events, for example a SEGMENT_DONE message corresponding to a SEEK event. It
329  * is considered good practice to make this correspondence when possible, though
330  * it is not required.
331  *
332  * Note that events and messages share the same sequence number incrementor;
333  * two events or messages will never have the same sequence number unless
334  * that correspondence was made explicitly.
335  *
336  * Returns: The message's sequence number.
337  *
338  * MT safe.
339  */
340 guint32
341 gst_message_get_seqnum (GstMessage * message)
342 {
343   g_return_val_if_fail (GST_IS_MESSAGE (message), -1);
344
345   return GST_MESSAGE_SEQNUM (message);
346 }
347
348 /**
349  * gst_message_set_seqnum:
350  * @message: A #GstMessage.
351  * @seqnum: A sequence number.
352  *
353  * Set the sequence number of a message.
354  *
355  * This function might be called by the creator of a message to indicate that
356  * the message relates to other messages or events. See gst_message_get_seqnum()
357  * for more information.
358  *
359  * MT safe.
360  */
361 void
362 gst_message_set_seqnum (GstMessage * message, guint32 seqnum)
363 {
364   g_return_if_fail (GST_IS_MESSAGE (message));
365
366   GST_MESSAGE_SEQNUM (message) = seqnum;
367 }
368
369 /**
370  * gst_message_new_eos:
371  * @src: (transfer none) (allow-none): The object originating the message.
372  *
373  * Create a new eos message. This message is generated and posted in
374  * the sink elements of a GstBin. The bin will only forward the EOS
375  * message to the application if all sinks have posted an EOS message.
376  *
377  * Returns: (transfer full): The new eos message.
378  *
379  * MT safe.
380  */
381 GstMessage *
382 gst_message_new_eos (GstObject * src)
383 {
384   GstMessage *message;
385
386   message = gst_message_new_custom (GST_MESSAGE_EOS, src, NULL);
387
388   return message;
389 }
390
391 /**
392  * gst_message_new_error:
393  * @src: (transfer none) (allow-none): The object originating the message.
394  * @error: (transfer none): The GError for this message.
395  * @debug: A debugging string.
396  *
397  * Create a new error message. The message will copy @error and
398  * @debug. This message is posted by element when a fatal event
399  * occurred. The pipeline will probably (partially) stop. The application
400  * receiving this message should stop the pipeline.
401  *
402  * Returns: (transfer full): the new error message.
403  *
404  * MT safe.
405  */
406 GstMessage *
407 gst_message_new_error (GstObject * src, GError * error, const gchar * debug)
408 {
409   GstMessage *message;
410   GstStructure *structure;
411
412   structure = gst_structure_new_id (GST_QUARK (MESSAGE_ERROR),
413       GST_QUARK (GERROR), G_TYPE_ERROR, error,
414       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
415   message = gst_message_new_custom (GST_MESSAGE_ERROR, src, structure);
416
417   return message;
418 }
419
420 /**
421  * gst_message_new_warning:
422  * @src: (transfer none) (allow-none): The object originating the message.
423  * @error: (transfer none): The GError for this message.
424  * @debug: A debugging string.
425  *
426  * Create a new warning message. The message will make copies of @error and
427  * @debug.
428  *
429  * Returns: (transfer full): The new warning message.
430  *
431  * MT safe.
432  */
433 GstMessage *
434 gst_message_new_warning (GstObject * src, GError * error, const gchar * debug)
435 {
436   GstMessage *message;
437   GstStructure *structure;
438
439   structure = gst_structure_new_id (GST_QUARK (MESSAGE_WARNING),
440       GST_QUARK (GERROR), G_TYPE_ERROR, error,
441       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
442   message = gst_message_new_custom (GST_MESSAGE_WARNING, src, structure);
443
444   return message;
445 }
446
447 /**
448  * gst_message_new_info:
449  * @src: (transfer none) (allow-none): The object originating the message.
450  * @error: (transfer none): The GError for this message.
451  * @debug: A debugging string.
452  *
453  * Create a new info message. The message will make copies of @error and
454  * @debug.
455  *
456  * MT safe.
457  *
458  * Returns: (transfer full): the new info message.
459  */
460 GstMessage *
461 gst_message_new_info (GstObject * src, GError * error, const gchar * debug)
462 {
463   GstMessage *message;
464   GstStructure *structure;
465
466   structure = gst_structure_new_id (GST_QUARK (MESSAGE_INFO),
467       GST_QUARK (GERROR), G_TYPE_ERROR, error,
468       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
469   message = gst_message_new_custom (GST_MESSAGE_INFO, src, structure);
470
471   return message;
472 }
473
474 /**
475  * gst_message_new_tag:
476  * @src: (transfer none) (allow-none): The object originating the message.
477  * @tag_list: (transfer full): the tag list for the message.
478  *
479  * Create a new tag message. The message will take ownership of the tag list.
480  * The message is posted by elements that discovered a new taglist.
481  *
482  * Returns: (transfer full): the new tag message.
483  *
484  * MT safe.
485  */
486 GstMessage *
487 gst_message_new_tag (GstObject * src, GstTagList * tag_list)
488 {
489   GstStructure *s;
490   GstMessage *message;
491   GValue val = G_VALUE_INIT;
492
493   g_return_val_if_fail (GST_IS_TAG_LIST (tag_list), NULL);
494
495   s = gst_structure_new_id_empty (GST_QUARK (MESSAGE_TAG));
496   g_value_init (&val, GST_TYPE_TAG_LIST);
497   g_value_take_boxed (&val, tag_list);
498   gst_structure_id_take_value (s, GST_QUARK (TAGLIST), &val);
499   message = gst_message_new_custom (GST_MESSAGE_TAG, src, s);
500   return message;
501 }
502
503 /**
504  * gst_message_new_buffering:
505  * @src: (transfer none) (allow-none): The object originating the message.
506  * @percent: The buffering percent
507  *
508  * Create a new buffering message. This message can be posted by an element that
509  * needs to buffer data before it can continue processing. @percent should be a
510  * value between 0 and 100. A value of 100 means that the buffering completed.
511  *
512  * When @percent is < 100 the application should PAUSE a PLAYING pipeline. When
513  * @percent is 100, the application can set the pipeline (back) to PLAYING.
514  * The application must be prepared to receive BUFFERING messages in the
515  * PREROLLING state and may only set the pipeline to PLAYING after receiving a
516  * message with @percent set to 100, which can happen after the pipeline
517  * completed prerolling.
518  *
519  * MT safe.
520  *
521  * Returns: (transfer full): The new buffering message.
522  */
523 GstMessage *
524 gst_message_new_buffering (GstObject * src, gint percent)
525 {
526   GstMessage *message;
527   GstStructure *structure;
528   gint64 buffering_left;
529
530   g_return_val_if_fail (percent >= 0 && percent <= 100, NULL);
531
532   buffering_left = (percent == 100 ? 0 : -1);
533
534   structure = gst_structure_new_id (GST_QUARK (MESSAGE_BUFFERING),
535       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent,
536       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
537       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
538       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
539       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
540   message = gst_message_new_custom (GST_MESSAGE_BUFFERING, src, structure);
541
542   return message;
543 }
544
545 /**
546  * gst_message_new_state_changed:
547  * @src: (transfer none) (allow-none): The object originating the message.
548  * @oldstate: the previous state
549  * @newstate: the new (current) state
550  * @pending: the pending (target) state
551  *
552  * Create a state change message. This message is posted whenever an element
553  * changed its state.
554  *
555  * Returns: (transfer full): the new state change message.
556  *
557  * MT safe.
558  */
559 GstMessage *
560 gst_message_new_state_changed (GstObject * src,
561     GstState oldstate, GstState newstate, GstState pending)
562 {
563   GstMessage *message;
564   GstStructure *structure;
565
566   structure = gst_structure_new_id (GST_QUARK (MESSAGE_STATE_CHANGED),
567       GST_QUARK (OLD_STATE), GST_TYPE_STATE, (gint) oldstate,
568       GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) newstate,
569       GST_QUARK (PENDING_STATE), GST_TYPE_STATE, (gint) pending, NULL);
570   message = gst_message_new_custom (GST_MESSAGE_STATE_CHANGED, src, structure);
571
572   return message;
573 }
574
575 /**
576  * gst_message_new_state_dirty:
577  * @src: (transfer none) (allow-none): The object originating the message
578  *
579  * Create a state dirty message. This message is posted whenever an element
580  * changed its state asynchronously and is used internally to update the
581  * states of container objects.
582  *
583  * Returns: (transfer full): the new state dirty message.
584  *
585  * MT safe.
586  */
587 GstMessage *
588 gst_message_new_state_dirty (GstObject * src)
589 {
590   GstMessage *message;
591
592   message = gst_message_new_custom (GST_MESSAGE_STATE_DIRTY, src, NULL);
593
594   return message;
595 }
596
597 /**
598  * gst_message_new_clock_provide:
599  * @src: (transfer none) (allow-none): The object originating the message.
600  * @clock: (transfer none): the clock it provides
601  * @ready: %TRUE if the sender can provide a clock
602  *
603  * Create a clock provide message. This message is posted whenever an
604  * element is ready to provide a clock or lost its ability to provide
605  * a clock (maybe because it paused or became EOS).
606  *
607  * This message is mainly used internally to manage the clock
608  * selection.
609  *
610  * Returns: (transfer full): the new provide clock message.
611  *
612  * MT safe.
613  */
614 GstMessage *
615 gst_message_new_clock_provide (GstObject * src, GstClock * clock,
616     gboolean ready)
617 {
618   GstMessage *message;
619   GstStructure *structure;
620
621   structure = gst_structure_new_id (GST_QUARK (MESSAGE_CLOCK_PROVIDE),
622       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock,
623       GST_QUARK (READY), G_TYPE_BOOLEAN, ready, NULL);
624   message = gst_message_new_custom (GST_MESSAGE_CLOCK_PROVIDE, src, structure);
625
626   return message;
627 }
628
629 /**
630  * gst_message_new_clock_lost:
631  * @src: (transfer none) (allow-none): The object originating the message.
632  * @clock: (transfer none): the clock that was lost
633  *
634  * Create a clock lost message. This message is posted whenever the
635  * clock is not valid anymore.
636  *
637  * If this message is posted by the pipeline, the pipeline will
638  * select a new clock again when it goes to PLAYING. It might therefore
639  * be needed to set the pipeline to PAUSED and PLAYING again.
640  *
641  * Returns: (transfer full): The new clock lost message.
642  *
643  * MT safe.
644  */
645 GstMessage *
646 gst_message_new_clock_lost (GstObject * src, GstClock * clock)
647 {
648   GstMessage *message;
649   GstStructure *structure;
650
651   structure = gst_structure_new_id (GST_QUARK (MESSAGE_CLOCK_LOST),
652       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
653   message = gst_message_new_custom (GST_MESSAGE_CLOCK_LOST, src, structure);
654
655   return message;
656 }
657
658 /**
659  * gst_message_new_new_clock:
660  * @src: (transfer none) (allow-none): The object originating the message.
661  * @clock: (transfer none): the new selected clock
662  *
663  * Create a new clock message. This message is posted whenever the
664  * pipeline selects a new clock for the pipeline.
665  *
666  * Returns: (transfer full): The new new clock message.
667  *
668  * MT safe.
669  */
670 GstMessage *
671 gst_message_new_new_clock (GstObject * src, GstClock * clock)
672 {
673   GstMessage *message;
674   GstStructure *structure;
675
676   structure = gst_structure_new_id (GST_QUARK (MESSAGE_NEW_CLOCK),
677       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
678   message = gst_message_new_custom (GST_MESSAGE_NEW_CLOCK, src, structure);
679
680   return message;
681 }
682
683 /**
684  * gst_message_new_structure_change:
685  * @src: (transfer none) (allow-none): The object originating the message.
686  * @type: The change type.
687  * @owner: (transfer none): The owner element of @src.
688  * @busy: Whether the structure change is busy.
689  *
690  * Create a new structure change message. This message is posted when the
691  * structure of a pipeline is in the process of being changed, for example
692  * when pads are linked or unlinked.
693  *
694  * @src should be the sinkpad that unlinked or linked.
695  *
696  * Returns: (transfer full): the new structure change message.
697  *
698  * MT safe.
699  */
700 GstMessage *
701 gst_message_new_structure_change (GstObject * src, GstStructureChangeType type,
702     GstElement * owner, gboolean busy)
703 {
704   GstMessage *message;
705   GstStructure *structure;
706
707   g_return_val_if_fail (GST_IS_PAD (src), NULL);
708   /* g_return_val_if_fail (GST_PAD_DIRECTION (src) == GST_PAD_SINK, NULL); */
709   g_return_val_if_fail (GST_IS_ELEMENT (owner), NULL);
710
711   structure = gst_structure_new_id (GST_QUARK (MESSAGE_STRUCTURE_CHANGE),
712       GST_QUARK (TYPE), GST_TYPE_STRUCTURE_CHANGE_TYPE, type,
713       GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner,
714       GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy, NULL);
715
716   message = gst_message_new_custom (GST_MESSAGE_STRUCTURE_CHANGE, src,
717       structure);
718
719   return message;
720 }
721
722 /**
723  * gst_message_new_segment_start:
724  * @src: (transfer none) (allow-none): The object originating the message.
725  * @format: The format of the position being played
726  * @position: The position of the segment being played
727  *
728  * Create a new segment message. This message is posted by elements that
729  * start playback of a segment as a result of a segment seek. This message
730  * is not received by the application but is used for maintenance reasons in
731  * container elements.
732  *
733  * Returns: (transfer full): the new segment start message.
734  *
735  * MT safe.
736  */
737 GstMessage *
738 gst_message_new_segment_start (GstObject * src, GstFormat format,
739     gint64 position)
740 {
741   GstMessage *message;
742   GstStructure *structure;
743
744   structure = gst_structure_new_id (GST_QUARK (MESSAGE_SEGMENT_START),
745       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
746       GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
747   message = gst_message_new_custom (GST_MESSAGE_SEGMENT_START, src, structure);
748
749   return message;
750 }
751
752 /**
753  * gst_message_new_segment_done:
754  * @src: (transfer none) (allow-none): The object originating the message.
755  * @format: The format of the position being done
756  * @position: The position of the segment being done
757  *
758  * Create a new segment done message. This message is posted by elements that
759  * finish playback of a segment as a result of a segment seek. This message
760  * is received by the application after all elements that posted a segment_start
761  * have posted the segment_done.
762  *
763  * Returns: (transfer full): the new segment done message.
764  *
765  * MT safe.
766  */
767 GstMessage *
768 gst_message_new_segment_done (GstObject * src, GstFormat format,
769     gint64 position)
770 {
771   GstMessage *message;
772   GstStructure *structure;
773
774   structure = gst_structure_new_id (GST_QUARK (MESSAGE_SEGMENT_DONE),
775       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
776       GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
777   message = gst_message_new_custom (GST_MESSAGE_SEGMENT_DONE, src, structure);
778
779   return message;
780 }
781
782 /**
783  * gst_message_new_application:
784  * @src: (transfer none) (allow-none): The object originating the message.
785  * @structure: (transfer full): the structure for the message. The message
786  *     will take ownership of the structure.
787  *
788  * Create a new application-typed message. GStreamer will never create these
789  * messages; they are a gift from us to you. Enjoy.
790  *
791  * Returns: (transfer full): The new application message.
792  *
793  * MT safe.
794  */
795 GstMessage *
796 gst_message_new_application (GstObject * src, GstStructure * structure)
797 {
798   g_return_val_if_fail (structure != NULL, NULL);
799
800   return gst_message_new_custom (GST_MESSAGE_APPLICATION, src, structure);
801 }
802
803 /**
804  * gst_message_new_element:
805  * @src: (transfer none) (allow-none): The object originating the message.
806  * @structure: (transfer full): The structure for the
807  *     message. The message will take ownership of the structure.
808  *
809  * Create a new element-specific message. This is meant as a generic way of
810  * allowing one-way communication from an element to an application, for example
811  * "the firewire cable was unplugged". The format of the message should be
812  * documented in the element's documentation. The structure field can be %NULL.
813  *
814  * Returns: (transfer full): The new element message.
815  *
816  * MT safe.
817  */
818 GstMessage *
819 gst_message_new_element (GstObject * src, GstStructure * structure)
820 {
821   g_return_val_if_fail (structure != NULL, NULL);
822
823   return gst_message_new_custom (GST_MESSAGE_ELEMENT, src, structure);
824 }
825
826 /**
827  * gst_message_new_duration_changed:
828  * @src: (transfer none) (allow-none): The object originating the message.
829  *
830  * Create a new duration changed message. This message is posted by elements
831  * that know the duration of a stream when the duration changes. This message
832  * is received by bins and is used to calculate the total duration of a
833  * pipeline. Elements may post a duration message with a duration of
834  * GST_CLOCK_TIME_NONE to indicate that the duration has changed and the 
835  * cached duration should be discarded. The new duration can then be 
836  * retrieved via a query.
837  *
838  * Returns: (transfer full): The new duration-changed message.
839  *
840  * MT safe.
841  */
842 GstMessage *
843 gst_message_new_duration_changed (GstObject * src)
844 {
845   GstMessage *message;
846
847   message = gst_message_new_custom (GST_MESSAGE_DURATION_CHANGED, src,
848       gst_structure_new_id_empty (GST_QUARK (MESSAGE_DURATION_CHANGED)));
849
850   return message;
851 }
852
853 /**
854  * gst_message_new_async_start:
855  * @src: (transfer none) (allow-none): The object originating the message.
856  *
857  * This message is posted by elements when they start an ASYNC state change.
858  *
859  * Returns: (transfer full): The new async_start message.
860  *
861  * MT safe.
862  */
863 GstMessage *
864 gst_message_new_async_start (GstObject * src)
865 {
866   GstMessage *message;
867
868   message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src, NULL);
869
870   return message;
871 }
872
873 /**
874  * gst_message_new_async_done:
875  * @src: (transfer none) (allow-none): The object originating the message.
876  * @running_time: the desired running_time
877  *
878  * The message is posted when elements completed an ASYNC state change.
879  * @running_time contains the time of the desired running_time when this
880  * elements goes to PLAYING. A value of #GST_CLOCK_TIME_NONE for @running_time
881  * means that the element has no clock interaction and thus doesn't care about
882  * the running_time of the pipeline.
883  *
884  * Returns: (transfer full): The new async_done message.
885  *
886  * MT safe.
887  */
888 GstMessage *
889 gst_message_new_async_done (GstObject * src, GstClockTime running_time)
890 {
891   GstMessage *message;
892   GstStructure *structure;
893
894   structure = gst_structure_new_id (GST_QUARK (MESSAGE_ASYNC_DONE),
895       GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time, NULL);
896   message = gst_message_new_custom (GST_MESSAGE_ASYNC_DONE, src, structure);
897
898   return message;
899 }
900
901 /**
902  * gst_message_new_latency:
903  * @src: (transfer none) (allow-none): The object originating the message.
904  *
905  * This message can be posted by elements when their latency requirements have
906  * changed.
907  *
908  * Returns: (transfer full): The new latency message.
909  *
910  * MT safe.
911  */
912 GstMessage *
913 gst_message_new_latency (GstObject * src)
914 {
915   GstMessage *message;
916
917   message = gst_message_new_custom (GST_MESSAGE_LATENCY, src, NULL);
918
919   return message;
920 }
921
922 /**
923  * gst_message_new_request_state:
924  * @src: (transfer none) (allow-none): The object originating the message.
925  * @state: The new requested state
926  *
927  * This message can be posted by elements when they want to have their state
928  * changed. A typical use case would be an audio server that wants to pause the
929  * pipeline because a higher priority stream is being played.
930  *
931  * Returns: (transfer full): the new request state message.
932  *
933  * MT safe.
934  */
935 GstMessage *
936 gst_message_new_request_state (GstObject * src, GstState state)
937 {
938   GstMessage *message;
939   GstStructure *structure;
940
941   structure = gst_structure_new_id (GST_QUARK (MESSAGE_REQUEST_STATE),
942       GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) state, NULL);
943   message = gst_message_new_custom (GST_MESSAGE_REQUEST_STATE, src, structure);
944
945   return message;
946 }
947
948 /**
949  * gst_message_get_structure:
950  * @message: The #GstMessage.
951  *
952  * Access the structure of the message.
953  *
954  * Returns: (transfer none): The structure of the message. The structure is
955  * still owned by the message, which means that you should not free it and
956  * that the pointer becomes invalid when you free the message.
957  *
958  * MT safe.
959  */
960 const GstStructure *
961 gst_message_get_structure (GstMessage * message)
962 {
963   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
964
965   return GST_MESSAGE_STRUCTURE (message);
966 }
967
968 /**
969  * gst_message_has_name:
970  * @message: The #GstMessage.
971  * @name: name to check
972  *
973  * Checks if @message has the given @name. This function is usually used to
974  * check the name of a custom message.
975  *
976  * Returns: %TRUE if @name matches the name of the message structure.
977  */
978 gboolean
979 gst_message_has_name (GstMessage * message, const gchar * name)
980 {
981   GstStructure *structure;
982
983   g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
984
985   structure = GST_MESSAGE_STRUCTURE (message);
986   if (structure == NULL)
987     return FALSE;
988
989   return gst_structure_has_name (structure, name);
990 }
991
992 /**
993  * gst_message_parse_tag:
994  * @message: A valid #GstMessage of type GST_MESSAGE_TAG.
995  * @tag_list: (out callee-allocates): return location for the tag-list.
996  *
997  * Extracts the tag list from the GstMessage. The tag list returned in the
998  * output argument is a copy; the caller must free it when done.
999  *
1000  * Typical usage of this function might be:
1001  * |[<!-- language="C" -->
1002  *   ...
1003  *   switch (GST_MESSAGE_TYPE (msg)) {
1004  *     case GST_MESSAGE_TAG: {
1005  *       GstTagList *tags = NULL;
1006  *       
1007  *       gst_message_parse_tag (msg, &amp;tags);
1008  *       g_print ("Got tags from element %s\n", GST_OBJECT_NAME (msg->src));
1009  *       handle_tags (tags);
1010  *       gst_tag_list_unref (tags);
1011  *       break;
1012  *     }
1013  *     ...
1014  *   }
1015  *   ...
1016  * ]|
1017  *
1018  * MT safe.
1019  */
1020 void
1021 gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list)
1022 {
1023   g_return_if_fail (GST_IS_MESSAGE (message));
1024   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
1025   g_return_if_fail (tag_list != NULL);
1026
1027   gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
1028       GST_QUARK (TAGLIST), GST_TYPE_TAG_LIST, tag_list, NULL);
1029 }
1030
1031 /**
1032  * gst_message_parse_buffering:
1033  * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
1034  * @percent: (out) (allow-none): Return location for the percent.
1035  *
1036  * Extracts the buffering percent from the GstMessage. see also
1037  * gst_message_new_buffering().
1038  *
1039  * MT safe.
1040  */
1041 void
1042 gst_message_parse_buffering (GstMessage * message, gint * percent)
1043 {
1044   g_return_if_fail (GST_IS_MESSAGE (message));
1045   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1046
1047   if (percent)
1048     *percent =
1049         g_value_get_int (gst_structure_id_get_value (GST_MESSAGE_STRUCTURE
1050             (message), GST_QUARK (BUFFER_PERCENT)));
1051 }
1052
1053 /**
1054  * gst_message_set_buffering_stats:
1055  * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
1056  * @mode: a buffering mode 
1057  * @avg_in: the average input rate
1058  * @avg_out: the average output rate
1059  * @buffering_left: amount of buffering time left in milliseconds
1060  *
1061  * Configures the buffering stats values in @message.
1062  */
1063 void
1064 gst_message_set_buffering_stats (GstMessage * message, GstBufferingMode mode,
1065     gint avg_in, gint avg_out, gint64 buffering_left)
1066 {
1067   g_return_if_fail (GST_IS_MESSAGE (message));
1068   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1069
1070   gst_structure_id_set (GST_MESSAGE_STRUCTURE (message),
1071       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
1072       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
1073       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
1074       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
1075 }
1076
1077 /**
1078  * gst_message_parse_buffering_stats:
1079  * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
1080  * @mode: (out) (allow-none): a buffering mode, or %NULL
1081  * @avg_in: (out) (allow-none): the average input rate, or %NULL
1082  * @avg_out: (out) (allow-none): the average output rate, or %NULL
1083  * @buffering_left: (out) (allow-none): amount of buffering time left in
1084  *     milliseconds, or %NULL
1085  *
1086  * Extracts the buffering stats values from @message.
1087  */
1088 void
1089 gst_message_parse_buffering_stats (GstMessage * message,
1090     GstBufferingMode * mode, gint * avg_in, gint * avg_out,
1091     gint64 * buffering_left)
1092 {
1093   GstStructure *structure;
1094
1095   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1096
1097   structure = GST_MESSAGE_STRUCTURE (message);
1098   if (mode)
1099     *mode = (GstBufferingMode)
1100         g_value_get_enum (gst_structure_id_get_value (structure,
1101             GST_QUARK (BUFFERING_MODE)));
1102   if (avg_in)
1103     *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
1104             GST_QUARK (AVG_IN_RATE)));
1105   if (avg_out)
1106     *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
1107             GST_QUARK (AVG_OUT_RATE)));
1108   if (buffering_left)
1109     *buffering_left =
1110         g_value_get_int64 (gst_structure_id_get_value (structure,
1111             GST_QUARK (BUFFERING_LEFT)));
1112 }
1113
1114 /**
1115  * gst_message_parse_state_changed:
1116  * @message: a valid #GstMessage of type GST_MESSAGE_STATE_CHANGED
1117  * @oldstate: (out) (allow-none): the previous state, or %NULL
1118  * @newstate: (out) (allow-none): the new (current) state, or %NULL
1119  * @pending: (out) (allow-none): the pending (target) state, or %NULL
1120  *
1121  * Extracts the old and new states from the GstMessage.
1122  *
1123  * Typical usage of this function might be:
1124  * |[<!-- language="C" -->
1125  *   ...
1126  *   switch (GST_MESSAGE_TYPE (msg)) {
1127  *     case GST_MESSAGE_STATE_CHANGED: {
1128  *       GstState old_state, new_state;
1129  *       
1130  *       gst_message_parse_state_changed (msg, &amp;old_state, &amp;new_state, NULL);
1131  *       g_print ("Element %s changed state from %s to %s.\n",
1132  *           GST_OBJECT_NAME (msg->src),
1133  *           gst_element_state_get_name (old_state),
1134  *           gst_element_state_get_name (new_state));
1135  *       break;
1136  *     }
1137  *     ...
1138  *   }
1139  *   ...
1140  * ]|
1141  *
1142  * MT safe.
1143  */
1144 void
1145 gst_message_parse_state_changed (GstMessage * message,
1146     GstState * oldstate, GstState * newstate, GstState * pending)
1147 {
1148   GstStructure *structure;
1149
1150   g_return_if_fail (GST_IS_MESSAGE (message));
1151   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STATE_CHANGED);
1152
1153   structure = GST_MESSAGE_STRUCTURE (message);
1154   if (oldstate)
1155     *oldstate = (GstState)
1156         g_value_get_enum (gst_structure_id_get_value (structure,
1157             GST_QUARK (OLD_STATE)));
1158   if (newstate)
1159     *newstate = (GstState)
1160         g_value_get_enum (gst_structure_id_get_value (structure,
1161             GST_QUARK (NEW_STATE)));
1162   if (pending)
1163     *pending = (GstState)
1164         g_value_get_enum (gst_structure_id_get_value (structure,
1165             GST_QUARK (PENDING_STATE)));
1166 }
1167
1168 /**
1169  * gst_message_parse_clock_provide:
1170  * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_PROVIDE.
1171  * @clock: (out) (allow-none) (transfer none): a pointer to  hold a clock
1172  *     object, or %NULL
1173  * @ready: (out) (allow-none): a pointer to hold the ready flag, or %NULL
1174  *
1175  * Extracts the clock and ready flag from the GstMessage.
1176  * The clock object returned remains valid until the message is freed.
1177  *
1178  * MT safe.
1179  */
1180 void
1181 gst_message_parse_clock_provide (GstMessage * message, GstClock ** clock,
1182     gboolean * ready)
1183 {
1184   const GValue *clock_gvalue;
1185   GstStructure *structure;
1186
1187   g_return_if_fail (GST_IS_MESSAGE (message));
1188   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_PROVIDE);
1189
1190   structure = GST_MESSAGE_STRUCTURE (message);
1191   clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
1192   g_return_if_fail (clock_gvalue != NULL);
1193   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1194
1195   if (ready)
1196     *ready =
1197         g_value_get_boolean (gst_structure_id_get_value (structure,
1198             GST_QUARK (READY)));
1199   if (clock)
1200     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1201 }
1202
1203 /**
1204  * gst_message_parse_clock_lost:
1205  * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_LOST.
1206  * @clock: (out) (allow-none) (transfer none): a pointer to hold the lost clock
1207  *
1208  * Extracts the lost clock from the GstMessage.
1209  * The clock object returned remains valid until the message is freed.
1210  *
1211  * MT safe.
1212  */
1213 void
1214 gst_message_parse_clock_lost (GstMessage * message, GstClock ** clock)
1215 {
1216   const GValue *clock_gvalue;
1217   GstStructure *structure;
1218
1219   g_return_if_fail (GST_IS_MESSAGE (message));
1220   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_LOST);
1221
1222   structure = GST_MESSAGE_STRUCTURE (message);
1223   clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
1224   g_return_if_fail (clock_gvalue != NULL);
1225   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1226
1227   if (clock)
1228     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1229 }
1230
1231 /**
1232  * gst_message_parse_new_clock:
1233  * @message: A valid #GstMessage of type GST_MESSAGE_NEW_CLOCK.
1234  * @clock: (out) (allow-none) (transfer none): a pointer to hold the selected
1235  *     new clock
1236  *
1237  * Extracts the new clock from the GstMessage.
1238  * The clock object returned remains valid until the message is freed.
1239  *
1240  * MT safe.
1241  */
1242 void
1243 gst_message_parse_new_clock (GstMessage * message, GstClock ** clock)
1244 {
1245   const GValue *clock_gvalue;
1246   GstStructure *structure;
1247
1248   g_return_if_fail (GST_IS_MESSAGE (message));
1249   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEW_CLOCK);
1250
1251   structure = GST_MESSAGE_STRUCTURE (message);
1252   clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
1253   g_return_if_fail (clock_gvalue != NULL);
1254   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1255
1256   if (clock)
1257     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1258 }
1259
1260 /**
1261  * gst_message_parse_structure_change:
1262  * @message: A valid #GstMessage of type GST_MESSAGE_STRUCTURE_CHANGE.
1263  * @type: (out): A pointer to hold the change type
1264  * @owner: (out) (allow-none) (transfer none): The owner element of the
1265  *     message source
1266  * @busy: (out) (allow-none): a pointer to hold whether the change is in
1267  *     progress or has been completed
1268  *
1269  * Extracts the change type and completion status from the GstMessage.
1270  *
1271  * MT safe.
1272  */
1273 void
1274 gst_message_parse_structure_change (GstMessage * message,
1275     GstStructureChangeType * type, GstElement ** owner, gboolean * busy)
1276 {
1277   const GValue *owner_gvalue;
1278   GstStructure *structure;
1279
1280   g_return_if_fail (GST_IS_MESSAGE (message));
1281   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STRUCTURE_CHANGE);
1282
1283   structure = GST_MESSAGE_STRUCTURE (message);
1284   owner_gvalue = gst_structure_id_get_value (structure, GST_QUARK (OWNER));
1285   g_return_if_fail (owner_gvalue != NULL);
1286   g_return_if_fail (G_VALUE_TYPE (owner_gvalue) == GST_TYPE_ELEMENT);
1287
1288   if (type)
1289     *type = (GstStructureChangeType)
1290         g_value_get_enum (gst_structure_id_get_value (structure,
1291             GST_QUARK (TYPE)));
1292   if (owner)
1293     *owner = (GstElement *) g_value_get_object (owner_gvalue);
1294   if (busy)
1295     *busy =
1296         g_value_get_boolean (gst_structure_id_get_value (structure,
1297             GST_QUARK (BUSY)));
1298 }
1299
1300 /**
1301  * gst_message_parse_error:
1302  * @message: A valid #GstMessage of type GST_MESSAGE_ERROR.
1303  * @gerror: (out) (allow-none) (transfer full): location for the GError
1304  * @debug: (out) (allow-none) (transfer full): location for the debug message,
1305  *     or %NULL
1306  *
1307  * Extracts the GError and debug string from the GstMessage. The values returned
1308  * in the output arguments are copies; the caller must free them when done.
1309  *
1310  * Typical usage of this function might be:
1311  * |[<!-- language="C" -->
1312  *   ...
1313  *   switch (GST_MESSAGE_TYPE (msg)) {
1314  *     case GST_MESSAGE_ERROR: {
1315  *       GError *err = NULL;
1316  *       gchar *dbg_info = NULL;
1317  *       
1318  *       gst_message_parse_error (msg, &amp;err, &amp;dbg_info);
1319  *       g_printerr ("ERROR from element %s: %s\n",
1320  *           GST_OBJECT_NAME (msg->src), err->message);
1321  *       g_printerr ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
1322  *       g_error_free (err);
1323  *       g_free (dbg_info);
1324  *       break;
1325  *     }
1326  *     ...
1327  *   }
1328  *   ...
1329  * ]|
1330  *
1331  * MT safe.
1332  */
1333 void
1334 gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug)
1335 {
1336   g_return_if_fail (GST_IS_MESSAGE (message));
1337   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
1338
1339   gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
1340       GST_QUARK (GERROR), G_TYPE_ERROR, gerror,
1341       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
1342 }
1343
1344 /**
1345  * gst_message_parse_warning:
1346  * @message: A valid #GstMessage of type GST_MESSAGE_WARNING.
1347  * @gerror: (out) (allow-none) (transfer full): location for the GError
1348  * @debug: (out) (allow-none) (transfer full): location for the debug message,
1349  *     or %NULL
1350  *
1351  * Extracts the GError and debug string from the GstMessage. The values returned
1352  * in the output arguments are copies; the caller must free them when done.
1353  *
1354  * MT safe.
1355  */
1356 void
1357 gst_message_parse_warning (GstMessage * message, GError ** gerror,
1358     gchar ** debug)
1359 {
1360   g_return_if_fail (GST_IS_MESSAGE (message));
1361   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);
1362
1363   gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
1364       GST_QUARK (GERROR), G_TYPE_ERROR, gerror,
1365       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
1366 }
1367
1368 /**
1369  * gst_message_parse_info:
1370  * @message: A valid #GstMessage of type GST_MESSAGE_INFO.
1371  * @gerror: (out) (allow-none) (transfer full): location for the GError
1372  * @debug: (out) (allow-none) (transfer full): location for the debug message,
1373  *     or %NULL
1374  *
1375  * Extracts the GError and debug string from the GstMessage. The values returned
1376  * in the output arguments are copies; the caller must free them when done.
1377  *
1378  * MT safe.
1379  */
1380 void
1381 gst_message_parse_info (GstMessage * message, GError ** gerror, gchar ** debug)
1382 {
1383   g_return_if_fail (GST_IS_MESSAGE (message));
1384   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO);
1385
1386   gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
1387       GST_QUARK (GERROR), G_TYPE_ERROR, gerror,
1388       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
1389 }
1390
1391 /**
1392  * gst_message_parse_segment_start:
1393  * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_START.
1394  * @format: (out) (allow-none): Result location for the format, or %NULL
1395  * @position: (out) (allow-none): Result location for the position, or %NULL
1396  *
1397  * Extracts the position and format from the segment start message.
1398  *
1399  * MT safe.
1400  */
1401 void
1402 gst_message_parse_segment_start (GstMessage * message, GstFormat * format,
1403     gint64 * position)
1404 {
1405   GstStructure *structure;
1406
1407   g_return_if_fail (GST_IS_MESSAGE (message));
1408   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_START);
1409
1410   structure = GST_MESSAGE_STRUCTURE (message);
1411   if (format)
1412     *format = (GstFormat)
1413         g_value_get_enum (gst_structure_id_get_value (structure,
1414             GST_QUARK (FORMAT)));
1415   if (position)
1416     *position =
1417         g_value_get_int64 (gst_structure_id_get_value (structure,
1418             GST_QUARK (POSITION)));
1419 }
1420
1421 /**
1422  * gst_message_parse_segment_done:
1423  * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_DONE.
1424  * @format: (out) (allow-none): Result location for the format, or %NULL
1425  * @position: (out) (allow-none): Result location for the position, or %NULL
1426  *
1427  * Extracts the position and format from the segment done message.
1428  *
1429  * MT safe.
1430  */
1431 void
1432 gst_message_parse_segment_done (GstMessage * message, GstFormat * format,
1433     gint64 * position)
1434 {
1435   GstStructure *structure;
1436
1437   g_return_if_fail (GST_IS_MESSAGE (message));
1438   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_DONE);
1439
1440   structure = GST_MESSAGE_STRUCTURE (message);
1441   if (format)
1442     *format = (GstFormat)
1443         g_value_get_enum (gst_structure_id_get_value (structure,
1444             GST_QUARK (FORMAT)));
1445   if (position)
1446     *position =
1447         g_value_get_int64 (gst_structure_id_get_value (structure,
1448             GST_QUARK (POSITION)));
1449 }
1450
1451 /**
1452  * gst_message_parse_async_done:
1453  * @message: A valid #GstMessage of type GST_MESSAGE_ASYNC_DONE.
1454  * @running_time: (out) (allow-none): Result location for the running_time or %NULL
1455  *
1456  * Extract the running_time from the async_done message.
1457  *
1458  * MT safe.
1459  */
1460 void
1461 gst_message_parse_async_done (GstMessage * message, GstClockTime * running_time)
1462 {
1463   GstStructure *structure;
1464
1465   g_return_if_fail (GST_IS_MESSAGE (message));
1466   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ASYNC_DONE);
1467
1468   structure = GST_MESSAGE_STRUCTURE (message);
1469   if (running_time)
1470     *running_time =
1471         g_value_get_uint64 (gst_structure_id_get_value (structure,
1472             GST_QUARK (RUNNING_TIME)));
1473 }
1474
1475 /**
1476  * gst_message_parse_request_state:
1477  * @message: A valid #GstMessage of type GST_MESSAGE_REQUEST_STATE.
1478  * @state: (out) (allow-none): Result location for the requested state or %NULL
1479  *
1480  * Extract the requested state from the request_state message.
1481  *
1482  * MT safe.
1483  */
1484 void
1485 gst_message_parse_request_state (GstMessage * message, GstState * state)
1486 {
1487   GstStructure *structure;
1488
1489   g_return_if_fail (GST_IS_MESSAGE (message));
1490   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REQUEST_STATE);
1491
1492   structure = GST_MESSAGE_STRUCTURE (message);
1493   if (state)
1494     *state = (GstState)
1495         g_value_get_enum (gst_structure_id_get_value (structure,
1496             GST_QUARK (NEW_STATE)));
1497 }
1498
1499 /**
1500  * gst_message_new_stream_status:
1501  * @src: The object originating the message.
1502  * @type: The stream status type.
1503  * @owner: (transfer none): the owner element of @src.
1504  *
1505  * Create a new stream status message. This message is posted when a streaming
1506  * thread is created/destroyed or when the state changed.
1507  * 
1508  * Returns: (transfer full): the new stream status message.
1509  *
1510  * MT safe.
1511  */
1512 GstMessage *
1513 gst_message_new_stream_status (GstObject * src, GstStreamStatusType type,
1514     GstElement * owner)
1515 {
1516   GstMessage *message;
1517   GstStructure *structure;
1518
1519   structure = gst_structure_new_id (GST_QUARK (MESSAGE_STREAM_STATUS),
1520       GST_QUARK (TYPE), GST_TYPE_STREAM_STATUS_TYPE, (gint) type,
1521       GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner, NULL);
1522   message = gst_message_new_custom (GST_MESSAGE_STREAM_STATUS, src, structure);
1523
1524   return message;
1525 }
1526
1527 /**
1528  * gst_message_parse_stream_status:
1529  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1530  * @type: (out): A pointer to hold the status type
1531  * @owner: (out) (transfer none): The owner element of the message source
1532  *
1533  * Extracts the stream status type and owner the GstMessage. The returned
1534  * owner remains valid for as long as the reference to @message is valid and
1535  * should thus not be unreffed.
1536  *
1537  * MT safe.
1538  */
1539 void
1540 gst_message_parse_stream_status (GstMessage * message,
1541     GstStreamStatusType * type, GstElement ** owner)
1542 {
1543   const GValue *owner_gvalue;
1544   GstStructure *structure;
1545
1546   g_return_if_fail (GST_IS_MESSAGE (message));
1547   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
1548
1549   structure = GST_MESSAGE_STRUCTURE (message);
1550   owner_gvalue = gst_structure_id_get_value (structure, GST_QUARK (OWNER));
1551   g_return_if_fail (owner_gvalue != NULL);
1552
1553   if (type)
1554     *type = (GstStreamStatusType)
1555         g_value_get_enum (gst_structure_id_get_value (structure,
1556             GST_QUARK (TYPE)));
1557   if (owner)
1558     *owner = (GstElement *) g_value_get_object (owner_gvalue);
1559 }
1560
1561 /**
1562  * gst_message_set_stream_status_object:
1563  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1564  * @object: the object controlling the streaming
1565  *
1566  * Configures the object handling the streaming thread. This is usually a
1567  * GstTask object but other objects might be added in the future.
1568  */
1569 void
1570 gst_message_set_stream_status_object (GstMessage * message,
1571     const GValue * object)
1572 {
1573   GstStructure *structure;
1574
1575   g_return_if_fail (GST_IS_MESSAGE (message));
1576   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
1577
1578   structure = GST_MESSAGE_STRUCTURE (message);
1579   gst_structure_id_set_value (structure, GST_QUARK (OBJECT), object);
1580 }
1581
1582 /**
1583  * gst_message_get_stream_status_object:
1584  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1585  *
1586  * Extracts the object managing the streaming thread from @message.
1587  *
1588  * Returns: a GValue containing the object that manages the streaming thread.
1589  * This object is usually of type GstTask but other types can be added in the
1590  * future. The object remains valid as long as @message is valid.
1591  */
1592 const GValue *
1593 gst_message_get_stream_status_object (GstMessage * message)
1594 {
1595   const GValue *result;
1596   GstStructure *structure;
1597
1598   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
1599   g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS,
1600       NULL);
1601
1602   structure = GST_MESSAGE_STRUCTURE (message);
1603   result = gst_structure_id_get_value (structure, GST_QUARK (OBJECT));
1604
1605   return result;
1606 }
1607
1608 /**
1609  * gst_message_new_step_done:
1610  * @src: The object originating the message.
1611  * @format: the format of @amount
1612  * @amount: the amount of stepped data
1613  * @rate: the rate of the stepped amount
1614  * @flush: is this an flushing step
1615  * @intermediate: is this an intermediate step
1616  * @duration: the duration of the data
1617  * @eos: the step caused EOS
1618  *
1619  * This message is posted by elements when they complete a part, when @intermediate set
1620  * to %TRUE, or a complete step operation.
1621  *
1622  * @duration will contain the amount of time (in GST_FORMAT_TIME) of the stepped
1623  * @amount of media in format @format.
1624  *
1625  * Returns: (transfer full): the new step_done message.
1626  *
1627  * MT safe.
1628  */
1629 GstMessage *
1630 gst_message_new_step_done (GstObject * src, GstFormat format, guint64 amount,
1631     gdouble rate, gboolean flush, gboolean intermediate, guint64 duration,
1632     gboolean eos)
1633 {
1634   GstMessage *message;
1635   GstStructure *structure;
1636
1637   structure = gst_structure_new_id (GST_QUARK (MESSAGE_STEP_DONE),
1638       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1639       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
1640       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
1641       GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
1642       GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate,
1643       GST_QUARK (DURATION), G_TYPE_UINT64, duration,
1644       GST_QUARK (EOS), G_TYPE_BOOLEAN, eos, NULL);
1645   message = gst_message_new_custom (GST_MESSAGE_STEP_DONE, src, structure);
1646
1647   return message;
1648 }
1649
1650 /**
1651  * gst_message_parse_step_done:
1652  * @message: A valid #GstMessage of type GST_MESSAGE_STEP_DONE.
1653  * @format: (out) (allow-none): result location for the format
1654  * @amount: (out) (allow-none): result location for the amount
1655  * @rate: (out) (allow-none): result location for the rate
1656  * @flush: (out) (allow-none): result location for the flush flag
1657  * @intermediate: (out) (allow-none): result location for the intermediate flag
1658  * @duration: (out) (allow-none): result location for the duration
1659  * @eos: (out) (allow-none): result location for the EOS flag
1660  *
1661  * Extract the values the step_done message.
1662  *
1663  * MT safe.
1664  */
1665 void
1666 gst_message_parse_step_done (GstMessage * message, GstFormat * format,
1667     guint64 * amount, gdouble * rate, gboolean * flush, gboolean * intermediate,
1668     guint64 * duration, gboolean * eos)
1669 {
1670   GstStructure *structure;
1671
1672   g_return_if_fail (GST_IS_MESSAGE (message));
1673   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_DONE);
1674
1675   structure = GST_MESSAGE_STRUCTURE (message);
1676   gst_structure_id_get (structure,
1677       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1678       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
1679       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
1680       GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
1681       GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate,
1682       GST_QUARK (DURATION), G_TYPE_UINT64, duration,
1683       GST_QUARK (EOS), G_TYPE_BOOLEAN, eos, NULL);
1684 }
1685
1686 /**
1687  * gst_message_new_step_start:
1688  * @src: The object originating the message.
1689  * @active: if the step is active or queued
1690  * @format: the format of @amount
1691  * @amount: the amount of stepped data
1692  * @rate: the rate of the stepped amount
1693  * @flush: is this an flushing step
1694  * @intermediate: is this an intermediate step
1695  *
1696  * This message is posted by elements when they accept or activate a new step
1697  * event for @amount in @format. 
1698  *
1699  * @active is set to %FALSE when the element accepted the new step event and has
1700  * queued it for execution in the streaming threads.
1701  *
1702  * @active is set to %TRUE when the element has activated the step operation and
1703  * is now ready to start executing the step in the streaming thread. After this
1704  * message is emitted, the application can queue a new step operation in the
1705  * element.
1706  *
1707  * Returns: (transfer full): The new step_start message. 
1708  *
1709  * MT safe.
1710  */
1711 GstMessage *
1712 gst_message_new_step_start (GstObject * src, gboolean active, GstFormat format,
1713     guint64 amount, gdouble rate, gboolean flush, gboolean intermediate)
1714 {
1715   GstMessage *message;
1716   GstStructure *structure;
1717
1718   structure = gst_structure_new_id (GST_QUARK (MESSAGE_STEP_START),
1719       GST_QUARK (ACTIVE), G_TYPE_BOOLEAN, active,
1720       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1721       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
1722       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
1723       GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
1724       GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate, NULL);
1725   message = gst_message_new_custom (GST_MESSAGE_STEP_START, src, structure);
1726
1727   return message;
1728 }
1729
1730 /**
1731  * gst_message_parse_step_start:
1732  * @message: A valid #GstMessage of type GST_MESSAGE_STEP_DONE.
1733  * @active: (out) (allow-none): result location for the active flag
1734  * @format: (out) (allow-none): result location for the format
1735  * @amount: (out) (allow-none): result location for the amount
1736  * @rate: (out) (allow-none): result location for the rate
1737  * @flush: (out) (allow-none): result location for the flush flag
1738  * @intermediate: (out) (allow-none): result location for the intermediate flag
1739  *
1740  * Extract the values from step_start message.
1741  *
1742  * MT safe.
1743  */
1744 void
1745 gst_message_parse_step_start (GstMessage * message, gboolean * active,
1746     GstFormat * format, guint64 * amount, gdouble * rate, gboolean * flush,
1747     gboolean * intermediate)
1748 {
1749   GstStructure *structure;
1750
1751   g_return_if_fail (GST_IS_MESSAGE (message));
1752   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_START);
1753
1754   structure = GST_MESSAGE_STRUCTURE (message);
1755   gst_structure_id_get (structure,
1756       GST_QUARK (ACTIVE), G_TYPE_BOOLEAN, active,
1757       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1758       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
1759       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
1760       GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
1761       GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate, NULL);
1762 }
1763
1764 /**
1765  * gst_message_new_qos:
1766  * @src: The object originating the message.
1767  * @live: if the message was generated by a live element
1768  * @running_time: the running time of the buffer that generated the message
1769  * @stream_time: the stream time of the buffer that generated the message
1770  * @timestamp: the timestamps of the buffer that generated the message
1771  * @duration: the duration of the buffer that generated the message
1772  *
1773  * A QOS message is posted on the bus whenever an element decides to drop a
1774  * buffer because of QoS reasons or whenever it changes its processing strategy
1775  * because of QoS reasons (quality adjustments such as processing at lower
1776  * accuracy).
1777  *
1778  * This message can be posted by an element that performs synchronisation against the
1779  * clock (live) or it could be dropped by an element that performs QoS because of QOS
1780  * events received from a downstream element (!live).
1781  *
1782  * @running_time, @stream_time, @timestamp, @duration should be set to the
1783  * respective running-time, stream-time, timestamp and duration of the (dropped)
1784  * buffer that generated the QoS event. Values can be left to
1785  * GST_CLOCK_TIME_NONE when unknown.
1786  *
1787  * Returns: (transfer full): The new qos message.
1788  *
1789  * MT safe.
1790  */
1791 GstMessage *
1792 gst_message_new_qos (GstObject * src, gboolean live, guint64 running_time,
1793     guint64 stream_time, guint64 timestamp, guint64 duration)
1794 {
1795   GstMessage *message;
1796   GstStructure *structure;
1797
1798   structure = gst_structure_new_id (GST_QUARK (MESSAGE_QOS),
1799       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
1800       GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time,
1801       GST_QUARK (STREAM_TIME), G_TYPE_UINT64, stream_time,
1802       GST_QUARK (TIMESTAMP), G_TYPE_UINT64, timestamp,
1803       GST_QUARK (DURATION), G_TYPE_UINT64, duration,
1804       GST_QUARK (JITTER), G_TYPE_INT64, (gint64) 0,
1805       GST_QUARK (PROPORTION), G_TYPE_DOUBLE, (gdouble) 1.0,
1806       GST_QUARK (QUALITY), G_TYPE_INT, (gint) 1000000,
1807       GST_QUARK (FORMAT), GST_TYPE_FORMAT, GST_FORMAT_UNDEFINED,
1808       GST_QUARK (PROCESSED), G_TYPE_UINT64, (guint64) - 1,
1809       GST_QUARK (DROPPED), G_TYPE_UINT64, (guint64) - 1, NULL);
1810   message = gst_message_new_custom (GST_MESSAGE_QOS, src, structure);
1811
1812   return message;
1813 }
1814
1815 /**
1816  * gst_message_set_qos_values:
1817  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
1818  * @jitter: The difference of the running-time against the deadline.
1819  * @proportion: Long term prediction of the ideal rate relative to normal rate
1820  * to get optimal quality.
1821  * @quality: An element dependent integer value that specifies the current
1822  * quality level of the element. The default maximum quality is 1000000.
1823  *
1824  * Set the QoS values that have been calculated/analysed from the QoS data
1825  *
1826  * MT safe.
1827  */
1828 void
1829 gst_message_set_qos_values (GstMessage * message, gint64 jitter,
1830     gdouble proportion, gint quality)
1831 {
1832   GstStructure *structure;
1833
1834   g_return_if_fail (GST_IS_MESSAGE (message));
1835   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
1836
1837   structure = GST_MESSAGE_STRUCTURE (message);
1838   gst_structure_id_set (structure,
1839       GST_QUARK (JITTER), G_TYPE_INT64, jitter,
1840       GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
1841       GST_QUARK (QUALITY), G_TYPE_INT, quality, NULL);
1842 }
1843
1844 /**
1845  * gst_message_set_qos_stats:
1846  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
1847  * @format: Units of the 'processed' and 'dropped' fields. Video sinks and video
1848  * filters will use GST_FORMAT_BUFFERS (frames). Audio sinks and audio filters
1849  * will likely use GST_FORMAT_DEFAULT (samples).
1850  * @processed: Total number of units correctly processed since the last state
1851  * change to READY or a flushing operation.
1852  * @dropped: Total number of units dropped since the last state change to READY
1853  * or a flushing operation.
1854  *
1855  * Set the QoS stats representing the history of the current continuous pipeline
1856  * playback period.
1857  *
1858  * When @format is @GST_FORMAT_UNDEFINED both @dropped and @processed are
1859  * invalid. Values of -1 for either @processed or @dropped mean unknown values.
1860  *
1861  * MT safe.
1862  */
1863 void
1864 gst_message_set_qos_stats (GstMessage * message, GstFormat format,
1865     guint64 processed, guint64 dropped)
1866 {
1867   GstStructure *structure;
1868
1869   g_return_if_fail (GST_IS_MESSAGE (message));
1870   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
1871
1872   structure = GST_MESSAGE_STRUCTURE (message);
1873   gst_structure_id_set (structure,
1874       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1875       GST_QUARK (PROCESSED), G_TYPE_UINT64, processed,
1876       GST_QUARK (DROPPED), G_TYPE_UINT64, dropped, NULL);
1877 }
1878
1879 /**
1880  * gst_message_parse_qos:
1881  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
1882  * @live: (out) (allow-none): if the message was generated by a live element
1883  * @running_time: (out) (allow-none): the running time of the buffer that
1884  *     generated the message
1885  * @stream_time: (out) (allow-none): the stream time of the buffer that
1886  *     generated the message
1887  * @timestamp: (out) (allow-none): the timestamps of the buffer that
1888  *     generated the message
1889  * @duration: (out) (allow-none): the duration of the buffer that
1890  *     generated the message
1891  *
1892  * Extract the timestamps and live status from the QoS message.
1893  *
1894  * The returned values give the running_time, stream_time, timestamp and
1895  * duration of the dropped buffer. Values of GST_CLOCK_TIME_NONE mean unknown
1896  * values.
1897  *
1898  * MT safe.
1899  */
1900 void
1901 gst_message_parse_qos (GstMessage * message, gboolean * live,
1902     guint64 * running_time, guint64 * stream_time, guint64 * timestamp,
1903     guint64 * duration)
1904 {
1905   GstStructure *structure;
1906
1907   g_return_if_fail (GST_IS_MESSAGE (message));
1908   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
1909
1910   structure = GST_MESSAGE_STRUCTURE (message);
1911   gst_structure_id_get (structure,
1912       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
1913       GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time,
1914       GST_QUARK (STREAM_TIME), G_TYPE_UINT64, stream_time,
1915       GST_QUARK (TIMESTAMP), G_TYPE_UINT64, timestamp,
1916       GST_QUARK (DURATION), G_TYPE_UINT64, duration, NULL);
1917 }
1918
1919 /**
1920  * gst_message_parse_qos_values:
1921  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
1922  * @jitter: (out) (allow-none): The difference of the running-time against
1923  *     the deadline.
1924  * @proportion: (out) (allow-none): Long term prediction of the ideal rate
1925  *     relative to normal rate to get optimal quality.
1926  * @quality: (out) (allow-none): An element dependent integer value that
1927  *     specifies the current quality level of the element. The default
1928  *     maximum quality is 1000000.
1929  *
1930  * Extract the QoS values that have been calculated/analysed from the QoS data
1931  *
1932  * MT safe.
1933  */
1934 void
1935 gst_message_parse_qos_values (GstMessage * message, gint64 * jitter,
1936     gdouble * proportion, gint * quality)
1937 {
1938   GstStructure *structure;
1939
1940   g_return_if_fail (GST_IS_MESSAGE (message));
1941   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
1942
1943   structure = GST_MESSAGE_STRUCTURE (message);
1944   gst_structure_id_get (structure,
1945       GST_QUARK (JITTER), G_TYPE_INT64, jitter,
1946       GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
1947       GST_QUARK (QUALITY), G_TYPE_INT, quality, NULL);
1948 }
1949
1950 /**
1951  * gst_message_parse_qos_stats:
1952  * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
1953  * @format: (out) (allow-none): Units of the 'processed' and 'dropped' fields.
1954  *     Video sinks and video filters will use GST_FORMAT_BUFFERS (frames).
1955  *     Audio sinks and audio filters will likely use GST_FORMAT_DEFAULT
1956  *     (samples).
1957  * @processed: (out) (allow-none): Total number of units correctly processed
1958  *     since the last state change to READY or a flushing operation.
1959  * @dropped: (out) (allow-none): Total number of units dropped since the last
1960  *     state change to READY or a flushing operation.
1961  *
1962  * Extract the QoS stats representing the history of the current continuous
1963  * pipeline playback period.
1964  *
1965  * When @format is @GST_FORMAT_UNDEFINED both @dropped and @processed are
1966  * invalid. Values of -1 for either @processed or @dropped mean unknown values.
1967  *
1968  * MT safe.
1969  */
1970 void
1971 gst_message_parse_qos_stats (GstMessage * message, GstFormat * format,
1972     guint64 * processed, guint64 * dropped)
1973 {
1974   GstStructure *structure;
1975
1976   g_return_if_fail (GST_IS_MESSAGE (message));
1977   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
1978
1979   structure = GST_MESSAGE_STRUCTURE (message);
1980   gst_structure_id_get (structure,
1981       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
1982       GST_QUARK (PROCESSED), G_TYPE_UINT64, processed,
1983       GST_QUARK (DROPPED), G_TYPE_UINT64, dropped, NULL);
1984 }
1985
1986 /**
1987  * gst_message_new_progress:
1988  * @src: The object originating the message.
1989  * @type: a #GstProgressType
1990  * @code: a progress code
1991  * @text: free, user visible text describing the progress
1992  *
1993  * Progress messages are posted by elements when they use an asynchronous task
1994  * to perform actions triggered by a state change.
1995  *
1996  * @code contains a well defined string describing the action.
1997  * @test should contain a user visible string detailing the current action.
1998  *
1999  * Returns: (transfer full): The new qos message.
2000  */
2001 GstMessage *
2002 gst_message_new_progress (GstObject * src, GstProgressType type,
2003     const gchar * code, const gchar * text)
2004 {
2005   GstMessage *message;
2006   GstStructure *structure;
2007   gint percent = 100, timeout = -1;
2008
2009   g_return_val_if_fail (code != NULL, NULL);
2010   g_return_val_if_fail (text != NULL, NULL);
2011
2012   if (type == GST_PROGRESS_TYPE_START || type == GST_PROGRESS_TYPE_CONTINUE)
2013     percent = 0;
2014
2015   structure = gst_structure_new_id (GST_QUARK (MESSAGE_PROGRESS),
2016       GST_QUARK (TYPE), GST_TYPE_PROGRESS_TYPE, type,
2017       GST_QUARK (CODE), G_TYPE_STRING, code,
2018       GST_QUARK (TEXT), G_TYPE_STRING, text,
2019       GST_QUARK (PERCENT), G_TYPE_INT, percent,
2020       GST_QUARK (TIMEOUT), G_TYPE_INT, timeout, NULL);
2021   message = gst_message_new_custom (GST_MESSAGE_PROGRESS, src, structure);
2022
2023   return message;
2024 }
2025
2026 /**
2027  * gst_message_parse_progress:
2028  * @message: A valid #GstMessage of type GST_MESSAGE_PROGRESS.
2029  * @type: (out) (allow-none): location for the type
2030  * @code: (out) (allow-none) (transfer full): location for the code
2031  * @text: (out) (allow-none) (transfer full): location for the text
2032  *
2033  * Parses the progress @type, @code and @text.
2034  */
2035 void
2036 gst_message_parse_progress (GstMessage * message, GstProgressType * type,
2037     gchar ** code, gchar ** text)
2038 {
2039   GstStructure *structure;
2040
2041   g_return_if_fail (GST_IS_MESSAGE (message));
2042   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_PROGRESS);
2043
2044   structure = GST_MESSAGE_STRUCTURE (message);
2045   gst_structure_id_get (structure,
2046       GST_QUARK (TYPE), GST_TYPE_PROGRESS_TYPE, type,
2047       GST_QUARK (CODE), G_TYPE_STRING, code,
2048       GST_QUARK (TEXT), G_TYPE_STRING, text, NULL);
2049 }
2050
2051 /**
2052  * gst_message_new_toc:
2053  * @src: the object originating the message.
2054  * @toc: (transfer none): #GstToc structure for the message.
2055  * @updated: whether TOC was updated or not.
2056  *
2057  * Create a new TOC message. The message is posted by elements
2058  * that discovered or updated a TOC.
2059  *
2060  * Returns: (transfer full): a new TOC message.
2061  *
2062  * MT safe.
2063  */
2064 GstMessage *
2065 gst_message_new_toc (GstObject * src, GstToc * toc, gboolean updated)
2066 {
2067   GstStructure *toc_struct;
2068
2069   g_return_val_if_fail (toc != NULL, NULL);
2070
2071   toc_struct = gst_structure_new_id (GST_QUARK (MESSAGE_TOC),
2072       GST_QUARK (TOC), GST_TYPE_TOC, toc,
2073       GST_QUARK (UPDATED), G_TYPE_BOOLEAN, updated, NULL);
2074
2075   return gst_message_new_custom (GST_MESSAGE_TOC, src, toc_struct);
2076 }
2077
2078 /**
2079  * gst_message_parse_toc:
2080  * @message: a valid #GstMessage of type GST_MESSAGE_TOC.
2081  * @toc: (out) (transfer full): return location for the TOC.
2082  * @updated: (out): return location for the updated flag.
2083  *
2084  * Extract the TOC from the #GstMessage. The TOC returned in the
2085  * output argument is a copy; the caller must free it with
2086  * gst_toc_unref() when done.
2087  *
2088  * MT safe.
2089  */
2090 void
2091 gst_message_parse_toc (GstMessage * message, GstToc ** toc, gboolean * updated)
2092 {
2093   g_return_if_fail (GST_IS_MESSAGE (message));
2094   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TOC);
2095   g_return_if_fail (toc != NULL);
2096
2097   gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
2098       GST_QUARK (TOC), GST_TYPE_TOC, toc,
2099       GST_QUARK (UPDATED), G_TYPE_BOOLEAN, updated, NULL);
2100 }
2101
2102 /**
2103  * gst_message_new_reset_time:
2104  * @src: (transfer none) (allow-none): The object originating the message.
2105  * @running_time: the requested running-time
2106  *
2107  * This message is posted when the pipeline running-time should be reset to
2108  * @running_time, like after a flushing seek.
2109  *
2110  * Returns: (transfer full): The new reset_time message.
2111  *
2112  * MT safe.
2113  */
2114 GstMessage *
2115 gst_message_new_reset_time (GstObject * src, GstClockTime running_time)
2116 {
2117   GstMessage *message;
2118   GstStructure *structure;
2119
2120   structure = gst_structure_new_id (GST_QUARK (MESSAGE_RESET_TIME),
2121       GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time, NULL);
2122   message = gst_message_new_custom (GST_MESSAGE_RESET_TIME, src, structure);
2123
2124   return message;
2125 }
2126
2127 /**
2128  * gst_message_parse_reset_time:
2129  * @message: A valid #GstMessage of type GST_MESSAGE_RESET_TIME.
2130  * @running_time: (out) (allow-none): Result location for the running_time or
2131  *      %NULL
2132  *
2133  * Extract the running-time from the RESET_TIME message.
2134  *
2135  * MT safe.
2136  */
2137 void
2138 gst_message_parse_reset_time (GstMessage * message, GstClockTime * running_time)
2139 {
2140   GstStructure *structure;
2141
2142   g_return_if_fail (GST_IS_MESSAGE (message));
2143   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_RESET_TIME);
2144
2145   structure = GST_MESSAGE_STRUCTURE (message);
2146   if (running_time)
2147     *running_time =
2148         g_value_get_uint64 (gst_structure_id_get_value (structure,
2149             GST_QUARK (RUNNING_TIME)));
2150 }
2151
2152 /**
2153  * gst_message_new_stream_start:
2154  * @src: (transfer none) (allow-none): The object originating the message.
2155  *
2156  * Create a new stream_start message. This message is generated and posted in
2157  * the sink elements of a GstBin. The bin will only forward the STREAM_START
2158  * message to the application if all sinks have posted an STREAM_START message.
2159  *
2160  * Returns: (transfer full): The new stream_start message.
2161  *
2162  * MT safe.
2163  */
2164 GstMessage *
2165 gst_message_new_stream_start (GstObject * src)
2166 {
2167   GstMessage *message;
2168   GstStructure *s;
2169
2170   s = gst_structure_new_id_empty (GST_QUARK (MESSAGE_STREAM_START));
2171   message = gst_message_new_custom (GST_MESSAGE_STREAM_START, src, s);
2172
2173   return message;
2174 }
2175
2176
2177 /**
2178  * gst_message_set_group_id:
2179  * @message: the message
2180  * @group_id: the group id
2181  *
2182  * Sets the group id on the stream-start message.
2183  *
2184  * All streams that have the same group id are supposed to be played
2185  * together, i.e. all streams inside a container file should have the
2186  * same group id but different stream ids. The group id should change
2187  * each time the stream is started, resulting in different group ids
2188  * each time a file is played for example.
2189  *
2190  * MT safe.
2191  *
2192  * Since: 1.2
2193  */
2194 void
2195 gst_message_set_group_id (GstMessage * message, guint group_id)
2196 {
2197   GstStructure *structure;
2198
2199   g_return_if_fail (GST_IS_MESSAGE (message));
2200   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_START);
2201   g_return_if_fail (gst_message_is_writable (message));
2202
2203   structure = GST_MESSAGE_STRUCTURE (message);
2204   gst_structure_id_set (structure, GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id,
2205       NULL);
2206 }
2207
2208 /**
2209  * gst_message_parse_group_id:
2210  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_START.
2211  * @group_id: (out) (allow-none): Result location for the group id or
2212  *      %NULL
2213  *
2214  * Extract the group from the STREAM_START message.
2215  *
2216  * Returns: %TRUE if the message had a group id set, %FALSE otherwise
2217  *
2218  * MT safe.
2219  *
2220  * Since: 1.2
2221  */
2222 gboolean
2223 gst_message_parse_group_id (GstMessage * message, guint * group_id)
2224 {
2225   GstStructure *structure;
2226   const GValue *v;
2227
2228   g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
2229   g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_START,
2230       FALSE);
2231
2232   if (!group_id)
2233     return TRUE;
2234
2235   structure = GST_MESSAGE_STRUCTURE (message);
2236
2237   v = gst_structure_id_get_value (structure, GST_QUARK (GROUP_ID));
2238   if (!v)
2239     return FALSE;
2240
2241   *group_id = g_value_get_uint (v);
2242   return TRUE;
2243 }
2244
2245 /**
2246  * gst_message_new_need_context:
2247  * @src: (transfer none) (allow-none): The object originating the message.
2248  * @context_type: The context type that is needed
2249  *
2250  * This message is posted when an element needs a specific #GstContext.
2251  *
2252  * Returns: (transfer full): The new need-context message.
2253  *
2254  * MT safe.
2255  *
2256  * Since: 1.2
2257  */
2258 GstMessage *
2259 gst_message_new_need_context (GstObject * src, const gchar * context_type)
2260 {
2261   GstMessage *message;
2262   GstStructure *structure;
2263
2264   g_return_val_if_fail (context_type != NULL, NULL);
2265
2266   structure = gst_structure_new_id (GST_QUARK (MESSAGE_NEED_CONTEXT),
2267       GST_QUARK (CONTEXT_TYPE), G_TYPE_STRING, context_type, NULL);
2268   message = gst_message_new_custom (GST_MESSAGE_NEED_CONTEXT, src, structure);
2269
2270   return message;
2271 }
2272
2273 /**
2274  * gst_message_parse_context_type:
2275  * @message: a GST_MESSAGE_NEED_CONTEXT type message
2276  * @context_type: (out) (allow-none): the context type, or %NULL
2277  *
2278  * Parse a context type from an existing GST_MESSAGE_NEED_CONTEXT message.
2279  *
2280  * Returns: a #gboolean indicating if the parsing succeeded.
2281  *
2282  * Since: 1.2
2283  */
2284 gboolean
2285 gst_message_parse_context_type (GstMessage * message,
2286     const gchar ** context_type)
2287 {
2288   GstStructure *structure;
2289   const GValue *value;
2290
2291   g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEED_CONTEXT,
2292       FALSE);
2293
2294   structure = GST_MESSAGE_STRUCTURE (message);
2295
2296   if (context_type) {
2297     value = gst_structure_id_get_value (structure, GST_QUARK (CONTEXT_TYPE));
2298     *context_type = g_value_get_string (value);
2299   }
2300
2301   return TRUE;
2302 }
2303
2304 /**
2305  * gst_message_new_have_context:
2306  * @src: (transfer none) (allow-none): The object originating the message.
2307  * @context: (transfer full): the context
2308  *
2309  * This message is posted when an element has a new local #GstContext.
2310  *
2311  * Returns: (transfer full): The new have-context message.
2312  *
2313  * MT safe.
2314  *
2315  * Since: 1.2
2316  */
2317 GstMessage *
2318 gst_message_new_have_context (GstObject * src, GstContext * context)
2319 {
2320   GstMessage *message;
2321   GstStructure *structure;
2322
2323   structure = gst_structure_new_id (GST_QUARK (MESSAGE_HAVE_CONTEXT),
2324       GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
2325   message = gst_message_new_custom (GST_MESSAGE_HAVE_CONTEXT, src, structure);
2326   gst_context_unref (context);
2327
2328   return message;
2329 }
2330
2331 /**
2332  * gst_message_parse_have_context:
2333  * @message: A valid #GstMessage of type GST_MESSAGE_HAVE_CONTEXT.
2334  * @context: (out) (transfer full) (allow-none): Result location for the
2335  *      context or %NULL
2336  *
2337  * Extract the context from the HAVE_CONTEXT message.
2338  *
2339  * MT safe.
2340  *
2341  * Since: 1.2
2342  */
2343 void
2344 gst_message_parse_have_context (GstMessage * message, GstContext ** context)
2345 {
2346   g_return_if_fail (GST_IS_MESSAGE (message));
2347   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_HAVE_CONTEXT);
2348
2349   if (context)
2350     gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
2351         GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
2352 }
2353
2354 /**
2355  * gst_message_new_device_added:
2356  * @src: The #GstObject that created the message
2357  * @device: (transfer none): The new #GstDevice
2358  *
2359  * Creates a new device-added message. The device-added message is produced by
2360  * #GstDeviceProvider or a #GstDeviceMonitor. They announce the appearance
2361  * of monitored devices.
2362  *
2363  * Returns: a newly allocated #GstMessage
2364  *
2365  * Since: 1.4
2366  */
2367 GstMessage *
2368 gst_message_new_device_added (GstObject * src, GstDevice * device)
2369 {
2370   GstMessage *message;
2371   GstStructure *structure;
2372
2373   g_return_val_if_fail (device != NULL, NULL);
2374   g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
2375
2376   structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_ADDED),
2377       GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
2378   message = gst_message_new_custom (GST_MESSAGE_DEVICE_ADDED, src, structure);
2379
2380   return message;
2381 }
2382
2383 /**
2384  * gst_message_parse_device_added:
2385  * @message: a #GstMessage of type %GST_MESSAGE_DEVICE_ADDED
2386  * @device: (out) (allow-none) (transfer full): A location where to store a
2387  *  pointer to the new #GstDevice, or %NULL
2388  * 
2389  * Parses a device-added message. The device-added message is produced by
2390  * #GstDeviceProvider or a #GstDeviceMonitor. It announces the appearance
2391  * of monitored devices.
2392  *
2393  * Since: 1.4
2394  */
2395 void
2396 gst_message_parse_device_added (GstMessage * message, GstDevice ** device)
2397 {
2398   g_return_if_fail (GST_IS_MESSAGE (message));
2399   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DEVICE_ADDED);
2400
2401   if (device)
2402     gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
2403         GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
2404 }
2405
2406 /**
2407  * gst_message_new_device_removed:
2408  * @src: The #GstObject that created the message
2409  * @device: (transfer none): The removed #GstDevice
2410  *
2411  * Creates a new device-removed message. The device-removed message is produced
2412  * by #GstDeviceProvider or a #GstDeviceMonitor. They announce the
2413  * disappearance of monitored devices.
2414  *
2415  * Returns: a newly allocated #GstMessage
2416  *
2417  * Since: 1.4
2418  */
2419 GstMessage *
2420 gst_message_new_device_removed (GstObject * src, GstDevice * device)
2421 {
2422   GstMessage *message;
2423   GstStructure *structure;
2424
2425   g_return_val_if_fail (device != NULL, NULL);
2426   g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
2427
2428   structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_REMOVED),
2429       GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
2430   message = gst_message_new_custom (GST_MESSAGE_DEVICE_REMOVED, src, structure);
2431
2432   return message;
2433 }
2434
2435 /**
2436  * gst_message_parse_device_removed:
2437  * @message: a #GstMessage of type %GST_MESSAGE_DEVICE_REMOVED
2438  * @device: (out) (allow-none) (transfer full): A location where to store a
2439  *  pointer to the removed #GstDevice, or %NULL
2440  *
2441  * Parses a device-removed message. The device-removed message is produced by
2442  * #GstDeviceProvider or a #GstDeviceMonitor. It announces the
2443  * disappearance of monitored devices.
2444  *
2445  * Since: 1.4
2446  */
2447 void
2448 gst_message_parse_device_removed (GstMessage * message, GstDevice ** device)
2449 {
2450   g_return_if_fail (GST_IS_MESSAGE (message));
2451   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DEVICE_REMOVED);
2452
2453   if (device)
2454     gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
2455         GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
2456 }
2457
2458 /**
2459  * gst_message_new_property_notify:
2460  * @src: The #GstObject whose property changed (may or may not be a #GstElement)
2461  * @property_name: name of the property that changed
2462  * @val: (allow-none) (transfer full): new property value, or %NULL
2463  *
2464  * Returns: a newly allocated #GstMessage
2465  *
2466  * Since: 1.10
2467  */
2468 GstMessage *
2469 gst_message_new_property_notify (GstObject * src, const gchar * property_name,
2470     GValue * val)
2471 {
2472   GstStructure *structure;
2473   GValue name_val = G_VALUE_INIT;
2474
2475   g_return_val_if_fail (property_name != NULL, NULL);
2476
2477   structure = gst_structure_new_id_empty (GST_QUARK (MESSAGE_PROPERTY_NOTIFY));
2478   g_value_init (&name_val, G_TYPE_STRING);
2479   /* should already be interned, but let's make sure */
2480   g_value_set_static_string (&name_val, g_intern_string (property_name));
2481   gst_structure_id_take_value (structure, GST_QUARK (PROPERTY_NAME), &name_val);
2482   if (val != NULL)
2483     gst_structure_id_take_value (structure, GST_QUARK (PROPERTY_VALUE), val);
2484
2485   return gst_message_new_custom (GST_MESSAGE_PROPERTY_NOTIFY, src, structure);
2486 }
2487
2488 /**
2489  * gst_message_parse_property_notify:
2490  * @message: a #GstMessage of type %GST_MESSAGE_PROPERTY_NOTIFY
2491  * @object: (out) (allow-none) (transfer none): location where to store a
2492  *     pointer to the object whose property got changed, or %NULL
2493  * @property_name: (out) (allow-none): return location for the name of the
2494  *     property that got changed, or %NULL
2495  * @property_value: (out) (allow-none): return location for the new value of
2496  *     the property that got changed, or %NULL. This will only be set if the
2497  *     property notify watch was told to include the value when it was set up
2498  *
2499  * Parses a property-notify message. These will be posted on the bus only
2500  * when set up with gst_element_add_property_notify_watch() or
2501  * gst_element_add_property_deep_notify_watch().
2502  *
2503  * Since: 1.10
2504  */
2505 void
2506 gst_message_parse_property_notify (GstMessage * message, GstObject ** object,
2507     const gchar ** property_name, const GValue ** property_value)
2508 {
2509   const GstStructure *s = GST_MESSAGE_STRUCTURE (message);
2510
2511   g_return_if_fail (GST_IS_MESSAGE (message));
2512   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_PROPERTY_NOTIFY);
2513
2514   if (object)
2515     *object = GST_MESSAGE_SRC (message);
2516
2517   if (property_name) {
2518     const GValue *name_value;
2519
2520     name_value = gst_structure_id_get_value (s, GST_QUARK (PROPERTY_NAME));
2521     *property_name = g_value_get_string (name_value);
2522   }
2523
2524   if (property_value)
2525     *property_value =
2526         gst_structure_id_get_value (s, GST_QUARK (PROPERTY_VALUE));
2527 }
2528
2529 /**
2530  * gst_message_new_stream_collection:
2531  * @src: The #GstObject that created the message
2532  * @collection: (transfer none): The #GstStreamCollection
2533  *
2534  * Creates a new stream-collection message. The message is used to announce new
2535  * #GstStreamCollection
2536  *
2537  * Returns: a newly allocated #GstMessage
2538  *
2539  * Since: 1.10
2540  */
2541 GstMessage *
2542 gst_message_new_stream_collection (GstObject * src,
2543     GstStreamCollection * collection)
2544 {
2545   GstMessage *message;
2546   GstStructure *structure;
2547
2548   g_return_val_if_fail (collection != NULL, NULL);
2549   g_return_val_if_fail (GST_IS_STREAM_COLLECTION (collection), NULL);
2550
2551   structure =
2552       gst_structure_new_id (GST_QUARK (MESSAGE_STREAM_COLLECTION),
2553       GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
2554   message =
2555       gst_message_new_custom (GST_MESSAGE_STREAM_COLLECTION, src, structure);
2556
2557   return message;
2558 }
2559
2560 /**
2561  * gst_message_parse_stream_collection:
2562  * @message: a #GstMessage of type %GST_MESSAGE_STREAM_COLLECTION
2563  * @collection: (out) (allow-none) (transfer full): A location where to store a
2564  *  pointer to the #GstStreamCollection, or %NULL
2565  *
2566  * Parses a stream-collection message. 
2567  *
2568  * Since: 1.10
2569  */
2570 void
2571 gst_message_parse_stream_collection (GstMessage * message,
2572     GstStreamCollection ** collection)
2573 {
2574   g_return_if_fail (GST_IS_MESSAGE (message));
2575   g_return_if_fail (GST_MESSAGE_TYPE (message) ==
2576       GST_MESSAGE_STREAM_COLLECTION);
2577
2578   if (collection)
2579     gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
2580         GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
2581 }
2582
2583 /**
2584  * gst_message_new_streams_selected:
2585  * @src: The #GstObject that created the message
2586  * @collection: (transfer none): The #GstStreamCollection
2587  *
2588  * Creates a new steams-selected message. The message is used to announce
2589  * that an array of streams has been selected. This is generally in response
2590  * to a #GST_EVENT_SELECT_STREAMS event, or when an element (such as decodebin3)
2591  * makes an initial selection of streams.
2592  *
2593  * The message also contains the #GstStreamCollection to which the various streams
2594  * belong to.
2595  *
2596  * Users of gst_message_new_streams_selected() can add the selected streams with
2597  * gst_message_streams_selected_add().
2598  *
2599  * Returns: a newly allocated #GstMessage
2600  *
2601  * Since: 1.10
2602  */
2603 GstMessage *
2604 gst_message_new_streams_selected (GstObject * src,
2605     GstStreamCollection * collection)
2606 {
2607   GstMessage *message;
2608   GstStructure *structure;
2609   GValue val = G_VALUE_INIT;
2610
2611   g_return_val_if_fail (collection != NULL, NULL);
2612   g_return_val_if_fail (GST_IS_STREAM_COLLECTION (collection), NULL);
2613
2614   structure =
2615       gst_structure_new_id (GST_QUARK (MESSAGE_STREAMS_SELECTED),
2616       GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
2617   g_value_init (&val, GST_TYPE_ARRAY);
2618   gst_structure_id_take_value (structure, GST_QUARK (STREAMS), &val);
2619   message =
2620       gst_message_new_custom (GST_MESSAGE_STREAMS_SELECTED, src, structure);
2621
2622   return message;
2623 }
2624
2625 /**
2626  * gst_message_streams_selected_get_size:
2627  * @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
2628  *
2629  * Returns the number of streams contained in the @message.
2630  *
2631  * Returns: The number of streams contained within.
2632  *
2633  * Since: 1.10
2634  */
2635 guint
2636 gst_message_streams_selected_get_size (GstMessage * msg)
2637 {
2638   const GValue *val;
2639
2640   g_return_val_if_fail (GST_IS_MESSAGE (msg), 0);
2641   g_return_val_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED,
2642       0);
2643
2644   val =
2645       gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (msg),
2646       GST_QUARK (STREAMS));
2647   return gst_value_array_get_size (val);
2648 }
2649
2650 /**
2651  * gst_message_streams_selected_add:
2652  * @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
2653  * @stream: (transfer none): a #GstStream to add to @message
2654  *
2655  * Adds the @stream to the @message.
2656  *
2657  * Since: 1.10
2658  */
2659 void
2660 gst_message_streams_selected_add (GstMessage * msg, GstStream * stream)
2661 {
2662   GValue *val;
2663   GValue to_add = G_VALUE_INIT;
2664
2665   g_return_if_fail (GST_IS_MESSAGE (msg));
2666   g_return_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED);
2667   g_return_if_fail (GST_IS_STREAM (stream));
2668
2669   val =
2670       (GValue *) gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (msg),
2671       GST_QUARK (STREAMS));
2672   g_value_init (&to_add, GST_TYPE_STREAM);
2673   g_value_set_object (&to_add, stream);
2674   gst_value_array_append_and_take_value (val, &to_add);
2675 }
2676
2677 /**
2678  * gst_message_streams_selected_get_stream:
2679  * @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
2680  * @idx: Index of the stream to retrieve
2681  *
2682  * Retrieves the #GstStream with index @index from the @message.
2683  *
2684  * Returns: (transfer full): A #GstStream
2685  *
2686  * Since: 1.10
2687  */
2688 GstStream *
2689 gst_message_streams_selected_get_stream (GstMessage * msg, guint idx)
2690 {
2691   const GValue *streams, *val;
2692
2693   g_return_val_if_fail (GST_IS_MESSAGE (msg), NULL);
2694   g_return_val_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED,
2695       NULL);
2696
2697   streams =
2698       gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (msg),
2699       GST_QUARK (STREAMS));
2700   val = gst_value_array_get_value (streams, idx);
2701   if (val) {
2702     return (GstStream *) g_value_dup_object (val);
2703   }
2704
2705   return NULL;
2706 }
2707
2708 /**
2709  * gst_message_parse_streams_selected:
2710  * @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
2711  * @collection: (out) (allow-none) (transfer full): A location where to store a
2712  *  pointer to the #GstStreamCollection, or %NULL
2713  *
2714  * Parses a streams-selected message. 
2715  *
2716  * Since: 1.10
2717  */
2718 void
2719 gst_message_parse_streams_selected (GstMessage * message,
2720     GstStreamCollection ** collection)
2721 {
2722   g_return_if_fail (GST_IS_MESSAGE (message));
2723   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAMS_SELECTED);
2724
2725   if (collection)
2726     gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
2727         GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
2728 }