timedvaluecontrolsource: Add some signals about values changes

In order for user to be able to track changes in the value set in
GstTimedValueControlSource the following signals have been added:
 * value-added
 * value-removed
 * value-changed

To be able to use a GstControlPoint to be marshalled into the signals,
the GstControlPoint structure is now registerd as a GBoxed type.

New API:
~~~~~~~
  * GstTimedValueControlSource::value-added
  * GstTimedValueControlSource::value-removed
  * GstTimedValueControlSource::value-added

https://bugzilla.gnome.org/show_bug.cgi?id=737616
This commit is contained in:
Thibault Saunier 2014-09-29 21:10:14 +02:00
parent 2674330420
commit 1a02a59e42
2 changed files with 108 additions and 8 deletions

View file

@ -52,6 +52,17 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstTimedValueControlSource,
gst_timed_value_control_source, GST_TYPE_CONTROL_SOURCE, _do_init);
enum
{
VALUE_CHANGED_SIGNAL,
VALUE_ADDED_SIGNAL,
VALUE_REMOVED_SIGNAL,
LAST_SIGNAL
};
static guint gst_timed_value_control_source_signals[LAST_SIGNAL] = { 0 };
/*
* gst_control_point_free:
* @prop: the object to free
@ -67,6 +78,29 @@ gst_control_point_free (GstControlPoint * cp)
g_slice_free (GstControlPoint, cp);
}
static gpointer
gst_control_point_copy (GstControlPoint * boxed)
{
return g_slice_dup (GstControlPoint, boxed);
}
GType
gst_control_point_get_type (void)
{
static volatile gsize type_id = 0;
if (g_once_init_enter (&type_id)) {
GType tmp =
g_boxed_type_register_static (g_intern_static_string
("GstControlPoint"),
(GBoxedCopyFunc) gst_control_point_copy,
(GBoxedFreeFunc) gst_control_point_free);
g_once_init_leave (&type_id, tmp);
}
return type_id;
}
static void
gst_timed_value_control_source_reset (GstTimedValueControlSource * self)
{
@ -138,9 +172,11 @@ gst_timed_value_control_source_set_internal (GstTimedValueControlSource *
self, GstClockTime timestamp, const gdouble value)
{
GSequenceIter *iter;
GstControlPoint *cp;
g_mutex_lock (&self->lock);
/* check if a control point for the timestamp already exists */
/* iter contains the iter right *after* timestamp */
if (G_LIKELY (self->values)) {
iter =
@ -152,8 +188,14 @@ gst_timed_value_control_source_set_internal (GstTimedValueControlSource *
/* If the timestamp is the same just update the control point value */
if (cp->timestamp == timestamp) {
/* update control point */
cp->value = value;
g_mutex_unlock (&self->lock);
g_signal_emit (self,
gst_timed_value_control_source_signals[VALUE_CHANGED_SIGNAL], 0,
cp);
goto done;
}
}
@ -163,9 +205,14 @@ gst_timed_value_control_source_set_internal (GstTimedValueControlSource *
}
/* sort new cp into the prop->values list */
g_sequence_insert_sorted (self->values, _make_new_cp (self, timestamp,
value), (GCompareDataFunc) gst_control_point_compare, NULL);
cp = _make_new_cp (self, timestamp, value);
g_sequence_insert_sorted (self->values, cp,
(GCompareDataFunc) gst_control_point_compare, NULL);
self->nvalues++;
g_mutex_unlock (&self->lock);
g_signal_emit (self,
gst_timed_value_control_source_signals[VALUE_ADDED_SIGNAL], 0, cp);
done:
self->valid_cache = FALSE;
@ -224,9 +271,7 @@ gst_timed_value_control_source_set (GstTimedValueControlSource * self,
g_return_val_if_fail (GST_IS_TIMED_VALUE_CONTROL_SOURCE (self), FALSE);
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
g_mutex_lock (&self->lock);
gst_timed_value_control_source_set_internal (self, timestamp, value);
g_mutex_unlock (&self->lock);
return TRUE;
}
@ -257,10 +302,8 @@ gst_timed_value_control_source_set_from_list (GstTimedValueControlSource *
GST_WARNING ("GstTimedValued with invalid timestamp passed to %s",
GST_FUNCTION);
} else {
g_mutex_lock (&self->lock);
gst_timed_value_control_source_set_internal (self, tv->timestamp,
tv->value);
g_mutex_unlock (&self->lock);
res = TRUE;
}
}
@ -283,6 +326,7 @@ gst_timed_value_control_source_unset (GstTimedValueControlSource * self,
{
GSequenceIter *iter;
gboolean res = FALSE;
GstControlPoint *cp = NULL;
g_return_val_if_fail (GST_IS_TIMED_VALUE_CONTROL_SOURCE (self), FALSE);
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
@ -292,7 +336,6 @@ gst_timed_value_control_source_unset (GstTimedValueControlSource * self,
if (G_LIKELY (self->values) && (iter =
g_sequence_search (self->values, &timestamp,
(GCompareDataFunc) gst_control_point_find, NULL))) {
GstControlPoint *cp;
/* Iter contains the iter right after timestamp, i.e.
* we need to get the previous one and check the timestamp
@ -300,6 +343,7 @@ gst_timed_value_control_source_unset (GstTimedValueControlSource * self,
iter = g_sequence_iter_prev (iter);
cp = g_sequence_get (iter);
if (cp->timestamp == timestamp) {
cp = g_slice_dup (GstControlPoint, cp);
g_sequence_remove (iter);
self->nvalues--;
self->valid_cache = FALSE;
@ -308,6 +352,12 @@ gst_timed_value_control_source_unset (GstTimedValueControlSource * self,
}
g_mutex_unlock (&self->lock);
if (cp) {
g_signal_emit (self,
gst_timed_value_control_source_signals[VALUE_REMOVED_SIGNAL], 0, cp);
g_slice_free (GstControlPoint, cp);
}
return res;
}
@ -420,5 +470,53 @@ gst_timed_value_control_source_class_init (GstTimedValueControlSourceClass
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
//GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass);
/**
* GstTimedValueControlSource::value-changed
* @self: The #GstTimedValueControlSource on which a #GstTimedValue has changed
* @timed_value: The #GstTimedValue where the value changed
*
* Emited right after the new value has been set on @timed_signals
*
* Since 1.6
*/
gst_timed_value_control_source_signals[VALUE_CHANGED_SIGNAL] =
g_signal_new ("value-changed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, 0, NULL,
NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
gst_control_point_get_type ());
/**
* GstTimedValueControlSource::value-added
* @self: The #GstTimedValueControlSource into which a #GstTimedValue has been
* added
* @timed_value: The newly added #GstTimedValue
*
* Emited right after the new value has been added to @self
*
* Since 1.6
*/
gst_timed_value_control_source_signals[VALUE_ADDED_SIGNAL] =
g_signal_new ("value-added", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, 0, NULL,
NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
gst_control_point_get_type ());
/**
* GstTimedValueControlSource::value-removed
* @self: The #GstTimedValueControlSource from which a #GstTimedValue has been
* removed
* @timed_value: The removed #GstTimedValue
*
* Emited when @timed_value is removed from @self
*
* Since 1.6
*/
gst_timed_value_control_source_signals[VALUE_REMOVED_SIGNAL] =
g_signal_new ("value-removed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, 0, NULL,
NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
gst_control_point_get_type ());
gobject_class->finalize = gst_timed_value_control_source_finalize;
}

View file

@ -76,6 +76,8 @@ struct _GstControlPoint
};
GType gst_control_point_get_type (void);
/**
* GstTimedValueControlSource:
*