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