diff --git a/configure.in b/configure.in
index 0344b85838..4eacd91bf8 100644
--- a/configure.in
+++ b/configure.in
@@ -597,6 +597,7 @@ AM_CONDITIONAL(HAVE_LIBSHOUT, test "x$HAVE_LIBSHOUT" = "xyes")
AM_CONDITIONAL(HAVE_LIBESD, test "x$HAVE_LIBESD" = "xyes")
AM_CONDITIONAL(HAVE_LIBASOUND, test "x$HAVE_LIBASOUND" = "xyes")
AM_CONDITIONAL(HAVE_MPEG2DEC, test "x$HAVE_MPEG2DEC" = "xyes")
+AM_CONDITIONAL(HAVE_LIBXMMS, test "x$HAVE_LIBXMMS" = "xyes")
@@ -680,6 +681,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/docs/gst/tmpl/gstautoplug.sgml b/docs/gst/tmpl/gstautoplug.sgml
index 2ea069b281..0fe0ed4306 100644
--- a/docs/gst/tmpl/gstautoplug.sgml
+++ b/docs/gst/tmpl/gstautoplug.sgml
@@ -15,60 +15,18 @@ to convert a certain GstCaps to another one.
-
-
-The maximum cost of a certain connection.
-
-
-
-
-
-
-Calculate the cost between two elements.
-
-
-@src: the source element
-@dest: the destination element
-@data: optional user data
-@Returns: the cost for a connection between the two elements
-
-
-
-
-Get a list of all elements. These elements will be used in autoplugging.
-
-
-@data: user data
-@Returns: a GList of elements
-
-
-
-
-
-
-
-@srccaps:
-@sinkcaps:
-@Returns:
-
-
-
-
-
-
-
-@srcpad:
-@sinkpad:
-@Returns:
-
-
+@autoplug:
+@srcpad:
+@sinkpad:
+@Varargs:
+@Returns:
+
@srccaps:
@sinkcaps:
-@Returns:
diff --git a/docs/gst/tmpl/gstpad.sgml b/docs/gst/tmpl/gstpad.sgml
index db45773d2d..5a5dd33144 100644
--- a/docs/gst/tmpl/gstpad.sgml
+++ b/docs/gst/tmpl/gstpad.sgml
@@ -133,6 +133,8 @@ a start/stop timecode pair.
@offset: the offset of the region to get
@len: the length of the region to get
@Returns: a #GstBuffer
+
+@size: the size of the region to get
diff --git a/docs/gst/tmpl/gstpipeline.sgml b/docs/gst/tmpl/gstpipeline.sgml
index da53a47805..f486cfb193 100644
--- a/docs/gst/tmpl/gstpipeline.sgml
+++ b/docs/gst/tmpl/gstpipeline.sgml
@@ -38,33 +38,6 @@ pipeline figure out what plugins to use.
@Returns:
-
-
-
-
-
-@pipeline:
-@sink:
-
-
-
-
-
-
-
-@pipeline:
-@src:
-
-
-
-
-
-
-
-@pipeline:
-@Returns:
-
-
Destroys the pipeline.
diff --git a/docs/gst/tmpl/gstplugin.sgml b/docs/gst/tmpl/gstplugin.sgml
index b281b08a9f..b4b87637e0 100644
--- a/docs/gst/tmpl/gstplugin.sgml
+++ b/docs/gst/tmpl/gstplugin.sgml
@@ -27,6 +27,8 @@ GStreamer is extensible so GstElements can be loaded at r
@numtypes:
@elements:
@numelements:
+@autopluggers:
+@numautopluggers:
@loaded:
@@ -203,15 +205,6 @@ by the loader at statup.
@Returns:
-
-
-
-
-
-@name:
-@Returns:
-
-
diff --git a/docs/gst/tmpl/gstreamer-unused.sgml b/docs/gst/tmpl/gstreamer-unused.sgml
index 1740957e0d..5f5ff9c6ea 100644
--- a/docs/gst/tmpl/gstreamer-unused.sgml
+++ b/docs/gst/tmpl/gstreamer-unused.sgml
@@ -780,10 +780,6 @@ Query whether this object has multiple input pads.
-
-Asynchronous disk reader. (asyncdisksrc)
-
-
@@ -1383,11 +1379,15 @@ The start point of a filter graph
@klass:
+<<<<<<< gstreamer-unused.sgml
GstAsyncDiskSrc
+=======
+
+>>>>>>> 1.23.2.3
@@ -2009,6 +2009,7 @@ GstFilter
+<<<<<<< gstreamer-unused.sgml
Flags for the GstSrc element
@@ -2024,6 +2025,18 @@ Flags for the GstSrc element
+=======
+
+
+Flags for the GstSrc element
+
+
+@GST_SRC_ASYNC: Indicates that this src is asynchronous
+@GST_SRC_FLAG_LAST: subclasses can use this to number their flags
+
+
+
+>>>>>>> 1.23.2.3
diff --git a/docs/random/hierarchy b/docs/random/hierarchy
new file mode 100644
index 0000000000..fc854aff72
--- /dev/null
+++ b/docs/random/hierarchy
@@ -0,0 +1,149 @@
+Face it, the plugins/ directory hierarchy is crap. We want to propose a
+better layout for it now. Some things to consider:
+
+ - Elements have a klass member in the factory that is used to
+ denote the functional type of the element. For example, the
+ mp3 encoder has a klass of Filter/Encoder/Audio
+
+ - The plugins can be grouped together by the media type they
+ operate on or by the way they work (decoder/encoder)
+
+In GStreamer all plugins are techically filters, the only way they
+can be considered sources or sinks (input/output) elements is
+by the absence of src/sink pads. At first sight the source/filter/
+sink distinction is quite useless because most of the plugins
+will go into the filters category anyway.
+
+We don't want to make the hierarchy too deep, yet provide a
+clean way to ask for a mp3 decoder element..
+
+Anyway this is a rough proposal to fire off the discussions...
+
+Wim
+
+Source
+ Disk
+ disksrc
+ fdsrc
+ multifilesrc
+ Network
+ HTTPsrc
+ RTPsrc
+ CDDA
+ cdparanoia
+ XMMS
+ ..
+ DVD
+ dvdsrc
+ Audio
+ ASLA
+ OSS
+ Capture
+ v4lsrc
+ firewire
+
+Demuxer
+ AVI
+ MPEG1
+ MPEG2
+ QT
+
+Muxer
+ AVI
+ MPEG1
+ QT
+
+Aggregator
+
+Tee
+ gsttee
+
+Connection
+ queue
+ CORBA
+
+Parser
+ MPEG1
+ MPEG2
+ AC3
+
+Mixer
+ Audio
+ Merge
+ Video
+ Subtitles
+ Merge
+
+Filters
+ Audio
+ ladspa
+ resample
+ Video
+ colorspace
+
+Effect
+ Audio
+ stereo
+ volume
+ delay
+ chorus
+ Video
+ median
+ smooth
+ XMMS
+
+Decoder
+ MPEG1
+ MPEG2
+ MP3
+ mpg123
+ xing
+ win32
+ AU
+ WAV
+ JPEG
+ AC3
+ ac3dec
+ RTJPEG
+ vorbis
+
+Encoder
+ MPEG1
+ MPEG2
+ MP3
+ lame
+ mpegaudio
+ win32
+ JPEG
+ AU
+ WAV
+ RTJPEG
+ Vorbis
+
+Visualisation
+ Video
+ histogram
+ Audio
+ smoothwave
+ spectrum
+ synaesthesia
+ vumeter
+ XMMS
+
+Sink
+ Disk
+ filesink
+ multifilesink
+ Network
+ ICECASTsink
+ FTPsink
+ RTPsink
+ XMMS
+ ESD
+ Video
+ videosink
+ SDLsink
+ Audio
+ OSSsink
+ ALSAsink
+
diff --git a/docs/random/wtay/autoplug2 b/docs/random/wtay/autoplug2
index 1c0f6f808c..c56f9b1f54 100644
--- a/docs/random/wtay/autoplug2
+++ b/docs/random/wtay/autoplug2
@@ -42,22 +42,26 @@ any intermediate steps to accomplish this conversion.
The API for the user apps should be no more then this:
- GstElement* gst_autoplug_construct (GstAutoplug *autoplug,
- GstCaps *incaps,
- GstCaps *outcaps, ...);
+ GstElement* gst_autoplug_caps_list (GstAutoplug *autoplug,
+ GList *incaps,
+ GList *outcaps, ...);
autoplug is a reference to the autoplug implementation
- incaps is a GstCaps handle for the source pad, the last set
- of arguments is a va_list of destination caps.
+ incaps is a GList of GstCaps* for the source pad, the last set
+ of arguments is a va_list of destination caps lists.
A handle to the autoplugger implementation can be obtained
with
- GList* gst_autoplug_get_list (void);
+ GList* gst_autoplugfactory_get_list (void);
which will return a GList* of autopluggers.
- GstAutoplug* gst_autoplug_get ("name");
+ GstAutoplug* gst_autoplugfactory_make ("name");
+
+or
+
+ GstAutoplug* gst_autoplugfactory_create (GstAutoplugFactory *autoplug);
is used to get an autoplugger.
@@ -72,11 +76,12 @@ overriding various methods.
the autoplugger can be registered with:
gst_plugin_add_autoplugger (GstPlugin *plugin,
- GstAutoplug *autoplug);
+ GstAutoplugFactory *autoplug);
This will allow us to only load the autoplugger when needed.
+
4) implementation
-----------------
@@ -108,11 +113,9 @@ properties:
- name, description, more text to identify the autoplugger.
- - a class method autoplug_construct that has to be implemented by
+ - a class method autoplug_caps_list that has to be implemented by
the real autoplugger.
- - possible PadTemplates that this autoplugger can handle well?
-
optionally, the core autoplugger code can provide convenience
functions to implement custom autopluggers. The shortest path
algorithm with pluggable weighting and list functions come to
@@ -124,8 +127,9 @@ A possible use case would be to let gstmediaplay perform an
autoplug on the media stream and insert a custom sound/video
effect in the pipeline when an appropriate element is created.
+the "new_object" signal will be fired by the autoplugger whenever
+a new object has been created. This signal can be caught by the
+user app to perform an introspection on the newly created object.
+
-comments?
-Wim
-
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/examples/autoplug/autoplug.c b/examples/autoplug/autoplug.c
index 4a3453552c..4e37b5d999 100644
--- a/examples/autoplug/autoplug.c
+++ b/examples/autoplug/autoplug.c
@@ -31,8 +31,6 @@ int main(int argc,char *argv[])
exit(-1);
}
-
-
/* create a new bin to hold the elements */
pipeline = gst_pipeline_new("pipeline");
g_assert(pipeline != NULL);
@@ -59,6 +57,7 @@ int main(int argc,char *argv[])
gtk_widget_show_all(appwindow);
/* add objects to the main pipeline */
+ /*
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), videosink);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
@@ -67,6 +66,7 @@ int main(int argc,char *argv[])
g_print("unable to handle stream\n");
exit(-1);
}
+ */
xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(pipeline)));
diff --git a/examples/helloworld2/helloworld2.c b/examples/helloworld2/helloworld2.c
index 90de5139d5..8b70518eda 100644
--- a/examples/helloworld2/helloworld2.c
+++ b/examples/helloworld2/helloworld2.c
@@ -41,6 +41,7 @@ int main(int argc,char *argv[])
g_assert(audiosink != NULL);
/* add objects to the main pipeline */
+ /*
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
@@ -48,6 +49,7 @@ int main(int argc,char *argv[])
g_print("unable to handle stream\n");
exit(-1);
}
+ */
// hmmmm hack? FIXME
GST_FLAG_UNSET (pipeline, GST_BIN_FLAG_MANAGER);
diff --git a/examples/queue2/queue2.c b/examples/queue2/queue2.c
index a3662b14e6..706acc073f 100644
--- a/examples/queue2/queue2.c
+++ b/examples/queue2/queue2.c
@@ -46,11 +46,12 @@ int main(int argc,char *argv[])
g_assert(audiosink != NULL);
/* add objects to the main pipeline */
+ /*
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), queue);
gst_bin_add(GST_BIN(thread), audiosink);
-
+
gst_pad_connect(gst_element_get_pad(queue,"src"),
gst_element_get_pad(audiosink,"sink"));
@@ -58,6 +59,7 @@ int main(int argc,char *argv[])
g_print("cannot autoplug pipeline\n");
exit(-1);
}
+ */
gst_bin_add(GST_BIN(pipeline), thread);
diff --git a/examples/thread/thread.c b/examples/thread/thread.c
index 533c38a6f7..b8bc00e1de 100644
--- a/examples/thread/thread.c
+++ b/examples/thread/thread.c
@@ -45,6 +45,7 @@ int main(int argc,char *argv[])
g_assert(audiosink != NULL);
/* add objects to the main pipeline */
+ /*
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
@@ -52,6 +53,7 @@ int main(int argc,char *argv[])
g_print("unable to handle stream\n");
exit(-1);
}
+ */
//gst_bin_remove(GST_BIN(pipeline), disksrc);
diff --git a/gst/Makefile.am b/gst/Makefile.am
index d25c9f9468..c5f4e9310e 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/autoplug/Makefile.am b/gst/autoplug/Makefile.am
new file mode 100644
index 0000000000..0ddb2a8a74
--- /dev/null
+++ b/gst/autoplug/Makefile.am
@@ -0,0 +1,12 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgststaticautoplug.la libgststaticautoplugrender.la
+
+libgststaticautoplug_la_SOURCES = \
+ gststaticautoplug.c
+
+libgststaticautoplugrender_la_SOURCES = \
+ gststaticautoplugrender.c
+
+libgststaticautoplug_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
+libgststaticautoplugrender_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
diff --git a/gst/autoplug/gststaticautoplug.c b/gst/autoplug/gststaticautoplug.c
new file mode 100644
index 0000000000..a39ac579fe
--- /dev/null
+++ b/gst/autoplug/gststaticautoplug.c
@@ -0,0 +1,619 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen
+ * 2000 Wim Taymans
+ *
+ * gststaticautoplug.c: A static Autoplugger of pipelines
+ *
+ * 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 "gststaticautoplug.h"
+
+#include
+
+#define GST_AUTOPLUG_MAX_COST 999999
+
+typedef guint (*GstAutoplugCostFunction) (gpointer src, gpointer dest, gpointer data);
+typedef GList* (*GstAutoplugListFunction) (gpointer data);
+
+
+static void gst_static_autoplug_class_init (GstStaticAutoplugClass *klass);
+static void gst_static_autoplug_init (GstStaticAutoplug *autoplug);
+
+static GList* gst_autoplug_func (gpointer src, gpointer sink,
+ GstAutoplugListFunction list_function,
+ GstAutoplugCostFunction cost_function,
+ gpointer data);
+
+
+
+static GstElement* gst_static_autoplug_to_caps (GstAutoplug *autoplug,
+ GList *srccaps, GList *sinkcaps, va_list args);
+
+static GstAutoplugClass *parent_class = NULL;
+
+GtkType gst_static_autoplug_get_type(void)
+{
+ static GtkType static_autoplug_type = 0;
+
+ if (!static_autoplug_type) {
+ static const GtkTypeInfo static_autoplug_info = {
+ "GstStaticAutoplug",
+ sizeof(GstElement),
+ sizeof(GstElementClass),
+ (GtkClassInitFunc)gst_static_autoplug_class_init,
+ (GtkObjectInitFunc)gst_static_autoplug_init,
+ (GtkArgSetFunc)NULL,
+ (GtkArgGetFunc)NULL,
+ (GtkClassInitFunc)NULL,
+ };
+ static_autoplug_type = gtk_type_unique (GST_TYPE_AUTOPLUG, &static_autoplug_info);
+ }
+ return static_autoplug_type;
+}
+
+static void
+gst_static_autoplug_class_init(GstStaticAutoplugClass *klass)
+{
+ GstAutoplugClass *gstautoplug_class;
+
+ gstautoplug_class = (GstAutoplugClass*) klass;
+
+ parent_class = gtk_type_class(GST_TYPE_AUTOPLUG);
+
+ gstautoplug_class->autoplug_to_caps = gst_static_autoplug_to_caps;
+}
+
+static void gst_static_autoplug_init(GstStaticAutoplug *autoplug) {
+}
+
+GstPlugin*
+plugin_init (GModule *module)
+{
+ GstPlugin *plugin;
+ GstAutoplugFactory *factory;
+
+ plugin = gst_plugin_new("gststaticautoplug");
+ g_return_val_if_fail(plugin != NULL,NULL);
+
+ gst_plugin_set_longname (plugin, "A static autoplugger");
+
+ factory = gst_autoplugfactory_new ("static",
+ "A static autoplugger, it constructs the complete element before running it",
+ gst_static_autoplug_get_type ());
+
+ if (factory != NULL) {
+ gst_plugin_add_autoplugger (plugin, factory);
+ }
+ return plugin;
+}
+
+static gboolean
+gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
+{
+ GList *srctemps, *desttemps;
+
+ srctemps = src->padtemplates;
+
+ while (srctemps) {
+ GstPadTemplate *srctemp = (GstPadTemplate *)srctemps->data;
+
+ desttemps = dest->padtemplates;
+
+ 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;
+}
+
+static gboolean
+gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
+{
+ 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;
+}
+
+typedef struct {
+ GstElement *result;
+ GList *endcap;
+ gint i;
+} dynamic_pad_struct;
+
+static void
+autoplug_dynamic_pad (GstElement *element, GstPad *pad, gpointer data)
+{
+ dynamic_pad_struct *info = (dynamic_pad_struct *)data;
+ GList *pads = gst_element_get_pad_list (element);
+
+ GST_DEBUG (0,"attempting to dynamically create a ghostpad for %s=%s\n", GST_ELEMENT_NAME (element),
+ GST_PAD_NAME (pad));
+
+ 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), info->endcap)) {
+ gst_element_add_ghost_pad (info->result, pad, g_strdup_printf("src_%02d", info->i));
+ GST_DEBUG (0,"gstpipeline: new dynamic pad %s\n", GST_PAD_NAME (pad));
+ break;
+ }
+ }
+}
+
+static void
+gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink)
+{
+ 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);
+ }
+}
+
+static GList*
+gst_autoplug_elementfactory_get_list (gpointer data)
+{
+ return gst_elementfactory_get_list ();
+}
+
+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)
+{
+ caps_struct *caps = (caps_struct *)data;
+ gboolean res;
+
+ 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);
+ }
+
+ if (res)
+ return 1;
+ else
+ return GST_AUTOPLUG_MAX_COST;
+}
+
+static GstElement*
+gst_static_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, va_list args)
+{
+ caps_struct caps;
+ GList *capslist;
+ GstElement *result = NULL, *srcelement = NULL;
+ GList **factories;
+ GList *chains = NULL;
+ GList *endcaps = NULL;
+ guint numsinks = 0, i;
+ gboolean have_common = FALSE;
+
+ capslist = sinkcaps;
+
+ /*
+ * 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;
+
+ while (capslist) {
+ GList *elements;
+
+ caps.sink = capslist;
+
+ GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
+
+ 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 *);
+ }
+
+ /*
+ * If no list could be found the pipeline cannot be autoplugged and
+ * we return a NULL element
+ */
+ if (numsinks == 0)
+ 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);
+ }
+ }
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
+
+ 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);
+
+ GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
+ gst_bin_add(GST_BIN(thebin), element);
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (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);
+ gboolean have_pad = FALSE;
+ endcaps = g_list_next (endcaps);
+
+ GST_DEBUG (0,"attempting to create a ghostpad for %s\n", GST_ELEMENT_NAME (thesrcelement));
+
+ 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));
+ have_pad = TRUE;
+ break;
+ }
+ }
+ if (!have_pad) {
+ dynamic_pad_struct *data = g_new0(dynamic_pad_struct, 1);
+
+ data->result = result;
+ data->endcap = endcap;
+ data->i = i;
+
+ GST_DEBUG (0,"delaying the creation of a ghostpad for %s\n", GST_ELEMENT_NAME (thesrcelement));
+ gtk_signal_connect (GTK_OBJECT (thesrcelement), "new_pad",
+ autoplug_dynamic_pad, data);
+ gtk_signal_connect (GTK_OBJECT (thesrcelement), "new_ghost_pad",
+ autoplug_dynamic_pad, data);
+ }
+ }
+ }
+
+ return result;
+}
+
+/*
+ * shortest path algorithm
+ *
+ */
+struct _gst_autoplug_node
+{
+ gpointer iNode;
+ gpointer iPrev;
+ gint iDist;
+};
+
+typedef struct _gst_autoplug_node gst_autoplug_node;
+
+static gint
+find_factory (gst_autoplug_node *rgnNodes, gpointer factory)
+{
+ gint i=0;
+
+ while (rgnNodes[i].iNode) {
+ if (rgnNodes[i].iNode == factory) return i;
+ i++;
+ }
+ return 0;
+}
+
+static GList*
+construct_path (gst_autoplug_node *rgnNodes, gpointer factory)
+{
+ GstElementFactory *current;
+ GList *factories = NULL;
+
+ 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);
+ }
+ 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);
+ }
+
+ 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);
+}
+
diff --git a/gst/autoplug/gststaticautoplug.h b/gst/autoplug/gststaticautoplug.h
new file mode 100644
index 0000000000..9a99097975
--- /dev/null
+++ b/gst/autoplug/gststaticautoplug.h
@@ -0,0 +1,64 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen
+ * 2000 Wim Taymans
+ *
+ * gstautoplug.h: Header for autoplugging functionality
+ *
+ * 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.
+ */
+
+
+#ifndef __GST_STATIC_AUTOPLUG_H__
+#define __GST_STATIC_AUTOPLUG_H__
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GST_TYPE_STATIC_AUTOPLUG \
+ (gst_static_autoplug_get_type())
+#define GST_STATIC_AUTOPLUG(obj) \
+ (GTK_CHECK_CAST((obj),GST_TYPE_STATIC_AUTOPLUG,GstStaticAutoplug))
+#define GST_STATIC_AUTOPLUG_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_STATIC_AUTOPLUG,GstStaticAutoplugClass))
+#define GST_IS_STATIC_AUTOPLUG(obj) \
+ (GTK_CHECK_TYPE((obj),GST_TYPE_STATIC_AUTOPLUG))
+#define GST_IS_STATIC_AUTOPLUG_CLASS(obj) \
+ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_STATIC_AUTOPLUG))
+
+typedef struct _GstStaticAutoplug GstStaticAutoplug;
+typedef struct _GstStaticAutoplugClass GstStaticAutoplugClass;
+
+struct _GstStaticAutoplug {
+ GstAutoplug object;
+};
+
+struct _GstStaticAutoplugClass {
+ GstAutoplugClass parent_class;
+};
+
+
+GtkType gst_static_autoplug_get_type (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STATIC_AUTOPLUG_H__ */
+
diff --git a/gst/autoplug/gststaticautoplugrender.c b/gst/autoplug/gststaticautoplugrender.c
new file mode 100644
index 0000000000..5533d69178
--- /dev/null
+++ b/gst/autoplug/gststaticautoplugrender.c
@@ -0,0 +1,650 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen
+ * 2000 Wim Taymans
+ *
+ * gststaticautoplug.c: A static Autoplugger of pipelines
+ *
+ * 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 "gststaticautoplugrender.h"
+
+#include
+
+#define GST_AUTOPLUG_MAX_COST 999999
+
+typedef guint (*GstAutoplugCostFunction) (gpointer src, gpointer dest, gpointer data);
+typedef GList* (*GstAutoplugListFunction) (gpointer data);
+
+
+static void gst_static_autoplug_render_class_init (GstStaticAutoplugRenderClass *klass);
+static void gst_static_autoplug_render_init (GstStaticAutoplugRender *autoplug);
+
+static GList* gst_autoplug_func (gpointer src, gpointer sink,
+ GstAutoplugListFunction list_function,
+ GstAutoplugCostFunction cost_function,
+ gpointer data);
+
+
+
+static GstElement* gst_static_autoplug_to_render (GstAutoplug *autoplug,
+ GList *srccaps, GstElement *target, va_list args);
+
+static GstAutoplugClass *parent_class = NULL;
+
+GtkType gst_static_autoplug_render_get_type(void)
+{
+ static GtkType static_autoplug_type = 0;
+
+ if (!static_autoplug_type) {
+ static const GtkTypeInfo static_autoplug_info = {
+ "GstStaticAutoplugRender",
+ sizeof(GstElement),
+ sizeof(GstElementClass),
+ (GtkClassInitFunc)gst_static_autoplug_render_class_init,
+ (GtkObjectInitFunc)gst_static_autoplug_render_init,
+ (GtkArgSetFunc)NULL,
+ (GtkArgGetFunc)NULL,
+ (GtkClassInitFunc)NULL,
+ };
+ static_autoplug_type = gtk_type_unique (GST_TYPE_AUTOPLUG, &static_autoplug_info);
+ }
+ return static_autoplug_type;
+}
+
+static void
+gst_static_autoplug_render_class_init(GstStaticAutoplugRenderClass *klass)
+{
+ GstAutoplugClass *gstautoplug_class;
+
+ gstautoplug_class = (GstAutoplugClass*) klass;
+
+ parent_class = gtk_type_class(GST_TYPE_AUTOPLUG);
+
+ gstautoplug_class->autoplug_to_renderers = gst_static_autoplug_to_render;
+}
+
+static void gst_static_autoplug_render_init(GstStaticAutoplugRender *autoplug) {
+}
+
+GstPlugin*
+plugin_init (GModule *module)
+{
+ GstPlugin *plugin;
+ GstAutoplugFactory *factory;
+
+ plugin = gst_plugin_new("gststaticautoplugrender");
+ g_return_val_if_fail(plugin != NULL,NULL);
+
+ gst_plugin_set_longname (plugin, "A static autoplugger");
+
+ factory = gst_autoplugfactory_new ("staticrender",
+ "A static autoplugger, it constructs the complete element before running it",
+ gst_static_autoplug_render_get_type ());
+
+ if (factory != NULL) {
+ gst_plugin_add_autoplugger (plugin, factory);
+ }
+ return plugin;
+}
+
+static gboolean
+gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
+{
+ GList *srctemps, *desttemps;
+
+ srctemps = src->padtemplates;
+
+ while (srctemps) {
+ GstPadTemplate *srctemp = (GstPadTemplate *)srctemps->data;
+
+ desttemps = dest->padtemplates;
+
+ 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;
+}
+
+static gboolean
+gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
+{
+ 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;
+}
+
+typedef struct {
+ GstElement *result;
+ GList *endcap;
+ gint i;
+} dynamic_pad_struct;
+
+static void
+autoplug_dynamic_pad (GstElement *element, GstPad *pad, gpointer data)
+{
+ dynamic_pad_struct *info = (dynamic_pad_struct *)data;
+ GList *pads = gst_element_get_pad_list (element);
+
+ GST_DEBUG (0,"attempting to dynamically create a ghostpad for %s=%s\n", GST_ELEMENT_NAME (element),
+ GST_PAD_NAME (pad));
+
+ 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), info->endcap)) {
+ gst_element_add_ghost_pad (info->result, pad, g_strdup_printf("src_%02d", info->i));
+ GST_DEBUG (0,"gstpipeline: new dynamic pad %s\n", GST_PAD_NAME (pad));
+ break;
+ }
+ }
+}
+
+static void
+gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink)
+{
+ 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);
+ gtk_signal_connect(GTK_OBJECT(src),"new_ghost_pad",
+ GTK_SIGNAL_FUNC(gst_autoplug_pads_autoplug_func), sink);
+ }
+}
+
+static GList*
+gst_autoplug_elementfactory_get_list (gpointer data)
+{
+ return gst_elementfactory_get_list ();
+}
+
+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)
+{
+ caps_struct *caps = (caps_struct *)data;
+ gboolean res;
+
+ 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);
+ }
+
+ if (res)
+ return 1;
+ else
+ return GST_AUTOPLUG_MAX_COST;
+}
+
+static GstElement*
+gst_static_autoplug_to_render (GstAutoplug *autoplug, GList *srccaps, GstElement *target, va_list args)
+{
+ caps_struct caps;
+ GstElement *targetelement;
+ GstElement *result = NULL, *srcelement = NULL;
+ GList **factories;
+ GList *chains = NULL;
+ GList *endelements = NULL;
+ guint numsinks = 0, i;
+ gboolean have_common = FALSE;
+
+ targetelement = target;
+
+ /*
+ * 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;
+
+ while (targetelement) {
+ GList *elements;
+ GstPad *pad;
+
+ pad = GST_PAD (gst_element_get_pad_list (targetelement)->data);
+
+ caps.sink = gst_pad_get_caps_list (pad);
+
+ GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
+
+ 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);
+ endelements = g_list_append (endelements, targetelement);
+ numsinks++;
+ }
+ else {
+ }
+
+ targetelement = va_arg (args, GstElement *);
+ }
+
+ /*
+ * If no list could be found the pipeline cannot be autoplugged and
+ * we return a NULL element
+ */
+ if (numsinks == 0)
+ 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);
+ }
+ }
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
+
+ srcelement = element;
+
+ // advance the pointer in all lists
+ for (i=0; idata);
+ endelements = g_list_next (endelements);
+
+ use_thread = have_common;
+
+ while (factories[i] || sinkelement) {
+ // fase 4: add other elements...
+ GstElementFactory *factory;
+ GstElement *element;
+
+ if (factories[i]) {
+ factory = (GstElementFactory *)(factories[i]->data);
+
+ GST_DEBUG (0,"factory \"%s\"\n", factory->name);
+ element = gst_elementfactory_create(factory, factory->name);
+ }
+ else {
+ element = sinkelement;
+ sinkelement = NULL;
+ }
+
+ // 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);
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (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_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
+ GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (thebin));
+ gst_bin_add(GST_BIN(result), thebin);
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (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_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
+ }
+ gst_autoplug_pads_autoplug(thesrcelement, element);
+
+ // this element is now the new source element
+ thesrcelement = element;
+
+ factories[i] = g_list_next(factories[i]);
+ }
+ }
+
+ return result;
+}
+
+/*
+ * shortest path algorithm
+ *
+ */
+struct _gst_autoplug_node
+{
+ gpointer iNode;
+ gpointer iPrev;
+ gint iDist;
+};
+
+typedef struct _gst_autoplug_node gst_autoplug_node;
+
+static gint
+find_factory (gst_autoplug_node *rgnNodes, gpointer factory)
+{
+ gint i=0;
+
+ while (rgnNodes[i].iNode) {
+ if (rgnNodes[i].iNode == factory) return i;
+ i++;
+ }
+ return 0;
+}
+
+static GList*
+construct_path (gst_autoplug_node *rgnNodes, gpointer factory)
+{
+ GstElementFactory *current;
+ GList *factories = NULL;
+
+ 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);
+ }
+ 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);
+ }
+
+ 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);
+}
+
diff --git a/gst/autoplug/gststaticautoplugrender.h b/gst/autoplug/gststaticautoplugrender.h
new file mode 100644
index 0000000000..351d4cdcaf
--- /dev/null
+++ b/gst/autoplug/gststaticautoplugrender.h
@@ -0,0 +1,64 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen
+ * 2000 Wim Taymans
+ *
+ * gstautoplug.h: Header for autoplugging functionality
+ *
+ * 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.
+ */
+
+
+#ifndef __GST_STATIC_AUTOPLUG_RENDER_H__
+#define __GST_STATIC_AUTOPLUG_RENDER_H__
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GST_TYPE_STATIC_AUTOPLUG_RENDER \
+ (gst_static_autoplug_render_get_type())
+#define GST_STATIC_AUTOPLUG_RENDER(obj) \
+ (GTK_CHECK_CAST((obj),GST_TYPE_STATIC_AUTOPLUG_RENDER,GstStaticAutoplugRender))
+#define GST_STATIC_AUTOPLUG_RENDER_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_STATIC_AUTOPLUG_RENDER,GstStaticAutoplugRenderClass))
+#define GST_IS_STATIC_AUTOPLUG_RENDER(obj) \
+ (GTK_CHECK_TYPE((obj),GST_TYPE_STATIC_AUTOPLUG_RENDER))
+#define GST_IS_STATIC_AUTOPLUG_RENDER_CLASS(obj) \
+ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_STATIC_AUTOPLUG_RENDER))
+
+typedef struct _GstStaticAutoplugRender GstStaticAutoplugRender;
+typedef struct _GstStaticAutoplugRenderClass GstStaticAutoplugRenderClass;
+
+struct _GstStaticAutoplugRender {
+ GstAutoplug object;
+};
+
+struct _GstStaticAutoplugRenderClass {
+ GstAutoplugClass parent_class;
+};
+
+
+GtkType gst_static_autoplug_render_get_type (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STATIC_AUTOPLUG_H__ */
+
diff --git a/gst/elements/gstdisksrc.c b/gst/elements/gstdisksrc.c
index 9eebbd4bf6..9e81eb9b73 100644
--- a/gst/elements/gstdisksrc.c
+++ b/gst/elements/gstdisksrc.c
@@ -2,7 +2,7 @@
* Copyright (C) 1999,2000 Erik Walthinsen
* 2000 Wim Taymans
*
- * gstdisksrc.c:
+ * gstdisksrc.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -56,23 +56,23 @@ enum {
};
-static void gst_disksrc_class_init (GstDiskSrcClass *klass);
-static void gst_disksrc_init (GstDiskSrc *disksrc);
+static void gst_disksrc_class_init (GstDiskSrcClass *klass);
+static void gst_disksrc_init (GstDiskSrc *disksrc);
-static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id);
-static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id);
+static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id);
+static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id);
static GstBuffer * gst_disksrc_get (GstPad *pad);
static GstBuffer * gst_disksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len);
-static GstElementStateReturn gst_disksrc_change_state (GstElement *element);
+static GstElementStateReturn gst_disksrc_change_state (GstElement *element);
static GstElementClass *parent_class = NULL;
//static guint gst_disksrc_signals[LAST_SIGNAL] = { 0 };
GtkType
-gst_disksrc_get_type(void)
+gst_disksrc_get_type(void)
{
static GtkType disksrc_type = 0;
@@ -93,7 +93,7 @@ gst_disksrc_get_type(void)
}
static void
-gst_disksrc_class_init (GstDiskSrcClass *klass)
+gst_disksrc_class_init (GstDiskSrcClass *klass)
{
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
@@ -118,8 +118,8 @@ gst_disksrc_class_init (GstDiskSrcClass *klass)
gstelement_class->change_state = gst_disksrc_change_state;
}
-static void
-gst_disksrc_init (GstDiskSrc *disksrc)
+static void
+gst_disksrc_init (GstDiskSrc *disksrc)
{
// GST_FLAG_SET (disksrc, GST_SRC_);
@@ -139,14 +139,14 @@ gst_disksrc_init (GstDiskSrc *disksrc)
}
-static void
-gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
+static void
+gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
{
GstDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_DISKSRC (object));
-
+
src = GST_DISKSRC (object);
switch(id) {
@@ -176,14 +176,14 @@ gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
}
}
-static void
-gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
+static void
+gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
{
GstDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_DISKSRC (object));
-
+
src = GST_DISKSRC (object);
switch (id) {
@@ -212,7 +212,7 @@ gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
* Push a new buffer from the disksrc at the current offset.
*/
static GstBuffer *
-gst_disksrc_get (GstPad *pad)
+gst_disksrc_get (GstPad *pad)
{
GstDiskSrc *src;
GstBuffer *buf;
@@ -223,7 +223,7 @@ gst_disksrc_get (GstPad *pad)
/* deal with EOF state */
if (src->curoffset >= src->size) {
- gst_element_signal_eos (GST_ELEMENT (src));
+ gst_pad_set_eos (pad);
return NULL;
}
@@ -269,7 +269,7 @@ gst_disksrc_get (GstPad *pad)
* Push a new buffer from the disksrc of given size at given offset.
*/
static GstBuffer *
-gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len)
+gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len)
{
GstDiskSrc *src;
GstBuffer *buf;
@@ -281,10 +281,10 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l
g_return_val_if_fail (GST_IS_DISKSRC (src), NULL);
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN), NULL);
-
+
/* deal with EOF state */
if (offset >= src->size) {
- gst_element_signal_eos (GST_ELEMENT (src));
+ gst_pad_set_eos (pad);
return NULL;
}
@@ -312,8 +312,8 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l
/* open the file and mmap it, necessary to go to READY state */
-static
-gboolean gst_disksrc_open_file (GstDiskSrc *src)
+static
+gboolean gst_disksrc_open_file (GstDiskSrc *src)
{
g_return_val_if_fail (!GST_FLAG_IS_SET (src ,GST_DISKSRC_OPEN), FALSE);
@@ -343,8 +343,8 @@ gboolean gst_disksrc_open_file (GstDiskSrc *src)
}
/* unmap and close the file */
-static void
-gst_disksrc_close_file (GstDiskSrc *src)
+static void
+gst_disksrc_close_file (GstDiskSrc *src)
{
g_return_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN));
@@ -365,8 +365,8 @@ gst_disksrc_close_file (GstDiskSrc *src)
}
-static GstElementStateReturn
-gst_disksrc_change_state (GstElement *element)
+static GstElementStateReturn
+gst_disksrc_change_state (GstElement *element)
{
g_return_val_if_fail (GST_IS_DISKSRC (element), GST_STATE_FAILURE);
@@ -375,7 +375,7 @@ gst_disksrc_change_state (GstElement *element)
gst_disksrc_close_file (GST_DISKSRC (element));
} else {
if (!GST_FLAG_IS_SET (element, GST_DISKSRC_OPEN)) {
- if (!gst_disksrc_open_file (GST_DISKSRC (element)))
+ if (!gst_disksrc_open_file (GST_DISKSRC (element)))
return GST_STATE_FAILURE;
}
}
diff --git a/gst/elements/gstelements.c b/gst/elements/gstelements.c
index 193592ac85..62b5a9288f 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
@@ -61,13 +61,13 @@ static struct _elements_entry _elements[] = {
{ "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 4a088a5344..3f74b25bb1 100644
--- a/gst/gstautoplug.c
+++ b/gst/gstautoplug.c
@@ -24,337 +24,268 @@
#include "gst_private.h"
#include "gstautoplug.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 (GST_TYPE_OBJECT, &autoplug_info);
}
return autoplug_type;
}
static void
-gst_autoplug_class_init(GstAutoplugClass *klass) {
+gst_autoplug_class_init(GstAutoplugClass *klass)
+{
+ GtkObjectClass *gtkobject_class;
+ GstObjectClass *gstobject_class;
+
+ gtkobject_class = (GtkObjectClass*) klass;
+ gstobject_class = (GstObjectClass*) klass;
+
parent_class = gtk_type_class(GST_TYPE_OBJECT);
+
+ 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);
+
+ gtk_object_class_add_signals (gtkobject_class, gst_autoplug_signals, LAST_SIGNAL);
}
-static void gst_autoplug_init(GstAutoplug *autoplug) {
-}
-
-static gboolean
-gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
+static void gst_autoplug_init(GstAutoplug *autoplug)
{
- GList *srctemps, *desttemps;
-
- srctemps = src->padtemplates;
-
- while (srctemps) {
- GstPadTemplate *srctemp = (GstPadTemplate *)srctemps->data;
-
- desttemps = dest->padtemplates;
-
- 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;
}
-static GList*
-gst_autoplug_elementfactory_get_list (gpointer data)
+void
+_gst_autoplug_initialize (void)
{
- return gst_elementfactory_get_list ();
+ _gst_autoplugfactories = NULL;
}
-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)
+void
+gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object)
{
- caps_struct *caps = (caps_struct *)data;
- gboolean res;
+ gtk_signal_emit (GTK_OBJECT (autoplug), gst_autoplug_signals[NEW_OBJECT], object);
+}
- 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);
- }
- if (res)
- return 1;
- else
- return GST_AUTOPLUG_MAX_COST;
+GstElement*
+gst_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, ...)
+{
+ GstAutoplugClass *oclass;
+ GstElement *element = NULL;
+ va_list args;
+
+ va_start (args, sinkcaps);
+
+ oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass);
+ if (oclass->autoplug_to_caps)
+ element = (oclass->autoplug_to_caps) (autoplug, srccaps, sinkcaps, args);
+
+ va_end (args);
+
+ return element;
+}
+
+GstElement*
+gst_autoplug_to_renderers (GstAutoplug *autoplug, GList *srccaps, GstElement *target, ...)
+{
+ GstAutoplugClass *oclass;
+ GstElement *element = NULL;
+ va_list args;
+
+ va_start (args, target);
+
+ oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass);
+ if (oclass->autoplug_to_renderers)
+ element = (oclass->autoplug_to_renderers) (autoplug, srccaps, target, 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_caps:
- * @srccaps: the source caps
- * @sinkcaps: the sink caps
+ * gst_autoplugfactory_destroy:
+ * @autoplug: factory to destroy
*
- * Perform autoplugging between the two given caps.
- *
- * Returns: a list of elementfactories that can connect
- * the two caps
+ * Removes the autoplug from the global list.
*/
-GList*
-gst_autoplug_caps (GstCaps *srccaps, GstCaps *sinkcaps)
+void
+gst_autoplugfactory_destroy (GstAutoplugFactory *autoplug)
{
- caps_struct caps;
+ g_return_if_fail (autoplug != NULL);
- caps.src = g_list_prepend (NULL,srccaps);
- caps.sink = g_list_prepend (NULL,sinkcaps);
+ _gst_autoplugfactories = g_list_remove (_gst_autoplugfactories, autoplug);
- GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
-
- return gst_autoplug_func (caps.src, caps.sink,
- gst_autoplug_elementfactory_get_list,
- gst_autoplug_caps_find_cost,
- &caps);
+ // we don't free the struct bacause someone might have a handle to it..
}
/**
- * gst_autoplug_caps_list:
- * @srccaps: the source caps list
- * @sinkcaps: the sink caps list
+ * gst_autoplug_find:
+ * @name: name of autoplugger to find
*
- * Perform autoplugging between the two given caps lists.
+ * Search for an autoplugger of the given name.
*
- * Returns: a list of elementfactories that can connect
- * the two caps lists
+ * Returns: #GstAutoplug if found, NULL otherwise
*/
-GList*
-gst_autoplug_caps_list (GList *srccaps, GList *sinkcaps)
+GstAutoplugFactory*
+gst_autoplugfactory_find (const gchar *name)
{
- caps_struct caps;
+ GList *walk;
+ GstAutoplugFactory *factory;
- caps.src = srccaps;
- caps.sink = sinkcaps;
+ g_return_val_if_fail(name != NULL, NULL);
- GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps list structures");
+ GST_DEBUG (0,"gstautoplug: find \"%s\"\n", name);
- return gst_autoplug_func (caps.src, caps.sink,
- gst_autoplug_elementfactory_get_list,
- gst_autoplug_caps_find_cost,
- &caps);
+ walk = _gst_autoplugfactories;
+ while (walk) {
+ factory = (GstAutoplugFactory *)(walk->data);
+ if (!strcmp (name, factory->name))
+ return factory;
+ walk = g_list_next (walk);
+ }
+
+ return NULL;
}
/**
- * gst_autoplug_pads:
- * @srcpad: the source pad
- * @sinkpad: the sink pad
+ * gst_autoplugfactory_get_list:
*
- * Perform autoplugging between the two given pads.
+ * Get the global list of elementfactories.
*
- * Returns: a list of elementfactories that can connect
- * the two pads
+ * Returns: GList of type #GstElementFactory
*/
GList*
-gst_autoplug_pads (GstPad *srcpad, GstPad *sinkpad)
+gst_autoplugfactory_get_list (void)
{
- caps_struct caps;
-
- caps.src = gst_pad_get_caps_list(srcpad);
- caps.sink = gst_pad_get_caps_list(sinkpad);
-
- GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
-
- return gst_autoplug_func (caps.src, caps.sink,
- gst_autoplug_elementfactory_get_list,
- gst_autoplug_caps_find_cost,
- &caps);
+ return _gst_autoplugfactories;
}
-static gint
-find_factory (gst_autoplug_node *rgnNodes, gpointer factory)
-{
- gint i=0;
- while (rgnNodes[i].iNode) {
- if (rgnNodes[i].iNode == factory) return i;
- i++;
+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);
}
- return 0;
+ 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;
}
-static GList*
-construct_path (gst_autoplug_node *rgnNodes, gpointer factory)
+GstAutoplug*
+gst_autoplugfactory_make (const gchar *name)
{
- GstElementFactory *current;
- GList *factories = NULL;
+ GstAutoplugFactory *factory;
- current = rgnNodes[find_factory(rgnNodes, factory)].iPrev;
+ g_return_val_if_fail (name != NULL, NULL);
- GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factories found in autoplugging (reversed order)");
+ factory = gst_autoplugfactory_find (name);
- while (current != NULL)
- {
- gpointer next = NULL;
+ if (factory == NULL)
+ return 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);
+ return gst_autoplugfactory_create (factory);;
+}
+
+xmlNodePtr
+gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent)
+{
+ g_return_val_if_fail(factory != NULL, NULL);
+
+ xmlNewChild(parent,NULL,"name",factory->name);
+ xmlNewChild(parent,NULL,"longdesc", factory->longdesc);
+
+ return parent;
+}
+
+GstAutoplugFactory*
+gst_autoplugfactory_load_thyself (xmlNodePtr parent)
+{
+ GstAutoplugFactory *factory = g_new0(GstAutoplugFactory, 1);
+ xmlNodePtr children = parent->xmlChildrenNode;
+
+ 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);
- }
-
- 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);
+ if (!strcmp(children->name, "longdesc")) {
+ factory->longdesc = xmlNodeGetContent(children);
}
+ children = children->next;
}
- 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 c646c24d61..14d96d55d3 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,30 +44,66 @@ extern "C" {
typedef struct _GstAutoplug GstAutoplug;
typedef struct _GstAutoplugClass GstAutoplugClass;
-#define GST_AUTOPLUG_MAX_COST 999999
+typedef enum {
+ GST_AUTOPLUG_TO_CAPS = GST_OBJECT_FLAG_LAST,
+ GST_AUTOPLUG_TO_RENDERER,
-typedef guint (*GstAutoplugCostFunction) (gpointer src, gpointer dest, gpointer data);
-typedef GList* (*GstAutoplugListFunction) (gpointer data);
+ GST_AUTOPLUG_FLAG_LAST = GST_OBJECT_FLAG_LAST + 8,
+} GstAutoplugFlags;
+
struct _GstAutoplug {
- GtkObject object;
+ GstObject object;
};
struct _GstAutoplugClass {
- GtkObjectClass parent_class;
+ GstObjectClass parent_class;
+
+ /* signal callbacks */
+ void (*new_object) (GstAutoplug *autoplug, GstObject *object);
+
+ /* perform the autoplugging */
+ GstElement* (*autoplug_to_caps) (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, va_list args);
+ GstElement* (*autoplug_to_renderers) (GstAutoplug *autoplug, GList *srccaps, GstElement *target, va_list args);
};
-GtkType gst_autoplug_get_type (void);
+typedef struct _GstAutoplugFactory GstAutoplugFactory;
-GList* gst_autoplug_caps (GstCaps *srccaps, GstCaps *sinkcaps);
-GList* gst_autoplug_caps_list (GList *srccaps, GList *sinkcaps);
-GList* gst_autoplug_pads (GstPad *srcpad, GstPad *sinkpad);
+struct _GstAutoplugFactory {
+ 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);
+
+void gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object);
+
+GstElement* gst_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, ...);
+GstElement* gst_autoplug_to_renderers (GstAutoplug *autoplug, GList *srccaps,
+ GstElement *target, ...);
+
+
+/*
+ * 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
}
#endif /* __cplusplus */
-#endif /* __GST_AUTOPLUG_H__ */
+#endif /* __GST_AUTOPLUG_H__ */
diff --git a/gst/gstbin.c b/gst/gstbin.c
index d33078b023..dc0331e07e 100644
--- a/gst/gstbin.c
+++ b/gst/gstbin.c
@@ -234,6 +234,7 @@ gst_bin_change_state (GstElement *element)
GstBin *bin;
GList *children;
GstElement *child;
+ GstElementStateReturn ret;
GST_DEBUG_ENTER("(\"%s\")",GST_ELEMENT_NAME (element));
@@ -265,6 +266,8 @@ gst_bin_change_state (GstElement *element)
break;
}
+ case GST_STATE_READY_TO_NULL:
+ GST_FLAG_UNSET (bin, GST_BIN_FLAG_MANAGER);
default:
break;
}
@@ -289,9 +292,9 @@ gst_bin_change_state (GstElement *element)
children = g_list_next (children);
}
// g_print("<-- \"%s\"\n",gst_object_get_name(GST_OBJECT(bin)));
+ ret = gst_bin_change_state_norecurse (bin);
-
- return gst_bin_change_state_norecurse (bin);
+ return ret;
}
@@ -587,7 +590,7 @@ gst_bin_create_plan (GstBin *bin)
static void
gst_bin_received_eos (GstElement *element, GstBin *bin)
{
- GST_INFO_ELEMENT (GST_CAT_PLANNING, bin, "child %s fired eos, pending %d\n", GST_ELEMENT_NAME (element),
+ GST_INFO_ELEMENT (GST_CAT_PLANNING, bin, "child %s fired eos, pending %d", GST_ELEMENT_NAME (element),
bin->num_eos_providers);
GST_LOCK (bin);
@@ -756,7 +759,9 @@ gst_bin_create_plan_func (GstBin *bin)
}
// else it's not ours and we need to wait for EOS notifications
else {
- gtk_signal_connect (GTK_OBJECT (element), "eos", gst_bin_received_eos, bin);
+ GST_DEBUG (0,"setting up EOS signal from \"%s\" to \"%s\"\n", elementname,
+ gst_element_get_name (GST_ELEMENT(bin)->manager));
+ gtk_signal_connect (GTK_OBJECT (element), "eos", gst_bin_received_eos, GST_ELEMENT(bin)->manager);
bin->eos_providers = g_list_prepend (bin->eos_providers, element);
bin->num_eos_providers++;
}
@@ -869,7 +874,7 @@ gst_bin_iterate_func (GstBin *bin)
if (bin->num_eos_providers) {
GST_LOCK (bin);
GST_DEBUG (0,"waiting for eos providers\n");
- g_cond_wait (bin->eoscond, GST_OBJECT(bin)->lock);
+ g_cond_wait (bin->eoscond, GST_GET_LOCK(bin));
GST_DEBUG (0,"num eos providers %d\n", bin->num_eos_providers);
GST_UNLOCK (bin);
}
diff --git a/gst/gstcaps.c b/gst/gstcaps.c
index f8bfcb3e66..ebdaccc301 100644
--- a/gst/gstcaps.c
+++ b/gst/gstcaps.c
@@ -29,8 +29,8 @@
#include "gstpropsprivate.h"
-void
-_gst_caps_initialize (void)
+void
+_gst_caps_initialize (void)
{
}
@@ -67,12 +67,12 @@ gst_caps_new (const gchar *name, const gchar *mime)
GstCaps *caps;
g_return_val_if_fail (mime != NULL, NULL);
-
+
caps = g_new0 (GstCaps, 1);
caps->name = g_strdup (name);
caps->id = get_type_for_mime (mime);
caps->properties = NULL;
-
+
return caps;
}
@@ -90,7 +90,7 @@ GstCaps*
gst_caps_new_with_props (const gchar *name, const gchar *mime, GstProps *props)
{
GstCaps *caps;
-
+
caps = gst_caps_new (name, mime);
caps->properties = props;
@@ -101,7 +101,7 @@ gst_caps_new_with_props (const gchar *name, const gchar *mime, GstProps *props)
* gst_caps_register:
* @factory: the factory to register
*
- * Register the factory.
+ * Register the factory.
*
* Returns: the registered capability
*/
@@ -140,7 +140,7 @@ gst_caps_register_count (GstCapsFactory *factory, guint *counter)
tag = (*factory)[i++];
g_return_val_if_fail (tag != NULL, NULL);
-
+
typeid = get_type_for_mime ((gchar *)tag);
caps = g_new0 (GstCaps, 1);
@@ -163,7 +163,7 @@ gst_caps_register_count (GstCapsFactory *factory, guint *counter)
*
* Returns: the name of the caps
*/
-const gchar*
+const gchar*
gst_caps_get_name (GstCaps *caps)
{
g_return_val_if_fail (caps != NULL, NULL);
@@ -173,7 +173,7 @@ gst_caps_get_name (GstCaps *caps)
/**
* gst_caps_set_name:
- * @caps: the caps to set the name to
+ * @caps: the caps to set the name to
* @name: the name to set
*
* Set the name of a caps.
@@ -182,7 +182,7 @@ void
gst_caps_set_name (GstCaps *caps, const gchar *name)
{
g_return_if_fail (caps != NULL);
-
+
if (caps->name)
g_free (caps->name);
@@ -197,7 +197,7 @@ gst_caps_set_name (GstCaps *caps, const gchar *name)
*
* Returns: the mime type of the caps
*/
-const gchar*
+const gchar*
gst_caps_get_mime (GstCaps *caps)
{
GstType *type;
@@ -206,9 +206,9 @@ gst_caps_get_mime (GstCaps *caps)
type = gst_type_find_by_id (caps->id);
- if (type)
+ if (type)
return type->mime;
- else
+ else
return "unknown/unknown";
}
@@ -236,7 +236,7 @@ gst_caps_set_mime (GstCaps *caps, const gchar *mime)
*
* Returns: the type id of the caps
*/
-guint16
+guint16
gst_caps_get_type_id (GstCaps *caps)
{
g_return_val_if_fail (caps != NULL, 0);
@@ -247,16 +247,16 @@ gst_caps_get_type_id (GstCaps *caps)
/**
* gst_caps_set_type_id:
* @caps: the caps to set the type id to
- * @typeid: the type id to set
+ * @typeid: the type id to set
*
* Set the type id of the caps.
*/
void
-gst_caps_set_type_id (GstCaps *caps, guint16 typeid)
+gst_caps_set_type_id (GstCaps *caps, guint16 type_id)
{
g_return_if_fail (caps != NULL);
- caps->id = typeid;
+ caps->id = type_id;
}
/**
@@ -276,7 +276,7 @@ gst_caps_set_props (GstCaps *caps, GstProps *props)
g_return_val_if_fail (caps->properties == NULL, caps);
caps->properties = props;
-
+
return caps;
}
@@ -310,7 +310,7 @@ gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
{
g_return_val_if_fail (fromcaps != NULL, FALSE);
g_return_val_if_fail (tocaps != NULL, FALSE);
-
+
if (fromcaps->id != tocaps->id) {
GST_DEBUG (0,"gstcaps: mime types differ (%d to %d)\n",
fromcaps->id, tocaps->id);
@@ -371,7 +371,7 @@ gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps)
*
* Returns: a new XML node pointer
*/
-xmlNodePtr
+xmlNodePtr
gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent)
{
xmlNodePtr subtree;
@@ -397,7 +397,7 @@ gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent)
*
* Returns: a new capability
*/
-GstCaps*
+GstCaps*
gst_caps_load_thyself (xmlNodePtr parent)
{
GstCaps *caps = g_new0 (GstCaps, 1);
diff --git a/gst/gstcaps.h b/gst/gstcaps.h
index 99634d462b..dffa1cd3d5 100644
--- a/gst/gstcaps.h
+++ b/gst/gstcaps.h
@@ -52,7 +52,7 @@ struct _GstCaps {
};
/* initialize the subsystem */
-void _gst_caps_initialize (void);
+void _gst_caps_initialize (void);
GstCaps* gst_caps_new (const gchar *name, const gchar *mime);
GstCaps* gst_caps_new_with_props (const gchar *name, const gchar *mime, GstProps *props);
@@ -60,21 +60,21 @@ GstCaps* gst_caps_register (GstCapsFactory *factory);
GstCaps* gst_caps_register_count (GstCapsFactory *factory, guint *counter);
const gchar* gst_caps_get_name (GstCaps *caps);
-void gst_caps_set_name (GstCaps *caps, const gchar *name);
+void gst_caps_set_name (GstCaps *caps, const gchar *name);
const gchar* gst_caps_get_mime (GstCaps *caps);
-void gst_caps_set_mime (GstCaps *caps, const gchar *mime);
+void gst_caps_set_mime (GstCaps *caps, const gchar *mime);
-guint16 gst_caps_get_type_id (GstCaps *caps);
-void gst_caps_set_type_id (GstCaps *caps, guint16 /*typeid*/);
+guint16 gst_caps_get_type_id (GstCaps *caps);
+void gst_caps_set_type_id (GstCaps *caps, guint16 type_id);
GstCaps* gst_caps_set_props (GstCaps *caps, GstProps *props);
GstProps* gst_caps_get_props (GstCaps *caps);
-gboolean gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps);
-gboolean gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps);
+gboolean gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps);
+gboolean gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps);
-xmlNodePtr gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent);
-GstCaps* gst_caps_load_thyself (xmlNodePtr parent);
+xmlNodePtr gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent);
+GstCaps* gst_caps_load_thyself (xmlNodePtr parent);
#endif /* __GST_CAPS_H__ */
diff --git a/gst/gstelement.c b/gst/gstelement.c
index ef1c1b98a2..e8dc9ce5f6 100644
--- a/gst/gstelement.c
+++ b/gst/gstelement.c
@@ -519,7 +519,7 @@ gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
g_return_val_if_fail (templ != NULL, NULL);
templ_new = gst_element_get_padtemplate_by_compatible (element, templ);
- if (templ_new != NULL)
+ if (templ_new != NULL)
pad = gst_element_request_pad (element, templ_new);
return pad;
@@ -902,13 +902,15 @@ gst_element_save_thyself (GstObject *object,
type = gtk_type_parent (type);
}
- pads = element->pads;
+ pads = GST_ELEMENT_PADS (element);
+
while (pads) {
GstPad *pad = GST_PAD (pads->data);
- xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
// figure out if it's a direct pad or a ghostpad
- if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element)
+ if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
+ xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL);
gst_object_save_thyself (GST_OBJECT (pad), padtag);
+ }
pads = g_list_next (pads);
}
@@ -973,7 +975,6 @@ gst_element_load_thyself (xmlNodePtr self, GstObject *parent)
}
child = child->next;
}
-
gst_util_set_object_arg (GTK_OBJECT (element), name, value);
}
children = children->next;
diff --git a/gst/gstelement.h b/gst/gstelement.h
index a88e216942..655d18fafe 100644
--- a/gst/gstelement.h
+++ b/gst/gstelement.h
@@ -122,6 +122,7 @@ typedef enum {
#define GST_ELEMENT_NAME(obj) (GST_OBJECT_NAME(obj))
#define GST_ELEMENT_PARENT(obj) (GST_OBJECT_PARENT(obj))
+#define GST_ELEMENT_PADS(obj) ((obj)->pads)
typedef struct _GstElement GstElement;
typedef struct _GstElementClass GstElementClass;
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/gstobject.c b/gst/gstobject.c
index fe80744e27..c26744f8e0 100644
--- a/gst/gstobject.c
+++ b/gst/gstobject.c
@@ -370,13 +370,15 @@ gst_object_get_path_string (GstObject *object)
GSList *parentage = NULL;
GSList *parents;
void *parent;
- gchar *prevpath, *path = "";
+ gchar *prevpath, *path;
const char *component;
gchar *separator = "";
gboolean free_component;
parentage = g_slist_prepend (NULL, object);
+ path = g_strdup ("");
+
// first walk the object hierarchy to build a list of the parents
do {
if (GST_IS_OBJECT (object)) {
@@ -397,9 +399,9 @@ gst_object_get_path_string (GstObject *object)
parents = parentage;
while (parents) {
if (GST_IS_OBJECT (parents->data)) {
- GstObjectClass *oclass = GST_OBJECT_CLASS (GTK_OBJECT (parents->data));
+ GstObjectClass *oclass = GST_OBJECT_CLASS (GTK_OBJECT (parents->data)->klass);
- component = GST_OBJECT_NAME (parents->data);
+ component = gst_object_get_name (parents->data);
separator = oclass->path_string_separator;
free_component = FALSE;
} else {
diff --git a/gst/gstpad.c b/gst/gstpad.c
index 6946810fab..e613addae3 100644
--- a/gst/gstpad.c
+++ b/gst/gstpad.c
@@ -35,7 +35,6 @@ static void gst_pad_init (GstPad *pad);
static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent);
-
static GstObject *pad_parent_class = NULL;
GtkType
@@ -593,6 +592,25 @@ gst_pad_get_parent (GstPad *pad)
return GST_OBJECT_PARENT (pad);
}
+/**
+ * gst_pad_get_real_parent:
+ * @pad: the pad to get the parent from
+ *
+ * Get the real parent object of this pad. If the pad
+ * is a ghostpad, the actual owner of the real pad is
+ * returned, as opposed to the gst_pad_get_parent.
+ *
+ * Returns: the parent object
+ */
+GstObject*
+gst_pad_get_real_parent (GstPad *pad)
+{
+ g_return_val_if_fail (pad != NULL, NULL);
+ g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+
+ return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
+}
+
/**
* gst_pad_add_ghost_pad:
* @pad: the pad to set the ghost parent
@@ -948,7 +966,7 @@ gst_pad_pull (GstPad *pad)
{
GstRealPad *peer = GST_RPAD_PEER(pad);
- g_return_if_fail (peer != NULL);
+ g_return_val_if_fail (peer != NULL, NULL);
GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
@@ -983,7 +1001,7 @@ gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len
{
GstRealPad *peer = GST_RPAD_PEER(pad);
- g_return_if_fail (peer != NULL);
+ g_return_val_if_fail (peer != NULL, NULL);
GST_DEBUG_ENTER("(%s:%s,%d,%lld,%lld)",GST_DEBUG_PAD_NAME(pad),type,offset,len);
@@ -1003,6 +1021,65 @@ gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len
* templates
*
*/
+static void gst_padtemplate_class_init (GstPadTemplateClass *klass);
+static void gst_padtemplate_init (GstPadTemplate *templ);
+
+enum {
+ TEMPL_PAD_CREATED,
+ /* FILL ME */
+ TEMPL_LAST_SIGNAL
+};
+
+static GstObject *padtemplate_parent_class = NULL;
+static guint gst_padtemplate_signals[TEMPL_LAST_SIGNAL] = { 0 };
+
+GtkType
+gst_padtemplate_get_type (void)
+{
+ static GtkType padtemplate_type = 0;
+
+ if (!padtemplate_type) {
+ static const GtkTypeInfo padtemplate_info = {
+ "GstPadTemplate",
+ sizeof(GstPadTemplate),
+ sizeof(GstPadTemplateClass),
+ (GtkClassInitFunc)gst_padtemplate_class_init,
+ (GtkObjectInitFunc)gst_padtemplate_init,
+ (GtkArgSetFunc)NULL,
+ (GtkArgGetFunc)NULL,
+ (GtkClassInitFunc)NULL,
+ };
+ padtemplate_type = gtk_type_unique(GST_TYPE_OBJECT,&padtemplate_info);
+ }
+ return padtemplate_type;
+}
+
+static void
+gst_padtemplate_class_init (GstPadTemplateClass *klass)
+{
+ GtkObjectClass *gtkobject_class;
+ GstObjectClass *gstobject_class;
+
+ gtkobject_class = (GtkObjectClass*)klass;
+ gstobject_class = (GstObjectClass*)klass;
+
+ padtemplate_parent_class = gtk_type_class(GST_TYPE_OBJECT);
+
+ gst_padtemplate_signals[TEMPL_PAD_CREATED] =
+ gtk_signal_new ("pad_created", GTK_RUN_LAST, gtkobject_class->type,
+ GTK_SIGNAL_OFFSET (GstPadTemplateClass, pad_created),
+ gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
+ GST_TYPE_PAD);
+
+ gtk_object_class_add_signals (gtkobject_class, gst_padtemplate_signals, TEMPL_LAST_SIGNAL);
+
+ gstobject_class->path_string_separator = "*";
+}
+
+static void
+gst_padtemplate_init (GstPadTemplate *templ)
+{
+}
/**
* gst_padtemplate_new:
@@ -1022,7 +1099,7 @@ gst_padtemplate_new (GstPadFactory *factory)
g_return_val_if_fail (factory != NULL, NULL);
- new = g_new0 (GstPadTemplate, 1);
+ new = gtk_type_new (gst_padtemplate_get_type ());
tag = (*factory)[i++];
g_return_val_if_fail (tag != NULL, new);
@@ -1063,7 +1140,9 @@ gst_padtemplate_create (gchar *name_template,
{
GstPadTemplate *new;
- new = g_new0 (GstPadTemplate, 1);
+ g_return_val_if_fail (name_template != NULL, NULL);
+
+ new = gtk_type_new (gst_padtemplate_get_type ());
new->name_template = name_template;
new->direction = direction;
@@ -1134,21 +1213,24 @@ GstPadTemplate*
gst_padtemplate_load_thyself (xmlNodePtr parent)
{
xmlNodePtr field = parent->xmlChildrenNode;
- GstPadTemplate *factory = g_new0 (GstPadTemplate, 1);
+ GstPadTemplate *factory;
+ gchar *name_template = NULL;
+ GstPadDirection direction = GST_PAD_UNKNOWN;
+ GstPadPresence presence = GST_PAD_ALWAYS;
+ GList *caps = NULL;
while (field) {
if (!strcmp(field->name, "nametemplate")) {
- factory->name_template = xmlNodeGetContent(field);
+ name_template = xmlNodeGetContent(field);
}
if (!strcmp(field->name, "direction")) {
gchar *value = xmlNodeGetContent(field);
- factory->direction = GST_PAD_UNKNOWN;
if (!strcmp(value, "sink")) {
- factory->direction = GST_PAD_SINK;
+ direction = GST_PAD_SINK;
}
else if (!strcmp(value, "src")) {
- factory->direction = GST_PAD_SRC;
+ direction = GST_PAD_SRC;
}
g_free (value);
}
@@ -1156,21 +1238,24 @@ gst_padtemplate_load_thyself (xmlNodePtr parent)
gchar *value = xmlNodeGetContent(field);
if (!strcmp(value, "always")) {
- factory->presence = GST_PAD_ALWAYS;
+ presence = GST_PAD_ALWAYS;
}
else if (!strcmp(value, "sometimes")) {
- factory->presence = GST_PAD_SOMETIMES;
+ presence = GST_PAD_SOMETIMES;
}
else if (!strcmp(value, "request")) {
- factory->presence = GST_PAD_REQUEST;
+ presence = GST_PAD_REQUEST;
}
g_free (value);
}
else if (!strcmp(field->name, "caps")) {
- factory->caps = g_list_append(factory->caps, gst_caps_load_thyself (field));
+ caps = g_list_append (caps, gst_caps_load_thyself (field));
}
field = field->next;
}
+
+ factory = gst_padtemplate_create (name_template, direction, presence, caps);
+
return factory;
}
@@ -1271,13 +1356,6 @@ gst_pad_get_element_private (GstPad *pad)
}
-
-
-
-
-
-
-
/***** ghost pads *****/
static void gst_ghost_pad_class_init (GstGhostPadClass *klass);
diff --git a/gst/gstpad.h b/gst/gstpad.h
index 8e1ed43cff..ef21617fdd 100644
--- a/gst/gstpad.h
+++ b/gst/gstpad.h
@@ -278,6 +278,7 @@ const gchar* gst_pad_get_name (GstPad *pad);
void gst_pad_set_parent (GstPad *pad, GstObject *parent);
GstObject* gst_pad_get_parent (GstPad *pad);
+GstObject* gst_pad_get_real_parent (GstPad *pad);
void gst_pad_add_ghost_pad (GstPad *pad, GstPad *ghostpad);
void gst_pad_remove_ghost_pad (GstPad *pad, GstPad *ghostpad);
diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c
index 065de192b2..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 = {
@@ -51,15 +47,13 @@ enum {
};
-static void gst_pipeline_class_init (GstPipelineClass *klass);
-static void gst_pipeline_init (GstPipeline *pipeline);
+static void gst_pipeline_class_init (GstPipelineClass *klass);
+static void gst_pipeline_init (GstPipeline *pipeline);
-static GstElementStateReturn gst_pipeline_change_state (GstElement *element);
+static GstElementStateReturn gst_pipeline_change_state (GstElement *element);
-static void gst_pipeline_prepare (GstPipeline *pipeline);
+static void gst_pipeline_prepare (GstPipeline *pipeline);
-static void gst_pipeline_have_type (GstElement *sink, GstElement *sink2, gpointer data);
-static void gst_pipeline_pads_autoplug (GstElement *src, GstElement *sink);
static GstBinClass *parent_class = NULL;
//static guint gst_pipeline_signals[LAST_SIGNAL] = { 0 };
@@ -85,7 +79,7 @@ gst_pipeline_get_type (void) {
}
static void
-gst_pipeline_class_init (GstPipelineClass *klass)
+gst_pipeline_class_init (GstPipelineClass *klass)
{
GstElementClass *gstelement_class;
@@ -96,14 +90,11 @@ gst_pipeline_class_init (GstPipelineClass *klass)
gstelement_class->change_state = gst_pipeline_change_state;
}
-static void
-gst_pipeline_init (GstPipeline *pipeline)
+static void
+gst_pipeline_init (GstPipeline *pipeline)
{
// we're a manager by default
GST_FLAG_SET (pipeline, GST_BIN_FLAG_MANAGER);
-
- pipeline->src = NULL;
- pipeline->sinks = NULL;
}
@@ -116,393 +107,25 @@ gst_pipeline_init (GstPipeline *pipeline)
* Returns: newly created GstPipeline
*/
GstElement*
-gst_pipeline_new (guchar *name)
+gst_pipeline_new (guchar *name)
{
return gst_elementfactory_make ("pipeline", name);
}
-static void
-gst_pipeline_prepare (GstPipeline *pipeline)
+static void
+gst_pipeline_prepare (GstPipeline *pipeline)
{
- GST_DEBUG (0,"GstPipeline: preparing pipeline \"%s\" for playing\n",
+ GST_DEBUG (0,"GstPipeline: preparing pipeline \"%s\" for playing\n",
GST_ELEMENT_NAME(GST_ELEMENT(pipeline)));
}
-static void
-gst_pipeline_have_type (GstElement *sink, GstElement *sink2, gpointer data)
-{
- GST_DEBUG (0,"GstPipeline: pipeline have type %p\n", (gboolean *)data);
-
- *(gboolean *)data = TRUE;
-}
-
-static GstCaps*
-gst_pipeline_typefind (GstPipeline *pipeline, GstElement *element)
-{
- gboolean found = FALSE;
- GstElement *typefind;
- GstCaps *caps = NULL;
-
- GST_DEBUG (0,"GstPipeline: typefind for element \"%s\" %p\n",
- GST_ELEMENT_NAME(element), &found);
-
- typefind = gst_elementfactory_make ("typefind", "typefind");
- g_return_val_if_fail (typefind != NULL, FALSE);
-
- gtk_signal_connect (GTK_OBJECT (typefind), "have_type",
- GTK_SIGNAL_FUNC (gst_pipeline_have_type), &found);
-
- gst_pad_connect (gst_element_get_pad (element, "src"),
- gst_element_get_pad (typefind, "sink"));
-
- gst_bin_add (GST_BIN (pipeline), typefind);
-
- //gst_bin_create_plan (GST_BIN (pipeline));
- gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
-
- // keep pushing buffers... the have_type signal handler will set the found flag
- while (!found) {
- gst_bin_iterate (GST_BIN (pipeline));
- }
-
- gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
-
- if (found) {
- caps = gst_util_get_pointer_arg (GTK_OBJECT (typefind), "caps");
-
- gst_pad_set_caps_list (gst_element_get_pad (element, "src"), g_list_prepend (NULL, caps));
- }
-
- gst_pad_disconnect (gst_element_get_pad (element, "src"),
- gst_element_get_pad (typefind, "sink"));
- gst_bin_remove (GST_BIN (pipeline), typefind);
- gst_object_unref (GST_OBJECT (typefind));
-
- return caps;
-}
-
-static gboolean
-gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
-{
- 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_pipeline_pads_autoplug (GstElement *src, GstElement *sink)
-{
- 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_pipeline_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_pipeline_pads_autoplug_func), sink);
- }
-}
-
-/**
- * gst_pipeline_add_src:
- * @pipeline: the pipeline to add the src to
- * @src: the src to add to the pipeline
- *
- * Adds a src element to the pipeline. This element
- * will be used as a src for autoplugging. If you add more
- * than one src element, the previously added element will
- * be removed.
- */
-void
-gst_pipeline_add_src (GstPipeline *pipeline, GstElement *src)
-{
- g_return_if_fail (pipeline != NULL);
- g_return_if_fail (GST_IS_PIPELINE (pipeline));
- g_return_if_fail (src != NULL);
- g_return_if_fail (GST_IS_ELEMENT (src));
-
- if (pipeline->src) {
- printf("gstpipeline: *WARNING* removing previously added element \"%s\"\n",
- GST_ELEMENT_NAME(pipeline->src));
- gst_bin_remove(GST_BIN(pipeline), pipeline->src);
- }
- pipeline->src = src;
- gst_bin_add(GST_BIN(pipeline), src);
-}
-
-/**
- * gst_pipeline_add_sink:
- * @pipeline: the pipeline to add the sink to
- * @sink: the sink to add to the pipeline
- *
- * Adds a sink element to the pipeline. This element
- * will be used as a sink for autoplugging.
- */
-void
-gst_pipeline_add_sink (GstPipeline *pipeline, GstElement *sink)
-{
- g_return_if_fail (pipeline != NULL);
- g_return_if_fail (GST_IS_PIPELINE (pipeline));
- g_return_if_fail (sink != NULL);
- g_return_if_fail (GST_IS_ELEMENT (sink));
-
- pipeline->sinks = g_list_prepend (pipeline->sinks, sink);
- //gst_bin_add(GST_BIN(pipeline), sink);
-}
-
-/**
- * gst_pipeline_autoplug:
- * @pipeline: the pipeline to autoplug
- *
- * Constructs a complete pipeline by automatically
- * detecting the plugins needed.
- *
- * Returns: a gboolean indicating success or failure.
- */
-gboolean
-gst_pipeline_autoplug (GstPipeline *pipeline)
-{
- GList *elements;
- GstElement *element, *srcelement = NULL, *sinkelement= NULL;
- GList **factories;
- GList **base_factories;
- GstElementFactory *factory;
- GstCaps *src_caps = 0;
- guint i, numsinks;
- gboolean use_thread = FALSE, have_common = FALSE;
- GList *sinkstart;
-
- g_return_val_if_fail(pipeline != NULL, FALSE);
- g_return_val_if_fail(GST_IS_PIPELINE(pipeline), FALSE);
-
- GST_DEBUG (0,"GstPipeline: autopluging pipeline \"%s\"\n",
- GST_ELEMENT_NAME(GST_ELEMENT(pipeline)));
-
-
- // fase 1, run typedetect on the source if needed...
- if (!pipeline->src) {
- GST_DEBUG (0,"GstPipeline: no source detected, can't autoplug pipeline \"%s\"\n",
- GST_ELEMENT_NAME(GST_ELEMENT(pipeline)));
- return FALSE;
- }
-
- GST_DEBUG (0,"GstPipeline: source \"%s\" has no MIME type, running typefind...\n",
- GST_ELEMENT_NAME(pipeline->src));
-
- src_caps = gst_pipeline_typefind(pipeline, pipeline->src);
-
- if (src_caps) {
- GST_DEBUG (0,"GstPipeline: source \"%s\" type found %d\n", GST_ELEMENT_NAME(pipeline->src),
- src_caps->id);
- }
- else {
- GST_DEBUG (0,"GstPipeline: source \"%s\" has no type\n", GST_ELEMENT_NAME(pipeline->src));
- return FALSE;
- }
-
- srcelement = pipeline->src;
-
- elements = pipeline->sinks;
-
- sinkstart = g_list_copy (elements);
-
- numsinks = g_list_length(elements);
- factories = g_new0(GList *, numsinks);
- base_factories = g_new0(GList *, numsinks);
-
- i = 0;
- // fase 2, loop over all the sinks..
- while (elements) {
- GstPad *pad;
-
- element = GST_ELEMENT(elements->data);
-
- pad = (GstPad *)gst_element_get_pad_list (element)->data;
-
- base_factories[i] = factories[i] = gst_autoplug_caps_list (g_list_append(NULL,src_caps),
-gst_pad_get_caps_list(pad));
- // if we have a succesfull connection, proceed
- if (factories[i] != NULL) {
- i++;
- }
- else {
- sinkstart = g_list_remove (sinkstart, element);
- }
-
- elements = g_list_next(elements);
- }
-
- while (factories[0]) {
- // fase 3: add common elements
- factory = (GstElementFactory *)(factories[0]->data);
-
- // check to other paths for mathing elements (factories)
- for (i=1; idata))) {
- goto differ;
- }
- factories[i] = g_list_next(factories[i]);
- }
- factory = (GstElementFactory *)(factories[0]->data);
-
- GST_DEBUG (0,"common factory \"%s\"\n", factory->name);
-
- element = gst_elementfactory_create(factory, factory->name);
- gst_bin_add(GST_BIN(pipeline), element);
-
- gst_pipeline_pads_autoplug(srcelement, element);
-
- srcelement = element;
-
- factories[0] = g_list_next(factories[0]);
-
- have_common = TRUE;
- }
-
-differ:
- // loop over all the sink elements
- elements = sinkstart;
-
- i = 0;
- while (elements) {
- GstElement *thesrcelement = srcelement;
- GstElement *thebin = GST_ELEMENT(pipeline);
-
- if (g_list_length(base_factories[i]) == 0) goto next;
-
- sinkelement = (GstElement *)elements->data;
-
- use_thread = have_common;
-
- while (factories[i] || sinkelement) {
- // fase 4: add other elements...
-
- if (factories[i]) {
- factory = (GstElementFactory *)(factories[i]->data);
- GST_DEBUG (0,"factory \"%s\"\n", factory->name);
- element = gst_elementfactory_create(factory, factory->name);
- factories[i] = g_list_next(factories[i]);
- }
- // we have arived to the final sink element
- else {
- element = sinkelement;
- sinkelement = NULL;
- }
-
- // 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_pipeline_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(pipeline), 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_pipeline_pads_autoplug(thesrcelement, element);
-
- // this element is now the new source element
- thesrcelement = element;
- }
-next:
- elements = g_list_next(elements);
- i++;
- }
- return TRUE;
-
- GST_DEBUG (0,"GstPipeline: unable to autoplug pipeline \"%s\"\n",
- GST_ELEMENT_NAME(GST_ELEMENT(pipeline)));
- return FALSE;
-}
-
-static GstElementStateReturn
-gst_pipeline_change_state (GstElement *element)
+static GstElementStateReturn
+gst_pipeline_change_state (GstElement *element)
{
GstPipeline *pipeline;
g_return_val_if_fail (GST_IS_PIPELINE (element), FALSE);
-
+
pipeline = GST_PIPELINE (element);
switch (GST_STATE_TRANSITION (pipeline)) {
@@ -513,22 +136,21 @@ gst_pipeline_change_state (GstElement *element)
default:
break;
}
-
+
if (GST_ELEMENT_CLASS (parent_class)->change_state)
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
-
+
return GST_STATE_SUCCESS;
}
-
/**
* gst_pipeline_iterate:
* @pipeline: #GstPipeline to iterate
*
* Cause the pipeline's contents to be run through one full 'iteration'.
*/
-void
-gst_pipeline_iterate (GstPipeline *pipeline)
+void
+gst_pipeline_iterate (GstPipeline *pipeline)
{
g_return_if_fail (pipeline != NULL);
g_return_if_fail (GST_IS_PIPELINE(pipeline));
diff --git a/gst/gstpipeline.h b/gst/gstpipeline.h
index 5ab0afe101..3c13978e63 100644
--- a/gst/gstpipeline.h
+++ b/gst/gstpipeline.h
@@ -50,30 +50,22 @@ typedef struct _GstPipelineClass GstPipelineClass;
struct _GstPipeline {
GstBin bin;
-
- GstElement *src; /* we only allow one src element */
- GList *sinks; /* and multiple sinks */
};
struct _GstPipelineClass {
GstBinClass parent_class;
};
-GtkType gst_pipeline_get_type (void);
+GtkType gst_pipeline_get_type (void);
GstElement* gst_pipeline_new (guchar *name);
-#define gst_pipeline_destroy(pipeline) gst_object_destroy(GST_OBJECT(pipeline))
+#define gst_pipeline_destroy(pipeline) gst_object_destroy(GST_OBJECT(pipeline))
-void gst_pipeline_add_src (GstPipeline *pipeline, GstElement *src);
-void gst_pipeline_add_sink (GstPipeline *pipeline, GstElement *sink);
-
-gboolean gst_pipeline_autoplug (GstPipeline *pipeline);
-
-void gst_pipeline_iterate (GstPipeline *pipeline);
+void gst_pipeline_iterate (GstPipeline *pipeline);
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#endif /* __GST_PIPELINE_H__ */
+#endif /* __GST_PIPELINE_H__ */
diff --git a/gst/gstplugin.c b/gst/gstplugin.c
index bea40e7cb0..557232a27c 100644
--- a/gst/gstplugin.c
+++ b/gst/gstplugin.c
@@ -82,6 +82,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");
#endif /* PLUGINS_USE_SRCDIR */
doc = xmlParseFile (GST_CONFIG_DIR"/reg.xml");
@@ -407,6 +409,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;
@@ -541,15 +545,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;
@@ -621,6 +617,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
@@ -708,6 +775,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:
*
@@ -716,7 +801,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;
}
@@ -733,34 +818,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;
}
@@ -776,43 +872,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++;
@@ -822,13 +925,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);
}
@@ -863,3 +967,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 c171ada41b..299d10edc1 100644
--- a/gst/gstplugin.h
+++ b/gst/gstplugin.h
@@ -36,10 +36,11 @@
#include
#include
+#include
-typedef struct _GstPlugin GstPlugin;
-typedef struct _GstPluginElement GstPluginElement;
+typedef struct _GstPlugin GstPlugin;
+typedef struct _GstPluginElement GstPluginElement;
struct _GstPlugin {
gchar *name; /* name of the plugin */
@@ -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 */
};
@@ -57,40 +60,41 @@ struct _GstPlugin {
typedef GstPlugin* (*GstPluginInitFunc) (GModule *module);
-void _gst_plugin_initialize (void);
+void _gst_plugin_initialize (void);
GstPlugin* gst_plugin_new (const gchar *name);
void gst_plugin_add_path (const gchar *path);
const gchar* gst_plugin_get_name (GstPlugin *plugin);
-void gst_plugin_set_name (GstPlugin *plugin, const gchar *name);
+void gst_plugin_set_name (GstPlugin *plugin, const gchar *name);
const gchar* gst_plugin_get_longname (GstPlugin *plugin);
-void gst_plugin_set_longname (GstPlugin *plugin, const gchar *longname);
+void gst_plugin_set_longname (GstPlugin *plugin, const gchar *longname);
const gchar* gst_plugin_get_filename (GstPlugin *plugin);
-gboolean gst_plugin_is_loaded (GstPlugin *plugin);
+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);
gboolean gst_plugin_load_absolute (const gchar *name);
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_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);
+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);
+xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent);
+void gst_plugin_load_thyself (xmlNodePtr parent);
#endif /* __GST_PLUGIN_H__ */
diff --git a/gst/gstprops.c b/gst/gstprops.c
index a3e688b26f..d3ca3cf8b0 100644
--- a/gst/gstprops.c
+++ b/gst/gstprops.c
@@ -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/gstthread.c b/gst/gstthread.c
index 7a5e767f87..ca269b0032 100644
--- a/gst/gstthread.c
+++ b/gst/gstthread.c
@@ -254,7 +254,7 @@ gst_thread_change_state (GstElement *element)
gst_thread_main_loop, thread);
// wait for it to 'spin up'
-// gst_thread_wait_thread (thread);
+ //gst_thread_wait_thread (thread);
} else {
GST_INFO (GST_CAT_THREAD, "gstthread: NOT starting thread \"%s\"",
GST_ELEMENT_NAME (GST_ELEMENT (element)));
diff --git a/gst/gsttype.c b/gst/gsttype.c
index 84090e74d3..437da194df 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,16 +70,17 @@ 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;
+ GST_DEBUG (0,"gsttype: new mime type '%s', id %d\n", type->mime, type->id);
} else {
type = gst_type_find_by_id (id);
@@ -96,8 +97,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 +143,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 +157,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 +174,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 +197,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 +211,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 +221,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 +264,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/gst/gsttype.h b/gst/gsttype.h
index 2e2ef0a129..68ab8ce686 100644
--- a/gst/gsttype.h
+++ b/gst/gsttype.h
@@ -52,14 +52,14 @@ struct _GstTypeFactory {
/* initialize the subsystem */
-void _gst_type_initialize (void);
+void _gst_type_initialize (void);
/* create a new type, or find/merge an existing one */
-guint16 gst_type_register (GstTypeFactory *factory);
+guint16 gst_type_register (GstTypeFactory *factory);
/* look up a type by mime or extension */
-guint16 gst_type_find_by_mime (const gchar *mime);
-guint16 gst_type_find_by_ext (const gchar *ext);
+guint16 gst_type_find_by_mime (const gchar *mime);
+guint16 gst_type_find_by_ext (const gchar *ext);
/* get GstType by id */
GstType* gst_type_find_by_id (guint16 id);
@@ -67,7 +67,7 @@ GstType* gst_type_find_by_id (guint16 id);
/* get the list of registered types (returns list of GstType!) */
GList* gst_type_get_list (void);
-xmlNodePtr gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent);
+xmlNodePtr gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent);
GstTypeFactory* gst_typefactory_load_thyself (xmlNodePtr parent);
#endif /* __GST_TYPE_H__ */
diff --git a/gst/gsttypefind.c b/gst/gsttypefind.c
index 8f8489d681..279a2fe766 100644
--- a/gst/gsttypefind.c
+++ b/gst/gsttypefind.c
@@ -52,19 +52,20 @@ enum {
};
-static void gst_typefind_class_init (GstTypeFindClass *klass);
-static void gst_typefind_init (GstTypeFind *typefind);
+static void gst_typefind_class_init (GstTypeFindClass *klass);
+static void gst_typefind_init (GstTypeFind *typefind);
-static void gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id);
-static void gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id);
+static void gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id);
+static void gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id);
-static void gst_typefind_chain (GstPad *pad, GstBuffer *buf);
+static void gst_typefind_chain (GstPad *pad, GstBuffer *buf);
static GstElementClass *parent_class = NULL;
static guint gst_typefind_signals[LAST_SIGNAL] = { 0 };
GtkType
-gst_typefind_get_type(void) {
+gst_typefind_get_type (void)
+{
static GtkType typefind_type = 0;
if (!typefind_type) {
@@ -78,13 +79,13 @@ gst_typefind_get_type(void) {
(GtkArgGetFunc)gst_typefind_get_arg,
(GtkClassInitFunc)NULL,
};
- typefind_type = gtk_type_unique(GST_TYPE_ELEMENT,&typefind_info);
+ typefind_type = gtk_type_unique (GST_TYPE_ELEMENT, &typefind_info);
}
return typefind_type;
}
static void
-gst_typefind_class_init (GstTypeFindClass *klass)
+gst_typefind_class_init (GstTypeFindClass *klass)
{
GtkObjectClass *gtkobject_class;
@@ -107,22 +108,22 @@ gst_typefind_class_init (GstTypeFindClass *klass)
gtkobject_class->get_arg = gst_typefind_get_arg;
}
-static void
-gst_typefind_init (GstTypeFind *typefind)
+static void
+gst_typefind_init (GstTypeFind *typefind)
{
typefind->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
gst_element_add_pad (GST_ELEMENT (typefind), typefind->sinkpad);
gst_pad_set_chain_function (typefind->sinkpad, gst_typefind_chain);
}
-static void
-gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id)
+static void
+gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id)
{
GstTypeFind *typefind;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_TYPEFIND (object));
-
+
typefind = GST_TYPEFIND (object);
switch(id) {
@@ -131,14 +132,14 @@ gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id)
}
}
-static void
-gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id)
+static void
+gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id)
{
GstTypeFind *typefind;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_TYPEFIND (object));
-
+
typefind = GST_TYPEFIND (object);
switch(id) {
@@ -150,8 +151,8 @@ gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id)
}
}
-static void
-gst_typefind_chain (GstPad *pad, GstBuffer *buf)
+static void
+gst_typefind_chain (GstPad *pad, GstBuffer *buf)
{
GstTypeFind *typefind;
GList *type_list;
diff --git a/gstplay/gstplay.c b/gstplay/gstplay.c
index 86aa6261b5..f0b7459dce 100644
--- a/gstplay/gstplay.c
+++ b/gstplay/gstplay.c
@@ -41,8 +41,8 @@ enum {
static GtkObject *parent_class = NULL;
static guint gst_play_signals[LAST_SIGNAL] = { 0 };
-GtkType
-gst_play_get_type (void)
+GtkType
+gst_play_get_type (void)
{
static GtkType play_type = 0;
@@ -62,8 +62,8 @@ gst_play_get_type (void)
return play_type;
}
-static void
-gst_play_class_init (GstPlayClass *klass)
+static void
+gst_play_class_init (GstPlayClass *klass)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
@@ -108,14 +108,13 @@ gst_play_class_init (GstPlayClass *klass)
object_class->set_arg = gst_play_set_arg;
object_class->get_arg = gst_play_get_arg;
- widget_class->realize = gst_play_realize;
+ widget_class->realize = gst_play_realize;
}
-static void
-gst_play_init (GstPlay *play)
+static void
+gst_play_init (GstPlay *play)
{
-
GstPlayPrivate *priv = g_new0 (GstPlayPrivate, 1);
play->priv = priv;
@@ -123,25 +122,20 @@ gst_play_init (GstPlay *play)
/* create a new bin to hold the elements */
priv->thread = gst_thread_new ("main_thread");
g_assert (priv->thread != NULL);
- priv->pipeline = gst_pipeline_new ("main_pipeline");
- g_assert (priv->pipeline != NULL);
+ priv->bin = gst_bin_new ("main_bin");
+ g_assert (priv->bin != NULL);
- /* and an audio sink */
- priv->audio_play = gst_elementfactory_make ("audiosink","play_audio");
- g_return_if_fail (priv->audio_play != NULL);
- gtk_signal_connect (GTK_OBJECT (priv->audio_play), "handoff",
+ priv->audio_element = gst_elementfactory_make ("audiosink", "play_audio");
+ g_return_if_fail (priv->audio_element != NULL);
+ gtk_signal_connect (GTK_OBJECT (priv->audio_element), "handoff",
GTK_SIGNAL_FUNC (gst_play_audio_handoff), play);
- /* and a video sink */
- priv->video_show = gst_elementfactory_make ("videosink","show");
- g_return_if_fail (priv->video_show != NULL);
- gtk_object_set (GTK_OBJECT (priv->video_show),"xv_enabled",FALSE,NULL);
- gtk_signal_connect (GTK_OBJECT (priv->video_show), "frame_displayed",
+ priv->video_element = gst_elementfactory_make ("videosink", "show");
+ g_return_if_fail (priv->video_element != NULL);
+ gtk_object_set (GTK_OBJECT (priv->video_element), "xv_enabled", FALSE, NULL);
+ gtk_signal_connect (GTK_OBJECT (priv->video_element), "frame_displayed",
GTK_SIGNAL_FUNC (gst_play_frame_displayed), play);
- gst_pipeline_add_sink (GST_PIPELINE (priv->pipeline), priv->audio_play);
- gst_pipeline_add_sink (GST_PIPELINE (priv->pipeline), priv->video_show);
-
play->state = GST_PLAY_STOPPED;
play->flags = 0;
@@ -155,155 +149,258 @@ gst_play_init (GstPlay *play)
}
GstPlay *
-gst_play_new ()
+gst_play_new ()
{
return GST_PLAY (gtk_type_new (GST_TYPE_PLAY));
}
-static void
-gst_play_eos (GstElement *element,
- GstPlay *play)
+static void
+gst_play_eos (GstElement *element,
+ GstPlay *play)
{
g_print("gstplay: eos reached\n");
gst_play_stop(play);
}
-static void
-gst_play_frame_displayed (GstElement *element,
- GstPlay *play)
+static void
+gst_play_frame_displayed (GstElement *element,
+ GstPlay *play)
{
+ GstPlayPrivate *priv;
+
+ priv = (GstPlayPrivate *)play->priv;
+
+ gdk_threads_enter ();
+ gtk_widget_show (GTK_WIDGET (priv->video_widget));
+ gdk_threads_leave ();
+
gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_FRAME_DISPLAYED],
NULL);
}
-static void
-gst_play_audio_handoff (GstElement *element,
- GstPlay *play)
+static void
+gst_play_audio_handoff (GstElement *element,
+ GstPlay *play)
{
gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_AUDIO_PLAYED],
NULL);
}
-static void
-gst_play_object_introspect (GstElement *element,
+static void
+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);
}
else {
*target = element;
- g_print("gstplay: using element \"%s\" for %s property\n",
+ g_print("gstplay: using element \"%s\" for %s property\n",
gst_element_get_name(element), property);
}
}
/* Dumb introspection of the interface...
- * this will change with glib 1.4
+ * this will change with glib 1.4
* */
-static void
-gst_play_object_added (GstElement *pipeline,
- GstElement *element,
- GstPlay *play)
+static void
+gst_play_object_added (GstAutoplug* autoplug,
+ GstObject *object,
+ GstPlay *play)
{
GstPlayPrivate *priv;
-
+
g_return_if_fail (play != NULL);
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);
- if (!priv->bit_rate_element)
- gst_play_object_introspect (element, "bit_rate", &priv->bit_rate_element);
+ if (!priv->offset_element)
+ gst_play_object_introspect (object, "offset", &priv->offset_element);
+ if (!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);
}
}
-GstPlayReturn
-gst_play_set_uri (GstPlay *play,
- const guchar *uri)
+static void
+gst_play_have_type (GstElement *sink, GstElement *sink2, gpointer data)
+{
+ GST_DEBUG (0,"GstPipeline: play have type %p\n", (gboolean *)data);
+
+ *(gboolean *)data = TRUE;
+}
+
+static GstCaps*
+gst_play_typefind (GstBin *bin, GstElement *element)
+{
+ gboolean found = FALSE;
+ GstElement *typefind;
+ GstCaps *caps = NULL;
+
+ GST_DEBUG (0,"GstPipeline: typefind for element \"%s\" %p\n",
+ GST_ELEMENT_NAME(element), &found);
+
+ typefind = gst_elementfactory_make ("typefind", "typefind");
+ g_return_val_if_fail (typefind != NULL, FALSE);
+
+ gtk_signal_connect (GTK_OBJECT (typefind), "have_type",
+ GTK_SIGNAL_FUNC (gst_play_have_type), &found);
+
+ gst_pad_connect (gst_element_get_pad (element, "src"),
+ gst_element_get_pad (typefind, "sink"));
+
+ gst_bin_add (bin, typefind);
+
+ gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
+
+ // push a buffer... the have_type signal handler will set the found flag
+ gst_bin_iterate (bin);
+
+ gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
+
+ if (found) {
+ caps = gst_util_get_pointer_arg (GTK_OBJECT (typefind), "caps");
+
+ gst_pad_set_caps_list (gst_element_get_pad (element, "src"), g_list_prepend (NULL, caps));
+ }
+
+ gst_pad_disconnect (gst_element_get_pad (element, "src"),
+ gst_element_get_pad (typefind, "sink"));
+ gst_bin_remove (bin, typefind);
+ gst_object_unref (GST_OBJECT (typefind));
+
+ return caps;
+}
+
+static gboolean
+connect_pads (GstElement *new_element, GstElement *target, gboolean add)
+{
+ GList *pads = gst_element_get_pad_list (new_element);
+ GstPad *targetpad = gst_element_get_pad (target, "sink");
+
+ while (pads) {
+ GstPad *pad = GST_PAD (pads->data);
+
+ if (gst_pad_check_compatibility (pad, targetpad)) {
+ if (add) {
+ gst_bin_add (GST_BIN (gst_element_get_parent (
+ GST_ELEMENT (gst_pad_get_real_parent (pad)))),
+ target);
+ }
+ gst_pad_connect (pad, targetpad);
+ return TRUE;
+ }
+ pads = g_list_next (pads);
+ }
+ return FALSE;
+}
+
+GstPlayReturn
+gst_play_set_uri (GstPlay *play,
+ const guchar *uri)
{
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);
g_return_val_if_fail (uri != NULL, GST_PLAY_ERROR);
-
+
priv = (GstPlayPrivate *)play->priv;
- if (priv->src) {
- }
-
- if (priv->uri) g_free (priv->uri);
+ if (priv->uri)
+ g_free (priv->uri);
priv->uri = g_strdup (uri);
- //priv->src = gst_elementfactory_make ("disksrc", "disk_src");
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);
- gtk_signal_connect (GTK_OBJECT (priv->src), "eos", GTK_SIGNAL_FUNC (gst_play_eos), play);
+ gtk_object_set (GTK_OBJECT (priv->src), "location", uri, NULL);
- gtk_signal_connect (GTK_OBJECT (priv->pipeline), "object_added", gst_play_object_added, play);
+ gst_bin_add (GST_BIN (priv->bin), priv->src);
- gst_pipeline_add_src (GST_PIPELINE (priv->pipeline),GST_ELEMENT (priv->src));
+ src_caps = gst_play_typefind (GST_BIN (priv->bin), priv->src);
- if (!gst_pipeline_autoplug (GST_PIPELINE (priv->pipeline))) {
+ if (!src_caps) {
return GST_PLAY_UNKNOWN_MEDIA;
}
- if (GST_PAD_CONNECTED (gst_element_get_pad (priv->video_show, "sink"))) {
- play->flags |= GST_PLAY_TYPE_VIDEO;
- }
- if (GST_PAD_CONNECTED (gst_element_get_pad (priv->audio_play, "sink"))) {
- play->flags |= GST_PLAY_TYPE_AUDIO;
+ autoplug = gst_autoplugfactory_make ("staticrender");
+ g_assert (autoplug != NULL);
+
+ gtk_signal_connect (GTK_OBJECT (autoplug), "new_object", gst_play_object_added, play);
+
+ new_element = gst_autoplug_to_renderers (autoplug,
+ gst_pad_get_caps_list (gst_element_get_pad (priv->src, "src")),
+ priv->video_element,
+ priv->audio_element,
+ NULL);
+
+ if (!new_element) {
+ return GST_PLAY_CANNOT_PLAY;
}
- // hmmmm hack? FIXME
- GST_FLAG_UNSET (priv->pipeline, GST_BIN_FLAG_MANAGER);
+ gst_bin_remove (GST_BIN (priv->bin), priv->src);
+ gst_bin_add (GST_BIN (priv->thread), priv->src);
- gst_bin_add (GST_BIN (priv->thread), priv->pipeline);
+ gst_bin_add (GST_BIN (priv->bin), new_element);
+
+ gst_element_connect (priv->src, "src", new_element, "sink");
+
+ gst_bin_add (GST_BIN (priv->thread), priv->bin);
+ gtk_signal_connect (GTK_OBJECT (priv->thread), "eos", GTK_SIGNAL_FUNC (gst_play_eos), play);
return GST_PLAY_OK;
}
-static void
-gst_play_realize (GtkWidget *widget)
+static void
+gst_play_realize (GtkWidget *widget)
{
GstPlay *play;
- GtkWidget *video_widget;
GstPlayPrivate *priv;
-
+
g_return_if_fail (GST_IS_PLAY (widget));
+ g_print ("gst_play: realize\n");
play = GST_PLAY (widget);
priv = (GstPlayPrivate *)play->priv;
- video_widget = gst_util_get_widget_arg (GTK_OBJECT (priv->video_show),"widget");
+ priv->video_widget = gst_util_get_widget_arg (GTK_OBJECT (priv->video_element), "widget");
- if (video_widget) {
- gtk_container_add (GTK_CONTAINER (widget), video_widget);
- gtk_widget_show (video_widget);
+ if (priv->video_widget) {
+ gtk_container_add (GTK_CONTAINER (widget), priv->video_widget);
+ }
+ else {
+ g_print ("oops, no video widget found\n");
}
if (GTK_WIDGET_CLASS (parent_class)->realize) {
@@ -311,8 +408,8 @@ gst_play_realize (GtkWidget *widget)
}
}
-void
-gst_play_play (GstPlay *play)
+void
+gst_play_play (GstPlay *play)
{
GstPlayPrivate *priv;
@@ -333,8 +430,8 @@ gst_play_play (GstPlay *play)
play->state);
}
-void
-gst_play_pause (GstPlay *play)
+void
+gst_play_pause (GstPlay *play)
{
GstPlayPrivate *priv;
@@ -353,8 +450,8 @@ gst_play_pause (GstPlay *play)
play->state);
}
-void
-gst_play_stop (GstPlay *play)
+void
+gst_play_stop (GstPlay *play)
{
GstPlayPrivate *priv;
@@ -374,8 +471,8 @@ gst_play_stop (GstPlay *play)
play->state);
}
-gulong
-gst_play_get_media_size (GstPlay *play)
+gulong
+gst_play_get_media_size (GstPlay *play)
{
GstPlayPrivate *priv;
@@ -387,7 +484,7 @@ gst_play_get_media_size (GstPlay *play)
return gst_util_get_long_arg (GTK_OBJECT (priv->src), "size");
}
-gulong
+gulong
gst_play_get_media_offset (GstPlay *play)
{
GstPlayPrivate *priv;
@@ -397,15 +494,18 @@ gst_play_get_media_offset (GstPlay *play)
priv = (GstPlayPrivate *)play->priv;
- return gst_util_get_long_arg (GTK_OBJECT (priv->offset_element), "offset");
+ if (priv->offset_element)
+ return gst_util_get_long_arg (GTK_OBJECT (priv->offset_element), "offset");
+ else
+ return 0;
}
-gulong
+gulong
gst_play_get_media_total_time (GstPlay *play)
{
gulong total_time, bit_rate;
GstPlayPrivate *priv;
-
+
g_return_val_if_fail (play != NULL, 0);
g_return_val_if_fail (GST_IS_PLAY (play), 0);
@@ -419,7 +519,7 @@ gst_play_get_media_total_time (GstPlay *play)
bit_rate = gst_util_get_long_arg (GTK_OBJECT (priv->bit_rate_element), "bit_rate");
- if (bit_rate)
+ if (bit_rate)
total_time = (gst_play_get_media_size (play) * 8) / bit_rate;
else
total_time = 0;
@@ -427,12 +527,12 @@ gst_play_get_media_total_time (GstPlay *play)
return total_time;
}
-gulong
+gulong
gst_play_get_media_current_time (GstPlay *play)
{
gulong current_time, bit_rate;
GstPlayPrivate *priv;
-
+
g_return_val_if_fail (play != NULL, 0);
g_return_val_if_fail (GST_IS_PLAY (play), 0);
@@ -446,7 +546,7 @@ gst_play_get_media_current_time (GstPlay *play)
bit_rate = gst_util_get_long_arg (GTK_OBJECT (priv->bit_rate_element), "bit_rate");
- if (bit_rate)
+ if (bit_rate)
current_time = (gst_play_get_media_offset (play) * 8) / bit_rate;
else
current_time = 0;
@@ -454,7 +554,7 @@ gst_play_get_media_current_time (GstPlay *play)
return current_time;
}
-gboolean
+gboolean
gst_play_media_can_seek (GstPlay *play)
{
GstPlayPrivate *priv;
@@ -467,8 +567,8 @@ gst_play_media_can_seek (GstPlay *play)
return priv->can_seek;
}
-void
-gst_play_media_seek (GstPlay *play,
+void
+gst_play_media_seek (GstPlay *play,
gulong offset)
{
GstPlayPrivate *priv;
@@ -482,10 +582,10 @@ gst_play_media_seek (GstPlay *play,
}
-static void
+static void
gst_play_set_arg (GtkObject *object,
GtkArg *arg,
- guint id)
+ guint id)
{
GstPlay *play;
@@ -503,10 +603,10 @@ gst_play_set_arg (GtkObject *object,
}
}
-static void
+static void
gst_play_get_arg (GtkObject *object,
GtkArg *arg,
- guint id)
+ guint id)
{
GstPlay *play;
GstPlayPrivate *priv;
diff --git a/gstplay/gstplay.h b/gstplay/gstplay.h
index 7452a78826..fcaebf2f18 100644
--- a/gstplay/gstplay.h
+++ b/gstplay/gstplay.h
@@ -31,6 +31,7 @@ typedef enum {
typedef enum {
GST_PLAY_OK,
GST_PLAY_UNKNOWN_MEDIA,
+ GST_PLAY_CANNOT_PLAY,
GST_PLAY_ERROR,
} GstPlayReturn;
diff --git a/gstplay/gstplayprivate.h b/gstplay/gstplayprivate.h
index 66b7b4dd9c..31e4e17f10 100644
--- a/gstplay/gstplayprivate.h
+++ b/gstplay/gstplayprivate.h
@@ -12,9 +12,9 @@ typedef struct _GstPlayPrivate GstPlayPrivate;
struct _GstPlayPrivate {
GstElement *thread;
- GstElement *pipeline;
- GstElement *audio_play;
- GstElement *video_show;
+ GstElement *bin;
+ GstElement *video_element, *audio_element;
+ GtkWidget *video_widget;
GstElement *src;
guchar *uri;
diff --git a/plugins/elements/gstdisksrc.c b/plugins/elements/gstdisksrc.c
index 9eebbd4bf6..9e81eb9b73 100644
--- a/plugins/elements/gstdisksrc.c
+++ b/plugins/elements/gstdisksrc.c
@@ -2,7 +2,7 @@
* Copyright (C) 1999,2000 Erik Walthinsen
* 2000 Wim Taymans
*
- * gstdisksrc.c:
+ * gstdisksrc.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -56,23 +56,23 @@ enum {
};
-static void gst_disksrc_class_init (GstDiskSrcClass *klass);
-static void gst_disksrc_init (GstDiskSrc *disksrc);
+static void gst_disksrc_class_init (GstDiskSrcClass *klass);
+static void gst_disksrc_init (GstDiskSrc *disksrc);
-static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id);
-static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id);
+static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id);
+static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id);
static GstBuffer * gst_disksrc_get (GstPad *pad);
static GstBuffer * gst_disksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len);
-static GstElementStateReturn gst_disksrc_change_state (GstElement *element);
+static GstElementStateReturn gst_disksrc_change_state (GstElement *element);
static GstElementClass *parent_class = NULL;
//static guint gst_disksrc_signals[LAST_SIGNAL] = { 0 };
GtkType
-gst_disksrc_get_type(void)
+gst_disksrc_get_type(void)
{
static GtkType disksrc_type = 0;
@@ -93,7 +93,7 @@ gst_disksrc_get_type(void)
}
static void
-gst_disksrc_class_init (GstDiskSrcClass *klass)
+gst_disksrc_class_init (GstDiskSrcClass *klass)
{
GtkObjectClass *gtkobject_class;
GstElementClass *gstelement_class;
@@ -118,8 +118,8 @@ gst_disksrc_class_init (GstDiskSrcClass *klass)
gstelement_class->change_state = gst_disksrc_change_state;
}
-static void
-gst_disksrc_init (GstDiskSrc *disksrc)
+static void
+gst_disksrc_init (GstDiskSrc *disksrc)
{
// GST_FLAG_SET (disksrc, GST_SRC_);
@@ -139,14 +139,14 @@ gst_disksrc_init (GstDiskSrc *disksrc)
}
-static void
-gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
+static void
+gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
{
GstDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_DISKSRC (object));
-
+
src = GST_DISKSRC (object);
switch(id) {
@@ -176,14 +176,14 @@ gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
}
}
-static void
-gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
+static void
+gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
{
GstDiskSrc *src;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail (GST_IS_DISKSRC (object));
-
+
src = GST_DISKSRC (object);
switch (id) {
@@ -212,7 +212,7 @@ gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
* Push a new buffer from the disksrc at the current offset.
*/
static GstBuffer *
-gst_disksrc_get (GstPad *pad)
+gst_disksrc_get (GstPad *pad)
{
GstDiskSrc *src;
GstBuffer *buf;
@@ -223,7 +223,7 @@ gst_disksrc_get (GstPad *pad)
/* deal with EOF state */
if (src->curoffset >= src->size) {
- gst_element_signal_eos (GST_ELEMENT (src));
+ gst_pad_set_eos (pad);
return NULL;
}
@@ -269,7 +269,7 @@ gst_disksrc_get (GstPad *pad)
* Push a new buffer from the disksrc of given size at given offset.
*/
static GstBuffer *
-gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len)
+gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len)
{
GstDiskSrc *src;
GstBuffer *buf;
@@ -281,10 +281,10 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l
g_return_val_if_fail (GST_IS_DISKSRC (src), NULL);
g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN), NULL);
-
+
/* deal with EOF state */
if (offset >= src->size) {
- gst_element_signal_eos (GST_ELEMENT (src));
+ gst_pad_set_eos (pad);
return NULL;
}
@@ -312,8 +312,8 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l
/* open the file and mmap it, necessary to go to READY state */
-static
-gboolean gst_disksrc_open_file (GstDiskSrc *src)
+static
+gboolean gst_disksrc_open_file (GstDiskSrc *src)
{
g_return_val_if_fail (!GST_FLAG_IS_SET (src ,GST_DISKSRC_OPEN), FALSE);
@@ -343,8 +343,8 @@ gboolean gst_disksrc_open_file (GstDiskSrc *src)
}
/* unmap and close the file */
-static void
-gst_disksrc_close_file (GstDiskSrc *src)
+static void
+gst_disksrc_close_file (GstDiskSrc *src)
{
g_return_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN));
@@ -365,8 +365,8 @@ gst_disksrc_close_file (GstDiskSrc *src)
}
-static GstElementStateReturn
-gst_disksrc_change_state (GstElement *element)
+static GstElementStateReturn
+gst_disksrc_change_state (GstElement *element)
{
g_return_val_if_fail (GST_IS_DISKSRC (element), GST_STATE_FAILURE);
@@ -375,7 +375,7 @@ gst_disksrc_change_state (GstElement *element)
gst_disksrc_close_file (GST_DISKSRC (element));
} else {
if (!GST_FLAG_IS_SET (element, GST_DISKSRC_OPEN)) {
- if (!gst_disksrc_open_file (GST_DISKSRC (element)))
+ if (!gst_disksrc_open_file (GST_DISKSRC (element)))
return GST_STATE_FAILURE;
}
}
diff --git a/plugins/elements/gstelements.c b/plugins/elements/gstelements.c
index 193592ac85..62b5a9288f 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
@@ -61,13 +61,13 @@ static struct _elements_entry _elements[] = {
{ "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/test/mp1parse.c b/test/mp1parse.c
index d49bdad0eb..641f4b4254 100644
--- a/test/mp1parse.c
+++ b/test/mp1parse.c
@@ -62,7 +62,6 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
// set up thread state and kick things off
gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL);
g_print("setting to READY state\n");
- gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_READY);
} else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
//} else if (0) {
@@ -116,7 +115,6 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) {
// set up thread state and kick things off
gtk_object_set(GTK_OBJECT(video_thread),"create_thread",TRUE,NULL);
g_print("setting to READY state\n");
- gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_READY);
}
g_print("\n");
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
diff --git a/tests/.gitignore b/tests/.gitignore
index 8d0cd0b737..fc4f7a1ff4 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -6,7 +6,7 @@ Makefile.in
.deps
.libs
*.xml
-
+*.gst
init
loadall
simplefake
@@ -24,3 +24,5 @@ markup
load
padfactory
tee
+autoplug2
+autoplug3
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f116e177bf..1d82923671 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 autoplug3
# 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 f6dcb1be39..87913c6f4f 100644
--- a/tests/autoplug.c
+++ b/tests/autoplug.c
@@ -1,63 +1,45 @@
#include
-static GList*
-autoplug_caps (gchar *mime1, gchar *mime2)
-{
- GstCaps *caps1, *caps2;
-
- caps1 = gst_caps_new ("tescaps1", mime1);
- caps2 = gst_caps_new ("tescaps2", mime2);
-
- return gst_autoplug_caps (caps1, caps2);
-}
-
static void
-dump_factories (GList *factories)
+new_object_added (GstAutoplug *autoplug, GstObject *object)
{
- g_print ("dumping factories\n");
-
- while (factories) {
- GstElementFactory *factory = (GstElementFactory *)factories->data;
-
- g_print ("factory: \"%s\"\n", factory->name);
-
- factories = g_list_next (factories);
- }
+ g_print ("added new object \"%s\"\n", gst_object_get_name (object));
}
-int main(int argc,char *argv[])
+int
+main (int argc, char *argv[])
{
- GList *factories;
+ GstElement *element;
+ GstElement *videosink, *audiosink;
+ GstAutoplug *autoplugger;
+ GList *testcaps;
gst_init(&argc,&argv);
- factories = autoplug_caps ("audio/mp3", "audio/raw");
- dump_factories (factories);
+ audiosink = gst_elementfactory_make ("audiosink", "audiosink");
+ g_assert (audiosink != NULL);
+ videosink = gst_elementfactory_make ("videosink", "videosink");
+ g_assert (videosink != NULL);
- factories = autoplug_caps ("video/mpeg", "audio/raw");
- dump_factories (factories);
+ testcaps = g_list_append (NULL,
+ gst_caps_new_with_props ("test_caps",
+ "video/mpeg",
+ gst_props_new (
+ "mpegversion", GST_PROPS_INT (1),
+ "systemstream", GST_PROPS_BOOLEAN (TRUE),
+ NULL)));
- factories = gst_autoplug_caps (
- gst_caps_new_with_props(
- "testcaps3",
- "video/mpeg",
- gst_props_new (
- "mpegversion", GST_PROPS_INT (1),
- "systemstream", GST_PROPS_BOOLEAN (TRUE),
- NULL)),
- gst_caps_new("testcaps4","audio/raw"));
- dump_factories (factories);
+ autoplugger = gst_autoplugfactory_make ("static");
- factories = gst_autoplug_caps (
- gst_caps_new_with_props(
- "testcaps5",
- "video/mpeg",
- gst_props_new (
- "mpegversion", GST_PROPS_INT (1),
- "systemstream", GST_PROPS_BOOLEAN (FALSE),
- NULL)),
- gst_caps_new("testcaps6", "video/raw"));
- dump_factories (factories);
+ gtk_signal_connect (GTK_OBJECT (autoplugger), "new_object", new_object_added, NULL);
+
+ element = gst_autoplug_to_caps (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));
exit (0);
}
diff --git a/tests/autoplug2.c b/tests/autoplug2.c
new file mode 100644
index 0000000000..64f0a9f58d
--- /dev/null
+++ b/tests/autoplug2.c
@@ -0,0 +1,78 @@
+#include
+
+static GstElement*
+autoplug_caps (GstAutoplug *autoplug, 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_to_caps (autoplug, caps1, caps2, NULL);
+}
+
+int
+main (int argc, char *argv[])
+{
+ GstElement *element;
+ GstAutoplug *autoplug;
+
+ gst_init(&argc,&argv);
+
+ autoplug = gst_autoplugfactory_make ("static");
+
+ element = autoplug_caps (autoplug, "audio/mp3", "audio/raw");
+ xmlSaveFile ("autoplug2_1.gst", gst_xml_write (element));
+
+ element = autoplug_caps (autoplug, "video/mpeg", "audio/raw");
+ xmlSaveFile ("autoplug2_2.gst", gst_xml_write (element));
+
+ element = gst_autoplug_to_caps (autoplug,
+ 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_to_caps (autoplug,
+ 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));
+
+ element = gst_autoplug_to_caps (autoplug,
+ g_list_append (NULL, gst_caps_new(
+ "testcaps7",
+ "video/avi")),
+ g_list_append (NULL, gst_caps_new("testcaps8", "video/raw")),
+ g_list_append (NULL, gst_caps_new("testcaps9", "audio/raw")),
+ NULL);
+ xmlSaveFile ("autoplug2_5.gst", gst_xml_write (element));
+
+ element = gst_autoplug_to_caps (autoplug,
+ g_list_append (NULL, gst_caps_new_with_props(
+ "testcaps10",
+ "video/mpeg",
+ gst_props_new (
+ "mpegversion", GST_PROPS_INT (1),
+ "systemstream", GST_PROPS_BOOLEAN (TRUE),
+ NULL))),
+ g_list_append (NULL, gst_caps_new("testcaps10", "video/raw")),
+ g_list_append (NULL, gst_caps_new("testcaps11", "audio/raw")),
+ NULL);
+ xmlSaveFile ("autoplug2_6.gst", gst_xml_write (element));
+
+ exit (0);
+ exit (0);
+}
diff --git a/tests/autoplug3.c b/tests/autoplug3.c
new file mode 100644
index 0000000000..d63726ddca
--- /dev/null
+++ b/tests/autoplug3.c
@@ -0,0 +1,102 @@
+#include
+
+int
+main (int argc, char *argv[])
+{
+ GstElement *element;
+ GstElement *sink1, *sink2;
+ GstAutoplug *autoplug;
+ GstAutoplug *autoplug2;
+
+ gst_init(&argc,&argv);
+
+ sink1 = gst_elementfactory_make ("videosink", "videosink");
+ sink2 = gst_elementfactory_make ("audiosink", "audiosink");
+
+ autoplug = gst_autoplugfactory_make ("staticrender");
+ autoplug2 = gst_autoplugfactory_make ("static");
+
+ element = gst_autoplug_to_renderers (autoplug,
+ g_list_append (NULL, gst_caps_new ("mp3caps", "audio/mp3")), sink2, NULL);
+ xmlSaveFile ("autoplug3_1.gst", gst_xml_write (element));
+
+ element = gst_autoplug_to_renderers (autoplug,
+ g_list_append (NULL, gst_caps_new ("mpeg1caps", "video/mpeg")), sink1, NULL);
+ if (element) {
+ xmlSaveFile ("autoplug3_2.gst", gst_xml_write (element));
+ }
+
+ element = gst_autoplug_to_caps (autoplug2,
+ 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);
+ if (element) {
+ xmlSaveFile ("autoplug3_3.gst", gst_xml_write (element));
+ }
+
+ element = gst_autoplug_to_caps (autoplug2,
+ 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);
+ if (element) {
+ xmlSaveFile ("autoplug3_4.gst", gst_xml_write (element));
+ }
+
+ element = gst_autoplug_to_caps (autoplug2,
+ g_list_append (NULL, gst_caps_new(
+ "testcaps7",
+ "video/avi")),
+ g_list_append (NULL, gst_caps_new("testcaps8", "video/raw")),
+ g_list_append (NULL, gst_caps_new("testcaps9", "audio/raw")),
+ NULL);
+ if (element) {
+ xmlSaveFile ("autoplug3_5.gst", gst_xml_write (element));
+ }
+
+ element = gst_autoplug_to_caps (autoplug2,
+ g_list_append (NULL, gst_caps_new_with_props(
+ "testcaps10",
+ "video/mpeg",
+ gst_props_new (
+ "mpegversion", GST_PROPS_INT (1),
+ "systemstream", GST_PROPS_BOOLEAN (TRUE),
+ NULL))),
+ g_list_append (NULL, gst_caps_new("testcaps10", "video/raw")),
+ g_list_append (NULL, gst_caps_new("testcaps11", "audio/raw")),
+ NULL);
+ if (element) {
+ xmlSaveFile ("autoplug3_6.gst", gst_xml_write (element));
+ }
+
+ sink1 = gst_elementfactory_make ("videosink", "videosink");
+ sink2 = gst_elementfactory_make ("audiosink", "audiosink");
+
+ element = gst_autoplug_to_renderers (autoplug,
+ g_list_append (NULL, gst_caps_new_with_props(
+ "testcaps10",
+ "video/mpeg",
+ gst_props_new (
+ "mpegversion", GST_PROPS_INT (1),
+ "systemstream", GST_PROPS_BOOLEAN (TRUE),
+ NULL))),
+ sink1,
+ sink2,
+ NULL);
+ if (element) {
+ xmlSaveFile ("autoplug3_7.gst", gst_xml_write (element));
+ }
+
+ exit (0);
+}
diff --git a/tests/old/examples/autoplug/autoplug.c b/tests/old/examples/autoplug/autoplug.c
index 4a3453552c..4e37b5d999 100644
--- a/tests/old/examples/autoplug/autoplug.c
+++ b/tests/old/examples/autoplug/autoplug.c
@@ -31,8 +31,6 @@ int main(int argc,char *argv[])
exit(-1);
}
-
-
/* create a new bin to hold the elements */
pipeline = gst_pipeline_new("pipeline");
g_assert(pipeline != NULL);
@@ -59,6 +57,7 @@ int main(int argc,char *argv[])
gtk_widget_show_all(appwindow);
/* add objects to the main pipeline */
+ /*
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), videosink);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
@@ -67,6 +66,7 @@ int main(int argc,char *argv[])
g_print("unable to handle stream\n");
exit(-1);
}
+ */
xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(pipeline)));
diff --git a/tests/old/examples/helloworld2/helloworld2.c b/tests/old/examples/helloworld2/helloworld2.c
index 90de5139d5..8b70518eda 100644
--- a/tests/old/examples/helloworld2/helloworld2.c
+++ b/tests/old/examples/helloworld2/helloworld2.c
@@ -41,6 +41,7 @@ int main(int argc,char *argv[])
g_assert(audiosink != NULL);
/* add objects to the main pipeline */
+ /*
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
@@ -48,6 +49,7 @@ int main(int argc,char *argv[])
g_print("unable to handle stream\n");
exit(-1);
}
+ */
// hmmmm hack? FIXME
GST_FLAG_UNSET (pipeline, GST_BIN_FLAG_MANAGER);
diff --git a/tests/old/examples/queue2/queue2.c b/tests/old/examples/queue2/queue2.c
index a3662b14e6..706acc073f 100644
--- a/tests/old/examples/queue2/queue2.c
+++ b/tests/old/examples/queue2/queue2.c
@@ -46,11 +46,12 @@ int main(int argc,char *argv[])
g_assert(audiosink != NULL);
/* add objects to the main pipeline */
+ /*
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), queue);
gst_bin_add(GST_BIN(thread), audiosink);
-
+
gst_pad_connect(gst_element_get_pad(queue,"src"),
gst_element_get_pad(audiosink,"sink"));
@@ -58,6 +59,7 @@ int main(int argc,char *argv[])
g_print("cannot autoplug pipeline\n");
exit(-1);
}
+ */
gst_bin_add(GST_BIN(pipeline), thread);
diff --git a/tests/old/examples/thread/thread.c b/tests/old/examples/thread/thread.c
index 533c38a6f7..b8bc00e1de 100644
--- a/tests/old/examples/thread/thread.c
+++ b/tests/old/examples/thread/thread.c
@@ -45,6 +45,7 @@ int main(int argc,char *argv[])
g_assert(audiosink != NULL);
/* add objects to the main pipeline */
+ /*
gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
@@ -52,6 +53,7 @@ int main(int argc,char *argv[])
g_print("unable to handle stream\n");
exit(-1);
}
+ */
//gst_bin_remove(GST_BIN(pipeline), disksrc);
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 {