tests/check/: use the new macro
[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
61
62 static void gst_message_init (GTypeInstance * instance, gpointer g_class);
63 static void gst_message_class_init (gpointer g_class, gpointer class_data);
64 static void gst_message_finalize (GstMessage * message);
65 static GstMessage *_gst_message_copy (GstMessage * message);
66
67 void
68 _gst_message_initialize (void)
69 {
70   gpointer ptr;
71
72   GST_CAT_INFO (GST_CAT_GST_INIT, "init messages");
73
74   gst_message_get_type ();
75
76   /* the GstMiniObject types need to be class_ref'd once before it can be
77    * done from multiple threads;
78    * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
79   ptr = g_type_class_ref (GST_TYPE_MESSAGE);
80   g_type_class_unref (ptr);
81 }
82
83 typedef struct
84 {
85   const gint type;
86   const gchar *name;
87   GQuark quark;
88 } GstMessageQuarks;
89
90 static GstMessageQuarks message_quarks[] = {
91   {GST_MESSAGE_UNKNOWN, "unknown", 0},
92   {GST_MESSAGE_EOS, "eos", 0},
93   {GST_MESSAGE_ERROR, "error", 0},
94   {GST_MESSAGE_WARNING, "warning", 0},
95   {GST_MESSAGE_INFO, "info", 0},
96   {GST_MESSAGE_TAG, "tag", 0},
97   {GST_MESSAGE_BUFFERING, "buffering", 0},
98   {GST_MESSAGE_STATE_CHANGED, "state-changed", 0},
99   {GST_MESSAGE_STATE_DIRTY, "state-dirty", 0},
100   {GST_MESSAGE_STEP_DONE, "step-done", 0},
101   {GST_MESSAGE_CLOCK_PROVIDE, "clock-provide", 0},
102   {GST_MESSAGE_CLOCK_LOST, "clock-lost", 0},
103   {GST_MESSAGE_NEW_CLOCK, "new-clock", 0},
104   {GST_MESSAGE_STRUCTURE_CHANGE, "structure-change", 0},
105   {GST_MESSAGE_STREAM_STATUS, "stream-status", 0},
106   {GST_MESSAGE_APPLICATION, "application", 0},
107   {GST_MESSAGE_ELEMENT, "element", 0},
108   {GST_MESSAGE_SEGMENT_START, "segment-start", 0},
109   {GST_MESSAGE_SEGMENT_DONE, "segment-done", 0},
110   {GST_MESSAGE_DURATION, "duration", 0},
111   {0, NULL, 0}
112 };
113
114 /**
115  * gst_message_type_get_name:
116  * @type: the message type
117  *
118  * Get a printable name for the given message type. Do not modify or free.
119  *
120  * Returns: a reference to the static name of the message.
121  */
122 const gchar *
123 gst_message_type_get_name (GstMessageType type)
124 {
125   gint i;
126
127   for (i = 0; message_quarks[i].name; i++) {
128     if (type == message_quarks[i].type)
129       return message_quarks[i].name;
130   }
131   return "unknown";
132 }
133
134 /**
135  * gst_message_type_to_quark:
136  * @type: the message type
137  *
138  * Get the unique quark for the given message type.
139  *
140  * Returns: the quark associated with the message type
141  */
142 GQuark
143 gst_message_type_to_quark (GstMessageType type)
144 {
145   gint i;
146
147   for (i = 0; message_quarks[i].name; i++) {
148     if (type == message_quarks[i].type)
149       return message_quarks[i].quark;
150   }
151   return 0;
152 }
153
154 GType
155 gst_message_get_type (void)
156 {
157   static GType _gst_message_type;
158
159   if (G_UNLIKELY (_gst_message_type == 0)) {
160     gint i;
161     static const GTypeInfo message_info = {
162       sizeof (GstMessageClass),
163       NULL,
164       NULL,
165       gst_message_class_init,
166       NULL,
167       NULL,
168       sizeof (GstMessage),
169       0,
170       gst_message_init,
171       NULL
172     };
173
174     _gst_message_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
175         "GstMessage", &message_info, 0);
176
177     for (i = 0; message_quarks[i].name; i++) {
178       message_quarks[i].quark =
179           g_quark_from_static_string (message_quarks[i].name);
180     }
181   }
182   return _gst_message_type;
183 }
184
185 static void
186 gst_message_class_init (gpointer g_class, gpointer class_data)
187 {
188   GstMessageClass *message_class = GST_MESSAGE_CLASS (g_class);
189
190   message_class->mini_object_class.copy =
191       (GstMiniObjectCopyFunction) _gst_message_copy;
192   message_class->mini_object_class.finalize =
193       (GstMiniObjectFinalizeFunction) gst_message_finalize;
194 }
195
196 static void
197 gst_message_init (GTypeInstance * instance, gpointer g_class)
198 {
199   GstMessage *message = GST_MESSAGE (instance);
200
201   GST_CAT_LOG (GST_CAT_MESSAGE, "new message %p", message);
202   GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
203 }
204
205 static void
206 gst_message_finalize (GstMessage * message)
207 {
208   g_return_if_fail (message != NULL);
209
210   GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p", message);
211
212   if (GST_MESSAGE_SRC (message)) {
213     gst_object_unref (GST_MESSAGE_SRC (message));
214     GST_MESSAGE_SRC (message) = NULL;
215   }
216
217   if (message->lock) {
218     GST_MESSAGE_LOCK (message);
219     GST_MESSAGE_SIGNAL (message);
220     GST_MESSAGE_UNLOCK (message);
221   }
222
223   if (message->structure) {
224     gst_structure_set_parent_refcount (message->structure, NULL);
225     gst_structure_free (message->structure);
226   }
227 }
228
229 static GstMessage *
230 _gst_message_copy (GstMessage * message)
231 {
232   GstMessage *copy;
233
234   GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p", message);
235
236   copy = (GstMessage *) gst_mini_object_new (GST_TYPE_MESSAGE);
237
238   /* FIXME, need to copy relevant data from the miniobject. */
239   //memcpy (copy, message, sizeof (GstMessage));
240
241   GST_MESSAGE_GET_LOCK (copy) = GST_MESSAGE_GET_LOCK (message);
242   GST_MESSAGE_COND (copy) = GST_MESSAGE_COND (message);
243   GST_MESSAGE_TYPE (copy) = GST_MESSAGE_TYPE (message);
244   GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
245
246   if (GST_MESSAGE_SRC (message)) {
247     GST_MESSAGE_SRC (copy) = gst_object_ref (GST_MESSAGE_SRC (message));
248   }
249
250   if (message->structure) {
251     copy->structure = gst_structure_copy (message->structure);
252     gst_structure_set_parent_refcount (copy->structure,
253         &copy->mini_object.refcount);
254   }
255
256   return copy;
257 }
258
259 /**
260  * gst_message_new_custom:
261  * @type: The #GstMessageType to distinguish messages
262  * @src: The object originating the message.
263  * @structure: The structure for the message. The message will take ownership of
264  * the structure.
265  *
266  * Create a new custom-typed message. This can be used for anything not
267  * handled by other message-specific functions to pass a message to the
268  * app. The structure field can be NULL.
269  *
270  * Returns: The new message.
271  *
272  * MT safe.
273  */
274 GstMessage *
275 gst_message_new_custom (GstMessageType type, GstObject * src,
276     GstStructure * structure)
277 {
278   GstMessage *message;
279
280   message = (GstMessage *) gst_mini_object_new (GST_TYPE_MESSAGE);
281
282   GST_CAT_LOG (GST_CAT_MESSAGE, "source %s: creating new message %p %s",
283       (src ? GST_OBJECT_NAME (src) : "NULL"), message,
284       gst_message_type_get_name (type));
285
286   message->type = type;
287
288   if (src)
289     gst_object_ref (src);
290   message->src = src;
291
292   if (structure) {
293     gst_structure_set_parent_refcount (structure,
294         &message->mini_object.refcount);
295   }
296   message->structure = structure;
297
298   return message;
299 }
300
301 /**
302  * gst_message_new_eos:
303  * @src: The object originating the message.
304  *
305  * Create a new eos message. This message is generated and posted in
306  * the sink elements of a GstBin. The bin will only forward the EOS
307  * message to the application if all sinks have posted an EOS message.
308  *
309  * Returns: The new eos message.
310  *
311  * MT safe.
312  */
313 GstMessage *
314 gst_message_new_eos (GstObject * src)
315 {
316   GstMessage *message;
317
318   message = gst_message_new_custom (GST_MESSAGE_EOS, src, NULL);
319
320   return message;
321 }
322
323 /**
324  * gst_message_new_error:
325  * @src: The object originating the message.
326  * @error: The GError for this message.
327  * @debug: A debugging string for something or other.
328  *
329  * Create a new error message. The message will copy @error and
330  * @debug. This message is posted by element when a fatal event
331  * occured. The pipeline will probably (partially) stop.
332  *
333  * Returns: The new error message.
334  *
335  * MT safe.
336  */
337 GstMessage *
338 gst_message_new_error (GstObject * src, GError * error, gchar * debug)
339 {
340   GstMessage *message;
341
342   message = gst_message_new_custom (GST_MESSAGE_ERROR, src,
343       gst_structure_new ("GstMessageError", "gerror", GST_TYPE_G_ERROR, error,
344           "debug", G_TYPE_STRING, debug, NULL));
345
346   return message;
347 }
348
349 /**
350  * gst_message_new_warning:
351  * @src: The object originating the message.
352  * @error: The GError for this message.
353  * @debug: A debugging string for something or other.
354  *
355  * Create a new warning message. The message will make copies of @error and
356  * @debug.
357  *
358  * Returns: The new warning message.
359  *
360  * MT safe.
361  */
362 GstMessage *
363 gst_message_new_warning (GstObject * src, GError * error, gchar * debug)
364 {
365   GstMessage *message;
366
367   message = gst_message_new_custom (GST_MESSAGE_WARNING, src,
368       gst_structure_new ("GstMessageWarning", "gerror", GST_TYPE_G_ERROR, error,
369           "debug", G_TYPE_STRING, debug, NULL));
370
371   return message;
372 }
373
374 /**
375  * gst_message_new_tag:
376  * @src: The object originating the message.
377  * @tag_list: The tag list for the message.
378  *
379  * Create a new tag message. The message will take ownership of the tag list.
380  * The message is posted by elements that discovered a new taglist.
381  *
382  * Returns: The new tag message.
383  *
384  * MT safe.
385  */
386 GstMessage *
387 gst_message_new_tag (GstObject * src, GstTagList * tag_list)
388 {
389   GstMessage *message;
390
391   g_return_val_if_fail (GST_IS_STRUCTURE (tag_list), NULL);
392
393   message =
394       gst_message_new_custom (GST_MESSAGE_TAG, src, (GstStructure *) tag_list);
395
396   return message;
397 }
398
399 /**
400  * gst_message_new_state_changed:
401  * @src: the object originating the message
402  * @oldstate: the previous state
403  * @newstate: the new (current) state
404  * @pending: the pending (target) state
405  *
406  * Create a state change message. This message is posted whenever an element
407  * changed its state.
408  *
409  * Returns: The new state change message.
410  *
411  * MT safe.
412  */
413 GstMessage *
414 gst_message_new_state_changed (GstObject * src,
415     GstState oldstate, GstState newstate, GstState pending)
416 {
417   GstMessage *message;
418
419   message = gst_message_new_custom (GST_MESSAGE_STATE_CHANGED, src,
420       gst_structure_new ("GstMessageState",
421           "old-state", GST_TYPE_STATE, (gint) oldstate,
422           "new-state", GST_TYPE_STATE, (gint) newstate,
423           "pending-state", GST_TYPE_STATE, (gint) pending, NULL));
424
425   return message;
426 }
427
428 /**
429  * gst_message_new_state_dirty:
430  * @src: the object originating the message
431  *
432  * Create a state dirty message. This message is posted whenever an element
433  * changed its state asynchronously and is used internally to update the
434  * states of container objects.
435  *
436  * Returns: The new state dirty message.
437  *
438  * MT safe.
439  */
440 GstMessage *
441 gst_message_new_state_dirty (GstObject * src)
442 {
443   GstMessage *message;
444
445   message = gst_message_new_custom (GST_MESSAGE_STATE_DIRTY, src, NULL);
446
447   return message;
448 }
449
450 /**
451  * gst_message_new_clock_provide:
452  * @src: The object originating the message.
453  * @clock: The clock it provides
454  * @ready: TRUE if the sender can provide a clock
455  *
456  * Create a clock provide message. This message is posted whenever an
457  * element is ready to provide a clock or lost its ability to provide
458  * a clock (maybe because it paused or became EOS).
459  *
460  * This message is mainly used internally to manage the clock
461  * selection.
462  *
463  * Returns: The new provide clock message.
464  *
465  * MT safe.
466  */
467 GstMessage *
468 gst_message_new_clock_provide (GstObject * src, GstClock * clock,
469     gboolean ready)
470 {
471   GstMessage *message;
472
473   message = gst_message_new_custom (GST_MESSAGE_CLOCK_PROVIDE, src,
474       gst_structure_new ("GstMessageClockProvide",
475           "clock", GST_TYPE_CLOCK, clock,
476           "ready", G_TYPE_BOOLEAN, ready, NULL));
477
478   return message;
479 }
480
481 /**
482  * gst_message_new_clock_lost:
483  * @src: The object originating the message.
484  * @clock: the clock that was lost
485  *
486  * Create a clock lost message. This message is posted whenever the
487  * clock is not valid anymore.
488  *
489  * If this message is posted by the pipeline, the pipeline will
490  * select a new clock again when it goes to PLAYING. It might therefore
491  * be needed to set the pipeline to PAUSED and PLAYING again.
492  *
493  * Returns: The new clock lost message.
494  *
495  * MT safe.
496  */
497 GstMessage *
498 gst_message_new_clock_lost (GstObject * src, GstClock * clock)
499 {
500   GstMessage *message;
501
502   message = gst_message_new_custom (GST_MESSAGE_CLOCK_LOST, src,
503       gst_structure_new ("GstMessageClockLost",
504           "clock", GST_TYPE_CLOCK, clock, NULL));
505
506   return message;
507 }
508
509 /**
510  * gst_message_new_new_clock:
511  * @src: The object originating the message.
512  * @clock: the new selected clock
513  *
514  * Create a new clock message. This message is posted whenever the
515  * pipeline selectes a new clock for the pipeline.
516  *
517  * Returns: The new new clock message.
518  *
519  * MT safe.
520  */
521 GstMessage *
522 gst_message_new_new_clock (GstObject * src, GstClock * clock)
523 {
524   GstMessage *message;
525
526   message = gst_message_new_custom (GST_MESSAGE_NEW_CLOCK, src,
527       gst_structure_new ("GstMessageNewClock",
528           "clock", GST_TYPE_CLOCK, clock, NULL));
529
530   return message;
531 }
532
533 /**
534  * gst_message_new_segment_start:
535  * @src: The object originating the message.
536  * @format: The format of the position being played
537  * @position: The position of the segment being played
538  *
539  * Create a new segment message. This message is posted by elements that
540  * start playback of a segment as a result of a segment seek. This message
541  * is not received by the application but is used for maintenance reasons in
542  * container elements.
543  *
544  * Returns: The new segment start message.
545  *
546  * MT safe.
547  */
548 GstMessage *
549 gst_message_new_segment_start (GstObject * src, GstFormat format,
550     gint64 position)
551 {
552   GstMessage *message;
553
554   message = gst_message_new_custom (GST_MESSAGE_SEGMENT_START, src,
555       gst_structure_new ("GstMessageSegmentStart",
556           "format", GST_TYPE_FORMAT, format,
557           "position", G_TYPE_INT64, position, NULL));
558
559   return message;
560 }
561
562 /**
563  * gst_message_new_segment_done:
564  * @src: The object originating the message.
565  * @format: The format of the position being done
566  * @position: The position of the segment being done
567  *
568  * Create a new segment done message. This message is posted by elements that
569  * finish playback of a segment as a result of a segment seek. This message
570  * is received by the application after all elements that posted a segment_start
571  * have posted the segment_done.
572  *
573  * Returns: The new segment done message.
574  *
575  * MT safe.
576  */
577 GstMessage *
578 gst_message_new_segment_done (GstObject * src, GstFormat format,
579     gint64 position)
580 {
581   GstMessage *message;
582
583   message = gst_message_new_custom (GST_MESSAGE_SEGMENT_DONE, src,
584       gst_structure_new ("GstMessageSegmentDone",
585           "format", GST_TYPE_FORMAT, format,
586           "position", G_TYPE_INT64, position, NULL));
587
588   return message;
589 }
590
591 /**
592  * gst_message_new_application:
593  * @src: The object originating the message.
594  * @structure: The structure for the message. The message will take ownership of
595  * the structure.
596  *
597  * Create a new application-typed message. GStreamer will never create these
598  * messages; they are a gift from us to you. Enjoy.
599  *
600  * Returns: The new application message.
601  *
602  * MT safe.
603  */
604 GstMessage *
605 gst_message_new_application (GstObject * src, GstStructure * structure)
606 {
607   return gst_message_new_custom (GST_MESSAGE_APPLICATION, src, structure);
608 }
609
610 /**
611  * gst_message_new_element:
612  * @src: The object originating the message.
613  * @structure: The structure for the message. The message will take ownership of
614  * the structure.
615  *
616  * Create a new element-specific message. This is meant as a generic way of
617  * allowing one-way communication from an element to an application, for example
618  * "the firewire cable was unplugged". The format of the message should be
619  * documented in the element's documentation. The structure field can be NULL.
620  *
621  * Returns: The new element message.
622  *
623  * MT safe.
624  */
625 GstMessage *
626 gst_message_new_element (GstObject * src, GstStructure * structure)
627 {
628   return gst_message_new_custom (GST_MESSAGE_ELEMENT, src, structure);
629 }
630
631 /**
632  * gst_message_new_duration:
633  * @src: The object originating the message.
634  * @format: The format of the duration
635  * @duration: The new duration 
636  *
637  * Create a new duration message. This message is posted by elements that
638  * know the duration of a stream in a specific format. This message
639  * is received by bins and is used to calculate the total duration of a
640  * pipeline. Elements may post a duration message with a duration of
641  * GST_CLOCK_TIME_NONE to indicate that the duration has changed and the 
642  * cached duration should be discarded. The new duration can then be 
643  * retrieved via a query.
644  *
645  * Returns: The new duration message.
646  *
647  * MT safe.
648  */
649 GstMessage *
650 gst_message_new_duration (GstObject * src, GstFormat format, gint64 duration)
651 {
652   GstMessage *message;
653
654   message = gst_message_new_custom (GST_MESSAGE_DURATION, src,
655       gst_structure_new ("GstMessageDuration",
656           "format", GST_TYPE_FORMAT, format,
657           "duration", G_TYPE_INT64, duration, NULL));
658
659   return message;
660 }
661
662 /**
663  * gst_message_get_structure:
664  * @message: The #GstMessage.
665  *
666  * Access the structure of the message.
667  *
668  * Returns: The structure of the message. The structure is still
669  * owned by the message, which means that you should not free it and
670  * that the pointer becomes invalid when you free the message.
671  *
672  * MT safe.
673  */
674 const GstStructure *
675 gst_message_get_structure (GstMessage * message)
676 {
677   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
678
679   return message->structure;
680 }
681
682 /**
683  * gst_message_parse_tag:
684  * @message: A valid #GstMessage of type GST_MESSAGE_TAG.
685  * @tag_list: Return location for the tag-list.
686  *
687  * Extracts the tag list from the GstMessage. The tag list returned in the
688  * output argument is a copy; the caller must free it when done.
689  *
690  * MT safe.
691  */
692 void
693 gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list)
694 {
695   g_return_if_fail (GST_IS_MESSAGE (message));
696   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
697   g_return_if_fail (tag_list != NULL);
698
699   *tag_list = (GstTagList *) gst_structure_copy (message->structure);
700 }
701
702 /**
703  * gst_message_parse_state_changed:
704  * @message: a valid #GstMessage of type GST_MESSAGE_STATE_CHANGED
705  * @oldstate: the previous state, or NULL
706  * @newstate: the new (current) state, or NULL
707  * @pending: the pending (target) state, or NULL
708  *
709  * Extracts the old and new states from the GstMessage.
710  *
711  * MT safe.
712  */
713 void
714 gst_message_parse_state_changed (GstMessage * message,
715     GstState * oldstate, GstState * newstate, GstState * pending)
716 {
717   g_return_if_fail (GST_IS_MESSAGE (message));
718   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STATE_CHANGED);
719
720   if (oldstate)
721     gst_structure_get_enum (message->structure, "old-state",
722         GST_TYPE_STATE, (gint *) oldstate);
723   if (newstate)
724     gst_structure_get_enum (message->structure, "new-state",
725         GST_TYPE_STATE, (gint *) newstate);
726   if (pending)
727     gst_structure_get_enum (message->structure, "pending-state",
728         GST_TYPE_STATE, (gint *) pending);
729 }
730
731 /**
732  * gst_message_parse_clock_provide:
733  * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_PROVIDE.
734  * @clock: A pointer to  hold a clock object.
735  * @ready: A pointer to hold the ready flag.
736  *
737  * Extracts the clock and ready flag from the GstMessage.
738  * The clock object returned remains valid until the message is freed.
739  *
740  * MT safe.
741  */
742 void
743 gst_message_parse_clock_provide (GstMessage * message, GstClock ** clock,
744     gboolean * ready)
745 {
746   const GValue *clock_gvalue;
747
748   g_return_if_fail (GST_IS_MESSAGE (message));
749   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_PROVIDE);
750
751   clock_gvalue = gst_structure_get_value (message->structure, "clock");
752   g_return_if_fail (clock_gvalue != NULL);
753   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
754
755   if (ready)
756     gst_structure_get_boolean (message->structure, "ready", ready);
757   if (clock)
758     *clock = (GstClock *) g_value_get_object (clock_gvalue);
759 }
760
761 /**
762  * gst_message_parse_clock_lost:
763  * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_LOST.
764  * @clock: A pointer to hold the lost clock
765  *
766  * Extracts the lost clock from the GstMessage.
767  * The clock object returned remains valid until the message is freed.
768  *
769  * MT safe.
770  */
771 void
772 gst_message_parse_clock_lost (GstMessage * message, GstClock ** clock)
773 {
774   const GValue *clock_gvalue;
775
776   g_return_if_fail (GST_IS_MESSAGE (message));
777   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_LOST);
778
779   clock_gvalue = gst_structure_get_value (message->structure, "clock");
780   g_return_if_fail (clock_gvalue != NULL);
781   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
782
783   if (clock)
784     *clock = (GstClock *) g_value_get_object (clock_gvalue);
785 }
786
787 /**
788  * gst_message_parse_new_clock:
789  * @message: A valid #GstMessage of type GST_MESSAGE_NEW_CLOCK.
790  * @clock: A pointer to hold the selected new clock
791  *
792  * Extracts the new clock from the GstMessage.
793  * The clock object returned remains valid until the message is freed.
794  *
795  * MT safe.
796  */
797 void
798 gst_message_parse_new_clock (GstMessage * message, GstClock ** clock)
799 {
800   const GValue *clock_gvalue;
801
802   g_return_if_fail (GST_IS_MESSAGE (message));
803   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEW_CLOCK);
804
805   clock_gvalue = gst_structure_get_value (message->structure, "clock");
806   g_return_if_fail (clock_gvalue != NULL);
807   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
808
809   if (clock)
810     *clock = (GstClock *) g_value_get_object (clock_gvalue);
811 }
812
813 /**
814  * gst_message_parse_error:
815  * @message: A valid #GstMessage of type GST_MESSAGE_ERROR.
816  * @gerror: Location for the GError
817  * @debug: Location for the debug message, or NULL
818  *
819  * Extracts the GError and debug string from the GstMessage. The values returned
820  * in the output arguments are copies; the caller must free them when done.
821  *
822  * MT safe.
823  */
824 void
825 gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug)
826 {
827   const GValue *error_gvalue;
828   GError *error_val;
829
830   g_return_if_fail (GST_IS_MESSAGE (message));
831   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
832
833   error_gvalue = gst_structure_get_value (message->structure, "gerror");
834   g_return_if_fail (error_gvalue != NULL);
835   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
836
837   error_val = (GError *) g_value_get_boxed (error_gvalue);
838   if (error_val)
839     *gerror = g_error_copy (error_val);
840   else
841     *gerror = NULL;
842
843   if (debug)
844     *debug = g_strdup (gst_structure_get_string (message->structure, "debug"));
845 }
846
847 /**
848  * gst_message_parse_warning:
849  * @message: A valid #GstMessage of type GST_MESSAGE_WARNING.
850  * @gerror: Location for the GError
851  * @debug: Location for the debug message, or NULL
852  *
853  * Extracts the GError and debug string from the GstMessage. The values returned
854  * in the output arguments are copies; the caller must free them when done.
855  *
856  * MT safe.
857  */
858 void
859 gst_message_parse_warning (GstMessage * message, GError ** gerror,
860     gchar ** debug)
861 {
862   const GValue *error_gvalue;
863   GError *error_val;
864
865   g_return_if_fail (GST_IS_MESSAGE (message));
866   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);
867
868   error_gvalue = gst_structure_get_value (message->structure, "gerror");
869   g_return_if_fail (error_gvalue != NULL);
870   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
871
872   error_val = (GError *) g_value_get_boxed (error_gvalue);
873   if (error_val)
874     *gerror = g_error_copy (error_val);
875   else
876     *gerror = NULL;
877
878   if (debug)
879     *debug = g_strdup (gst_structure_get_string (message->structure, "debug"));
880 }
881
882 /**
883  * gst_message_parse_segment_start:
884  * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_START.
885  * @format: Result location for the format, or NULL
886  * @position: Result location for the position, or NULL
887  *
888  * Extracts the position and format from the segment start message.
889  *
890  * MT safe.
891  */
892 void
893 gst_message_parse_segment_start (GstMessage * message, GstFormat * format,
894     gint64 * position)
895 {
896   const GstStructure *structure;
897
898   g_return_if_fail (GST_IS_MESSAGE (message));
899   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_START);
900
901   structure = gst_message_get_structure (message);
902   if (format)
903     *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
904   if (position)
905     *position =
906         g_value_get_int64 (gst_structure_get_value (structure, "position"));
907 }
908
909 /**
910  * gst_message_parse_segment_done:
911  * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_DONE.
912  * @format: Result location for the format, or NULL
913  * @position: Result location for the position, or NULL
914  *
915  * Extracts the position and format from the segment start message.
916  *
917  * MT safe.
918  */
919 void
920 gst_message_parse_segment_done (GstMessage * message, GstFormat * format,
921     gint64 * position)
922 {
923   const GstStructure *structure;
924
925   g_return_if_fail (GST_IS_MESSAGE (message));
926   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_DONE);
927
928   structure = gst_message_get_structure (message);
929   if (format)
930     *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
931   if (position)
932     *position =
933         g_value_get_int64 (gst_structure_get_value (structure, "position"));
934 }
935
936 /**
937  * gst_message_parse_duration:
938  * @message: A valid #GstMessage of type GST_MESSAGE_DURATION.
939  * @format: Result location for the format, or NULL
940  * @duration: Result location for the duration, or NULL
941  *
942  * Extracts the duration and format from the duration message. The duration
943  * might be GST_CLOCK_TIME_NONE, which indicates that the duration has
944  * changed. Applications should always use a query to retrieve the duration
945  * of a pipeline.
946  *
947  * MT safe.
948  */
949 void
950 gst_message_parse_duration (GstMessage * message, GstFormat * format,
951     gint64 * duration)
952 {
953   const GstStructure *structure;
954
955   g_return_if_fail (GST_IS_MESSAGE (message));
956   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION);
957
958   structure = gst_message_get_structure (message);
959   if (format)
960     *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
961   if (duration)
962     *duration =
963         g_value_get_int64 (gst_structure_get_value (structure, "duration"));
964 }