📄 gstcontroller.c
字号:
* Returns: a #GstControlledProperty object of %NULL if the property is not * being controlled. */static GstControlledProperty *gst_controller_find_controlled_property (GstController * self, const gchar * name){ GstControlledProperty *prop; GList *node; for (node = self->properties; node; node = g_list_next (node)) { prop = node->data; if (!strcmp (prop->name, name)) { return (prop); } } GST_DEBUG ("controller does not (yet) manage property '%s'", name); return (NULL);}/* methods *//** * gst_controller_new_valist: * @object: the object of which some properties should be controlled * @var_args: %NULL terminated list of property names that should be controlled * * Creates a new GstController for the given object's properties * * Returns: the new controller. */GstController *gst_controller_new_valist (GObject * object, va_list var_args){ GstController *self; GstControlledProperty *prop; gboolean ref_existing = TRUE; gchar *name; g_return_val_if_fail (G_IS_OBJECT (object), NULL); GST_INFO ("setting up a new controller"); /* TODO should this method check if the given object implements GstParent and if so instantiate a GstParentController ? BilboEd: This is too specific to be put here, don't we want GstController to be as generic as possible ? Ensonic: So we will have gst_parent_controller_new as well and maybe a convinience function that automatically chooses the right one (how to name it)? GstParent will be in core after all. */ self = g_object_get_qdata (object, __gst_controller_key); /* create GstControlledProperty for each property */ while ((name = va_arg (var_args, gchar *))) { /* test if this property isn't yet controlled */ if (!self || !(prop = gst_controller_find_controlled_property (self, name))) { /* create GstControlledProperty and add to self->propeties List */ if ((prop = gst_controlled_property_new (object, name))) { /* if we don't have a controller object yet, now is the time to create one */ if (!self) { self = g_object_new (GST_TYPE_CONTROLLER, NULL); self->object = g_object_ref (object); /* store the controller */ g_object_set_qdata (object, __gst_controller_key, self); ref_existing = FALSE; } else { /* only want one single _ref(), even for multiple properties */ if (ref_existing) { g_object_ref (self); ref_existing = FALSE; GST_INFO ("returning existing controller"); } } self->properties = g_list_prepend (self->properties, prop); } } else { GST_WARNING ("trying to control property again"); if (ref_existing) { g_object_ref (self); ref_existing = FALSE; } } } va_end (var_args); if (self) GST_INFO ("controller->ref_count=%d", G_OBJECT (self)->ref_count); return (self);}/** * gst_controller_new_list: * @object: the object of which some properties should be controlled * @list: list of property names that should be controlled * * Creates a new GstController for the given object's properties * * Returns: the new controller. */GstController *gst_controller_new_list (GObject * object, GList * list){ GstController *self; GstControlledProperty *prop; gboolean ref_existing = TRUE; gchar *name; GList *node; g_return_val_if_fail (G_IS_OBJECT (object), NULL); GST_INFO ("setting up a new controller"); self = g_object_get_qdata (object, __gst_controller_key); /* create GstControlledProperty for each property */ for (node = list; node; node = g_list_next (node)) { name = (gchar *) node->data; /* test if this property isn't yet controlled */ if (!self || !(prop = gst_controller_find_controlled_property (self, name))) { /* create GstControlledProperty and add to self->propeties List */ if ((prop = gst_controlled_property_new (object, name))) { /* if we don't have a controller object yet, now is the time to create one */ if (!self) { self = g_object_new (GST_TYPE_CONTROLLER, NULL); self->object = g_object_ref (object); /* store the controller */ g_object_set_qdata (object, __gst_controller_key, self); ref_existing = FALSE; } else { /* only want one single _ref(), even for multiple properties */ if (ref_existing) { g_object_ref (self); ref_existing = FALSE; GST_INFO ("returning existing controller"); } } self->properties = g_list_prepend (self->properties, prop); } } else { GST_WARNING ("trying to control property again"); if (ref_existing) { g_object_ref (self); ref_existing = FALSE; } } } if (self) GST_INFO ("controller->ref_count=%d", G_OBJECT (self)->ref_count); return (self);}/** * gst_controller_new: * @object: the object of which some properties should be controlled * @...: %NULL terminated list of property names that should be controlled * * Creates a new GstController for the given object's properties * * Returns: the new controller. */GstController *gst_controller_new (GObject * object, ...){ GstController *self; va_list var_args; g_return_val_if_fail (G_IS_OBJECT (object), NULL); va_start (var_args, object); self = gst_controller_new_valist (object, var_args); va_end (var_args); return (self);}/** * gst_controller_remove_properties_valist: * @self: the controller object from which some properties should be removed * @var_args: %NULL terminated list of property names that should be removed * * Removes the given object properties from the controller * * Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise */gbooleangst_controller_remove_properties_valist (GstController * self, va_list var_args){ gboolean res = TRUE; GstControlledProperty *prop; gchar *name; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); while ((name = va_arg (var_args, gchar *))) { /* find the property in the properties list of the controller, remove and free it */ g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, name))) { self->properties = g_list_remove (self->properties, prop); g_signal_handler_disconnect (self->object, prop->notify_handler_id); gst_controlled_property_free (prop); } else { res = FALSE; } g_mutex_unlock (self->lock); } return (res);}/** * gst_controller_remove_properties_list: * @self: the controller object from which some properties should be removed * @list: #GList of property names that should be removed * * Removes the given object properties from the controller * * Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise */gbooleangst_controller_remove_properties_list (GstController * self, GList * list){ gboolean res = TRUE; GstControlledProperty *prop; gchar *name; GList *tmp; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); for (tmp = list; tmp; tmp = g_list_next (tmp)) { name = (gchar *) tmp->data; /* find the property in the properties list of the controller, remove and free it */ g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, name))) { self->properties = g_list_remove (self->properties, prop); g_signal_handler_disconnect (self->object, prop->notify_handler_id); gst_controlled_property_free (prop); } else { res = FALSE; } g_mutex_unlock (self->lock); } return (res);}/** * gst_controller_remove_properties: * @self: the controller object from which some properties should be removed * @...: %NULL terminated list of property names that should be removed * * Removes the given object properties from the controller * * Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise */gbooleangst_controller_remove_properties (GstController * self, ...){ gboolean res; va_list var_args; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); va_start (var_args, self); res = gst_controller_remove_properties_valist (self, var_args); va_end (var_args); return (res);}/** * gst_controller_set: * @self: the controller object which handles the properties * @property_name: the name of the property to set * @timestamp: the time the control-change is schedules for * @value: the control-value * * Set the value of given controller-handled property at a certain time. * * Returns: FALSE if the values couldn't be set (ex : properties not handled by controller), TRUE otherwise */gbooleangst_controller_set (GstController * self, gchar * property_name, GstClockTime timestamp, GValue * value){ gboolean res = FALSE; GstControlledProperty *prop; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); g_return_val_if_fail (property_name, FALSE); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); g_return_val_if_fail (G_IS_VALUE (value), FALSE); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { if (G_VALUE_TYPE (value) == prop->type) { GstControlPoint *cp; GList *node; /* check if a control point for the timestamp already exists */ if ((node = g_list_find_custom (prop->values, ×tamp, gst_control_point_find))) { cp = node->data; g_value_reset (&cp->value); g_value_copy (value, &cp->value); } else { /* create a new GstControlPoint */ cp = g_new0 (GstControlPoint, 1); cp->timestamp = timestamp; g_value_init (&cp->value, prop->type); g_value_copy (value, &cp->value); /* and sort it into the prop->values list */ prop->values = g_list_insert_sorted (prop->values, cp, gst_control_point_compare); } res = TRUE; } else { GST_WARNING ("incompatible value type for property '%s'", prop->name); } } g_mutex_unlock (self->lock); return (res);}/** * gst_controller_set_from_list: * @self: the controller object which handles the properties * @property_name: the name of the property to set * @timedvalues: a list with #GstTimedValue items * * Sets multiple timed values at once. * * Returns: %FALSE if the values couldn't be set (ex : properties not handled by controller), %TRUE otherwise */gbooleangst_controller_set_from_list (GstController * self, gchar * property_name, GSList * timedvalues){ gboolean res = FALSE; GstControlledProperty *prop; GSList *node; GstTimedValue *tv; GstControlPoint *cp; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); g_return_val_if_fail (property_name, FALSE); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { for (node = timedvalues; node; node = g_slist_next (node)) { tv = node->data; if (G_VALUE_TYPE (&tv->value) == prop->type) { if (GST_CLOCK_TIME_IS_VALID (tv->timestamp)) { cp = g_new0 (GstControlPoint, 1); cp->timestamp = tv->timestamp; g_value_init (&cp->value, prop->type); g_value_copy (&tv->value, &cp->value); prop->values = g_list_insert_sorted (prop->values, cp, gst_control_point_compare); res = TRUE; } else { g_warning ("GstTimedValued with invalid timestamp passed to %s " "for property '%s'", GST_FUNCTION, property_name); } } else { GST_WARNING ("incompatible value type for property '%s'", prop->name); } } } g_mutex_unlock (self->lock); return (res);}/** * gst_controller_unset: * @self: the controller object which handles the properties * @property_name: the name of the property to unset * @timestamp: the time the control-change should be removed from * * Used to remove the value of given controller-handled property at a certain * time. * * Returns: %FALSE if the values couldn't be unset (ex : properties not handled by controller), %TRUE otherwise */gbooleangst_controller_unset (GstController * self, gchar * property_name, GstClockTime timestamp){ gboolean res = FALSE; GstControlledProperty *prop; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); g_return_val_if_fail (property_name, FALSE); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { GList *node; /* check if a control point for the timestamp exists */ if ((node = g_list_find_custom (prop->values, ×tamp, gst_control_point_find))) { if (node == prop->last_requested_value) prop->last_requested_value = NULL; gst_control_point_free (node->data); /* free GstControlPoint */ prop->values = g_list_delete_link (prop->values, node); res = TRUE; } } g_mutex_unlock (self->lock); return (res);}/** * gst_controller_unset_all: * @self: the controller object which handles the properties * @property_name: the name of the property to unset * * Used to remove all time-stamped values of given controller-handled property * * Returns: %FALSE if the values couldn't be unset (ex : properties not handled * by controller), %TRUE otherwise * Since: 0.10.5 */gbooleangst_controller_unset_all (GstController * self, gchar * property_name){ gboolean res = FALSE; GstControlledProperty *prop; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); g_return_val_if_fail (property_name, FALSE); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { /* free GstControlPoint structures */ g_list_foreach (prop->values, (GFunc) gst_control_point_free, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -