diff --git a/girs/Gst-1.0.gir b/girs/Gst-1.0.gir index 06e4fcd3b6..4765abc16d 100644 --- a/girs/Gst-1.0.gir +++ b/girs/Gst-1.0.gir @@ -24121,6 +24121,22 @@ MT safe + + Returns the optional details structure of the message. May be NULL if none. + +The returned structure must not be freed. + + + The details, or NULL if none. + + + + + A #GstMessage + + + + @@ -24477,6 +24493,24 @@ The returned structure must not be freed. + + Returns the details structure if present or will create one if not present. +The returned structure must not be freed. + + + + + + + The writable message object + + + + A pointer to the returned details + + + + Extract the group from the STREAM_START message. @@ -24561,6 +24595,24 @@ The returned structure must not be freed. + + Returns the details structure if present or will create one if not present. +The returned structure must not be freed. + + + + + + + The writable message object + + + + A pointer to the returned details + + + + Parses the rate_multiplier from the instant-rate-request message. @@ -25209,6 +25261,24 @@ The returned structure must not be freed. + + Returns the details structure if present or will create one if not present. +The returned structure must not be freed. + + + + + + + The writable message object + + + + A pointer to the returned details + + + + Convenience macro to increase the reference count of the message. @@ -25252,6 +25322,24 @@ The returned structure must not be freed. + + Add @details to @message. Will fail if the message already has details set on +it or if it is not writable. + + + + + + + A #GstMessage + + + + A GstStructure with details + + + + Sets the group id on the stream-start message. @@ -25445,6 +25533,24 @@ freeing it. + + Returns the details structure of the @message. If not present it will be +created. Use this function (instead of gst_message_get_details()) if you +want to write to the @details structure. + +The returned structure must not be freed. + + + The details, or NULL if none. + + + + + A writable #GstMessage + + + + Get a writable version of the structure. diff --git a/subprojects/gstreamer/gst/gstmessage.c b/subprojects/gstreamer/gst/gstmessage.c index f2dd8834a6..37d4050c92 100644 --- a/subprojects/gstreamer/gst/gstmessage.c +++ b/subprojects/gstreamer/gst/gstmessage.c @@ -399,6 +399,138 @@ gst_message_new_eos (GstObject * src) return message; } +/* Internal function for setting details on a message. Checks for valid + * arguments should be done before calling this. + * + * Will create a message structure if it doesn't have one already + **/ +static void +message_set_details (GstMessage * message, GstStructure * details) +{ + GValue v = G_VALUE_INIT; + + if (GST_MESSAGE_STRUCTURE (message) == NULL) { + GQuark message_quark = gst_message_type_to_quark (message->type); + g_return_if_fail (message_quark); + GstStructure *structure = gst_structure_new_id_empty (message_quark); + gst_structure_set_parent_refcount (structure, + &message->mini_object.refcount); + GST_MESSAGE_STRUCTURE (message) = structure; + } + 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); +} + +/** + * gst_message_set_details: + * @message: A #GstMessage + * @details: (transfer full) (nullable): A GstStructure with details + * + * Add @details to @message. Will fail if the message already has details set on + * it or if it is not writable. + * + * Since: 1.26 + */ +void +gst_message_set_details (GstMessage * message, GstStructure * details) +{ + g_return_if_fail (GST_IS_MESSAGE (message)); + g_return_if_fail (gst_message_is_writable (message)); + g_return_if_fail (details); + + if (GST_MESSAGE_STRUCTURE (message) + && gst_structure_id_has_field (GST_MESSAGE_STRUCTURE (message), + details_quark)) { + gst_structure_free (details); + g_critical ("Message already has details"); + return; + } + + message_set_details (message, details); +} + +/* Internal function for parsing details of a message. + * Checks for valid arguments should be done before calling this. + * + * Will create a details structure if create_if_missing is TRUE + */ +static void +message_parse_details (GstMessage * message, GstStructure ** details, + gboolean create_if_missing) +{ + *details = NULL; + + if (GST_MESSAGE_STRUCTURE (message) == NULL && !create_if_missing) + return; + + if (GST_MESSAGE_STRUCTURE (message) && + gst_structure_id_has_field (GST_MESSAGE_STRUCTURE (message), + details_quark)) { + const GValue *v = + gst_structure_id_get_value (GST_MESSAGE_STRUCTURE (message), + details_quark); + if (v && G_VALUE_TYPE (v) == GST_TYPE_STRUCTURE) { + *details = g_value_get_boxed (v); + } + } else if (create_if_missing) { + *details = gst_structure_new_empty ("message-details"); + message_set_details (message, (GstStructure *) * details); + } +} + +/** + * gst_message_get_details: + * @message: A #GstMessage + * + * Returns the optional details structure of the message. May be NULL if none. + * + * The returned structure must not be freed. + * + * Returns: (transfer none) (nullable): The details, or NULL if none. + * + * Since: 1.26 + */ +const GstStructure * +gst_message_get_details (GstMessage * message) +{ + const GstStructure *details; + + g_return_val_if_fail (GST_IS_MESSAGE (message), NULL); + + message_parse_details (message, (GstStructure **) & details, FALSE); + + return details; +} + +/** + * gst_message_writable_details: + * @message: A writable #GstMessage + * + * Returns the details structure of the @message. If not present it will be + * created. Use this function (instead of gst_message_get_details()) if you + * want to write to the @details structure. + * + * The returned structure must not be freed. + * + * Returns: (transfer none) (nullable): The details, or NULL if none. + * + * Since: 1.26 + */ +GstStructure * +gst_message_writable_details (GstMessage * message) +{ + GstStructure *details; + + g_return_val_if_fail (GST_IS_MESSAGE (message), NULL); + g_return_val_if_fail (gst_message_is_writable (message), NULL); + + message_parse_details (message, &details, TRUE); + + return details; +} + /** * gst_message_new_error_with_details: * @src: (transfer none) (nullable): The object originating the message. @@ -433,12 +565,7 @@ gst_message_new_error_with_details (GstObject * src, GError * 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); + message_set_details (message, details); } return message; @@ -479,18 +606,33 @@ 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); - } + message_parse_details (message, (GstStructure **) structure, FALSE); +} + +/** + * gst_message_parse_error_writable_details: + * @message: The writable message object + * @structure: (optional) (nullable) (transfer none) (out): A pointer to the returned details + * + * Returns the details structure if present or will create one if not present. + * The returned structure must not be freed. + * + * Since: 1.26 + */ +void +gst_message_parse_error_writable_details (GstMessage * message, + GstStructure ** structure) +{ + g_return_if_fail (GST_IS_MESSAGE (message)); + g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR); + g_return_if_fail (gst_message_is_writable (message)); + g_return_if_fail (structure != NULL); + + message_parse_details (message, (GstStructure **) structure, TRUE); } /** @@ -525,12 +667,7 @@ gst_message_new_warning_with_details (GstObject * src, GError * 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); + message_set_details (message, details); } return message; @@ -569,18 +706,33 @@ 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); - } + message_parse_details (message, (GstStructure **) structure, FALSE); +} + +/** + * gst_message_parse_warning_writable_details: + * @message: The writable message object + * @structure: (optional) (nullable) (transfer none) (out): A pointer to the returned details + * + * Returns the details structure if present or will create one if not present. + * The returned structure must not be freed. + * + * Since: 1.26 + */ +void +gst_message_parse_warning_writable_details (GstMessage * message, + GstStructure ** structure) +{ + g_return_if_fail (GST_IS_MESSAGE (message)); + g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING); + g_return_if_fail (gst_message_is_writable (message)); + g_return_if_fail (structure != NULL); + + message_parse_details (message, (GstStructure **) structure, TRUE); } /** @@ -615,12 +767,7 @@ gst_message_new_info_with_details (GstObject * src, GError * 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); + message_set_details (message, details); } return message; @@ -659,18 +806,33 @@ 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); - } + message_parse_details (message, (GstStructure **) structure, FALSE); +} + +/** + * gst_message_parse_info_writable_details: + * @message: The writable message object + * @structure: (optional) (nullable) (transfer none) (out): A pointer to the returned details + * + * Returns the details structure if present or will create one if not present. + * The returned structure must not be freed. + * + * Since: 1.26 + */ +void +gst_message_parse_info_writable_details (GstMessage * message, + GstStructure ** structure) +{ + g_return_if_fail (GST_IS_MESSAGE (message)); + g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO); + g_return_if_fail (gst_message_is_writable (message)); + g_return_if_fail (structure != NULL); + + message_parse_details (message, (GstStructure **) structure, TRUE); } /** diff --git a/subprojects/gstreamer/gst/gstmessage.h b/subprojects/gstreamer/gst/gstmessage.h index ea3f49fea6..ddb23d0cd7 100644 --- a/subprojects/gstreamer/gst/gstmessage.h +++ b/subprojects/gstreamer/gst/gstmessage.h @@ -462,6 +462,16 @@ GstStructure * gst_message_writable_structure (GstMessage *message); GST_API gboolean gst_message_has_name (GstMessage *message, const gchar *name); +GST_API +void gst_message_set_details (GstMessage *message, GstStructure *details); + +GST_API +const GstStructure * + gst_message_get_details (GstMessage *message); + +GST_API +GstStructure * gst_message_writable_details (GstMessage *message); + /* identifiers for events and messages */ GST_API @@ -489,6 +499,9 @@ void gst_message_parse_error (GstMessage *message, GError **g GST_API void gst_message_parse_error_details (GstMessage *message, const GstStructure **structure); +GST_API +void gst_message_parse_error_writable_details (GstMessage *message, GstStructure **structure); + /* WARNING */ GST_API @@ -503,6 +516,9 @@ void gst_message_parse_warning (GstMessage *message, GError **g GST_API void gst_message_parse_warning_details (GstMessage *message, const GstStructure **structure); +GST_API +void gst_message_parse_warning_writable_details (GstMessage *message, GstStructure **structure); + /* INFO */ GST_API @@ -517,6 +533,9 @@ void gst_message_parse_info (GstMessage *message, GError **g GST_API void gst_message_parse_info_details (GstMessage *message, const GstStructure **structure); +GST_API +void gst_message_parse_info_writable_details (GstMessage *message, GstStructure **structure); + /* TAG */ GST_API diff --git a/subprojects/gstreamer/tests/check/gst/gstmessage.c b/subprojects/gstreamer/tests/check/gst/gstmessage.c index 88e6cf84d0..e511df2c51 100644 --- a/subprojects/gstreamer/tests/check/gst/gstmessage.c +++ b/subprojects/gstreamer/tests/check/gst/gstmessage.c @@ -85,6 +85,7 @@ GST_START_TEST (test_parsing) gchar *debug; GstStructure *d; const GstStructure *dc; + GstStructure *writable_dc; error = g_error_new (domain, 10, "test error"); fail_if (error == NULL); @@ -115,6 +116,15 @@ GST_START_TEST (test_parsing) G_TYPE_STRING)); fail_unless (gst_structure_get_string (dc, "test-field"), "test-contents"); + /* Check writable variant */ + gst_message_ref (message); + /* Should fail if message is not writable */ + ASSERT_CRITICAL (gst_message_parse_error_writable_details (message, + &writable_dc)); + gst_message_unref (message); + gst_message_parse_error_writable_details (message, &writable_dc); + fail_unless (dc == writable_dc); + gst_message_unref (message); g_error_free (error); g_free (debug); @@ -625,6 +635,54 @@ GST_START_TEST (test_parsing) gst_message_parse_instant_rate_request (message, &rate_multiplier); fail_unless (rate_multiplier == 1.5); + gst_message_unref (message); + } + /* Message details */ + { + GstStructure *details = NULL; + const GstStructure *message_structure = NULL; + + /* create a message without a pre-existing structure */ + message = gst_message_new_eos (NULL); + + details = gst_message_writable_details (message); + fail_unless (details != NULL); + fail_unless (GST_IS_STRUCTURE (details)); + + /* The message (which initially did not have a supporting structure) should + * now has a structure whose name should be the message type name */ + message_structure = gst_message_get_structure (message); + fail_if (message_structure == NULL); + fail_unless_equals_string (gst_structure_get_name (message_structure), + gst_message_type_get_name (GST_MESSAGE_TYPE (message))); + + gst_message_unref (message); + + /* Same thing but when trying to set details */ + message = gst_message_new_eos (NULL); + details = + gst_structure_new ("awesome-details", "something", G_TYPE_INT, 42, + NULL); + gst_message_set_details (message, details); + + details = gst_message_writable_details (message); + fail_unless (details != NULL); + fail_unless (GST_IS_STRUCTURE (details)); + + gst_message_unref (message); + + /* Make sure we can't set details on a message which already has details */ + message = gst_message_new_eos (NULL); + details = + gst_structure_new ("awesome-details", "something", G_TYPE_INT, 42, + NULL); + gst_message_set_details (message, details); + details = NULL; + + details = gst_structure_new_empty ("some-other-details"); + ASSERT_CRITICAL (gst_message_set_details (message, details)); + /* No need to free structure on failures, it will be freed */ + gst_message_unref (message); } }