libs/gst/controller/: API: gst_controller_suggest_next_sync(), gst_object_suggest_next_sync()

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.
This commit is contained in:
Sebastian Dröge 2007-05-17 17:37:58 +00:00
parent 3b7871d993
commit 82543e317f
4 changed files with 108 additions and 21 deletions

View file

@ -1,3 +1,28 @@
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_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>

View file

@ -86,7 +86,8 @@ enum
struct _GstControllerPrivate
{
guint control_rate;
GstClockTime control_rate;
GstClockTime last_sync;
};
/* imports from gst-interpolation.c */
@ -959,6 +960,38 @@ gst_controller_get_all (GstController * self, gchar * property_name)
return (res);
}
/**
* 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
@ -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 */

View 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 */

View 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;