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