/** * gst_controller_get_value_array: * @self: the controller that handles the values * @timestamp: the time that should be processed * @value_array: array to put control-values in * * Function to be able to get an array of values for one element property. * * All fields of @value_array must be filled correctly. Especially the * @value_array->values array must be big enough to keep the requested amount * of values. * * The type of the values in the array is the same as the property's type. * * <note><para>This doesn't modify the controlled GObject property!</para></note> * * Returns: %TRUE if the given array could be filled, %FALSE otherwise */ gboolean gst_controller_get_value_array (GstController * self, GstClockTime timestamp, GstValueArray * value_array) { gboolean res = FALSE; GstControlledProperty *prop; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); g_return_val_if_fail (value_array, FALSE); g_return_val_if_fail (value_array->property_name, FALSE); g_return_val_if_fail (value_array->values, FALSE); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, value_array->property_name))) { /* get current value_array via control source */ if (!prop->csource) goto out; res = gst_control_source_get_value_array (prop->csource, timestamp, value_array); } out: 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 */ gboolean gst_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_get: * @self: the controller object which handles the properties * @property_name: the name of the property to get * @timestamp: the time the control-change should be read from * * Gets the value for the given controller-handled property at the requested * time. * * Returns: the GValue of the property at the given time, or %NULL if the * property isn't handled by the controller */ GValue * gst_controller_get (GstController * self, gchar * property_name, GstClockTime timestamp) { GstControlledProperty *prop; GValue *val = NULL; g_return_val_if_fail (GST_IS_CONTROLLER (self), NULL); g_return_val_if_fail (property_name, NULL); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { val = g_new0 (GValue, 1); g_value_init (val, G_PARAM_SPEC_VALUE_TYPE (prop->pspec)); if (prop->csource) { gboolean res; /* get current value via control source */ res = gst_control_source_get_value (prop->csource, timestamp, val); if (!res) { g_free (val); val = NULL; } } else { g_object_get_property (self->object, prop->name, val); } } g_mutex_unlock (self->lock); return val; }
gboolean gst_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))) { if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource)) goto out; res = gst_interpolation_control_source_unset (GST_INTERPOLATION_CONTROL_SOURCE (prop->csource), timestamp); } out: g_mutex_unlock (self->lock); return res; }
gboolean gst_controller_set_from_list (GstController * self, gchar * property_name, GSList * timedvalues) { 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))) { /* FIXME: backward compat, add GstInterpolationControlSource */ if (!prop->csource) gst_controlled_property_add_interpolation_control_source (prop); if (!GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource)) goto out; res = gst_interpolation_control_source_set_from_list (GST_INTERPOLATION_CONTROL_SOURCE (prop->csource), timedvalues); } out: g_mutex_unlock (self->lock); return res; }
EXPORT_C #endif gboolean gst_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; }
EXPORT_C #endif const GList * gst_controller_get_all (GstController * self, gchar * property_name) { const GList *res = NULL; GstControlledProperty *prop; g_return_val_if_fail (GST_IS_CONTROLLER (self), NULL); g_return_val_if_fail (property_name, NULL); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource)) goto out; res = gst_interpolation_control_source_get_all (GST_INTERPOLATION_CONTROL_SOURCE (prop->csource)); } out: g_mutex_unlock (self->lock); return res; }
EXPORT_C #endif gboolean gst_controller_sync_values (GstController * self, GstClockTime timestamp) { GstControlledProperty *prop; GList *node; gboolean ret = TRUE, val_ret; GValue value = { 0, }; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); GST_LOG ("sync_values"); g_mutex_lock (self->lock); g_object_freeze_notify (self->object); /* go over the controlled properties of the controller */ for (node = self->properties; node; node = g_list_next (node)) { prop = node->data; if (!prop->csource || prop->disabled) continue; GST_LOG ("property '%s' at ts=%" G_GUINT64_FORMAT, prop->name, timestamp); /* we can make this faster * http://bugzilla.gnome.org/show_bug.cgi?id=536939 */ g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (prop->pspec)); val_ret = gst_control_source_get_value (prop->csource, timestamp, &value); if (G_LIKELY (val_ret)) { /* always set the value for first time, but then only if it changed * this should limit g_object_notify invocations. * FIXME: can we detect negative playback rates? */ if ((timestamp < self->priv->last_sync) || gst_value_compare (&value, &prop->last_value) != GST_VALUE_EQUAL) { g_object_set_property (self->object, prop->name, &value); g_value_copy (&value, &prop->last_value); } } else { GST_DEBUG ("no control value for param %s", prop->name); } g_value_unset (&value); ret &= val_ret; } self->priv->last_sync = timestamp; g_object_thaw_notify (self->object); g_mutex_unlock (self->lock); return ret; }
/** * 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 */ gboolean gst_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; }
void gst_controller_set_disabled (GstController * self, gboolean disabled) { GList *node; GstControlledProperty *prop; g_return_if_fail (GST_IS_CONTROLLER (self)); g_mutex_lock (self->lock); for (node = self->properties; node; node = node->next) { prop = node->data; prop->disabled = disabled; } g_mutex_unlock (self->lock); }
void gst_controller_set_property_disabled (GstController * self, gchar * property_name, gboolean disabled) { GstControlledProperty *prop; g_return_if_fail (GST_IS_CONTROLLER (self)); g_return_if_fail (property_name); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { prop->disabled = disabled; } g_mutex_unlock (self->lock); }
/** * gst_controller_get_value_arrays: * @self: the controller that handles the values * @timestamp: the time that should be processed * @value_arrays: list to return the control-values in * * Function to be able to get an array of values for one or more given element * properties. * * All fields of the %GstValueArray in the list must be filled correctly. * Especially the GstValueArray->values arrays must be big enough to keep * the requested amount of values. * * The types of the values in the array are the same as the property's type. * * <note><para>This doesn't modify the controlled GObject properties!</para></note> * * Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise */ gboolean gst_controller_get_value_arrays (GstController * self, GstClockTime timestamp, GSList * value_arrays) { gboolean res = TRUE; GSList *node; g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); g_return_val_if_fail (value_arrays, FALSE); for (node = value_arrays; (res && node); node = g_slist_next (node)) { res = gst_controller_get_value_array (self, timestamp, node->data); } return (res); }
gboolean gst_controller_set_interpolation_mode (GstController * self, gchar * property_name, GstInterpolateMode mode) { 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))) { res = gst_controlled_property_set_interpolation_mode (prop, mode); } g_mutex_unlock (self->lock); return res; }
/** * gst_controller_get_control_source: * @self: the controller object * @property_name: name of the property for which the #GstControlSource should be get * * Gets the corresponding #GstControlSource for the property. This should be unreferenced * again after use. * * Returns: the #GstControlSource for @property_name or NULL if the property is not * controlled by this controller or no #GstControlSource was assigned yet. * * Since: 0.10.14 */ GstControlSource * gst_controller_get_control_source (GstController * self, gchar * property_name) { GstControlledProperty *prop; GstControlSource *ret = NULL; g_return_val_if_fail (GST_IS_CONTROLLER (self), NULL); g_return_val_if_fail (property_name, NULL); g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { ret = prop->csource; } g_mutex_unlock (self->lock); if (ret) g_object_ref (ret); return ret; }
/** * gst_controller_suggest_next_sync: * @self: the controller that handles the values * * Returns a suggestion for timestamps where buffers should be split * to get best controller results. * * Returns: Returns the suggested timestamp or %GST_CLOCK_TIME_NONE * if no control-rate was set. * * Since: 0.10.13 */ GstClockTime gst_controller_suggest_next_sync (GstController * self) { GstClockTime ret; g_return_val_if_fail (GST_IS_CONTROLLER (self), GST_CLOCK_TIME_NONE); g_return_val_if_fail (self->priv->control_rate != GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE); g_mutex_lock (self->lock); /* TODO: Implement more logic, depending on interpolation mode * and control points * FIXME: we need playback direction */ ret = self->priv->last_sync + self->priv->control_rate; g_mutex_unlock (self->lock); return ret; }
gboolean gst_controller_unset_all (GstController * self, gchar * property_name) { 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))) { if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource)) goto out; gst_interpolation_control_source_unset_all (GST_INTERPOLATION_CONTROL_SOURCE (prop->csource)); } out: g_mutex_unlock (self->lock); return TRUE; }