mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-10 10:04:23 +00:00
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:
parent
3b7871d993
commit
82543e317f
4 changed files with 108 additions and 21 deletions
25
ChangeLog
25
ChangeLog
|
@ -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>
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue