mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 07:42:23 +02:00
clapper: Add "message" signal to the player
A detailed signal that allows for applications to receive element messages posted on the pipeline bus. Useful if app cares about some custom message that player normally does not handle. For example audio player might want to read "level" messages in order to show current audio level or implement visualizations.
This commit is contained in:
@@ -52,6 +52,8 @@ void clapper_app_bus_post_object_desc_signal (ClapperAppBus *app_bus, GstObject
|
||||
|
||||
void clapper_app_bus_post_desc_with_details_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, const gchar *desc, const gchar *details);
|
||||
|
||||
void clapper_app_bus_post_message_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GstMessage *msg);
|
||||
|
||||
void clapper_app_bus_post_error_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GError *error, const gchar *debug_info);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -46,6 +46,7 @@ enum
|
||||
CLAPPER_APP_BUS_STRUCTURE_SIMPLE_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_OBJECT_DESC_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_DESC_WITH_DETAILS_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_MESSAGE_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_ERROR_SIGNAL
|
||||
};
|
||||
|
||||
@@ -58,6 +59,7 @@ static ClapperBusQuark _structure_quarks[] = {
|
||||
{"simple-signal", 0},
|
||||
{"object-desc-signal", 0},
|
||||
{"desc-with-details-signal", 0},
|
||||
{"message", 0},
|
||||
{"error-signal", 0},
|
||||
{NULL, 0}
|
||||
};
|
||||
@@ -276,6 +278,53 @@ _handle_desc_with_details_signal_msg (GstMessage *msg, const GstStructure *struc
|
||||
g_free (details);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_bus_post_message_signal (ClapperAppBus *self,
|
||||
GstObject *src, guint signal_id, GstMessage *msg)
|
||||
{
|
||||
/* Check for any "message" signal connection */
|
||||
if (g_signal_handler_find (src, G_SIGNAL_MATCH_ID,
|
||||
signal_id, 0, NULL, NULL, NULL) != 0) {
|
||||
const GstStructure *structure = gst_message_get_structure (msg);
|
||||
GQuark detail;
|
||||
|
||||
if (G_UNLIKELY (structure == NULL))
|
||||
return;
|
||||
|
||||
detail = g_quark_from_string (gst_structure_get_name (structure));
|
||||
|
||||
/* If specific detail is connected or ALL "message" handler */
|
||||
if (g_signal_handler_find (src, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL,
|
||||
signal_id, detail, NULL, NULL, NULL) != 0
|
||||
|| g_signal_handler_find (src, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL,
|
||||
signal_id, 0, NULL, NULL, NULL) != 0) {
|
||||
GstStructure *structure = gst_structure_new_id (_STRUCTURE_QUARK (MESSAGE_SIGNAL),
|
||||
_FIELD_QUARK (SIGNAL_ID), G_TYPE_UINT, signal_id,
|
||||
_FIELD_QUARK (DETAILS), G_TYPE_UINT, detail,
|
||||
_FIELD_QUARK (OBJECT), GST_TYPE_MESSAGE, msg,
|
||||
NULL);
|
||||
gst_bus_post (GST_BUS_CAST (self), gst_message_new_application (src, structure));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_handle_message_signal_msg (GstMessage *msg, const GstStructure *structure)
|
||||
{
|
||||
guint signal_id = 0;
|
||||
GQuark detail = 0;
|
||||
GstMessage *fwd_message = NULL;
|
||||
|
||||
gst_structure_id_get (structure,
|
||||
_FIELD_QUARK (SIGNAL_ID), G_TYPE_UINT, &signal_id,
|
||||
_FIELD_QUARK (DETAILS), G_TYPE_UINT, &detail,
|
||||
_FIELD_QUARK (OBJECT), GST_TYPE_MESSAGE, &fwd_message,
|
||||
NULL);
|
||||
g_signal_emit (_MESSAGE_SRC_GOBJECT (msg), signal_id, detail, fwd_message);
|
||||
|
||||
gst_message_unref (fwd_message);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_bus_post_error_signal (ClapperAppBus *self,
|
||||
GstObject *src, guint signal_id,
|
||||
@@ -326,6 +375,8 @@ clapper_app_bus_message_func (GstBus *bus, GstMessage *msg, gpointer user_data G
|
||||
_handle_simple_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (OBJECT_DESC_SIGNAL))
|
||||
_handle_object_desc_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (MESSAGE_SIGNAL))
|
||||
_handle_message_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (ERROR_SIGNAL))
|
||||
_handle_error_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (DESC_WITH_DETAILS_SIGNAL))
|
||||
|
@@ -930,6 +930,11 @@ _handle_element_msg (GstMessage *msg, ClapperPlayer *player)
|
||||
GST_OBJECT_CAST (downloaded_item), location);
|
||||
|
||||
gst_object_unref (downloaded_item);
|
||||
} else {
|
||||
guint signal_id = g_signal_lookup ("message", CLAPPER_TYPE_PLAYER);
|
||||
|
||||
clapper_app_bus_post_message_signal (player->app_bus,
|
||||
GST_OBJECT_CAST (player), signal_id, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -111,6 +111,7 @@ enum
|
||||
SIGNAL_SEEK_DONE,
|
||||
SIGNAL_DOWNLOAD_COMPLETE,
|
||||
SIGNAL_MISSING_PLUGIN,
|
||||
SIGNAL_MESSAGE,
|
||||
SIGNAL_WARNING,
|
||||
SIGNAL_ERROR,
|
||||
SIGNAL_LAST
|
||||
@@ -2985,6 +2986,28 @@ clapper_player_class_init (ClapperPlayerClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
|
||||
|
||||
/**
|
||||
* ClapperPlayer::message:
|
||||
* @player: a #ClapperPlayer
|
||||
* @msg: a #GstMessage
|
||||
*
|
||||
* Allows for applications to receive element messages posted
|
||||
* on the underlaying pipeline bus.
|
||||
*
|
||||
* This is a detailed signal. Connect to it via `message::name`
|
||||
* to only receive messages with a certain `name`.
|
||||
*
|
||||
* Player will only forward messages to the main app thread (from which
|
||||
* this signal is emitted) that have a matching signal handler, thus
|
||||
* it is more efficient to listen only for specific messages instead
|
||||
* of connecting to simply `message` with no details (without message name).
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
signals[SIGNAL_MESSAGE] = g_signal_new ("message", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
|
||||
|
||||
/**
|
||||
* ClapperPlayer::warning:
|
||||
* @player: a #ClapperPlayer
|
||||
|
Reference in New Issue
Block a user