/* GStreamer
 * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
 *
 * gstmessage.c: GstMessage subsystem
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstmessage
 * @title: GstMessage
 * @short_description: Lightweight objects to signal the application of
 *                     pipeline events
 * @see_also: #GstBus, #GstMiniObject, #GstElement
 *
 * Messages are implemented as a subclass of #GstMiniObject with a generic
 * #GstStructure as the content. This allows for writing custom messages without
 * requiring an API change while allowing a wide range of different types
 * of messages.
 *
 * Messages are posted by objects in the pipeline and are passed to the
 * application using the #GstBus.
 *
 * The basic use pattern of posting a message on a #GstBus is as follows:
 * |[<!-- language="C" -->
 *   gst_bus_post (bus, gst_message_new_eos());
 * ]|
 *
 * A #GstElement usually posts messages on the bus provided by the parent
 * container using gst_element_post_message().
 */


#include "gst_private.h"
#include <string.h>             /* memcpy */
#include "gsterror.h"
#include "gstenumtypes.h"
#include "gstinfo.h"
#include "gstmessage.h"
#include "gsttaglist.h"
#include "gstutils.h"
#include "gstquark.h"
#include "gstvalue.h"


typedef struct
{
  GstMessage message;

  GstStructure *structure;
} GstMessageImpl;

#define GST_MESSAGE_STRUCTURE(m)  (((GstMessageImpl *)(m))->structure)

typedef struct
{
  const gint type;
  const gchar *name;
  GQuark quark;
} GstMessageQuarks;

static GstMessageQuarks message_quarks[] = {
  {GST_MESSAGE_UNKNOWN, "unknown", 0},
  {GST_MESSAGE_EOS, "eos", 0},
  {GST_MESSAGE_ERROR, "error", 0},
  {GST_MESSAGE_WARNING, "warning", 0},
  {GST_MESSAGE_INFO, "info", 0},
  {GST_MESSAGE_TAG, "tag", 0},
  {GST_MESSAGE_BUFFERING, "buffering", 0},
  {GST_MESSAGE_STATE_CHANGED, "state-changed", 0},
  {GST_MESSAGE_STATE_DIRTY, "state-dirty", 0},
  {GST_MESSAGE_STEP_DONE, "step-done", 0},
  {GST_MESSAGE_CLOCK_PROVIDE, "clock-provide", 0},
  {GST_MESSAGE_CLOCK_LOST, "clock-lost", 0},
  {GST_MESSAGE_NEW_CLOCK, "new-clock", 0},
  {GST_MESSAGE_STRUCTURE_CHANGE, "structure-change", 0},
  {GST_MESSAGE_STREAM_STATUS, "stream-status", 0},
  {GST_MESSAGE_APPLICATION, "application", 0},
  {GST_MESSAGE_ELEMENT, "element", 0},
  {GST_MESSAGE_SEGMENT_START, "segment-start", 0},
  {GST_MESSAGE_SEGMENT_DONE, "segment-done", 0},
  {GST_MESSAGE_DURATION_CHANGED, "duration-changed", 0},
  {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},
  {GST_MESSAGE_QOS, "qos", 0},
  {GST_MESSAGE_PROGRESS, "progress", 0},
  {GST_MESSAGE_TOC, "toc", 0},
  {GST_MESSAGE_RESET_TIME, "reset-time", 0},
  {GST_MESSAGE_STREAM_START, "stream-start", 0},
  {GST_MESSAGE_NEED_CONTEXT, "need-context", 0},
  {GST_MESSAGE_HAVE_CONTEXT, "have-context", 0},
  {GST_MESSAGE_DEVICE_ADDED, "device-added", 0},
  {GST_MESSAGE_DEVICE_REMOVED, "device-removed", 0},
  {GST_MESSAGE_PROPERTY_NOTIFY, "property-notify", 0},
  {GST_MESSAGE_STREAM_COLLECTION, "stream-collection", 0},
  {GST_MESSAGE_STREAMS_SELECTED, "streams-selected", 0},
  {GST_MESSAGE_REDIRECT, "redirect", 0},
  {0, NULL, 0}
};

static GQuark details_quark = 0;

GType _gst_message_type = 0;
GST_DEFINE_MINI_OBJECT_TYPE (GstMessage, gst_message);

void
_priv_gst_message_initialize (void)
{
  gint i;

  GST_CAT_INFO (GST_CAT_GST_INIT, "init messages");

  for (i = 0; message_quarks[i].name; i++) {
    message_quarks[i].quark =
        g_quark_from_static_string (message_quarks[i].name);
  }
  details_quark = g_quark_from_static_string ("details");

  _gst_message_type = gst_message_get_type ();
}

/**
 * gst_message_type_get_name:
 * @type: the message type
 *
 * Get a printable name for the given message type. Do not modify or free.
 *
 * Returns: a reference to the static name of the message.
 */
const gchar *
gst_message_type_get_name (GstMessageType type)
{
  gint i;

  for (i = 0; message_quarks[i].name; i++) {
    if (type == message_quarks[i].type)
      return message_quarks[i].name;
  }
  return "unknown";
}

/**
 * gst_message_type_to_quark:
 * @type: the message type
 *
 * Get the unique quark for the given message type.
 *
 * Returns: the quark associated with the message type
 */
GQuark
gst_message_type_to_quark (GstMessageType type)
{
  gint i;

  for (i = 0; message_quarks[i].name; i++) {
    if (type == message_quarks[i].type)
      return message_quarks[i].quark;
  }
  return 0;
}

static gboolean
_gst_message_dispose (GstMessage * message)
{
  gboolean do_free = TRUE;

  if (GST_MINI_OBJECT_FLAG_IS_SET (message, GST_MESSAGE_FLAG_ASYNC_DELIVERY)) {
    /* revive message, so bus can finish with it and clean it up */
    gst_message_ref (message);

    GST_INFO ("[msg %p] signalling async free", message);

    GST_MESSAGE_LOCK (message);
    GST_MESSAGE_SIGNAL (message);
    GST_MESSAGE_UNLOCK (message);

    /* don't free it yet, let bus finish with it first */
    do_free = FALSE;
  }

  return do_free;
}

static void
_gst_message_free (GstMessage * message)
{
  GstStructure *structure;

  g_return_if_fail (message != NULL);

  GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p, %s from %s", message,
      GST_MESSAGE_TYPE_NAME (message), GST_MESSAGE_SRC_NAME (message));

  if (GST_MESSAGE_SRC (message)) {
    gst_object_unref (GST_MESSAGE_SRC (message));
    GST_MESSAGE_SRC (message) = NULL;
  }

  structure = GST_MESSAGE_STRUCTURE (message);
  if (structure) {
    gst_structure_set_parent_refcount (structure, NULL);
    gst_structure_free (structure);
  }

  g_slice_free1 (sizeof (GstMessageImpl), message);
}

static void
gst_message_init (GstMessageImpl * message, GstMessageType type,
    GstObject * src);

static GstMessage *
_gst_message_copy (GstMessage * message)
{
  GstMessageImpl *copy;
  GstStructure *structure;

  GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p, %s from %s", message,
      GST_MESSAGE_TYPE_NAME (message),
      GST_OBJECT_NAME (GST_MESSAGE_SRC (message)));

  copy = g_slice_new0 (GstMessageImpl);

  gst_message_init (copy, GST_MESSAGE_TYPE (message),
      GST_MESSAGE_SRC (message));

  GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
  GST_MESSAGE_SEQNUM (copy) = GST_MESSAGE_SEQNUM (message);

  structure = GST_MESSAGE_STRUCTURE (message);
  if (structure) {
    GST_MESSAGE_STRUCTURE (copy) = gst_structure_copy (structure);
    gst_structure_set_parent_refcount (GST_MESSAGE_STRUCTURE (copy),
        &copy->message.mini_object.refcount);
  } else {
    GST_MESSAGE_STRUCTURE (copy) = NULL;
  }

  return GST_MESSAGE_CAST (copy);
}

static void
gst_message_init (GstMessageImpl * message, GstMessageType type,
    GstObject * src)
{
  gst_mini_object_init (GST_MINI_OBJECT_CAST (message), 0, _gst_message_type,
      (GstMiniObjectCopyFunction) _gst_message_copy,
      (GstMiniObjectDisposeFunction) _gst_message_dispose,
      (GstMiniObjectFreeFunction) _gst_message_free);

  GST_MESSAGE_TYPE (message) = type;
  if (src)
    gst_object_ref (src);
  GST_MESSAGE_SRC (message) = src;
  GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
  GST_MESSAGE_SEQNUM (message) = gst_util_seqnum_next ();
}


/**
 * gst_message_new_custom:
 * @type: The #GstMessageType to distinguish messages
 * @src: (transfer none) (allow-none): The object originating the message.
 * @structure: (transfer full) (allow-none): the structure for the
 *     message. The message will take ownership of the structure.
 *
 * Create a new custom-typed message. This can be used for anything not
 * handled by other message-specific functions to pass a message to the
 * app. The structure field can be %NULL.
 *
 * Returns: (transfer full): The new message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_custom (GstMessageType type, GstObject * src,
    GstStructure * structure)
{
  GstMessageImpl *message;

  message = g_slice_new0 (GstMessageImpl);

  GST_CAT_LOG (GST_CAT_MESSAGE, "source %s: creating new message %p %s",
      (src ? GST_OBJECT_NAME (src) : "NULL"), message,
      gst_message_type_get_name (type));

  if (structure) {
    /* structure must not have a parent */
    if (!gst_structure_set_parent_refcount (structure,
            &message->message.mini_object.refcount))
      goto had_parent;
  }
  gst_message_init (message, type, src);

  GST_MESSAGE_STRUCTURE (message) = structure;

  return GST_MESSAGE_CAST (message);

  /* ERRORS */
had_parent:
  {
    g_slice_free1 (sizeof (GstMessageImpl), message);
    g_warning ("structure is already owned by another object");
    return NULL;
  }
}

/**
 * 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 have the same sequence number unless
 * that correspondence was made explicitly.
 *
 * Returns: The message's sequence number.
 *
 * MT safe.
 */
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.
 */
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: (transfer none) (allow-none): The object originating the message.
 *
 * Create a new eos message. This message is generated and posted in
 * the sink elements of a GstBin. The bin will only forward the EOS
 * message to the application if all sinks have posted an EOS message.
 *
 * Returns: (transfer full): The new eos message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_eos (GstObject * src)
{
  GstMessage *message;

  message = gst_message_new_custom (GST_MESSAGE_EOS, src, NULL);

  return message;
}

/**
 * gst_message_new_error_with_details:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @debug: A debugging string.
 * @details: (transfer full): (allow-none): A GstStructure with details
 *
 * Create a new error message. The message will copy @error and
 * @debug. This message is posted by element when a fatal event
 * occurred. The pipeline will probably (partially) stop. The application
 * receiving this message should stop the pipeline.
 *
 * Returns: (transfer full): the new error message.
 *
 * Since: 1.10
 */
GstMessage *
gst_message_new_error_with_details (GstObject * src, GError * error,
    const gchar * debug, GstStructure * details)
{
  GstMessage *message;
  GstStructure *structure;

  if (debug && !g_utf8_validate (debug, -1, NULL)) {
    debug = NULL;
    g_warning ("Trying to set debug field of error message, but "
        "string is not valid UTF-8. Please file a bug.");
  }

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_ERROR),
      GST_QUARK (GERROR), G_TYPE_ERROR, error,
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
  message = gst_message_new_custom (GST_MESSAGE_ERROR, src, structure);
  if (details) {
    GValue v = G_VALUE_INIT;

    g_value_init (&v, GST_TYPE_STRUCTURE);
    g_value_take_boxed (&v, details);
    gst_structure_id_take_value (GST_MESSAGE_STRUCTURE (message), details_quark,
        &v);
  }

  return message;
}

/**
 * gst_message_new_error:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @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
 * occurred. The pipeline will probably (partially) stop. The application
 * receiving this message should stop the pipeline.
 *
 * Returns: (transfer full): the new error message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_error (GstObject * src, GError * error, const gchar * debug)
{
  return gst_message_new_error_with_details (src, error, debug, NULL);
}

/**
 * gst_message_parse_error_details:
 * @message: The message object
 * @structure: (out): A pointer to the returned details
 *
 * Returns the optional details structure, may be NULL if none.
 * The returned structure must not be freed.
 *
 * Since: 1.10
 */
void
gst_message_parse_error_details (GstMessage * message,
    const GstStructure ** structure)
{
  const GValue *v;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
  g_return_if_fail (structure != NULL);

  *structure = NULL;
  v = gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (message),
      details_quark);
  if (v) {
    *structure = g_value_get_boxed (v);
  }
}

/**
 * gst_message_new_warning_with_details:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @debug: A debugging string.
 * @details: (transfer full): (allow-none): A GstStructure with details
 *
 * Create a new warning message. The message will make copies of @error and
 * @debug.
 *
 * Returns: (transfer full): the new warning message.
 *
 * Since: 1.10
 */
GstMessage *
gst_message_new_warning_with_details (GstObject * src, GError * error,
    const gchar * debug, GstStructure * details)
{
  GstMessage *message;
  GstStructure *structure;

  if (debug && !g_utf8_validate (debug, -1, NULL)) {
    debug = NULL;
    g_warning ("Trying to set debug field of warning message, but "
        "string is not valid UTF-8. Please file a bug.");
  }

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_WARNING),
      GST_QUARK (GERROR), G_TYPE_ERROR, error,
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
  message = gst_message_new_custom (GST_MESSAGE_WARNING, src, structure);
  if (details) {
    GValue v = G_VALUE_INIT;

    g_value_init (&v, GST_TYPE_STRUCTURE);
    g_value_take_boxed (&v, details);
    gst_structure_id_take_value (GST_MESSAGE_STRUCTURE (message), details_quark,
        &v);
  }

  return message;
}

/**
 * gst_message_new_warning:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @debug: A debugging string.
 *
 * Create a new warning message. The message will make copies of @error and
 * @debug.
 *
 * Returns: (transfer full): the new warning message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_warning (GstObject * src, GError * error, const gchar * debug)
{
  return gst_message_new_warning_with_details (src, error, debug, NULL);
}

/**
 * gst_message_parse_warning_details:
 * @message: The message object
 * @structure: (out): A pointer to the returned details structure
 *
 * Returns the optional details structure, may be NULL if none
 * The returned structure must not be freed.
 *
 * Since: 1.10
 */
void
gst_message_parse_warning_details (GstMessage * message,
    const GstStructure ** structure)
{
  const GValue *v;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);
  g_return_if_fail (structure != NULL);

  *structure = NULL;
  v = gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (message),
      details_quark);
  if (v) {
    *structure = g_value_get_boxed (v);
  }
}

/**
 * gst_message_new_info_with_details:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @debug: A debugging string.
 * @details: (transfer full): (allow-none): A GstStructure with details
 *
 * Create a new info message. The message will make copies of @error and
 * @debug.
 *
 * Returns: (transfer full): the new warning message.
 *
 * Since: 1.10
 */
GstMessage *
gst_message_new_info_with_details (GstObject * src, GError * error,
    const gchar * debug, GstStructure * details)
{
  GstMessage *message;
  GstStructure *structure;

  if (debug && !g_utf8_validate (debug, -1, NULL)) {
    debug = NULL;
    g_warning ("Trying to set debug field of info message, but "
        "string is not valid UTF-8. Please file a bug.");
  }

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_INFO),
      GST_QUARK (GERROR), G_TYPE_ERROR, error,
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
  message = gst_message_new_custom (GST_MESSAGE_INFO, src, structure);
  if (details) {
    GValue v = G_VALUE_INIT;

    g_value_init (&v, GST_TYPE_STRUCTURE);
    g_value_take_boxed (&v, details);
    gst_structure_id_take_value (GST_MESSAGE_STRUCTURE (message), details_quark,
        &v);
  }

  return message;
}

/**
 * gst_message_new_info:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @error: (transfer none): The GError for this message.
 * @debug: A debugging string.
 *
 * Create a new info message. The message will make copies of @error and
 * @debug.
 *
 * Returns: (transfer full): the new info message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_info (GstObject * src, GError * error, const gchar * debug)
{
  return gst_message_new_info_with_details (src, error, debug, NULL);
}

/**
 * gst_message_parse_info_details:
 * @message: The message object
 * @structure: (out): A pointer to the returned details structure
 *
 * Returns the optional details structure, may be NULL if none
 * The returned structure must not be freed.
 *
 * Since: 1.10
 */
void
gst_message_parse_info_details (GstMessage * message,
    const GstStructure ** structure)
{
  const GValue *v;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO);
  g_return_if_fail (structure != NULL);

  *structure = NULL;
  v = gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (message),
      details_quark);
  if (v) {
    *structure = g_value_get_boxed (v);
  }
}

/**
 * gst_message_new_tag:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @tag_list: (transfer full): 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.
 *
 * Returns: (transfer full): the new tag message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_tag (GstObject * src, GstTagList * tag_list)
{
  GstStructure *s;
  GstMessage *message;
  GValue val = G_VALUE_INIT;

  g_return_val_if_fail (GST_IS_TAG_LIST (tag_list), NULL);

  s = gst_structure_new_id_empty (GST_QUARK (MESSAGE_TAG));
  g_value_init (&val, GST_TYPE_TAG_LIST);
  g_value_take_boxed (&val, tag_list);
  gst_structure_id_take_value (s, GST_QUARK (TAGLIST), &val);
  message = gst_message_new_custom (GST_MESSAGE_TAG, src, s);
  return message;
}

/**
 * gst_message_new_buffering:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @percent: The buffering percent
 *
 * Create a new buffering message. This message can be posted by an element that
 * needs to buffer data before it can continue processing. @percent should be a
 * value between 0 and 100. A value of 100 means that the buffering completed.
 *
 * When @percent is < 100 the application should PAUSE a PLAYING pipeline. When
 * @percent is 100, the application can set the pipeline (back) to PLAYING.
 * The application must be prepared to receive BUFFERING messages in the
 * PREROLLING state and may only set the pipeline to PLAYING after receiving a
 * message with @percent set to 100, which can happen after the pipeline
 * completed prerolling.
 *
 * MT safe.
 *
 * Returns: (transfer full): The new buffering message.
 */
GstMessage *
gst_message_new_buffering (GstObject * src, gint percent)
{
  GstMessage *message;
  GstStructure *structure;
  gint64 buffering_left;

  g_return_val_if_fail (percent >= 0 && percent <= 100, NULL);

  buffering_left = (percent == 100 ? 0 : -1);

  structure = gst_structure_new_id (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, buffering_left, NULL);
  message = gst_message_new_custom (GST_MESSAGE_BUFFERING, src, structure);

  return message;
}

/**
 * gst_message_new_state_changed:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @oldstate: the previous state
 * @newstate: the new (current) state
 * @pending: the pending (target) state
 *
 * Create a state change message. This message is posted whenever an element
 * changed its state.
 *
 * Returns: (transfer full): the new state change message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_state_changed (GstObject * src,
    GstState oldstate, GstState newstate, GstState pending)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_STATE_CHANGED),
      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;
}

/**
 * gst_message_new_state_dirty:
 * @src: (transfer none) (allow-none): The object originating the message
 *
 * Create a state dirty message. This message is posted whenever an element
 * changed its state asynchronously and is used internally to update the
 * states of container objects.
 *
 * Returns: (transfer full): the new state dirty message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_state_dirty (GstObject * src)
{
  GstMessage *message;

  message = gst_message_new_custom (GST_MESSAGE_STATE_DIRTY, src, NULL);

  return message;
}

/**
 * gst_message_new_clock_provide:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @clock: (transfer none): the clock it provides
 * @ready: %TRUE if the sender can provide a clock
 *
 * Create a clock provide message. This message is posted whenever an
 * element is ready to provide a clock or lost its ability to provide
 * a clock (maybe because it paused or became EOS).
 *
 * This message is mainly used internally to manage the clock
 * selection.
 *
 * Returns: (transfer full): the new provide clock message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_clock_provide (GstObject * src, GstClock * clock,
    gboolean ready)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (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;
}

/**
 * gst_message_new_clock_lost:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @clock: (transfer none): the clock that was lost
 *
 * Create a clock lost message. This message is posted whenever the
 * clock is not valid anymore.
 *
 * If this message is posted by the pipeline, the pipeline will
 * select a new clock again when it goes to PLAYING. It might therefore
 * be needed to set the pipeline to PAUSED and PLAYING again.
 *
 * Returns: (transfer full): The new clock lost message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_clock_lost (GstObject * src, GstClock * clock)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (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;
}

/**
 * gst_message_new_new_clock:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @clock: (transfer none): the new selected clock
 *
 * Create a new clock message. This message is posted whenever the
 * pipeline selects a new clock for the pipeline.
 *
 * Returns: (transfer full): The new new clock message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_new_clock (GstObject * src, GstClock * clock)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (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: (transfer none) (allow-none): The object originating the message.
 * @type: The change type.
 * @owner: (transfer none): 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 sinkpad that unlinked or linked.
 *
 * Returns: (transfer full): the new structure change message.
 *
 * MT safe.
 */
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_SINK, NULL); */
  g_return_val_if_fail (GST_IS_ELEMENT (owner), NULL);

  structure = gst_structure_new_id (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;
}

/**
 * gst_message_new_segment_start:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @format: The format of the position being played
 * @position: The position of the segment being played
 *
 * Create a new segment message. This message is posted by elements that
 * start playback of a segment as a result of a segment seek. This message
 * is not received by the application but is used for maintenance reasons in
 * container elements.
 *
 * Returns: (transfer full): the new segment start message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_segment_start (GstObject * src, GstFormat format,
    gint64 position)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (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;
}

/**
 * gst_message_new_segment_done:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @format: The format of the position being done
 * @position: The position of the segment being done
 *
 * Create a new segment done message. This message is posted by elements that
 * finish playback of a segment as a result of a segment seek. This message
 * is received by the application after all elements that posted a segment_start
 * have posted the segment_done.
 *
 * Returns: (transfer full): the new segment done message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_segment_done (GstObject * src, GstFormat format,
    gint64 position)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (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;
}

/**
 * gst_message_new_application:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @structure: (transfer full): the structure for the message. The message
 *     will take ownership of the structure.
 *
 * Create a new application-typed message. GStreamer will never create these
 * messages; they are a gift from us to you. Enjoy.
 *
 * Returns: (transfer full): The new application message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_application (GstObject * src, GstStructure * structure)
{
  g_return_val_if_fail (structure != NULL, NULL);

  return gst_message_new_custom (GST_MESSAGE_APPLICATION, src, structure);
}

/**
 * gst_message_new_element:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @structure: (transfer full): The structure for the
 *     message. The message will take ownership of the structure.
 *
 * Create a new element-specific message. This is meant as a generic way of
 * allowing one-way communication from an element to an application, for example
 * "the firewire cable was unplugged". The format of the message should be
 * documented in the element's documentation. The structure field can be %NULL.
 *
 * Returns: (transfer full): The new element message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_element (GstObject * src, GstStructure * structure)
{
  g_return_val_if_fail (structure != NULL, NULL);

  return gst_message_new_custom (GST_MESSAGE_ELEMENT, src, structure);
}

/**
 * gst_message_new_duration_changed:
 * @src: (transfer none) (allow-none): The object originating the message.
 *
 * Create a new duration changed message. This message is posted by elements
 * that know the duration of a stream when the duration changes. This message
 * is received by bins and is used to calculate the total duration of a
 * pipeline.
 *
 * Returns: (transfer full): The new duration-changed message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_duration_changed (GstObject * src)
{
  GstMessage *message;

  message = gst_message_new_custom (GST_MESSAGE_DURATION_CHANGED, src,
      gst_structure_new_id_empty (GST_QUARK (MESSAGE_DURATION_CHANGED)));

  return message;
}

/**
 * gst_message_new_async_start:
 * @src: (transfer none) (allow-none): The object originating the message.
 *
 * This message is posted by elements when they start an ASYNC state change.
 *
 * Returns: (transfer full): The new async_start message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_async_start (GstObject * src)
{
  GstMessage *message;

  message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src, NULL);

  return message;
}

/**
 * gst_message_new_async_done:
 * @src: (transfer none) (allow-none): The object originating the message.
 * @running_time: the desired running_time
 *
 * The message is posted when elements completed an ASYNC state change.
 * @running_time contains the time of the desired running_time when this
 * elements goes to PLAYING. A value of #GST_CLOCK_TIME_NONE for @running_time
 * means that the element has no clock interaction and thus doesn't care about
 * the running_time of the pipeline.
 *
 * Returns: (transfer full): The new async_done message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_async_done (GstObject * src, GstClockTime running_time)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_ASYNC_DONE),
      GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time, NULL);
  message = gst_message_new_custom (GST_MESSAGE_ASYNC_DONE, src, structure);

  return message;
}

/**
 * gst_message_new_latency:
 * @src: (transfer none) (allow-none): The object originating the message.
 *
 * This message can be posted by elements when their latency requirements have
 * changed.
 *
 * Returns: (transfer full): The new latency message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_latency (GstObject * src)
{
  GstMessage *message;

  message = gst_message_new_custom (GST_MESSAGE_LATENCY, src, NULL);

  return message;
}

/**
 * gst_message_new_request_state:
 * @src: (transfer none) (allow-none): 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: (transfer full): the new request state message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_request_state (GstObject * src, GstState state)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (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.
 *
 * Access the structure of the message.
 *
 * Returns: (transfer none): The structure of the message. The structure is
 * still owned by the message, which means that you should not free it and
 * that the pointer becomes invalid when you free the message.
 *
 * MT safe.
 */
const GstStructure *
gst_message_get_structure (GstMessage * message)
{
  g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);

  return GST_MESSAGE_STRUCTURE (message);
}

/**
 * gst_message_has_name:
 * @message: The #GstMessage.
 * @name: name to check
 *
 * Checks if @message has the given @name. This function is usually used to
 * check the name of a custom message.
 *
 * Returns: %TRUE if @name matches the name of the message structure.
 */
gboolean
gst_message_has_name (GstMessage * message, const gchar * name)
{
  GstStructure *structure;

  g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);

  structure = GST_MESSAGE_STRUCTURE (message);
  if (structure == NULL)
    return FALSE;

  return gst_structure_has_name (structure, name);
}

/**
 * gst_message_parse_tag:
 * @message: A valid #GstMessage of type GST_MESSAGE_TAG.
 * @tag_list: (out callee-allocates): 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.
 *
 * Typical usage of this function might be:
 * |[<!-- language="C" -->
 *   ...
 *   switch (GST_MESSAGE_TYPE (msg)) {
 *     case GST_MESSAGE_TAG: {
 *       GstTagList *tags = NULL;
 *
 *       gst_message_parse_tag (msg, &amp;tags);
 *       g_print ("Got tags from element %s\n", GST_OBJECT_NAME (msg->src));
 *       handle_tags (tags);
 *       gst_tag_list_unref (tags);
 *       break;
 *     }
 *     ...
 *   }
 *   ...
 * ]|
 *
 * MT safe.
 */
void
gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list)
{
  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);

  gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
      GST_QUARK (TAGLIST), GST_TYPE_TAG_LIST, tag_list, NULL);
}

/**
 * gst_message_parse_buffering:
 * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING.
 * @percent: (out) (allow-none): Return location for the percent.
 *
 * Extracts the buffering percent from the GstMessage. see also
 * gst_message_new_buffering().
 *
 * MT safe.
 */
void
gst_message_parse_buffering (GstMessage * message, gint * percent)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);

  if (percent)
    *percent =
        g_value_get_int (gst_structure_id_get_value (GST_MESSAGE_STRUCTURE
            (message), 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.
 */
void
gst_message_set_buffering_stats (GstMessage * message, GstBufferingMode mode,
    gint avg_in, gint avg_out, gint64 buffering_left)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);

  gst_structure_id_set (GST_MESSAGE_STRUCTURE (message),
      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: (out) (allow-none): a buffering mode, or %NULL
 * @avg_in: (out) (allow-none): the average input rate, or %NULL
 * @avg_out: (out) (allow-none): the average output rate, or %NULL
 * @buffering_left: (out) (allow-none): amount of buffering time left in
 *     milliseconds, or %NULL
 *
 * Extracts the buffering stats values from @message.
 */
void
gst_message_parse_buffering_stats (GstMessage * message,
    GstBufferingMode * mode, gint * avg_in, gint * avg_out,
    gint64 * buffering_left)
{
  GstStructure *structure;

  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);

  structure = GST_MESSAGE_STRUCTURE (message);
  if (mode)
    *mode = (GstBufferingMode)
        g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (BUFFERING_MODE)));
  if (avg_in)
    *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
            GST_QUARK (AVG_IN_RATE)));
  if (avg_out)
    *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
            GST_QUARK (AVG_OUT_RATE)));
  if (buffering_left)
    *buffering_left =
        g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (BUFFERING_LEFT)));
}

/**
 * gst_message_parse_state_changed:
 * @message: a valid #GstMessage of type GST_MESSAGE_STATE_CHANGED
 * @oldstate: (out) (allow-none): the previous state, or %NULL
 * @newstate: (out) (allow-none): the new (current) state, or %NULL
 * @pending: (out) (allow-none): the pending (target) state, or %NULL
 *
 * Extracts the old and new states from the GstMessage.
 *
 * Typical usage of this function might be:
 * |[<!-- language="C" -->
 *   ...
 *   switch (GST_MESSAGE_TYPE (msg)) {
 *     case GST_MESSAGE_STATE_CHANGED: {
 *       GstState old_state, new_state;
 *
 *       gst_message_parse_state_changed (msg, &amp;old_state, &amp;new_state, NULL);
 *       g_print ("Element %s changed state from %s to %s.\n",
 *           GST_OBJECT_NAME (msg->src),
 *           gst_element_state_get_name (old_state),
 *           gst_element_state_get_name (new_state));
 *       break;
 *     }
 *     ...
 *   }
 *   ...
 * ]|
 *
 * MT safe.
 */
void
gst_message_parse_state_changed (GstMessage * message,
    GstState * oldstate, GstState * newstate, GstState * pending)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STATE_CHANGED);

  structure = GST_MESSAGE_STRUCTURE (message);
  if (oldstate)
    *oldstate = (GstState)
        g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (OLD_STATE)));
  if (newstate)
    *newstate = (GstState)
        g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (NEW_STATE)));
  if (pending)
    *pending = (GstState)
        g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (PENDING_STATE)));
}

/**
 * gst_message_parse_clock_provide:
 * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_PROVIDE.
 * @clock: (out) (allow-none) (transfer none): a pointer to  hold a clock
 *     object, or %NULL
 * @ready: (out) (allow-none): a pointer to hold the ready flag, or %NULL
 *
 * Extracts the clock and ready flag from the GstMessage.
 * The clock object returned remains valid until the message is freed.
 *
 * MT safe.
 */
void
gst_message_parse_clock_provide (GstMessage * message, GstClock ** clock,
    gboolean * ready)
{
  const GValue *clock_gvalue;
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_PROVIDE);

  structure = GST_MESSAGE_STRUCTURE (message);
  clock_gvalue = gst_structure_id_get_value (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)
    *ready =
        g_value_get_boolean (gst_structure_id_get_value (structure,
            GST_QUARK (READY)));
  if (clock)
    *clock = (GstClock *) g_value_get_object (clock_gvalue);
}

/**
 * gst_message_parse_clock_lost:
 * @message: A valid #GstMessage of type GST_MESSAGE_CLOCK_LOST.
 * @clock: (out) (allow-none) (transfer none): a pointer to hold the lost clock
 *
 * Extracts the lost clock from the GstMessage.
 * The clock object returned remains valid until the message is freed.
 *
 * MT safe.
 */
void
gst_message_parse_clock_lost (GstMessage * message, GstClock ** clock)
{
  const GValue *clock_gvalue;
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_LOST);

  structure = GST_MESSAGE_STRUCTURE (message);
  clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
  g_return_if_fail (clock_gvalue != NULL);
  g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);

  if (clock)
    *clock = (GstClock *) g_value_get_object (clock_gvalue);
}

/**
 * gst_message_parse_new_clock:
 * @message: A valid #GstMessage of type GST_MESSAGE_NEW_CLOCK.
 * @clock: (out) (allow-none) (transfer none): a pointer to hold the selected
 *     new clock
 *
 * Extracts the new clock from the GstMessage.
 * The clock object returned remains valid until the message is freed.
 *
 * MT safe.
 */
void
gst_message_parse_new_clock (GstMessage * message, GstClock ** clock)
{
  const GValue *clock_gvalue;
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEW_CLOCK);

  structure = GST_MESSAGE_STRUCTURE (message);
  clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
  g_return_if_fail (clock_gvalue != NULL);
  g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);

  if (clock)
    *clock = (GstClock *) g_value_get_object (clock_gvalue);
}

/**
 * gst_message_parse_structure_change:
 * @message: A valid #GstMessage of type GST_MESSAGE_STRUCTURE_CHANGE.
 * @type: (out): A pointer to hold the change type
 * @owner: (out) (allow-none) (transfer none): The owner element of the
 *     message source
 * @busy: (out) (allow-none): 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.
 */
void
gst_message_parse_structure_change (GstMessage * message,
    GstStructureChangeType * type, GstElement ** owner, gboolean * busy)
{
  const GValue *owner_gvalue;
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STRUCTURE_CHANGE);

  structure = GST_MESSAGE_STRUCTURE (message);
  owner_gvalue = gst_structure_id_get_value (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 = (GstStructureChangeType)
        g_value_get_enum (gst_structure_id_get_value (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 (structure,
            GST_QUARK (BUSY)));
}

/**
 * gst_message_parse_error:
 * @message: A valid #GstMessage of type GST_MESSAGE_ERROR.
 * @gerror: (out) (allow-none) (transfer full): location for the GError
 * @debug: (out) (allow-none) (transfer full): location for the debug message,
 *     or %NULL
 *
 * Extracts the GError and debug string from the GstMessage. The values returned
 * in the output arguments are copies; the caller must free them when done.
 *
 * Typical usage of this function might be:
 * |[<!-- language="C" -->
 *   ...
 *   switch (GST_MESSAGE_TYPE (msg)) {
 *     case GST_MESSAGE_ERROR: {
 *       GError *err = NULL;
 *       gchar *dbg_info = NULL;
 *
 *       gst_message_parse_error (msg, &amp;err, &amp;dbg_info);
 *       g_printerr ("ERROR from element %s: %s\n",
 *           GST_OBJECT_NAME (msg->src), err->message);
 *       g_printerr ("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
 *       g_error_free (err);
 *       g_free (dbg_info);
 *       break;
 *     }
 *     ...
 *   }
 *   ...
 * ]|
 *
 * MT safe.
 */
void
gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);

  gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
      GST_QUARK (GERROR), G_TYPE_ERROR, gerror,
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
}

/**
 * gst_message_parse_warning:
 * @message: A valid #GstMessage of type GST_MESSAGE_WARNING.
 * @gerror: (out) (allow-none) (transfer full): location for the GError
 * @debug: (out) (allow-none) (transfer full): location for the debug message,
 *     or %NULL
 *
 * Extracts the GError and debug string from the GstMessage. The values returned
 * in the output arguments are copies; the caller must free them when done.
 *
 * MT safe.
 */
void
gst_message_parse_warning (GstMessage * message, GError ** gerror,
    gchar ** debug)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);

  gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
      GST_QUARK (GERROR), G_TYPE_ERROR, gerror,
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
}

/**
 * gst_message_parse_info:
 * @message: A valid #GstMessage of type GST_MESSAGE_INFO.
 * @gerror: (out) (allow-none) (transfer full): location for the GError
 * @debug: (out) (allow-none) (transfer full): location for the debug message,
 *     or %NULL
 *
 * Extracts the GError and debug string from the GstMessage. The values returned
 * in the output arguments are copies; the caller must free them when done.
 *
 * MT safe.
 */
void
gst_message_parse_info (GstMessage * message, GError ** gerror, gchar ** debug)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO);

  gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
      GST_QUARK (GERROR), G_TYPE_ERROR, gerror,
      GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL);
}

/**
 * gst_message_parse_segment_start:
 * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_START.
 * @format: (out) (allow-none): Result location for the format, or %NULL
 * @position: (out) (allow-none): Result location for the position, or %NULL
 *
 * Extracts the position and format from the segment start message.
 *
 * MT safe.
 */
void
gst_message_parse_segment_start (GstMessage * message, GstFormat * format,
    gint64 * position)
{
  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_STRUCTURE (message);
  if (format)
    *format = (GstFormat)
        g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (FORMAT)));
  if (position)
    *position =
        g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (POSITION)));
}

/**
 * gst_message_parse_segment_done:
 * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_DONE.
 * @format: (out) (allow-none): Result location for the format, or %NULL
 * @position: (out) (allow-none): Result location for the position, or %NULL
 *
 * Extracts the position and format from the segment done message.
 *
 * MT safe.
 */
void
gst_message_parse_segment_done (GstMessage * message, GstFormat * format,
    gint64 * position)
{
  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_STRUCTURE (message);
  if (format)
    *format = (GstFormat)
        g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (FORMAT)));
  if (position)
    *position =
        g_value_get_int64 (gst_structure_id_get_value (structure,
            GST_QUARK (POSITION)));
}

/**
 * gst_message_parse_async_done:
 * @message: A valid #GstMessage of type GST_MESSAGE_ASYNC_DONE.
 * @running_time: (out) (allow-none): Result location for the running_time or %NULL
 *
 * Extract the running_time from the async_done message.
 *
 * MT safe.
 */
void
gst_message_parse_async_done (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_ASYNC_DONE);

  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_parse_request_state:
 * @message: A valid #GstMessage of type GST_MESSAGE_REQUEST_STATE.
 * @state: (out) (allow-none): Result location for the requested state or %NULL
 *
 * Extract the requested state from the request_state message.
 *
 * MT safe.
 */
void
gst_message_parse_request_state (GstMessage * message, GstState * state)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REQUEST_STATE);

  structure = GST_MESSAGE_STRUCTURE (message);
  if (state)
    *state = (GstState)
        g_value_get_enum (gst_structure_id_get_value (structure,
            GST_QUARK (NEW_STATE)));
}

/**
 * gst_message_new_stream_status:
 * @src: The object originating the message.
 * @type: The stream status type.
 * @owner: (transfer none): 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: (transfer full): the new stream status message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_stream_status (GstObject * src, GstStreamStatusType type,
    GstElement * owner)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (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: (out): A pointer to hold the status type
 * @owner: (out) (transfer none): 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.
 */
void
gst_message_parse_stream_status (GstMessage * message,
    GstStreamStatusType * type, GstElement ** owner)
{
  const GValue *owner_gvalue;
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);

  structure = GST_MESSAGE_STRUCTURE (message);
  owner_gvalue = gst_structure_id_get_value (structure, GST_QUARK (OWNER));
  g_return_if_fail (owner_gvalue != NULL);

  if (type)
    *type = (GstStreamStatusType)
        g_value_get_enum (gst_structure_id_get_value (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.
 */
void
gst_message_set_stream_status_object (GstMessage * message,
    const GValue * object)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_set_value (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.
 */
const GValue *
gst_message_get_stream_status_object (GstMessage * message)
{
  const GValue *result;
  GstStructure *structure;

  g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
  g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS,
      NULL);

  structure = GST_MESSAGE_STRUCTURE (message);
  result = gst_structure_id_get_value (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: (transfer full): the new step_done message.
 *
 * MT safe.
 */
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_new_id (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: (out) (allow-none): result location for the format
 * @amount: (out) (allow-none): result location for the amount
 * @rate: (out) (allow-none): result location for the rate
 * @flush: (out) (allow-none): result location for the flush flag
 * @intermediate: (out) (allow-none): result location for the intermediate flag
 * @duration: (out) (allow-none): result location for the duration
 * @eos: (out) (allow-none): result location for the EOS flag
 *
 * Extract the values the step_done message.
 *
 * MT safe.
 */
void
gst_message_parse_step_done (GstMessage * message, GstFormat * format,
    guint64 * amount, gdouble * rate, gboolean * flush, gboolean * intermediate,
    guint64 * duration, gboolean * eos)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_DONE);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_get (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 emitted, the application can queue a new step operation in the
 * element.
 *
 * Returns: (transfer full): The new step_start message.
 *
 * MT safe.
 */
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_new_id (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: (out) (allow-none): result location for the active flag
 * @format: (out) (allow-none): result location for the format
 * @amount: (out) (allow-none): result location for the amount
 * @rate: (out) (allow-none): result location for the rate
 * @flush: (out) (allow-none): result location for the flush flag
 * @intermediate: (out) (allow-none): result location for the intermediate flag
 *
 * Extract the values from step_start message.
 *
 * MT safe.
 */
void
gst_message_parse_step_start (GstMessage * message, gboolean * active,
    GstFormat * format, guint64 * amount, gdouble * rate, gboolean * flush,
    gboolean * intermediate)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_START);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_get (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);
}

/**
 * gst_message_new_qos:
 * @src: The object originating the message.
 * @live: if the message was generated by a live element
 * @running_time: the running time of the buffer that generated the message
 * @stream_time: the stream time of the buffer that generated the message
 * @timestamp: the timestamps of the buffer that generated the message
 * @duration: the duration of the buffer that generated the message
 *
 * A QOS message is posted on the bus whenever an element decides to drop a
 * buffer because of QoS reasons or whenever it changes its processing strategy
 * because of QoS reasons (quality adjustments such as processing at lower
 * accuracy).
 *
 * This message can be posted by an element that performs synchronisation against the
 * clock (live) or it could be dropped by an element that performs QoS because of QOS
 * events received from a downstream element (!live).
 *
 * @running_time, @stream_time, @timestamp, @duration should be set to the
 * respective running-time, stream-time, timestamp and duration of the (dropped)
 * buffer that generated the QoS event. Values can be left to
 * GST_CLOCK_TIME_NONE when unknown.
 *
 * Returns: (transfer full): The new qos message.
 *
 * MT safe.
 */
GstMessage *
gst_message_new_qos (GstObject * src, gboolean live, guint64 running_time,
    guint64 stream_time, guint64 timestamp, guint64 duration)
{
  GstMessage *message;
  GstStructure *structure;

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_QOS),
      GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
      GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time,
      GST_QUARK (STREAM_TIME), G_TYPE_UINT64, stream_time,
      GST_QUARK (TIMESTAMP), G_TYPE_UINT64, timestamp,
      GST_QUARK (DURATION), G_TYPE_UINT64, duration,
      GST_QUARK (JITTER), G_TYPE_INT64, (gint64) 0,
      GST_QUARK (PROPORTION), G_TYPE_DOUBLE, (gdouble) 1.0,
      GST_QUARK (QUALITY), G_TYPE_INT, (gint) 1000000,
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, GST_FORMAT_UNDEFINED,
      GST_QUARK (PROCESSED), G_TYPE_UINT64, (guint64) - 1,
      GST_QUARK (DROPPED), G_TYPE_UINT64, (guint64) - 1, NULL);
  message = gst_message_new_custom (GST_MESSAGE_QOS, src, structure);

  return message;
}

/**
 * gst_message_set_qos_values:
 * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
 * @jitter: The difference of the running-time against the deadline.
 * @proportion: Long term prediction of the ideal rate relative to normal rate
 * to get optimal quality.
 * @quality: An element dependent integer value that specifies the current
 * quality level of the element. The default maximum quality is 1000000.
 *
 * Set the QoS values that have been calculated/analysed from the QoS data
 *
 * MT safe.
 */
void
gst_message_set_qos_values (GstMessage * message, gint64 jitter,
    gdouble proportion, gint quality)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_set (structure,
      GST_QUARK (JITTER), G_TYPE_INT64, jitter,
      GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
      GST_QUARK (QUALITY), G_TYPE_INT, quality, NULL);
}

/**
 * gst_message_set_qos_stats:
 * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
 * @format: Units of the 'processed' and 'dropped' fields. Video sinks and video
 * filters will use GST_FORMAT_BUFFERS (frames). Audio sinks and audio filters
 * will likely use GST_FORMAT_DEFAULT (samples).
 * @processed: Total number of units correctly processed since the last state
 * change to READY or a flushing operation.
 * @dropped: Total number of units dropped since the last state change to READY
 * or a flushing operation.
 *
 * Set the QoS stats representing the history of the current continuous pipeline
 * playback period.
 *
 * When @format is @GST_FORMAT_UNDEFINED both @dropped and @processed are
 * invalid. Values of -1 for either @processed or @dropped mean unknown values.
 *
 * MT safe.
 */
void
gst_message_set_qos_stats (GstMessage * message, GstFormat format,
    guint64 processed, guint64 dropped)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_set (structure,
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (PROCESSED), G_TYPE_UINT64, processed,
      GST_QUARK (DROPPED), G_TYPE_UINT64, dropped, NULL);
}

/**
 * gst_message_parse_qos:
 * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
 * @live: (out) (allow-none): if the message was generated by a live element
 * @running_time: (out) (allow-none): the running time of the buffer that
 *     generated the message
 * @stream_time: (out) (allow-none): the stream time of the buffer that
 *     generated the message
 * @timestamp: (out) (allow-none): the timestamps of the buffer that
 *     generated the message
 * @duration: (out) (allow-none): the duration of the buffer that
 *     generated the message
 *
 * Extract the timestamps and live status from the QoS message.
 *
 * The returned values give the running_time, stream_time, timestamp and
 * duration of the dropped buffer. Values of GST_CLOCK_TIME_NONE mean unknown
 * values.
 *
 * MT safe.
 */
void
gst_message_parse_qos (GstMessage * message, gboolean * live,
    guint64 * running_time, guint64 * stream_time, guint64 * timestamp,
    guint64 * duration)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_get (structure,
      GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
      GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time,
      GST_QUARK (STREAM_TIME), G_TYPE_UINT64, stream_time,
      GST_QUARK (TIMESTAMP), G_TYPE_UINT64, timestamp,
      GST_QUARK (DURATION), G_TYPE_UINT64, duration, NULL);
}

/**
 * gst_message_parse_qos_values:
 * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
 * @jitter: (out) (allow-none): The difference of the running-time against
 *     the deadline.
 * @proportion: (out) (allow-none): Long term prediction of the ideal rate
 *     relative to normal rate to get optimal quality.
 * @quality: (out) (allow-none): An element dependent integer value that
 *     specifies the current quality level of the element. The default
 *     maximum quality is 1000000.
 *
 * Extract the QoS values that have been calculated/analysed from the QoS data
 *
 * MT safe.
 */
void
gst_message_parse_qos_values (GstMessage * message, gint64 * jitter,
    gdouble * proportion, gint * quality)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_get (structure,
      GST_QUARK (JITTER), G_TYPE_INT64, jitter,
      GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
      GST_QUARK (QUALITY), G_TYPE_INT, quality, NULL);
}

/**
 * gst_message_parse_qos_stats:
 * @message: A valid #GstMessage of type GST_MESSAGE_QOS.
 * @format: (out) (allow-none): Units of the 'processed' and 'dropped' fields.
 *     Video sinks and video filters will use GST_FORMAT_BUFFERS (frames).
 *     Audio sinks and audio filters will likely use GST_FORMAT_DEFAULT
 *     (samples).
 * @processed: (out) (allow-none): Total number of units correctly processed
 *     since the last state change to READY or a flushing operation.
 * @dropped: (out) (allow-none): Total number of units dropped since the last
 *     state change to READY or a flushing operation.
 *
 * Extract the QoS stats representing the history of the current continuous
 * pipeline playback period.
 *
 * When @format is @GST_FORMAT_UNDEFINED both @dropped and @processed are
 * invalid. Values of -1 for either @processed or @dropped mean unknown values.
 *
 * MT safe.
 */
void
gst_message_parse_qos_stats (GstMessage * message, GstFormat * format,
    guint64 * processed, guint64 * dropped)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_get (structure,
      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
      GST_QUARK (PROCESSED), G_TYPE_UINT64, processed,
      GST_QUARK (DROPPED), G_TYPE_UINT64, dropped, NULL);
}

/**
 * gst_message_new_progress:
 * @src: The object originating the message.
 * @type: a #GstProgressType
 * @code: a progress code
 * @text: free, user visible text describing the progress
 *
 * Progress messages are posted by elements when they use an asynchronous task
 * to perform actions triggered by a state change.
 *
 * @code contains a well defined string describing the action.
 * @text should contain a user visible string detailing the current action.
 *
 * Returns: (transfer full): The new qos message.
 */
GstMessage *
gst_message_new_progress (GstObject * src, GstProgressType type,
    const gchar * code, const gchar * text)
{
  GstMessage *message;
  GstStructure *structure;
  gint percent = 100, timeout = -1;

  g_return_val_if_fail (code != NULL, NULL);
  g_return_val_if_fail (text != NULL, NULL);

  if (type == GST_PROGRESS_TYPE_START || type == GST_PROGRESS_TYPE_CONTINUE)
    percent = 0;

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_PROGRESS),
      GST_QUARK (TYPE), GST_TYPE_PROGRESS_TYPE, type,
      GST_QUARK (CODE), G_TYPE_STRING, code,
      GST_QUARK (TEXT), G_TYPE_STRING, text,
      GST_QUARK (PERCENT), G_TYPE_INT, percent,
      GST_QUARK (TIMEOUT), G_TYPE_INT, timeout, NULL);
  message = gst_message_new_custom (GST_MESSAGE_PROGRESS, src, structure);

  return message;
}

/**
 * gst_message_parse_progress:
 * @message: A valid #GstMessage of type GST_MESSAGE_PROGRESS.
 * @type: (out) (allow-none): location for the type
 * @code: (out) (allow-none) (transfer full): location for the code
 * @text: (out) (allow-none) (transfer full): location for the text
 *
 * Parses the progress @type, @code and @text.
 */
void
gst_message_parse_progress (GstMessage * message, GstProgressType * type,
    gchar ** code, gchar ** text)
{
  GstStructure *structure;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_PROGRESS);

  structure = GST_MESSAGE_STRUCTURE (message);
  gst_structure_id_get (structure,
      GST_QUARK (TYPE), GST_TYPE_PROGRESS_TYPE, type,
      GST_QUARK (CODE), G_TYPE_STRING, code,
      GST_QUARK (TEXT), G_TYPE_STRING, text, NULL);
}

/**
 * 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 the 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) (allow-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) (allow-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) (allow-none): The object originating the message.
 * @context_type: The context type that is needed
 *
 * 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, const gchar * context_type)
{
  GstMessage *message;
  GstStructure *structure;

  g_return_val_if_fail (context_type != NULL, NULL);

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_NEED_CONTEXT),
      GST_QUARK (CONTEXT_TYPE), G_TYPE_STRING, context_type, NULL);
  message = gst_message_new_custom (GST_MESSAGE_NEED_CONTEXT, src, structure);

  return message;
}

/**
 * gst_message_parse_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.
 *
 * Returns: a #gboolean indicating if the parsing succeeded.
 *
 * Since: 1.2
 */
gboolean
gst_message_parse_context_type (GstMessage * message,
    const gchar ** context_type)
{
  GstStructure *structure;
  const GValue *value;

  g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEED_CONTEXT,
      FALSE);

  structure = GST_MESSAGE_STRUCTURE (message);

  if (context_type) {
    value = gst_structure_id_get_value (structure, GST_QUARK (CONTEXT_TYPE));
    *context_type = g_value_get_string (value);
  }

  return TRUE;
}

/**
 * gst_message_new_have_context:
 * @src: (transfer none) (allow-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);
}

/**
 * gst_message_new_device_added:
 * @src: The #GstObject that created the message
 * @device: (transfer none): The new #GstDevice
 *
 * Creates a new device-added message. The device-added message is produced by
 * #GstDeviceProvider or a #GstDeviceMonitor. They announce the appearance
 * of monitored devices.
 *
 * Returns: a newly allocated #GstMessage
 *
 * Since: 1.4
 */
GstMessage *
gst_message_new_device_added (GstObject * src, GstDevice * device)
{
  GstMessage *message;
  GstStructure *structure;

  g_return_val_if_fail (device != NULL, NULL);
  g_return_val_if_fail (GST_IS_DEVICE (device), NULL);

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_ADDED),
      GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
  message = gst_message_new_custom (GST_MESSAGE_DEVICE_ADDED, src, structure);

  return message;
}

/**
 * gst_message_parse_device_added:
 * @message: a #GstMessage of type %GST_MESSAGE_DEVICE_ADDED
 * @device: (out) (allow-none) (transfer full): A location where to store a
 *  pointer to the new #GstDevice, or %NULL
 *
 * Parses a device-added message. The device-added message is produced by
 * #GstDeviceProvider or a #GstDeviceMonitor. It announces the appearance
 * of monitored devices.
 *
 * Since: 1.4
 */
void
gst_message_parse_device_added (GstMessage * message, GstDevice ** device)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DEVICE_ADDED);

  if (device)
    gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
        GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
}

/**
 * gst_message_new_device_removed:
 * @src: The #GstObject that created the message
 * @device: (transfer none): The removed #GstDevice
 *
 * Creates a new device-removed message. The device-removed message is produced
 * by #GstDeviceProvider or a #GstDeviceMonitor. They announce the
 * disappearance of monitored devices.
 *
 * Returns: a newly allocated #GstMessage
 *
 * Since: 1.4
 */
GstMessage *
gst_message_new_device_removed (GstObject * src, GstDevice * device)
{
  GstMessage *message;
  GstStructure *structure;

  g_return_val_if_fail (device != NULL, NULL);
  g_return_val_if_fail (GST_IS_DEVICE (device), NULL);

  structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_REMOVED),
      GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
  message = gst_message_new_custom (GST_MESSAGE_DEVICE_REMOVED, src, structure);

  return message;
}

/**
 * gst_message_parse_device_removed:
 * @message: a #GstMessage of type %GST_MESSAGE_DEVICE_REMOVED
 * @device: (out) (allow-none) (transfer full): A location where to store a
 *  pointer to the removed #GstDevice, or %NULL
 *
 * Parses a device-removed message. The device-removed message is produced by
 * #GstDeviceProvider or a #GstDeviceMonitor. It announces the
 * disappearance of monitored devices.
 *
 * Since: 1.4
 */
void
gst_message_parse_device_removed (GstMessage * message, GstDevice ** device)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DEVICE_REMOVED);

  if (device)
    gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
        GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
}

/**
 * gst_message_new_property_notify:
 * @src: The #GstObject whose property changed (may or may not be a #GstElement)
 * @property_name: name of the property that changed
 * @val: (allow-none) (transfer full): new property value, or %NULL
 *
 * Returns: a newly allocated #GstMessage
 *
 * Since: 1.10
 */
GstMessage *
gst_message_new_property_notify (GstObject * src, const gchar * property_name,
    GValue * val)
{
  GstStructure *structure;
  GValue name_val = G_VALUE_INIT;

  g_return_val_if_fail (property_name != NULL, NULL);

  structure = gst_structure_new_id_empty (GST_QUARK (MESSAGE_PROPERTY_NOTIFY));
  g_value_init (&name_val, G_TYPE_STRING);
  /* should already be interned, but let's make sure */
  g_value_set_static_string (&name_val, g_intern_string (property_name));
  gst_structure_id_take_value (structure, GST_QUARK (PROPERTY_NAME), &name_val);
  if (val != NULL)
    gst_structure_id_take_value (structure, GST_QUARK (PROPERTY_VALUE), val);

  return gst_message_new_custom (GST_MESSAGE_PROPERTY_NOTIFY, src, structure);
}

/**
 * gst_message_parse_property_notify:
 * @message: a #GstMessage of type %GST_MESSAGE_PROPERTY_NOTIFY
 * @object: (out) (allow-none) (transfer none): location where to store a
 *     pointer to the object whose property got changed, or %NULL
 * @property_name: (out) (allow-none): return location for the name of the
 *     property that got changed, or %NULL
 * @property_value: (out) (allow-none): return location for the new value of
 *     the property that got changed, or %NULL. This will only be set if the
 *     property notify watch was told to include the value when it was set up
 *
 * Parses a property-notify message. These will be posted on the bus only
 * when set up with gst_element_add_property_notify_watch() or
 * gst_element_add_property_deep_notify_watch().
 *
 * Since: 1.10
 */
void
gst_message_parse_property_notify (GstMessage * message, GstObject ** object,
    const gchar ** property_name, const GValue ** property_value)
{
  const GstStructure *s = GST_MESSAGE_STRUCTURE (message);

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_PROPERTY_NOTIFY);

  if (object)
    *object = GST_MESSAGE_SRC (message);

  if (property_name) {
    const GValue *name_value;

    name_value = gst_structure_id_get_value (s, GST_QUARK (PROPERTY_NAME));
    *property_name = g_value_get_string (name_value);
  }

  if (property_value)
    *property_value =
        gst_structure_id_get_value (s, GST_QUARK (PROPERTY_VALUE));
}

/**
 * gst_message_new_stream_collection:
 * @src: The #GstObject that created the message
 * @collection: (transfer none): The #GstStreamCollection
 *
 * Creates a new stream-collection message. The message is used to announce new
 * #GstStreamCollection
 *
 * Returns: a newly allocated #GstMessage
 *
 * Since: 1.10
 */
GstMessage *
gst_message_new_stream_collection (GstObject * src,
    GstStreamCollection * collection)
{
  GstMessage *message;
  GstStructure *structure;

  g_return_val_if_fail (collection != NULL, NULL);
  g_return_val_if_fail (GST_IS_STREAM_COLLECTION (collection), NULL);

  structure =
      gst_structure_new_id (GST_QUARK (MESSAGE_STREAM_COLLECTION),
      GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
  message =
      gst_message_new_custom (GST_MESSAGE_STREAM_COLLECTION, src, structure);

  return message;
}

/**
 * gst_message_parse_stream_collection:
 * @message: a #GstMessage of type %GST_MESSAGE_STREAM_COLLECTION
 * @collection: (out) (allow-none) (transfer full): A location where to store a
 *  pointer to the #GstStreamCollection, or %NULL
 *
 * Parses a stream-collection message.
 *
 * Since: 1.10
 */
void
gst_message_parse_stream_collection (GstMessage * message,
    GstStreamCollection ** collection)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) ==
      GST_MESSAGE_STREAM_COLLECTION);

  if (collection)
    gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
        GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
}

/**
 * gst_message_new_streams_selected:
 * @src: The #GstObject that created the message
 * @collection: (transfer none): The #GstStreamCollection
 *
 * Creates a new steams-selected message. The message is used to announce
 * that an array of streams has been selected. This is generally in response
 * to a #GST_EVENT_SELECT_STREAMS event, or when an element (such as decodebin3)
 * makes an initial selection of streams.
 *
 * The message also contains the #GstStreamCollection to which the various streams
 * belong to.
 *
 * Users of gst_message_new_streams_selected() can add the selected streams with
 * gst_message_streams_selected_add().
 *
 * Returns: a newly allocated #GstMessage
 *
 * Since: 1.10
 */
GstMessage *
gst_message_new_streams_selected (GstObject * src,
    GstStreamCollection * collection)
{
  GstMessage *message;
  GstStructure *structure;
  GValue val = G_VALUE_INIT;

  g_return_val_if_fail (collection != NULL, NULL);
  g_return_val_if_fail (GST_IS_STREAM_COLLECTION (collection), NULL);

  structure =
      gst_structure_new_id (GST_QUARK (MESSAGE_STREAMS_SELECTED),
      GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
  g_value_init (&val, GST_TYPE_ARRAY);
  gst_structure_id_take_value (structure, GST_QUARK (STREAMS), &val);
  message =
      gst_message_new_custom (GST_MESSAGE_STREAMS_SELECTED, src, structure);

  return message;
}

/**
 * gst_message_streams_selected_get_size:
 * @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
 *
 * Returns the number of streams contained in the @message.
 *
 * Returns: The number of streams contained within.
 *
 * Since: 1.10
 */
guint
gst_message_streams_selected_get_size (GstMessage * msg)
{
  const GValue *val;

  g_return_val_if_fail (GST_IS_MESSAGE (msg), 0);
  g_return_val_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED,
      0);

  val =
      gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (msg),
      GST_QUARK (STREAMS));
  return gst_value_array_get_size (val);
}

/**
 * gst_message_streams_selected_add:
 * @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
 * @stream: (transfer none): a #GstStream to add to @message
 *
 * Adds the @stream to the @message.
 *
 * Since: 1.10
 */
void
gst_message_streams_selected_add (GstMessage * msg, GstStream * stream)
{
  GValue *val;
  GValue to_add = G_VALUE_INIT;

  g_return_if_fail (GST_IS_MESSAGE (msg));
  g_return_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED);
  g_return_if_fail (GST_IS_STREAM (stream));

  val =
      (GValue *) gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (msg),
      GST_QUARK (STREAMS));
  g_value_init (&to_add, GST_TYPE_STREAM);
  g_value_set_object (&to_add, stream);
  gst_value_array_append_and_take_value (val, &to_add);
}

/**
 * gst_message_streams_selected_get_stream:
 * @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
 * @idx: Index of the stream to retrieve
 *
 * Retrieves the #GstStream with index @index from the @message.
 *
 * Returns: (transfer full): A #GstStream
 *
 * Since: 1.10
 */
GstStream *
gst_message_streams_selected_get_stream (GstMessage * msg, guint idx)
{
  const GValue *streams, *val;

  g_return_val_if_fail (GST_IS_MESSAGE (msg), NULL);
  g_return_val_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_STREAMS_SELECTED,
      NULL);

  streams =
      gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (msg),
      GST_QUARK (STREAMS));
  val = gst_value_array_get_value (streams, idx);
  if (val) {
    return (GstStream *) g_value_dup_object (val);
  }

  return NULL;
}

/**
 * gst_message_parse_streams_selected:
 * @message: a #GstMessage of type %GST_MESSAGE_STREAMS_SELECTED
 * @collection: (out) (allow-none) (transfer full): A location where to store a
 *  pointer to the #GstStreamCollection, or %NULL
 *
 * Parses a streams-selected message.
 *
 * Since: 1.10
 */
void
gst_message_parse_streams_selected (GstMessage * message,
    GstStreamCollection ** collection)
{
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAMS_SELECTED);

  if (collection)
    gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
        GST_QUARK (COLLECTION), GST_TYPE_STREAM_COLLECTION, collection, NULL);
}

/**
 * gst_message_new_redirect:
 * @src: The #GstObject whose property changed (may or may not be a #GstElement)
 * @location: (transfer none): location string for the new entry
 * @tag_list: (transfer full) (allow-none): tag list for the new entry
 * @entry_struct: (transfer full) (allow-none): structure for the new entry
 *
 * Creates a new redirect message and adds a new entry to it. Redirect messages
 * are posted when an element detects that the actual data has to be retrieved
 * from a different location. This is useful if such a redirection cannot be
 * handled inside a source element, for example when HTTP 302/303 redirects
 * return a non-HTTP URL.
 *
 * The redirect message can hold multiple entries. The first one is added
 * when the redirect message is created, with the given location, tag_list,
 * entry_struct arguments. Use gst_message_add_redirect_entry() to add more
 * entries.
 *
 * Each entry has a location, a tag list, and a structure. All of these are
 * optional. The tag list and structure are useful for additional metadata,
 * such as bitrate statistics for the given location.
 *
 * By default, message recipients should treat entries in the order they are
 * stored. The recipient should therefore try entry #0 first, and if this
 * entry is not acceptable or working, try entry #1 etc. Senders must make
 * sure that they add entries in this order. However, recipients are free to
 * ignore the order and pick an entry that is "best" for them. One example
 * would be a recipient that scans the entries for the one with the highest
 * bitrate tag.
 *
 * The specified location string is copied. However, ownership over the tag
 * list and structure are transferred to the message.
 *
 * Returns: a newly allocated #GstMessage
 *
 * Since: 1.10
 */
GstMessage *
gst_message_new_redirect (GstObject * src, const gchar * location,
    GstTagList * tag_list, const GstStructure * entry_struct)
{
  GstStructure *structure;
  GstMessage *message;
  GValue entry_locations_gvalue = G_VALUE_INIT;
  GValue entry_taglists_gvalue = G_VALUE_INIT;
  GValue entry_structures_gvalue = G_VALUE_INIT;

  g_return_val_if_fail (location != NULL, NULL);

  g_value_init (&entry_locations_gvalue, GST_TYPE_LIST);
  g_value_init (&entry_taglists_gvalue, GST_TYPE_LIST);
  g_value_init (&entry_structures_gvalue, GST_TYPE_LIST);

  structure = gst_structure_new_id_empty (GST_QUARK (MESSAGE_REDIRECT));
  gst_structure_id_take_value (structure, GST_QUARK (REDIRECT_ENTRY_LOCATIONS),
      &entry_locations_gvalue);
  gst_structure_id_take_value (structure, GST_QUARK (REDIRECT_ENTRY_TAGLISTS),
      &entry_taglists_gvalue);
  gst_structure_id_take_value (structure, GST_QUARK (REDIRECT_ENTRY_STRUCTURES),
      &entry_structures_gvalue);

  message = gst_message_new_custom (GST_MESSAGE_REDIRECT, src, structure);
  g_assert (message != NULL);

  gst_message_add_redirect_entry (message, location, tag_list, entry_struct);

  return message;
}

/**
 * gst_message_add_redirect_entry:
 * @message: a #GstMessage of type %GST_MESSAGE_REDIRECT
 * @location: (transfer none): location string for the new entry
 * @tag_list: (transfer full) (allow-none): tag list for the new entry
 * @entry_struct: (transfer full) (allow-none): structure for the new entry
 *
 * Creates and appends a new entry.
 *
 * The specified location string is copied. However, ownership over the tag
 * list and structure are transferred to the message.
 *
 * Since: 1.10
 */
void
gst_message_add_redirect_entry (GstMessage * message, const gchar * location,
    GstTagList * tag_list, const GstStructure * entry_struct)
{
  GValue val = G_VALUE_INIT;
  GstStructure *structure;
  GValue *entry_locations_gvalue;
  GValue *entry_taglists_gvalue;
  GValue *entry_structures_gvalue;

  g_return_if_fail (location != NULL);
  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REDIRECT);

  structure = GST_MESSAGE_STRUCTURE (message);

  entry_locations_gvalue =
      (GValue *) gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_LOCATIONS));
  g_return_if_fail (GST_VALUE_HOLDS_LIST (entry_locations_gvalue));
  entry_taglists_gvalue =
      (GValue *) gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_TAGLISTS));
  g_return_if_fail (GST_VALUE_HOLDS_LIST (entry_taglists_gvalue));
  entry_structures_gvalue =
      (GValue *) gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_STRUCTURES));
  g_return_if_fail (GST_VALUE_HOLDS_LIST (entry_structures_gvalue));

  g_value_init (&val, G_TYPE_STRING);
  if (location)
    g_value_set_string (&val, location);
  gst_value_list_append_and_take_value (entry_locations_gvalue, &val);

  g_value_init (&val, GST_TYPE_TAG_LIST);
  if (tag_list)
    g_value_take_boxed (&val, tag_list);
  gst_value_list_append_and_take_value (entry_taglists_gvalue, &val);

  g_value_init (&val, GST_TYPE_STRUCTURE);
  if (entry_struct)
    g_value_take_boxed (&val, entry_struct);
  gst_value_list_append_and_take_value (entry_structures_gvalue, &val);
}

/**
 * gst_message_parse_redirect_entry:
 * @message: a #GstMessage of type %GST_MESSAGE_REDIRECT
 * @entry_index: index of the entry to parse
 * @location: (out) (transfer none) (allow-none): return location for
 *     the pointer to the entry's location string, or %NULL
 * @tag_list: (out) (transfer none) (allow-none): return location for
 *     the pointer to the entry's tag list, or %NULL
 * @entry_struct: (out) (transfer none) (allow-none): return location
 *     for the pointer to the entry's structure, or %NULL
 *
 * Parses the location and/or structure from the entry with the given index.
 * The index must be between 0 and gst_message_get_num_redirect_entries() - 1.
 * Returned pointers are valid for as long as this message exists.
 *
 * Since: 1.10
 */
void
gst_message_parse_redirect_entry (GstMessage * message, gsize entry_index,
    const gchar ** location, GstTagList ** tag_list,
    const GstStructure ** entry_struct)
{
  const GValue *val;
  GstStructure *structure;
  const GValue *entry_locations_gvalue;
  const GValue *entry_taglists_gvalue;
  const GValue *entry_structures_gvalue;

  g_return_if_fail (GST_IS_MESSAGE (message));
  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REDIRECT);

  if (G_UNLIKELY (!location && !tag_list && !entry_struct))
    return;

  structure = GST_MESSAGE_STRUCTURE (message);

  entry_locations_gvalue =
      gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_LOCATIONS));
  g_return_if_fail (GST_VALUE_HOLDS_LIST (entry_locations_gvalue));
  entry_taglists_gvalue =
      gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_TAGLISTS));
  g_return_if_fail (GST_VALUE_HOLDS_LIST (entry_taglists_gvalue));
  entry_structures_gvalue =
      gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_STRUCTURES));
  g_return_if_fail (GST_VALUE_HOLDS_LIST (entry_structures_gvalue));

  if (location) {
    val = gst_value_list_get_value (entry_locations_gvalue, entry_index);
    g_return_if_fail (val != NULL);
    *location = g_value_get_string (val);
  }

  if (tag_list) {
    val = gst_value_list_get_value (entry_taglists_gvalue, entry_index);
    g_return_if_fail (val != NULL);
    *tag_list = (GstTagList *) g_value_get_boxed (val);
  }

  if (entry_struct) {
    val = gst_value_list_get_value (entry_structures_gvalue, entry_index);
    g_return_if_fail (val != NULL);
    *entry_struct = (const GstStructure *) g_value_get_boxed (val);
  }
}

/**
 * gst_message_get_num_redirect_entries:
 * @message: a #GstMessage of type %GST_MESSAGE_REDIRECT
 *
 * Returns: the number of entries stored in the message
 *
 * Since: 1.10
 */
gsize
gst_message_get_num_redirect_entries (GstMessage * message)
{
  GstStructure *structure;
  const GValue *entry_locations_gvalue;
  const GValue *entry_taglists_gvalue;
  const GValue *entry_structures_gvalue;
  gsize size;

  g_return_val_if_fail (GST_IS_MESSAGE (message), 0);
  g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REDIRECT, 0);

  structure = GST_MESSAGE_STRUCTURE (message);

  entry_locations_gvalue =
      gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_LOCATIONS));
  g_return_val_if_fail (GST_VALUE_HOLDS_LIST (entry_locations_gvalue), 0);
  entry_taglists_gvalue =
      gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_TAGLISTS));
  g_return_val_if_fail (GST_VALUE_HOLDS_LIST (entry_taglists_gvalue), 0);
  entry_structures_gvalue =
      gst_structure_id_get_value (structure,
      GST_QUARK (REDIRECT_ENTRY_STRUCTURES));
  g_return_val_if_fail (GST_VALUE_HOLDS_LIST (entry_structures_gvalue), 0);

  size = gst_value_list_get_size (entry_locations_gvalue);

  g_return_val_if_fail ((size ==
          gst_value_list_get_size (entry_structures_gvalue))
      && (size == gst_value_list_get_size (entry_taglists_gvalue)), 0);

  return size;
}
