Beispiel #1
0
/**
 * 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;
}
Beispiel #2
0
/**
 * 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;
}
Beispiel #3
0
/**
 * 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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #9
0
/**
 * 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;
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
}
Beispiel #12
0
/**
 * 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);
}
Beispiel #13
0
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;
}
Beispiel #14
0
/**
 * 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;
}
Beispiel #15
0
/**
 * 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;
}
Beispiel #16
0
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;
}