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