+2005-08-21 Thomas Vander Stichele <thomas at apestaart dot org>
+
+ * check/Makefile.am:
+ clean up environment for when registry gets built versus
+ when actual tests are run; valgrind seems to not report
+ leaks if GST_PLUGIN_PATH is set to some specific values
+ * check/gst/gstbin.c: (GST_START_TEST):
+ add more refcounting checks; maybe this exposes a
+ preroll lock bug ?
+ * common/check.mak:
+ * gst/base/gstbasesink.c: (gst_base_sink_handle_object):
+ * gst/check/gstcheck.h:
+ * gst/gstbin.c: (bin_element_is_semi_sink), (gst_bin_get_state),
+ (gst_bin_change_state):
+ * gst/gstpad.c: (gst_pad_activate_push), (gst_pad_chain):
+ add/fix debugging/whitespace
+
2005-08-21 Jan Schmidt <thaytan@mad.scientist.com>
* check/gst/gstevent.c: (event_probe), (test_event),
GST_TOOLS_DIR = $(top_builddir)/tools
-TESTS_ENVIRONMENT=\
+REGISTRY_ENVIRONMENT = \
GST_REGISTRY=$(CHECK_REGISTRY)
+TESTS_ENVIRONMENT = \
+ $(REGISTRY_ENVIRONMENT) \
+ GST_PLUGIN_PATH_ONLY=yes \
+ GST_PLUGIN_PATH=$(top_builddir)/gst
+
plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
# rebuild gst-register-@GST_MAJORMINOR@ if needed
$(CHECK_REGISTRY):
$(TESTS_ENVIRONMENT) \
- GST_PLUGIN_PATH_ONLY=yes \
- GST_PLUGIN_PATH=$(top_builddir)/gst \
- $(top_builddir)/tools/gst-register
+ $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@
-# FIXME: it'd be nicer to run the versioned register, but in that case
-# "make dist" complains about not finding gst-register-0.9.c
-TESTS = $(top_builddir)/tools/gst-register \
+check_PROGRAMS = \
gst/gst \
gst/gstbin \
gst/gstbuffer \
gst-libs/controller \
gst-libs/gdp
-check_PROGRAMS = $(TESTS)
+TESTS = $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \
+ $(check_PROGRAMS)
noinst_HEADERS = gst/capslist.h
gst/gstminiobject \
gst/gstobject
-VALGRIND_TESTS_DISABLE = \
- $(top_builddir)/tools/gst-register \
- $(TESTS_THREADED) \
+VALGRIND_TESTS_DISABLE = \
+ $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \
+ $(TESTS_THREADED) \
$(TESTS_TO_FIX)
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
- ASSERT_OBJECT_REFCOUNT (src, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
bus = GST_ELEMENT_BUS (pipeline);
- /* change state, spawning three times three messages */
+ /* change state to READY, spawning three messages */
+ GST_DEBUG ("setting pipeline to READY");
+ fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
+ == GST_STATE_SUCCESS);
+
+ /* each object is referenced by a message */
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+ pop_messages (bus, 3);
+ fail_if ((gst_bus_pop (bus)) != NULL);
+
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ /* change state to PAUSED, spawning three messages */
+ GST_DEBUG ("setting pipeline to PAUSED");
+ fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED)
+ == GST_STATE_SUCCESS);
+
+ /* each object is referenced by a message;
+ * base_sink_chain has taken a refcount on the sink, and is blocked on
+ * preroll */
+ ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+ pop_messages (bus, 3);
+ fail_if ((gst_bus_pop (bus)) != NULL);
+
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ /* change state to PLAYING, spawning three messages */
GST_DEBUG ("setting pipeline to PLAYING");
fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING)
== GST_STATE_SUCCESS);
- pop_messages (bus, 9);
+ /* each object is referenced by one message; sink still has an extra
+ * because it's still blocked on preroll */
+ ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+ pop_messages (bus, 3);
+ fail_if ((gst_bus_pop (bus)) != NULL);
- /* this test is completely bogus as the refcount can change while running */
-#if 0
ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
- ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
-#endif
/* go back to READY, spawning six messages */
+ /* FIXME: only now does the sink get unblocked from preroll
+ * (check log for "done preroll")
+ * mabe that's a bug ? */
GST_DEBUG ("setting pipeline to READY");
fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
== GST_STATE_SUCCESS);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
pop_messages (bus, 6);
+ fail_if ((gst_bus_pop (bus)) != NULL);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
-Subproject commit 609c7716bab17e1dc086d3b54b51740300ec6f0f
+Subproject commit aa2a757c587d91069a230d8e656481c3c364ccc6
/* GStreamer
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
*
- * gstbasesink.c:
+ * gstbasesink.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
GST_PREROLL_LOCK (pad);
/* push object on the queue */
- GST_DEBUG ("push on queue %p", basesink, obj);
+ GST_DEBUG_OBJECT (basesink, "push %p on preroll_queue", obj);
g_queue_push_tail (basesink->preroll_queue, obj);
have_event = GST_IS_EVENT (obj);
/* now we commit our state */
GST_STATE_LOCK (basesink);
- GST_DEBUG ("commit state %p >", basesink);
+ GST_DEBUG_OBJECT (basesink, "commit state");
gst_element_commit_state (GST_ELEMENT (basesink));
GST_STATE_UNLOCK (basesink);
* application thread and we don't want to block there. */
if (length > basesink->preroll_queue_max_len && !have_event) {
/* block until the state changes, or we get a flush, or something */
- GST_DEBUG ("element %s waiting to finish preroll",
+ GST_DEBUG_OBJECT (basesink, "waiting to finish preroll",
GST_ELEMENT_NAME (basesink));
GST_PREROLL_WAIT (pad);
- GST_DEBUG ("done preroll");
+ GST_DEBUG_OBJECT (basesink, "done preroll");
}
GST_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
g_warning ("STREAM_LOCK should have been locked !!");
}
GST_STATE_LOCK (basesink);
- GST_DEBUG ("commit state %p >", basesink);
+ GST_DEBUG_OBJECT (basesink, "commit state");
gst_element_commit_state (GST_ELEMENT (basesink));
GST_STATE_UNLOCK (basesink);
if (t > 0)
/* now we abort our state */
GST_STATE_LOCK (basesink);
- GST_DEBUG ("abort state %p >", basesink);
+ GST_DEBUG_OBJECT (basesink, "abort state");
gst_element_abort_state (GST_ELEMENT (basesink));
GST_STATE_UNLOCK (basesink);
return result;
}
-/* FIXME, not all sinks can operate in pull mode
+/* FIXME, not all sinks can operate in pull mode
*/
static void
gst_base_sink_loop (GstPad * pad)
int rc; \
rc = GST_OBJECT_REFCOUNT_VALUE (object); \
fail_unless (rc == value, \
- "%s refcount is %d instead of %d", name, rc, value); \
+ "%s (%p) refcount is %d instead of %d", \
+ name, object, rc, value); \
} G_STMT_END
#define ASSERT_CAPS_REFCOUNT(caps, name, value) \
for (pads = child->srcpads; pads; pads = g_list_next (pads)) {
GstPad *peer;
+ GST_DEBUG ("looking at pad %p", pads->data);
if ((peer = gst_pad_get_peer (GST_PAD_CAST (pads->data)))) {
connected_src =
has_ancestor (GST_OBJECT_CAST (peer), GST_OBJECT_CAST (bin));
GstElement *child = GST_ELEMENT_CAST (children->data);
gst_object_ref (child);
- /* now we release the lock to enter a non blocking wait. We
+ /* now we release the lock to enter a non blocking wait. We
* release the lock anyway since we can. */
GST_UNLOCK (bin);
/* take base time */
base_time = element->base_time;
- /* make sure queues are empty, they could be filled when
+ /* make sure queues are empty, they could be filled when
* restarting. */
clear_queue (elem_queue, TRUE);
clear_queue (semi_queue, TRUE);
children = bin->children;
children_cookie = bin->children_cookie;
+ GST_DEBUG_OBJECT (bin, "reffing and examining children");
while (children) {
GstElement *child = GST_ELEMENT_CAST (children->data);
}
children = g_list_next (children);
}
+ GST_DEBUG_OBJECT (bin, "reffed and examined children");
GST_UNLOCK (bin);
+
/* after this point new elements can be added/removed from the
* bin. We operate on the snapshot taken above. Applications
* should serialize their add/remove and set_state. */
}
/* second step, change state of elements in the queue */
+ GST_DEBUG_OBJECT (bin, "change state of elements in the queue");
while (!g_queue_is_empty (elem_queue)) {
GstElement *qelement;
GList *pads;
GstActivateMode old;
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+ GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "trying to set %s in push mode",
+ active ? "activated" : "deactivated");
GST_LOCK (pad);
old = GST_PAD_ACTIVATE_MODE (pad);
goto not_negotiated;
}
- /* NOTE: we read the chainfunc unlocked.
+ /* NOTE: we read the chainfunc unlocked.
* we cannot hold the lock for the pad so we might send
* the data to the wrong function. This is not really a
* problem since functions are assigned at creation time
ret = chainfunc (pad, buffer);
+ GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+ "called chainfunction &%s of pad %s:%s, returned %d",
+ GST_DEBUG_FUNCPTR_NAME (chainfunc), GST_DEBUG_PAD_NAME (pad), ret);
+
GST_STREAM_UNLOCK (pad);
return ret;
/* GStreamer
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
*
- * gstbasesink.c:
+ * gstbasesink.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
GST_PREROLL_LOCK (pad);
/* push object on the queue */
- GST_DEBUG ("push on queue %p", basesink, obj);
+ GST_DEBUG_OBJECT (basesink, "push %p on preroll_queue", obj);
g_queue_push_tail (basesink->preroll_queue, obj);
have_event = GST_IS_EVENT (obj);
/* now we commit our state */
GST_STATE_LOCK (basesink);
- GST_DEBUG ("commit state %p >", basesink);
+ GST_DEBUG_OBJECT (basesink, "commit state");
gst_element_commit_state (GST_ELEMENT (basesink));
GST_STATE_UNLOCK (basesink);
* application thread and we don't want to block there. */
if (length > basesink->preroll_queue_max_len && !have_event) {
/* block until the state changes, or we get a flush, or something */
- GST_DEBUG ("element %s waiting to finish preroll",
+ GST_DEBUG_OBJECT (basesink, "waiting to finish preroll",
GST_ELEMENT_NAME (basesink));
GST_PREROLL_WAIT (pad);
- GST_DEBUG ("done preroll");
+ GST_DEBUG_OBJECT (basesink, "done preroll");
}
GST_LOCK (pad);
if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
g_warning ("STREAM_LOCK should have been locked !!");
}
GST_STATE_LOCK (basesink);
- GST_DEBUG ("commit state %p >", basesink);
+ GST_DEBUG_OBJECT (basesink, "commit state");
gst_element_commit_state (GST_ELEMENT (basesink));
GST_STATE_UNLOCK (basesink);
if (t > 0)
/* now we abort our state */
GST_STATE_LOCK (basesink);
- GST_DEBUG ("abort state %p >", basesink);
+ GST_DEBUG_OBJECT (basesink, "abort state");
gst_element_abort_state (GST_ELEMENT (basesink));
GST_STATE_UNLOCK (basesink);
return result;
}
-/* FIXME, not all sinks can operate in pull mode
+/* FIXME, not all sinks can operate in pull mode
*/
static void
gst_base_sink_loop (GstPad * pad)
int rc; \
rc = GST_OBJECT_REFCOUNT_VALUE (object); \
fail_unless (rc == value, \
- "%s refcount is %d instead of %d", name, rc, value); \
+ "%s (%p) refcount is %d instead of %d", \
+ name, object, rc, value); \
} G_STMT_END
#define ASSERT_CAPS_REFCOUNT(caps, name, value) \
GST_TOOLS_DIR = $(top_builddir)/tools
-TESTS_ENVIRONMENT=\
+REGISTRY_ENVIRONMENT = \
GST_REGISTRY=$(CHECK_REGISTRY)
+TESTS_ENVIRONMENT = \
+ $(REGISTRY_ENVIRONMENT) \
+ GST_PLUGIN_PATH_ONLY=yes \
+ GST_PLUGIN_PATH=$(top_builddir)/gst
+
plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
# rebuild gst-register-@GST_MAJORMINOR@ if needed
$(CHECK_REGISTRY):
$(TESTS_ENVIRONMENT) \
- GST_PLUGIN_PATH_ONLY=yes \
- GST_PLUGIN_PATH=$(top_builddir)/gst \
- $(top_builddir)/tools/gst-register
+ $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@
-# FIXME: it'd be nicer to run the versioned register, but in that case
-# "make dist" complains about not finding gst-register-0.9.c
-TESTS = $(top_builddir)/tools/gst-register \
+check_PROGRAMS = \
gst/gst \
gst/gstbin \
gst/gstbuffer \
gst-libs/controller \
gst-libs/gdp
-check_PROGRAMS = $(TESTS)
+TESTS = $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \
+ $(check_PROGRAMS)
noinst_HEADERS = gst/capslist.h
gst/gstminiobject \
gst/gstobject
-VALGRIND_TESTS_DISABLE = \
- $(top_builddir)/tools/gst-register \
- $(TESTS_THREADED) \
+VALGRIND_TESTS_DISABLE = \
+ $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \
+ $(TESTS_THREADED) \
$(TESTS_TO_FIX)
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
- ASSERT_OBJECT_REFCOUNT (src, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
bus = GST_ELEMENT_BUS (pipeline);
- /* change state, spawning three times three messages */
+ /* change state to READY, spawning three messages */
+ GST_DEBUG ("setting pipeline to READY");
+ fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
+ == GST_STATE_SUCCESS);
+
+ /* each object is referenced by a message */
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+ pop_messages (bus, 3);
+ fail_if ((gst_bus_pop (bus)) != NULL);
+
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ /* change state to PAUSED, spawning three messages */
+ GST_DEBUG ("setting pipeline to PAUSED");
+ fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED)
+ == GST_STATE_SUCCESS);
+
+ /* each object is referenced by a message;
+ * base_sink_chain has taken a refcount on the sink, and is blocked on
+ * preroll */
+ ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+ pop_messages (bus, 3);
+ fail_if ((gst_bus_pop (bus)) != NULL);
+
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ /* change state to PLAYING, spawning three messages */
GST_DEBUG ("setting pipeline to PLAYING");
fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING)
== GST_STATE_SUCCESS);
- pop_messages (bus, 9);
+ /* each object is referenced by one message; sink still has an extra
+ * because it's still blocked on preroll */
+ ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+ pop_messages (bus, 3);
+ fail_if ((gst_bus_pop (bus)) != NULL);
- /* this test is completely bogus as the refcount can change while running */
-#if 0
ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
- ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
-#endif
/* go back to READY, spawning six messages */
+ /* FIXME: only now does the sink get unblocked from preroll
+ * (check log for "done preroll")
+ * mabe that's a bug ? */
GST_DEBUG ("setting pipeline to READY");
fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
== GST_STATE_SUCCESS);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
pop_messages (bus, 6);
+ fail_if ((gst_bus_pop (bus)) != NULL);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);