+2005-08-31 Stefan Kost <ensonic@users.sf.net>
+
+ * check/gst-libs/controller.c: (gst_test_mono_source_get_property),
+ (gst_test_mono_source_set_property),
+ (gst_test_mono_source_class_init), (GST_START_TEST),
+ (gst_controller_suite):
+ more tests (hehe I have the most)
+ * gst/gstbus.c:
+ describe popping messages whenusing mulltiple sources
+ * libs/gst/controller/gst-controller.c:
+ (gst_controlled_property_set_interpolation_mode),
+ (gst_controlled_property_new):
+ * libs/gst/controller/gst-controller.h:
+ * libs/gst/controller/gst-interpolation.c:
+ implement boolean properties
+
2005-08-31 Wim Taymans <wim@fluendo.com>
* gst/gstminiobject.c: (gst_mini_object_ref):
ARG_ULONG = 1,
ARG_DOUBLE,
ARG_BOOLEAN,
+ ARG_READONLY,
+ ARG_STATIC,
+ ARG_CONSTRUCTONLY,
ARG_COUNT
};
GstElement parent;
gulong val_ulong;
gdouble val_double;
- gboolean val_bool;
+ gboolean val_boolean;
};
struct _GstTestMonoSourceClass
{
case ARG_DOUBLE:
g_value_set_double (value, self->val_double);
break;
+ case ARG_BOOLEAN:
+ g_value_set_boolean (value, self->val_boolean);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
case ARG_DOUBLE:
self->val_double = g_value_get_double (value);
break;
+ case ARG_BOOLEAN:
+ self->val_boolean = g_value_get_boolean (value);
+ break;
+ case ARG_CONSTRUCTONLY:
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
"double prop",
"double number parameter for the test_mono_source",
0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, ARG_BOOLEAN,
+ g_param_spec_boolean ("boolean",
+ "boolean prop",
+ "boolean parameter for the test_mono_source",
+ FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, ARG_READONLY,
+ g_param_spec_ulong ("readonly",
+ "readonly prop",
+ "readonly parameter for the test_mono_source",
+ 0, G_MAXULONG, 0, G_PARAM_READABLE | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, ARG_STATIC,
+ g_param_spec_ulong ("static",
+ "static prop",
+ "static parameter for the test_mono_source",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_CONSTRUCTONLY,
+ g_param_spec_ulong ("construct-only",
+ "construct-only prop",
+ "construct-only parameter for the test_mono_source",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static void
GST_END_TEST;
+/* tests for readonly params */
+GST_START_TEST (controller_new_fail3)
+{
+ GstController *ctrl;
+ GstElement *elem;
+
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+
+ /* that property should exist and but is readonly */
+ ASSERT_CRITICAL (ctrl =
+ gst_controller_new (G_OBJECT (elem), "readonly", NULL));
+ fail_unless (ctrl == NULL, NULL);
+
+ g_object_unref (elem);
+}
+
+GST_END_TEST;
+
+/* tests for static params */
+GST_START_TEST (controller_new_fail4)
+{
+ GstController *ctrl;
+ GstElement *elem;
+
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+
+ /* that property should exist and but is not controlable */
+ ASSERT_CRITICAL (ctrl = gst_controller_new (G_OBJECT (elem), "static", NULL));
+ fail_unless (ctrl == NULL, NULL);
+
+ g_object_unref (elem);
+}
+
+GST_END_TEST;
+
+/* tests for static params */
+GST_START_TEST (controller_new_fail5)
+{
+ GstController *ctrl;
+ GstElement *elem;
+
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+
+ /* that property should exist and but is construct-only */
+ ASSERT_CRITICAL (ctrl =
+ gst_controller_new (G_OBJECT (elem), "construct-only", NULL));
+ fail_unless (ctrl == NULL, NULL);
+
+ g_object_unref (elem);
+}
+
+GST_END_TEST;
+
+
/* tests for an element with controlled params */
GST_START_TEST (controller_new_okay1)
{
tcase_add_test (tc, controller_init);
tcase_add_test (tc, controller_new_fail1);
tcase_add_test (tc, controller_new_fail2);
+ tcase_add_test (tc, controller_new_fail3);
+ tcase_add_test (tc, controller_new_fail4);
+ tcase_add_test (tc, controller_new_fail5);
tcase_add_test (tc, controller_new_okay1);
tcase_add_test (tc, controller_new_okay2);
tcase_add_test (tc, controller_new_okay3);
* possible to react to a message in the same thread that posted the
* message on the bus. This should only be used if the application is able
* to deal with messages from different threads.
+ *
+ * It is important to make sure that every message is popped from the bus at
+ * some point in time. Otherwise it will be presented to the watches (#GSource
+ * elements) again and again. One way to implement it is having one watch with a
+ * low priority (see gst_add_watch_full()) that pops all messages.
*
* Every #GstElement has its own bus.
+ *
*/
#include <errno.h>
*
* Sets the given Interpolation mode for the controlled property and activates
* the respective interpolation hooks.
+ *
+ * Returns: %TRUE for success
*/
static gboolean
gst_controlled_property_set_interpolation_mode (GstControlledProperty * self,
GstInterpolateMode mode)
{
+ gboolean res = TRUE;
+
self->interpolation = mode;
if (mode != GST_INTERPOLATE_USER) {
switch (self->type) {
self->get_value_array =
interpolation_methods[mode]->get_double_value_array;
break;
+ case G_TYPE_BOOLEAN:
+ self->get = interpolation_methods[mode]->get_boolean;
+ self->get_value_array =
+ interpolation_methods[mode]->get_boolean_value_array;
+ break;
+ break;
default:
self->get = NULL;
self->get_value_array = NULL;
- GST_WARNING ("incomplete implementation for type '%d'", self->type);
+ }
+ if (!self->get || !self->get_value_array) {
+ GST_WARNING ("incomplete implementation for type '%d'", self->type);
+ res = FALSE;
}
} else {
/* TODO shouldn't this also get a GstInterpolateMethod *user_method
for the case mode==GST_INTERPOLATE_USER
*/
+ res = FALSE;
}
- return (TRUE);
+ return (res);
}
/*
g_object_class_find_property (G_OBJECT_GET_CLASS (object), name))) {
GST_DEBUG (" psec->flags : 0x%08x", pspec->flags);
- // check if this param is controlable
- g_return_val_if_fail (!(pspec->
- flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)), NULL);
- //g_return_val_if_fail((pspec->flags&GST_PARAM_CONTROLLABLE),NULL);
+ // check if this param is witable
+ g_return_val_if_fail ((pspec->flags & G_PARAM_WRITABLE), NULL);
+ // check if property is controlable
+ g_return_val_if_fail ((pspec->flags & GST_PARAM_CONTROLLABLE), NULL);
+ // check if this param is not construct-only
+ g_return_val_if_fail (!(pspec->flags & G_PARAM_CONSTRUCT_ONLY), NULL);
+
/* TODO do sanity checks
we don't control some pspec->value_type:
G_TYPE_PARAM_BOXED
InterpolateGetValueArray get_float_value_array;
InterpolateGet get_double;
InterpolateGetValueArray get_double_value_array;
+ InterpolateGet get_boolean;
+ InterpolateGetValueArray get_boolean_value_array;
} GstInterpolateMethod;
/**
DEFINE_NONE_GET (long)
DEFINE_NONE_GET (float)
DEFINE_NONE_GET (double)
+DEFINE_NONE_GET (boolean)
static GstInterpolateMethod interpolate_none = {
interpolate_none_get,
interpolate_none_get,
interpolate_none_get_float_value_array,
interpolate_none_get,
- interpolate_none_get_double_value_array
+ interpolate_none_get_double_value_array,
+ interpolate_none_get,
+ interpolate_none_get_boolean_value_array
};
// returns the default value of the property, except for times with specific values
interpolate_trigger_get,
NULL,
interpolate_trigger_get,
+ NULL,
+ interpolate_trigger_get,
NULL
};
interpolate_linear_get_float_value_array,
interpolate_linear_get_double,
interpolate_linear_get_double_value_array,
+ NULL,
+ NULL
};
// square interpolation
*
* Sets the given Interpolation mode for the controlled property and activates
* the respective interpolation hooks.
+ *
+ * Returns: %TRUE for success
*/
static gboolean
gst_controlled_property_set_interpolation_mode (GstControlledProperty * self,
GstInterpolateMode mode)
{
+ gboolean res = TRUE;
+
self->interpolation = mode;
if (mode != GST_INTERPOLATE_USER) {
switch (self->type) {
self->get_value_array =
interpolation_methods[mode]->get_double_value_array;
break;
+ case G_TYPE_BOOLEAN:
+ self->get = interpolation_methods[mode]->get_boolean;
+ self->get_value_array =
+ interpolation_methods[mode]->get_boolean_value_array;
+ break;
+ break;
default:
self->get = NULL;
self->get_value_array = NULL;
- GST_WARNING ("incomplete implementation for type '%d'", self->type);
+ }
+ if (!self->get || !self->get_value_array) {
+ GST_WARNING ("incomplete implementation for type '%d'", self->type);
+ res = FALSE;
}
} else {
/* TODO shouldn't this also get a GstInterpolateMethod *user_method
for the case mode==GST_INTERPOLATE_USER
*/
+ res = FALSE;
}
- return (TRUE);
+ return (res);
}
/*
g_object_class_find_property (G_OBJECT_GET_CLASS (object), name))) {
GST_DEBUG (" psec->flags : 0x%08x", pspec->flags);
- // check if this param is controlable
- g_return_val_if_fail (!(pspec->
- flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)), NULL);
- //g_return_val_if_fail((pspec->flags&GST_PARAM_CONTROLLABLE),NULL);
+ // check if this param is witable
+ g_return_val_if_fail ((pspec->flags & G_PARAM_WRITABLE), NULL);
+ // check if property is controlable
+ g_return_val_if_fail ((pspec->flags & GST_PARAM_CONTROLLABLE), NULL);
+ // check if this param is not construct-only
+ g_return_val_if_fail (!(pspec->flags & G_PARAM_CONSTRUCT_ONLY), NULL);
+
/* TODO do sanity checks
we don't control some pspec->value_type:
G_TYPE_PARAM_BOXED
InterpolateGetValueArray get_float_value_array;
InterpolateGet get_double;
InterpolateGetValueArray get_double_value_array;
+ InterpolateGet get_boolean;
+ InterpolateGetValueArray get_boolean_value_array;
} GstInterpolateMethod;
/**
DEFINE_NONE_GET (long)
DEFINE_NONE_GET (float)
DEFINE_NONE_GET (double)
+DEFINE_NONE_GET (boolean)
static GstInterpolateMethod interpolate_none = {
interpolate_none_get,
interpolate_none_get,
interpolate_none_get_float_value_array,
interpolate_none_get,
- interpolate_none_get_double_value_array
+ interpolate_none_get_double_value_array,
+ interpolate_none_get,
+ interpolate_none_get_boolean_value_array
};
// returns the default value of the property, except for times with specific values
interpolate_trigger_get,
NULL,
interpolate_trigger_get,
+ NULL,
+ interpolate_trigger_get,
NULL
};
interpolate_linear_get_float_value_array,
interpolate_linear_get_double,
interpolate_linear_get_double_value_array,
+ NULL,
+ NULL
};
// square interpolation
ARG_ULONG = 1,
ARG_DOUBLE,
ARG_BOOLEAN,
+ ARG_READONLY,
+ ARG_STATIC,
+ ARG_CONSTRUCTONLY,
ARG_COUNT
};
GstElement parent;
gulong val_ulong;
gdouble val_double;
- gboolean val_bool;
+ gboolean val_boolean;
};
struct _GstTestMonoSourceClass
{
case ARG_DOUBLE:
g_value_set_double (value, self->val_double);
break;
+ case ARG_BOOLEAN:
+ g_value_set_boolean (value, self->val_boolean);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
case ARG_DOUBLE:
self->val_double = g_value_get_double (value);
break;
+ case ARG_BOOLEAN:
+ self->val_boolean = g_value_get_boolean (value);
+ break;
+ case ARG_CONSTRUCTONLY:
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
"double prop",
"double number parameter for the test_mono_source",
0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, ARG_BOOLEAN,
+ g_param_spec_boolean ("boolean",
+ "boolean prop",
+ "boolean parameter for the test_mono_source",
+ FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, ARG_READONLY,
+ g_param_spec_ulong ("readonly",
+ "readonly prop",
+ "readonly parameter for the test_mono_source",
+ 0, G_MAXULONG, 0, G_PARAM_READABLE | GST_PARAM_CONTROLLABLE));
+
+ g_object_class_install_property (gobject_class, ARG_STATIC,
+ g_param_spec_ulong ("static",
+ "static prop",
+ "static parameter for the test_mono_source",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_CONSTRUCTONLY,
+ g_param_spec_ulong ("construct-only",
+ "construct-only prop",
+ "construct-only parameter for the test_mono_source",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static void
GST_END_TEST;
+/* tests for readonly params */
+GST_START_TEST (controller_new_fail3)
+{
+ GstController *ctrl;
+ GstElement *elem;
+
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+
+ /* that property should exist and but is readonly */
+ ASSERT_CRITICAL (ctrl =
+ gst_controller_new (G_OBJECT (elem), "readonly", NULL));
+ fail_unless (ctrl == NULL, NULL);
+
+ g_object_unref (elem);
+}
+
+GST_END_TEST;
+
+/* tests for static params */
+GST_START_TEST (controller_new_fail4)
+{
+ GstController *ctrl;
+ GstElement *elem;
+
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+
+ /* that property should exist and but is not controlable */
+ ASSERT_CRITICAL (ctrl = gst_controller_new (G_OBJECT (elem), "static", NULL));
+ fail_unless (ctrl == NULL, NULL);
+
+ g_object_unref (elem);
+}
+
+GST_END_TEST;
+
+/* tests for static params */
+GST_START_TEST (controller_new_fail5)
+{
+ GstController *ctrl;
+ GstElement *elem;
+
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+
+ /* that property should exist and but is construct-only */
+ ASSERT_CRITICAL (ctrl =
+ gst_controller_new (G_OBJECT (elem), "construct-only", NULL));
+ fail_unless (ctrl == NULL, NULL);
+
+ g_object_unref (elem);
+}
+
+GST_END_TEST;
+
+
/* tests for an element with controlled params */
GST_START_TEST (controller_new_okay1)
{
tcase_add_test (tc, controller_init);
tcase_add_test (tc, controller_new_fail1);
tcase_add_test (tc, controller_new_fail2);
+ tcase_add_test (tc, controller_new_fail3);
+ tcase_add_test (tc, controller_new_fail4);
+ tcase_add_test (tc, controller_new_fail5);
tcase_add_test (tc, controller_new_okay1);
tcase_add_test (tc, controller_new_okay2);
tcase_add_test (tc, controller_new_okay3);