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);
}
}