Added explanation for current autoplugging
authorWim Taymans <wim.taymans@gmail.com>
Wed, 20 Dec 2000 00:55:45 +0000 (00:55 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 20 Dec 2000 00:55:45 +0000 (00:55 +0000)
Original commit message from CVS:
Added explanation for current autoplugging

docs/random/autoplug1 [new file with mode: 0644]

diff --git a/docs/random/autoplug1 b/docs/random/autoplug1
new file mode 100644 (file)
index 0000000..60446e2
--- /dev/null
@@ -0,0 +1,202 @@
+A little explanation of the first autoplugger in GStreamer:
+
+Autoplugging is implemented in the following places:
+
+ gstpipeline.c : construction of the pipeline
+ gstautoplug.c : selection of the elementfactories needed for autoplugging
+
+1) pipeline setup
+-----------------
+
+before any autoplugging will take place, a new GstPipeline has to be created.
+The autoplugger needs to have a src element and one or more sink elements. the
+autoplugger will try to find the elements needed to connect the src element
+to the sinks.
+
+using:
+
+  gst_pipeline_add_src (GstPipeline *pipeline, GstElement *element);
+
+a source element is added to the pipeline. only one src element can be added
+for now.
+
+using:
+
+  gst_pipeline_add_sink (GstPipeline *pipeline, GstElement *element);
+
+a sink element can be added to the pipeline.
+
+2) starting autoplug
+--------------------
+
+when the pipeline has been set up as above, you will call
+
+  gst_pipeline_autoplug (GstPipeline *pipeline);
+
+to start the autoplugger. this will be done in four phases
+
+ex. we are going to autoplug an mpeg1 system stream.
+
+2a) phase1: figure out the type (GstCaps) of the src element.
+-------------------------------------------------------------
+
+the gsttypefind element is connected to the "src" pad of the source
+element. gst_bin_iterate is called in a loop until gsttypefind
+signals "have_type". the gst_bin_iterate is stopped and the GstCaps
+is retrieved from the gsttypefind element.
+
+gsttypefind is disconnected from the src element and removed from the 
+bin.
+
+the GstCaps of the source element is called src_caps later on.
+
+ex. all typefind functions are tried and the one in mpeg1types will
+     return a GstCaps:
+
+        video/mpeg,
+       "systemstream", GST_PROPS_BOOLEAN (TRUE),
+       "mpegversion",  GST_PROPS_INT (1),
+       NULL
+
+
+2b) phase2: create lists of factories.
+---------------------------------------
+
+for each sink:
+{
+   sinkpad = take the first sinkpad of the sink (HACK)
+   call
+   
+   list[i] = gst_autoplug_caps (src_caps, sinkpad->caps);
+     
+   I++;
+}
+
+gst_autoplug_caps will figure out (based on the padtemplates)
+which elementfactories are needed to connect src_caps to sinkpad->caps
+and will return them in a list.
+
+ex. we have two sinks with following caps:
+
+        video/raw                    audio/raw
+       "...."                       "...."
+
+ gst_autoplug_caps will figure out that for the first sink the following
+ elements are needed:
+
+   mpeg1parse, mp1videoparse, mpeg_play
+
+ for the second sink the following is needed:
+
+   mpeg1parse, mp3parse, mpg123
+
+ We now have two lists of elementfactories.
+
+2c) phase3: collect common elements from the lists.
+---------------------------------------------------
+
+the rationale is that from the lists we have created in phase2, there
+must be some element that is a splitter and that it has to come first (HACK)
+We try to find that element by comparing the lists until an element differs.
+
+we add the common elements to the bin and run gst_pipeline_pads_autoplug. this
+function will loop over the pads of the previous element and the one we
+just added, and tries to connect src to sink if possible. 
+
+If a connection between the two elements could not be made, a signal "new_pad"
+is connected to the element so that pad connection can occur later on when
+the pad is actually created.
+
+ex. when we compare the two lists we see that we have common element: mpeg1parse.
+
+ we add this element to the bin and try to connect it to the previous element in
+ the bin, the disksrc.
+
+ we see that the src pad of the disksrc and the sinkpad of the mpeg1parse element
+ can be connected because they are compatible. We have a pipeline like:
+
+  ---------)         (--------
+   disksrc !         ! mpeg1parse
+           src --- sink
+  ---------)         (--------
+
+
+2d) phase4: add remaining elements
+----------------------------------
+
+now we loop over all the list and try to add the remaining elements
+
+(HACK) we always use a new thread for the elements when there is a common
+element found.
+
+if a new thread is needed (either bacuase the previous element is a common
+element or the object flag of the next element is set to GST_SUGGEST_THREAD)
+we add a queue to the bin and we add a new thread. We add the elements to
+the bin and connect them using gst_pipeline_pads_autoplug.
+
+If we add a queue, we have to copy the caps of the sink element of the queue
+to the src pad of the queue (else they won't connect)
+
+we finally arrive at the sink element and we're done.
+
+ex.
+    
+     we have just found our mpeg1parse common element, so we start a thread.
+     We add a queue to the bin and a new thread, we add the elements
+     mp1videoparse and mpeg_play to the thread. We arrive at the videosink, we
+     see that the SUGGEST_THREAD flag is set, we add a queue and a thread and
+     add the videosink in the thread.
+     the same procedure happens for the audio part. We are now left with the
+     following pipeline:
+
+     We will also have set a signal "new_pad" on the mpeg1parse element bacause
+     the element mp1videoparse could not be connected to the element just yet.
+
+                                                 (------------------------------------)         (----------
+                                                 !thread                              !         ! thread
+                                                 ! (-------------)       (---------)  !         ! (---------)
+                                                ! !mp1videoparse!       !mpeg_play!  !         ! !videosink!
+                                   videoqueue--sink             src -- sink      src -- queue --- sink     !
+  ---------)         (-----------)               ! (-------------)       (---------)  !         ! (---------)
+   disksrc !         ! mpeg1parse!               (------------------------------------)         (-------------
+           src --- sink          !
+  ---------)         (-----------)    
+                                      queue-----  same for audio
+
+
+   then we play, create_plan happens, data is flowing and the "new_pad" signal is called
+   from mpeg1parse, gst_pipeline_pad_autoplug is called and the connection between
+   mpeg1parse and the videoqueue is made. same for audio.
+
+   voila. smame procedure for mp3/vorbis/avi/qt/mpeg2 etc...
+
+
+Problems:
+---------
+
+this is obviously a very naive solution. the creation of the elements actually happens
+beforehand. MPEG2, for one, fails bacause there are multiple possibilities to go
+from the mpeg demuxer to audio/raw (ac3, mp3)
+
+Also any intermedia elements like mixers (subtitles) are not possible because we 
+assume that after the common elements, the streams to not converge anymore.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+