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