From: Benjamin O. <co...@pd...> - 2004-05-03 16:12:16
|
CVS Root: /home/cvs/gstreamer Module: gst-sandbox Changes by: company Date: Mon May 03 2004 09:12:12 PDT Log message: * configure.ac: * elements/Makefile.am: * elements/deb.c: * elements/deb.h: * elements/identity.c: * elements/identity.h: * elements/plugin.c: (plugin_init): add element based on convertmanager * Makefile.am: add elements/ dir and disable src/ dir until someone actively starts hacking on it again * gst/autoplug/.cvsignore: add for marshals * gst/autoplug/convertmanager.c: * gst/autoplug/elementlink.c: * gst/autoplug/link.c: * gst/autoplug/link.h: * gst/autoplug/manager.c: * gst/autoplug/manager.h: add stuff to make autoplugging not leak * gst/autoplug/utils.c: * gst/autoplug/utils.h: add gst_ap_disconnect to diconnect a known number of handlers from an object * testsuite/Makefile.am: * testsuite/elements/.cvsignore: * testsuite/elements/Makefile.am: * testsuite/elements/deb-simple.c: (main): * testsuite/elements/deb.c: (not_reached), (main): add tests for new element * testsuite/files/sine.mp3: new test file * testsuite/managers/convertmanager-simple.c: (main): * testsuite/managers/convertmanager.c: (main): update for refcounting fixes Modified files: gst-autoplug : ChangeLog Makefile.am configure.ac gst-autoplug/gst/autoplug: convertmanager.c elementlink.c link.c link.h manager.c manager.h utils.c utils.h gst-autoplug/testsuite: Makefile.am gst-autoplug/testsuite/managers: convertmanager-simple.c convertmanager.c Added files: gst-autoplug/elements: Makefile.am deb.c deb.h identity.c identity.h plugin.c gst-autoplug/gst/autoplug: .cvsignore gst-autoplug/testsuite/elements: .cvsignore Makefile.am deb-simple.c deb.c gst-autoplug/testsuite/files: sine.mp3 Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/ChangeLog.diff?r1=1.10&r2=1.11 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/Makefile.am.diff?r1=1.3&r2=1.4 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/configure.ac.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/elements/Makefile.am?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/elements/deb.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/elements/deb.h?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/elements/identity.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/elements/identity.h?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/elements/plugin.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/.cvsignore?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/convertmanager.c.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/elementlink.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/link.c.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/link.h.diff?r1=1.5&r2=1.6 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/manager.c.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/manager.h.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/utils.c.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/utils.h.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/testsuite/Makefile.am.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/testsuite/elements/.cvsignore?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/testsuite/elements/Makefile.am?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/testsuite/elements/deb-simple.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/testsuite/elements/deb.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/testsuite/files/sine.mp3?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/testsuite/managers/convertmanager-simple.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-autoplug/testsuite/managers/convertmanager.c.diff?r1=1.1&r2=1.2 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/ChangeLog,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- a/ChangeLog 26 Apr 2004 23:46:00 -0000 1.10 +++ b/ChangeLog 3 May 2004 16:11:59 -0000 1.11 @@ -1,3 +1,41 @@ +2004-05-03 Benjamin Otte <in...@pu...> + + * configure.ac: + * elements/Makefile.am: + * elements/deb.c: + * elements/deb.h: + * elements/identity.c: + * elements/identity.h: + * elements/plugin.c: (plugin_init): + add element based on convertmanager + * Makefile.am: + add elements/ dir and disable src/ dir until someone actively starts + hacking on it again + * gst/autoplug/.cvsignore: + add for marshals + * gst/autoplug/convertmanager.c: + * gst/autoplug/elementlink.c: + * gst/autoplug/link.c: + * gst/autoplug/link.h: + * gst/autoplug/manager.c: + * gst/autoplug/manager.h: + add stuff to make autoplugging not leak + * gst/autoplug/utils.c: + * gst/autoplug/utils.h: + add gst_ap_disconnect to diconnect a known number of handlers from + an object + * testsuite/Makefile.am: + * testsuite/elements/.cvsignore: + * testsuite/elements/Makefile.am: + * testsuite/elements/deb-simple.c: (main): + * testsuite/elements/deb.c: (not_reached), (main): + add tests for new element + * testsuite/files/sine.mp3: + new test file + * testsuite/managers/convertmanager-simple.c: (main): + * testsuite/managers/convertmanager.c: (main): + update for refcounting fixes 2004-04-26 Benjamin Otte <in...@pu...> * gst/autoplug/path.c: Index: Makefile.am RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/Makefile.am,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- a/Makefile.am 6 Feb 2004 16:20:09 -0000 1.3 +++ b/Makefile.am 3 May 2004 16:11:59 -0000 1.4 @@ -1,3 +1,5 @@ -SUBDIRS=gst src po testsuite +SUBDIRS=gst elements po testsuite +DIST_SUBDIRS=$(SUBDIRS) src EXTRA_DIST=depcomp gettext.patch Index: configure.ac RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/configure.ac,v retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- a/configure.ac 20 Apr 2004 16:34:53 -0000 1.4 +++ b/configure.ac 3 May 2004 16:11:59 -0000 1.5 @@ -55,8 +55,7 @@ GST_MAJORMINOR=0.8 PKG_CHECK_MODULES(GST, \ - gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED \ - gstreamer-control-$GST_MAJORMINOR >= $GST_REQUIRED, + gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED, HAVE_GST=yes,HAVE_GST=no) dnl Give error and exit if we don't have gstreamer @@ -98,11 +97,13 @@ AC_OUTPUT( Makefile + elements/Makefile gst/Makefile gst/autoplug/Makefile po/Makefile.in src/Makefile testsuite/Makefile + testsuite/elements/Makefile testsuite/files/Makefile testsuite/managers/Makefile testsuite/selectors/Makefile --- NEW FILE: Makefile.am --- plugindir= $(libdir)/gstreamer-@GST_MAJORMINOR@ plugin_LTLIBRARIES = libgstautoplug.la libgstautoplug_la_SOURCES = identity.c deb.c plugin.c libgstautoplug_la_CFLAGS = $(GST_AP_CFLAGS) libgstautoplug_la_LDFLAGS = $(GST_AP_LIBS) noinst_HEADERS = identity.h --- NEW FILE: deb.c --- /* * GStreamer * Copyright (C) 2004 Benjamin Otte <ot...@gn...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "deb.h" #include <gst/autoplug/convertmanager.h> static GstStaticPadTemplate gst_ap_deb_sink_template = GST_STATIC_PAD_TEMPLATE ( "sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY ); static GstStaticPadTemplate gst_ap_deb_src_template = "src", GST_PAD_SRC, static void gst_ap_deb_class_init (GstApDebClass *klass); static void gst_ap_deb_base_init (GstApDebClass *klass); static void gst_ap_deb_init (GstApDeb *deb); static void gst_ap_deb_dispose (GObject *object); static GstBinClass *parent_class = NULL; GType gst_ap_deb_get_type (void) { static GType plugin_type = 0; if (!plugin_type) { static const GTypeInfo plugin_info = { sizeof (GstApDebClass), (GBaseInitFunc) gst_ap_deb_base_init, NULL, (GClassInitFunc) gst_ap_deb_class_init, sizeof (GstApDeb), 0, (GInstanceInitFunc) gst_ap_deb_init, }; plugin_type = g_type_register_static (GST_TYPE_BIN, "GstApDeb", &plugin_info, 0); } return plugin_type; } static void gst_ap_deb_base_init (GstApDebClass *klass) static GstElementDetails plugin_details = { "1:1 Autoplugger", "Autoplug", "autoplugger that connects one incoming stream to one outgoing stream", "Benjamin Otte <ot...@gn...>" }; GstElementClass *element_class = GST_ELEMENT_CLASS (klass); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_ap_deb_src_template)); gst_static_pad_template_get (&gst_ap_deb_sink_template)); gst_element_class_set_details (element_class, &plugin_details); gst_ap_deb_class_init (GstApDebClass *klass) GObjectClass *object = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object->dispose = gst_ap_deb_dispose; gst_ap_deb_init (GstApDeb *deb) GstPad *ghost; gchar *name; GstElement *element = GST_ELEMENT (deb); name = g_strdup_printf ("sink%s", gst_object_get_name (GST_OBJECT (deb))); deb->sink = g_object_new (GST_AP_TYPE_IDENTITY, "name", name, NULL); ghost = gst_ghost_pad_new ("sink", deb->sink->sinkpad); gst_bin_add (GST_BIN (deb), GST_ELEMENT (deb->sink)); gst_element_add_pad (element, ghost); g_free (name); name = g_strdup_printf ("src%s", gst_object_get_name (GST_OBJECT (deb))); deb->src = g_object_new (GST_AP_TYPE_IDENTITY, "name", name, NULL); ghost = gst_ghost_pad_new ("src", deb->src->srcpad); gst_bin_add (GST_BIN (deb), GST_ELEMENT (deb->src)); deb->manager = gst_ap_convert_manager_new (GST_BIN (deb)); gst_ap_manager_add_sink (deb->manager, deb->src->sinkpad); gst_ap_manager_add_src (deb->manager, deb->sink->srcpad); gst_ap_deb_dispose (GObject *object) GstApDeb *deb = GST_AP_DEB (object); if (deb->manager) { gst_object_unparent (GST_OBJECT (deb->manager)); deb->manager = NULL; G_OBJECT_CLASS (parent_class)->dispose (object); --- NEW FILE: deb.h --- /* * gstplugin.h: sample header file for plug-in #ifndef __GST_AP_DEB_H__ #define __GST_AP_DEB_H__ #include "identity.h" #include <gst/autoplug/manager.h> #include <gst/gstbin.h> G_BEGIN_DECLS /* #define's don't like whitespacey bits */ #define GST_AP_TYPE_DEB \ (gst_ap_deb_get_type()) #define GST_AP_DEB(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_AP_TYPE_DEB,GstApDeb)) #define GST_AP_DEB_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_AP_TYPE_DEB,GstApDeb)) #define GST_AP_IS_DEB(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_AP_TYPE_DEB)) #define GST_AP_IS_DEB_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_AP_TYPE_DEB)) typedef struct _GstApDeb GstApDeb; typedef struct _GstApDebClass GstApDebClass; struct _GstApDeb GstBin bin; GstApIdentity *sink; GstApIdentity *src; GstApManager *manager; }; struct _GstApDebClass GstBinClass bin_class; GType gst_ap_deb_get_type (void); G_END_DECLS #endif /* __GST_AP_DEB_H__ */ --- NEW FILE: identity.c --- #include <gst/gstutils.h> #include <gst/gstinfo.h> static GstStaticPadTemplate gst_ap_identity_sink_template = static GstStaticPadTemplate gst_ap_identity_src_template = GST_DEBUG_CATEGORY_STATIC (GstApIdDebug); #define GST_CAT_DEFAULT GstApIdDebug #define do_init(x) \ GST_DEBUG_CATEGORY_INIT (GstApIdDebug, "GstApIdentity", \ GST_DEBUG_BG_YELLOW | GST_DEBUG_FG_GREEN, \ "outer identity elements") GST_BOILERPLATE_FULL (GstApIdentity, gst_ap_identity, GstElement, GST_TYPE_ELEMENT, do_init) static void gst_ap_identity_loop (GstElement *element); gst_ap_identity_base_init (gpointer klass) "Autoplugger Identity", "Autoplug/Identity", "generic identity to connect autopluggers to the outside world", gst_static_pad_template_get (&gst_ap_identity_src_template)); gst_static_pad_template_get (&gst_ap_identity_sink_template)); gst_ap_identity_class_init (GstApIdentityClass *klass) gst_ap_identity_init (GstApIdentity *id) GstElement *element = GST_ELEMENT (id); gst_element_set_loop_function (element, gst_ap_identity_loop); id->sinkpad = gst_pad_new_from_template ( gst_static_pad_template_get (&gst_ap_identity_sink_template), "sink"); gst_pad_set_link_function (id->sinkpad, gst_pad_proxy_pad_link); gst_pad_set_getcaps_function (id->sinkpad, gst_pad_proxy_getcaps); gst_pad_set_fixate_function (id->sinkpad, gst_pad_proxy_fixate); gst_element_add_pad (element, id->sinkpad); id->srcpad = gst_pad_new_from_template ( gst_static_pad_template_get (&gst_ap_identity_src_template), "src"); gst_pad_set_link_function (id->srcpad, gst_pad_proxy_pad_link); gst_pad_set_fixate_function (id->srcpad, gst_pad_proxy_fixate); gst_pad_set_getcaps_function (id->srcpad, gst_pad_proxy_getcaps); gst_element_add_pad (element, id->srcpad); gst_ap_identity_loop (GstElement *element) GstData *data; GstApIdentity *id = GST_AP_IDENTITY (element); /* wait until we have data */ if (!GST_PAD_PEER (id->sinkpad)) { GST_INFO_OBJECT (element, "interrupting..."); gst_element_interrupt (element); return; data = gst_pad_pull (id->sinkpad); if (GST_IS_EVENT (data)) { gst_pad_event_default (id->sinkpad, GST_EVENT (data)); } else { gst_pad_push (id->srcpad, data); --- NEW FILE: identity.h --- #ifndef __GST_AP_IDENTITY_H__ #define __GST_AP_IDENTITY_H__ #include <gst/gstelement.h> #define GST_AP_TYPE_IDENTITY \ (gst_ap_identity_get_type()) #define GST_AP_IDENTITY(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_AP_TYPE_IDENTITY,GstApIdentity)) #define GST_AP_IDENTITY_CLASS(klass) \ (G_TYPE_CHECK_CLASS_CAST((klass),GST_AP_TYPE_IDENTITY,GstApIdentity)) #define GST_AP_IS_IDENTITY(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_AP_TYPE_IDENTITY)) #define GST_AP_IS_IDENTITY_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_AP_TYPE_IDENTITY)) typedef struct _GstApIdentity GstApIdentity; typedef struct _GstApIdentityClass GstApIdentityClass; struct _GstApIdentity GstElement element; GstPad *sinkpad, *srcpad; struct _GstApIdentityClass GstElementClass parent_class; GType gst_ap_identity_get_type (void); #endif /* __GST_AP_IDENTITY_H__ */ --- NEW FILE: plugin.c --- #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <gst/gstversion.h> static gboolean plugin_init (GstPlugin *plugin) if (!gst_element_register (plugin, "deb", GST_RANK_NONE, GST_AP_TYPE_DEB)) return FALSE; return TRUE; GST_PLUGIN_DEFINE ( GST_VERSION_MAJOR, GST_VERSION_MINOR, PACKAGE, "autoplugging elements using " PACKAGE, plugin_init, VERSION, "LGPL", "GStreamer Autoplug", "http://gstreamer.net/" ) --- NEW FILE: .cvsignore --- marshal.c marshal.h Index: convertmanager.c RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/convertmanager.c,v retrieving revision 1.2 diff -u -d -r1.2 -r1.3 --- a/convertmanager.c 26 Apr 2004 20:55:40 -0000 1.2 +++ b/convertmanager.c 3 May 2004 16:12:00 -0000 1.3 @@ -31,6 +31,8 @@ LAST_SIGNAL }; +static void gst_ap_convert_manager_dispose (GObject *object); static gboolean _convert_manager_add_src (GstApManager * manager2, GstPad * pad); static gboolean _convert_manager_add_sink (GstApManager * manager2, @@ -64,6 +66,7 @@ gst_ap_convert_manager_class_init (GstApConvertManagerClass *klass) { GstApManagerClass *manager = GST_AP_MANAGER_CLASS (klass); + GObjectClass *object = G_OBJECT_CLASS (klass); manager->add_src = _convert_manager_add_src; manager->add_sink = _convert_manager_add_sink; @@ -71,6 +74,8 @@ manager->remove_sink = _convert_manager_remove_sink; manager->need_sinkcaps = _convert_manager_need_sinkcaps; manager->negotiated = _convert_manager_negotiated; + object->dispose = gst_ap_convert_manager_dispose; } static void @@ -78,6 +83,19 @@ +static void +gst_ap_convert_manager_dispose (GObject *object) +{ + GstApConvertManager *manager = GST_AP_CONVERT_MANAGER (object); + if (manager->srcpad) + gst_ap_manager_remove_src (GST_AP_MANAGER (manager), manager->srcpad); + if (manager->sinkpad) + gst_ap_manager_remove_sink (GST_AP_MANAGER (manager), manager->sinkpad); + GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); +} static GstCaps * _convert_manager_need_sinkcaps (GstApManager *man, GstApLink *link, const GstCaps *caps) @@ -251,8 +269,7 @@ in general we should ref the bin, but that doesn't work if the bin is our manager */ manager = GST_AP_MANAGER (g_object_new (GST_AP_TYPE_CONVERT_MANAGER, NULL)); - gst_object_ref (GST_OBJECT (bin)); - manager->bin = bin; + gst_object_set_parent (GST_OBJECT (manager), GST_OBJECT (bin)); return manager; Index: elementlink.c RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/elementlink.c,v retrieving revision 1.1 diff -u -d -r1.1 -r1.2 --- a/elementlink.c 20 Apr 2004 16:34:53 -0000 1.1 +++ b/elementlink.c 3 May 2004 16:12:00 -0000 1.2 @@ -18,6 +18,7 @@ */ #include "elementlink.h" +#include "utils.h" #include <gst/gstutils.h> #include <gst/gstbin.h> #include <gst/gstinfo.h> @@ -32,6 +33,7 @@ GST_BOILERPLATE_FULL (GstApElementLink, gst_ap_element_link, GstApLink, GST_AP_TYPE_LINK, do_init) +static void gst_ap_element_link_dispose (GObject *object); static void _element_link_set_srcpad (GstApLink * link, GstPad * pad); static gboolean _element_link_set_sink (GstApLink * link, @@ -78,9 +80,12 @@ gst_ap_element_link_class_init (GstApElementLinkClass *klass) GstApLinkClass *link = GST_AP_LINK_CLASS (klass); link->set_srcpad = _element_link_set_srcpad; link->set_sink = _element_link_set_sink; + object->dispose = gst_ap_element_link_dispose; @@ -89,11 +94,22 @@ static guint nr = 0; link->link = g_object_new (_LINK_ELEMENT_TYPE, NULL); + gst_object_ref (GST_OBJECT (link->link)); GST_OBJECT (link->link)->name = g_strdup_printf ("_gst_ap_link_%u", nr++); _LINK_ELEMENT (link->link)->link = link; +gst_ap_element_link_dispose (GObject *object) + GstApElementLink *link = GST_AP_ELEMENT_LINK (object); + + /* we need link->link during parents disposal, so do this after */ + gst_object_unref (GST_OBJECT (link->link)); cb_change_state (GstElement *element, GstElementState old, GstElementState new, GstApElementLink *link) GST_LOG_OBJECT (link, "state change callback: %d => %d", old, new); @@ -114,31 +130,47 @@ GstElement *parent; GstApElementLink *link = GST_AP_ELEMENT_LINK (l); + GstPad *old = gst_ap_link_get_srcpad (l); + if (old) { + parent = gst_pad_get_parent (old); + gst_ap_disconnect (old, link, 1); + gst_ap_disconnect (parent, link, 1); + gst_pad_unlink (old, _LINK_ELEMENT (link->link)->sinkpad); + cb_change_state (parent, gst_element_get_state (link->link), GST_STATE_NULL, link); + gst_bin_remove (GST_BIN (gst_object_get_parent (GST_OBJECT (parent))), link->link); + } - g_assert (gst_ap_link_get_srcpad (GST_AP_LINK (link)) == NULL); GST_CALL_PARENT (GST_AP_LINK_CLASS, set_srcpad, (l, pad)); - parent = gst_pad_get_parent (pad); - if (!GST_PAD_LINK_SUCCESSFUL (gst_pad_link (pad, _LINK_ELEMENT (link->link)->sinkpad))) - g_assert_not_reached (); - gst_bin_add (GST_BIN (gst_object_get_parent (GST_OBJECT (parent))), link->link); - g_signal_connect (parent, "state-change", (GCallback) cb_change_state, link); - g_signal_connect (pad, "fixate", (GCallback) cb_fixate, link); - cb_change_state (parent, gst_element_get_state (link->link), gst_element_get_state (parent), link); + if (pad) { + parent = gst_pad_get_parent (pad); + if (!GST_PAD_LINK_SUCCESSFUL (gst_pad_link (pad, _LINK_ELEMENT (link->link)->sinkpad))) + g_assert_not_reached (); + gst_bin_add (GST_BIN (gst_object_get_parent (GST_OBJECT (parent))), link->link); + g_signal_connect (parent, "state-change", (GCallback) cb_change_state, link); + g_signal_connect (pad, "fixate", (GCallback) cb_fixate, link); + cb_change_state (parent, gst_element_get_state (link->link), gst_element_get_state (parent), link); static gboolean _element_link_set_sink (GstApLink *l, GstObject *object) + GstPad *old; - g_assert (gst_ap_link_get_srcpad (GST_AP_LINK (link)) != NULL); - g_assert (gst_ap_link_get_sinkpad (GST_AP_LINK (link)) == NULL); + if ((old = gst_ap_link_get_sinkpad (GST_AP_LINK (link)))) { + gst_pad_unlink (_LINK_ELEMENT (link->link)->srcpad, old); if (GST_IS_PAD (object)) { - GST_CALL_PARENT (GST_AP_LINK_CLASS, set_sink, (l, object)); + if (!GST_CALL_PARENT_WITH_DEFAULT (GST_AP_LINK_CLASS, set_sink, (l, object), TRUE)) + return FALSE; if (!GST_PAD_LINK_SUCCESSFUL (gst_pad_link (_LINK_ELEMENT (link->link)->srcpad, GST_PAD (object)))) return FALSE; return TRUE; - } else { + } else if (GST_IS_ELEMENT (object)) { gboolean test; if (!GST_PAD_LINK_SUCCESSFUL (gst_element_link_pads (link->link, "src", GST_ELEMENT (object), NULL))) @@ -146,6 +178,9 @@ test = GST_CALL_PARENT_WITH_DEFAULT (GST_AP_LINK_CLASS, set_sink, (l, GST_OBJECT (GST_PAD_PEER (_LINK_ELEMENT(link->link)->srcpad))), TRUE); return test; + } else { + g_assert (object == NULL); + return GST_CALL_PARENT_WITH_DEFAULT (GST_AP_LINK_CLASS, set_sink, (l, NULL), TRUE); } Index: link.c RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/link.c,v --- a/link.c 26 Apr 2004 20:55:40 -0000 1.4 +++ b/link.c 3 May 2004 16:12:00 -0000 1.5 @@ -22,6 +22,7 @@ #include "marshal.h" #include "utils.h" +#include <gst/gstinfo.h> enum { NEED_SINKCAPS, @@ -33,23 +34,25 @@ ARG_0, - ARG_MANAGER, -GST_BOILERPLATE (GstApLink, gst_ap_link, GObject, G_TYPE_OBJECT) +GST_DEBUG_CATEGORY_STATIC (GstApLinkDebug); +#define GST_CAT_DEFAULT GstApLinkDebug +#define do_init(x) \ + GST_DEBUG_CATEGORY_INIT (GstApLinkDebug, "GstApLink", \ + GST_DEBUG_BG_YELLOW | GST_DEBUG_FG_BLUE, \ + "base class for links") +GST_BOILERPLATE_FULL (GstApLink, gst_ap_link, GstObject, GST_TYPE_OBJECT, do_init) static void _link_set_srcpad (GstApLink * link, GstPad * pad); static gboolean _link_set_sink (GstApLink * link, GstObject * object); static void gst_ap_link_dispose (GObject * object); -static void gst_ap_link_set_property(GObject * object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gst_ap_link_get_property(GObject *object, guint prop_id, - GValue *value, - GParamSpec *pspec); +static void gst_ap_link_parent_set (GstObject *object, GstObject *parent); +static void gst_ap_link_parent_unset (GstObject *object, GstObject *parent); static guint gst_ap_link_signals[LAST_SIGNAL] = { 0 }; @@ -72,16 +75,14 @@ gst_ap_link_class_init (GstApLinkClass *klass) + GstObjectClass *gst_object = GST_OBJECT_CLASS (klass); GObjectClass *object = G_OBJECT_CLASS (klass); - object->set_property = gst_ap_link_set_property; - object->get_property = gst_ap_link_get_property; + gst_object->parent_set = gst_ap_link_parent_set; + gst_object->parent_unset = gst_ap_link_parent_unset; object->dispose = gst_ap_link_dispose; - g_object_class_install_property (object, ARG_MANAGER, - g_param_spec_object ("manager", "manager", "manager managing this link", - GST_AP_TYPE_MANAGER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - gst_ap_link_signals[NEED_SINKCAPS] = g_signal_new ("need-sinkcaps", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstApLinkClass, need_sinkcaps), gst_ap_collect_sinkcaps, NULL, @@ -114,50 +115,40 @@ gst_ap_link_dispose (GObject *object) GstApLink *link = GST_AP_LINK (object); - GstApManagerClass *klass; - klass = GST_AP_MANAGER_GET_CLASS (link->manager); - if (klass->link_removed) - klass->link_removed (link->manager, link); + g_assert (link->manager == NULL); + if (link->src) + gst_ap_link_set_srcpad (link, NULL); + if (link->sink) + gst_ap_link_set_sinkpad (link, NULL); GST_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); -gst_ap_link_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +gst_ap_link_parent_set (GstObject *object, GstObject *parent) GstApManagerClass *klass; - switch (prop_id) - { - case ARG_MANAGER: - link->manager = g_value_get_object (value); - klass = GST_AP_MANAGER_GET_CLASS (link->manager); - if (klass->link_added) - klass->link_added (link->manager, link); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } + link->manager = GST_AP_MANAGER (parent); + klass = GST_AP_MANAGER_GET_CLASS (link->manager); + if (klass->link_added) + klass->link_added (link->manager, link); + GST_CALL_PARENT (GST_OBJECT_CLASS, parent_set, (object, parent)); -gst_ap_link_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) +gst_ap_link_parent_unset (GstObject *object, GstObject *parent) + GstApManagerClass *klass; - switch (prop_id) { - g_value_set_object (value, link->manager); + link->manager = NULL; + klass = GST_AP_MANAGER_GET_CLASS (parent); + if (klass->link_removed) + klass->link_removed (GST_AP_MANAGER (parent), link); + GST_CALL_PARENT (GST_OBJECT_CLASS, parent_unset, (object, parent)); @@ -171,6 +162,7 @@ gst_object_unref (GST_OBJECT (parent)); + GST_LOG_OBJECT (link, "setting src to %"GST_PTR_FORMAT, pad); link->src = pad; if (pad) { @@ -194,6 +186,7 @@ + GST_LOG_OBJECT (link, "setting sink to %"GST_PTR_FORMAT, pad); link->sink = GST_PAD (pad); Index: link.h RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/link.h,v retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- a/link.h 26 Apr 2004 20:55:40 -0000 1.5 +++ b/link.h 3 May 2004 16:12:00 -0000 1.6 @@ -1,5 +1,5 @@ /* GStreamer Autoplug - * Copyright (C) 2003 Benjamin Otte <in...@pu...> + * Copyright (C) 2003-2004 Benjamin Otte <ot...@gn...> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,6 +17,7 @@ * Boston, MA 02111-1307, USA. +#include <gst/gstobject.h> #include <gst/gstpad.h> #include <gst/autoplug/types.h> @@ -39,7 +40,7 @@ #define GST_AP_LINK_GET_CLASS(link) (G_TYPE_INSTANCE_GET_CLASS ((link), GST_AP_TYPE_LINK, GstApLinkClass)) struct _GstApLink { - GObject object; + GstObject object; GstApManager * manager; @@ -50,7 +51,7 @@ struct _GstApLinkClass { - GObjectClass parent_class; + GstObjectClass parent_class; /* signals */ GstCaps * (* need_sinkcaps) (GstApLink * link, @@ -67,7 +68,6 @@ GType gst_ap_link_get_type (void); -GstApManager * gst_ap_link_get_manager (GstApLink * link); void gst_ap_link_set_srcpad (GstApLink * link, gboolean gst_ap_link_set_sinkpad (GstApLink * link, Index: manager.c RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/manager.c,v --- a/manager.c 26 Apr 2004 20:55:40 -0000 1.2 +++ b/manager.c 3 May 2004 16:12:00 -0000 1.3 @@ -22,12 +22,13 @@ #include "link.h" #include "rankselector.h" typedef enum { WATCH_NONE, WATCH_LINK, - WATCH_SOMETIMES + WATCH_ELEMENT } WatchType; typedef struct { @@ -46,9 +47,19 @@ -GST_BOILERPLATE (GstApManager, gst_ap_manager, GObject, G_TYPE_OBJECT) +GST_DEBUG_CATEGORY_STATIC (GstApManagerDebug); +#define GST_CAT_DEFAULT GstApManagerDebug + GST_DEBUG_CATEGORY_INIT (GstApManagerDebug, "GstApManager", \ + "manager base class") +GST_BOILERPLATE_FULL (GstApManager, gst_ap_manager, GstObject, GST_TYPE_OBJECT, do_init) static void gst_ap_manager_dispose (GObject *object); +static void gst_ap_manager_parent_set (GstObject *object, GstObject *parent); +static void gst_ap_manager_parent_unset (GstObject *object, GstObject *parent); static void gst_ap_manager_link_added (GstApManager *manager, GstApLink *link); static void gst_ap_manager_link_removed (GstApManager *manager, GstApLink *link); @@ -76,8 +87,12 @@ gst_ap_manager_class_init (GstApManagerClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); + gst_object->parent_set = gst_ap_manager_parent_set; + gst_object->parent_unset = gst_ap_manager_parent_unset; object_class->dispose = gst_ap_manager_dispose; gst_ap_manager_signals[ADD_SRC] = @@ -120,21 +135,36 @@ +gst_ap_manager_do_unset_parent (gpointer data, GObject *parent) + gst_object_unparent (GST_OBJECT (data)); +static void +gst_ap_manager_parent_set (GstObject *object, GstObject *parent) + g_object_weak_ref (G_OBJECT (parent), gst_ap_manager_do_unset_parent, object); +gst_ap_manager_parent_unset (GstObject *object, GstObject *parent) + g_object_weak_unref (G_OBJECT (parent), gst_ap_manager_do_unset_parent, object); watchpoint_do_remove (GstApManager *manager, guint idx) WatchPoint *point = &g_array_index (manager->watched, WatchPoint, idx); - //g_print ("removing watchpoint for type %d, object %p\n", point->type, point->data); + GST_LOG_OBJECT (manager, "removing watchpoint for type %d, object %p", point->type, point->data); switch (point->type) { case WATCH_LINK: - if (g_signal_handlers_disconnect_matched (point->data, G_SIGNAL_MATCH_DATA, 0, 0, - NULL, NULL, manager) != 2) - g_assert_not_reached (); + gst_ap_disconnect (point->data, manager, 2); break; - case WATCH_SOMETIMES: - NULL, NULL, manager) != 1) + case WATCH_ELEMENT: + gst_ap_disconnect (point->data, manager, 1); + gst_object_unref (GST_OBJECT (point->data)); default: g_assert_not_reached (); @@ -169,18 +199,20 @@ g_object_unref (manager->selector); manager->selector = NULL; - gst_object_replace ((GstObject **) &manager->bin, NULL); while (manager->watched->len > 0) { - /* FIXME!!! */ - WatchPoint *p = &g_array_index (manager->watched, WatchPoint, 0); + /* FIXME!!! - I don't want a switch here */ + WatchPoint *p = &g_array_index (manager->watched, WatchPoint, manager->watched->len - 1); if (p->type == WATCH_LINK) { - g_object_unref (p->data); + gst_object_unparent (GST_OBJECT (p->data)); } else { watchpoint_do_remove (manager, manager->watched->len - 1); } g_array_free (manager->watched, TRUE); manager->watched = NULL; #define DO_STUFF_FUNCTION(stuff,type) \ @@ -225,7 +257,7 @@ g_return_val_if_fail (GST_AP_IS_MANAGER (manager), NULL); - return manager->bin; + return GST_BIN (gst_object_get_parent (GST_OBJECT (manager))); @@ -243,12 +275,9 @@ proxy_negotiated (GstApLink *link, const GstCaps *srccaps, GstApManager *manager) gboolean ret; - g_signal_emit (manager, gst_ap_manager_signals[NEGOTIATED], 0, link, srccaps, &ret); - if (ret) - watchpoint_remove (manager, WATCH_LINK, link); @@ -269,10 +298,11 @@ WatchPoint p = { type, TRUE, data }; - //g_print ("adding watchpoint for type %d, object %p\n", type, data); + GST_LOG_OBJECT (manager, "adding watchpoint for type %d, object %p", type, data); switch (type) { g_signal_connect (data, "new-pad", (GCallback) got_new_pad, manager); + gst_object_ref (data); g_signal_connect (data, "need-sinkcaps", (GCallback) proxy_needcaps, manager); @@ -289,16 +319,17 @@ gst_ap_manager_add_element (GstApManager *manager, GstElement *element) GList *list; - gst_bin_add (manager->bin, element); + gst_bin_add (gst_ap_manager_get_bin (manager), element); for (list = element->pads; list; list = g_list_next (list)) { got_new_pad (element, GST_PAD (list->data), manager); + watchpoint_add (manager, WATCH_ELEMENT, element); for (list = gst_element_get_pad_template_list (element); list; list = g_list_next (list)) { GstPadTemplate *templ = list->data; if (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES && GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) { - watchpoint_add (manager, WATCH_SOMETIMES, element); + /* FIXME: activate */ @@ -314,7 +345,7 @@ void gst_ap_manager_remove_element (GstApManager *manager, GstElement *element) - watchpoint_remove (manager, WATCH_SOMETIMES, element); + watchpoint_remove (manager, WATCH_ELEMENT, element); g_assert_not_reached (); @@ -326,7 +357,8 @@ /* FIXME: make configurable */ - link = g_object_new (GST_AP_TYPE_ELEMENT_LINK, "manager", manager, NULL); + link = g_object_new (GST_AP_TYPE_ELEMENT_LINK, NULL); + gst_object_set_parent (GST_OBJECT (link), GST_OBJECT (manager)); return link; Index: manager.h RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/manager.h,v --- a/manager.h 26 Apr 2004 20:55:40 -0000 1.2 +++ b/manager.h 3 May 2004 16:12:00 -0000 1.3 @@ -40,9 +40,8 @@ #define GST_AP_MANAGER_GET_CLASS(manager) (G_TYPE_INSTANCE_GET_CLASS ((manager), GST_AP_TYPE_MANAGER, GstApManagerClass)) struct _GstApManager { - GstBin * bin; GstApSelector * selector; GArray * watched; @@ -51,7 +50,7 @@ struct _GstApManagerClass { gboolean (* add_src) (GstApManager * manager, Index: utils.c RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/utils.c,v --- a/utils.c 20 Apr 2004 16:34:53 -0000 1.2 +++ b/utils.c 3 May 2004 16:12:00 -0000 1.3 @@ -19,6 +19,16 @@ +void +gst_ap_disconnect (gpointer object, gpointer data, gint expected) + gint count = g_signal_handlers_disconnect_matched (object, + G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data); + if (expected < 0) return; + g_assert (count == expected); static GstPadTemplate * gst_ap_utils_can_connect_caps (GstElementFactory *factory, const GstCaps *caps, GstPadDirection dir) Index: utils.h RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/gst/autoplug/utils.h,v --- a/utils.h 20 Apr 2004 16:34:53 -0000 1.2 +++ b/utils.h 3 May 2004 16:12:00 -0000 1.3 @@ -25,6 +25,10 @@ G_BEGIN_DECLS +void gst_ap_disconnect (gpointer object, + gpointer data, + gint count); GstPadTemplate * gst_ap_utils_factory_can_sink (GstElementFactory * factory, const GstCaps * caps); GstPadTemplate * gst_ap_utils_factory_can_src (GstElementFactory * factory, RCS file: /home/cvs/gstreamer/gst-sandbox/gst-autoplug/testsuite/Makefile.am,v --- a/Makefile.am 20 Apr 2004 16:34:53 -0000 1.2 +++ b/Makefile.am 3 May 2004 16:12:00 -0000 1.3 @@ -1,2 +1,2 @@ -SUBDIRS=files managers selectors +SUBDIRS=files managers selectors elements deb deb-simple testprogs = deb-simple deb TESTS = $(testprogs) check_PROGRAMS = $(testprogs) # we have nothing but apps here, we can do this safely LIBS = $(GST_AP_LIBS) AM_CFLAGS = $(GST_AP_CFLAGS) --- NEW FILE: deb-simple.c --- #include <gst/gst.h> int main (int argc, char **argv) GstElement *pipeline; GError *error = NULL; gst_init (&argc, &argv); gst_alloc_trace_set_flags_all (GST_ALLOC_TRACE_LIVE); pipeline = gst_parse_launch ("filesrc location=../files/sine.mp3 ! deb ! audio/x-raw-int ! fakesink", &error); g_assert (error == NULL); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); while (gst_bin_iterate (GST_BIN (pipeline))); gst_object_unref (GST_OBJECT (pipeline)); gst_alloc_trace_print_all (); return 0; not_reached (void) g_assert_not_reached (); GstElement *pipeline, *src; gchar *locations[] = {"../files/sine.mp3", "../files/sine.ogg" }; guint i; pipeline = gst_parse_launch ("filesrc name=src ! deb ! audio/x-raw-int ! fakesink", src = gst_bin_get_by_name (GST_BIN (pipeline), "src"); g_assert (src); g_signal_connect (pipeline, "error", (GCallback) not_reached, NULL); for (i = 0; i < G_N_ELEMENTS (locations); i++) { g_object_set (src, "location", locations[i], NULL); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); while (gst_bin_iterate (GST_BIN (pipeline))); if (gst_element_set_state (pipeline, GST_STATE_NULL) != GST_STATE_SUCCESS) --- NEW FILE: sine.mp3 --- ÿûPÄ |