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