+2005-05-05 Wim Taymans <wim@fluendo.com>
+
+ * 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 <wingo@pobox.com>
* check/Makefile.am:
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) {
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);
#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);
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);
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);
}
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);
}
/**
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;
+ }
+}
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);
if (oclass->request_new_pad)
newpad = (oclass->request_new_pad) (element, templ, name);
+ if (newpad)
+ gst_object_ref (GST_OBJECT (newpad));
+
return newpad;
}
* 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)
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;
/* 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));
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));
#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
#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
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);
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;
if (oclass->request_new_pad)
newpad = (oclass->request_new_pad) (element, templ, name);
+ if (newpad)
+ gst_object_ref (GST_OBJECT (newpad));
+
return newpad;
}
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);