| COMPLETELY OUTDATED |
| ------------------- |
| |
| |
| 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. |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |