X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstmessage.c;h=f72bd62c61fd2dc335ba097d30665f4a6c5ab852;hb=04a637ae64582e8830205c42cc6d9ef4aabc969a;hp=6b8b2c037c9fb8ecc7481aca7118f9727128733f;hpb=1a61f3ec192ed9bdb085d8ed59eff4247cdc77c4;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstmessage.c b/gst/gstmessage.c index 6b8b2c0..f72bd62c61 100644 --- a/gst/gstmessage.c +++ b/gst/gstmessage.c @@ -15,12 +15,13 @@ * * 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., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * 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 @@ -34,18 +35,12 @@ * application using the #GstBus. * * The basic use pattern of posting a message on a #GstBus is as follows: - * - * - * Posting a #GstMessage - * - * gst_bus_post (bus, gst_message_new_eos()); - * - * + * |[ + * 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(). - * - * Last reviewed on 2005-11-09 (0.9.4) */ @@ -58,6 +53,7 @@ #include "gsttaglist.h" #include "gstutils.h" #include "gstquark.h" +#include "gstvalue.h" typedef struct @@ -67,7 +63,7 @@ typedef struct GstStructure *structure; } GstMessageImpl; -#define GST_MESSAGE_STRUCTURE(m) (((GstMessageImpl *)(m))->structure) +#define GST_MESSAGE_STRUCTURE(m) (((GstMessageImpl *)(m))->structure) typedef struct { @@ -96,7 +92,7 @@ static GstMessageQuarks message_quarks[] = { {GST_MESSAGE_ELEMENT, "element", 0}, {GST_MESSAGE_SEGMENT_START, "segment-start", 0}, {GST_MESSAGE_SEGMENT_DONE, "segment-done", 0}, - {GST_MESSAGE_DURATION, "duration", 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}, @@ -105,10 +101,23 @@ static GstMessageQuarks message_quarks[] = { {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_DEVICE_CHANGED, "device-changed", 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 GType _gst_message_type = 0; +static GQuark details_quark = 0; + +GType _gst_message_type = 0; GST_DEFINE_MINI_OBJECT_TYPE (GstMessage, gst_message); void @@ -118,15 +127,11 @@ _priv_gst_message_initialize (void) GST_CAT_INFO (GST_CAT_GST_INIT, "init messages"); - /* the GstMiniObject types need to be class_ref'd once before it can be - * done from multiple threads; - * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */ - gst_message_get_type (); - 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 (); } @@ -171,6 +176,28 @@ gst_message_type_to_quark (GstMessageType type) 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) { @@ -186,23 +213,20 @@ _gst_message_free (GstMessage * message) GST_MESSAGE_SRC (message) = NULL; } - if (message->lock.p) { - GST_MESSAGE_LOCK (message); - GST_MESSAGE_SIGNAL (message); - GST_MESSAGE_UNLOCK (message); - } - structure = GST_MESSAGE_STRUCTURE (message); if (structure) { gst_structure_set_parent_refcount (structure, NULL); gst_structure_free (structure); } +#ifdef USE_POISONING + memset (message, 0xff, sizeof (GstMessageImpl)); +#endif - g_slice_free1 (GST_MINI_OBJECT_SIZE (message), message); + g_slice_free1 (sizeof (GstMessageImpl), message); } static void -gst_message_init (GstMessageImpl * message, gsize size, GstMessageType type, +gst_message_init (GstMessageImpl * message, GstMessageType type, GstObject * src); static GstMessage * @@ -217,7 +241,7 @@ _gst_message_copy (GstMessage * message) copy = g_slice_new0 (GstMessageImpl); - gst_message_init (copy, sizeof (GstMessageImpl), GST_MESSAGE_TYPE (message), + gst_message_init (copy, GST_MESSAGE_TYPE (message), GST_MESSAGE_SRC (message)); GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message); @@ -236,16 +260,13 @@ _gst_message_copy (GstMessage * message) } static void -gst_message_init (GstMessageImpl * message, gsize size, GstMessageType type, +gst_message_init (GstMessageImpl * message, GstMessageType type, GstObject * src) { - gst_mini_object_init (GST_MINI_OBJECT_CAST (message), _gst_message_type, - size); - - message->message.mini_object.copy = - (GstMiniObjectCopyFunction) _gst_message_copy; - message->message.mini_object.free = - (GstMiniObjectFreeFunction) _gst_message_free; + 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) @@ -259,15 +280,15 @@ gst_message_init (GstMessageImpl * message, gsize size, GstMessageType type, /** * gst_message_new_custom: * @type: The #GstMessageType to distinguish messages - * @src: The object originating the message. - * @structure: (transfer full): the structure for the message. The message - * will take ownership of the structure. + * @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. + * app. The structure field can be %NULL. * - * Returns: (transfer full): The new message. + * Returns: (transfer full) (nullable): The new message. * * MT safe. */ @@ -289,7 +310,7 @@ gst_message_new_custom (GstMessageType type, GstObject * src, &message->message.mini_object.refcount)) goto had_parent; } - gst_message_init (message, sizeof (GstMessageImpl), type, src); + gst_message_init (message, type, src); GST_MESSAGE_STRUCTURE (message) = structure; @@ -298,7 +319,7 @@ gst_message_new_custom (GstMessageType type, GstObject * src, /* ERRORS */ had_parent: { - g_slice_free1 (GST_MINI_OBJECT_SIZE (message), message); + g_slice_free1 (sizeof (GstMessageImpl), message); g_warning ("structure is already owned by another object"); return NULL; } @@ -324,8 +345,6 @@ had_parent: * Returns: The message's sequence number. * * MT safe. - * - * Since: 0.10.22 */ guint32 gst_message_get_seqnum (GstMessage * message) @@ -347,20 +366,19 @@ gst_message_get_seqnum (GstMessage * message) * for more information. * * MT safe. - * - * Since: 0.10.22 */ void gst_message_set_seqnum (GstMessage * message, guint32 seqnum) { g_return_if_fail (GST_IS_MESSAGE (message)); + g_return_if_fail (seqnum != GST_SEQNUM_INVALID); GST_MESSAGE_SEQNUM (message) = seqnum; } /** * gst_message_new_eos: - * @src: (transfer none): The object originating the message. + * @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 @@ -381,93 +399,282 @@ gst_message_new_eos (GstObject * src) } /** - * gst_message_new_error: - * @src: (transfer none): The object originating the 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 - * occured. The pipeline will probably (partially) stop. The application + * occurred. The pipeline will probably (partially) stop. The application * receiving this message should stop the pipeline. * - * Returns: (transfer full): the new error message. + * Returns: (transfer full) (nullable): the new error message. * - * MT safe. + * Since: 1.10 */ GstMessage * -gst_message_new_error (GstObject * src, GError * error, const gchar * debug) +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_warning: - * @src: (transfer none): The object originating the 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: (transfer none) (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. + * Returns: (transfer full) (nullable): the new warning message. * - * MT safe. + * Since: 1.10 */ GstMessage * -gst_message_new_warning (GstObject * src, GError * error, const gchar * debug) +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_info: - * @src: (transfer none): The object originating the 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 info message. The message will make copies of @error and + * 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: (transfer none) (out): A pointer to the returned details structure * - * Returns: (transfer full): the new info message. + * 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. * - * Since: 0.10.12 + * Returns: (transfer full) (nullable): the new warning message. + * + * Since: 1.10 */ GstMessage * -gst_message_new_info (GstObject * src, GError * error, const gchar * debug) +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: (transfer none) (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): The object originating the message. + * @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. @@ -480,19 +687,23 @@ gst_message_new_info (GstObject * src, GError * error, const gchar * debug) 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_STRUCTURE (tag_list), NULL); - - message = - gst_message_new_custom (GST_MESSAGE_TAG, src, (GstStructure *) tag_list); + 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): The object originating the message. + * @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 @@ -504,29 +715,29 @@ gst_message_new_tag (GstObject * src, GstTagList * tag_list) * 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. + * completed prerolling. * * MT safe. * - * Returns: (transfer full): The new buffering message. - * - * Since: 0.10.11 + * Returns: (transfer full) (nullable): 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, G_GINT64_CONSTANT (-1), - GST_QUARK (ESTIMATED_TOTAL), G_TYPE_INT64, G_GINT64_CONSTANT (-1), NULL); + GST_QUARK (BUFFERING_LEFT), G_TYPE_INT64, buffering_left, NULL); message = gst_message_new_custom (GST_MESSAGE_BUFFERING, src, structure); return message; @@ -534,7 +745,7 @@ gst_message_new_buffering (GstObject * src, gint percent) /** * gst_message_new_state_changed: - * @src: (transfer none): the object originating the message + * @src: (transfer none) (allow-none): The object originating the message. * @oldstate: the previous state * @newstate: the new (current) state * @pending: the pending (target) state @@ -553,7 +764,7 @@ gst_message_new_state_changed (GstObject * src, GstMessage *message; GstStructure *structure; - structure = gst_structure_new_id (GST_QUARK (MESSAGE_STATE), + 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); @@ -564,7 +775,7 @@ gst_message_new_state_changed (GstObject * src, /** * gst_message_new_state_dirty: - * @src: (transfer none): the object originating the message + * @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 @@ -586,9 +797,9 @@ gst_message_new_state_dirty (GstObject * src) /** * gst_message_new_clock_provide: - * @src: (transfer none): the object originating the message. + * @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 + * @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 @@ -618,7 +829,7 @@ gst_message_new_clock_provide (GstObject * src, GstClock * clock, /** * gst_message_new_clock_lost: - * @src: (transfer none): the object originating the message. + * @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 @@ -647,11 +858,11 @@ gst_message_new_clock_lost (GstObject * src, GstClock * clock) /** * gst_message_new_new_clock: - * @src: (transfer none): The object originating the message. + * @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 selectes a new clock for the pipeline. + * pipeline selects a new clock for the pipeline. * * Returns: (transfer full): The new new clock message. * @@ -672,7 +883,7 @@ gst_message_new_new_clock (GstObject * src, GstClock * clock) /** * gst_message_new_structure_change: - * @src: (transfer none): The object originating the message. + * @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. @@ -686,8 +897,6 @@ gst_message_new_new_clock (GstObject * src, GstClock * clock) * Returns: (transfer full): the new structure change message. * * MT safe. - * - * Since: 0.10.22. */ GstMessage * gst_message_new_structure_change (GstObject * src, GstStructureChangeType type, @@ -713,7 +922,7 @@ gst_message_new_structure_change (GstObject * src, GstStructureChangeType type, /** * gst_message_new_segment_start: - * @src: (transfer none): The object originating the message. + * @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 * @@ -743,7 +952,7 @@ gst_message_new_segment_start (GstObject * src, GstFormat format, /** * gst_message_new_segment_done: - * @src: (transfer none): the object originating the message. + * @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 * @@ -773,79 +982,75 @@ gst_message_new_segment_done (GstObject * src, GstFormat format, /** * gst_message_new_application: - * @src: (transfer none): the object originating the message. + * @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. + * Returns: (transfer full) (nullable): 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): The object originating the message. - * @structure: (transfer full): The structure for the message. The message - * will take ownership of the structure. + * @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. + * documented in the element's documentation. The structure field can be %NULL. * - * Returns: (transfer full): The new element message. + * Returns: (transfer full) (nullable): 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: - * @src: (transfer none): The object originating the message. - * @format: The format of the duration - * @duration: The new duration + * gst_message_new_duration_changed: + * @src: (transfer none) (allow-none): The object originating the message. * - * Create a new duration message. This message is posted by elements that - * know the duration of a stream in a specific format. This 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. Elements may post a duration message with a duration of - * GST_CLOCK_TIME_NONE to indicate that the duration has changed and the - * cached duration should be discarded. The new duration can then be - * retrieved via a query. + * pipeline. * - * Returns: (transfer full): The new duration message. + * Returns: (transfer full): The new duration-changed message. * * MT safe. */ GstMessage * -gst_message_new_duration (GstObject * src, GstFormat format, gint64 duration) +gst_message_new_duration_changed (GstObject * src) { GstMessage *message; - GstStructure *structure; - structure = gst_structure_new_id (GST_QUARK (MESSAGE_DURATION), - GST_QUARK (FORMAT), GST_TYPE_FORMAT, format, - GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL); - message = gst_message_new_custom (GST_MESSAGE_DURATION, src, structure); + 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): The object originating the message. + * @src: (transfer none) (allow-none): The object originating the message. * * This message is posted by elements when they start an ASYNC state change. * @@ -865,25 +1070,27 @@ gst_message_new_async_start (GstObject * src) /** * gst_message_new_async_done: - * @src: (transfer none): The object originating the message. - * @reset_time: if the running_time should be reset + * @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. - * @reset_time is set to TRUE when the element requests a new running_time - * before going to PLAYING. + * @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, gboolean reset_time) +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 (RESET_TIME), G_TYPE_BOOLEAN, reset_time, NULL); + GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time, NULL); message = gst_message_new_custom (GST_MESSAGE_ASYNC_DONE, src, structure); return message; @@ -891,7 +1098,7 @@ gst_message_new_async_done (GstObject * src, gboolean reset_time) /** * gst_message_new_latency: - * @src: (transfer none): The object originating the message. + * @src: (transfer none) (allow-none): The object originating the message. * * This message can be posted by elements when their latency requirements have * changed. @@ -899,8 +1106,6 @@ gst_message_new_async_done (GstObject * src, gboolean reset_time) * Returns: (transfer full): The new latency message. * * MT safe. - * - * Since: 0.10.12 */ GstMessage * gst_message_new_latency (GstObject * src) @@ -914,18 +1119,16 @@ gst_message_new_latency (GstObject * src) /** * gst_message_new_request_state: - * @src: (transfer none): the object originating the message. + * @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 requst state message. + * Returns: (transfer full): the new request state message. * * MT safe. - * - * Since: 0.10.23 */ GstMessage * gst_message_new_request_state (GstObject * src, GstState state) @@ -946,9 +1149,9 @@ gst_message_new_request_state (GstObject * src, GstState state) * * 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. + * Returns: (transfer none) (nullable): 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. */ @@ -961,6 +1164,43 @@ gst_message_get_structure (GstMessage * message) } /** + * gst_message_writable_structure: + * @message: The #GstMessage. + * + * Get a writable version of the structure. + * + * 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. + * This function checks if @message is writable and will never return + * %NULL. + * + * MT safe. + * + * Since: 1.14 + */ +GstStructure * +gst_message_writable_structure (GstMessage * message) +{ + GstStructure *structure; + + g_return_val_if_fail (GST_IS_MESSAGE (message), NULL); + g_return_val_if_fail (gst_message_is_writable (message), NULL); + + structure = GST_MESSAGE_STRUCTURE (message); + + if (structure == NULL) { + structure = + gst_structure_new_id_empty (gst_message_type_to_quark (GST_MESSAGE_TYPE + (message))); + gst_structure_set_parent_refcount (structure, + &message->mini_object.refcount); + GST_MESSAGE_STRUCTURE (message) = structure; + } + return structure; +} + +/** * gst_message_has_name: * @message: The #GstMessage. * @name: name to check @@ -969,8 +1209,6 @@ gst_message_get_structure (GstMessage * message) * check the name of a custom message. * * Returns: %TRUE if @name matches the name of the message structure. - * - * Since: 0.10.20 */ gboolean gst_message_has_name (GstMessage * message, const gchar * name) @@ -995,16 +1233,16 @@ gst_message_has_name (GstMessage * message, const gchar * name) * output argument is a copy; the caller must free it when done. * * Typical usage of this function might be: - * |[ + * |[ * ... * switch (GST_MESSAGE_TYPE (msg)) { * case GST_MESSAGE_TAG: { * GstTagList *tags = NULL; - * + * * gst_message_parse_tag (msg, &tags); * g_print ("Got tags from element %s\n", GST_OBJECT_NAME (msg->src)); * handle_tags (tags); - * gst_tag_list_free (tags); + * gst_tag_list_unref (tags); * break; * } * ... @@ -1017,16 +1255,12 @@ gst_message_has_name (GstMessage * message, const gchar * name) void gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list) { - GstStructure *ret; - g_return_if_fail (GST_IS_MESSAGE (message)); g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG); g_return_if_fail (tag_list != NULL); - ret = gst_structure_copy (GST_MESSAGE_STRUCTURE (message)); - gst_structure_remove_field (ret, "source-pad"); - - *tag_list = (GstTagList *) ret; + gst_structure_id_get (GST_MESSAGE_STRUCTURE (message), + GST_QUARK (TAGLIST), GST_TYPE_TAG_LIST, tag_list, NULL); } /** @@ -1038,8 +1272,6 @@ gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list) * gst_message_new_buffering(). * * MT safe. - * - * Since: 0.10.11 */ void gst_message_parse_buffering (GstMessage * message, gint * percent) @@ -1056,19 +1288,18 @@ gst_message_parse_buffering (GstMessage * message, gint * percent) /** * gst_message_set_buffering_stats: * @message: A valid #GstMessage of type GST_MESSAGE_BUFFERING. - * @mode: a buffering mode + * @mode: a buffering mode * @avg_in: the average input rate * @avg_out: the average output rate * @buffering_left: amount of buffering time left in milliseconds * * Configures the buffering stats values in @message. - * - * Since: 0.10.20 */ 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), @@ -1081,15 +1312,13 @@ gst_message_set_buffering_stats (GstMessage * message, GstBufferingMode mode, /** * 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 + * @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 + * milliseconds, or %NULL * * Extracts the buffering stats values from @message. - * - * Since: 0.10.20 */ void gst_message_parse_buffering_stats (GstMessage * message, @@ -1120,19 +1349,19 @@ gst_message_parse_buffering_stats (GstMessage * message, /** * 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 + * @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: - * |[ + * |[ * ... * switch (GST_MESSAGE_TYPE (msg)) { * case GST_MESSAGE_STATE_CHANGED: { * GstState old_state, new_state; - * + * * gst_message_parse_state_changed (msg, &old_state, &new_state, NULL); * g_print ("Element %s changed state from %s to %s.\n", * GST_OBJECT_NAME (msg->src), @@ -1175,8 +1404,8 @@ gst_message_parse_state_changed (GstMessage * message, * 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 + * 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. @@ -1275,8 +1504,6 @@ gst_message_parse_new_clock (GstMessage * message, GstClock ** clock) * Extracts the change type and completion status from the GstMessage. * * MT safe. - * - * Since: 0.10.22 */ void gst_message_parse_structure_change (GstMessage * message, @@ -1310,19 +1537,19 @@ gst_message_parse_structure_change (GstMessage * message, * @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 + * 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: - * |[ + * |[ * ... * switch (GST_MESSAGE_TYPE (msg)) { * case GST_MESSAGE_ERROR: { * GError *err = NULL; * gchar *dbg_info = NULL; - * + * * gst_message_parse_error (msg, &err, &dbg_info); * g_printerr ("ERROR from element %s: %s\n", * GST_OBJECT_NAME (msg->src), err->message); @@ -1341,28 +1568,12 @@ gst_message_parse_structure_change (GstMessage * message, void gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug) { - const GValue *error_gvalue; - GError *error_val; - GstStructure *structure; - g_return_if_fail (GST_IS_MESSAGE (message)); g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR); - structure = GST_MESSAGE_STRUCTURE (message); - error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR)); - g_return_if_fail (error_gvalue != NULL); - g_return_if_fail (G_VALUE_TYPE (error_gvalue) == G_TYPE_ERROR); - - error_val = (GError *) g_value_get_boxed (error_gvalue); - if (error_val) - *gerror = g_error_copy (error_val); - else - *gerror = NULL; - - if (debug) - *debug = - g_value_dup_string (gst_structure_id_get_value (structure, - GST_QUARK (DEBUG))); + gst_structure_id_get (GST_MESSAGE_STRUCTURE (message), + GST_QUARK (GERROR), G_TYPE_ERROR, gerror, + GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL); } /** @@ -1370,7 +1581,7 @@ gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug) * @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 + * 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. @@ -1381,28 +1592,12 @@ void gst_message_parse_warning (GstMessage * message, GError ** gerror, gchar ** debug) { - const GValue *error_gvalue; - GError *error_val; - GstStructure *structure; - g_return_if_fail (GST_IS_MESSAGE (message)); g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING); - structure = GST_MESSAGE_STRUCTURE (message); - error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR)); - g_return_if_fail (error_gvalue != NULL); - g_return_if_fail (G_VALUE_TYPE (error_gvalue) == G_TYPE_ERROR); - - error_val = (GError *) g_value_get_boxed (error_gvalue); - if (error_val) - *gerror = g_error_copy (error_val); - else - *gerror = NULL; - - if (debug) - *debug = - g_value_dup_string (gst_structure_id_get_value (structure, - GST_QUARK (DEBUG))); + gst_structure_id_get (GST_MESSAGE_STRUCTURE (message), + GST_QUARK (GERROR), G_TYPE_ERROR, gerror, + GST_QUARK (DEBUG), G_TYPE_STRING, debug, NULL); } /** @@ -1410,47 +1605,29 @@ gst_message_parse_warning (GstMessage * message, GError ** gerror, * @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 + * 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. - * - * Since: 0.10.12 */ void gst_message_parse_info (GstMessage * message, GError ** gerror, gchar ** debug) { - const GValue *error_gvalue; - GError *error_val; - GstStructure *structure; - g_return_if_fail (GST_IS_MESSAGE (message)); g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO); - structure = GST_MESSAGE_STRUCTURE (message); - error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR)); - g_return_if_fail (error_gvalue != NULL); - g_return_if_fail (G_VALUE_TYPE (error_gvalue) == G_TYPE_ERROR); - - error_val = (GError *) g_value_get_boxed (error_gvalue); - if (error_val) - *gerror = g_error_copy (error_val); - else - *gerror = NULL; - - if (debug) - *debug = - g_value_dup_string (gst_structure_id_get_value (structure, - GST_QUARK (DEBUG))); + 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): Result location for the format, or NULL - * @position: (out): Result location for the position, or NULL + * @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. * @@ -1479,10 +1656,10 @@ gst_message_parse_segment_start (GstMessage * message, GstFormat * format, /** * gst_message_parse_segment_done: * @message: A valid #GstMessage of type GST_MESSAGE_SEGMENT_DONE. - * @format: (out): Result location for the format, or NULL - * @position: (out): Result location for the position, or NULL + * @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. + * Extracts the position and format from the segment done message. * * MT safe. */ @@ -1507,49 +1684,16 @@ gst_message_parse_segment_done (GstMessage * message, GstFormat * format, } /** - * gst_message_parse_duration: - * @message: A valid #GstMessage of type GST_MESSAGE_DURATION. - * @format: (out): Result location for the format, or NULL - * @duration: (out): Result location for the duration, or NULL - * - * Extracts the duration and format from the duration message. The duration - * might be GST_CLOCK_TIME_NONE, which indicates that the duration has - * changed. Applications should always use a query to retrieve the duration - * of a pipeline. - * - * MT safe. - */ -void -gst_message_parse_duration (GstMessage * message, GstFormat * format, - gint64 * duration) -{ - GstStructure *structure; - - g_return_if_fail (GST_IS_MESSAGE (message)); - g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION); - - structure = GST_MESSAGE_STRUCTURE (message); - if (format) - *format = (GstFormat) - g_value_get_enum (gst_structure_id_get_value (structure, - GST_QUARK (FORMAT))); - if (duration) - *duration = - g_value_get_int64 (gst_structure_id_get_value (structure, - GST_QUARK (DURATION))); -} - -/** * gst_message_parse_async_done: * @message: A valid #GstMessage of type GST_MESSAGE_ASYNC_DONE. - * @reset_time: (out): Result location for the reset_time or NULL + * @running_time: (out) (allow-none): Result location for the running_time or %NULL * - * Extract the reset_time from the async_done message. + * Extract the running_time from the async_done message. * * MT safe. */ void -gst_message_parse_async_done (GstMessage * message, gboolean * reset_time) +gst_message_parse_async_done (GstMessage * message, GstClockTime * running_time) { GstStructure *structure; @@ -1557,22 +1701,20 @@ gst_message_parse_async_done (GstMessage * message, gboolean * reset_time) g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ASYNC_DONE); structure = GST_MESSAGE_STRUCTURE (message); - if (reset_time) - *reset_time = - g_value_get_boolean (gst_structure_id_get_value (structure, - GST_QUARK (RESET_TIME))); + 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): Result location for the requested state or NULL + * @state: (out) (allow-none): Result location for the requested state or %NULL * * Extract the requested state from the request_state message. * * MT safe. - * - * Since: 0.10.23 */ void gst_message_parse_request_state (GstMessage * message, GstState * state) @@ -1597,12 +1739,10 @@ gst_message_parse_request_state (GstMessage * message, GstState * state) * * 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. - * - * Since: 0.10.24. */ GstMessage * gst_message_new_stream_status (GstObject * src, GstStreamStatusType type, @@ -1630,8 +1770,6 @@ gst_message_new_stream_status (GstObject * src, GstStreamStatusType type, * should thus not be unreffed. * * MT safe. - * - * Since: 0.10.24. */ void gst_message_parse_stream_status (GstMessage * message, @@ -1662,8 +1800,6 @@ gst_message_parse_stream_status (GstMessage * message, * * Configures the object handling the streaming thread. This is usually a * GstTask object but other objects might be added in the future. - * - * Since: 0.10.24 */ void gst_message_set_stream_status_object (GstMessage * message, @@ -1684,11 +1820,10 @@ gst_message_set_stream_status_object (GstMessage * message, * * Extracts the object managing the streaming thread from @message. * - * Returns: a GValue containing the object that manages the streaming thread. - * This object is usually of type GstTask but other types can be added in the - * future. The object remains valid as long as @message is valid. - * - * Since: 0.10.24 + * Returns: (nullable): 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) @@ -1718,7 +1853,7 @@ gst_message_get_stream_status_object (GstMessage * message) * @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. + * 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. @@ -1726,8 +1861,6 @@ gst_message_get_stream_status_object (GstMessage * message) * Returns: (transfer full): the new step_done message. * * MT safe. - * - * Since: 0.10.24 */ GstMessage * gst_message_new_step_done (GstObject * src, GstFormat format, guint64 amount, @@ -1764,8 +1897,6 @@ gst_message_new_step_done (GstObject * src, GstFormat format, guint64 amount, * Extract the values the step_done message. * * MT safe. - * - * Since: 0.10.24 */ void gst_message_parse_step_done (GstMessage * message, GstFormat * format, @@ -1799,21 +1930,19 @@ gst_message_parse_step_done (GstMessage * message, GstFormat * format, * @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. + * event for @amount in @format. * - * @active is set to FALSE when the element accepted the new step event and has + * @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 + * @active is set to %TRUE when the element has activated the step operation and * is now ready to start executing the step in the streaming thread. After this - * message is emited, the application can queue a new step operation in the + * message is emitted, the application can queue a new step operation in the * element. * - * Returns: (transfer full): The new step_start message. + * Returns: (transfer full): The new step_start message. * * MT safe. - * - * Since: 0.10.24 */ GstMessage * gst_message_new_step_start (GstObject * src, gboolean active, GstFormat format, @@ -1847,8 +1976,6 @@ gst_message_new_step_start (GstObject * src, gboolean active, GstFormat format, * Extract the values from step_start message. * * MT safe. - * - * Since: 0.10.24 */ void gst_message_parse_step_start (GstMessage * message, gboolean * active, @@ -1896,8 +2023,6 @@ gst_message_parse_step_start (GstMessage * message, gboolean * active, * Returns: (transfer full): The new qos message. * * MT safe. - * - * Since: 0.10.29 */ GstMessage * gst_message_new_qos (GstObject * src, gboolean live, guint64 running_time, @@ -1935,8 +2060,6 @@ gst_message_new_qos (GstObject * src, gboolean live, guint64 running_time, * Set the QoS values that have been calculated/analysed from the QoS data * * MT safe. - * - * Since: 0.10.29 */ void gst_message_set_qos_values (GstMessage * message, gint64 jitter, @@ -1972,8 +2095,6 @@ gst_message_set_qos_values (GstMessage * message, gint64 jitter, * invalid. Values of -1 for either @processed or @dropped mean unknown values. * * MT safe. - * - * Since: 0.10.29 */ void gst_message_set_qos_stats (GstMessage * message, GstFormat format, @@ -2011,8 +2132,6 @@ gst_message_set_qos_stats (GstMessage * message, GstFormat format, * values. * * MT safe. - * - * Since: 0.10.29 */ void gst_message_parse_qos (GstMessage * message, gboolean * live, @@ -2047,8 +2166,6 @@ gst_message_parse_qos (GstMessage * message, gboolean * live, * Extract the QoS values that have been calculated/analysed from the QoS data * * MT safe. - * - * Since: 0.10.29 */ void gst_message_parse_qos_values (GstMessage * message, gint64 * jitter, @@ -2085,8 +2202,6 @@ gst_message_parse_qos_values (GstMessage * message, gint64 * jitter, * invalid. Values of -1 for either @processed or @dropped mean unknown values. * * MT safe. - * - * Since: 0.10.29 */ void gst_message_parse_qos_stats (GstMessage * message, GstFormat * format, @@ -2115,11 +2230,9 @@ gst_message_parse_qos_stats (GstMessage * message, GstFormat * format, * to perform actions triggered by a state change. * * @code contains a well defined string describing the action. - * @test should contain a user visible string detailing the current action. - * - * Returns: (transfer full): The new qos message. + * @text should contain a user visible string detailing the current action. * - * Since: 0.10.33 + * Returns: (transfer full) (nullable): The new qos message. */ GstMessage * gst_message_new_progress (GstObject * src, GstProgressType type, @@ -2154,8 +2267,6 @@ gst_message_new_progress (GstObject * src, GstProgressType type, * @text: (out) (allow-none) (transfer full): location for the text * * Parses the progress @type, @code and @text. - * - * Since: 0.10.33 */ void gst_message_parse_progress (GstMessage * message, GstProgressType * type, @@ -2176,17 +2287,15 @@ gst_message_parse_progress (GstMessage * message, GstProgressType * type, /** * gst_message_new_toc: * @src: the object originating the message. - * @toc: #GstToc structure for 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: a new TOC message. + * Returns: (transfer full): a new TOC message. * * MT safe. - * - * Since: 0.10.37 */ GstMessage * gst_message_new_toc (GstObject * src, GstToc * toc, gboolean updated) @@ -2195,28 +2304,24 @@ gst_message_new_toc (GstObject * src, GstToc * toc, gboolean updated) g_return_val_if_fail (toc != NULL, NULL); - toc_struct = __gst_toc_to_structure (toc); + 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); - if (G_LIKELY (toc_struct != NULL)) { - __gst_toc_structure_set_updated (toc_struct, updated); - return gst_message_new_custom (GST_MESSAGE_TOC, src, toc_struct); - } else - return 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): return location for the 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_free() when done. + * gst_toc_unref() when done. * * MT safe. - * - * Since: 0.10.37 */ void gst_message_parse_toc (GstMessage * message, GstToc ** toc, gboolean * updated) @@ -2225,9 +2330,939 @@ gst_message_parse_toc (GstMessage * message, GstToc ** toc, gboolean * updated) g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TOC); g_return_if_fail (toc != NULL); - *toc = __gst_toc_from_structure (GST_MESSAGE_STRUCTURE (message)); + 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) (transfer none) (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_device_changed: + * @src: The #GstObject that created the message + * @device: (transfer none): The newly created device representing @replaced_device + * with its new configuration. + * + * Creates a new device-changed message. The device-changed message is produced + * by #GstDeviceProvider or a #GstDeviceMonitor. They announce that a device + * properties has changed and @device represent the new modified version of @changed_device. + * + * Returns: a newly allocated #GstMessage + * + * Since: 1.16 + */ +GstMessage * +gst_message_new_device_changed (GstObject * src, GstDevice * device, + GstDevice * changed_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_CHANGED), + GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, + GST_QUARK (DEVICE_CHANGED), GST_TYPE_DEVICE, changed_device, NULL); + message = gst_message_new_custom (GST_MESSAGE_DEVICE_CHANGED, src, structure); + + return message; +} + +/** + * gst_message_parse_device_changed: + * @message: a #GstMessage of type %GST_MESSAGE_DEVICE_CHANGED + * @device: (out) (allow-none) (transfer full): A location where to store a + * pointer to the updated version of the #GstDevice, or %NULL + * @changed_device: (out) (allow-none) (transfer full): A location where to store a + * pointer to the old version of the #GstDevice, or %NULL + * + * Parses a device-changed message. The device-changed message is produced by + * #GstDeviceProvider or a #GstDeviceMonitor. It announces the + * disappearance of monitored devices. * It announce that a device properties has + * changed and @device represents the new modified version of @changed_device. + * + * Since: 1.16 + */ +void +gst_message_parse_device_changed (GstMessage * message, GstDevice ** device, + GstDevice ** changed_device) +{ + g_return_if_fail (GST_IS_MESSAGE (message)); + g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DEVICE_CHANGED); + + if (device) + gst_structure_id_get (GST_MESSAGE_STRUCTURE (message), + GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL); + + if (changed_device) + gst_structure_id_get (GST_MESSAGE_STRUCTURE (message), + GST_QUARK (DEVICE_CHANGED), GST_TYPE_DEVICE, changed_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) (transfer none) (allow-none): return location for + * the name of the property that got changed, or %NULL + * @property_value: (out) (transfer none) (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) (nullable): 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); - if (updated != NULL) - *updated = - __gst_toc_structure_get_updated (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; }