+
+/**
+ * gst_message_new_toc:
+ * @src: the object originating the message.
+ * @toc: (transfer none): #GstToc structure for the message.
+ * @updated: whether TOC was updated or not.
+ *
+ * Create a new TOC message. The message is posted by elements
+ * that discovered or updated a TOC.
+ *
+ * Returns: (transfer full): a new TOC message.
+ *
+ * MT safe.
+ */
+GstMessage *
+gst_message_new_toc (GstObject * src, GstToc * toc, gboolean updated)
+{
+ GstStructure *toc_struct;
+
+ g_return_val_if_fail (toc != NULL, NULL);
+
+ toc_struct = gst_structure_new_id (GST_QUARK (MESSAGE_TOC),
+ GST_QUARK (TOC), GST_TYPE_TOC, toc,
+ GST_QUARK (UPDATED), G_TYPE_BOOLEAN, updated, NULL);
+
+ return gst_message_new_custom (GST_MESSAGE_TOC, src, toc_struct);
+}
+
+/**
+ * gst_message_parse_toc:
+ * @message: a valid #GstMessage of type GST_MESSAGE_TOC.
+ * @toc: (out) (transfer full): return location for the TOC.
+ * @updated: (out): return location for the updated flag.
+ *
+ * Extract thef TOC from the #GstMessage. The TOC returned in the
+ * output argument is a copy; the caller must free it with
+ * gst_toc_unref() when done.
+ *
+ * MT safe.
+ */
+void
+gst_message_parse_toc (GstMessage * message, GstToc ** toc, gboolean * updated)
+{
+ g_return_if_fail (GST_IS_MESSAGE (message));
+ g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TOC);
+ g_return_if_fail (toc != NULL);
+
+ gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
+ GST_QUARK (TOC), GST_TYPE_TOC, toc,
+ GST_QUARK (UPDATED), G_TYPE_BOOLEAN, updated, NULL);
+}
+
+/**
+ * gst_message_new_reset_time:
+ * @src: (transfer none): The object originating the message.
+ * @running_time: the requested running-time
+ *
+ * This message is posted when the pipeline running-time should be reset to
+ * @running_time, like after a flushing seek.
+ *
+ * Returns: (transfer full): The new reset_time message.
+ *
+ * MT safe.
+ */
+GstMessage *
+gst_message_new_reset_time (GstObject * src, GstClockTime running_time)
+{
+ GstMessage *message;
+ GstStructure *structure;
+
+ structure = gst_structure_new_id (GST_QUARK (MESSAGE_RESET_TIME),
+ GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time, NULL);
+ message = gst_message_new_custom (GST_MESSAGE_RESET_TIME, src, structure);
+
+ return message;
+}
+
+/**
+ * gst_message_parse_reset_time:
+ * @message: A valid #GstMessage of type GST_MESSAGE_RESET_TIME.
+ * @running_time: (out) (allow-none): Result location for the running_time or
+ * NULL
+ *
+ * Extract the running-time from the RESET_TIME message.
+ *
+ * MT safe.
+ */
+void
+gst_message_parse_reset_time (GstMessage * message, GstClockTime * running_time)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_IS_MESSAGE (message));
+ g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_RESET_TIME);
+
+ structure = GST_MESSAGE_STRUCTURE (message);
+ if (running_time)
+ *running_time =
+ g_value_get_uint64 (gst_structure_id_get_value (structure,
+ GST_QUARK (RUNNING_TIME)));
+}
+
+/**
+ * gst_message_new_stream_start:
+ * @src: (transfer none): The object originating the message.
+ *
+ * Create a new stream_start message. This message is generated and posted in
+ * the sink elements of a GstBin. The bin will only forward the STREAM_START
+ * message to the application if all sinks have posted an STREAM_START message.
+ *
+ * Returns: (transfer full): The new stream_start message.
+ *
+ * MT safe.
+ */
+GstMessage *
+gst_message_new_stream_start (GstObject * src)
+{
+ GstMessage *message;
+ GstStructure *s;
+
+ s = gst_structure_new_id_empty (GST_QUARK (MESSAGE_STREAM_START));
+ message = gst_message_new_custom (GST_MESSAGE_STREAM_START, src, s);
+
+ return message;
+}
+
+
+/**
+ * gst_message_set_group_id:
+ * @message: the message
+ * @group_id: the group id
+ *
+ * Sets the group id on the stream-start message.
+ *
+ * All streams that have the same group id are supposed to be played
+ * together, i.e. all streams inside a container file should have the
+ * same group id but different stream ids. The group id should change
+ * each time the stream is started, resulting in different group ids
+ * each time a file is played for example.
+ *
+ * MT safe.
+ *
+ * Since: 1.2
+ */
+void
+gst_message_set_group_id (GstMessage * message, guint group_id)
+{
+ GstStructure *structure;
+
+ g_return_if_fail (GST_IS_MESSAGE (message));
+ g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_START);
+ g_return_if_fail (gst_message_is_writable (message));
+
+ structure = GST_MESSAGE_STRUCTURE (message);
+ gst_structure_id_set (structure, GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id,
+ NULL);
+}
+
+/**
+ * gst_message_parse_group_id:
+ * @message: A valid #GstMessage of type GST_MESSAGE_STREAM_START.
+ * @group_id: (out) (allow-none): Result location for the group id or
+ * NULL
+ *
+ * Extract the group from the STREAM_START message.
+ *
+ * Returns: %TRUE if the message had a group id set, %FALSE otherwise
+ *
+ * MT safe.
+ *
+ * Since: 1.2
+ */
+gboolean
+gst_message_parse_group_id (GstMessage * message, guint * group_id)
+{
+ GstStructure *structure;
+ const GValue *v;
+
+ g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
+ g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_START,
+ FALSE);
+
+ if (!group_id)
+ return TRUE;
+
+ structure = GST_MESSAGE_STRUCTURE (message);
+
+ v = gst_structure_id_get_value (structure, GST_QUARK (GROUP_ID));
+ if (!v)
+ return FALSE;
+
+ *group_id = g_value_get_uint (v);
+ return TRUE;
+}
+
+/**
+ * gst_message_new_need_context:
+ * @src: (transfer none): The object originating the message.
+ *
+ * This message is posted when an element needs a specific #GstContext.
+ *
+ * Returns: (transfer full): The new need-context message.
+ *
+ * MT safe.
+ *
+ * Since: 1.2
+ */
+GstMessage *
+gst_message_new_need_context (GstObject * src)
+{
+ GstMessage *message;
+ GstStructure *structure;
+
+ structure = gst_structure_new_id_empty (GST_QUARK (MESSAGE_NEED_CONTEXT));
+ message = gst_message_new_custom (GST_MESSAGE_NEED_CONTEXT, src, structure);
+
+ return message;
+}
+
+static GArray *
+ensure_array (GstStructure * s, GQuark quark, gsize element_size,
+ GDestroyNotify clear_func)
+{
+ GArray *array;
+ const GValue *value;
+
+ value = gst_structure_id_get_value (s, quark);
+ if (value) {
+ array = (GArray *) g_value_get_boxed (value);
+ } else {
+ GValue new_array_val = { 0, };
+
+ array = g_array_new (FALSE, TRUE, element_size);
+ if (clear_func)
+ g_array_set_clear_func (array, clear_func);
+
+ g_value_init (&new_array_val, G_TYPE_ARRAY);
+ g_value_take_boxed (&new_array_val, array);
+
+ gst_structure_id_take_value (s, quark, &new_array_val);
+ }
+ return array;
+}
+
+static void
+free_array_string (gpointer ptr)
+{
+ gchar *str = *(gchar **) ptr;
+ g_free (str);
+}
+
+/**
+ * gst_message_add_context_type:
+ * @message: a GST_MESSAGE_NEED_CONTEXT type message
+ * @context_type: a context type
+ *
+ * Add a new context type to @message.
+ *
+ * Since: 1.2
+ */
+void
+gst_message_add_context_type (GstMessage * message, const gchar * context_type)
+{
+ GstStructure *structure;
+ GArray *array;
+ gchar *copy;
+
+ g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEED_CONTEXT);
+ g_return_if_fail (gst_message_is_writable (message));
+
+ structure = GST_MESSAGE_STRUCTURE (message);
+ array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES),
+ sizeof (gchar *), free_array_string);
+
+ copy = g_strdup (context_type);
+ g_array_append_val (array, copy);
+}
+
+/**
+ * gst_message_get_n_context_types:
+ * @message: a GST_MESSAGE_NEED_CONTEXT type message
+ *
+ * Retrieve the number of values currently stored in the
+ * context-types array of the message's structure.
+ *
+ * Returns: the context-types array size as a #guint.
+ *
+ * Since: 1.2
+ */
+guint
+gst_message_get_n_context_types (GstMessage * message)
+{
+ GstStructure *structure;
+ GArray *array;
+
+ g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEED_CONTEXT,
+ 0);
+
+ structure = GST_MESSAGE_STRUCTURE (message);
+ array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES),
+ sizeof (gchar *), free_array_string);
+
+ return array->len;
+}
+
+/**
+ * gst_message_parse_nth_context_type:
+ * @message: a GST_MESSAGE_NEED_CONTEXT type message
+ * @context_type: (out) (allow-none): the context type, or NULL
+ *
+ * Parse a context type from an existing GST_MESSAGE_NEED_CONTEXT message
+ * from @index.
+ *
+ * Returns: a #gboolean indicating if the parsing succeeded.
+ *
+ * Since: 1.2
+ */
+gboolean
+gst_message_parse_nth_context_type (GstMessage * message, guint index,
+ const gchar ** context_type)
+{
+ GstStructure *structure;
+ GArray *array;
+
+ g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEED_CONTEXT,
+ FALSE);
+
+ structure = GST_MESSAGE_STRUCTURE (message);
+
+ array = ensure_array (structure, GST_QUARK (CONTEXT_TYPES),
+ sizeof (gchar *), free_array_string);
+ g_return_val_if_fail (index < array->len, FALSE);
+
+ if (context_type)
+ *context_type = g_array_index (array, gchar *, index);
+
+ return TRUE;
+}
+
+/**
+ * gst_message_new_have_context:
+ * @src: (transfer none): The object originating the message.
+ * @context: (transfer full): the context
+ *
+ * This message is posted when an element has a new local #GstContext.
+ *
+ * Returns: (transfer full): The new have-context message.
+ *
+ * MT safe.
+ *
+ * Since: 1.2
+ */
+GstMessage *
+gst_message_new_have_context (GstObject * src, GstContext * context)
+{
+ GstMessage *message;
+ GstStructure *structure;
+
+ structure = gst_structure_new_id (GST_QUARK (MESSAGE_HAVE_CONTEXT),
+ GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
+ message = gst_message_new_custom (GST_MESSAGE_HAVE_CONTEXT, src, structure);
+ gst_context_unref (context);
+
+ return message;
+}
+
+/**
+ * gst_message_parse_have_context:
+ * @message: A valid #GstMessage of type GST_MESSAGE_HAVE_CONTEXT.
+ * @context: (out) (transfer full) (allow-none): Result location for the
+ * context or NULL
+ *
+ * Extract the context from the HAVE_CONTEXT message.
+ *
+ * MT safe.
+ *
+ * Since: 1.2
+ */
+void
+gst_message_parse_have_context (GstMessage * message, GstContext ** context)
+{
+ g_return_if_fail (GST_IS_MESSAGE (message));
+ g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_HAVE_CONTEXT);
+
+ if (context)
+ gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
+ GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
+}