/** * 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; }
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; }
static gboolean gst_direct_control_binding_sync_values (GstControlBinding * _self, GstObject * object, GstClockTime timestamp, GstClockTime last_sync) { GstDirectControlBinding *self = GST_DIRECT_CONTROL_BINDING (_self); gdouble src_val; gboolean ret; g_return_val_if_fail (GST_IS_DIRECT_CONTROL_BINDING (self), FALSE); g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE); GST_LOG_OBJECT (object, "property '%s' at ts=%" GST_TIME_FORMAT, _self->name, GST_TIME_ARGS (timestamp)); ret = gst_control_source_get_value (self->cs, timestamp, &src_val); if (G_LIKELY (ret)) { GST_LOG_OBJECT (object, " new value %lf", src_val); /* 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 < last_sync) || (src_val != self->last_value)) { GValue *dst_val = &self->cur_value; GST_LOG_OBJECT (object, " mapping %s to value of type %s", _self->name, G_VALUE_TYPE_NAME (dst_val)); /* run mapping function to convert gdouble to GValue */ self->convert_g_value (self, src_val, dst_val); /* we can make this faster * http://bugzilla.gnome.org/show_bug.cgi?id=536939 */ g_object_set_property ((GObject *) object, _self->name, dst_val); self->last_value = src_val; } } else { GST_DEBUG_OBJECT (object, "no control value for param %s", _self->name); } return (ret); }
static GValue * gst_direct_control_binding_get_value (GstControlBinding * _self, GstClockTime timestamp) { GstDirectControlBinding *self = GST_DIRECT_CONTROL_BINDING (_self); GValue *dst_val = NULL; gdouble src_val; g_return_val_if_fail (GST_IS_DIRECT_CONTROL_BINDING (self), NULL); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL); g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE); /* get current value via control source */ if (gst_control_source_get_value (self->cs, timestamp, &src_val)) { dst_val = g_new0 (GValue, 1); g_value_init (dst_val, G_PARAM_SPEC_VALUE_TYPE (_self->pspec)); self->convert_g_value (self, src_val, dst_val); } else { GST_LOG ("no control value for property %s at ts %" GST_TIME_FORMAT, _self->name, GST_TIME_ARGS (timestamp)); } return dst_val; }