libs/gst/controller/: API: gst_controller_suggest_next_sync(), gst_object_suggest_nex...
authorSebastian Dröge <slomo@circular-chaos.org>
Thu, 17 May 2007 17:37:58 +0000 (17:37 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Thu, 17 May 2007 17:37:58 +0000 (17:37 +0000)
Original commit message from CVS:
reviewed by: Stefan Kost <ensonic@users.sf.net>
* libs/gst/controller/gstcontroller.c:
(gst_controller_suggest_next_sync), (gst_controller_sync_values),
(_gst_controller_get_property), (_gst_controller_set_property),
(_gst_controller_init), (_gst_controller_class_init):
* libs/gst/controller/gstcontroller.h:
* libs/gst/controller/gsthelper.c: (gst_object_suggest_next_sync),
(gst_object_get_control_rate), (gst_object_set_control_rate):
API: gst_controller_suggest_next_sync(), gst_object_suggest_next_sync()
Add API that provides sync suggestion timestamps for elements that
call gst_object_sync_values() from which those elements can subdivide
their processing loop to get the best results for the controlled
properties. For now it just suggests last_sync + control_rate as
new timestamp but this will be improved in the future.
While doing that change the control-rate property to a GstClockTime
from guint and change it's meaning from samples to nanoseconds as
the GstController doesn't know anything about sampling rate. Strictly
speaking this breaks ABI but as the control-rate property didn't do
anything in the past and as such couldn't be used this should be no
problem.

ChangeLog
libs/gst/controller/gstcontroller.c
libs/gst/controller/gstcontroller.h
libs/gst/controller/gsthelper.c

index 1bc4d52..ab90c51 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,31 @@
 
        reviewed by: Stefan Kost <ensonic@users.sf.net>
 
+       * libs/gst/controller/gstcontroller.c:
+       (gst_controller_suggest_next_sync), (gst_controller_sync_values),
+       (_gst_controller_get_property), (_gst_controller_set_property),
+       (_gst_controller_init), (_gst_controller_class_init):
+       * libs/gst/controller/gstcontroller.h:
+       * libs/gst/controller/gsthelper.c: (gst_object_suggest_next_sync),
+       (gst_object_get_control_rate), (gst_object_set_control_rate):
+       API: gst_controller_suggest_next_sync(), gst_object_suggest_next_sync()
+       Add API that provides sync suggestion timestamps for elements that
+       call gst_object_sync_values() from which those elements can subdivide
+       their processing loop to get the best results for the controlled
+       properties. For now it just suggests last_sync + control_rate as
+       new timestamp but this will be improved in the future.
+
+       While doing that change the control-rate property to a GstClockTime
+       from guint and change it's meaning from samples to nanoseconds as
+       the GstController doesn't know anything about sampling rate. Strictly
+       speaking this breaks ABI but as the control-rate property didn't do
+       anything in the past and as such couldn't be used this should be no
+       problem.        
+
+2007-05-17  Sebastian Dröge  <slomo@circular-chaos.org>
+
+       reviewed by: Stefan Kost <ensonic@users.sf.net>
+
        * libs/gst/controller/gstcontroller.c: (gst_controller_unset),
        (gst_controller_unset_all):
        * libs/gst/controller/gstcontrollerprivate.h:
index 43141e6..47bf671 100644 (file)
@@ -86,7 +86,8 @@ enum
 
 struct _GstControllerPrivate
 {
-  guint control_rate;
+  GstClockTime control_rate;
+  GstClockTime last_sync;
 };
 
 /* imports from gst-interpolation.c */
@@ -960,6 +961,38 @@ gst_controller_get_all (GstController * self, gchar * property_name)
 }
 
 /**
+ * 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 */
+  ret = self->priv->last_sync + self->priv->control_rate;
+
+  g_mutex_unlock (self->lock);
+
+  return ret;
+}
+
+/**
  * gst_controller_sync_values:
  * @self: the controller that handles the values
  * @timestamp: the time that should be processed
@@ -976,7 +1009,7 @@ gst_controller_sync_values (GstController * self, GstClockTime timestamp)
   GstControlledProperty *prop;
   GList *node;
   GValue *value;
-  gboolean live;
+  gboolean live = FALSE;
 
   g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
@@ -1016,6 +1049,9 @@ gst_controller_sync_values (GstController * self, GstClockTime timestamp)
       g_object_set_property (self->object, prop->name, value);
     }
   }
+  if (G_LIKELY (!live))
+    self->priv->last_sync = timestamp;
+
   g_mutex_unlock (self->lock);
   /* TODO what can here go wrong, to return FALSE ?
      BilboEd : Nothing I guess, as long as all the checks are made when creating the controller,
@@ -1182,7 +1218,7 @@ _gst_controller_get_property (GObject * object, guint property_id,
          (ret == GST_STATE_CHANGE_ASYNC &&
          (p_state == GST_STATE_NULL || p_state == GST_STATE_READY))) {
        */
-      g_value_set_uint (value, self->priv->control_rate);
+      g_value_set_uint64 (value, self->priv->control_rate);
       /*
          }
          else {
@@ -1208,7 +1244,7 @@ _gst_controller_set_property (GObject * object, guint property_id,
 
   switch (property_id) {
     case PROP_CONTROL_RATE:{
-      self->priv->control_rate = g_value_get_uint (value);
+      self->priv->control_rate = g_value_get_uint64 (value);
     }
       break;
     default:{
@@ -1270,6 +1306,8 @@ _gst_controller_init (GTypeInstance * instance, gpointer g_class)
   self->priv =
       G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_CONTROLLER,
       GstControllerPrivate);
+  self->priv->last_sync = GST_CLOCK_TIME_NONE;
+  self->priv->control_rate = 100 * GST_MSECOND;
 }
 
 static void
@@ -1289,10 +1327,10 @@ _gst_controller_class_init (GstControllerClass * klass)
 
   /* register properties */
   g_object_class_install_property (gobject_class, PROP_CONTROL_RATE,
-      g_param_spec_uint ("control-rate",
+      g_param_spec_uint64 ("control-rate",
           "control rate",
-          "Controlled properties will be updated this many times per second",
-          1, G_MAXUINT, 10, G_PARAM_READWRITE));
+          "Controlled properties will be updated at least every control-rate nanoseconds",
+          1, G_MAXUINT, 100 * GST_MSECOND, G_PARAM_READWRITE));
 
   /* register signals */
   /* set defaults for overridable methods */
index 9c64480..996be79 100644 (file)
@@ -164,7 +164,7 @@ GValue *gst_controller_get (GstController * self, gchar * property_name,
 const GList *gst_controller_get_all (GstController * self,
     gchar * property_name);
 
-
+GstClockTime gst_controller_suggest_next_sync (GstController *self);
 gboolean gst_controller_sync_values (GstController * self,
     GstClockTime timestamp);
 
@@ -185,6 +185,7 @@ gboolean gst_object_uncontrol_properties (GObject * object, ...) G_GNUC_NULL_TER
 GstController *gst_object_get_controller (GObject * object);
 gboolean gst_object_set_controller (GObject * object, GstController * controller);
 
+GstClockTime gst_object_suggest_next_sync (GObject * object);
 gboolean gst_object_sync_values (GObject * object, GstClockTime timestamp);
 
 gboolean gst_object_get_value_arrays (GObject * object,
@@ -192,8 +193,8 @@ gboolean gst_object_get_value_arrays (GObject * object,
 gboolean gst_object_get_value_array (GObject * object,
     GstClockTime timestamp, GstValueArray * value_array);
 
-guint gst_object_get_control_rate (GObject * object);
-void gst_object_set_control_rate (GObject * object, guint control_rate);
+GstClockTime gst_object_get_control_rate (GObject * object);
+void gst_object_set_control_rate (GObject * object, GstClockTime control_rate);
 
 /* lib init/done */
 
index 4fad3e4..3320599 100644 (file)
@@ -145,6 +145,29 @@ gst_object_set_controller (GObject * object, GstController * controller)
   return (FALSE);
 }
 
+ /**
+ * gst_object_suggest_next_sync:
+ * @object: the object that has controlled properties
+ * @timestamp: the time that should be processed
+ *
+ * Convenience function for GObject
+ *
+ * Returns: same thing as gst_controller_suggest_next_sync()
+ * Since: 0.10.13
+ */
+GstClockTime
+gst_object_suggest_next_sync (GObject * object)
+{
+  GstController *ctrl = NULL;
+
+  g_return_val_if_fail (G_IS_OBJECT (object), GST_CLOCK_TIME_NONE);
+
+  if ((ctrl = g_object_get_qdata (object, __gst_controller_key))) {
+    return gst_controller_suggest_next_sync (ctrl);
+  }
+  return (GST_CLOCK_TIME_NONE);
+}
+
 /**
  * gst_object_sync_values:
  * @object: the object that has controlled properties
@@ -240,22 +263,22 @@ gst_object_get_value_array (GObject * object, GstClockTime timestamp,
  * Obtain the control-rate for this @object. Audio processing #GstElement
  * objects will use this rate to sub-divide their processing loop and call
  * gst_object_sync_values() inbetween. The length of the processing segment
- * should be sampling-rate/control-rate.
+ * should be up to @control-rate nanoseconds.
  *
- * If the @object is not under property control, this will return 0. This allows
- * the element to avoid the sub-dividing.
+ * If the @object is not under property control, this will return
+ * %GST_CLOCK_TIME_NONE. This allows the element to avoid the sub-dividing.
  *
- * The control-rate is not expected to change if the elemnt is in
+ * The control-rate is not expected to change if the element is in
  * %GST_STATE_PAUSED or %GST_STATE_PLAYING.
  *
- * Returns: the control rate
+ * Returns: the control rate in nanoseconds
  * Since: 0.10.10
  */
-guint
+GstClockTime
 gst_object_get_control_rate (GObject * object)
 {
   GstController *ctrl;
-  guint control_rate = 0;
+  GstClockTime control_rate = GST_CLOCK_TIME_NONE;
 
   g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
 
@@ -268,20 +291,20 @@ gst_object_get_control_rate (GObject * object)
 /**
  * gst_object_set_control_rate:
  * @object: the object that has controlled properties
- * @control_rate: the new control-rate (1 .. sampling_rate)
+ * @control_rate: the new control-rate in nanoseconds.
  *
  * Change the control-rate for this @object. Audio processing #GstElement
  * objects will use this rate to sub-divide their processing loop and call
  * gst_object_sync_values() inbetween. The length of the processing segment
- * should be sampling-rate/control-rate.
+ * should be up to @control-rate nanoseconds.
  *
- * The control-rate should not change if the elemnt is in %GST_STATE_PAUSED or
+ * The control-rate should not change if the element is in %GST_STATE_PAUSED or
  * %GST_STATE_PLAYING.
  *
  * Since: 0.10.10
  */
 void
-gst_object_set_control_rate (GObject * object, guint control_rate)
+gst_object_set_control_rate (GObject * object, GstClockTime control_rate)
 {
   GstController *ctrl;