⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gstcontroller.c

📁 gnash 在pc和嵌入式下开发需要的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GStreamer * * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dot net> * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org> * * gstcontroller.c: dynamic parameter control subsystem * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//** * SECTION:gstcontroller * @short_description: dynamic parameter control subsystem * * The controller subsystem offers a lightweight way to adjust gobject * properties over stream-time. It works by using time-stamped value pairs that * are queued for element-properties. At run-time the elements continously pull * values changes for the current stream-time. * * What needs to be changed in a #GstElement? * Very little - it is just two steps to make a plugin controllable! * <orderedlist> *   <listitem><para> *     mark gobject-properties paramspecs that make sense to be controlled, *     by GST_PARAM_CONTROLLABLE. *   </para></listitem> *   <listitem><para> *     when processing data (get, chain, loop function) at the beginning call *     gst_object_sync_values(element,timestamp). *     This will made the controller to update all gobject properties that are under *     control with the current values based on timestamp. *   </para></listitem> * </orderedlist> * * What needs to be done in applications? * Again its not a lot to change. * <orderedlist> *   <listitem><para> *     first put some properties under control, by calling *     controller = g_object_control_properties(object, "prop1", "prop2",...); *   </para></listitem> *   <listitem><para> *     Get a #GstControlSource for the property and set it up. *     csource = gst_interpolation_control_source_new (); *     gst_interpolation_control_source_set_interpolation_mode(csource, mode); *     gst_interpolation_control_source_set (csource,0 * GST_SECOND, value1); *     gst_interpolation_control_source_set (csource,1 * GST_SECOND, value2); *   </para></listitem> *   <listitem><para> *     Set the #GstControlSource in the controller. *     gst_controller_set_control_source (controller, "prop1", csource); *   </para></listitem> *   <listitem><para> *     start your pipeline *   </para></listitem> * </orderedlist> */#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include "gstcontroller.h"#include "gstcontrollerprivate.h"#include "gstcontrolsource.h"#include "gstinterpolationcontrolsource.h"#define GST_CAT_DEFAULT gst_controller_debugGST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);static GObjectClass *parent_class = NULL;GQuark __gst_controller_key;/* property ids */enum{  PROP_CONTROL_RATE = 1};struct _GstControllerPrivate{  GstClockTime control_rate;  GstClockTime last_sync;};/* helper */static voidgst_controlled_property_add_interpolation_control_source (GstControlledProperty    * self){  GstControlSource *csource =      GST_CONTROL_SOURCE (gst_interpolation_control_source_new ());  GST_INFO      ("Adding a GstInterpolationControlSource because of backward compatibility");  g_return_if_fail (!self->csource);  gst_control_source_bind (GST_CONTROL_SOURCE (csource), self->pspec);  self->csource = csource;}/* * gst_controlled_property_new: * @object: for which object the controlled property should be set up * @name: the name of the property to be controlled * * Private method which initializes the fields of a new controlled property * structure. * * Returns: a freshly allocated structure or %NULL */static GstControlledProperty *gst_controlled_property_new (GObject * object, const gchar * name){  GstControlledProperty *prop = NULL;  GParamSpec *pspec;  GST_INFO ("trying to put property '%s' under control", name);  /* check if the object has a property of that name */  if ((pspec =          g_object_class_find_property (G_OBJECT_GET_CLASS (object), name))) {    GST_DEBUG ("  psec->flags : 0x%08x", pspec->flags);    /* check if this param is witable */    g_return_val_if_fail ((pspec->flags & G_PARAM_WRITABLE), NULL);    /* check if property is controlable */    g_return_val_if_fail ((pspec->flags & GST_PARAM_CONTROLLABLE), NULL);    /* check if this param is not construct-only */    g_return_val_if_fail (!(pspec->flags & G_PARAM_CONSTRUCT_ONLY), NULL);    if ((prop = g_new0 (GstControlledProperty, 1))) {      prop->pspec = pspec;      prop->name = pspec->name;      prop->disabled = FALSE;    }  } else {    GST_WARNING ("class '%s' has no property '%s'", G_OBJECT_TYPE_NAME (object),        name);  }  return prop;}/* * gst_controlled_property_free: * @prop: the object to free * * Private method which frees all data allocated by a #GstControlledProperty * instance. */static voidgst_controlled_property_free (GstControlledProperty * prop){  if (prop->csource)    g_object_unref (prop->csource);  g_free (prop);}/* * gst_controller_find_controlled_property: * @self: the controller object to search for a property in * @name: the gobject property name to look for * * Searches the list of properties under control. * * 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");  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;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -