diff --git a/ChangeLog b/ChangeLog index 68b58c78da..2fcfd2c41f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2005-05-05 Wim Taymans + + * gst/gstbin.c: (gst_bin_send_event), (compare_name), + (gst_bin_get_by_name): + * gst/gstbuffer.h: + * gst/gstclock.c: (gst_clock_entry_new), (gst_clock_class_init), + (gst_clock_finalize): + * gst/gstdata.c: (gst_data_replace): + * gst/gstdata.h: + * gst/gstelement.c: (gst_element_request_pad), + (gst_element_pads_activate): + * gst/gstobject.c: (gst_object_init), (gst_object_ref), + (gst_object_unref): + * gst/gstpad.c: (gst_pad_set_active), (gst_pad_peer_set_active), + (gst_pad_set_checkgetrange_function), + (gst_pad_link_check_compatible_unlocked), (gst_pad_set_caps), + (gst_pad_check_pull_range), (gst_pad_pull_range), + (gst_static_pad_template_get_caps), (gst_pad_start_task), + (gst_pad_pause_task), (gst_pad_stop_task): + * gst/gstutils.c: (gst_element_get_compatible_pad_template), + (gst_element_request_pad), (gst_pad_proxy_getcaps): + Fix name lookup in GstBin. + Added _data_replace() function and _buffer_replace() + Use finalize method to clean up clock. + Fix refcounting on request pads. + Fix pad schedule mode error. + Some more object refcounting debug info, + + 2005-05-04 Andy Wingo * check/Makefile.am: diff --git a/gst/gstbin.c b/gst/gstbin.c index f15c4dd2c3..15cd1b77bf 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -1102,7 +1102,7 @@ compare_name (GstElement * element, const gchar * name) gint eq; GST_LOCK (element); - eq = strcmp (GST_ELEMENT_NAME (element), name) == 0; + eq = strcmp (GST_ELEMENT_NAME (element), name); GST_UNLOCK (element); if (eq != 0) { @@ -1133,6 +1133,9 @@ gst_bin_get_by_name (GstBin * bin, const gchar * name) g_return_val_if_fail (GST_IS_BIN (bin), NULL); + GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s", + GST_ELEMENT_NAME (bin), name); + children = gst_bin_iterate_recurse (bin); result = gst_iterator_find_custom (children, (GCompareFunc) compare_name, (gpointer) name); diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h index c30af9577f..915e5e6d97 100644 --- a/gst/gstbuffer.h +++ b/gst/gstbuffer.h @@ -159,6 +159,8 @@ G_STMT_START { \ #define gst_buffer_is_writable(buf) gst_data_is_writable (GST_DATA (buf)) #define gst_buffer_copy_on_write(buf) GST_BUFFER (gst_data_copy_on_write (GST_DATA (buf))) +#define gst_buffer_replace(obuf,nbuf) gst_data_replace ((GstData **)(obuf), GST_DATA (nbuf)) + GstCaps* gst_buffer_get_caps (GstBuffer *buffer); void gst_buffer_set_caps (GstBuffer *buffer, GstCaps *caps); diff --git a/gst/gstclock.c b/gst/gstclock.c index 7f3a199a93..f9322c8e70 100644 --- a/gst/gstclock.c +++ b/gst/gstclock.c @@ -51,7 +51,7 @@ static GstMemChunk *_gst_clock_entries_chunk; static void gst_clock_class_init (GstClockClass * klass); static void gst_clock_init (GstClock * clock); -static void gst_clock_dispose (GObject * object); +static void gst_clock_finalize (GObject * object); static void gst_clock_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); @@ -457,7 +457,7 @@ gst_clock_class_init (GstClockClass * klass) gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME); #endif - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_clock_dispose); + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_clock_finalize); gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_clock_set_property); gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_clock_get_property); @@ -478,13 +478,13 @@ gst_clock_init (GstClock * clock) } static void -gst_clock_dispose (GObject * object) +gst_clock_finalize (GObject * object) { GstClock *clock = GST_CLOCK (object); g_cond_free (clock->entries_changed); - G_OBJECT_CLASS (parent_class)->dispose (object); + G_OBJECT_CLASS (parent_class)->finalize (object); } /** diff --git a/gst/gstdata.c b/gst/gstdata.c index 0dac173f06..ba1bfe28f9 100644 --- a/gst/gstdata.c +++ b/gst/gstdata.c @@ -264,3 +264,29 @@ gst_data_unref (GstData * data) data->free (data); } } + +/** + * gst_data_replace: + * @olddata: pointer to place of old GstData + * @newdata: new GstData + * + * Unrefs the data pointer to by olddata, refs the newdata and + * puts the newdata in *olddata. Be carefull when calling this + * function, it does not take any locks. You might want to lock + * the object owning the olddata pointer before calling this + * function. + * + * MT safe. + */ +void +gst_data_replace (GstData ** olddata, GstData * newdata) +{ + if (G_LIKELY (*olddata != newdata)) { + if (newdata) + gst_data_ref (newdata); + if (*olddata) + gst_data_unref (*olddata); + + *olddata = newdata; + } +} diff --git a/gst/gstdata.h b/gst/gstdata.h index 88ba8627d3..7d94fb845f 100644 --- a/gst/gstdata.h +++ b/gst/gstdata.h @@ -100,6 +100,9 @@ GstData* gst_data_ref (GstData* data); GstData* gst_data_ref_by_count (GstData* data, gint count); void gst_data_unref (GstData* data); +/* replace data pointer */ +void gst_data_replace (GstData** olddata, GstData *newdata); + /* GType for GstData */ GType gst_data_get_type (void); diff --git a/gst/gstelement.c b/gst/gstelement.c index b9ab2e49e8..821f2c3931 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -754,6 +754,9 @@ gst_element_request_pad (GstElement * element, GstPadTemplate * templ, if (oclass->request_new_pad) newpad = (oclass->request_new_pad) (element, templ, name); + if (newpad) + gst_object_ref (GST_OBJECT (newpad)); + return newpad; } @@ -765,7 +768,7 @@ gst_element_request_pad (GstElement * element, GstPadTemplate * templ, * Retrieves a pad from the element by name. This version only retrieves * request pads. * - * Returns: requested #GstPad if found, otherwise NULL. + * Returns: requested #GstPad if found, otherwise NULL. Unref after usage. */ GstPad * gst_element_get_request_pad (GstElement * element, const gchar * name) @@ -1997,6 +2000,9 @@ restart: gst_object_ref (GST_OBJECT (peer)); GST_UNLOCK (pad); + GST_DEBUG ("pad %s:%s: get: %d, random: %d, loop: %d", + GST_DEBUG_PAD_NAME (pad), pad_get, pad_random, pad_loop); + if (peer) { gboolean peer_loop, peer_get; gboolean peer_random = FALSE; @@ -2007,10 +2013,14 @@ restart: /* see if the peer has a loop function */ peer_loop = GST_RPAD_LOOPFUNC (peer) != NULL; + GST_DEBUG ("peer %s:%s: get: %d, random: %d, loop: %d", + GST_DEBUG_PAD_NAME (peer), peer_get, peer_random, peer_loop); + /* If the pad is a sink with loop and the peer has a get function, - * we can activate the sinkpad */ - if ((GST_PAD_IS_SINK (pad) && pad_loop && peer_get) || - (GST_PAD_IS_SRC (pad) && peer_loop && pad_get)) { + * we can activate the sinkpad, FIXME, logic is reversed as + * check_pull_range() checks the peer of the given pad. */ + if ((GST_PAD_IS_SINK (pad) && pad_get && peer_loop) || + (GST_PAD_IS_SRC (pad) && peer_get && pad_loop)) { GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "%sactivating pad %s pull mode", (active ? "" : "(de)"), GST_OBJECT_NAME (pad)); diff --git a/gst/gstobject.c b/gst/gstobject.c index 0143e57781..ab19c4993e 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -210,6 +210,7 @@ gst_object_init (GTypeInstance * instance, gpointer g_class) object->lock = g_mutex_new (); object->parent = NULL; object->name = NULL; + GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p new", object); gst_atomic_int_set (&object->refcount, 1); PATCH_REFCOUNT (object); gst_object_set_name_default (object, G_OBJECT_CLASS_NAME (g_class)); @@ -261,11 +262,13 @@ gst_object_ref (GstObject * object) #ifdef DEBUG_REFCOUNT #ifdef REFCOUNT_HACK - GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "ref %d->%d", + GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref %d->%d", + object, GST_OBJECT_REFCOUNT_VALUE (object), GST_OBJECT_REFCOUNT_VALUE (object) + 1); #else - GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "ref %d->%d", + GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref %d->%d", + object, ((GObject *) object)->ref_count, ((GObject *) object)->ref_count + 1); #endif #endif @@ -311,11 +314,13 @@ gst_object_unref (GstObject * object) #ifdef DEBUG_REFCOUNT #ifdef REFCOUNT_HACK - GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unref %d->%d", + GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p unref %d->%d", + object, GST_OBJECT_REFCOUNT_VALUE (object), GST_OBJECT_REFCOUNT_VALUE (object) - 1); #else - GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unref %d->%d", + GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "%p unref %d->%d", + object, ((GObject *) object)->ref_count, ((GObject *) object)->ref_count - 1); #endif #endif diff --git a/gst/gstpad.c b/gst/gstpad.c index 0da4356f90..54968035a6 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -1996,7 +1996,7 @@ gst_pad_set_caps (GstPad * pad, GstCaps * caps) if (caps) caps = gst_caps_ref (caps); - GST_PAD_CAPS (pad) = caps; + gst_caps_replace (&GST_PAD_CAPS (pad), caps); GST_CAT_DEBUG (GST_CAT_CAPS, "%s:%s caps %" GST_PTR_FORMAT, GST_DEBUG_PAD_NAME (pad), caps); GST_UNLOCK (pad); diff --git a/gst/gstutils.c b/gst/gstutils.c index 164fbee2cb..e9648ca950 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -451,11 +451,16 @@ gst_element_get_compatible_pad_template (GstElement * element, padtempl->direction == GST_PAD_SRC ? "src" : "sink", padtempl->name_template); + GST_CAT_DEBUG (GST_CAT_CAPS, + "intersecting %" GST_PTR_FORMAT, GST_PAD_TEMPLATE_CAPS (compattempl)); + GST_CAT_DEBUG (GST_CAT_CAPS, + "..and %" GST_PTR_FORMAT, GST_PAD_TEMPLATE_CAPS (padtempl)); + intersection = gst_caps_intersect (GST_PAD_TEMPLATE_CAPS (compattempl), GST_PAD_TEMPLATE_CAPS (padtempl)); - GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible", - (intersection ? "" : "not ")); + GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible %" GST_PTR_FORMAT, + (intersection ? "" : "not "), intersection); if (!gst_caps_is_empty (intersection)) newtempl = padtempl; @@ -487,6 +492,9 @@ gst_element_request_pad (GstElement * element, GstPadTemplate * templ, if (oclass->request_new_pad) newpad = (oclass->request_new_pad) (element, templ, name); + if (newpad) + gst_object_ref (GST_OBJECT (newpad)); + return newpad; } @@ -1571,6 +1579,8 @@ gst_pad_proxy_getcaps (GstPad * pad) GST_DEBUG ("proxying getcaps for %s:%s", GST_DEBUG_PAD_NAME (pad)); element = gst_pad_get_parent (pad); + if (element == NULL) + return NULL; iter = gst_element_iterate_pads (element);