diff --git a/configure.in b/configure.in index 48239417ca..3734d93d6e 100644 --- a/configure.in +++ b/configure.in @@ -656,6 +656,7 @@ gst/Makefile gst/types/Makefile gst/meta/Makefile gst/elements/Makefile +gst/autoplug/Makefile libs/Makefile libs/riff/Makefile libs/colorspace/Makefile diff --git a/editor/gsteditor.h b/editor/gsteditor.h index 105e18087a..e67667e8a4 100644 --- a/editor/gsteditor.h +++ b/editor/gsteditor.h @@ -155,14 +155,14 @@ struct _GstEditorElement { struct _GstEditorElementClass { GnomeCanvasGroupClass parent_class; - void (*name_changed) (GstEditorElement *element); - void (*position_changed) (GstEditorElement *element); - void (*size_changed) (GstEditorElement *element); - void (*realize) (GstEditorElement *element); - gint (*event) (GnomeCanvasItem *item,GdkEvent *event, - GstEditorElement *element); - gint (*button_event) (GnomeCanvasItem *item,GdkEvent *event, - GstEditorElement *element); + void (*name_changed) (GstEditorElement *element); + void (*position_changed) (GstEditorElement *element); + void (*size_changed) (GstEditorElement *element); + void (*realize) (GstEditorElement *element); + gint (*event) (GnomeCanvasItem *item,GdkEvent *event, + GstEditorElement *element); + gint (*button_event) (GnomeCanvasItem *item,GdkEvent *event, + GstEditorElement *element); }; @@ -188,11 +188,11 @@ const gchar *gst_editor_element_get_name(GstEditorElement *element); (GTK_CHECK_TYPE((obj),GST_TYPE_EDITOR_BIN)) #define GST_IS_EDITOR_BIN_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EDITOR_BIN)) - + struct _GstEditorBin { GstEditorElement element; - /* lists of GUI elements and connections */ + /* lists of GUI elements and connections */ GList *elements, *connections; /* connection state */ @@ -213,11 +213,11 @@ struct _GstEditorBinClass { GtkType gst_editor_bin_get_type(); GstEditorBin* gst_editor_bin_new (GstBin *bin, const gchar *first_arg_name,...); -void gst_editor_bin_add (GstEditorBin *bin, GstEditorElement *element); - -void gst_editor_bin_connection_drag (GstEditorBin *bin, - gdouble wx,gdouble wy); -void gst_editor_bin_start_banding (GstEditorBin *bin,GstEditorPad *pad); +void gst_editor_bin_add (GstEditorBin *bin, GstEditorElement *element); + +void gst_editor_bin_connection_drag (GstEditorBin *bin, + gdouble wx,gdouble wy); +void gst_editor_bin_start_banding (GstEditorBin *bin,GstEditorPad *pad); #define GST_TYPE_EDITOR_CANVAS \ @@ -246,8 +246,8 @@ struct _GstEditorCanvasClass { GstEditorCanvas* gst_editor_canvas_new (void); GstEditorCanvas* gst_editor_canvas_new_with_bin (GstEditorBin *bin); -void gst_editor_canvas_set_bin (GstEditorCanvas *canvas, - GstEditorBin *element); +void gst_editor_canvas_set_bin (GstEditorCanvas *canvas, + GstEditorBin *element); GstEditorElement* gst_editor_canvas_get_bin (GstEditorCanvas *canvas); @@ -263,7 +263,7 @@ GstEditorElement* gst_editor_canvas_get_bin (GstEditorCanvas *canvas); (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EDITOR_PAD)) struct _GstEditorPad { - GtkObject object; + GtkObject object; /* parent element */ GstEditorElement *parent; @@ -291,7 +291,7 @@ struct _GstEditorPad { gdouble width,height; // actual size gdouble boxwidth,boxheight; // size of pad box gboolean resize; // does it need resizing? - + /* interaction state */ gboolean dragging,resizing,moved; gdouble dragx,dragy; @@ -300,13 +300,13 @@ struct _GstEditorPad { // GnomeCanvasItem *connection; // can't use //GstEditorConnection }; - + struct _GstEditorPadClass { GtkObjectClass parent_class; void (*realize) (GstEditorPad *pad); }; - + GtkType gst_editor_pad_get_type(); GstEditorPad *gst_editor_pad_new(GstEditorElement *parent,GstPad *pad, const gchar *first_arg_name, ...); @@ -329,7 +329,7 @@ void gst_editor_pad_repack(GstEditorPad *pad); (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EDITOR_PADTEMPLATE)) struct _GstEditorPadTemplate { - GtkObject object; + GtkObject object; /* parent element */ GstEditorElement *parent; @@ -361,7 +361,7 @@ struct _GstEditorPadTemplate { gdouble width,height; // actual size gdouble boxwidth,boxheight; // size of padtemplate box gboolean resize; // does it need resizing? - + /* interaction state */ gboolean dragging,resizing,moved; gdouble dragx,dragy; @@ -370,13 +370,13 @@ struct _GstEditorPadTemplate { // GnomeCanvasItem *connection; // can't use //GstEditorConnection }; - + struct _GstEditorPadTemplateClass { GtkObjectClass parent_class; void (*realize) (GstEditorPadTemplate *padtemplate); }; - + GtkType gst_editor_padtemplate_get_type(); GstEditorPadTemplate *gst_editor_padtemplate_new(GstEditorElement *parent,GstPadTemplate *padtemplate, const gchar *first_arg_name, ...); diff --git a/gst/Makefile.am b/gst/Makefile.am index fb80219ba4..5c6c686431 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -1,5 +1,5 @@ # cheap trick to build . first... -SUBDIRS = . types meta elements +SUBDIRS = . types meta elements autoplug lib_LTLIBRARIES = libgst.la diff --git a/gst/elements/gstdisksrc.c b/gst/elements/gstdisksrc.c index fbeaddc853..1978a15b56 100644 --- a/gst/elements/gstdisksrc.c +++ b/gst/elements/gstdisksrc.c @@ -32,7 +32,7 @@ GstElementDetails gst_disksrc_details = { - "hronous Disk Source", + "asynchronous Disk Source", "Source/File", "Read from arbitrary point in a file", VERSION, diff --git a/gst/elements/gstelements.c b/gst/elements/gstelements.c index 294793df44..1621fd20b4 100644 --- a/gst/elements/gstelements.c +++ b/gst/elements/gstelements.c @@ -2,7 +2,7 @@ * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * - * gstelements.c: + * gstelements.c: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -48,27 +48,27 @@ struct _elements_entry { }; static struct _elements_entry _elements[] = { - { "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details, NULL }, - { "fakesink", gst_fakesink_get_type, &gst_fakesink_details, NULL }, - { "asyncdisksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, - { "audiosink", gst_audiosink_get_type, &gst_audiosink_details, gst_audiosink_factory_init }, - { "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details, NULL }, - { "disksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, - { "identity", gst_identity_get_type, &gst_identity_details, NULL }, - { "fdsink", gst_fdsink_get_type, &gst_fdsink_details, NULL }, - { "fdsrc", gst_fdsrc_get_type, &gst_fdsrc_details, NULL }, - { "pipefilter", gst_pipefilter_get_type, &gst_pipefilter_details, NULL }, - { "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details, NULL }, - { "tee", gst_tee_get_type, &gst_tee_details, gst_tee_factory_init }, + { "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details, NULL }, + { "fakesink", gst_fakesink_get_type, &gst_fakesink_details, NULL }, + { "asyncdisksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, + { "audiosink", gst_audiosink_get_type, &gst_audiosink_details, gst_audiosink_factory_init }, + { "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details, NULL }, + { "disksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, + { "identity", gst_identity_get_type, &gst_identity_details, NULL }, + { "fdsink", gst_fdsink_get_type, &gst_fdsink_details, NULL }, + { "fdsrc", gst_fdsrc_get_type, &gst_fdsrc_details, NULL }, + { "pipefilter", gst_pipefilter_get_type, &gst_pipefilter_details, NULL }, + { "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details, NULL }, + { "tee", gst_tee_get_type, &gst_tee_details, gst_tee_factory_init }, #if HAVE_LIBGHTTP - { "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details, NULL }, + { "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details, NULL }, #endif /* HAVE_LIBGHTTP */ - + { NULL, 0 }, }; -GstPlugin *plugin_init (GModule *module) +GstPlugin *plugin_init (GModule *module) { GstPlugin *plugin; GstElementFactory *factory; diff --git a/gst/gstautoplug.c b/gst/gstautoplug.c index db17586f34..16eafbf27c 100644 --- a/gst/gstautoplug.c +++ b/gst/gstautoplug.c @@ -24,570 +24,248 @@ #include "gst_private.h" #include "gstautoplug.h" -#include "gstbin.h" +#include "gstplugin.h" + +GList* _gst_autoplugfactories; + +enum { + NEW_OBJECT, + LAST_SIGNAL +}; + +enum { + ARG_0, + /* FILL ME */ +}; static void gst_autoplug_class_init (GstAutoplugClass *klass); static void gst_autoplug_init (GstAutoplug *autoplug); -static GList* gst_autoplug_func (gpointer src, gpointer sink, - GstAutoplugListFunction list_function, - GstAutoplugCostFunction cost_function, - gpointer data); - -struct _gst_autoplug_node -{ - gpointer iNode; - gpointer iPrev; - gint iDist; -}; - -typedef struct _gst_autoplug_node gst_autoplug_node; - static GstObjectClass *parent_class = NULL; +static guint gst_autoplug_signals[LAST_SIGNAL] = { 0 }; -GtkType gst_autoplug_get_type(void) { +GtkType gst_autoplug_get_type(void) +{ static GtkType autoplug_type = 0; if (!autoplug_type) { static const GtkTypeInfo autoplug_info = { "GstAutoplug", - sizeof(GstElement), - sizeof(GstElementClass), + sizeof(GstAutoplug), + sizeof(GstAutoplugClass), (GtkClassInitFunc)gst_autoplug_class_init, (GtkObjectInitFunc)gst_autoplug_init, (GtkArgSetFunc)NULL, (GtkArgGetFunc)NULL, (GtkClassInitFunc)NULL, }; - autoplug_type = gtk_type_unique(GST_TYPE_AUTOPLUG,&autoplug_info); + autoplug_type = gtk_type_unique (GTK_TYPE_OBJECT, &autoplug_info); } return autoplug_type; } static void -gst_autoplug_class_init(GstAutoplugClass *klass) { - parent_class = gtk_type_class(GST_TYPE_OBJECT); -} - -static void gst_autoplug_init(GstAutoplug *autoplug) { -} - -static gboolean -gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest) +gst_autoplug_class_init(GstAutoplugClass *klass) { - GList *srctemps, *desttemps; + GtkObjectClass *gtkobject_class; - srctemps = src->padtemplates; + gtkobject_class = (GtkObjectClass*) klass; - while (srctemps) { - GstPadTemplate *srctemp = (GstPadTemplate *)srctemps->data; + parent_class = gtk_type_class(GTK_TYPE_OBJECT); - desttemps = dest->padtemplates; + gst_autoplug_signals[NEW_OBJECT] = + gtk_signal_new ("new_object", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstAutoplugClass, new_object), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GST_TYPE_OBJECT); - while (desttemps) { - GstPadTemplate *desttemp = (GstPadTemplate *)desttemps->data; - - if (srctemp->direction == GST_PAD_SRC && - desttemp->direction == GST_PAD_SINK) { - if (gst_caps_list_check_compatibility (srctemp->caps, desttemp->caps)) { - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT, - "factory \"%s\" can connect with factory \"%s\"", src->name, dest->name); - return TRUE; - } - } - - desttemps = g_list_next (desttemps); - } - srctemps = g_list_next (srctemps); - } - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT, - "factory \"%s\" cannot connect with factory \"%s\"", src->name, dest->name); - return FALSE; + gtk_object_class_add_signals (gtkobject_class, gst_autoplug_signals, LAST_SIGNAL); } -static gboolean -gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink) +static void gst_autoplug_init(GstAutoplug *autoplug) { - GList *sinkpads; - gboolean connected = FALSE; - - GST_DEBUG (0,"gstpipeline: autoplug pad connect function for \"%s\" to \"%s\"\n", - GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink)); - - sinkpads = gst_element_get_pad_list(sink); - while (sinkpads) { - GstPad *sinkpad = (GstPad *)sinkpads->data; - - // if we have a match, connect the pads - if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK && - !GST_PAD_CONNECTED(sinkpad)) - { - if (gst_caps_list_check_compatibility (gst_pad_get_caps_list(pad), gst_pad_get_caps_list(sinkpad))) { - gst_pad_connect(pad, sinkpad); - GST_DEBUG (0,"gstpipeline: autoconnect pad \"%s\" in element %s <-> ", GST_PAD_NAME (pad), - GST_ELEMENT_NAME(src)); - GST_DEBUG (0,"pad \"%s\" in element %s\n", GST_PAD_NAME (sinkpad), - GST_ELEMENT_NAME(sink)); - connected = TRUE; - break; - } - else { - GST_DEBUG (0,"pads incompatible %s, %s\n", GST_PAD_NAME (pad), GST_PAD_NAME (sinkpad)); - } - } - sinkpads = g_list_next(sinkpads); - } - - if (!connected) { - GST_DEBUG (0,"gstpipeline: no path to sinks for type\n"); - } - return connected; } -static void -gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink) +void +_gst_autoplug_initialize (void) { - GList *srcpads; - gboolean connected = FALSE; - - srcpads = gst_element_get_pad_list(src); - - while (srcpads && !connected) { - GstPad *srcpad = (GstPad *)srcpads->data; - - if (gst_pad_get_direction(srcpad) == GST_PAD_SRC) - connected = gst_autoplug_pads_autoplug_func (src, srcpad, sink); - - srcpads = g_list_next(srcpads); - } - - if (!connected) { - GST_DEBUG (0,"gstpipeline: delaying pad connections for \"%s\" to \"%s\"\n", - GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink)); - gtk_signal_connect(GTK_OBJECT(src),"new_pad", - GTK_SIGNAL_FUNC(gst_autoplug_pads_autoplug_func), sink); - } + _gst_autoplugfactories = NULL; } -static GList* -gst_autoplug_elementfactory_get_list (gpointer data) +void +gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object) { - return gst_elementfactory_get_list (); + gtk_signal_emit (GTK_OBJECT (autoplug), gst_autoplug_signals[NEW_OBJECT], object); } -typedef struct { - GList *src; - GList *sink; -} caps_struct; -#define IS_CAPS(cap) (((cap) == caps->src) || (cap) == caps->sink) - -static guint -gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data) +GstElement* +gst_autoplug_caps_list (GstAutoplug *autoplug, GList *srcpad, GList *sinkpad, ...) { - caps_struct *caps = (caps_struct *)data; - gboolean res; + GstAutoplugClass *oclass; + GstElement *element = NULL; + va_list args; - if (IS_CAPS (src) && IS_CAPS (dest)) { - res = gst_caps_list_check_compatibility ((GList *)src, (GList *)dest); - //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"caps %d to caps %d %d", ((GstCaps *)src)->id, ((GstCaps *)dest)->id, res); - } - else if (IS_CAPS (src)) { - res = gst_elementfactory_can_sink_caps_list ((GstElementFactory *)dest, (GList *)src); - //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to src caps %d %d", ((GstElementFactory *)dest)->name, ((GstCaps *)src)->id, res); - } - else if (IS_CAPS (dest)) { - res = gst_elementfactory_can_src_caps_list ((GstElementFactory *)src, (GList *)dest); - //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to sink caps %d %d", ((GstElementFactory *)src)->name, ((GstCaps *)dest)->id, res); - } - else { - res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest); - } + va_start (args, sinkpad); - if (res) - return 1; - else - return GST_AUTOPLUG_MAX_COST; + oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass); + if (oclass->autoplug_caps_list) + element = (oclass->autoplug_caps_list) (autoplug, srcpad, sinkpad, args); + + va_end (args); + + return element; +} + + +/** + * gst_autoplugfactory_new: + * @name: name of autoplugfactory to create + * @longdesc: long description of autoplugfactory to create + * @type: the gtk type of the GstAutoplug element of this factory + * + * Create a new autoplugfactory with the given parameters + * + * Returns: a new #GstAutoplugFactory. + */ +GstAutoplugFactory* +gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GtkType type) +{ + GstAutoplugFactory *factory; + + g_return_val_if_fail(name != NULL, NULL); + + factory = g_new0(GstAutoplugFactory, 1); + + factory->name = g_strdup(name); + factory->longdesc = g_strdup (longdesc); + factory->type = type; + + _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory); + + return factory; } /** - * gst_autoplug_pads: - * @srcpad: the source pad - * @sinkpad: the sink pad + * gst_autoplugfactory_destroy: + * @autoplug: factory to destroy * - * Perform autoplugging between the two given pads. - * - * Returns: a list of elementfactories that can connect - * the two pads + * Removes the autoplug from the global list. */ -GstElement* -gst_autoplug_caps_list (GList *srccaps, GList *sinkcaps, ...) +void +gst_autoplugfactory_destroy (GstAutoplugFactory *autoplug) { - caps_struct caps; - va_list args; - GList *capslist; - GstElement *result = NULL, *srcelement = NULL; - GList **factories; - GList *chains = NULL; - GList *endcaps = NULL; - guint numsinks = 0, i; - gboolean have_common = FALSE; + g_return_if_fail (autoplug != NULL); - va_start (args, sinkcaps); - capslist = sinkcaps; + _gst_autoplugfactories = g_list_remove (_gst_autoplugfactories, autoplug); - /* - * We first create a list of elements that are needed - * to convert the srcpad caps to the different sinkpad caps. - * and add the list of elementfactories to a list (chains). - */ - caps.src = srccaps; + // we don't free the struct bacause someone might have a handle to it.. +} - while (capslist) { - GList *elements; +/** + * gst_autoplug_find: + * @name: name of autoplugger to find + * + * Search for an autoplugger of the given name. + * + * Returns: #GstAutoplug if found, NULL otherwise + */ +GstAutoplugFactory* +gst_autoplugfactory_find (const gchar *name) +{ + GList *walk; + GstAutoplugFactory *factory; - caps.sink = capslist; + g_return_val_if_fail(name != NULL, NULL); - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures"); + GST_DEBUG (0,"gstautoplug: find \"%s\"\n", name); - elements = gst_autoplug_func (caps.src, caps.sink, - gst_autoplug_elementfactory_get_list, - gst_autoplug_caps_find_cost, - &caps); - - if (elements) { - chains = g_list_append (chains, elements); - endcaps = g_list_append (endcaps, capslist); - numsinks++; - } - else { - } - - capslist = va_arg (args, GList *); + walk = _gst_autoplugfactories; + while (walk) { + factory = (GstAutoplugFactory *)(walk->data); + if (!strcmp (name, factory->name)) + return factory; + walk = g_list_next (walk); } - va_end (args); - /* - * If no list could be found the pipeline cannot be autoplugged and - * we return a NULL element - */ - if (numsinks == 0) + return NULL; +} + +/** + * gst_autoplugfactory_get_list: + * + * Get the global list of elementfactories. + * + * Returns: GList of type #GstElementFactory + */ +GList* +gst_autoplugfactory_get_list (void) +{ + return _gst_autoplugfactories; +} + +GstAutoplug* +gst_autoplugfactory_create (GstAutoplugFactory *factory) +{ + GstAutoplug *new = NULL; + + g_return_val_if_fail (factory != NULL, NULL); + + if (factory->type == 0){ + factory = gst_plugin_load_autoplugfactory (factory->name); + } + g_return_val_if_fail (factory != NULL, NULL); + g_return_val_if_fail (factory->type != 0, NULL); + + new = GST_AUTOPLUG (gtk_type_new (factory->type)); + + return new; +} + +GstAutoplug* +gst_autoplugfactory_make (const gchar *name) +{ + GstAutoplugFactory *factory; + + g_return_val_if_fail (name != NULL, NULL); + + factory = gst_autoplugfactory_find (name); + + if (factory == NULL) return NULL; - /* - * We now have a list of lists. We will turn this into an array - * of lists, this will make it much more easy to manipulate it - * in the next steps. - */ - factories = g_new0 (GList *, numsinks); - - for (i = 0; chains; i++) { - GList *elements = (GList *) chains->data; - - factories[i] = elements; - - chains = g_list_next (chains); - } - //FIXME, free the list - - result = gst_bin_new ("autoplug_bin"); - - /* - * We now hav a list of lists that is probably like: - * - * ! - * A -> B -> C - * ! - * A -> D -> E - * - * we now try to find the common elements (A) and add them to - * the bin. We remove them from both lists too. - */ - while (factories[0]) { - GstElementFactory *factory; - GstElement *element; - - // fase 3: add common elements - factory = (GstElementFactory *) (factories[0]->data); - - // check to other paths for matching elements (factories) - for (i=1; idata)) { - goto differ; - } - } - - GST_DEBUG (0,"common factory \"%s\"\n", factory->name); - - element = gst_elementfactory_create (factory, factory->name); - gst_bin_add (GST_BIN(result), element); - - if (srcelement != NULL) { - gst_autoplug_pads_autoplug (srcelement, element); - } - // this is the first element, find a good ghostpad - else { - GList *pads; - - pads = gst_element_get_pad_list (element); - - while (pads) { - GstPad *pad = GST_PAD (pads->data); - - if (gst_caps_list_check_compatibility (srccaps, gst_pad_get_caps_list (pad))) { - gst_element_add_ghost_pad (result, pad, "sink"); - break; - } - - pads = g_list_next (pads); - } - } - - srcelement = element; - - // advance the pointer in all lists - for (i=0; idata); - - GST_DEBUG (0,"factory \"%s\"\n", factory->name); - element = gst_elementfactory_create(factory, factory->name); - - // this element suggests the use of a thread, so we set one up... - if (GST_ELEMENT_IS_THREAD_SUGGESTED(element) || use_thread) { - GstElement *queue; - GList *sinkpads; - GstPad *srcpad, *sinkpad; - - use_thread = FALSE; - - GST_DEBUG (0,"sugest new thread for \"%s\" %08x\n", GST_ELEMENT_NAME (element), GST_FLAGS(element)); - - // create a new queue and add to the previous bin - queue = gst_elementfactory_make("queue", g_strconcat("queue_", GST_ELEMENT_NAME(element), NULL)); - GST_DEBUG (0,"adding element \"%s\"\n", GST_ELEMENT_NAME (element)); - gst_bin_add(GST_BIN(thebin), queue); - - // this will be the new bin for all following elements - thebin = gst_elementfactory_make("thread", g_strconcat("thread_", GST_ELEMENT_NAME(element), NULL)); - - srcpad = gst_element_get_pad(queue, "src"); - - sinkpads = gst_element_get_pad_list(element); - while (sinkpads) { - sinkpad = (GstPad *)sinkpads->data; - - // FIXME connect matching pads, not just the first one... - if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK && - !GST_PAD_CONNECTED(sinkpad)) { - GList *caps = gst_pad_get_caps_list (sinkpad); - - // the queue has the type of the elements it connects - gst_pad_set_caps_list (srcpad, caps); - gst_pad_set_caps_list (gst_element_get_pad(queue, "sink"), caps); - break; - } - sinkpads = g_list_next(sinkpads); - } - gst_autoplug_pads_autoplug(thesrcelement, queue); - - GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element)); - gst_bin_add(GST_BIN(thebin), element); - GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (thebin)); - gst_bin_add(GST_BIN(result), thebin); - thesrcelement = queue; - } - // no thread needed, easy case - else { - GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element)); - gst_bin_add(GST_BIN(thebin), element); - } - gst_autoplug_pads_autoplug(thesrcelement, element); - - // this element is now the new source element - thesrcelement = element; - - factories[i] = g_list_next(factories[i]); - } - /* - * we're at the last element in the chain, - * find a suitable pad to turn into a ghostpad - */ - { - GList *endcap = (GList *)(endcaps->data); - GList *pads = gst_element_get_pad_list (thesrcelement); - endcaps = g_list_next (endcaps); - - while (pads) { - GstPad *pad = GST_PAD (pads->data); - pads = g_list_next (pads); - - if (gst_caps_list_check_compatibility (gst_pad_get_caps_list (pad), endcap)) { - gst_element_add_ghost_pad (result, pad, g_strdup_printf("src_%02d", i)); - break; - } - } - } - } - - return result; + return gst_autoplugfactory_create (factory);; } -static gint -find_factory (gst_autoplug_node *rgnNodes, gpointer factory) +xmlNodePtr +gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent) { - gint i=0; + g_return_val_if_fail(factory != NULL, NULL); - while (rgnNodes[i].iNode) { - if (rgnNodes[i].iNode == factory) return i; - i++; - } - return 0; + xmlNewChild(parent,NULL,"name",factory->name); + xmlNewChild(parent,NULL,"longdesc", factory->longdesc); + + return parent; } -static GList* -construct_path (gst_autoplug_node *rgnNodes, gpointer factory) +GstAutoplugFactory* +gst_autoplugfactory_load_thyself (xmlNodePtr parent) { - GstElementFactory *current; - GList *factories = NULL; + GstAutoplugFactory *factory = g_new0(GstAutoplugFactory, 1); + xmlNodePtr children = parent->xmlChildrenNode; - current = rgnNodes[find_factory(rgnNodes, factory)].iPrev; - - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factories found in autoplugging (reversed order)"); - - while (current != NULL) - { - gpointer next = NULL; - - next = rgnNodes[find_factory(rgnNodes, current)].iPrev; - if (next) { - factories = g_list_prepend (factories, current); - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", current->name); + while (children) { + if (!strcmp(children->name, "name")) { + factory->name = xmlNodeGetContent(children); } - current = next; - } - return factories; -} - -static GList* -gst_autoplug_enqueue (GList *queue, gpointer iNode, gint iDist, gpointer iPrev) -{ - gst_autoplug_node *node = g_malloc (sizeof (gst_autoplug_node)); - - node->iNode = iNode; - node->iDist = iDist; - node->iPrev = iPrev; - - queue = g_list_append (queue, node); - - return queue; -} - -static GList* -gst_autoplug_dequeue (GList *queue, gpointer *iNode, gint *iDist, gpointer *iPrev) -{ - GList *head; - gst_autoplug_node *node; - - head = g_list_first (queue); - - if (head) { - node = (gst_autoplug_node *)head->data; - *iNode = node->iNode; - *iPrev = node->iPrev; - *iDist = node->iDist; - head = g_list_remove (queue, node); + if (!strcmp(children->name, "longdesc")) { + factory->longdesc = xmlNodeGetContent(children); + } + children = children->next; } - return head; -} - -static GList* -gst_autoplug_func (gpointer src, gpointer sink, - GstAutoplugListFunction list_function, - GstAutoplugCostFunction cost_function, - gpointer data) -{ - gst_autoplug_node *rgnNodes; - GList *queue = NULL; - gpointer iNode, iPrev; - gint iDist, i, iCost; - - GList *elements = g_list_copy (list_function(data)); - GList *factories; - guint num_factories; - - elements = g_list_append (elements, sink); - elements = g_list_append (elements, src); - - factories = elements; - - num_factories = g_list_length (factories); - - rgnNodes = g_new0 (gst_autoplug_node, num_factories+1); - - for (i=0; i< num_factories; i++) { - gpointer fact = factories->data; - - rgnNodes[i].iNode = fact; - rgnNodes[i].iPrev = NULL; - - if (fact == src) { - rgnNodes[i].iDist = 0; - } - else { - rgnNodes[i].iDist = GST_AUTOPLUG_MAX_COST; - } - - factories = g_list_next (factories); - } - rgnNodes[num_factories].iNode = NULL; - - queue = gst_autoplug_enqueue (queue, src, 0, NULL); - - while (g_list_length (queue) > 0) { - GList *factories2 = elements; - - queue = gst_autoplug_dequeue (queue, &iNode, &iDist, &iPrev); - - for (i=0; i< num_factories; i++) { - gpointer current = factories2->data; - - iCost = cost_function (iNode, current, data); - if (iCost != GST_AUTOPLUG_MAX_COST) { - if((GST_AUTOPLUG_MAX_COST == rgnNodes[i].iDist) || - (rgnNodes[i].iDist > (iCost + iDist))) { - rgnNodes[i].iDist = iDist + iCost; - rgnNodes[i].iPrev = iNode; - - queue = gst_autoplug_enqueue (queue, current, iDist + iCost, iNode); - } - } - - factories2 = g_list_next (factories2); - } - } - - return construct_path (rgnNodes, sink); + _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory); + + return factory; } diff --git a/gst/gstautoplug.h b/gst/gstautoplug.h index d12f41771d..484471ffc6 100644 --- a/gst/gstautoplug.h +++ b/gst/gstautoplug.h @@ -31,7 +31,7 @@ extern "C" { #endif /* __cplusplus */ #define GST_TYPE_AUTOPLUG \ - (gst_object_get_type()) + (gst_autoplug_get_type()) #define GST_AUTOPLUG(obj) \ (GTK_CHECK_CAST((obj),GST_TYPE_AUTOPLUG,GstAutoplug)) #define GST_AUTOPLUG_CLASS(klass) \ @@ -44,11 +44,6 @@ extern "C" { typedef struct _GstAutoplug GstAutoplug; typedef struct _GstAutoplugClass GstAutoplugClass; -#define GST_AUTOPLUG_MAX_COST 999999 - -typedef guint (*GstAutoplugCostFunction) (gpointer src, gpointer dest, gpointer data); -typedef GList* (*GstAutoplugListFunction) (gpointer data); - struct _GstAutoplug { GtkObject object; }; @@ -57,19 +52,42 @@ struct _GstAutoplugClass { GtkObjectClass parent_class; /* signal callbacks */ - void (*element_added) (GstAutoplug *eutoplug, GstElement *element); + void (*new_object) (GstAutoplug *autoplug, GstObject *object); + /* perform the autoplugging */ + GstElement* (*autoplug_caps_list) (GstAutoplug *autoplug, GList *srcpad, GList *sinkpad, va_list args); }; +typedef struct _GstAutoplugFactory GstAutoplugFactory; + struct _GstAutoplugFactory { - gchar *name; /* name of element */ + gchar *name; /* name of autoplugger */ + gchar *longdesc; /* long description of the autoplugger (well, don't overdo it..) */ GtkType type; /* unique GtkType of the autoplugger */ }; -GtkType gst_autoplug_get_type (void); +GtkType gst_autoplug_get_type (void); -GstElement* gst_autoplug_caps_list (GList *srcpad, GList *sinkpad, ...); +void gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object); +GstElement* gst_autoplug_caps_list (GstAutoplug *autoplug, GList *srcpad, GList *sinkpad, ...); + + +/* + * creating autopluggers + * + */ +GstAutoplugFactory* gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GtkType type); +void gst_autoplugfactory_destroy (GstAutoplugFactory *factory); + +GstAutoplugFactory* gst_autoplugfactory_find (const gchar *name); +GList* gst_autoplugfactory_get_list (void); + +GstAutoplug* gst_autoplugfactory_create (GstAutoplugFactory *factory); +GstAutoplug* gst_autoplugfactory_make (const gchar *name); + +xmlNodePtr gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent); +GstAutoplugFactory* gst_autoplugfactory_load_thyself (xmlNodePtr parent); #ifdef __cplusplus } diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 6e31a0d6e2..eced12ed3e 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -30,8 +30,8 @@ /* global list of registered elementfactories */ GList* _gst_elementfactories; -void -_gst_elementfactory_initialize (void) +void +_gst_elementfactory_initialize (void) { _gst_elementfactories = NULL; } @@ -42,8 +42,8 @@ _gst_elementfactory_initialize (void) * * Removes the elementfactory from the global list. */ -void -gst_elementfactory_destroy (GstElementFactory *elementfactory) +void +gst_elementfactory_destroy (GstElementFactory *elementfactory) { g_return_if_fail (elementfactory != NULL); @@ -61,7 +61,7 @@ gst_elementfactory_destroy (GstElementFactory *elementfactory) * Returns: #GstElementFactory if found, NULL otherwise */ GstElementFactory* -gst_elementfactory_find (const gchar *name) +gst_elementfactory_find (const gchar *name) { GList *walk; GstElementFactory *factory; @@ -89,7 +89,7 @@ gst_elementfactory_find (const gchar *name) * Returns: GList of type #GstElementFactory */ GList* -gst_elementfactory_get_list (void) +gst_elementfactory_get_list (void) { return _gst_elementfactories; } @@ -108,12 +108,14 @@ gst_elementfactory_get_list (void) */ GstElementFactory* gst_elementfactory_new (const gchar *name, GtkType type, - GstElementDetails *details) + GstElementDetails *details) { - GstElementFactory *factory = g_new0(GstElementFactory, 1); + GstElementFactory *factory; g_return_val_if_fail(name != NULL, NULL); + factory = g_new0(GstElementFactory, 1); + factory->name = g_strdup(name); factory->type = type; factory->details = details; @@ -138,7 +140,7 @@ gst_elementfactory_new (const gchar *name, GtkType type, */ GstElement * gst_elementfactory_create (GstElementFactory *factory, - const gchar *name) + const gchar *name) { GstElement *element; GstElementClass *oclass; @@ -184,7 +186,7 @@ gst_elementfactory_create (GstElementFactory *factory, * Returns: new #GstElement */ GstElement* -gst_elementfactory_make (const gchar *factoryname, const gchar *name) +gst_elementfactory_make (const gchar *factoryname, const gchar *name) { GstElementFactory *factory; GstElement *element; @@ -338,15 +340,15 @@ gst_elementfactory_can_sink_caps (GstElementFactory *factory, /** * gst_elementfactory_save_thyself: * @factory: factory to save - * @parent: the parent xmlNodePtr + * @parent: the parent xmlNodePtr * * Saves the factory into an XML tree. - * + * * Returns: the new xmlNodePtr */ -xmlNodePtr -gst_elementfactory_save_thyself (GstElementFactory *factory, - xmlNodePtr parent) +xmlNodePtr +gst_elementfactory_save_thyself (GstElementFactory *factory, + xmlNodePtr parent) { GList *pads; @@ -377,14 +379,14 @@ gst_elementfactory_save_thyself (GstElementFactory *factory, /** * gst_elementfactory_load_thyself: - * @parent: the parent xmlNodePtr + * @parent: the parent xmlNodePtr * * Creates a new factory from an xmlNodePtr. - * + * * Returns: the new factory */ GstElementFactory * -gst_elementfactory_load_thyself (xmlNodePtr parent) +gst_elementfactory_load_thyself (xmlNodePtr parent) { GstElementFactory *factory = g_new0(GstElementFactory, 1); xmlNodePtr children = parent->xmlChildrenNode; @@ -415,7 +417,7 @@ gst_elementfactory_load_thyself (xmlNodePtr parent) } if (!strcmp(children->name, "padtemplate")) { GstPadTemplate *template; - + template = gst_padtemplate_load_thyself (children); gst_elementfactory_add_padtemplate (factory, template); diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c index cf4335040c..f42d82bd2b 100644 --- a/gst/gstpipeline.c +++ b/gst/gstpipeline.c @@ -24,10 +24,6 @@ #include "gst_private.h" #include "gstpipeline.h" -#include "gstthread.h" -#include "gstutils.h" -#include "gsttype.h" -#include "gstautoplug.h" GstElementDetails gst_pipeline_details = { diff --git a/gst/gstplugin.c b/gst/gstplugin.c index f6a5d73ad2..9012bec2f6 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -80,6 +80,8 @@ _gst_plugin_initialize (void) PLUGINS_SRCDIR "/gst/elements"); _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_SRCDIR "/gst/types"); + _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, + PLUGINS_SRCDIR "/gst/autoplug"); #else /* PLUGINS_USE_SRCDIR */ /* add the main (installed) library path */ _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_DIR); @@ -395,6 +397,8 @@ gst_plugin_new (const gchar *name) plugin->numelements = 0; plugin->types = NULL; plugin->numtypes = 0; + plugin->autopluggers = NULL; + plugin->numautopluggers = 0; plugin->loaded = TRUE; return plugin; @@ -529,15 +533,7 @@ gst_plugin_find (const gchar *name) return NULL; } -/** - * gst_plugin_find_elementfactory: - * @name: name of elementfactory to find - * - * Find a registered elementfactory by name. - * - * Returns: @GstElementFactory if found, NULL if not - */ -GstElementFactory* +static GstElementFactory* gst_plugin_find_elementfactory (const gchar *name) { GList *plugins, *factories; @@ -609,6 +605,77 @@ gst_plugin_load_elementfactory (const gchar *name) return factory; } +static GstAutoplugFactory* +gst_plugin_find_autoplugfactory (const gchar *name) +{ + GList *plugins, *factories; + GstAutoplugFactory *factory; + + g_return_val_if_fail(name != NULL, NULL); + + plugins = _gst_plugins; + while (plugins) { + factories = ((GstPlugin *)(plugins->data))->autopluggers; + while (factories) { + factory = (GstAutoplugFactory*)(factories->data); + if (!strcmp(factory->name, name)) + return (GstAutoplugFactory*)(factory); + factories = g_list_next(factories); + } + plugins = g_list_next(plugins); + } + + return NULL; +} +/** + * gst_plugin_load_autoplugfactory: + * @name: name of autoplugfactory to load + * + * Load a registered autoplugfactory by name. + * + * Returns: @GstAutoplugFactory if loaded, NULL if not + */ +GstAutoplugFactory* +gst_plugin_load_autoplugfactory (const gchar *name) +{ + GList *plugins, *factories; + GstAutoplugFactory *factory = NULL; + GstPlugin *plugin; + + g_return_val_if_fail(name != NULL, NULL); + + plugins = _gst_plugins; + while (plugins) { + plugin = (GstPlugin *)plugins->data; + factories = plugin->autopluggers; + + while (factories) { + factory = (GstAutoplugFactory*)(factories->data); + + if (!strcmp(factory->name,name)) { + if (!plugin->loaded) { + gchar *filename = g_strdup (plugin->filename); + gchar *pluginname = g_strdup (plugin->name); + + GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded autoplugfactory %s from plugin %s",name,plugin->name); + gst_plugin_remove(plugin); + if (!gst_plugin_load_absolute(filename)) { + GST_DEBUG (0,"gstplugin: error loading autoplug factory %s from plugin %s\n", name, pluginname); + } + g_free (pluginname); + g_free (filename); + } + factory = gst_plugin_find_autoplugfactory(name); + return factory; + } + factories = g_list_next(factories); + } + plugins = g_list_next(plugins); + } + + return factory; +} + /** * gst_plugin_load_typefactory: * @mime: name of typefactory to load @@ -696,6 +763,24 @@ gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory) gst_type_register (factory); } +/** + * gst_plugin_add_type: + * @plugin: plugin to add type to + * @factory: the typefactory to add + * + * Add a typefactory to the list of those provided by the plugin. + */ +void +gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory) +{ + g_return_if_fail (plugin != NULL); + g_return_if_fail (factory != NULL); + +// g_print("adding factory to plugin\n"); + plugin->autopluggers = g_list_prepend (plugin->autopluggers, factory); + plugin->numautopluggers++; +} + /** * gst_plugin_get_list: * @@ -704,7 +789,7 @@ gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory) * Returns; a GList of GstPlugin elements */ GList* -gst_plugin_get_list(void) +gst_plugin_get_list (void) { return _gst_plugins; } @@ -721,34 +806,45 @@ xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent) { xmlNodePtr tree, subtree; - GList *plugins = NULL, *elements = NULL, *types = NULL; + GList *plugins = NULL, *elements = NULL, *types = NULL, *autopluggers = NULL; - plugins = gst_plugin_get_list(); + plugins = gst_plugin_get_list (); while (plugins) { GstPlugin *plugin = (GstPlugin *)plugins->data; - tree = xmlNewChild(parent,NULL,"plugin",NULL); - xmlNewChild(tree,NULL,"name",plugin->name); - xmlNewChild(tree,NULL,"longname",plugin->longname); - xmlNewChild(tree,NULL,"filename",plugin->filename); + + tree = xmlNewChild (parent, NULL, "plugin", NULL); + xmlNewChild (tree, NULL, "name", plugin->name); + xmlNewChild (tree, NULL, "longname", plugin->longname); + xmlNewChild (tree, NULL, "filename", plugin->filename); + types = plugin->types; while (types) { GstTypeFactory *factory = (GstTypeFactory *)types->data; - subtree = xmlNewChild(tree,NULL,"typefactory",NULL); + subtree = xmlNewChild(tree, NULL, "typefactory", NULL); - gst_typefactory_save_thyself(factory, subtree); + gst_typefactory_save_thyself (factory, subtree); - types = g_list_next(types); + types = g_list_next (types); } elements = plugin->elements; while (elements) { GstElementFactory *factory = (GstElementFactory *)elements->data; - subtree = xmlNewChild(tree,NULL,"elementfactory",NULL); + subtree = xmlNewChild (tree, NULL, "elementfactory", NULL); - gst_elementfactory_save_thyself(factory, subtree); + gst_elementfactory_save_thyself (factory, subtree); - elements = g_list_next(elements); + elements = g_list_next (elements); } - plugins = g_list_next(plugins); + autopluggers = plugin->autopluggers; + while (autopluggers) { + GstAutoplugFactory *factory = (GstAutoplugFactory *)autopluggers->data; + subtree = xmlNewChild (tree, NULL, "autoplugfactory", NULL); + + gst_autoplugfactory_save_thyself (factory, subtree); + + autopluggers = g_list_next (autopluggers); + } + plugins = g_list_next (plugins); } return parent; } @@ -764,43 +860,50 @@ gst_plugin_load_thyself (xmlNodePtr parent) { xmlNodePtr kinderen; gint elementcount = 0; + gint autoplugcount = 0; gint typecount = 0; gchar *pluginname; kinderen = parent->xmlChildrenNode; // Dutch invasion :-) while (kinderen) { - if (!strcmp(kinderen->name, "plugin")) { + if (!strcmp (kinderen->name, "plugin")) { xmlNodePtr field = kinderen->xmlChildrenNode; GstPlugin *plugin = g_new0 (GstPlugin, 1); + plugin->elements = NULL; plugin->types = NULL; plugin->loaded = FALSE; while (field) { - if (!strcmp(field->name, "name")) { - pluginname = xmlNodeGetContent(field); - if (gst_plugin_find(pluginname)) { - g_free(pluginname); - g_free(plugin); + if (!strcmp (field->name, "name")) { + pluginname = xmlNodeGetContent (field); + if (gst_plugin_find (pluginname)) { + g_free (pluginname); + g_free (plugin); plugin = NULL; break; } else { plugin->name = pluginname; } } - else if (!strcmp(field->name, "longname")) { - plugin->longname = xmlNodeGetContent(field); + else if (!strcmp (field->name, "longname")) { + plugin->longname = xmlNodeGetContent (field); } - else if (!strcmp(field->name, "filename")) { - plugin->filename = xmlNodeGetContent(field); + else if (!strcmp (field->name, "filename")) { + plugin->filename = xmlNodeGetContent (field); } - else if (!strcmp(field->name, "elementfactory")) { - GstElementFactory *factory = gst_elementfactory_load_thyself(field); + else if (!strcmp (field->name, "elementfactory")) { + GstElementFactory *factory = gst_elementfactory_load_thyself (field); gst_plugin_add_factory (plugin, factory); elementcount++; } - else if (!strcmp(field->name, "typefactory")) { - GstTypeFactory *factory = gst_typefactory_load_thyself(field); + else if (!strcmp (field->name, "autoplugfactory")) { + GstAutoplugFactory *factory = gst_autoplugfactory_load_thyself (field); + gst_plugin_add_autoplugger (plugin, factory); + autoplugcount++; + } + else if (!strcmp (field->name, "typefactory")) { + GstTypeFactory *factory = gst_typefactory_load_thyself (field); gst_plugin_add_type (plugin, factory); elementcount++; typecount++; @@ -810,13 +913,14 @@ gst_plugin_load_thyself (xmlNodePtr parent) } if (plugin) { - _gst_plugins = g_list_prepend(_gst_plugins, plugin); + _gst_plugins = g_list_prepend (_gst_plugins, plugin); } } kinderen = kinderen->next; } - GST_INFO (GST_CAT_PLUGIN_LOADING,"added %d registered factories and %d types",elementcount,typecount); + GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d registered factories, %d autopluggers and %d types", + elementcount, autoplugcount, typecount); } @@ -851,3 +955,19 @@ gst_plugin_get_type_list (GstPlugin *plugin) return plugin->types; } + +/** + * gst_plugin_get_autoplug_list: + * @plugin: the plugin to get the autoplugfactories from + * + * get a list of all the autoplugfactories that this plugin provides + * + * Returns: a GList of factories + */ +GList* +gst_plugin_get_autoplug_list (GstPlugin *plugin) +{ + g_return_val_if_fail (plugin != NULL, NULL); + + return plugin->autopluggers; +} diff --git a/gst/gstplugin.h b/gst/gstplugin.h index 08938bba56..545ce05fce 100644 --- a/gst/gstplugin.h +++ b/gst/gstplugin.h @@ -36,6 +36,7 @@ #include #include +#include typedef struct _GstPlugin GstPlugin; @@ -50,6 +51,8 @@ struct _GstPlugin { gint numtypes; GList *elements; /* list of elements provided */ gint numelements; + GList *autopluggers; /* list of autopluggers provided */ + gint numautopluggers; gboolean loaded; /* if the plugin is in memory */ }; @@ -71,6 +74,7 @@ gboolean gst_plugin_is_loaded (GstPlugin *plugin); GList* gst_plugin_get_type_list (GstPlugin *plugin); GList* gst_plugin_get_factory_list (GstPlugin *plugin); +GList* gst_plugin_get_autoplug_list (GstPlugin *plugin); void gst_plugin_load_all (void); gboolean gst_plugin_load (const gchar *name); @@ -79,14 +83,14 @@ gboolean gst_library_load (const gchar *name); void gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory); void gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory); +void gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory); GstPlugin* gst_plugin_find (const gchar *name); GList* gst_plugin_get_list (void); -GstElementFactory* gst_plugin_find_elementfactory (const gchar *name); - GstElementFactory* gst_plugin_load_elementfactory (const gchar *name); void gst_plugin_load_typefactory (const gchar *mime); +GstAutoplugFactory* gst_plugin_load_autoplugfactory (const gchar *name); xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent); void gst_plugin_load_thyself (xmlNodePtr parent); diff --git a/gst/gstprops.c b/gst/gstprops.c index 11a5a523ae..b5b11386ab 100644 --- a/gst/gstprops.c +++ b/gst/gstprops.c @@ -578,7 +578,7 @@ gst_props_load_thyself_func (xmlNodePtr field) prop = xmlGetProp (field, "min"); sscanf (prop, "%d", &entry->data.int_range_data.min); g_free (prop); - prop = xmlGetProp (field, "min"); + prop = xmlGetProp (field, "max"); sscanf (prop, "%d", &entry->data.int_range_data.max); g_free (prop); } @@ -601,6 +601,10 @@ gst_props_load_thyself_func (xmlNodePtr field) sscanf (prop, "%08x", &entry->data.fourcc_data); g_free (prop); } + else { + g_free (entry); + entry = NULL; + } return entry; } @@ -634,7 +638,8 @@ gst_props_load_thyself (xmlNodePtr parent) while (subfield) { GstPropsEntry *subentry = gst_props_load_thyself_func (subfield); - entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, subentry); + if (subentry) + entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, subentry); subfield = subfield->next; } diff --git a/gst/gsttype.c b/gst/gsttype.c index 84090e74d3..7b7b34efd3 100644 --- a/gst/gsttype.c +++ b/gst/gsttype.c @@ -43,10 +43,10 @@ struct _GstTypeFindInfo { GstPlugin *plugin; /* the plugin with this typefind function */ }; -static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv); +static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv); -void -_gst_type_initialize (void) +void +_gst_type_initialize (void) { _gst_types = NULL; _gst_maxtype = 1; /* type 0 is undefined */ @@ -60,8 +60,8 @@ _gst_type_initialize (void) * * Returns: the new type id */ -guint16 -gst_type_register (GstTypeFactory *factory) +guint16 +gst_type_register (GstTypeFactory *factory) { guint16 id; GstType *type; @@ -70,14 +70,14 @@ gst_type_register (GstTypeFactory *factory) // GST_INFO (GST_CAT_TYPES,"type register %s", factory->mime); id = gst_type_find_by_mime (factory->mime); - + if (!id) { type = g_new0 (GstType, 1); - type->id = _gst_maxtype++; - type->mime = factory->mime; - type->exts = factory->exts; - _gst_types = g_list_prepend (_gst_types, type); + type->id = _gst_maxtype++; + type->mime = factory->mime; + type->exts = factory->exts; + _gst_types = g_list_prepend (_gst_types, type); id = type->id; @@ -96,8 +96,8 @@ gst_type_register (GstTypeFactory *factory) return id; } -static -guint16 gst_type_find_by_mime_func (const gchar *mime) +static +guint16 gst_type_find_by_mime_func (const gchar *mime) { GList *walk; GstType *type; @@ -142,8 +142,8 @@ guint16 gst_type_find_by_mime_func (const gchar *mime) * * Returns: the type id */ -guint16 -gst_type_find_by_mime (const gchar *mime) +guint16 +gst_type_find_by_mime (const gchar *mime) { return gst_type_find_by_mime_func (mime); } @@ -156,8 +156,8 @@ gst_type_find_by_mime (const gchar *mime) * * Returns: the type id */ -guint16 -gst_type_find_by_ext (const gchar *ext) +guint16 +gst_type_find_by_ext (const gchar *ext) { //FIXME g_warning ("gsttype: find_by_ext not implemented"); @@ -173,7 +173,7 @@ gst_type_find_by_ext (const gchar *ext) * Returns: the type */ GstType* -gst_type_find_by_id (guint16 id) +gst_type_find_by_id (guint16 id) { GList *walk = _gst_types; GstType *type; @@ -196,7 +196,7 @@ gst_type_find_by_id (guint16 id) * Returns: a list of GstTypes */ GList* -gst_type_get_list (void) +gst_type_get_list (void) { return _gst_types; } @@ -210,8 +210,8 @@ gst_type_get_list (void) * * Returns: the new xmlNodePtr */ -xmlNodePtr -gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) +xmlNodePtr +gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) { xmlNewChild (parent, NULL, "mime", factory->mime); if (factory->exts) { @@ -220,11 +220,11 @@ gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) if (factory->typefindfunc) { xmlNewChild (parent, NULL, "typefind", NULL); } - + return parent; } -static GstCaps * +static GstCaps * gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv) { GstType *type = (GstType *)priv; @@ -263,7 +263,7 @@ gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv) * Returns: the new typefactory */ GstTypeFactory* -gst_typefactory_load_thyself (xmlNodePtr parent) +gst_typefactory_load_thyself (xmlNodePtr parent) { GstTypeFactory *factory = g_new0 (GstTypeFactory, 1); diff --git a/gstplay/gstplay.c b/gstplay/gstplay.c index 7c3e82886f..660c02e8d6 100644 --- a/gstplay/gstplay.c +++ b/gstplay/gstplay.c @@ -206,14 +206,20 @@ gst_play_audio_handoff (GstElement *element, } static void -gst_play_object_introspect (GstElement *element, +gst_play_object_introspect (GstObject *object, const gchar *property, GstElement **target) { gchar *info; GtkArgInfo *arg; + GstElement *element; - info = gtk_object_arg_get_info( GTK_OBJECT_TYPE(element), property, &arg); + if (!GST_IS_ELEMENT (object)) + return; + + element = GST_ELEMENT (object); + + info = gtk_object_arg_get_info (GTK_OBJECT_TYPE (element), property, &arg); if (info) { g_free(info); @@ -229,8 +235,8 @@ gst_play_object_introspect (GstElement *element, * this will change with glib 1.4 * */ static void -gst_play_object_added (GstElement *pipeline, - GstElement *element, +gst_play_object_added (GstAutoplug* autoplug, + GstObject *object, GstPlay *play) { GstPlayPrivate *priv; @@ -239,23 +245,23 @@ gst_play_object_added (GstElement *pipeline, priv = (GstPlayPrivate *)play->priv; - if (GST_FLAG_IS_SET (element, GST_ELEMENT_NO_SEEK)) { + if (GST_FLAG_IS_SET (object, GST_ELEMENT_NO_SEEK)) { priv->can_seek = FALSE; } - if (GST_IS_BIN (element)) { - gtk_signal_connect (GTK_OBJECT (element), "object_added", gst_play_object_added, play); + if (GST_IS_BIN (object)) { + //gtk_signal_connect (GTK_OBJECT (object), "object_added", gst_play_object_added, play); } else { // first come first serve here... if (!priv->offset_element) - gst_play_object_introspect (element, "offset", &priv->offset_element); + gst_play_object_introspect (object, "offset", &priv->offset_element); if (!priv->bit_rate_element) - gst_play_object_introspect (element, "bit_rate", &priv->bit_rate_element); + gst_play_object_introspect (object, "bit_rate", &priv->bit_rate_element); if (!priv->media_time_element) - gst_play_object_introspect (element, "media_time", &priv->media_time_element); + gst_play_object_introspect (object, "media_time", &priv->media_time_element); if (!priv->current_time_element) - gst_play_object_introspect (element, "current_time", &priv->current_time_element); + gst_play_object_introspect (object, "current_time", &priv->current_time_element); } } @@ -337,6 +343,7 @@ gst_play_set_uri (GstPlay *play, GstPlayPrivate *priv; GstCaps *src_caps; GstElement *new_element; + GstAutoplug *autoplug; g_return_val_if_fail (play != NULL, GST_PLAY_ERROR); g_return_val_if_fail (GST_IS_PLAY (play), GST_PLAY_ERROR); @@ -351,6 +358,7 @@ gst_play_set_uri (GstPlay *play, priv->src = gst_elementfactory_make ("disksrc", "disk_src"); //priv->src = gst_elementfactory_make ("dvdsrc", "disk_src"); + priv->offset_element = priv->src; g_return_val_if_fail (priv->src != NULL, -1); gtk_object_set (GTK_OBJECT (priv->src), "location", uri, NULL); @@ -363,8 +371,12 @@ gst_play_set_uri (GstPlay *play, return GST_PLAY_UNKNOWN_MEDIA; } - new_element = gst_autoplug_caps_list - (gst_pad_get_caps_list (gst_element_get_pad (priv->src, "src")), + autoplug = gst_autoplugfactory_make ("static"); + + gtk_signal_connect (GTK_OBJECT (autoplug), "new_object", gst_play_object_added, play); + + new_element = gst_autoplug_caps_list (autoplug, + gst_pad_get_caps_list (gst_element_get_pad (priv->src, "src")), gst_pad_get_caps_list (gst_element_get_pad (priv->video_queue, "sink")), gst_pad_get_caps_list (gst_element_get_pad (priv->audio_queue, "sink")), NULL); diff --git a/plugins/elements/gstdisksrc.c b/plugins/elements/gstdisksrc.c index fbeaddc853..1978a15b56 100644 --- a/plugins/elements/gstdisksrc.c +++ b/plugins/elements/gstdisksrc.c @@ -32,7 +32,7 @@ GstElementDetails gst_disksrc_details = { - "hronous Disk Source", + "asynchronous Disk Source", "Source/File", "Read from arbitrary point in a file", VERSION, diff --git a/plugins/elements/gstelements.c b/plugins/elements/gstelements.c index 294793df44..1621fd20b4 100644 --- a/plugins/elements/gstelements.c +++ b/plugins/elements/gstelements.c @@ -2,7 +2,7 @@ * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * - * gstelements.c: + * gstelements.c: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -48,27 +48,27 @@ struct _elements_entry { }; static struct _elements_entry _elements[] = { - { "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details, NULL }, - { "fakesink", gst_fakesink_get_type, &gst_fakesink_details, NULL }, - { "asyncdisksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, - { "audiosink", gst_audiosink_get_type, &gst_audiosink_details, gst_audiosink_factory_init }, - { "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details, NULL }, - { "disksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, - { "identity", gst_identity_get_type, &gst_identity_details, NULL }, - { "fdsink", gst_fdsink_get_type, &gst_fdsink_details, NULL }, - { "fdsrc", gst_fdsrc_get_type, &gst_fdsrc_details, NULL }, - { "pipefilter", gst_pipefilter_get_type, &gst_pipefilter_details, NULL }, - { "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details, NULL }, - { "tee", gst_tee_get_type, &gst_tee_details, gst_tee_factory_init }, + { "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details, NULL }, + { "fakesink", gst_fakesink_get_type, &gst_fakesink_details, NULL }, + { "asyncdisksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, + { "audiosink", gst_audiosink_get_type, &gst_audiosink_details, gst_audiosink_factory_init }, + { "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details, NULL }, + { "disksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, + { "identity", gst_identity_get_type, &gst_identity_details, NULL }, + { "fdsink", gst_fdsink_get_type, &gst_fdsink_details, NULL }, + { "fdsrc", gst_fdsrc_get_type, &gst_fdsrc_details, NULL }, + { "pipefilter", gst_pipefilter_get_type, &gst_pipefilter_details, NULL }, + { "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details, NULL }, + { "tee", gst_tee_get_type, &gst_tee_details, gst_tee_factory_init }, #if HAVE_LIBGHTTP - { "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details, NULL }, + { "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details, NULL }, #endif /* HAVE_LIBGHTTP */ - + { NULL, 0 }, }; -GstPlugin *plugin_init (GModule *module) +GstPlugin *plugin_init (GModule *module) { GstPlugin *plugin; GstElementFactory *factory; diff --git a/tests/Makefile.am b/tests/Makefile.am index 1c6bed2cc2..d40db412c7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = sched eos noinst_PROGRAMS = init loadall simplefake states caps queue registry \ -paranoia rip mp3encode autoplug props case4 markup load tee +paranoia rip mp3encode autoplug props case4 markup load tee autoplug2 # we have nothing but apps here, we can do this safely LIBS += $(GST_LIBS) diff --git a/tests/autoplug.c b/tests/autoplug.c index 83092d07b5..198824c487 100644 --- a/tests/autoplug.c +++ b/tests/autoplug.c @@ -1,10 +1,17 @@ #include +static void +new_object_added (GstAutoplug *autoplug, GstObject *object) +{ + g_print ("added new object \"%s\"\n", gst_object_get_name (object)); +} + int main (int argc, char *argv[]) { GstElement *element; GstElement *videosink, *audiosink; + GstAutoplug *autoplugger; GList *testcaps; gst_init(&argc,&argv); @@ -22,9 +29,14 @@ main (int argc, char *argv[]) "systemstream", GST_PROPS_BOOLEAN (TRUE), NULL))); + autoplugger = gst_autoplugfactory_make ("static"); - element = gst_autoplug_caps_list (testcaps, gst_pad_get_caps_list (gst_element_get_pad (audiosink, "sink")), - gst_pad_get_caps_list (gst_element_get_pad (videosink, "sink")), NULL); + gtk_signal_connect (GTK_OBJECT (autoplugger), "new_object", new_object_added, NULL); + + element = gst_autoplug_caps_list (autoplugger, testcaps, + gst_pad_get_caps_list (gst_element_get_pad (audiosink, "sink")), + gst_pad_get_caps_list (gst_element_get_pad (videosink, "sink")), + NULL); g_assert (element != NULL); xmlDocDump (stdout, gst_xml_write (element)); diff --git a/tests/autoplug2.c b/tests/autoplug2.c new file mode 100644 index 0000000000..8a90882b28 --- /dev/null +++ b/tests/autoplug2.c @@ -0,0 +1,52 @@ +#include + +static GstElement* +autoplug_caps (gchar *mime1, gchar *mime2) +{ + GList *caps1, *caps2; + + caps1 = g_list_append (NULL, gst_caps_new ("tescaps1", mime1)); + caps2 = g_list_append (NULL, gst_caps_new ("tescaps2", mime2)); + + return gst_autoplug_caps_list (caps1, caps2, NULL); +} + +int +main (int argc, char *argv[]) +{ + GstElement *element; + + gst_init(&argc,&argv); + + element = autoplug_caps ("audio/mp3", "audio/raw"); + xmlSaveFile ("autoplug2_1.gst", gst_xml_write (element)); + + element = autoplug_caps ("video/mpeg", "audio/raw"); + xmlSaveFile ("autoplug2_2.gst", gst_xml_write (element)); + + element = gst_autoplug_caps_list ( + g_list_append (NULL, gst_caps_new_with_props( + "testcaps3", + "video/mpeg", + gst_props_new ( + "mpegversion", GST_PROPS_INT (1), + "systemstream", GST_PROPS_BOOLEAN (TRUE), + NULL))), + g_list_append (NULL, gst_caps_new("testcaps4","audio/raw")), + NULL); + xmlSaveFile ("autoplug2_3.gst", gst_xml_write (element)); + + element = gst_autoplug_caps_list ( + g_list_append (NULL, gst_caps_new_with_props( + "testcaps5", + "video/mpeg", + gst_props_new ( + "mpegversion", GST_PROPS_INT (1), + "systemstream", GST_PROPS_BOOLEAN (FALSE), + NULL))), + g_list_append (NULL, gst_caps_new("testcaps6", "video/raw")), + NULL); + xmlSaveFile ("autoplug2_4.gst", gst_xml_write (element)); + + exit (0); +} diff --git a/tools/gstreamer-inspect.c b/tools/gstreamer-inspect.c index a95392e9cb..f8d4ac3703 100644 --- a/tools/gstreamer-inspect.c +++ b/tools/gstreamer-inspect.c @@ -42,7 +42,7 @@ void print_prop(GstPropsEntry *prop,gboolean showname,gchar *pfx) { g_free(longprefix); break; default: - printf("\n"); + printf("unknown props %d\n", prop->propstype); } } @@ -59,30 +59,9 @@ void print_props(GstProps *properties,gchar *pfx) { } } -/* -struct _GstPropsEntry { - GQuark propid; - GstPropsId propstype; - - union { - // flat values - gboolean bool_data; - guint32 fourcc_data; - gint int_data; - - // structured values - struct { - GList *entries; - } list_data; - struct { - gint min; - gint max; - } int_range_data; - } data; -}; -*/ - -gint print_element_info(GstElementFactory *factory) { +gint +print_element_info (GstElementFactory *factory) +{ GstElement *element; GstObjectClass *gstobject_class; GstElementClass *gstelement_class; @@ -322,11 +301,9 @@ void print_element_list() { } } - -void print_plugin_info(GstPlugin *plugin) { - GList *factories; - GstElementFactory *factory; - +void +print_plugin_info (GstPlugin *plugin) +{ printf("Plugin Details:\n"); printf(" Name:\t\t%s\n",plugin->name); printf(" Long Name:\t%s\n",plugin->longname); @@ -334,6 +311,9 @@ void print_plugin_info(GstPlugin *plugin) { printf("\n"); if (plugin->numelements) { + GList *factories; + GstElementFactory *factory; + printf("Element Factories:\n"); factories = gst_plugin_get_factory_list(plugin); @@ -344,6 +324,36 @@ void print_plugin_info(GstPlugin *plugin) { printf(" %s: %s\n",factory->name,factory->details->longname); } } + if (plugin->numautopluggers) { + GList *factories; + GstAutoplugFactory *factory; + + printf("Autpluggers:\n"); + + factories = gst_plugin_get_autoplug_list(plugin); + while (factories) { + factory = (GstAutoplugFactory*)(factories->data); + factories = g_list_next(factories); + + printf(" %s: %s\n", factory->name, factory->longdesc); + } + } + if (plugin->numtypes) { + GList *factories; + GstTypeFactory *factory; + + printf("Types:\n"); + + factories = gst_plugin_get_type_list(plugin); + while (factories) { + factory = (GstTypeFactory*)(factories->data); + factories = g_list_next(factories); + + printf(" %s: %s\n", factory->mime, factory->exts); + if (factory->typefindfunc) + printf(" Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(factory->typefindfunc)); + } + } printf("\n"); } @@ -357,7 +367,7 @@ int main(int argc,char *argv[]) { // if no arguments, print out list of elements if (argc == 1) { - print_element_list(); + print_element_list(); // else we try to get a factory } else {