gstreamer_core/gst/gstmessage.c
changeset 16 8e837d1bf446
parent 0 0e761a78d257
child 30 7e817e7e631c
--- a/gstreamer_core/gst/gstmessage.c	Wed Mar 24 17:58:42 2010 -0500
+++ b/gstreamer_core/gst/gstmessage.c	Wed Mar 24 18:04:17 2010 -0500
@@ -57,14 +57,14 @@
 #include "gstmessage.h"
 #include "gsttaglist.h"
 #include "gstutils.h"
+#include "gstquark.h"
 
 #ifdef __SYMBIAN32__
 #include <glib_global.h>
 #endif
 
+#define GST_MESSAGE_SEQNUM(e) ((GstMessage*)e)->abidata.ABI.seqnum
 
-static void gst_message_init (GTypeInstance * instance, gpointer g_class);
-static void gst_message_class_init (gpointer g_class, gpointer class_data);
 static void gst_message_finalize (GstMessage * message);
 static GstMessage *_gst_message_copy (GstMessage * message);
 
@@ -116,6 +116,8 @@
   {GST_MESSAGE_LATENCY, "latency", 0},
   {GST_MESSAGE_ASYNC_START, "async-start", 0},
   {GST_MESSAGE_ASYNC_DONE, "async-done", 0},
+  {GST_MESSAGE_REQUEST_STATE, "request-state", 0},
+  {GST_MESSAGE_STEP_START, "step-start", 0},
   {0, NULL, 0}
 };
 
@@ -166,60 +168,33 @@
   }
   return 0;
 }
-#ifdef __SYMBIAN32__
-EXPORT_C
-#endif
 
-
-GType
-gst_message_get_type (void)
-{
-  static GType _gst_message_type;
-
-  if (G_UNLIKELY (_gst_message_type == 0)) {
-    gint i;
-    static const GTypeInfo message_info = {
-      sizeof (GstMessageClass),
-      NULL,
-      NULL,
-      gst_message_class_init,
-      NULL,
-      NULL,
-      sizeof (GstMessage),
-      0,
-      gst_message_init,
-      NULL
-    };
-
-    _gst_message_type = g_type_register_static (GST_TYPE_MINI_OBJECT,
-        "GstMessage", &message_info, 0);
-
-    for (i = 0; message_quarks[i].name; i++) {
-      message_quarks[i].quark =
-          g_quark_from_static_string (message_quarks[i].name);
-    }
-  }
-  return _gst_message_type;
+#define _do_init \
+{ \
+  gint i; \
+  \
+  for (i = 0; message_quarks[i].name; i++) { \
+    message_quarks[i].quark = \
+        g_quark_from_static_string (message_quarks[i].name); \
+  } \
 }
 
-static void
-gst_message_class_init (gpointer g_class, gpointer class_data)
-{
-  GstMessageClass *message_class = GST_MESSAGE_CLASS (g_class);
+G_DEFINE_TYPE_WITH_CODE (GstMessage, gst_message, GST_TYPE_MINI_OBJECT,
+    _do_init);
 
-  parent_class = g_type_class_peek_parent (g_class);
+static void
+gst_message_class_init (GstMessageClass * klass)
+{
+  parent_class = g_type_class_peek_parent (klass);
 
-  message_class->mini_object_class.copy =
-      (GstMiniObjectCopyFunction) _gst_message_copy;
-  message_class->mini_object_class.finalize =
+  klass->mini_object_class.copy = (GstMiniObjectCopyFunction) _gst_message_copy;
+  klass->mini_object_class.finalize =
       (GstMiniObjectFinalizeFunction) gst_message_finalize;
 }
 
 static void
-gst_message_init (GTypeInstance * instance, gpointer g_class)
+gst_message_init (GstMessage * message)
 {
-  GstMessage *message = GST_MESSAGE (instance);
-
   GST_CAT_LOG (GST_CAT_MESSAGE, "new message %p", message);
   GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
 }
@@ -247,7 +222,7 @@
     gst_structure_free (message->structure);
   }
 
-  GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (message));
+/*   GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (message)); */
 }
 
 static GstMessage *
@@ -266,6 +241,7 @@
   GST_MESSAGE_COND (copy) = GST_MESSAGE_COND (message);
   GST_MESSAGE_TYPE (copy) = GST_MESSAGE_TYPE (message);
   GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
+  GST_MESSAGE_SEQNUM (copy) = GST_MESSAGE_SEQNUM (message);
 
   if (GST_MESSAGE_SRC (message)) {
     GST_MESSAGE_SRC (copy) = gst_object_ref (GST_MESSAGE_SRC (message));
@@ -323,10 +299,74 @@
   }
   message->structure = structure;
 
+  GST_MESSAGE_SEQNUM (message) = gst_util_seqnum_next ();
+
   return message;
 }
 
 /**
+ * gst_message_get_seqnum:
+ * @message: A #GstMessage.
+ *
+ * Retrieve the sequence number of a message.
+ *
+ * Messages have ever-incrementing sequence numbers, which may also be set
+ * explicitly via gst_message_set_seqnum(). Sequence numbers are typically used
+ * to indicate that a message corresponds to some other set of messages or
+ * events, for example a SEGMENT_DONE message corresponding to a SEEK event. It
+ * is considered good practice to make this correspondence when possible, though
+ * it is not required.
+ *
+ * Note that events and messages share the same sequence number incrementor;
+ * two events or messages will never not have the same sequence number unless
+ * that correspondence was made explicitly.
+ *
+ * Returns: The message's sequence number.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.22
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+guint32
+gst_message_get_seqnum (GstMessage * message)
+{
+  g_return_val_if_fail (GST_IS_MESSAGE (message), -1);
+
+  return GST_MESSAGE_SEQNUM (message);
+}
+
+/**
+ * gst_message_set_seqnum:
+ * @message: A #GstMessage.
+ * @seqnum: A sequence number.
+ *
+ * Set the sequence number of a message.
+ *
+ * This function might be called by the creator of a message to indicate that
+ * the message relates to other messages or events. See gst_message_get_seqnum()
+ * for more information.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.22
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_set_seqnum (GstMessage * message, guint32 seqnum)
+{
+  g_return_if_fail (GST_IS_MESSAGE (message));
+
+  GST_MESSAGE_SEQNUM (message) = seqnum;
+}
+
+/**
  * gst_message_new_eos:
  * @src: The object originating the message.
  *
@@ -356,7 +396,7 @@
  * gst_message_new_error:
  * @src: The object originating the message.
  * @error: The GError for this message.
- * @debug: A debugging string for something or other.
+ * @debug: A debugging string.
  *
  * Create a new error message. The message will copy @error and
  * @debug. This message is posted by element when a fatal event
@@ -372,13 +412,15 @@
 #endif
 
 GstMessage *
-gst_message_new_error (GstObject * src, GError * error, gchar * debug)
+gst_message_new_error (GstObject * src, GError * error, const gchar * debug)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_ERROR, src,
-      gst_structure_new ("GstMessageError", "gerror", GST_TYPE_G_ERROR, error,
-          "debug", G_TYPE_STRING, debug, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_ERROR),
+      GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
+      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_ERROR, src, structure);
 
   return message;
 }
@@ -387,7 +429,7 @@
  * gst_message_new_warning:
  * @src: The object originating the message.
  * @error: The GError for this message.
- * @debug: A debugging string for something or other.
+ * @debug: A debugging string.
  *
  * Create a new warning message. The message will make copies of @error and
  * @debug.
@@ -401,13 +443,15 @@
 #endif
 
 GstMessage *
-gst_message_new_warning (GstObject * src, GError * error, gchar * debug)
+gst_message_new_warning (GstObject * src, GError * error, const gchar * debug)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_WARNING, src,
-      gst_structure_new ("GstMessageWarning", "gerror", GST_TYPE_G_ERROR, error,
-          "debug", G_TYPE_STRING, debug, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_WARNING),
+      GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
+      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_WARNING, src, structure);
 
   return message;
 }
@@ -416,29 +460,31 @@
  * gst_message_new_info:
  * @src: The object originating the message.
  * @error: The GError for this message.
- * @debug: A debugging string for something or other.
+ * @debug: A debugging string.
  *
  * Create a new info message. The message will make copies of @error and
  * @debug.
  *
+ * MT safe.
+ *
  * Returns: The new info message.
  *
  * Since: 0.10.12
- *
- * MT safe.
  */
 #ifdef __SYMBIAN32__
 EXPORT_C
 #endif
 
 GstMessage *
-gst_message_new_info (GstObject * src, GError * error, gchar * debug)
+gst_message_new_info (GstObject * src, GError * error, const gchar * debug)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_INFO, src,
-      gst_structure_new ("GstMessageInfo", "gerror", GST_TYPE_G_ERROR, error,
-          "debug", G_TYPE_STRING, debug, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_INFO),
+      GST_QUARK (GERROR), GST_TYPE_G_ERROR, error,
+      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_INFO, src, structure);
 
   return message;
 }
@@ -473,6 +519,43 @@
 }
 
 /**
+ * gst_message_new_tag_full:
+ * @src: The object originating the message.
+ * @pad: The originating pad for the tag.
+ * @tag_list: The tag list for the message.
+ *
+ * Create a new tag message. The message will take ownership of the tag list.
+ * The message is posted by elements that discovered a new taglist.
+ *
+ * MT safe.
+ *
+ * Returns: The new tag message.
+ *
+ * Since: 0.10.24
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+GstMessage *
+gst_message_new_tag_full (GstObject * src, GstPad * pad, GstTagList * tag_list)
+{
+  GstMessage *message;
+  GstStructure *s;
+
+  g_return_val_if_fail (GST_IS_STRUCTURE (tag_list), NULL);
+  g_return_val_if_fail (pad == NULL || GST_IS_PAD (pad), NULL);
+
+  s = (GstStructure *) tag_list;
+  if (pad)
+    gst_structure_set (s, "source-pad", GST_TYPE_PAD, pad, NULL);
+
+  message = gst_message_new_custom (GST_MESSAGE_TAG, src, s);
+
+  return message;
+}
+
+/**
  * gst_message_new_buffering:
  * @src: The object originating the message.
  * @percent: The buffering percent
@@ -488,11 +571,11 @@
  * message with @percent set to 100, which can happen after the pipeline
  * completed prerolling. 
  *
+ * MT safe.
+ *
  * Returns: The new buffering message.
  *
  * Since: 0.10.11
- *
- * MT safe.
  */
 #ifdef __SYMBIAN32__
 EXPORT_C
@@ -502,12 +585,18 @@
 gst_message_new_buffering (GstObject * src, gint percent)
 {
   GstMessage *message;
+  GstStructure *structure;
 
   g_return_val_if_fail (percent >= 0 && percent <= 100, NULL);
 
-  message = gst_message_new_custom (GST_MESSAGE_BUFFERING, src,
-      gst_structure_new ("GstMessageBuffering",
-          "buffer-percent", G_TYPE_INT, percent, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_BUFFERING),
+      GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent,
+      GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, GST_BUFFERING_STREAM,
+      GST_QUARK (AVG_IN_RATE), G_TYPE_INT, -1,
+      GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, -1,
+      GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, G_GINT64_CONSTANT (-1),
+      GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL);
+  message = gst_message_new_custom (GST_MESSAGE_BUFFERING, src, structure);
 
   return message;
 }
@@ -535,12 +624,13 @@
     GstState oldstate, GstState newstate, GstState pending)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_STATE_CHANGED, src,
-      gst_structure_new ("GstMessageState",
-          "old-state", GST_TYPE_STATE, (gint) oldstate,
-          "new-state", GST_TYPE_STATE, (gint) newstate,
-          "pending-state", GST_TYPE_STATE, (gint) pending, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_STATE),
+      GST_QUARK (OLD_STATE), GST_TYPE_STATE, (gint) oldstate,
+      GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) newstate,
+      GST_QUARK (PENDING_STATE), GST_TYPE_STATE, (gint) pending, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_STATE_CHANGED, src, structure);
 
   return message;
 }
@@ -597,11 +687,12 @@
     gboolean ready)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_CLOCK_PROVIDE, src,
-      gst_structure_new ("GstMessageClockProvide",
-          "clock", GST_TYPE_CLOCK, clock,
-          "ready", G_TYPE_BOOLEAN, ready, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_CLOCK_PROVIDE),
+      GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock,
+      GST_QUARK (READY), G_TYPE_BOOLEAN, ready, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_CLOCK_PROVIDE, src, structure);
 
   return message;
 }
@@ -630,10 +721,11 @@
 gst_message_new_clock_lost (GstObject * src, GstClock * clock)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_CLOCK_LOST, src,
-      gst_structure_new ("GstMessageClockLost",
-          "clock", GST_TYPE_CLOCK, clock, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_CLOCK_LOST),
+      GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_CLOCK_LOST, src, structure);
 
   return message;
 }
@@ -658,10 +750,56 @@
 gst_message_new_new_clock (GstObject * src, GstClock * clock)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_NEW_CLOCK, src,
-      gst_structure_new ("GstMessageNewClock",
-          "clock", GST_TYPE_CLOCK, clock, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_NEW_CLOCK),
+      GST_QUARK (CLOCK), GST_TYPE_CLOCK, clock, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_NEW_CLOCK, src, structure);
+
+  return message;
+}
+
+/**
+ * gst_message_new_structure_change:
+ * @src: The object originating the message.
+ * @type: The change type.
+ * @owner: The owner element of @src.
+ * @busy: Whether the structure change is busy.
+ *
+ * Create a new structure change message. This message is posted when the
+ * structure of a pipeline is in the process of being changed, for example
+ * when pads are linked or unlinked.
+ *
+ * @src should be the srcpad that unlinked or linked.
+ *
+ * Returns: The new structure change message.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.22.
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+GstMessage *
+gst_message_new_structure_change (GstObject * src, GstStructureChangeType type,
+    GstElement * owner, gboolean busy)
+{
+  GstMessage *message;
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_IS_PAD (src), NULL);
+  g_return_val_if_fail (GST_PAD_DIRECTION (src) == GST_PAD_SRC, NULL);
+  g_return_val_if_fail (GST_IS_ELEMENT (owner), NULL);
+
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_STRUCTURE_CHANGE),
+      GST_QUARK (TYPE), GST_TYPE_STRUCTURE_CHANGE_TYPE, type,
+      GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner,
+      GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy, NULL);
+
+  message = gst_message_new_custom (GST_MESSAGE_STRUCTURE_CHANGE, src,
+      structure);
 
   return message;
 }
@@ -690,11 +828,12 @@
     gint64 position)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_SEGMENT_START, src,
-      gst_structure_new ("GstMessageSegmentStart",
-          "format", GST_TYPE_FORMAT, format,
-          "position", G_TYPE_INT64, position, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_SEGMENT_START),
+      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
+      GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_SEGMENT_START, src, structure);
 
   return message;
 }
@@ -723,11 +862,12 @@
     gint64 position)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_SEGMENT_DONE, src,
-      gst_structure_new ("GstMessageSegmentDone",
-          "format", GST_TYPE_FORMAT, format,
-          "position", G_TYPE_INT64, position, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_SEGMENT_DONE),
+      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
+      GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_SEGMENT_DONE, src, structure);
 
   return message;
 }
@@ -806,11 +946,12 @@
 gst_message_new_duration (GstObject * src, GstFormat format, gint64 duration)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_DURATION, src,
-      gst_structure_new ("GstMessageDuration",
-          "format", GST_TYPE_FORMAT, format,
-          "duration", G_TYPE_INT64, duration, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_DURATION),
+      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
+      GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_DURATION, src, structure);
 
   return message;
 }
@@ -838,10 +979,11 @@
 gst_message_new_async_start (GstObject * src, gboolean new_base_time)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src,
-      gst_structure_new ("GstMessageAsyncStart",
-          "new-base-time", G_TYPE_BOOLEAN, new_base_time, NULL));
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_ASYNC_START),
+      GST_QUARK (NEW_BASE_TIME), G_TYPE_BOOLEAN, new_base_time, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src, structure);
 
   return message;
 }
@@ -900,6 +1042,38 @@
 }
 
 /**
+ * gst_message_new_request_state:
+ * @src: The object originating the message.
+ * @state: The new requested state
+ *
+ * This message can be posted by elements when they want to have their state
+ * changed. A typical use case would be an audio server that wants to pause the
+ * pipeline because a higher priority stream is being played.
+ *
+ * Returns: The new requst state message. 
+ *
+ * MT safe.
+ *
+ * Since: 0.10.23
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+GstMessage *
+gst_message_new_request_state (GstObject * src, GstState state)
+{
+  GstMessage *message;
+  GstStructure *structure;
+
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_REQUEST_STATE),
+      GST_QUARK (NEW_STATE), GST_TYPE_STATE, (gint) state, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_REQUEST_STATE, src, structure);
+
+  return message;
+}
+
+/**
  * gst_message_get_structure:
  * @message: The #GstMessage.
  *
@@ -940,11 +1114,61 @@
 void
 gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list)
 {
+  GstStructure *ret;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
   g_return_if_fail (tag_list != NULL);
 
-  *tag_list = (GstTagList *) gst_structure_copy (message->structure);
+  ret = gst_structure_copy (message->structure);
+  gst_structure_remove_field (ret, "source-pad");
+
+  *tag_list = (GstTagList *) ret;
+}
+
+/**
+ * gst_message_parse_tag_full:
+ * @message: A valid #GstMessage of type GST_MESSAGE_TAG.
+ * @pad: Location where the originating pad is stored, unref after usage
+ * @tag_list: Return location for the tag-list.
+ *
+ * Extracts the tag list from the GstMessage. The tag list returned in the
+ * output argument is a copy; the caller must free it when done.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.24
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_parse_tag_full (GstMessage * message, GstPad ** pad,
+    GstTagList ** tag_list)
+{
+  GstStructure *ret;
+
+  g_return_if_fail (GST_IS_MESSAGE (message));
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
+  g_return_if_fail (tag_list != NULL);
+
+  ret = gst_structure_copy (message->structure);
+
+  if (gst_structure_has_field (ret, "source-pad") && pad) {
+    const GValue *v;
+
+    v = gst_structure_get_value (ret, "source-pad");
+    if (v && G_VALUE_HOLDS (v, GST_TYPE_PAD))
+      *pad = (GstPad*)g_value_dup_object (v);
+    else
+      *pad = NULL;
+  } else if (pad) {
+    *pad = NULL;
+  }
+  gst_structure_remove_field (ret, "source-pad");
+
+  *tag_list = (GstTagList *) ret;
 }
 
 /**
@@ -955,9 +1179,9 @@
  * Extracts the buffering percent from the GstMessage. see also
  * gst_message_new_buffering().
  *
- * Since: 0.10.11
+ * MT safe.
  *
- * MT safe.
+ * Since: 0.10.11
  */
 #ifdef __SYMBIAN32__
 EXPORT_C
@@ -970,7 +1194,75 @@
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
 
   if (percent)
-    gst_structure_get_int (message->structure, "buffer-percent", percent);
+    *percent = g_value_get_int (gst_structure_id_get_value (message->structure,
+            GST_QUARK (BUFFER_PERCENT)));
+}
+
+/**
+ * gst_message_set_buffering_stats:
+ * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
+ * @mode: a buffering mode 
+ * @avg_in: the average input rate
+ * @avg_out: the average output rate
+ * @buffering_left: amount of buffering time left in milliseconds
+ *
+ * Configures the buffering stats values in @message.
+ *
+ * Since: 0.10.20
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_set_buffering_stats (GstMessage * message, GstBufferingMode mode,
+    gint avg_in, gint avg_out, gint64 buffering_left)
+{
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
+
+  gst_structure_id_set (message->structure,
+      GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
+      GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
+      GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
+      GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL);
+}
+
+/**
+ * gst_message_parse_buffering_stats:
+ * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
+ * @mode: a buffering mode 
+ * @avg_in: the average input rate
+ * @avg_out: the average output rate
+ * @buffering_left: amount of buffering time left in milliseconds.
+ *
+ * Extracts the buffering stats values from @message.
+ *
+ * Since: 0.10.20
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_parse_buffering_stats (GstMessage * message,
+    GstBufferingMode * mode, gint * avg_in, gint * avg_out,
+    gint64 * buffering_left)
+{
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
+
+  if (mode)
+    *mode = g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (BUFFERING_MODE)));
+  if (avg_in)
+    *avg_in = g_value_get_int (gst_structure_id_get_value (message->structure,
+            GST_QUARK (AVG_IN_RATE)));
+  if (avg_out)
+    *avg_out = g_value_get_int (gst_structure_id_get_value (message->structure,
+            GST_QUARK (AVG_OUT_RATE)));
+  if (buffering_left)
+    *buffering_left =
+        g_value_get_int64 (gst_structure_id_get_value (message->structure,
+            GST_QUARK (BUFFERING_LEFT)));
 }
 
 /**
@@ -996,14 +1288,16 @@
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STATE_CHANGED);
 
   if (oldstate)
-    gst_structure_get_enum (message->structure, "old-state",
-        GST_TYPE_STATE, (gint *) oldstate);
+    *oldstate =
+        g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (OLD_STATE)));
   if (newstate)
-    gst_structure_get_enum (message->structure, "new-state",
-        GST_TYPE_STATE, (gint *) newstate);
+    *newstate =
+        g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (NEW_STATE)));
   if (pending)
-    gst_structure_get_enum (message->structure, "pending-state",
-        GST_TYPE_STATE, (gint *) pending);
+    *pending = g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (PENDING_STATE)));
 }
 
 /**
@@ -1030,12 +1324,15 @@
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_PROVIDE);
 
-  clock_gvalue = gst_structure_get_value (message->structure, "clock");
+  clock_gvalue =
+      gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
   g_return_if_fail (clock_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
 
   if (ready)
-    gst_structure_get_boolean (message->structure, "ready", ready);
+    *ready =
+        g_value_get_boolean (gst_structure_id_get_value (message->structure,
+            GST_QUARK (READY)));
   if (clock)
     *clock = (GstClock *) g_value_get_object (clock_gvalue);
 }
@@ -1062,7 +1359,8 @@
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_LOST);
 
-  clock_gvalue = gst_structure_get_value (message->structure, "clock");
+  clock_gvalue =
+      gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
   g_return_if_fail (clock_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
 
@@ -1092,7 +1390,8 @@
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEW_CLOCK);
 
-  clock_gvalue = gst_structure_get_value (message->structure, "clock");
+  clock_gvalue =
+      gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
   g_return_if_fail (clock_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
 
@@ -1101,6 +1400,49 @@
 }
 
 /**
+ * gst_message_parse_structure_change:
+ * @message: A valid #GstMessage of type GST_MESSAGE_STRUCTURE_CHANGE.
+ * @type: A pointer to hold the change type
+ * @owner: The owner element of the message source
+ * @busy: A pointer to hold whether the change is in progress or has been
+ * completed
+ *
+ * Extracts the change type and completion status from the GstMessage.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.22
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_parse_structure_change (GstMessage * message,
+    GstStructureChangeType * type, GstElement ** owner, gboolean * busy)
+{
+  const GValue *owner_gvalue;
+
+  g_return_if_fail (GST_IS_MESSAGE (message));
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STRUCTURE_CHANGE);
+
+  owner_gvalue =
+      gst_structure_id_get_value (message->structure, GST_QUARK (OWNER));
+  g_return_if_fail (owner_gvalue != NULL);
+  g_return_if_fail (G_VALUE_TYPE (owner_gvalue) == GST_TYPE_ELEMENT);
+
+  if (type)
+    *type = g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (TYPE)));
+  if (owner)
+    *owner = (GstElement *) g_value_get_object (owner_gvalue);
+  if (busy)
+    *busy =
+        g_value_get_boolean (gst_structure_id_get_value (message->structure,
+            GST_QUARK (BUSY)));
+}
+
+/**
  * gst_message_parse_error:
  * @message: A valid #GstMessage of type GST_MESSAGE_ERROR.
  * @gerror: Location for the GError
@@ -1124,7 +1466,8 @@
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
 
-  error_gvalue = gst_structure_get_value (message->structure, "gerror");
+  error_gvalue =
+      gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
   g_return_if_fail (error_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
 
@@ -1135,7 +1478,9 @@
     *gerror = NULL;
 
   if (debug)
-    *debug = g_strdup (gst_structure_get_string (message->structure, "debug"));
+    *debug =
+        g_value_dup_string (gst_structure_id_get_value (message->structure,
+            GST_QUARK (DEBUG)));
 }
 
 /**
@@ -1163,7 +1508,8 @@
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);
 
-  error_gvalue = gst_structure_get_value (message->structure, "gerror");
+  error_gvalue =
+      gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
   g_return_if_fail (error_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
 
@@ -1174,7 +1520,9 @@
     *gerror = NULL;
 
   if (debug)
-    *debug = g_strdup (gst_structure_get_string (message->structure, "debug"));
+    *debug =
+        g_value_dup_string (gst_structure_id_get_value (message->structure,
+            GST_QUARK (DEBUG)));
 }
 
 /**
@@ -1203,7 +1551,8 @@
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO);
 
-  error_gvalue = gst_structure_get_value (message->structure, "gerror");
+  error_gvalue =
+      gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
   g_return_if_fail (error_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
 
@@ -1214,7 +1563,9 @@
     *gerror = NULL;
 
   if (debug)
-    *debug = g_strdup (gst_structure_get_string (message->structure, "debug"));
+    *debug =
+        g_value_dup_string (gst_structure_id_get_value (message->structure,
+            GST_QUARK (DEBUG)));
 }
 
 /**
@@ -1235,17 +1586,17 @@
 gst_message_parse_segment_start (GstMessage * message, GstFormat * format,
     gint64 * position)
 {
-  const GstStructure *structure;
-
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_START);
 
-  structure = gst_message_get_structure (message);
   if (format)
-    *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+    *format =
+        g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (FORMAT)));
   if (position)
     *position =
-        g_value_get_int64 (gst_structure_get_value (structure, "position"));
+        g_value_get_int64 (gst_structure_id_get_value (message->structure,
+            GST_QUARK (POSITION)));
 }
 
 /**
@@ -1266,17 +1617,17 @@
 gst_message_parse_segment_done (GstMessage * message, GstFormat * format,
     gint64 * position)
 {
-  const GstStructure *structure;
-
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_DONE);
 
-  structure = gst_message_get_structure (message);
   if (format)
-    *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+    *format =
+        g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (FORMAT)));
   if (position)
     *position =
-        g_value_get_int64 (gst_structure_get_value (structure, "position"));
+        g_value_get_int64 (gst_structure_id_get_value (message->structure,
+            GST_QUARK (POSITION)));
 }
 
 /**
@@ -1300,17 +1651,17 @@
 gst_message_parse_duration (GstMessage * message, GstFormat * format,
     gint64 * duration)
 {
-  const GstStructure *structure;
-
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION);
 
-  structure = gst_message_get_structure (message);
   if (format)
-    *format = g_value_get_enum (gst_structure_get_value (structure, "format"));
+    *format =
+        g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (FORMAT)));
   if (duration)
     *duration =
-        g_value_get_int64 (gst_structure_get_value (structure, "duration"));
+        g_value_get_int64 (gst_structure_id_get_value (message->structure,
+            GST_QUARK (DURATION)));
 }
 
 /**
@@ -1331,14 +1682,337 @@
 void
 gst_message_parse_async_start (GstMessage * message, gboolean * new_base_time)
 {
-  const GstStructure *structure;
-
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ASYNC_START);
 
-  structure = gst_message_get_structure (message);
   if (new_base_time)
     *new_base_time =
-        g_value_get_boolean (gst_structure_get_value (structure,
-            "new-base-time"));
+        g_value_get_boolean (gst_structure_id_get_value (message->structure,
+            GST_QUARK (NEW_BASE_TIME)));
+}
+
+/**
+ * gst_message_parse_request_state:
+ * @message: A valid #GstMessage of type GST_MESSAGE_REQUEST_STATE.
+ * @state: Result location for the requested state or NULL
+ *
+ * Extract the requested state from the request_state message.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.23
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_parse_request_state (GstMessage * message, GstState * state)
+{
+  g_return_if_fail (GST_IS_MESSAGE (message));
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REQUEST_STATE);
+
+  if (state)
+    *state = g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (NEW_STATE)));
+}
+
+/**
+ * gst_message_new_stream_status:
+ * @src: The object originating the message.
+ * @type: The stream status type.
+ * @owner: The owner element of @src.
+ *
+ * Create a new stream status message. This message is posted when a streaming
+ * thread is created/destroyed or when the state changed.
+ * 
+ * Returns: The new stream status message.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.24.
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+GstMessage *
+gst_message_new_stream_status (GstObject * src, GstStreamStatusType type,
+    GstElement * owner)
+{
+  GstMessage *message;
+  GstStructure *structure;
+
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_STREAM_STATUS),
+      GST_QUARK (TYPE), GST_TYPE_STREAM_STATUS_TYPE, (gint) type,
+      GST_QUARK (OWNER), GST_TYPE_ELEMENT, owner, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_STREAM_STATUS, src, structure);
+
+  return message;
+}
+
+/**
+ * gst_message_parse_stream_status:
+ * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
+ * @type: A pointer to hold the status type
+ * @owner: The owner element of the message source
+ *
+ * Extracts the stream status type and owner the GstMessage. The returned
+ * owner remains valid for as long as the reference to @message is valid and
+ * should thus not be unreffed.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.24.
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_parse_stream_status (GstMessage * message,
+    GstStreamStatusType * type, GstElement ** owner)
+{
+  const GValue *owner_gvalue;
+
+  g_return_if_fail (GST_IS_MESSAGE (message));
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
+
+  owner_gvalue =
+      gst_structure_id_get_value (message->structure, GST_QUARK (OWNER));
+  g_return_if_fail (owner_gvalue != NULL);
+
+  if (type)
+    *type = g_value_get_enum (gst_structure_id_get_value (message->structure,
+            GST_QUARK (TYPE)));
+  if (owner)
+    *owner = (GstElement *) g_value_get_object (owner_gvalue);
+}
+
+/**
+ * gst_message_set_stream_status_object:
+ * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
+ * @object: the object controlling the streaming
+ *
+ * Configures the object handling the streaming thread. This is usually a
+ * GstTask object but other objects might be added in the future.
+ *
+ * Since: 0.10.24
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_set_stream_status_object (GstMessage * message,
+    const GValue * object)
+{
+  g_return_if_fail (GST_IS_MESSAGE (message));
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
+
+  gst_structure_id_set_value (message->structure, GST_QUARK (OBJECT), object);
+}
+
+/**
+ * gst_message_get_stream_status_object:
+ * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_STATUS.
+ *
+ * Extracts the object managing the streaming thread from @message.
+ *
+ * Returns: a GValue containing the object that manages the streaming thread.
+ * This object is usually of type GstTask but other types can be added in the
+ * future. The object remains valid as long as @message is valid.
+ *
+ * Since: 0.10.24
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+const GValue *
+gst_message_get_stream_status_object (GstMessage * message)
+{
+  const GValue *result;
+
+  g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
+  g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS,
+      NULL);
+
+  result = gst_structure_id_get_value (message->structure, GST_QUARK (OBJECT));
+
+  return result;
 }
+
+/**
+ * gst_message_new_step_done:
+ * @src: The object originating the message.
+ * @format: the format of @amount
+ * @amount: the amount of stepped data
+ * @rate: the rate of the stepped amount
+ * @flush: is this an flushing step
+ * @intermediate: is this an intermediate step
+ * @duration: the duration of the data
+ * @eos: the step caused EOS
+ *
+ * This message is posted by elements when they complete a part, when @intermediate set
+ * to TRUE, or a complete step operation.
+ *
+ * @duration will contain the amount of time (in GST_FORMAT_TIME) of the stepped
+ * @amount of media in format @format.
+ *
+ * Returns: The new step_done message. 
+ *
+ * MT safe.
+ *
+ * Since: 0.10.24
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+GstMessage *
+gst_message_new_step_done (GstObject * src, GstFormat format, guint64 amount,
+    gdouble rate, gboolean flush, gboolean intermediate, guint64 duration,
+    gboolean eos)
+{
+  GstMessage *message;
+  GstStructure *structure;
+
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_STEP_DONE),
+      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
+      GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
+      GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
+      GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
+      GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate,
+      GST_QUARK (DURATION), G_TYPE_UINT64, duration,
+      GST_QUARK (EOS), G_TYPE_BOOLEAN, eos, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_STEP_DONE, src, structure);
+
+  return message;
+}
+
+/**
+ * gst_message_parse_step_done:
+ * @message: A valid #GstMessage of type GST_MESSAGE_STEP_DONE.
+ * @format: result location for the format
+ * @amount: result location for the amount
+ * @rate: result location for the rate
+ * @flush: result location for the flush flag
+ * @intermediate: result location for the intermediate flag
+ * @duration: result location for the duration
+ * @eos: result location for the EOS flag
+ *
+ * Extract the values the step_done message.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.24
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_parse_step_done (GstMessage * message, GstFormat * format,
+    guint64 * amount, gdouble * rate, gboolean * flush, gboolean * intermediate,
+    guint64 * duration, gboolean * eos)
+{
+  g_return_if_fail (GST_IS_MESSAGE (message));
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_DONE);
+
+  gst_structure_id_get (message->structure,
+      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
+      GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
+      GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
+      GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
+      GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate,
+      GST_QUARK (DURATION), G_TYPE_UINT64, duration,
+      GST_QUARK (EOS), G_TYPE_BOOLEAN, eos, NULL);
+}
+
+/**
+ * gst_message_new_step_start:
+ * @src: The object originating the message.
+ * @active: if the step is active or queued
+ * @format: the format of @amount
+ * @amount: the amount of stepped data
+ * @rate: the rate of the stepped amount
+ * @flush: is this an flushing step
+ * @intermediate: is this an intermediate step
+ *
+ * This message is posted by elements when they accept or activate a new step
+ * event for @amount in @format. 
+ *
+ * @active is set to FALSE when the element accepted the new step event and has
+ * queued it for execution in the streaming threads.
+ *
+ * @active is set to TRUE when the element has activated the step operation and
+ * is now ready to start executing the step in the streaming thread. After this
+ * message is emited, the application can queue a new step operation in the
+ * element.
+ *
+ * Returns: The new step_start message. 
+ *
+ * MT safe.
+ *
+ * Since: 0.10.24
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+GstMessage *
+gst_message_new_step_start (GstObject * src, gboolean active, GstFormat format,
+    guint64 amount, gdouble rate, gboolean flush, gboolean intermediate)
+{
+  GstMessage *message;
+  GstStructure *structure;
+
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_STEP_START),
+      GST_QUARK (ACTIVE), G_TYPE_BOOLEAN, active,
+      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
+      GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
+      GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
+      GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
+      GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_STEP_START, src, structure);
+
+  return message;
+}
+
+/**
+ * gst_message_parse_step_start:
+ * @message: A valid #GstMessage of type GST_MESSAGE_STEP_DONE.
+ * @active: result location for the active flag
+ * @format: result location for the format
+ * @amount: result location for the amount
+ * @rate: result location for the rate
+ * @flush: result location for the flush flag
+ * @intermediate: result location for the intermediate flag
+ *
+ * Extract the values from step_start message.
+ *
+ * MT safe.
+ *
+ * Since: 0.10.24
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_message_parse_step_start (GstMessage * message, gboolean * active,
+    GstFormat * format, guint64 * amount, gdouble * rate, gboolean * flush,
+    gboolean * intermediate)
+{
+  g_return_if_fail (GST_IS_MESSAGE (message));
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_START);
+
+  gst_structure_id_get (message->structure,
+      GST_QUARK (ACTIVE), G_TYPE_BOOLEAN, active,
+      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
+      GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
+      GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
+      GST_QUARK (FLUSH), G_TYPE_BOOLEAN, flush,
+      GST_QUARK (INTERMEDIATE), G_TYPE_BOOLEAN, intermediate, NULL);
+}