structure: add gst_structure_id_new() convenience function
[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 #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   {0, NULL, 0}
114 };
115
116 /**
117  * gst_message_type_get_name:
118  * @type: the message type
119  *
120  * Get a printable name for the given message type. Do not modify or free.
121  *
122  * Returns: a reference to the static name of the message.
123  */
124 const gchar *
125 gst_message_type_get_name (GstMessageType type)
126 {
127   gint i;
128
129   for (i = 0; message_quarks[i].name; i++) {
130     if (type == message_quarks[i].type)
131       return message_quarks[i].name;
132   }
133   return "unknown";
134 }
135
136 /**
137  * gst_message_type_to_quark:
138  * @type: the message type
139  *
140  * Get the unique quark for the given message type.
141  *
142  * Returns: the quark associated with the message type
143  */
144 GQuark
145 gst_message_type_to_quark (GstMessageType type)
146 {
147   gint i;
148
149   for (i = 0; message_quarks[i].name; i++) {
150     if (type == message_quarks[i].type)
151       return message_quarks[i].quark;
152   }
153   return 0;
154 }
155
156 #define _do_init \
157 { \
158   gint i; \
159   \
160   for (i = 0; message_quarks[i].name; i++) { \
161     message_quarks[i].quark = \
162         g_quark_from_static_string (message_quarks[i].name); \
163   } \
164 }
165
166 G_DEFINE_TYPE_WITH_CODE (GstMessage, gst_message, GST_TYPE_MINI_OBJECT,
167     _do_init);
168
169 static void
170 gst_message_class_init (GstMessageClass * klass)
171 {
172   parent_class = g_type_class_peek_parent (klass);
173
174   klass->mini_object_class.copy = (GstMiniObjectCopyFunction) _gst_message_copy;
175   klass->mini_object_class.finalize =
176       (GstMiniObjectFinalizeFunction) gst_message_finalize;
177 }
178
179 static void
180 gst_message_init (GstMessage * message)
181 {
182   GST_CAT_LOG (GST_CAT_MESSAGE, "new message %p", message);
183   GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
184 }
185
186 static void
187 gst_message_finalize (GstMessage * message)
188 {
189   g_return_if_fail (message != NULL);
190
191   GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p", message);
192
193   if (GST_MESSAGE_SRC (message)) {
194     gst_object_unref (GST_MESSAGE_SRC (message));
195     GST_MESSAGE_SRC (message) = NULL;
196   }
197
198   if (message->lock) {
199     GST_MESSAGE_LOCK (message);
200     GST_MESSAGE_SIGNAL (message);
201     GST_MESSAGE_UNLOCK (message);
202   }
203
204   if (message->structure) {
205     gst_structure_set_parent_refcount (message->structure, NULL);
206     gst_structure_free (message->structure);
207   }
208
209   GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (message));
210 }
211
212 static GstMessage *
213 _gst_message_copy (GstMessage * message)
214 {
215   GstMessage *copy;
216
217   GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p", message);
218
219   copy = (GstMessage *) gst_mini_object_new (GST_TYPE_MESSAGE);
220
221   /* FIXME, need to copy relevant data from the miniobject. */
222   //memcpy (copy, message, sizeof (GstMessage));
223
224   GST_MESSAGE_GET_LOCK (copy) = GST_MESSAGE_GET_LOCK (message);
225   GST_MESSAGE_COND (copy) = GST_MESSAGE_COND (message);
226   GST_MESSAGE_TYPE (copy) = GST_MESSAGE_TYPE (message);
227   GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
228   GST_MESSAGE_SEQNUM (copy) = GST_MESSAGE_SEQNUM (message);
229
230   if (GST_MESSAGE_SRC (message)) {
231     GST_MESSAGE_SRC (copy) = gst_object_ref (GST_MESSAGE_SRC (message));
232   }
233
234   if (message->structure) {
235     copy->structure = gst_structure_copy (message->structure);
236     gst_structure_set_parent_refcount (copy->structure,
237         &copy->mini_object.refcount);
238   }
239
240   return 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: The structure for the message. The message will take ownership of
248  * 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: The new message.
255  *
256  * MT safe.
257  */
258 GstMessage *
259 gst_message_new_custom (GstMessageType type, GstObject * src,
260     GstStructure * structure)
261 {
262   GstMessage *message;
263
264   message = (GstMessage *) gst_mini_object_new (GST_TYPE_MESSAGE);
265
266   GST_CAT_LOG (GST_CAT_MESSAGE, "source %s: creating new message %p %s",
267       (src ? GST_OBJECT_NAME (src) : "NULL"), message,
268       gst_message_type_get_name (type));
269
270   message->type = type;
271
272   if (src)
273     gst_object_ref (src);
274   message->src = src;
275
276   if (structure) {
277     gst_structure_set_parent_refcount (structure,
278         &message->mini_object.refcount);
279   }
280   message->structure = structure;
281
282   GST_MESSAGE_SEQNUM (message) = gst_util_seqnum_next ();
283
284   return message;
285 }
286
287 /**
288  * gst_message_get_seqnum:
289  * @message: A #GstMessage.
290  *
291  * Retrieve the sequence number of a message.
292  *
293  * Messages have ever-incrementing sequence numbers, which may also be set
294  * explicitly via gst_message_set_seqnum(). Sequence numbers are typically used
295  * to indicate that a message corresponds to some other set of messages or
296  * events, for example a SEGMENT_DONE message corresponding to a SEEK event. It
297  * is considered good practice to make this correspondence when possible, though
298  * it is not required.
299  *
300  * Note that events and messages share the same sequence number incrementor;
301  * two events or messages will never not have the same sequence number unless
302  * that correspondence was made explicitly.
303  *
304  * Returns: The message's sequence number.
305  *
306  * MT safe.
307  *
308  * Since: 0.10.22
309  */
310 guint32
311 gst_message_get_seqnum (GstMessage * message)
312 {
313   g_return_val_if_fail (GST_IS_MESSAGE (message), -1);
314
315   return GST_MESSAGE_SEQNUM (message);
316 }
317
318 /**
319  * gst_message_set_seqnum:
320  * @message: A #GstMessage.
321  * @seqnum: A sequence number.
322  *
323  * Set the sequence number of a message.
324  *
325  * This function might be called by the creator of a message to indicate that
326  * the message relates to other messages or events. See gst_message_get_seqnum()
327  * for more information.
328  *
329  * MT safe.
330  *
331  * Since: 0.10.22
332  */
333 void
334 gst_message_set_seqnum (GstMessage * message, guint32 seqnum)
335 {
336   g_return_if_fail (GST_IS_MESSAGE (message));
337
338   GST_MESSAGE_SEQNUM (message) = seqnum;
339 }
340
341 /**
342  * gst_message_new_eos:
343  * @src: The object originating the message.
344  *
345  * Create a new eos message. This message is generated and posted in
346  * the sink elements of a GstBin. The bin will only forward the EOS
347  * message to the application if all sinks have posted an EOS message.
348  *
349  * Returns: The new eos message.
350  *
351  * MT safe.
352  */
353 GstMessage *
354 gst_message_new_eos (GstObject * src)
355 {
356   GstMessage *message;
357
358   message = gst_message_new_custom (GST_MESSAGE_EOS, src, NULL);
359
360   return message;
361 }
362
363 /**
364  * gst_message_new_error:
365  * @src: The object originating the message.
366  * @error: The GError for this message.
367  * @debug: A debugging string.
368  *
369  * Create a new error message. The message will copy @error and
370  * @debug. This message is posted by element when a fatal event
371  * occured. The pipeline will probably (partially) stop. The application
372  * receiving this message should stop the pipeline.
373  *
374  * Returns: The new error message.
375  *
376  * MT safe.
377  */
378 GstMessage *
379 gst_message_new_error (GstObject * src, GError * error, const gchar * debug)
380 {
381   GstMessage *message;
382   GstStructure *structure;
383
384   structure = gst_structure_id_new (GST_QUARK (MESSAGE_ERROR),
385       GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
386       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
387   message = gst_message_new_custom (GST_MESSAGE_ERROR, src, structure);
388
389   return message;
390 }
391
392 /**
393  * gst_message_new_warning:
394  * @src: The object originating the message.
395  * @error: The GError for this message.
396  * @debug: A debugging string.
397  *
398  * Create a new warning message. The message will make copies of @error and
399  * @debug.
400  *
401  * Returns: The new warning message.
402  *
403  * MT safe.
404  */
405 GstMessage *
406 gst_message_new_warning (GstObject * src, GError * error, const gchar * debug)
407 {
408   GstMessage *message;
409   GstStructure *structure;
410
411   structure = gst_structure_id_new (GST_QUARK (MESSAGE_WARNING),
412       GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
413       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
414   message = gst_message_new_custom (GST_MESSAGE_WARNING, src, structure);
415
416   return message;
417 }
418
419 /**
420  * gst_message_new_info:
421  * @src: The object originating the message.
422  * @error: The GError for this message.
423  * @debug: A debugging string.
424  *
425  * Create a new info message. The message will make copies of @error and
426  * @debug.
427  *
428  * MT safe.
429  *
430  * Returns: The new info message.
431  *
432  * Since: 0.10.12
433  */
434 GstMessage *
435 gst_message_new_info (GstObject * src, GError * error, const gchar * debug)
436 {
437   GstMessage *message;
438   GstStructure *structure;
439
440   structure = gst_structure_id_new (GST_QUARK (MESSAGE_INFO),
441       GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
442       GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
443   message = gst_message_new_custom (GST_MESSAGE_INFO, src, structure);
444
445   return message;
446 }
447
448 /**
449  * gst_message_new_tag:
450  * @src: The object originating the message.
451  * @tag_list: The tag list for the message.
452  *
453  * Create a new tag message. The message will take ownership of the tag list.
454  * The message is posted by elements that discovered a new taglist.
455  *
456  * Returns: The new tag message.
457  *
458  * MT safe.
459  */
460 GstMessage *
461 gst_message_new_tag (GstObject * src, GstTagList * tag_list)
462 {
463   GstMessage *message;
464
465   g_return_val_if_fail (GST_IS_STRUCTURE (tag_list), NULL);
466
467   message =
468       gst_message_new_custom (GST_MESSAGE_TAG, src, (GstStructure *) tag_list);
469
470   return message;
471 }
472
473 /**
474  * gst_message_new_tag_full:
475  * @src: The object originating the message.
476  * @pad: The originating pad for the tag.
477  * @tag_list: The tag list for the message.
478  *
479  * Create a new tag message. The message will take ownership of the tag list.
480  * The message is posted by elements that discovered a new taglist.
481  *
482  * Returns: The new tag message.
483  *
484  * Since: 0.10.24
485  *
486  * MT safe.
487  */
488 GstMessage *
489 gst_message_new_tag_full (GstObject * src, GstPad * pad, GstTagList * tag_list)
490 {
491   GstMessage *message;
492   GstStructure *s;
493
494   g_return_val_if_fail (GST_IS_STRUCTURE (tag_list), NULL);
495   g_return_val_if_fail (pad == NULL || GST_IS_PAD (pad), NULL);
496
497   s = (GstStructure *) tag_list;
498   if (pad)
499     gst_structure_set (s, "source-pad", GST_TYPE_PAD, pad, NULL);
500
501   message = gst_message_new_custom (GST_MESSAGE_TAG, src, s);
502
503   return message;
504 }
505
506 /**
507  * gst_message_new_buffering:
508  * @src: The object originating the message.
509  * @percent: The buffering percent
510  *
511  * Create a new buffering message. This message can be posted by an element that
512  * needs to buffer data before it can continue processing. @percent should be a
513  * value between 0 and 100. A value of 100 means that the buffering completed.
514  *
515  * When @percent is < 100 the application should PAUSE a PLAYING pipeline. When
516  * @percent is 100, the application can set the pipeline (back) to PLAYING.
517  * The application must be prepared to receive BUFFERING messages in the
518  * PREROLLING state and may only set the pipeline to PLAYING after receiving a
519  * message with @percent set to 100, which can happen after the pipeline
520  * completed prerolling. 
521  *
522  * MT safe.
523  *
524  * Returns: The new buffering message.
525  *
526  * Since: 0.10.11
527  */
528 GstMessage *
529 gst_message_new_buffering (GstObject * src, gint percent)
530 {
531   GstMessage *message;
532   GstStructure *structure;
533
534   g_return_val_if_fail (percent >= 0 && percent <= 100, NULL);
535
536   structure = gst_structure_id_new (GST_QUARK (MESSAGE_BUFFERING),
537       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent,
538       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
539       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
540       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
541       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
542       GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
543   message = gst_message_new_custom (GST_MESSAGE_BUFFERING, src, structure);
544
545   return message;
546 }
547
548 /**
549  * gst_message_new_state_changed:
550  * @src: the object originating the message
551  * @oldstate: the previous state
552  * @newstate: the new (current) state
553  * @pending: the pending (target) state
554  *
555  * Create a state change message. This message is posted whenever an element
556  * changed its state.
557  *
558  * Returns: The new state change message.
559  *
560  * MT safe.
561  */
562 GstMessage *
563 gst_message_new_state_changed (GstObject * src,
564     GstState oldstate, GstState newstate, GstState pending)
565 {
566   GstMessage *message;
567   GstStructure *structure;
568
569   structure = gst_structure_id_new (GST_QUARK (MESSAGE_STATE),
570       GST_QUARK (OLD_STATE), GST_TYPE_STATE, (gint) oldstate,
571       GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) newstate,
572       GST_QUARK (PENDING_STATE), GST_TYPE_STATE, (gint) pending, NULL);
573   message = gst_message_new_custom (GST_MESSAGE_STATE_CHANGED, src, structure);
574
575   return message;
576 }
577
578 /**
579  * gst_message_new_state_dirty:
580  * @src: the object originating the message
581  *
582  * Create a state dirty message. This message is posted whenever an element
583  * changed its state asynchronously and is used internally to update the
584  * states of container objects.
585  *
586  * Returns: The new state dirty message.
587  *
588  * MT safe.
589  */
590 GstMessage *
591 gst_message_new_state_dirty (GstObject * src)
592 {
593   GstMessage *message;
594
595   message = gst_message_new_custom (GST_MESSAGE_STATE_DIRTY, src, NULL);
596
597   return message;
598 }
599
600 /**
601  * gst_message_new_clock_provide:
602  * @src: The object originating the message.
603  * @clock: The clock it provides
604  * @ready: TRUE if the sender can provide a clock
605  *
606  * Create a clock provide message. This message is posted whenever an
607  * element is ready to provide a clock or lost its ability to provide
608  * a clock (maybe because it paused or became EOS).
609  *
610  * This message is mainly used internally to manage the clock
611  * selection.
612  *
613  * Returns: The new provide clock message.
614  *
615  * MT safe.
616  */
617 GstMessage *
618 gst_message_new_clock_provide (GstObject * src, GstClock * clock,
619     gboolean ready)
620 {
621   GstMessage *message;
622   GstStructure *structure;
623
624   structure = gst_structure_id_new (GST_QUARK (MESSAGE_CLOCK_PROVIDE),
625       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock,
626       GST_QUARK (READY), G_TYPE_BOOLEAN, ready, NULL);
627   message = gst_message_new_custom (GST_MESSAGE_CLOCK_PROVIDE, src, structure);
628
629   return message;
630 }
631
632 /**
633  * gst_message_new_clock_lost:
634  * @src: The object originating the message.
635  * @clock: the clock that was lost
636  *
637  * Create a clock lost message. This message is posted whenever the
638  * clock is not valid anymore.
639  *
640  * If this message is posted by the pipeline, the pipeline will
641  * select a new clock again when it goes to PLAYING. It might therefore
642  * be needed to set the pipeline to PAUSED and PLAYING again.
643  *
644  * Returns: The new clock lost message.
645  *
646  * MT safe.
647  */
648 GstMessage *
649 gst_message_new_clock_lost (GstObject * src, GstClock * clock)
650 {
651   GstMessage *message;
652   GstStructure *structure;
653
654   structure = gst_structure_id_new (GST_QUARK (MESSAGE_CLOCK_LOST),
655       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
656   message = gst_message_new_custom (GST_MESSAGE_CLOCK_LOST, src, structure);
657
658   return message;
659 }
660
661 /**
662  * gst_message_new_new_clock:
663  * @src: The object originating the message.
664  * @clock: the new selected clock
665  *
666  * Create a new clock message. This message is posted whenever the
667  * pipeline selectes a new clock for the pipeline.
668  *
669  * Returns: The new new clock message.
670  *
671  * MT safe.
672  */
673 GstMessage *
674 gst_message_new_new_clock (GstObject * src, GstClock * clock)
675 {
676   GstMessage *message;
677   GstStructure *structure;
678
679   structure = gst_structure_id_new (GST_QUARK (MESSAGE_NEW_CLOCK),
680       GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
681   message = gst_message_new_custom (GST_MESSAGE_NEW_CLOCK, src, structure);
682
683   return message;
684 }
685
686 /**
687  * gst_message_new_structure_change:
688  * @src: The object originating the message.
689  * @type: The change type.
690  * @owner: The owner element of @src.
691  * @busy: Whether the structure change is busy.
692  *
693  * Create a new structure change message. This message is posted when the
694  * structure of a pipeline is in the process of being changed, for example
695  * when pads are linked or unlinked.
696  *
697  * @src should be the srcpad that unlinked or linked.
698  *
699  * Returns: The new structure change message.
700  *
701  * MT safe.
702  *
703  * Since: 0.10.22.
704  */
705 GstMessage *
706 gst_message_new_structure_change (GstObject * src, GstStructureChangeType type,
707     GstElement * owner, gboolean busy)
708 {
709   GstMessage *message;
710   GstStructure *structure;
711
712   g_return_val_if_fail (GST_IS_PAD (src), NULL);
713   g_return_val_if_fail (GST_PAD_DIRECTION (src) == GST_PAD_SRC, NULL);
714   g_return_val_if_fail (GST_IS_ELEMENT (owner), NULL);
715
716   structure = gst_structure_id_new (GST_QUARK (MESSAGE_STRUCTURE_CHANGE),
717       GST_QUARK (TYPE), GST_TYPE_STRUCTURE_CHANGE_TYPE, type,
718       GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner,
719       GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy, NULL);
720
721   message = gst_message_new_custom (GST_MESSAGE_STRUCTURE_CHANGE, src,
722       structure);
723
724   return message;
725 }
726
727 /**
728  * gst_message_new_segment_start:
729  * @src: The object originating the message.
730  * @format: The format of the position being played
731  * @position: The position of the segment being played
732  *
733  * Create a new segment message. This message is posted by elements that
734  * start playback of a segment as a result of a segment seek. This message
735  * is not received by the application but is used for maintenance reasons in
736  * container elements.
737  *
738  * Returns: The new segment start message.
739  *
740  * MT safe.
741  */
742 GstMessage *
743 gst_message_new_segment_start (GstObject * src, GstFormat format,
744     gint64 position)
745 {
746   GstMessage *message;
747   GstStructure *structure;
748
749   structure = gst_structure_id_new (GST_QUARK (MESSAGE_SEGMENT_START),
750       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
751       GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
752   message = gst_message_new_custom (GST_MESSAGE_SEGMENT_START, src, structure);
753
754   return message;
755 }
756
757 /**
758  * gst_message_new_segment_done:
759  * @src: The object originating the message.
760  * @format: The format of the position being done
761  * @position: The position of the segment being done
762  *
763  * Create a new segment done message. This message is posted by elements that
764  * finish playback of a segment as a result of a segment seek. This message
765  * is received by the application after all elements that posted a segment_start
766  * have posted the segment_done.
767  *
768  * Returns: The new segment done message.
769  *
770  * MT safe.
771  */
772 GstMessage *
773 gst_message_new_segment_done (GstObject * src, GstFormat format,
774     gint64 position)
775 {
776   GstMessage *message;
777   GstStructure *structure;
778
779   structure = gst_structure_id_new (GST_QUARK (MESSAGE_SEGMENT_DONE),
780       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
781       GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
782   message = gst_message_new_custom (GST_MESSAGE_SEGMENT_DONE, src, structure);
783
784   return message;
785 }
786
787 /**
788  * gst_message_new_application:
789  * @src: The object originating the message.
790  * @structure: The structure for the message. The message will take ownership of
791  * the structure.
792  *
793  * Create a new application-typed message. GStreamer will never create these
794  * messages; they are a gift from us to you. Enjoy.
795  *
796  * Returns: The new application message.
797  *
798  * MT safe.
799  */
800 GstMessage *
801 gst_message_new_application (GstObject * src, GstStructure * structure)
802 {
803   return gst_message_new_custom (GST_MESSAGE_APPLICATION, src, structure);
804 }
805
806 /**
807  * gst_message_new_element:
808  * @src: The object originating the message.
809  * @structure: The structure for the message. The message will take ownership of
810  * the structure.
811  *
812  * Create a new element-specific message. This is meant as a generic way of
813  * allowing one-way communication from an element to an application, for example
814  * "the firewire cable was unplugged". The format of the message should be
815  * documented in the element's documentation. The structure field can be NULL.
816  *
817  * Returns: The new element message.
818  *
819  * MT safe.
820  */
821 GstMessage *
822 gst_message_new_element (GstObject * src, GstStructure * structure)
823 {
824   return gst_message_new_custom (GST_MESSAGE_ELEMENT, src, structure);
825 }
826
827 /**
828  * gst_message_new_duration:
829  * @src: The object originating the message.
830  * @format: The format of the duration
831  * @duration: The new duration 
832  *
833  * Create a new duration message. This message is posted by elements that
834  * know the duration of a stream in a specific format. This message
835  * is received by bins and is used to calculate the total duration of a
836  * pipeline. Elements may post a duration message with a duration of
837  * GST_CLOCK_TIME_NONE to indicate that the duration has changed and the 
838  * cached duration should be discarded. The new duration can then be 
839  * retrieved via a query.
840  *
841  * Returns: The new duration message.
842  *
843  * MT safe.
844  */
845 GstMessage *
846 gst_message_new_duration (GstObject * src, GstFormat format, gint64 duration)
847 {
848   GstMessage *message;
849   GstStructure *structure;
850
851   structure = gst_structure_id_new (GST_QUARK (MESSAGE_DURATION),
852       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
853       GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL);
854   message = gst_message_new_custom (GST_MESSAGE_DURATION, src, structure);
855
856   return message;
857 }
858
859 /**
860  * gst_message_new_async_start:
861  * @src: The object originating the message.
862  * @new_base_time: if a new base_time should be set on the element
863  *
864  * This message is posted by elements when they start an ASYNC state change. 
865  * @new_base_time is set to TRUE when the element lost its state when it was
866  * PLAYING.
867  *
868  * Returns: The new async_start message. 
869  *
870  * MT safe.
871  *
872  * Since: 0.10.13
873  */
874 GstMessage *
875 gst_message_new_async_start (GstObject * src, gboolean new_base_time)
876 {
877   GstMessage *message;
878   GstStructure *structure;
879
880   structure = gst_structure_id_new (GST_QUARK (MESSAGE_ASYNC_START),
881       GST_QUARK (NEW_BASE_TIME), G_TYPE_BOOLEAN, new_base_time, NULL);
882   message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src, structure);
883
884   return message;
885 }
886
887 /**
888  * gst_message_new_async_done:
889  * @src: The object originating the message.
890  *
891  * The message is posted when elements completed an ASYNC state change.
892  *
893  * Returns: The new async_done message.
894  *
895  * MT safe.
896  *
897  * Since: 0.10.13
898  */
899 GstMessage *
900 gst_message_new_async_done (GstObject * src)
901 {
902   GstMessage *message;
903
904   message = gst_message_new_custom (GST_MESSAGE_ASYNC_DONE, src, NULL);
905
906   return message;
907 }
908
909 /**
910  * gst_message_new_latency:
911  * @src: The object originating the message.
912  *
913  * This message can be posted by elements when their latency requirements have
914  * changed.
915  *
916  * Returns: The new latency message. 
917  *
918  * MT safe.
919  *
920  * Since: 0.10.12
921  */
922 GstMessage *
923 gst_message_new_latency (GstObject * src)
924 {
925   GstMessage *message;
926
927   message = gst_message_new_custom (GST_MESSAGE_LATENCY, src, NULL);
928
929   return message;
930 }
931
932 /**
933  * gst_message_new_request_state:
934  * @src: The object originating the message.
935  * @state: The new requested state
936  *
937  * This message can be posted by elements when they want to have their state
938  * changed. A typical use case would be an audio server that wants to pause the
939  * pipeline because a higher priority stream is being played.
940  *
941  * Returns: The new requst state message. 
942  *
943  * MT safe.
944  *
945  * Since: 0.10.23
946  */
947 GstMessage *
948 gst_message_new_request_state (GstObject * src, GstState state)
949 {
950   GstMessage *message;
951   GstStructure *structure;
952
953   structure = gst_structure_id_new (GST_QUARK (MESSAGE_REQUEST_STATE),
954       GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) state, NULL);
955   message = gst_message_new_custom (GST_MESSAGE_REQUEST_STATE, src, structure);
956
957   return message;
958 }
959
960 /**
961  * gst_message_get_structure:
962  * @message: The #GstMessage.
963  *
964  * Access the structure of the message.
965  *
966  * Returns: The structure of the message. The structure is still
967  * owned by the message, which means that you should not free it and
968  * that the pointer becomes invalid when you free the message.
969  *
970  * MT safe.
971  */
972 const GstStructure *
973 gst_message_get_structure (GstMessage * message)
974 {
975   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
976
977   return message->structure;
978 }
979
980 /**
981  * gst_message_parse_tag:
982  * @message: A valid #GstMessage of type GST_MESSAGE_TAG.
983  * @tag_list: Return location for the tag-list.
984  *
985  * Extracts the tag list from the GstMessage. The tag list returned in the
986  * output argument is a copy; the caller must free it when done.
987  *
988  * MT safe.
989  */
990 void
991 gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list)
992 {
993   GstStructure *ret;
994
995   g_return_if_fail (GST_IS_MESSAGE (message));
996   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
997   g_return_if_fail (tag_list != NULL);
998
999   ret = gst_structure_copy (message->structure);
1000   gst_structure_remove_field (ret, "source-pad");
1001
1002   *tag_list = (GstTagList *) ret;
1003 }
1004
1005 /**
1006  * gst_message_parse_tag_full:
1007  * @message: A valid #GstMessage of type GST_MESSAGE_TAG.
1008  * @pad: Location where the originating pad is stored, unref after usage
1009  * @tag_list: Return location for the tag-list.
1010  *
1011  * Extracts the tag list from the GstMessage. The tag list returned in the
1012  * output argument is a copy; the caller must free it when done.
1013  *
1014  * Since: 0.10.24
1015  *
1016  * MT safe.
1017  */
1018 void
1019 gst_message_parse_tag_full (GstMessage * message, GstPad ** pad,
1020     GstTagList ** tag_list)
1021 {
1022   GstStructure *ret;
1023
1024   g_return_if_fail (GST_IS_MESSAGE (message));
1025   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
1026   g_return_if_fail (tag_list != NULL);
1027
1028   ret = gst_structure_copy (message->structure);
1029
1030   if (gst_structure_has_field (ret, "source-pad") && pad) {
1031     const GValue *v;
1032
1033     v = gst_structure_get_value (ret, "source-pad");
1034     if (v && G_VALUE_HOLDS (v, GST_TYPE_PAD))
1035       *pad = g_value_dup_object (v);
1036     else
1037       *pad = NULL;
1038   } else if (pad) {
1039     *pad = NULL;
1040   }
1041   gst_structure_remove_field (ret, "source-pad");
1042
1043   *tag_list = (GstTagList *) ret;
1044 }
1045
1046 /**
1047  * gst_message_parse_buffering:
1048  * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
1049  * @percent: Return location for the percent.
1050  *
1051  * Extracts the buffering percent from the GstMessage. see also
1052  * gst_message_new_buffering().
1053  *
1054  * MT safe.
1055  *
1056  * Since: 0.10.11
1057  */
1058 void
1059 gst_message_parse_buffering (GstMessage * message, gint * percent)
1060 {
1061   g_return_if_fail (GST_IS_MESSAGE (message));
1062   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1063
1064   if (percent)
1065     *percent = g_value_get_int (gst_structure_id_get_value (message->structure,
1066             GST_QUARK (BUFFER_PERCENT)));
1067 }
1068
1069 /**
1070  * gst_message_set_buffering_stats:
1071  * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
1072  * @mode: a buffering mode 
1073  * @avg_in: the average input rate
1074  * @avg_out: the average output rate
1075  * @buffering_left: amount of buffering time left in milliseconds
1076  *
1077  * Configures the buffering stats values in @message.
1078  *
1079  * Since: 0.10.20
1080  */
1081 void
1082 gst_message_set_buffering_stats (GstMessage * message, GstBufferingMode mode,
1083     gint avg_in, gint avg_out, gint64 buffering_left)
1084 {
1085   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1086
1087   gst_structure_id_set (message->structure,
1088       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
1089       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
1090       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
1091       GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
1092 }
1093
1094 /**
1095  * gst_message_parse_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  * Extracts the buffering stats values from @message.
1103  *
1104  * Since: 0.10.20
1105  */
1106 void
1107 gst_message_parse_buffering_stats (GstMessage * message,
1108     GstBufferingMode * mode, gint * avg_in, gint * avg_out,
1109     gint64 * buffering_left)
1110 {
1111   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
1112
1113   if (mode)
1114     *mode = g_value_get_enum (gst_structure_id_get_value (message->structure,
1115             GST_QUARK (BUFFERING_MODE)));
1116   if (avg_in)
1117     *avg_in = g_value_get_int (gst_structure_id_get_value (message->structure,
1118             GST_QUARK (AVG_IN_RATE)));
1119   if (avg_out)
1120     *avg_out = g_value_get_int (gst_structure_id_get_value (message->structure,
1121             GST_QUARK (AVG_OUT_RATE)));
1122   if (buffering_left)
1123     *buffering_left =
1124         g_value_get_int64 (gst_structure_id_get_value (message->structure,
1125             GST_QUARK (BUFFERING_LEFT)));
1126 }
1127
1128 /**
1129  * gst_message_parse_state_changed:
1130  * @message: a valid #GstMessage of type GST_MESSAGE_STATE_CHANGED
1131  * @oldstate: the previous state, or NULL
1132  * @newstate: the new (current) state, or NULL
1133  * @pending: the pending (target) state, or NULL
1134  *
1135  * Extracts the old and new states from the GstMessage.
1136  *
1137  * MT safe.
1138  */
1139 void
1140 gst_message_parse_state_changed (GstMessage * message,
1141     GstState * oldstate, GstState * newstate, GstState * pending)
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   if (oldstate)
1147     *oldstate =
1148         g_value_get_enum (gst_structure_id_get_value (message->structure,
1149             GST_QUARK (OLD_STATE)));
1150   if (newstate)
1151     *newstate =
1152         g_value_get_enum (gst_structure_id_get_value (message->structure,
1153             GST_QUARK (NEW_STATE)));
1154   if (pending)
1155     *pending = g_value_get_enum (gst_structure_id_get_value (message->structure,
1156             GST_QUARK (PENDING_STATE)));
1157 }
1158
1159 /**
1160  * gst_message_parse_clock_provide:
1161  * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_PROVIDE.
1162  * @clock: A pointer to  hold a clock object.
1163  * @ready: A pointer to hold the ready flag.
1164  *
1165  * Extracts the clock and ready flag from the GstMessage.
1166  * The clock object returned remains valid until the message is freed.
1167  *
1168  * MT safe.
1169  */
1170 void
1171 gst_message_parse_clock_provide (GstMessage * message, GstClock ** clock,
1172     gboolean * ready)
1173 {
1174   const GValue *clock_gvalue;
1175
1176   g_return_if_fail (GST_IS_MESSAGE (message));
1177   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_PROVIDE);
1178
1179   clock_gvalue =
1180       gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
1181   g_return_if_fail (clock_gvalue != NULL);
1182   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1183
1184   if (ready)
1185     *ready =
1186         g_value_get_boolean (gst_structure_id_get_value (message->structure,
1187             GST_QUARK (READY)));
1188   if (clock)
1189     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1190 }
1191
1192 /**
1193  * gst_message_parse_clock_lost:
1194  * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_LOST.
1195  * @clock: A pointer to hold the lost clock
1196  *
1197  * Extracts the lost clock from the GstMessage.
1198  * The clock object returned remains valid until the message is freed.
1199  *
1200  * MT safe.
1201  */
1202 void
1203 gst_message_parse_clock_lost (GstMessage * message, GstClock ** clock)
1204 {
1205   const GValue *clock_gvalue;
1206
1207   g_return_if_fail (GST_IS_MESSAGE (message));
1208   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_LOST);
1209
1210   clock_gvalue =
1211       gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
1212   g_return_if_fail (clock_gvalue != NULL);
1213   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1214
1215   if (clock)
1216     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1217 }
1218
1219 /**
1220  * gst_message_parse_new_clock:
1221  * @message: A valid #GstMessage of type GST_MESSAGE_NEW_CLOCK.
1222  * @clock: A pointer to hold the selected new clock
1223  *
1224  * Extracts the new clock from the GstMessage.
1225  * The clock object returned remains valid until the message is freed.
1226  *
1227  * MT safe.
1228  */
1229 void
1230 gst_message_parse_new_clock (GstMessage * message, GstClock ** clock)
1231 {
1232   const GValue *clock_gvalue;
1233
1234   g_return_if_fail (GST_IS_MESSAGE (message));
1235   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEW_CLOCK);
1236
1237   clock_gvalue =
1238       gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
1239   g_return_if_fail (clock_gvalue != NULL);
1240   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
1241
1242   if (clock)
1243     *clock = (GstClock *) g_value_get_object (clock_gvalue);
1244 }
1245
1246 /**
1247  * gst_message_parse_structure_change:
1248  * @message: A valid #GstMessage of type GST_MESSAGE_STRUCTURE_CHANGE.
1249  * @type: A pointer to hold the change type
1250  * @owner: The owner element of the message source
1251  * @busy: A pointer to hold whether the change is in progress or has been
1252  * completed
1253  *
1254  * Extracts the change type and completion status from the GstMessage.
1255  *
1256  * MT safe.
1257  *
1258  * Since: 0.10.22
1259  */
1260 void
1261 gst_message_parse_structure_change (GstMessage * message,
1262     GstStructureChangeType * type, GstElement ** owner, gboolean * busy)
1263 {
1264   const GValue *owner_gvalue;
1265
1266   g_return_if_fail (GST_IS_MESSAGE (message));
1267   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STRUCTURE_CHANGE);
1268
1269   owner_gvalue =
1270       gst_structure_id_get_value (message->structure, GST_QUARK (OWNER));
1271   g_return_if_fail (owner_gvalue != NULL);
1272   g_return_if_fail (G_VALUE_TYPE (owner_gvalue) == GST_TYPE_ELEMENT);
1273
1274   if (type)
1275     *type = g_value_get_enum (gst_structure_id_get_value (message->structure,
1276             GST_QUARK (TYPE)));
1277   if (owner)
1278     *owner = (GstElement *) g_value_get_object (owner_gvalue);
1279   if (busy)
1280     *busy =
1281         g_value_get_boolean (gst_structure_id_get_value (message->structure,
1282             GST_QUARK (BUSY)));
1283 }
1284
1285 /**
1286  * gst_message_parse_error:
1287  * @message: A valid #GstMessage of type GST_MESSAGE_ERROR.
1288  * @gerror: Location for the GError
1289  * @debug: Location for the debug message, or NULL
1290  *
1291  * Extracts the GError and debug string from the GstMessage. The values returned
1292  * in the output arguments are copies; the caller must free them when done.
1293  *
1294  * MT safe.
1295  */
1296 void
1297 gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug)
1298 {
1299   const GValue *error_gvalue;
1300   GError *error_val;
1301
1302   g_return_if_fail (GST_IS_MESSAGE (message));
1303   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
1304
1305   error_gvalue =
1306       gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
1307   g_return_if_fail (error_gvalue != NULL);
1308   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
1309
1310   error_val = (GError *) g_value_get_boxed (error_gvalue);
1311   if (error_val)
1312     *gerror = g_error_copy (error_val);
1313   else
1314     *gerror = NULL;
1315
1316   if (debug)
1317     *debug =
1318         g_value_dup_string (gst_structure_id_get_value (message->structure,
1319             GST_QUARK (DEBUG)));
1320 }
1321
1322 /**
1323  * gst_message_parse_warning:
1324  * @message: A valid #GstMessage of type GST_MESSAGE_WARNING.
1325  * @gerror: Location for the GError
1326  * @debug: Location for the debug message, or NULL
1327  *
1328  * Extracts the GError and debug string from the GstMessage. The values returned
1329  * in the output arguments are copies; the caller must free them when done.
1330  *
1331  * MT safe.
1332  */
1333 void
1334 gst_message_parse_warning (GstMessage * message, GError ** gerror,
1335     gchar ** debug)
1336 {
1337   const GValue *error_gvalue;
1338   GError *error_val;
1339
1340   g_return_if_fail (GST_IS_MESSAGE (message));
1341   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);
1342
1343   error_gvalue =
1344       gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
1345   g_return_if_fail (error_gvalue != NULL);
1346   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
1347
1348   error_val = (GError *) g_value_get_boxed (error_gvalue);
1349   if (error_val)
1350     *gerror = g_error_copy (error_val);
1351   else
1352     *gerror = NULL;
1353
1354   if (debug)
1355     *debug =
1356         g_value_dup_string (gst_structure_id_get_value (message->structure,
1357             GST_QUARK (DEBUG)));
1358 }
1359
1360 /**
1361  * gst_message_parse_info:
1362  * @message: A valid #GstMessage of type GST_MESSAGE_INFO.
1363  * @gerror: Location for the GError
1364  * @debug: Location for the debug message, or NULL
1365  *
1366  * Extracts the GError and debug string from the GstMessage. The values returned
1367  * in the output arguments are copies; the caller must free them when done.
1368  *
1369  * MT safe.
1370  *
1371  * Since: 0.10.12
1372  */
1373 void
1374 gst_message_parse_info (GstMessage * message, GError ** gerror, gchar ** debug)
1375 {
1376   const GValue *error_gvalue;
1377   GError *error_val;
1378
1379   g_return_if_fail (GST_IS_MESSAGE (message));
1380   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO);
1381
1382   error_gvalue =
1383       gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
1384   g_return_if_fail (error_gvalue != NULL);
1385   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
1386
1387   error_val = (GError *) g_value_get_boxed (error_gvalue);
1388   if (error_val)
1389     *gerror = g_error_copy (error_val);
1390   else
1391     *gerror = NULL;
1392
1393   if (debug)
1394     *debug =
1395         g_value_dup_string (gst_structure_id_get_value (message->structure,
1396             GST_QUARK (DEBUG)));
1397 }
1398
1399 /**
1400  * gst_message_parse_segment_start:
1401  * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_START.
1402  * @format: Result location for the format, or NULL
1403  * @position: Result location for the position, or NULL
1404  *
1405  * Extracts the position and format from the segment start message.
1406  *
1407  * MT safe.
1408  */
1409 void
1410 gst_message_parse_segment_start (GstMessage * message, GstFormat * format,
1411     gint64 * position)
1412 {
1413   g_return_if_fail (GST_IS_MESSAGE (message));
1414   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_START);
1415
1416   if (format)
1417     *format =
1418         g_value_get_enum (gst_structure_id_get_value (message->structure,
1419             GST_QUARK (FORMAT)));
1420   if (position)
1421     *position =
1422         g_value_get_int64 (gst_structure_id_get_value (message->structure,
1423             GST_QUARK (POSITION)));
1424 }
1425
1426 /**
1427  * gst_message_parse_segment_done:
1428  * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_DONE.
1429  * @format: Result location for the format, or NULL
1430  * @position: Result location for the position, or NULL
1431  *
1432  * Extracts the position and format from the segment start message.
1433  *
1434  * MT safe.
1435  */
1436 void
1437 gst_message_parse_segment_done (GstMessage * message, GstFormat * format,
1438     gint64 * position)
1439 {
1440   g_return_if_fail (GST_IS_MESSAGE (message));
1441   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_DONE);
1442
1443   if (format)
1444     *format =
1445         g_value_get_enum (gst_structure_id_get_value (message->structure,
1446             GST_QUARK (FORMAT)));
1447   if (position)
1448     *position =
1449         g_value_get_int64 (gst_structure_id_get_value (message->structure,
1450             GST_QUARK (POSITION)));
1451 }
1452
1453 /**
1454  * gst_message_parse_duration:
1455  * @message: A valid #GstMessage of type GST_MESSAGE_DURATION.
1456  * @format: Result location for the format, or NULL
1457  * @duration: Result location for the duration, or NULL
1458  *
1459  * Extracts the duration and format from the duration message. The duration
1460  * might be GST_CLOCK_TIME_NONE, which indicates that the duration has
1461  * changed. Applications should always use a query to retrieve the duration
1462  * of a pipeline.
1463  *
1464  * MT safe.
1465  */
1466 void
1467 gst_message_parse_duration (GstMessage * message, GstFormat * format,
1468     gint64 * duration)
1469 {
1470   g_return_if_fail (GST_IS_MESSAGE (message));
1471   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION);
1472
1473   if (format)
1474     *format =
1475         g_value_get_enum (gst_structure_id_get_value (message->structure,
1476             GST_QUARK (FORMAT)));
1477   if (duration)
1478     *duration =
1479         g_value_get_int64 (gst_structure_id_get_value (message->structure,
1480             GST_QUARK (DURATION)));
1481 }
1482
1483 /**
1484  * gst_message_parse_async_start:
1485  * @message: A valid #GstMessage of type GST_MESSAGE_ASYNC_DONE.
1486  * @new_base_time: Result location for the new_base_time or NULL
1487  *
1488  * Extract the new_base_time from the async_start message. 
1489  *
1490  * MT safe.
1491  *
1492  * Since: 0.10.13
1493  */
1494 void
1495 gst_message_parse_async_start (GstMessage * message, gboolean * new_base_time)
1496 {
1497   g_return_if_fail (GST_IS_MESSAGE (message));
1498   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ASYNC_START);
1499
1500   if (new_base_time)
1501     *new_base_time =
1502         g_value_get_boolean (gst_structure_id_get_value (message->structure,
1503             GST_QUARK (NEW_BASE_TIME)));
1504 }
1505
1506 /**
1507  * gst_message_parse_request_state:
1508  * @message: A valid #GstMessage of type GST_MESSAGE_REQUEST_STATE.
1509  * @state: Result location for the requested state or NULL
1510  *
1511  * Extract the requested state from the request_state message.
1512  *
1513  * MT safe.
1514  *
1515  * Since: 0.10.23
1516  */
1517 void
1518 gst_message_parse_request_state (GstMessage * message, GstState * state)
1519 {
1520   g_return_if_fail (GST_IS_MESSAGE (message));
1521   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REQUEST_STATE);
1522
1523   if (state)
1524     *state = g_value_get_enum (gst_structure_id_get_value (message->structure,
1525             GST_QUARK (NEW_STATE)));
1526 }
1527
1528 /**
1529  * gst_message_new_stream_status:
1530  * @src: The object originating the message.
1531  * @type: The stream status type.
1532  * @owner: The owner element of @src.
1533  *
1534  * Create a new stream status message. This message is posted when a streaming
1535  * thread is created/destroyed or when the state changed.
1536  * 
1537  * Returns: The new stream status message.
1538  *
1539  * MT safe.
1540  *
1541  * Since: 0.10.24.
1542  */
1543 GstMessage *
1544 gst_message_new_stream_status (GstObject * src, GstStreamStatusType type,
1545     GstElement * owner)
1546 {
1547   GstMessage *message;
1548   GstStructure *structure;
1549
1550   structure = gst_structure_id_new (GST_QUARK (MESSAGE_STREAM_STATUS),
1551       GST_QUARK (TYPE), GST_TYPE_STREAM_STATUS_TYPE, (gint) type,
1552       GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner, NULL);
1553   message = gst_message_new_custom (GST_MESSAGE_STREAM_STATUS, src, structure);
1554
1555   return message;
1556 }
1557
1558 /**
1559  * gst_message_parse_stream_status:
1560  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1561  * @type: A pointer to hold the status type
1562  * @owner: The owner element of the message source
1563  *
1564  * Extracts the stream status type and owner the GstMessage. The returned
1565  * owner remains valid for as long as the reference to @message is valid and
1566  * should thus not be unreffed.
1567  *
1568  * MT safe.
1569  *
1570  * Since: 0.10.24.
1571  */
1572 void
1573 gst_message_parse_stream_status (GstMessage * message,
1574     GstStreamStatusType * type, GstElement ** owner)
1575 {
1576   const GValue *owner_gvalue;
1577
1578   g_return_if_fail (GST_IS_MESSAGE (message));
1579   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
1580
1581   owner_gvalue =
1582       gst_structure_id_get_value (message->structure, GST_QUARK (OWNER));
1583   g_return_if_fail (owner_gvalue != NULL);
1584
1585   if (type)
1586     *type = g_value_get_enum (gst_structure_id_get_value (message->structure,
1587             GST_QUARK (TYPE)));
1588   if (owner)
1589     *owner = (GstElement *) g_value_get_object (owner_gvalue);
1590 }
1591
1592 /**
1593  * gst_message_set_stream_status_object:
1594  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1595  * @object: the object controlling the streaming
1596  *
1597  * Configures the object handling the streaming thread. This is usually a
1598  * GstTask object but other objects might be added in the future.
1599  *
1600  * Since: 0.10.24
1601  */
1602 void
1603 gst_message_set_stream_status_object (GstMessage * message,
1604     const GValue * object)
1605 {
1606   g_return_if_fail (GST_IS_MESSAGE (message));
1607   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
1608
1609   gst_structure_id_set_value (message->structure, GST_QUARK (OBJECT), object);
1610 }
1611
1612 /**
1613  * gst_message_get_stream_status_object:
1614  * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
1615  *
1616  * Extracts the object managing the streaming thread from @message.
1617  *
1618  * Returns: a GValue containing the object that manages the streaming thread.
1619  * This object is usually of type GstTask but other types can be added in the
1620  * future. The object remains valid as long as @message is valid.
1621  *
1622  * Since: 0.10.24
1623  */
1624 const GValue *
1625 gst_message_get_stream_status_object (GstMessage * message)
1626 {
1627   const GValue *result;
1628
1629   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
1630   g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS,
1631       NULL);
1632
1633   result = gst_structure_id_get_value (message->structure, GST_QUARK (OBJECT));
1634
1635   return result;
1636 }