mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-04 01:32:42 +00:00
libs/gst/controller/gstinterpolationcontrolsource.c: Optimize list handling. Use own find function. Exploit that fact...
Original commit message from CVS: * libs/gst/controller/gstinterpolationcontrolsource.c: Optimize list handling. Use own find function. Exploit that fact that the list is sorted. Also pass back the node before, so that we can insert quickly. Have a fast path for append.
This commit is contained in:
parent
2e8d4a491d
commit
b1b4a78ffc
2 changed files with 91 additions and 14 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2008-06-29 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
|
* libs/gst/controller/gstinterpolationcontrolsource.c:
|
||||||
|
Optimize list handling. Use own find function. Exploit that fact that
|
||||||
|
the list is sorted. Also pass back the node before, so that we can
|
||||||
|
insert quickly. Have a fast path for append.
|
||||||
|
|
||||||
2008-06-29 Stefan Kost <ensonic@users.sf.net>
|
2008-06-29 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
* docs/design/draft-framestep.txt:
|
* docs/design/draft-framestep.txt:
|
||||||
|
|
|
@ -415,34 +415,104 @@ gst_control_point_find (gconstpointer p1, gconstpointer p2)
|
||||||
return ((ct1 < ct2) ? -1 : ((ct1 == ct2) ? 0 : 1));
|
return ((ct1 < ct2) ? -1 : ((ct1 == ct2) ? 0 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/*
|
||||||
gst_interpolation_control_source_set_internal (GstInterpolationControlSource *
|
* _list_find_sorted_custom:
|
||||||
self, GstClockTime timestamp, GValue * value)
|
*
|
||||||
|
* This works like g_list_find_custom() with the difference that it expects the
|
||||||
|
* list to be sorted in ascending order (0->MAX), stops when it the list-values
|
||||||
|
* are bigger that what is searched for and optionaly delivers the last node
|
||||||
|
* back in the @prev_node argument. This can be used to quickly insert a new
|
||||||
|
* node at the correct position.
|
||||||
|
*/
|
||||||
|
static GList *
|
||||||
|
_list_find_sorted_custom (GList * list, gconstpointer data, GCompareFunc func,
|
||||||
|
GList ** prev_node)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (func != NULL, list);
|
||||||
|
GList *prev = list;
|
||||||
|
gint cmp;
|
||||||
|
|
||||||
|
while (list) {
|
||||||
|
cmp = func (list->data, data);
|
||||||
|
switch (cmp) {
|
||||||
|
case -1:
|
||||||
|
prev = list;
|
||||||
|
list = list->next;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
return list;
|
||||||
|
case 1:
|
||||||
|
if (prev_node)
|
||||||
|
*prev_node = prev;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (prev_node)
|
||||||
|
*prev_node = prev;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstControlPoint *
|
||||||
|
_make_new_cp (GstInterpolationControlSource * self, GstClockTime timestamp,
|
||||||
|
GValue * value)
|
||||||
{
|
{
|
||||||
GstControlPoint *cp;
|
GstControlPoint *cp;
|
||||||
GList *node;
|
|
||||||
|
|
||||||
/* check if a control point for the timestamp already exists */
|
|
||||||
if ((node = g_list_find_custom (self->priv->values, ×tamp,
|
|
||||||
gst_control_point_find))) {
|
|
||||||
cp = node->data;
|
|
||||||
g_value_reset (&cp->value);
|
|
||||||
g_value_copy (value, &cp->value);
|
|
||||||
} else {
|
|
||||||
/* create a new GstControlPoint */
|
/* create a new GstControlPoint */
|
||||||
cp = g_slice_new0 (GstControlPoint);
|
cp = g_slice_new0 (GstControlPoint);
|
||||||
cp->timestamp = timestamp;
|
cp->timestamp = timestamp;
|
||||||
g_value_init (&cp->value, self->priv->type);
|
g_value_init (&cp->value, self->priv->type);
|
||||||
g_value_copy (value, &cp->value);
|
g_value_copy (value, &cp->value);
|
||||||
/* and sort it into the prop->values list */
|
|
||||||
self->priv->values =
|
return cp;
|
||||||
g_list_insert_sorted (self->priv->values, cp,
|
}
|
||||||
gst_control_point_compare);
|
|
||||||
|
static void
|
||||||
|
gst_interpolation_control_source_set_internal (GstInterpolationControlSource *
|
||||||
|
self, GstClockTime timestamp, GValue * value)
|
||||||
|
{
|
||||||
|
GList *node, *prev = self->priv->values;
|
||||||
|
|
||||||
|
/* check if we can shortcut and append */
|
||||||
|
if ((node = g_list_last (self->priv->values))) {
|
||||||
|
GstControlPoint *last_cp = node->data;
|
||||||
|
|
||||||
|
if (timestamp > last_cp->timestamp) {
|
||||||
|
/* pass 'node' instead of list, and also deliberately ignore the result */
|
||||||
|
node = g_list_append (node, _make_new_cp (self, timestamp, value));
|
||||||
|
self->priv->nvalues++;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if a control point for the timestamp already exists */
|
||||||
|
if ((node = _list_find_sorted_custom (self->priv->values, ×tamp,
|
||||||
|
gst_control_point_find, &prev))) {
|
||||||
|
/* update control point */
|
||||||
|
GstControlPoint *cp = node->data;
|
||||||
|
g_value_reset (&cp->value);
|
||||||
|
g_value_copy (value, &cp->value);
|
||||||
|
} else {
|
||||||
|
/* sort new cp into the prop->values list */
|
||||||
|
if (self->priv->values) {
|
||||||
|
GList *new_list;
|
||||||
|
|
||||||
|
/* pass 'prev' instead of list */
|
||||||
|
new_list = g_list_insert_sorted (prev,
|
||||||
|
_make_new_cp (self, timestamp, value), gst_control_point_compare);
|
||||||
|
if (self->priv->values == prev)
|
||||||
|
self->priv->values = new_list;
|
||||||
|
} else {
|
||||||
|
self->priv->values = g_list_prepend (NULL,
|
||||||
|
_make_new_cp (self, timestamp, value));
|
||||||
|
}
|
||||||
self->priv->nvalues++;
|
self->priv->nvalues++;
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
self->priv->valid_cache = FALSE;
|
self->priv->valid_cache = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_interpolation_control_source_set:
|
* gst_interpolation_control_source_set:
|
||||||
* @self: the #GstInterpolationControlSource object
|
* @self: the #GstInterpolationControlSource object
|
||||||
|
|
Loading…
Reference in a new issue