mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 07:42:23 +02:00
clapper: Add ability to enable/disable creation of given enhancer
Allow apps to enable or disable given enhancer instances from being created. Also as a safely measure, by default only enable enhancers that work on-demand (extractables) and disable others (reactables).
This commit is contained in:
@@ -86,6 +86,8 @@ struct _ClapperEnhancerProxy
|
||||
ClapperEnhancerParamFlags scope;
|
||||
GstStructure *local_config;
|
||||
|
||||
gboolean allowed;
|
||||
|
||||
/* GSettings are not thread-safe,
|
||||
* so store schema instead */
|
||||
GSettingsSchema *schema;
|
||||
@@ -100,6 +102,7 @@ enum
|
||||
PROP_MODULE_DIR,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_VERSION,
|
||||
PROP_TARGET_CREATION_ALLOWED,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@@ -229,6 +232,8 @@ clapper_enhancer_proxy_copy (ClapperEnhancerProxy *src_proxy, const gchar *copy_
|
||||
if (src_proxy->local_config)
|
||||
copy->local_config = gst_structure_copy (src_proxy->local_config);
|
||||
|
||||
copy->allowed = src_proxy->allowed;
|
||||
|
||||
GST_OBJECT_UNLOCK (src_proxy);
|
||||
|
||||
gst_object_ref_sink (copy);
|
||||
@@ -359,6 +364,8 @@ clapper_enhancer_proxy_fill_from_cache (ClapperEnhancerProxy *self)
|
||||
if (G_UNLIKELY ((self->ifaces[i] = clapper_cache_read_iface (&data)) == 0))
|
||||
goto abort_reading;
|
||||
}
|
||||
/* Reactable type is always last */
|
||||
self->allowed = (self->ifaces[self->n_ifaces - 1] != CLAPPER_TYPE_REACTABLE);
|
||||
}
|
||||
|
||||
/* Restore ParamSpecs */
|
||||
@@ -456,6 +463,7 @@ clapper_enhancer_proxy_export_to_cache (ClapperEnhancerProxy *self)
|
||||
gboolean
|
||||
clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *self, GObject *enhancer)
|
||||
{
|
||||
/* NOTE: REACTABLE must be last for "allowed" to work as expected */
|
||||
const GType enhancer_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_REACTABLE };
|
||||
GType *ifaces;
|
||||
GParamSpec **pspecs;
|
||||
@@ -465,9 +473,12 @@ clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *self, GObject *
|
||||
/* Filter to only Clapper interfaces */
|
||||
ifaces = g_type_interfaces (G_OBJECT_TYPE (enhancer), &n);
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < G_N_ELEMENTS (enhancer_types); ++j) {
|
||||
const guint n_types = G_N_ELEMENTS (enhancer_types);
|
||||
|
||||
for (j = 0; j < n_types; ++j) {
|
||||
if (ifaces[i] == enhancer_types[j]) {
|
||||
ifaces[write_index++] = ifaces[i];
|
||||
self->allowed = (j < n_types - 1);
|
||||
break; // match found, do next iface
|
||||
}
|
||||
}
|
||||
@@ -1088,6 +1099,58 @@ clapper_enhancer_proxy_set_locally_with_table (ClapperEnhancerProxy *self, GHash
|
||||
gst_structure_free (structure);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_enhancer_proxy_set_target_creation_allowed:
|
||||
* @proxy: a #ClapperEnhancerProxy
|
||||
* @allowed: whether allowed
|
||||
*
|
||||
* Set whether to allow instances of proxy target to be created.
|
||||
*
|
||||
* See [property@Clapper.EnhancerProxy:target-creation-allowed] for
|
||||
* detailed descripton what this does.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
void
|
||||
clapper_enhancer_proxy_set_target_creation_allowed (ClapperEnhancerProxy *self, gboolean allowed)
|
||||
{
|
||||
gboolean changed;
|
||||
|
||||
g_return_if_fail (CLAPPER_IS_ENHANCER_PROXY (self));
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
if ((changed = self->allowed != allowed))
|
||||
self->allowed = allowed;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
if (changed)
|
||||
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_TARGET_CREATION_ALLOWED]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_enhancer_proxy_get_target_creation_allowed:
|
||||
* @proxy: a #ClapperEnhancerProxy
|
||||
*
|
||||
* Get whether it is allowed to create instances of enhancer that this proxy targets.
|
||||
*
|
||||
* Returns: whether target creation is allowed.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
gboolean
|
||||
clapper_enhancer_proxy_get_target_creation_allowed (ClapperEnhancerProxy *self)
|
||||
{
|
||||
gboolean allowed;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_IS_ENHANCER_PROXY (self), FALSE);
|
||||
|
||||
GST_OBJECT_LOCK (self);
|
||||
allowed = self->allowed;
|
||||
GST_OBJECT_UNLOCK (self);
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_proxy_init (ClapperEnhancerProxy *self)
|
||||
{
|
||||
@@ -1137,6 +1200,25 @@ clapper_enhancer_proxy_get_property (GObject *object, guint prop_id,
|
||||
case PROP_VERSION:
|
||||
g_value_set_string (value, clapper_enhancer_proxy_get_version (self));
|
||||
break;
|
||||
case PROP_TARGET_CREATION_ALLOWED:
|
||||
g_value_set_boolean (value, clapper_enhancer_proxy_get_target_creation_allowed (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_proxy_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperEnhancerProxy *self = CLAPPER_ENHANCER_PROXY_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_TARGET_CREATION_ALLOWED:
|
||||
clapper_enhancer_proxy_set_target_creation_allowed (self, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -1152,6 +1234,7 @@ clapper_enhancer_proxy_class_init (ClapperEnhancerProxyClass *klass)
|
||||
"Clapper Enhancer Proxy");
|
||||
|
||||
gobject_class->get_property = clapper_enhancer_proxy_get_property;
|
||||
gobject_class->set_property = clapper_enhancer_proxy_set_property;
|
||||
gobject_class->finalize = clapper_enhancer_proxy_finalize;
|
||||
|
||||
/**
|
||||
@@ -1209,5 +1292,29 @@ clapper_enhancer_proxy_class_init (ClapperEnhancerProxyClass *klass)
|
||||
NULL, NULL, NULL,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperEnhancerProxy:target-creation-allowed:
|
||||
*
|
||||
* Whether to allow instances of proxy target to be created.
|
||||
*
|
||||
* This effectively means whether the given enhancer can be used.
|
||||
*
|
||||
* By default all enhancers that work on-demand such as [iface@Clapper.Extractable]
|
||||
* are allowed while enhancers implementing [iface@Clapper.Reactable] are not.
|
||||
*
|
||||
* Value of this property from a `GLOBAL` [class@Clapper.EnhancerProxyList] will carry
|
||||
* over to all newly created [class@Clapper.Player] objects, while altering this on
|
||||
* `LOCAL` proxy list will only influence given player instance that list belongs to.
|
||||
*
|
||||
* Changing this property will not remove already created enhancer instances, thus
|
||||
* it is usually best practice to allow/disallow creation of given enhancer plugin
|
||||
* right after [class@Clapper.Player] is created (before it or its queue are used).
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
param_specs[PROP_TARGET_CREATION_ALLOWED] = g_param_spec_boolean ("target-creation-allowed",
|
||||
NULL, NULL, FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||
}
|
||||
|
@@ -76,4 +76,10 @@ void clapper_enhancer_proxy_set_locally (ClapperEnhancerProxy *proxy, const gcha
|
||||
CLAPPER_API
|
||||
void clapper_enhancer_proxy_set_locally_with_table (ClapperEnhancerProxy *proxy, GHashTable *table);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_enhancer_proxy_set_target_creation_allowed (ClapperEnhancerProxy *proxy, gboolean allowed);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_enhancer_proxy_get_target_creation_allowed (ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -54,6 +54,28 @@ _import_enhancers (const gchar *enhancers_path)
|
||||
g_strfreev (dir_paths);
|
||||
}
|
||||
|
||||
static GObject *
|
||||
_force_create_enhancer (ClapperEnhancerProxy *proxy, GType iface_type)
|
||||
{
|
||||
GObject *enhancer = NULL;
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) clapper_enhancer_proxy_get_peas_info (proxy);
|
||||
|
||||
g_mutex_lock (&load_lock);
|
||||
|
||||
if (!peas_plugin_info_is_loaded (info) && !peas_engine_load_plugin (_engine, info)) {
|
||||
GST_ERROR ("Could not load enhancer: %s", peas_plugin_info_get_module_name (info));
|
||||
} else if (!peas_engine_provides_extension (_engine, info, iface_type)) {
|
||||
GST_LOG ("No \"%s\" enhancer in module: %s", g_type_name (iface_type),
|
||||
peas_plugin_info_get_module_name (info));
|
||||
} else {
|
||||
enhancer = peas_engine_create_extension (_engine, info, iface_type, NULL);
|
||||
}
|
||||
|
||||
g_mutex_unlock (&load_lock);
|
||||
|
||||
return enhancer;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_initialize:
|
||||
*
|
||||
@@ -155,7 +177,7 @@ clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies)
|
||||
|
||||
/* We cannot ask libpeas for "any" of our main interfaces, so try each one until found */
|
||||
for (j = 0; j < G_N_ELEMENTS (main_types); ++j) {
|
||||
if ((enhancer = clapper_enhancers_loader_create_enhancer (proxy, main_types[j]))) {
|
||||
if ((enhancer = _force_create_enhancer (proxy, main_types[j]))) {
|
||||
filled = clapper_enhancer_proxy_fill_from_instance (proxy, enhancer);
|
||||
g_object_unref (enhancer);
|
||||
|
||||
@@ -200,21 +222,8 @@ clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies)
|
||||
GObject *
|
||||
clapper_enhancers_loader_create_enhancer (ClapperEnhancerProxy *proxy, GType iface_type)
|
||||
{
|
||||
GObject *enhancer = NULL;
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) clapper_enhancer_proxy_get_peas_info (proxy);
|
||||
if (!clapper_enhancer_proxy_get_target_creation_allowed (proxy))
|
||||
return NULL;
|
||||
|
||||
g_mutex_lock (&load_lock);
|
||||
|
||||
if (!peas_plugin_info_is_loaded (info) && !peas_engine_load_plugin (_engine, info)) {
|
||||
GST_ERROR ("Could not load enhancer: %s", peas_plugin_info_get_module_name (info));
|
||||
} else if (!peas_engine_provides_extension (_engine, info, iface_type)) {
|
||||
GST_LOG ("No \"%s\" enhancer in module: %s", g_type_name (iface_type),
|
||||
peas_plugin_info_get_module_name (info));
|
||||
} else {
|
||||
enhancer = peas_engine_create_extension (_engine, info, iface_type, NULL);
|
||||
}
|
||||
|
||||
g_mutex_unlock (&load_lock);
|
||||
|
||||
return enhancer;
|
||||
return _force_create_enhancer (proxy, iface_type);
|
||||
}
|
||||
|
@@ -2339,8 +2339,6 @@ clapper_player_init (ClapperPlayer *self)
|
||||
if (clapper_enhancer_proxy_list_has_proxy_with_interface (self->enhancer_proxies, CLAPPER_TYPE_REACTABLE)) {
|
||||
self->reactables_manager = clapper_reactables_manager_new ();
|
||||
gst_object_set_parent (GST_OBJECT_CAST (self->reactables_manager), GST_OBJECT_CAST (self));
|
||||
|
||||
clapper_reactables_manager_trigger_prepare (self->reactables_manager);
|
||||
}
|
||||
|
||||
self->position_query = gst_query_new_position (GST_FORMAT_TIME);
|
||||
|
@@ -36,9 +36,6 @@ void clapper_reactables_manager_initialize (void);
|
||||
G_GNUC_INTERNAL
|
||||
ClapperReactablesManager * clapper_reactables_manager_new (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_reactables_manager_trigger_prepare (ClapperReactablesManager *manager);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_reactables_manager_trigger_configure_take_config (ClapperReactablesManager *manager, ClapperEnhancerProxy *proxy, GstStructure *config);
|
||||
|
||||
|
@@ -43,6 +43,8 @@ struct _ClapperReactablesManager
|
||||
|
||||
GstBus *bus;
|
||||
GPtrArray *array;
|
||||
|
||||
gboolean prepare_called;
|
||||
};
|
||||
|
||||
#define parent_class clapper_reactables_manager_parent_class
|
||||
@@ -74,15 +76,13 @@ enum
|
||||
|
||||
enum
|
||||
{
|
||||
CLAPPER_REACTABLES_MANAGER_QUARK_PREPARE = 0,
|
||||
CLAPPER_REACTABLES_MANAGER_QUARK_CONFIGURE,
|
||||
CLAPPER_REACTABLES_MANAGER_QUARK_CONFIGURE = 0,
|
||||
CLAPPER_REACTABLES_MANAGER_QUARK_EVENT,
|
||||
CLAPPER_REACTABLES_MANAGER_QUARK_VALUE,
|
||||
CLAPPER_REACTABLES_MANAGER_QUARK_EXTRA_VALUE
|
||||
};
|
||||
|
||||
static ClapperBusQuark _quarks[] = {
|
||||
{"prepare", 0},
|
||||
{"configure", 0},
|
||||
{"event", 0},
|
||||
{"value", 0},
|
||||
@@ -161,7 +161,7 @@ clapper_reactables_manager_handle_prepare (ClapperReactablesManager *self)
|
||||
clapper_enhancers_loader_create_enhancer (proxy, CLAPPER_TYPE_REACTABLE));
|
||||
#endif
|
||||
|
||||
if (G_LIKELY (reactable != NULL)) {
|
||||
if (reactable) {
|
||||
ClapperReactableManagerData *data;
|
||||
GstStructure *config;
|
||||
|
||||
@@ -216,11 +216,9 @@ clapper_reactables_manager_handle_configure (ClapperReactablesManager *self, con
|
||||
if (data->proxy == proxy) {
|
||||
clapper_enhancer_proxy_apply_config_to_enhancer (data->proxy,
|
||||
config, (GObject *) data->reactable);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GST_ERROR_OBJECT (self, "Triggered configure, but no matching enhancer proxy found");
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -319,9 +317,11 @@ _bus_message_func (GstBus *bus, GstMessage *msg, gpointer user_data G_GNUC_UNUSE
|
||||
GQuark quark = gst_structure_get_name_id (structure);
|
||||
|
||||
if (quark == _QUARK (EVENT)) {
|
||||
if (G_UNLIKELY (!self->prepare_called)) {
|
||||
clapper_reactables_manager_handle_prepare (self);
|
||||
self->prepare_called = TRUE;
|
||||
}
|
||||
clapper_reactables_manager_handle_event (self, structure);
|
||||
} else if (quark == _QUARK (PREPARE)) {
|
||||
clapper_reactables_manager_handle_prepare (self);
|
||||
} else if (quark == _QUARK (CONFIGURE)) {
|
||||
clapper_reactables_manager_handle_configure (self, structure);
|
||||
} else {
|
||||
@@ -365,15 +365,6 @@ clapper_reactables_manager_new (void)
|
||||
return reactables_manager;
|
||||
}
|
||||
|
||||
void
|
||||
clapper_reactables_manager_trigger_prepare (ClapperReactablesManager *self)
|
||||
{
|
||||
GstStructure *structure = gst_structure_new_id_empty (_QUARK (PREPARE));
|
||||
|
||||
gst_bus_post (self->bus, gst_message_new_application (
|
||||
GST_OBJECT_CAST (self), structure));
|
||||
}
|
||||
|
||||
void
|
||||
clapper_reactables_manager_trigger_configure_take_config (ClapperReactablesManager *self,
|
||||
ClapperEnhancerProxy *proxy, GstStructure *config)
|
||||
|
@@ -93,7 +93,7 @@ clapper_enhancer_director_extract_in_thread (ClapperEnhancerDirectorData *data)
|
||||
clapper_enhancers_loader_create_enhancer (proxy, CLAPPER_TYPE_EXTRACTABLE));
|
||||
#endif
|
||||
|
||||
if (G_LIKELY (extractable != NULL)) {
|
||||
if (extractable) {
|
||||
if (config)
|
||||
clapper_enhancer_proxy_apply_config_to_enhancer (proxy, config, (GObject *) extractable);
|
||||
|
||||
|
Reference in New Issue
Block a user