+2006-10-11 Tim-Philipp Müller <tim at centricular dot net>
+
+ * libs/gst/controller/gstcontroller.c: (gst_controller_new_list):
+ Fix refcounting here too, just like we did for _new_valist() a few
+ days ago (#357180) (thanks to René Stadler). Also remove all those
+ 'Since: 0.9' from the gtk-doc blobs.
+
+ * tests/check/libs/controller.c: (controller_refcount_new_list),
+ (gst_controller_suite):
+ Unit test for the above.
+
2006-10-10 Wim Taymans <wim@fluendo.com>
Patch by: Sebastien Cote <sebas642 at yahoo dot ca>
* Creates a new GstController for the given object's properties
*
* Returns: the new controller.
- * Since: 0.9
*/
GstController *
gst_controller_new_valist (GObject * object, va_list var_args)
* Creates a new GstController for the given object's properties
*
* Returns: the new controller.
- * Since: 0.9
*/
GstController *
gst_controller_new_list (GObject * object, GList * list)
{
GstController *self;
GstControlledProperty *prop;
+ gboolean ref_existing = TRUE;
gchar *name;
GList *node;
self->object = g_object_ref (object);
/* store the controller */
g_object_set_qdata (object, __gst_controller_key, self);
+ ref_existing = FALSE;
} else {
- g_object_ref (self);
- GST_INFO ("returning existing controller");
+ /* only want one single _ref(), even for multiple properties */
+ if (ref_existing) {
+ g_object_ref (self);
+ ref_existing = FALSE;
+ GST_INFO ("returning existing controller");
+ }
}
self->properties = g_list_prepend (self->properties, prop);
}
} else {
GST_WARNING ("trying to control property again");
+ if (ref_existing) {
+ g_object_ref (self);
+ ref_existing = FALSE;
+ }
}
}
* Creates a new GstController for the given object's properties
*
* Returns: the new controller.
- * Since: 0.9
*/
GstController *
gst_controller_new (GObject * object, ...)
* Removes the given object properties from the controller
*
* Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_remove_properties_valist (GstController * self, va_list var_args)
* Removes the given object properties from the controller
*
* Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_remove_properties_list (GstController * self, GList * list)
* Removes the given object properties from the controller
*
* Returns: %FALSE if one of the given property isn't handled by the controller, %TRUE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_remove_properties (GstController * self, ...)
* Set the value of given controller-handled property at a certain time.
*
* Returns: FALSE if the values couldn't be set (ex : properties not handled by controller), TRUE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_set (GstController * self, gchar * property_name,
* Sets multiple timed values at once.
*
* Returns: %FALSE if the values couldn't be set (ex : properties not handled by controller), %TRUE otherwise
- * Since: 0.9
*/
gboolean
* time.
*
* Returns: %FALSE if the values couldn't be unset (ex : properties not handled by controller), %TRUE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_unset (GstController * self, gchar * property_name,
* time.
*
* Returns: the GValue of the property at the given time, or %NULL if the property isn't handled by the controller
- * Since: 0.9
*/
GValue *
gst_controller_get (GstController * self, gchar * property_name,
* Free the list after done with it.
*
* Returns: a copy of the list, or %NULL if the property isn't handled by the controller
- * Since: 0.9
*/
const GList *
gst_controller_get_all (GstController * self, gchar * property_name)
*
* Returns: %TRUE if the controller values could be applied to the object
* properties, %FALSE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_sync_values (GstController * self, GstClockTime timestamp)
* The type of the values in the array are the same as the property's type.
*
* Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_get_value_arrays (GstController * self,
* The type of the values in the array are the same as the property's type.
*
* Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_get_value_array (GstController * self, GstClockTime timestamp,
* Sets the given interpolation mode on the given property.
*
* Returns: %TRUE if the property is handled by the controller, %FALSE otherwise
- * Since: 0.9
*/
gboolean
gst_controller_set_interpolation_mode (GstController * self,
GST_END_TEST;
+GST_START_TEST (controller_refcount_new_list)
+{
+ GstController *ctrl, *ctrl2;
+ GstElement *elem;
+ GList *list = NULL;
+
+ gst_controller_init (NULL, NULL);
+
+ /* that property should exist and should be controllable */
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+ list = g_list_append (NULL, "ulong");
+ ctrl = gst_controller_new_list (G_OBJECT (elem), list);
+ fail_unless (ctrl != NULL, NULL);
+ GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+ fail_unless (G_OBJECT (ctrl)->ref_count == 1);
+ g_list_free (list);
+ g_object_unref (ctrl);
+ gst_object_unref (elem);
+
+ /* try the same property twice, make sure the refcount is still 1 */
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+ list = g_list_append (NULL, "ulong");
+ list = g_list_append (list, "ulong");
+ ctrl = gst_controller_new_list (G_OBJECT (elem), list);
+ fail_unless (ctrl != NULL, NULL);
+ GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+ fail_unless (G_OBJECT (ctrl)->ref_count == 1);
+ g_list_free (list);
+ g_object_unref (ctrl);
+ gst_object_unref (elem);
+
+ /* try two properties, make sure the refcount is still 1 */
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+ list = g_list_append (NULL, "ulong");
+ list = g_list_append (list, "boolean");
+ ctrl = gst_controller_new_list (G_OBJECT (elem), list);
+ fail_unless (ctrl != NULL, NULL);
+ GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+ fail_unless (G_OBJECT (ctrl)->ref_count == 1);
+ g_list_free (list);
+ g_object_unref (ctrl);
+ gst_object_unref (elem);
+
+ /* try _new_list with existing controller */
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+ ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
+ fail_unless (ctrl != NULL, NULL);
+ GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+ list = g_list_append (NULL, "ulong");
+ ctrl2 = gst_controller_new_list (G_OBJECT (elem), list);
+ fail_unless (ctrl2 != NULL, NULL);
+ fail_unless (ctrl == ctrl2, NULL);
+ GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+ fail_unless (G_OBJECT (ctrl)->ref_count == 2);
+ g_list_free (list);
+ g_object_unref (ctrl);
+ g_object_unref (ctrl2);
+ gst_object_unref (elem);
+
+ /* try _new_list first and then _new */
+ elem = gst_element_factory_make ("testmonosource", "test_source");
+ list = g_list_append (NULL, "ulong");
+ ctrl = gst_controller_new_list (G_OBJECT (elem), list);
+ fail_unless (ctrl != NULL, NULL);
+ GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+ ctrl2 = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
+ fail_unless (ctrl2 != NULL, NULL);
+ fail_unless (ctrl == ctrl2, NULL);
+ GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
+ fail_unless (G_OBJECT (ctrl)->ref_count == 2);
+ g_list_free (list);
+ g_object_unref (ctrl);
+ g_object_unref (ctrl2);
+ gst_object_unref (elem);
+}
+
+GST_END_TEST;
+
static Suite *
gst_controller_suite (void)
{
suite_add_tcase (s, tc);
tcase_add_test (tc, controller_init);
+ tcase_add_test (tc, controller_refcount_new_list);
tcase_add_test (tc, controller_new_fail1);
tcase_add_test (tc, controller_new_fail2);
tcase_add_test (tc, controller_new_fail3);