summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2001-01-30 23:53:04 +0000
committerWim Taymans <wim.taymans@gmail.com>2001-01-30 23:53:04 +0000
commit1a5cfae0f635408e4d2e7d155ef90ecf4f45609a (patch)
treeded3dfe549c568126f2fc5ea61c1b02f767efb5f
parent6873d31fed213566cfa4230a017b5b76e2d6aaa2 (diff)
Added a first attempt for XML embedding in the main core XML.
Original commit message from CVS: Added a first attempt for XML embedding in the main core XML. Objects will emit a signal that a user app can connect to in order to insert its XML into the tree. You can catch the object_loaded signal in GstXML to parse the user supplied XML data in the stream. The object_loaded signal is implemented with a custom made class signal. All GstObject classes now automatically create a GstSignalObject that serves as a proxy to the user app when an object is loaded. All objects are currently responsible to emit the class signal themselves. runxml and createxml serve as an example how the XML hooks can be used to insert and retrieve custom XML tags.
-rw-r--r--examples/xml/createxml.c17
-rw-r--r--examples/xml/runxml.c27
-rw-r--r--gst/gstelement.c2
-rw-r--r--gst/gstobject.c116
-rw-r--r--gst/gstobject.h15
-rw-r--r--gst/gstxml.c35
-rw-r--r--gst/gstxml.h12
-rw-r--r--tests/old/examples/xml/createxml.c17
-rw-r--r--tests/old/examples/xml/runxml.c27
9 files changed, 220 insertions, 48 deletions
diff --git a/examples/xml/createxml.c b/examples/xml/createxml.c
index 873a3e15f..154f943b9 100644
--- a/examples/xml/createxml.c
+++ b/examples/xml/createxml.c
@@ -2,13 +2,25 @@
#include <gst/gst.h>
gboolean playing;
+xmlNsPtr ns;
-int main(int argc,char *argv[])
+static void
+object_saved (GstObject *object, xmlNodePtr parent, gpointer data)
+{
+ xmlNodePtr child;
+
+ child = xmlNewChild(parent, ns, "comment", NULL);
+ xmlNewChild(child, ns, "text", (gchar *)data);
+}
+
+int main(int argc,char *argv[])
{
GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode;
GstElement *bin;
GstElement *thread, *thread2;
+ ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test");
+
gst_init(&argc,&argv);
if (argc != 2) {
@@ -20,9 +32,12 @@ int main(int argc,char *argv[])
//thread = gst_thread_new("thread");
thread = gst_elementfactory_make("thread", "thread");
g_assert(thread != NULL);
+ gtk_signal_connect (GTK_OBJECT (thread), "object_saved", object_saved, g_strdup ("decoder thread"));
+
thread2 = gst_elementfactory_make("thread", "thread2");
//thread2 = gst_thread_new("thread2");
g_assert(thread2 != NULL);
+ gtk_signal_connect (GTK_OBJECT (thread2), "object_saved", object_saved, g_strdup ("render thread"));
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
diff --git a/examples/xml/runxml.c b/examples/xml/runxml.c
index 9bc756f01..5594ec86b 100644
--- a/examples/xml/runxml.c
+++ b/examples/xml/runxml.c
@@ -4,13 +4,24 @@
gboolean playing;
static void
-xml_loaded (GstXML *xml, GstObject *object, gpointer data)
+xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data)
{
- if (GST_IS_PAD (object)) {
- g_print ("pad loaded '%s'\n", gst_pad_get_name (GST_PAD (object)));
- }
- else if (GST_IS_ELEMENT (object)) {
- g_print ("element loaded '%s'\n", gst_element_get_name (GST_ELEMENT (object)));
+ xmlNodePtr children = self->xmlChildrenNode;
+
+ while (children) {
+ if (!strcmp (children->name, "comment")) {
+ xmlNodePtr nodes = children->xmlChildrenNode;
+
+ while (nodes) {
+ if (!strcmp (nodes->name, "text")) {
+ gchar *name = g_strdup (xmlNodeGetContent (nodes));
+ g_print ("object %s loaded with comment '%s'\n",
+ gst_object_get_name (object), name);
+ }
+ nodes = nodes->next;
+ }
+ }
+ children = children->next;
}
}
@@ -24,7 +35,9 @@ int main(int argc,char *argv[])
xml = gst_xml_new ();
- gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, NULL);
+ //g_print ("%p\n", xml);
+
+ gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, xml);
ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL);
g_assert (ret == TRUE);
diff --git a/gst/gstelement.c b/gst/gstelement.c
index f00880185..c3b544d9d 100644
--- a/gst/gstelement.c
+++ b/gst/gstelement.c
@@ -1065,6 +1065,8 @@ gst_element_load_thyself (xmlNodePtr self, GstObject *parent)
if (parent)
gst_object_unparent (GST_OBJECT (element));
+ gst_class_signal_emit_by_name (GST_OBJECT (element), "object_loaded", self);
+
return element;
}
diff --git a/gst/gstobject.c b/gst/gstobject.c
index b1c522b8d..9dd496487 100644
--- a/gst/gstobject.c
+++ b/gst/gstobject.c
@@ -27,6 +27,7 @@
/* Object signals and args */
enum {
PARENT_SET,
+ OBJECT_SAVED,
LAST_SIGNAL
};
@@ -35,6 +36,19 @@ enum {
/* FILL ME */
};
+enum {
+ SO_OBJECT_LOADED,
+ SO_LAST_SIGNAL
+};
+
+typedef struct _GstSignalObject GstSignalObject;
+typedef struct _GstSignalObjectClass GstSignalObjectClass;
+
+static GtkType gst_signal_object_get_type (void);
+static void gst_signal_object_class_init (GstSignalObjectClass *klass);
+static void gst_signal_object_init (GstSignalObject *object);
+
+static guint gst_signal_object_signals[SO_LAST_SIGNAL] = { 0 };
static void gst_object_class_init (GstObjectClass *klass);
static void gst_object_init (GstObject *object);
@@ -42,6 +56,11 @@ static void gst_object_init (GstObject *object);
static GtkObjectClass *parent_class = NULL;
static guint gst_object_signals[LAST_SIGNAL] = { 0 };
+void
+gst_object_inititialize (void)
+{
+}
+
GtkType
gst_object_get_type (void)
{
@@ -77,14 +96,24 @@ gst_object_class_init (GstObjectClass *klass)
GTK_SIGNAL_OFFSET (GstObjectClass, parent_set),
gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
GST_TYPE_OBJECT);
+ gst_object_signals[OBJECT_SAVED] =
+ gtk_signal_new ("object_saved", GTK_RUN_LAST, gtkobject_class->type,
+ GTK_SIGNAL_OFFSET (GstObjectClass, object_saved),
+ gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
+ GTK_TYPE_POINTER);
gtk_object_class_add_signals (gtkobject_class, gst_object_signals, LAST_SIGNAL);
klass->path_string_separator = "/";
+ klass->signal_object = gtk_type_new (gst_signal_object_get_type ());
}
static void
gst_object_init (GstObject *object)
{
+ GstObjectClass *oclass;
+
+ oclass = GST_OBJECT_CLASS (GTK_OBJECT (object)->klass);
+
object->lock = g_mutex_new();
#ifdef HAVE_ATOMIC_H
atomic_set(&(object->refcount),1);
@@ -321,13 +350,9 @@ gst_object_save_thyself (GstObject *object, xmlNodePtr parent)
if (oclass->save_thyself)
oclass->save_thyself (object, parent);
- return parent;
-}
+ gtk_signal_emit (GTK_OBJECT (object), gst_object_signals[OBJECT_SAVED], parent);
-void
-gst_object_load_thyself (xmlNodePtr self, GstObject *parent)
-{
- g_print ("gstobject: load thyself\n");
+ return parent;
}
/**
@@ -397,3 +422,82 @@ gst_object_get_path_string (GstObject *object)
return path;
}
+
+
+struct _GstSignalObject {
+ GtkObject object;
+};
+
+struct _GstSignalObjectClass {
+ GtkObjectClass parent_class;
+
+ /* signals */
+ void (*object_loaded) (GstSignalObject *object, GstObject *new, xmlNodePtr self);
+};
+
+static GtkType
+gst_signal_object_get_type (void)
+{
+ static GtkType signal_object_type = 0;
+
+ if (!signal_object_type) {
+ static const GtkTypeInfo signal_object_info = {
+ "GstSignalObject",
+ sizeof(GstSignalObject),
+ sizeof(GstSignalObjectClass),
+ (GtkClassInitFunc)gst_signal_object_class_init,
+ (GtkObjectInitFunc)gst_signal_object_init,
+ (GtkArgSetFunc)NULL,
+ (GtkArgGetFunc)NULL,
+ (GtkClassInitFunc)NULL,
+ };
+ signal_object_type = gtk_type_unique(gtk_object_get_type(),&signal_object_info);
+ }
+ return signal_object_type;
+}
+
+static void
+gst_signal_object_class_init (GstSignalObjectClass *klass)
+{
+ GtkObjectClass *gtkobject_class;
+
+ gtkobject_class = (GtkObjectClass*) klass;
+
+ parent_class = gtk_type_class (gtk_object_get_type ());
+
+ gst_signal_object_signals[SO_OBJECT_LOADED] =
+ gtk_signal_new ("object_loaded", GTK_RUN_LAST, gtkobject_class->type,
+ GTK_SIGNAL_OFFSET (GstSignalObjectClass, object_loaded),
+ gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2,
+ GST_TYPE_OBJECT, GTK_TYPE_POINTER);
+ gtk_object_class_add_signals (gtkobject_class, gst_signal_object_signals, LAST_SIGNAL);
+}
+
+static void
+gst_signal_object_init (GstSignalObject *object)
+{
+}
+
+guint
+gst_class_signal_connect (GstObjectClass *klass,
+ const gchar *name,
+ GtkSignalFunc func,
+ gpointer func_data)
+{
+ return gtk_signal_connect (klass->signal_object, name, func, func_data);
+}
+
+void
+gst_class_signal_emit_by_name (GstObject *object,
+ const gchar *name,
+ xmlNodePtr self)
+{
+ GstObjectClass *oclass;
+
+ oclass = GST_OBJECT_CLASS (GTK_OBJECT (object)->klass);
+
+ gtk_signal_emit_by_name (oclass->signal_object, name, object, self);
+}
+
+
+
diff --git a/gst/gstobject.h b/gst/gstobject.h
index 80a9631cd..9e1e6bb95 100644
--- a/gst/gstobject.h
+++ b/gst/gstobject.h
@@ -79,12 +79,14 @@ struct _GstObject {
};
struct _GstObjectClass {
- GtkObjectClass parent_class;
+ GtkObjectClass parent_class;
- gchar *path_string_separator;
+ gchar *path_string_separator;
+ GtkObject *signal_object;
/* signals */
void (*parent_set) (GstObject *object, GstObject *parent);
+ void (*object_saved) (GstObject *object, xmlNodePtr parent);
/* functions go here */
xmlNodePtr (*save_thyself) (GstObject *object, xmlNodePtr parent);
@@ -133,6 +135,15 @@ xmlNodePtr gst_object_save_thyself (GstObject *object, xmlNodePtr parent);
/* printing out the 'path' of the object */
gchar * gst_object_get_path_string (GstObject *object);
+guint gst_class_signal_connect (GstObjectClass *klass,
+ const gchar *name,
+ GtkSignalFunc func,
+ gpointer func_data);
+
+void gst_class_signal_emit_by_name (GstObject *object,
+ const gchar *name,
+ xmlNodePtr self);
+
#ifdef __cplusplus
}
diff --git a/gst/gstxml.c b/gst/gstxml.c
index 6f92516f7..876ecf70b 100644
--- a/gst/gstxml.c
+++ b/gst/gstxml.c
@@ -27,14 +27,14 @@
enum {
OBJECT_LOADED,
- OBJECT_SAVED,
LAST_SIGNAL
};
-
static void gst_xml_class_init (GstXMLClass *klass);
static void gst_xml_init (GstXML *xml);
+static void gst_xml_object_loaded (GstObject *private, GstObject *object, xmlNodePtr self, gpointer data);
+
static GstObjectClass *parent_class = NULL;
static guint gst_xml_signals[LAST_SIGNAL] = { 0 };
@@ -74,12 +74,6 @@ gst_xml_class_init (GstXMLClass *klass)
gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2,
GST_TYPE_OBJECT, GTK_TYPE_POINTER);
- gst_xml_signals[OBJECT_SAVED] =
- gtk_signal_new ("object_saved", GTK_RUN_LAST, gtkobject_class->type,
- GTK_SIGNAL_OFFSET (GstXMLClass, object_saved),
- gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2,
- GST_TYPE_OBJECT, GTK_TYPE_POINTER);
-
gtk_object_class_add_signals (gtkobject_class, gst_xml_signals, LAST_SIGNAL);
}
@@ -123,15 +117,15 @@ gst_xml_write (GstElement *element)
doc->xmlRootNode = xmlNewDocNode (doc, ns, "gstreamer", NULL);
- elementnode = xmlNewChild (doc->xmlRootNode, NULL, "element", NULL);
+ elementnode = xmlNewChild (doc->xmlRootNode, ns, "element", NULL);
gst_object_save_thyself (GST_OBJECT (element), elementnode);
return doc;
}
-static gboolean
-gst_xml_real_parse (GstXML *xml, xmlDocPtr doc, const guchar *root)
+gboolean
+gst_xml_parse_doc (GstXML *xml, xmlDocPtr doc, const guchar *root)
{
xmlNodePtr field, cur;
xmlNsPtr ns;
@@ -151,6 +145,9 @@ gst_xml_real_parse (GstXML *xml, xmlDocPtr doc, const guchar *root)
return FALSE;
}
+ gst_class_signal_connect (GST_OBJECT_CLASS (GTK_OBJECT (xml)->klass),
+ "object_loaded", gst_xml_object_loaded, xml);
+
xml->ns = ns;
field = cur->xmlChildrenNode;
@@ -200,7 +197,7 @@ gst_xml_parse_file (GstXML *xml, const guchar *fname, const guchar *root)
return FALSE;
}
- return gst_xml_real_parse (xml, doc, root);
+ return gst_xml_parse_doc (xml, doc, root);
}
/**
@@ -223,20 +220,18 @@ gst_xml_parse_memory (GstXML *xml, guchar *buffer, guint size, const gchar *root
doc = xmlParseMemory (buffer, size);
- return gst_xml_real_parse (xml, doc, root);
+ return gst_xml_parse_doc (xml, doc, root);
}
-void
-gst_xml_object_loaded (GstXML *xml, GstObject *object, xmlNodePtr self)
+static void
+gst_xml_object_loaded (GstObject *private, GstObject *object, xmlNodePtr self, gpointer data)
{
+ GstXML *xml = GST_XML (data);
+
+ // FIXME check that this element was created from the same xmlDocPtr...
gtk_signal_emit (GTK_OBJECT (xml), gst_xml_signals[OBJECT_LOADED], object, self);
}
-void
-gst_xml_object_saved (GstXML *xml, GstObject *object, xmlNodePtr self)
-{
- gtk_signal_emit (GTK_OBJECT (xml), gst_xml_signals[OBJECT_SAVED], object, self);
-}
/**
* gst_xml_get_topelements:
* @xml: The GstXML to get the elements from
diff --git a/gst/gstxml.h b/gst/gstxml.h
index a797272c9..7d114f1c6 100644
--- a/gst/gstxml.h
+++ b/gst/gstxml.h
@@ -52,6 +52,9 @@ extern "C" {
typedef struct _GstXML GstXML;
typedef struct _GstXMLClass GstXMLClass;
+typedef void (*GstXMLObjectLoadedCallback) (GstXML *xml, GstObject *object, xmlNodePtr self);
+typedef void (*GstXMLObjectSavedCallback) (GstXML *xml, GstObject *object, xmlNodePtr self);
+
struct _GstXML {
GstObject object;
@@ -64,8 +67,8 @@ struct _GstXMLClass {
GstObjectClass parent_class;
/* signal callbacks */
- void (*object_loaded) (GstXML *xml, GstObject *object, xmlNodePtr self);
- void (*object_saved) (GstXML *xml, GstObject *object, xmlNodePtr self);
+ void (*object_loaded) (GstXML *xml, GstObject *object, xmlNodePtr self);
+ void (*object_saved) (GstXML *xml, GstObject *object, xmlNodePtr self);
};
GtkType gst_xml_get_type (void);
@@ -76,6 +79,7 @@ xmlDocPtr gst_xml_write (GstElement *element);
GstXML* gst_xml_new (void);
+gboolean gst_xml_parse_doc (GstXML *xml, xmlDocPtr doc, const guchar *root);
gboolean gst_xml_parse_file (GstXML *xml, const guchar *fname, const guchar *root);
gboolean gst_xml_parse_memory (GstXML *xml, guchar *buffer, guint size, const gchar *root);
@@ -83,8 +87,8 @@ gboolean gst_xml_parse_memory (GstXML *xml, guchar *buffer, guint size, const gc
GstElement* gst_xml_get_element (GstXML *xml, const guchar *name);
GList* gst_xml_get_topelements (GstXML *xml);
-void gst_xml_object_loaded (GstXML *xml, GstObject *object, xmlNodePtr self);
-void gst_xml_object_saved (GstXML *xml, GstObject *object, xmlNodePtr self);
+void gst_xml_connect_object_loaded (GstXML *xml, GstXMLObjectLoadedCallback *callback, gpointer data);
+void gst_xml_connect_object_saved (GstXML *xml, GstXMLObjectSavedCallback *callback, gpointer data);
#ifdef __cplusplus
}
diff --git a/tests/old/examples/xml/createxml.c b/tests/old/examples/xml/createxml.c
index 873a3e15f..154f943b9 100644
--- a/tests/old/examples/xml/createxml.c
+++ b/tests/old/examples/xml/createxml.c
@@ -2,13 +2,25 @@
#include <gst/gst.h>
gboolean playing;
+xmlNsPtr ns;
-int main(int argc,char *argv[])
+static void
+object_saved (GstObject *object, xmlNodePtr parent, gpointer data)
+{
+ xmlNodePtr child;
+
+ child = xmlNewChild(parent, ns, "comment", NULL);
+ xmlNewChild(child, ns, "text", (gchar *)data);
+}
+
+int main(int argc,char *argv[])
{
GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode;
GstElement *bin;
GstElement *thread, *thread2;
+ ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test");
+
gst_init(&argc,&argv);
if (argc != 2) {
@@ -20,9 +32,12 @@ int main(int argc,char *argv[])
//thread = gst_thread_new("thread");
thread = gst_elementfactory_make("thread", "thread");
g_assert(thread != NULL);
+ gtk_signal_connect (GTK_OBJECT (thread), "object_saved", object_saved, g_strdup ("decoder thread"));
+
thread2 = gst_elementfactory_make("thread", "thread2");
//thread2 = gst_thread_new("thread2");
g_assert(thread2 != NULL);
+ gtk_signal_connect (GTK_OBJECT (thread2), "object_saved", object_saved, g_strdup ("render thread"));
/* create a new bin to hold the elements */
bin = gst_bin_new("bin");
diff --git a/tests/old/examples/xml/runxml.c b/tests/old/examples/xml/runxml.c
index 9bc756f01..5594ec86b 100644
--- a/tests/old/examples/xml/runxml.c
+++ b/tests/old/examples/xml/runxml.c
@@ -4,13 +4,24 @@
gboolean playing;
static void
-xml_loaded (GstXML *xml, GstObject *object, gpointer data)
+xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data)
{
- if (GST_IS_PAD (object)) {
- g_print ("pad loaded '%s'\n", gst_pad_get_name (GST_PAD (object)));
- }
- else if (GST_IS_ELEMENT (object)) {
- g_print ("element loaded '%s'\n", gst_element_get_name (GST_ELEMENT (object)));
+ xmlNodePtr children = self->xmlChildrenNode;
+
+ while (children) {
+ if (!strcmp (children->name, "comment")) {
+ xmlNodePtr nodes = children->xmlChildrenNode;
+
+ while (nodes) {
+ if (!strcmp (nodes->name, "text")) {
+ gchar *name = g_strdup (xmlNodeGetContent (nodes));
+ g_print ("object %s loaded with comment '%s'\n",
+ gst_object_get_name (object), name);
+ }
+ nodes = nodes->next;
+ }
+ }
+ children = children->next;
}
}
@@ -24,7 +35,9 @@ int main(int argc,char *argv[])
xml = gst_xml_new ();
- gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, NULL);
+ //g_print ("%p\n", xml);
+
+ gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, xml);
ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL);
g_assert (ret == TRUE);