Merged the AUTOPLUG2 branch
authorWim Taymans <wim.taymans@gmail.com>
Wed, 7 Mar 2001 21:52:56 +0000 (21:52 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 7 Mar 2001 21:52:56 +0000 (21:52 +0000)
Original commit message from CVS:
Merged the AUTOPLUG2 branch

57 files changed:
configure.in
docs/gst/tmpl/gstautoplug.sgml
docs/gst/tmpl/gstpad.sgml
docs/gst/tmpl/gstpipeline.sgml
docs/gst/tmpl/gstplugin.sgml
docs/gst/tmpl/gstreamer-unused.sgml
docs/random/hierarchy [new file with mode: 0644]
docs/random/wtay/autoplug2
editor/gsteditor.h
examples/autoplug/autoplug.c
examples/helloworld2/helloworld2.c
examples/queue2/queue2.c
examples/thread/thread.c
gst/Makefile.am
gst/autoplug/Makefile.am [new file with mode: 0644]
gst/autoplug/gststaticautoplug.c [new file with mode: 0644]
gst/autoplug/gststaticautoplug.h [new file with mode: 0644]
gst/autoplug/gststaticautoplugrender.c [new file with mode: 0644]
gst/autoplug/gststaticautoplugrender.h [new file with mode: 0644]
gst/elements/gstdisksrc.c
gst/elements/gstelements.c
gst/gstautoplug.c
gst/gstautoplug.h
gst/gstbin.c
gst/gstcaps.c
gst/gstcaps.h
gst/gstelement.c
gst/gstelement.h
gst/gstelementfactory.c
gst/gstobject.c
gst/gstpad.c
gst/gstpad.h
gst/gstpipeline.c
gst/gstpipeline.h
gst/gstplugin.c
gst/gstplugin.h
gst/gstprops.c
gst/gstthread.c
gst/gsttype.c
gst/gsttype.h
gst/gsttypefind.c
gstplay/gstplay.c
gstplay/gstplay.h
gstplay/gstplayprivate.h
plugins/elements/gstdisksrc.c
plugins/elements/gstelements.c
test/mp1parse.c
tests/.gitignore
tests/Makefile.am
tests/autoplug.c
tests/autoplug2.c [new file with mode: 0644]
tests/autoplug3.c [new file with mode: 0644]
tests/old/examples/autoplug/autoplug.c
tests/old/examples/helloworld2/helloworld2.c
tests/old/examples/queue2/queue2.c
tests/old/examples/thread/thread.c
tools/gstreamer-inspect.c

index 0344b8583897b92068077147e7bcd6546f6da1a7..4eacd91bf88518ebbef7e9746ab8527c0ff8ae7d 100644 (file)
@@ -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
index 2ea069b281489c6a2e2bbf419612162164ffce77..0fe0ed43060e4c60dbbf8fc6042d1f85a0e2440f 100644 (file)
@@ -15,60 +15,18 @@ to convert a certain GstCaps to another one.
 
 </para>
 
-<!-- ##### MACRO GST_AUTOPLUG_MAX_COST ##### -->
-<para>
-The maximum cost of a certain connection.
-</para>
-
-
-
-<!-- ##### USER_FUNCTION GstAutoplugCostFunction ##### -->
-<para>
-Calculate the cost between two elements.
-</para>
-
-@src: the source element
-@dest: the destination element
-@data: optional user data
-@Returns: the cost for a connection between the two elements
-
-
-<!-- ##### USER_FUNCTION GstAutoplugListFunction ##### -->
-<para>
-Get a list of all elements. These elements will be used in autoplugging.
-</para>
-
-@data: user data
-@Returns: a GList of elements
-
-
-<!-- ##### FUNCTION gst_autoplug_caps ##### -->
-<para>
-
-</para>
-
-@srccaps: 
-@sinkcaps: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_autoplug_pads ##### -->
+<!-- ##### FUNCTION gst_autoplug_caps_list ##### -->
 <para>
 
 </para>
 
+@autoplug: 
 @srcpad: 
 @sinkpad: 
+@Varargs: 
 @Returns: 
-
-
-<!-- ##### FUNCTION gst_autoplug_caps_list ##### -->
-<para>
-
-</para>
-
+<!-- # Unused Parameters # -->
 @srccaps: 
 @sinkcaps: 
-@Returns: 
 
 
index db45773d2d91aed7dc34a8d89aa20ceac3354297..5a5dd33144f6b0a774c82e60dc86b7632024f210 100644 (file)
@@ -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
+<!-- # Unused Parameters # -->
+@size: the size of the region to get
 
 
 <!-- ##### USER_FUNCTION GstPadQoSFunction ##### -->
index da53a4780536daed12d76b5913e6268482c4d155..f486cfb19374298f5c7b4547f6fbb0659447334e 100644 (file)
@@ -38,33 +38,6 @@ pipeline figure out what plugins to use.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_pipeline_add_sink ##### -->
-<para>
-
-</para>
-
-@pipeline: 
-@sink: 
-
-
-<!-- ##### FUNCTION gst_pipeline_add_src ##### -->
-<para>
-
-</para>
-
-@pipeline: 
-@src: 
-
-
-<!-- ##### FUNCTION gst_pipeline_autoplug ##### -->
-<para>
-
-</para>
-
-@pipeline: 
-@Returns: 
-
-
 <!-- ##### MACRO gst_pipeline_destroy ##### -->
 <para>
 Destroys the pipeline.
index b281b08a9fbe6360e7b4116e2ae90f7ceeeac8f8..b4b87637e08b9d7691563cd5a7c9f29ac82791e5 100644 (file)
@@ -27,6 +27,8 @@ GStreamer is extensible so <classname>GstElements</classname> can be loaded at r
 @numtypes: 
 @elements: 
 @numelements: 
+@autopluggers: 
+@numautopluggers: 
 @loaded: 
 
 <!-- ##### STRUCT GstPluginElement ##### -->
@@ -203,15 +205,6 @@ by the loader at statup.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_plugin_find_elementfactory ##### -->
-<para>
-
-</para>
-
-@name: 
-@Returns: 
-
-
 <!-- ##### FUNCTION gst_plugin_load_elementfactory ##### -->
 <para>
 
index 1740957e0d91d8cd8a0022bb9ca57ef8c4337b16..5f5ff9c6eac7b63ec1e15ed6c619cadf43d4d092 100644 (file)
@@ -780,10 +780,6 @@ Query whether this object has multiple input pads.
 </para>
 
 
-<!-- ##### SECTION ./tmpl/gstasyncdisksrc.sgml:Short_Description ##### -->
-Asynchronous disk reader. (asyncdisksrc)
-
-
 <!-- ##### FUNCTION gst_src_signal_eos ##### -->
 <para>
 
@@ -1383,11 +1379,15 @@ The start point of a filter graph
 
 @klass: 
 
+<<<<<<< gstreamer-unused.sgml
 <!-- ##### SECTION ./tmpl/gstasyncdisksrc.sgml:Title ##### -->
 GstAsyncDiskSrc
 
 
 <!-- ##### MACRO GST_TYPE_ASYNCDISKSRC ##### -->
+=======
+<!-- ##### MACRO GST_TYPE_ASYNCDISKSRC ##### -->
+>>>>>>> 1.23.2.3
 <para>
 
 </para>
@@ -2009,6 +2009,7 @@ GstFilter
 </para>
 
 
+<<<<<<< gstreamer-unused.sgml
 <!-- ##### ENUM GstSrcFlags ##### -->
 <para>
 Flags for the GstSrc element
@@ -2024,6 +2025,18 @@ Flags for the GstSrc element
 
 
 <!-- ##### MACRO GST_HTTPSRC ##### -->
+=======
+<!-- ##### ENUM GstSrcFlags ##### -->
+<para>
+Flags for the GstSrc element
+</para>
+
+@GST_SRC_ASYNC: Indicates that this src is asynchronous
+@GST_SRC_FLAG_LAST: subclasses can use this to number their flags
+
+
+<!-- ##### MACRO GST_HTTPSRC ##### -->
+>>>>>>> 1.23.2.3
 <para>
 
 </para>
diff --git a/docs/random/hierarchy b/docs/random/hierarchy
new file mode 100644 (file)
index 0000000..fc854af
--- /dev/null
@@ -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
+    
index 1c0f6f808cd459a241acf888db2171d09da75099..c56f9b1f5429cecd5d4eed6200b5246a9b5c9ea1 100644 (file)
@@ -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
index 105e18087afb0950d1a5fb420a0c83308dd273ed..e67667e8a437ceca90b25b00632f170c03a63cde 100644 (file)
@@ -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, ...);
index 4a3453552cc83e2927768032614d4294ed28d4bc..4e37b5d999cc27cb55d2af431af0faa937933983 100644 (file)
@@ -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)));
 
index 90de5139d535787eab1897008a55c10188396d4b..8b70518edae5e69b46a248a8983862737655ec50 100644 (file)
@@ -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);
index a3662b14e608473ee2a42699efc0e8ff0b8176bf..706acc073fbb12560318901b09bdf1873010464e 100644 (file)
@@ -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);
 
index 533c38a6f7f94febf539cbd33e14510598dd2e5b..b8bc00e1de4024b89dc0ade11649b72fe67bd5c4 100644 (file)
@@ -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);
 
index d25c9f94686c3ff4b1f921632a6109668c8c1465..c5f4e9310edde32bf32953e484ffaf5f7140c2f6 100644 (file)
@@ -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 (file)
index 0000000..0ddb2a8
--- /dev/null
@@ -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 (file)
index 0000000..a39ac57
--- /dev/null
@@ -0,0 +1,619 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * 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 <gst/gst.h>
+
+#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; i<numsinks; i++) {
+      if (factory != (GstElementFactory *) (factories[i]->data)) {
+       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; i<numsinks; i++) {
+      factories[i] = g_list_next (factories[i]);
+    }
+
+    have_common = TRUE;
+  }
+
+differ:
+
+  // loop over all the sink elements
+  for (i = 0; i < numsinks; i++) {
+    GstElement *thesrcelement = srcelement;
+    GstElement *thebin = GST_ELEMENT(result);
+
+    while (factories[i]) {
+      // fase 4: add other elements...
+      GstElementFactory *factory;
+      GstElement *element;
+
+      factory = (GstElementFactory *)(factories[i]->data);
+
+      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 (file)
index 0000000..9a99097
--- /dev/null
@@ -0,0 +1,64 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * 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 <gst/gstautoplug.h>
+
+#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 (file)
index 0000000..5533d69
--- /dev/null
@@ -0,0 +1,650 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * 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 <gst/gst.h>
+
+#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; i<numsinks; i++) {
+      if (factory != (GstElementFactory *) (factories[i]->data)) {
+       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; i<numsinks; i++) {
+      factories[i] = g_list_next (factories[i]);
+    }
+
+    have_common = TRUE;
+  }
+
+differ:
+
+  // loop over all the sink elements
+  for (i = 0; i < numsinks; i++) {
+    GstElement *thesrcelement = srcelement;
+    GstElement *thebin = GST_ELEMENT(result);
+    GstElement *sinkelement;
+    gboolean use_thread;
+
+    sinkelement = GST_ELEMENT (endelements->data);
+    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 (file)
index 0000000..351d4cd
--- /dev/null
@@ -0,0 +1,64 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * 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 <gst/gstautoplug.h>
+
+#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__ */
+
index 9eebbd4bf64c67f8b873f379ea91018eded1249e..9e81eb9b739796d65997eebcd44da29bf0c3665b 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wtay@chello.be>
  *
- * 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;
     }
   }
index 193592ac851950c97ef74ff3b253fe7cc6296500..62b5a9288f4fdf84420b7597647f1a159523b0f2 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wtay@chello.be>
  *
- * 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;
index 4a088a5344f34c35e8f6caa0e4737080bcbb6524..3f74b25bb1f0fb8ab13e296491410a9bce2e9d73 100644 (file)
 #include "gst_private.h"
 
 #include "gstautoplug.h"
+#include "gstplugin.h"
 
-static void     gst_autoplug_class_init (GstAutoplugClass *klass);
-static void     gst_autoplug_init       (GstAutoplug *autoplug);
+GList* _gst_autoplugfactories;
 
-static GList*  gst_autoplug_func       (gpointer src, gpointer sink,
-                                        GstAutoplugListFunction list_function,
-                                        GstAutoplugCostFunction cost_function,
-                                        gpointer data);
+enum {
+  NEW_OBJECT,
+  LAST_SIGNAL
+};
 
-struct _gst_autoplug_node
-{
-  gpointer iNode;
-  gpointer iPrev;
-  gint iDist;
+enum {
+  ARG_0,
+  /* FILL ME */
 };
 
-typedef struct _gst_autoplug_node gst_autoplug_node;
+static void     gst_autoplug_class_init (GstAutoplugClass *klass);
+static void     gst_autoplug_init       (GstAutoplug *autoplug);
 
 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 void gst_autoplug_init(GstAutoplug *autoplug) {
+void
+_gst_autoplug_initialize (void)
+{
+  _gst_autoplugfactories = NULL;
 }
 
-static gboolean
-gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
+void
+gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object)
 {
-  GList *srctemps, *desttemps;
+  gtk_signal_emit (GTK_OBJECT (autoplug), gst_autoplug_signals[NEW_OBJECT], object);
+}
 
-  srctemps = src->padtemplates;
 
-  while (srctemps) {
-    GstPadTemplate *srctemp = (GstPadTemplate *)srctemps->data;
+GstElement*
+gst_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, ...)
+{
+  GstAutoplugClass *oclass;
+  GstElement *element = NULL;
+  va_list args;
 
-    desttemps = dest->padtemplates;
+  va_start (args, sinkcaps);
 
-    while (desttemps) {
-      GstPadTemplate *desttemp = (GstPadTemplate *)desttemps->data;
+  oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass);
+  if (oclass->autoplug_to_caps)
+    element = (oclass->autoplug_to_caps) (autoplug, srccaps, sinkcaps, args);
 
-      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;
-       }
-      }
+  va_end (args);
 
-      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;
+  return element;
 }
 
-static GList*
-gst_autoplug_elementfactory_get_list (gpointer data)
+GstElement*
+gst_autoplug_to_renderers (GstAutoplug *autoplug, GList *srccaps, GstElement *target, ...)
 {
-  return gst_elementfactory_get_list ();
-}
+  GstAutoplugClass *oclass;
+  GstElement *element = NULL;
+  va_list args;
 
-typedef struct {
-  GList *src;
-  GList *sink;
-} caps_struct;
+  va_start (args, target);
 
-#define IS_CAPS(cap) (((cap) == caps->src) || (cap) == caps->sink)
+  oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass);
+  if (oclass->autoplug_to_renderers)
+    element = (oclass->autoplug_to_renderers) (autoplug, srccaps, target, args);
 
-static guint
-gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data)
-{
-  caps_struct *caps = (caps_struct *)data;
-  gboolean res;
+  va_end (args);
 
-  if (IS_CAPS (src) && IS_CAPS (dest)) {
-    res = gst_caps_list_check_compatibility ((GList *)src, (GList *)dest);
-    //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"caps %d to caps %d %d", ((GstCaps *)src)->id, ((GstCaps *)dest)->id, res);
-  }
-  else if (IS_CAPS (src)) {
-    res = gst_elementfactory_can_sink_caps_list ((GstElementFactory *)dest, (GList *)src);
-    //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to src caps %d %d", ((GstElementFactory *)dest)->name, ((GstCaps *)src)->id, res);
-  }
-  else if (IS_CAPS (dest)) {
-    res = gst_elementfactory_can_src_caps_list ((GstElementFactory *)src, (GList *)dest);
-    //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to sink caps %d %d", ((GstElementFactory *)src)->name, ((GstCaps *)dest)->id, res);
-  }
-  else {
-    res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest);
-  }
-
-  if (res)
-    return 1;
-  else
-    return GST_AUTOPLUG_MAX_COST;
+  return element;
 }
 
+
 /**
- * gst_autoplug_caps:
- * @srccaps: the source caps
- * @sinkcaps: the sink caps
+ * 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
  *
- * Perform autoplugging between the two given caps.
+ * Create a new autoplugfactory with the given parameters
  *
- * Returns: a list of elementfactories that can connect
- * the two caps
+ * Returns: a new #GstAutoplugFactory.
  */
-GList*
-gst_autoplug_caps (GstCaps *srccaps, GstCaps *sinkcaps)
+GstAutoplugFactory*
+gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GtkType type)
 {
-  caps_struct caps;
+  GstAutoplugFactory *factory;
+
+  g_return_val_if_fail(name != NULL, NULL);
 
-  caps.src = g_list_prepend (NULL,srccaps);
-  caps.sink = g_list_prepend (NULL,sinkcaps);
+  factory = g_new0(GstAutoplugFactory, 1);
 
-  GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
+  factory->name = g_strdup(name);
+  factory->longdesc = g_strdup (longdesc);
+  factory->type = type;
 
-  return gst_autoplug_func (caps.src, caps.sink,
-                           gst_autoplug_elementfactory_get_list,
-                           gst_autoplug_caps_find_cost,
-                           &caps);
+  _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory);
+
+  return factory;
 }
 
 /**
- * gst_autoplug_caps_list:
- * @srccaps: the source caps list
- * @sinkcaps: the sink caps list
- *
- * Perform autoplugging between the two given caps lists.
+ * gst_autoplugfactory_destroy:
+ * @autoplug: factory to destroy
  *
- * Returns: a list of elementfactories that can connect
- * the two caps lists
+ * Removes the autoplug from the global list.
  */
-GList*
-gst_autoplug_caps_list (GList *srccaps, GList *sinkcaps)
+void
+gst_autoplugfactory_destroy (GstAutoplugFactory *autoplug)
 {
-  caps_struct caps;
-
-  caps.src = srccaps;
-  caps.sink = sinkcaps;
+  g_return_if_fail (autoplug != NULL);
 
-  GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps list structures");
+  _gst_autoplugfactories = g_list_remove (_gst_autoplugfactories, autoplug);
 
-  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_pads:
- * @srcpad: the source pad
- * @sinkpad: the sink pad
+ * gst_autoplug_find:
+ * @name: name of autoplugger to find
  *
- * Perform autoplugging between the two given pads.
+ * Search for an autoplugger of the given name.
  *
- * Returns: a list of elementfactories that can connect
- * the two pads
+ * Returns: #GstAutoplug if found, NULL otherwise
  */
-GList*
-gst_autoplug_pads (GstPad *srcpad, GstPad *sinkpad)
+GstAutoplugFactory*
+gst_autoplugfactory_find (const gchar *name)
 {
-  caps_struct caps;
+  GList *walk;
+  GstAutoplugFactory *factory;
+
+  g_return_val_if_fail(name != NULL, NULL);
 
-  caps.src = gst_pad_get_caps_list(srcpad);
-  caps.sink = gst_pad_get_caps_list(sinkpad);
+  GST_DEBUG (0,"gstautoplug: find \"%s\"\n", name);
 
-  GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
+  walk = _gst_autoplugfactories;
+  while (walk) {
+    factory = (GstAutoplugFactory *)(walk->data);
+    if (!strcmp (name, factory->name))
+      return factory;
+    walk = g_list_next (walk);
+  }
 
-  return gst_autoplug_func (caps.src, caps.sink,
-                           gst_autoplug_elementfactory_get_list,
-                           gst_autoplug_caps_find_cost,
-                           &caps);
+  return NULL;
 }
-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;
+/**
+ * gst_autoplugfactory_get_list:
+ *
+ * Get the global list of elementfactories.
+ *
+ * Returns: GList of type #GstElementFactory
+ */
+GList*
+gst_autoplugfactory_get_list (void)
+{
+  return _gst_autoplugfactories;
 }
 
-static GList*
-construct_path (gst_autoplug_node *rgnNodes, gpointer factory)
+GstAutoplug*
+gst_autoplugfactory_create (GstAutoplugFactory *factory)
 {
-  GstElementFactory *current;
-  GList *factories = NULL;
+  GstAutoplug *new = NULL;
 
-  current = rgnNodes[find_factory(rgnNodes, factory)].iPrev;
+  g_return_val_if_fail (factory != NULL, NULL);
 
-  GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factories found in autoplugging (reversed order)");
+  if (factory->type == 0){
+    factory = gst_plugin_load_autoplugfactory (factory->name);
+  }
+  g_return_val_if_fail (factory != NULL, NULL);
+  g_return_val_if_fail (factory->type != 0, NULL);
 
-  while (current != NULL)
-  {
-    gpointer next = NULL;
+  new = GST_AUTOPLUG (gtk_type_new (factory->type));
 
-    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;
+  return new;
 }
 
-static GList*
-gst_autoplug_enqueue (GList *queue, gpointer iNode, gint iDist, gpointer iPrev)
+GstAutoplug*
+gst_autoplugfactory_make (const gchar *name)
 {
-  gst_autoplug_node *node = g_malloc (sizeof (gst_autoplug_node));
+  GstAutoplugFactory *factory;
+
+  g_return_val_if_fail (name != NULL, NULL);
 
-  node->iNode = iNode;
-  node->iDist = iDist;
-  node->iPrev = iPrev;
+  factory = gst_autoplugfactory_find (name);
 
-  queue = g_list_append (queue, node);
+  if (factory == NULL)
+    return NULL;
 
-  return queue;
+  return gst_autoplugfactory_create (factory);;
 }
 
-static GList*
-gst_autoplug_dequeue (GList *queue, gpointer *iNode, gint *iDist, gpointer *iPrev)
+xmlNodePtr
+gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent)
 {
-  GList *head;
-  gst_autoplug_node *node;
+  g_return_val_if_fail(factory != NULL, NULL);
 
-  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);
-  }
+  xmlNewChild(parent,NULL,"name",factory->name);
+  xmlNewChild(parent,NULL,"longdesc", factory->longdesc);
 
-  return head;
+  return parent;
 }
 
-static GList*
-gst_autoplug_func (gpointer src, gpointer sink,
-                  GstAutoplugListFunction list_function,
-                  GstAutoplugCostFunction cost_function,
-                  gpointer data)
+GstAutoplugFactory*
+gst_autoplugfactory_load_thyself (xmlNodePtr parent)
 {
-  gst_autoplug_node *rgnNodes;
-  GList *queue = NULL;
-  gpointer iNode, iPrev;
-  gint iDist, i, iCost;
+  GstAutoplugFactory *factory = g_new0(GstAutoplugFactory, 1);
+  xmlNodePtr children = parent->xmlChildrenNode;
 
-  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;
+  while (children) {
+    if (!strcmp(children->name, "name")) {
+      factory->name = xmlNodeGetContent(children);
     }
-    else {
-      rgnNodes[i].iDist = GST_AUTOPLUG_MAX_COST;
+    if (!strcmp(children->name, "longdesc")) {
+      factory->longdesc = xmlNodeGetContent(children);
     }
-
-    factories = g_list_next (factories);
+    children = children->next;
   }
-  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);
-    }
-  }
+  _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory);
 
-  return construct_path (rgnNodes, sink);
+  return factory;
 }
 
index c646c24d6172455b2d7d3811155f46841c6de781..14d96d55d32a6e92f5191d087bb96da7cb85c0c3 100644 (file)
@@ -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);
+};
+
+typedef struct _GstAutoplugFactory GstAutoplugFactory;
+
+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);
+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);
 
-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);
+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__ */
 
index d33078b0232ac5b673c53b2e96ad5bcfcfa6737e..dc0331e07e864e8e86795fac1999f2835767e314 100644 (file)
@@ -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);
     }
index f8bfcb3e66b4664852c103bc10565f22cb617ad5..ebdaccc301ffe154ad7df16ef4dcddc04b274abd 100644 (file)
@@ -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);
index 99634d462ba6529272b528e4c5528fb216b6fcc6..dffa1cd3d572a9a0900c181b054e8a7a9acfe88b 100644 (file)
@@ -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__ */
index ef1c1b98a25ae5599a4e9e9c92b057fe3fb95804..e8dc9ce5f6d9a325bdbf7ac866ab97d5c25fc2e1 100644 (file)
@@ -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;
index a88e216942d29165f7a1f9297943d01725c7ba5c..655d18fafe93d65289653efff973f54923ca73bb 100644 (file)
@@ -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;
index 6e31a0d6e29aacfe2f3eda88a922a9d18f6eedee..eced12ed3e38ecc2ec1f8c7542cd1b4cb7859520 100644 (file)
@@ -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);
index fe80744e27550ce04cd446507dcd8c650d5dad1a..c26744f8e0efc9838014bc7709ae90d9c73ea7e6 100644 (file)
@@ -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 {
index 6946810faba89e2d4835405c818457fc4a4d3f46..e613addae3517baf8f0236971bd0b015c6364e3b 100644 (file)
@@ -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);
index 8e1ed43cffabbdab47143e571a9c54b46506b429..ef21617fdd8e701c7874638a68a5e5d1de93716a 100644 (file)
@@ -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);
index 065de192b2e6d53f50ca8ad11a337897e81d250a..f42d82bd2b4ee4f891259557eea830346ad7b807 100644 (file)
 #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) 
-{
-  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) 
+static void
+gst_pipeline_prepare (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; i<numsinks; i++) {
-      if (!factories[i] || (factory != (GstElementFactory *)(factories[i]->data))) {
-       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_DEBUG (0,"GstPipeline: preparing pipeline \"%s\" for playing\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));
index 5ab0afe10123f2e91c521b9c4f1c493a89423515..3c13978e6368a6db525f86ca9061d0431876331c 100644 (file)
@@ -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))
-
-void           gst_pipeline_add_src            (GstPipeline *pipeline, GstElement *src);
-void           gst_pipeline_add_sink           (GstPipeline *pipeline, GstElement *sink);
-
-gboolean       gst_pipeline_autoplug           (GstPipeline *pipeline);
+#define                gst_pipeline_destroy(pipeline)  gst_object_destroy(GST_OBJECT(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__ */
 
index bea40e7cb01e2430fd9394f266c0f53696d8e4d2..557232a27c8a83a8c1dcc0f846a99e083e855f89 100644 (file)
@@ -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;
+}
index c171ada41bffdaaafc8f543e93fe542c6dc5a24c..299d10edc15bb167c43e3d719cc779873fe38d24 100644 (file)
 
 #include <gst/gsttype.h>
 #include <gst/gstelement.h>
+#include <gst/gstautoplug.h>
 
 
-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__ */
index a3e688b26f0a119bc600d33f7b5390b97d13de0a..d3ca3cf8b0bea63d912a8b99c696170d1f968300 100644 (file)
@@ -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;
       }
index 7a5e767f8726155af6413b301322a56e0ab17b6c..ca269b0032b3cfff1f364825a5c3bc0ab7282c12 100644 (file)
@@ -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)));
index 84090e74d39b782bda1553039e216e17a049f844..437da194df2e3f1b62cbe7dec2ae677df33737e5 100644 (file)
@@ -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);
index 2e2ef0a129d64a1fe6d8f307a4ff267a2c65aa13..68ab8ce6863fd3965af136424bbd02a6e42877c9 100644 (file)
@@ -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__ */
index 8f8489d681f5a16e24a0df8574ae7fa0533022a6..279a2fe7665b00159cf38822182aa808049b2325 100644 (file)
@@ -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;
index 86aa6261b554ea871e390e74f30a2c8f44ba3af1..f0b7459dce20e5b58f229273e6b38ec55d718bc4 100644 (file)
@@ -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);
+  }
+}
+
+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;
 }
 
-GstPlayReturn 
-gst_play_set_uri (GstPlay *play, 
-                 const guchar *uri) 
+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) {
-  }
+  priv = (GstPlayPrivate *)play->priv;
 
-  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->bin), new_element);
+
+  gst_element_connect (priv->src, "src", new_element, "sink");
 
-  gst_bin_add (GST_BIN (priv->thread), priv->pipeline);
+  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;
index 7452a78826a6c5a82ff910b8e9454e6389fec17e..fcaebf2f181737c1afe71959479f5f3c5ec87595 100644 (file)
@@ -31,6 +31,7 @@ typedef enum {
 typedef enum {
   GST_PLAY_OK,
   GST_PLAY_UNKNOWN_MEDIA,
+  GST_PLAY_CANNOT_PLAY,
   GST_PLAY_ERROR,
 } GstPlayReturn;
 
index 66b7b4dd9c4f1b1786244c2bfbcac3c1f83b58e3..31e4e17f10e335b8e331a8dab3e450c95f39f841 100644 (file)
@@ -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;
index 9eebbd4bf64c67f8b873f379ea91018eded1249e..9e81eb9b739796d65997eebcd44da29bf0c3665b 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wtay@chello.be>
  *
- * 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;
     }
   }
index 193592ac851950c97ef74ff3b253fe7cc6296500..62b5a9288f4fdf84420b7597647f1a159523b0f2 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wtay@chello.be>
  *
- * 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;
index d49bdad0ebb646aa63efb0e9ab4259c8574a501e..641f4b42543e38d7a60cadf5db7f283d672fb28e 100644 (file)
@@ -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);
index 8d0cd0b737e416d6f9eafed3ad4b3689d218d181..fc4f7a1ff4eb75a723c6653ee78e0cb6039596bc 100644 (file)
@@ -6,7 +6,7 @@ Makefile.in
 .deps
 .libs
 *.xml
-
+*.gst
 init
 loadall
 simplefake
@@ -24,3 +24,5 @@ markup
 load
 padfactory
 tee
+autoplug2
+autoplug3
index f116e177bf451bdcc9383bf2ef3615ce09ffa332..1d8292367192eb5843f871c76b740b4f8702d156 100644 (file)
@@ -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)
index f6dcb1be392755a625a175122e230e3c0e463699..87913c6f4fd71850ff8d2ca4b6c00b7f06ea0a6a 100644 (file)
@@ -1,63 +1,45 @@
 #include <gst/gst.h>
 
-static GList* 
-autoplug_caps (gchar *mime1, gchar *mime2) 
+static void
+new_object_added (GstAutoplug *autoplug, GstObject *object)
 {
-  GstCaps *caps1, *caps2;
-
-  caps1 = gst_caps_new ("tescaps1", mime1);
-  caps2 = gst_caps_new ("tescaps2", mime2);
-
-  return gst_autoplug_caps (caps1, caps2);
+  g_print ("added new object \"%s\"\n", gst_object_get_name (object));
 }
 
-static void
-dump_factories (GList *factories) 
+int
+main (int argc, char *argv[])
 {
-  g_print ("dumping factories\n");
+  GstElement *element;
+  GstElement *videosink, *audiosink;
+  GstAutoplug *autoplugger;
+  GList *testcaps;
 
-  while (factories) {
-    GstElementFactory *factory = (GstElementFactory *)factories->data;
+  gst_init(&argc,&argv);
 
-    g_print ("factory: \"%s\"\n", factory->name);
+  audiosink = gst_elementfactory_make ("audiosink", "audiosink");
+  g_assert (audiosink != NULL);
+  videosink = gst_elementfactory_make ("videosink", "videosink");
+  g_assert (videosink != NULL);
 
-    factories = g_list_next (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)));
 
-int main(int argc,char *argv[]) 
-{
-  GList *factories;
+  autoplugger = gst_autoplugfactory_make ("static");
 
-  gst_init(&argc,&argv);
+  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);
 
-  factories = autoplug_caps ("audio/mp3", "audio/raw");
-  dump_factories (factories);
-
-  factories = autoplug_caps ("video/mpeg", "audio/raw");
-  dump_factories (factories);
-
-  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);
-
-  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);
+  xmlDocDump (stdout, gst_xml_write (element));
 
   exit (0);
 }
diff --git a/tests/autoplug2.c b/tests/autoplug2.c
new file mode 100644 (file)
index 0000000..64f0a9f
--- /dev/null
@@ -0,0 +1,78 @@
+#include <gst/gst.h>
+
+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 (file)
index 0000000..d63726d
--- /dev/null
@@ -0,0 +1,102 @@
+#include <gst/gst.h>
+
+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);
+}
index 4a3453552cc83e2927768032614d4294ed28d4bc..4e37b5d999cc27cb55d2af431af0faa937933983 100644 (file)
@@ -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)));
 
index 90de5139d535787eab1897008a55c10188396d4b..8b70518edae5e69b46a248a8983862737655ec50 100644 (file)
@@ -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);
index a3662b14e608473ee2a42699efc0e8ff0b8176bf..706acc073fbb12560318901b09bdf1873010464e 100644 (file)
@@ -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);
 
index 533c38a6f7f94febf539cbd33e14510598dd2e5b..b8bc00e1de4024b89dc0ade11649b72fe67bd5c4 100644 (file)
@@ -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);
 
index a95392e9cba982742e74190c33e141294753eaf4..f8d4ac37031e37949a39b5f9c5139d29725fcde7 100644 (file)
@@ -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 {