+2005-07-09 Thomas Vander Stichele <thomas at apestaart dot org>
+
+ * check/gst/gstbin.c: (START_TEST), (gst_bin_suite):
+ add test for state change message on a bin
+ * check/gst/gstelement.c: (START_TEST), (gst_element_suite):
+ add another test
+ * gst/gstbin.c: (gst_bin_init):
+ * gst/gstbus.c: (gst_bus_init), (gst_bus_post):
+ * gst/gstelement.c: (gst_element_post_message),
+ (gst_element_set_state):
+ * gst/gstelementfactory.c: (gst_element_factory_create):
+ * gst/gstmessage.c: (gst_message_new):
+ * gst/gstscheduler.c:
+ various debugging additions and cleanups
+
2005-07-08 Thomas Vander Stichele <thomas at apestaart dot org>
* check/Makefile.am:
/* GStreamer
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart dot org>
*
* gstbin.c: Unit test for GstBin
*
gst_object_unref (bin);
}
-END_TEST Suite *
+
+END_TEST;
+
+START_TEST (test_message_state_changed)
+{
+ GstBin *bin;
+ GstBus *bus;
+ GstMessage *message;
+
+ bin = GST_BIN (gst_bin_new (NULL));
+ fail_unless (bin != NULL, "Could not create bin");
+ ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
+
+ bus = GST_ELEMENT_BUS (bin);
+
+ /* change state, spawning a message, causing an incref on the bin */
+ gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
+
+ ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
+
+ /* get and unref the message, causing a decref on the bin */
+ fail_unless (gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED,
+ -1) == GST_MESSAGE_STATE_CHANGED,
+ "did not get GST_MESSAGE_STATE_CHANGED");
+
+ message = gst_bus_pop (bus);
+ gst_message_unref (message);
+
+ ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
+
+ /* clean up */
+ gst_object_unref (bin);
+}
+
+END_TEST;
+
+Suite *
gst_bin_suite (void)
{
Suite *s = suite_create ("GstBin");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_interface);
+ tcase_add_test (tc_chain, test_message_state_changed);
return s;
}
#include "../gstcheck.h"
-START_TEST (test_add_pad)
+START_TEST (test_add_remove_pad)
{
GstElement *e;
GstPad *p;
END_TEST;
+START_TEST (test_add_pad_unref_element)
+{
+ GstElement *e;
+ GstPad *p;
+
+ /* getting an existing element class is cheating, but easier */
+ e = gst_element_factory_make ("fakesrc", "source");
+
+ /* create a new floating pad with refcount 1 */
+ p = gst_pad_new ("source", GST_PAD_SRC);
+ ASSERT_OBJECT_REFCOUNT (p, "pad", 1);
+ /* ref it for ourselves */
+ gst_object_ref (p);
+ ASSERT_OBJECT_REFCOUNT (p, "pad", 2);
+ /* adding it sinks the pad -> not floating, same refcount */
+ gst_element_add_pad (e, p);
+ ASSERT_OBJECT_REFCOUNT (p, "pad", 2);
+
+ /* unreffing the element should clean it up */
+ gst_object_unref (GST_OBJECT (e));
+
+ ASSERT_OBJECT_REFCOUNT (p, "pad", 1);
+
+ /* clean up our own reference */
+ gst_object_unref (p);
+}
+
+END_TEST;
+
+
Suite *
gst_element_suite (void)
{
TCase *tc_chain = tcase_create ("element tests");
suite_add_tcase (s, tc_chain);
- tcase_add_test (tc_chain, test_add_pad);
+ tcase_add_test (tc_chain, test_add_remove_pad);
+ tcase_add_test (tc_chain, test_add_pad_unref_element);
return s;
}
bin->children_cookie = 0;
bin->eosed = NULL;
- /* Set up a bus for listening to child elements,
+ /* Set up a bus for listening to child elements,
* and one for sending messages up the hierarchy */
bus = g_object_new (gst_bus_get_type (), NULL);
bin->child_bus = bus;
bus->queue = g_queue_new ();
bus->queue_lock = g_mutex_new ();
+ GST_DEBUG_OBJECT (bus, "created");
+
return;
}
g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
- GST_DEBUG_OBJECT (bus, "posting message on bus, type %d",
- GST_MESSAGE_TYPE (message));
+ GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus, type %d",
+ message, GST_MESSAGE_TYPE (message));
GST_LOCK (bus);
if (GST_FLAG_IS_SET (bus, GST_BUS_FLUSHING)) {
switch (reply) {
case GST_BUS_DROP:
/* drop the message */
+ GST_DEBUG_OBJECT (bus, "[msg %p] dropped", message);
break;
case GST_BUS_PASS:
/* pass the message to the async queue */
+ GST_DEBUG_OBJECT (bus, "[msg %p] pushing on async queue", message);
g_mutex_lock (bus->queue_lock);
g_queue_push_tail (bus->queue, message);
g_mutex_unlock (bus->queue_lock);
+ GST_DEBUG_OBJECT (bus, "[msg %p] pushed on async queue", message);
/* FIXME cannot assume the source is only in the default context */
g_main_context_wakeup (NULL);
GST_MESSAGE_COND (message) = cond;
GST_MESSAGE_GET_LOCK (message) = lock;
- GST_DEBUG ("waiting for async delivery of message %p", message);
+ GST_DEBUG_OBJECT (bus, "[msg %p] waiting for async delivery", message);
/* now we lock the message mutex, send the message to the async
- * queue. When the message is handled by the app and destroyed,
+ * queue. When the message is handled by the app and destroyed,
* the cond will be signalled and we can continue */
g_mutex_lock (lock);
g_mutex_lock (bus->queue_lock);
g_cond_wait (cond, lock);
g_mutex_unlock (lock);
- GST_DEBUG ("message %p delivered asynchronously", message);
+ GST_DEBUG_OBJECT (bus, "[msg %p] delivered asynchronously", message);
g_mutex_free (lock);
g_cond_free (cond);
*
* Post a message on the elements #GstBus.
*
- * Returns: TRUE if the message was successfuly posted.
+ * Returns: TRUE if the message was successfully posted.
*
* MT safe.
*/
return FALSE;
}
gst_object_ref (bus);
- GST_DEBUG ("... on bus %p", bus);
+ GST_DEBUG ("... on bus %" GST_PTR_FORMAT, bus);
GST_UNLOCK (element);
result = gst_bus_post (bus, message);
goto exit;
case GST_STATE_SUCCESS:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
- "element changed state successfuly");
+ "element changed state successfully");
/* we can commit the state now and proceed to the next state */
gst_element_commit_state (element);
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
break;
case GST_STATE_NO_PREROLL:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
- "element changed state successfuly and can't preroll");
+ "element changed state successfully and can't preroll");
/* we can commit the state now and proceed to the next state */
gst_element_commit_state (element);
GST_STATE_NO_PREROLL (element) = TRUE;
if (name)
gst_object_set_name (GST_OBJECT (element), name);
- GST_DEBUG ("created \"%s\" at", GST_PLUGIN_FEATURE_NAME (factory));
+ GST_DEBUG ("created \"%s\"", GST_PLUGIN_FEATURE_NAME (factory));
return element;
}
message->type = type;
if (src) {
message->src = gst_object_ref (src);
+ GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, src, "message source");
} else {
message->src = NULL;
+ GST_CAT_DEBUG (GST_CAT_MESSAGE, "NULL message source");
}
message->structure = NULL;
* @name: the name of the factory used to create the instance
* @parent: the parent element of this scheduler
*
- * Create a new #GstScheduler instance from the
+ * Create a new #GstScheduler instance from the
* schedulerfactory with the given name and parent. @parent will
* have its scheduler set to the returned #GstScheduler instance.
* If %NULL is passed as @name, the default scheduler name will
/* GStreamer
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart dot org>
*
* gstbin.c: Unit test for GstBin
*
gst_object_unref (bin);
}
-END_TEST Suite *
+
+END_TEST;
+
+START_TEST (test_message_state_changed)
+{
+ GstBin *bin;
+ GstBus *bus;
+ GstMessage *message;
+
+ bin = GST_BIN (gst_bin_new (NULL));
+ fail_unless (bin != NULL, "Could not create bin");
+ ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
+
+ bus = GST_ELEMENT_BUS (bin);
+
+ /* change state, spawning a message, causing an incref on the bin */
+ gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
+
+ ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
+
+ /* get and unref the message, causing a decref on the bin */
+ fail_unless (gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED,
+ -1) == GST_MESSAGE_STATE_CHANGED,
+ "did not get GST_MESSAGE_STATE_CHANGED");
+
+ message = gst_bus_pop (bus);
+ gst_message_unref (message);
+
+ ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
+
+ /* clean up */
+ gst_object_unref (bin);
+}
+
+END_TEST;
+
+Suite *
gst_bin_suite (void)
{
Suite *s = suite_create ("GstBin");
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_interface);
+ tcase_add_test (tc_chain, test_message_state_changed);
return s;
}
#include "../gstcheck.h"
-START_TEST (test_add_pad)
+START_TEST (test_add_remove_pad)
{
GstElement *e;
GstPad *p;
END_TEST;
+START_TEST (test_add_pad_unref_element)
+{
+ GstElement *e;
+ GstPad *p;
+
+ /* getting an existing element class is cheating, but easier */
+ e = gst_element_factory_make ("fakesrc", "source");
+
+ /* create a new floating pad with refcount 1 */
+ p = gst_pad_new ("source", GST_PAD_SRC);
+ ASSERT_OBJECT_REFCOUNT (p, "pad", 1);
+ /* ref it for ourselves */
+ gst_object_ref (p);
+ ASSERT_OBJECT_REFCOUNT (p, "pad", 2);
+ /* adding it sinks the pad -> not floating, same refcount */
+ gst_element_add_pad (e, p);
+ ASSERT_OBJECT_REFCOUNT (p, "pad", 2);
+
+ /* unreffing the element should clean it up */
+ gst_object_unref (GST_OBJECT (e));
+
+ ASSERT_OBJECT_REFCOUNT (p, "pad", 1);
+
+ /* clean up our own reference */
+ gst_object_unref (p);
+}
+
+END_TEST;
+
+
Suite *
gst_element_suite (void)
{
TCase *tc_chain = tcase_create ("element tests");
suite_add_tcase (s, tc_chain);
- tcase_add_test (tc_chain, test_add_pad);
+ tcase_add_test (tc_chain, test_add_remove_pad);
+ tcase_add_test (tc_chain, test_add_pad_unref_element);
return s;
}