1 /* Copyright (C) <2021> Thibault Saunier <tsaunier@igalia.com>
3 * This library is free software; you can redistribute it and/or modify it under the terms of the
4 * GNU Library General Public License as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
8 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 * Library General Public License for more details.
11 * You should have received a copy of the GNU Library General Public License along with this
12 * library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
13 * Boston, MA 02110-1301, USA.
15 #include "gstwpeextension.h"
21 GST_DEBUG_CATEGORY (wpe_bus_msg_forwarder_debug);
22 #define GST_CAT_DEFAULT wpe_bus_msg_forwarder_debug
24 struct _GstWpeBusMsgForwarder
27 GCancellable *cancellable;
30 G_DEFINE_TYPE_WITH_CODE (GstWpeBusMsgForwarder, gst_wpe_bus_msg_forwarder,
31 GST_TYPE_TRACER, GST_DEBUG_CATEGORY_INIT (wpe_bus_msg_forwarder_debug,
32 "wpebusmsgforwarder", 0, "WPE message forwarder"););
35 dispose (GObject * object)
37 GstWpeBusMsgForwarder *self = GST_WPE_BUS_MSG_FORWARDER (object);
39 g_clear_object (&self->cancellable);
42 static WebKitUserMessage *
43 create_gerror_bus_msg (GstElement * element, GstMessage * message)
46 gchar *debug_str, *details_structure, *src_path;
47 WebKitUserMessage *msg;
48 const GstStructure *details = NULL;
50 if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
51 gst_message_parse_error (message, &error, &debug_str);
52 gst_message_parse_error_details (message, &details);
53 } else if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING) {
54 gst_message_parse_warning (message, &error, &debug_str);
55 gst_message_parse_warning_details (message, &details);
57 gst_message_parse_info (message, &error, &debug_str);
58 gst_message_parse_info_details (message, &details);
62 details ? gst_structure_to_string (details) : g_strdup ("");
63 src_path = gst_object_get_path_string (GST_MESSAGE_SRC (message));
65 msg = webkit_user_message_new ("gstwpe.bus_gerror_message",
66 /* (message_type, src_path, error_domain, error_code, msg, debug_str, details_structure) */
67 g_variant_new ("(issssusss)",
68 GST_MESSAGE_TYPE (message),
69 GST_MESSAGE_SRC_NAME (message),
70 G_OBJECT_TYPE_NAME (GST_MESSAGE_SRC (message)),
72 g_quark_to_string (error->domain),
73 error->code, error->message, debug_str, details_structure)
80 /* Those types can't be deserialized on the receiver
81 * side, so we just ignore them for now */
82 #define IS_NOT_DESERIALIZABLE_TYPE(value) \
83 (g_type_is_a ((G_VALUE_TYPE (value)), G_TYPE_OBJECT) || \
84 g_type_is_a ((G_VALUE_TYPE (value)), G_TYPE_ERROR) || \
85 g_type_is_a ((G_VALUE_TYPE (value)), GST_TYPE_CONTEXT) || \
86 g_type_is_a ((G_VALUE_TYPE (value)), G_TYPE_POINTER))
89 cleanup_structure (GQuark field_id, GValue * value, gpointer self)
91 /* We need soome API in core to make that happen cleanly */
92 if (IS_NOT_DESERIALIZABLE_TYPE (value)) {
96 if (GST_VALUE_HOLDS_LIST (value)) {
99 for (i = 0; i < gst_value_list_get_size (value); i++) {
100 if (IS_NOT_DESERIALIZABLE_TYPE (gst_value_list_get_value (value, i)))
105 if (GST_VALUE_HOLDS_ARRAY (value)) {
108 for (i = 0; i < gst_value_array_get_size (value); i++) {
109 if (IS_NOT_DESERIALIZABLE_TYPE (gst_value_array_get_value (value, i)))
118 gst_message_post_cb (GObject * object, GstClockTime ts, GstElement * element,
119 GstMessage * message)
122 WebKitUserMessage *msg = NULL;
123 GstStructure *structure;
124 GstWpeBusMsgForwarder *self;
125 const GstStructure *message_struct;
127 if (!GST_IS_PIPELINE (element))
130 self = GST_WPE_BUS_MSG_FORWARDER (object);
131 message_struct = gst_message_get_structure (message);
132 structure = message_struct ? gst_structure_copy (message_struct) : NULL;
135 gst_structure_filter_and_map_in_place (structure, cleanup_structure, self);
136 str = gst_structure_to_string (structure);
141 /* we special case error as gst can't serialize/de-serialize it */
142 if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR
143 || GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING
144 || GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO) {
145 msg = create_gerror_bus_msg (element, message);
147 gchar *src_path = gst_object_get_path_string (GST_MESSAGE_SRC (message));
148 msg = webkit_user_message_new ("gstwpe.bus_message",
149 g_variant_new ("(issss)",
150 GST_MESSAGE_TYPE (message),
151 GST_MESSAGE_SRC_NAME (message),
152 G_OBJECT_TYPE_NAME (GST_MESSAGE_SRC (message)), src_path, str));
156 gst_wpe_extension_send_message (msg, self->cancellable, NULL, NULL);
161 constructed (GObject * object)
163 GstTracer *tracer = GST_TRACER (object);
164 gst_tracing_register_hook (tracer, "element-post-message-pre",
165 G_CALLBACK (gst_message_post_cb));
169 gst_wpe_bus_msg_forwarder_init (GstWpeBusMsgForwarder * self)
171 self->cancellable = g_cancellable_new ();
175 gst_wpe_bus_msg_forwarder_class_init (GstWpeBusMsgForwarderClass * klass)
177 GObjectClass *object_class = G_OBJECT_CLASS (klass);
179 object_class->dispose = dispose;
180 object_class->constructed = constructed;