diff --git a/docs/manual/advanced.sgml b/docs/manual/advanced.sgml new file mode 100644 index 0000000000..1c67a53e60 --- /dev/null +++ b/docs/manual/advanced.sgml @@ -0,0 +1,318 @@ +<chapter id="cha-advanced"> + <title>Threads</title> + <para> + The small application we created in the previous chapter used the + concept of a factory to create the elements. In this chapter we will + show you how to use the factory concepts. + </para> + + <sect1> + <title>The problems with the helloworld example</title> + <para> + If we take a look at how the elements were created in the previous + example we used a rather crude mechanism: + </para> + + <programlisting> + ... + /* now it's time to get the parser */ + parse = gst_elementfactory_make("mp3parse","parse"); + decoder = gst_elementfactory_make("mpg123","decoder"); + ... + </programlisting> + + <para> + While this mechanism is quite effective it also has one big problems: + The elements are created base on their name. Indeed, we create an + element mpg123 by explicitly stating the mpg123 elements name. + Our little program therefore always uses the mpg123 decoder element + to decode the MP3 audio stream, even if there are 3 other MP3 decoders + in the system. We will see how we can use a more general way to create + an MP3 decoder element. + </para> + <para> + We have to introduce the concept of MIME types added to the source and + sink pads. + </para> + </sect1> + + <sect1> + <title>MIME Types</title> + <para> + GStreamer uses MIME types to indentify the different types of data + that can be handled by the elements. They are the high level + mechanisms to make sure that everyone is talking about the right + kind of data. + </para> + <para> + A MIME (Multipurpose Internet Mail Extension) types are a set of + string that donote a certain type of data. examples include: + <itemizedlist> + <listitem> + <para> + audio/raw : raw audio samples + </para> + </listitem> + <listitem> + <para> + audio/mpeg : mpeg audio + </para> + </listitem> + <listitem> + <para> + video/mpeg : mpeg video + </para> + </listitem> + </itemizedlist> + </para> + <para> + An element must associate a MIME type to its source and sink pads + when it is loaded into the system. GStreamer knows about the + different elements and what type of data they expect and emit. + This allows for very dynamic and extensible element creation as we + will see. + </para> + + <para> + In our helloworld example the elements we constructed would have the + following MIME types associated with their source and sink pads: + </para> + <para> + We will see how you can create an element based on the MIME types + of its source and sink pads. This way the end-user will have the + ability to choose his/her favorite audio/mpeg decoder without + you even having to care about it. + </para> + <para> + The typing of the source and sink pads also makes it possible to + 'autoplug' a pipeline. We will have the ability to say: "construct + me a pipeline that does an audio/mpeg to audio/raw conversion". + </para> + <note> + <para> + The basic GStreamer library does not try to solve all of your + autoplug problems. It leaves the hard decisions to the application + programmer, where they belong. + </para> + </note> + + </sect1> + + <sect1> + <title>GStreamer types</title> + <para> + GStreamer assigns a unique number to all registered MIME types. It + also maintains a list of all elements that either uses this type + as a source or as a sink. GStreamer also keeps a reference to + a function that can be used to determine if a given buffer is of + the given MIME type. + </para> + <para> + There is also an association between a MIME type and a file + extension. + </para> + <para> + The type information is maintained in a list of + <classname>GstType</classname>. The definition of a + <classname>GstType</classname> is like: + </para> + <programlisting> +typedef gboolean (*GstTypeFindFunc) (GstBuffer *buf,gpointer *priv); + +typedef struct _GstType GstType; + +struct _GstType { + guint16 id; /* type id (assigned) */ + + gchar *mime; /* MIME type */ + gchar *exts; /* space-delimited list of extensions */ + + GstTypeFindFunc typefindfunc; /* typefind function */ + + GList *srcs; /* list of src objects for this type */ + GList *sinks; /* list of sink objects for type */ +}; + </programlisting> + <para> + All operations on <classname>GstType</classname> occur via their + <classname>guint16 id</classname> numbers, with <classname>GstType</classname> + structure private to the GStreamer library. + </para> + + <sect2> + <title>MIME type to id conversion</title> + + <para> + We can obtain the id for a given MIME type + with the following piece of code: + </para> + <programlisting> + guint16 id; + + id = gst_type_find_by_mime("audio/mpeg"); + </programlisting> + <para> + This function will return 0 if the type was not known. + </para> + </sect2> + + <sect2> + <title>id to <classname>GstType</classname> conversion</title> + <para> + We can obtain the <classname>GstType</classname> for a given id + with the following piece of code: + </para> + <programlisting> + GstType *type; + + type = gst_type_find_by_id(id); + </programlisting> + <para> + This function will return NULL if the id was associated with + any known <classname>GstType</classname> + </para> + </sect2> + + <sect2> + <title>extension to id conversion</title> + <para> + We can obtain the id for a given file extension + with the following piece of code: + </para> + <programlisting> + guint16 id; + + id = gst_type_find_by_ext(".mp3"); + </programlisting> + <para> + This function will return 0 if the extension was not known. + </para> + </sect2> + + <sect2> + <title>id to <classname>GstElementFactory</classname> conversion</title> + <para> + When we have obtained a given type id using one of the above methods, + we can obtain a list of all the elements that operate on this MIME + type or extension. + </para> + <para> + Obtain a list of all the elements that use this id as source with: + </para> + <programlisting> + GList *list; + + list = gst_type_gst_srcs(id); + </programlisting> + + <para> + Obtain a list of all the elements that use this id as sink with: + </para> + <programlisting> + GList *list; + + list = gst_type_gst_sinks(id); + </programlisting> + <para> + When you have a list of elements, you can simply take the first + element of the list to obtain an appropriate element. + </para> + <note> + <para> + As you can see, there might be a multitude of elements that + are able to operate on video/raw types. some might include: + <itemizedlist> + <listitem> + <para> + an MP3 audio encoder. + </para> + </listitem> + <listitem> + <para> + an audio sink. + </para> + </listitem> + <listitem> + <para> + an audio resampler. + </para> + </listitem> + <listitem> + <para> + a spectrum filter. + </para> + </listitem> + </itemizedlist> + Depending on the application, you might want to use a different + element. This is why GStreamer leaves that decision up to the + application programmer. + </para> + </note> + + </sect2> + + <sect2> + <title>id to id path detection</title> + <para> + You can obtain a <classname>GList</classname> of elements that + will transform the source id into the destination id. + </para> + <programlisting> + GList *list; + + list = gst_type_gst_sink_to_src(sourceid, sinkid); + </programlisting> + <para> + This piece of code will give you the elements needed to construct + a path from sourceid to sinkid. This function is mainly used in + autoplugging the pipeline. + </para> + </sect2> + </sect1> + + <sect1> + <title>creating elements with the factory</title> + <para> + In the previous section we described how you could obtain + an element factory using MIME types. One the factory has been + obtained, you can create an element using: + </para> + <programlisting> + GstElementFactory *factory; + GstElement *element; + + // obtain the factory + factory = ... + + element = gst_elementfactory_create(factory, "name"); + </programlisting> + <para> + This way, you do not have to create elements by name which + allows the end-user to select the elements he/she prefers for the + given MIME types. + </para> + </sect1> + + <sect1> + <title>GStreamer basic types</title> + <para> + GStreamer only has two builtin types: + </para> + <itemizedlist> + <listitem> + <para> + audio/raw : raw audio samples + </para> + </listitem> + <listitem> + <para> + video/raw and image/raw : raw video data + </para> + </listitem> + </itemizedlist> + <para> + All other MIME types are maintained by the plugin elements. + </para> + + </sect1> +</chapter> diff --git a/docs/manual/cothreads.sgml b/docs/manual/cothreads.sgml new file mode 100644 index 0000000000..2b0080bbdc --- /dev/null +++ b/docs/manual/cothreads.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-cothreads"> + <title>Cothreads</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/dynamic.sgml b/docs/manual/dynamic.sgml new file mode 100644 index 0000000000..b7b3fdc6cd --- /dev/null +++ b/docs/manual/dynamic.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-dynamic"> + <title>Dynamic pipelines</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/factories.sgml b/docs/manual/factories.sgml index d9423325c0..5b156e01fe 100644 --- a/docs/manual/factories.sgml +++ b/docs/manual/factories.sgml @@ -3,9 +3,14 @@ <para> The small application we created in the previous chapter used the concept of a factory to create the elements. In this chapter we will - show you how to use the factory concepts. + show you how to use the factory concepts to create elements based + on what they do instead of how they are called. </para> + <para> + We will first explain the concepts involved before we move on + to the reworked helloworld example using autoplugging. + </para> <sect1> <title>The problems with the helloworld example</title> <para> @@ -194,7 +199,7 @@ struct _GstType { </sect2> <sect2> - <title>id to <classname>GstElement</classname> conversion</title> + <title>id to <classname>GstElementFactory</classname> conversion</title> <para> When we have obtained a given type id using one of the above methods, we can obtain a list of all the elements that operate on this MIME @@ -254,7 +259,49 @@ struct _GstType { </note> </sect2> + + <sect2> + <title>id to id path detection</title> + <para> + You can obtain a <classname>GList</classname> of elements that + will transform the source id into the destination id. + </para> + <programlisting> + GList *list; + + list = gst_type_gst_sink_to_src(sourceid, sinkid); + </programlisting> + <para> + This piece of code will give you the elements needed to construct + a path from sourceid to sinkid. This function is mainly used in + autoplugging the pipeline. + </para> + </sect2> </sect1> + + <sect1> + <title>creating elements with the factory</title> + <para> + In the previous section we described how you could obtain + an element factory using MIME types. One the factory has been + obtained, you can create an element using: + </para> + <programlisting> + GstElementFactory *factory; + GstElement *element; + + // obtain the factory + factory = ... + + element = gst_elementfactory_create(factory, "name"); + </programlisting> + <para> + This way, you do not have to create elements by name which + allows the end-user to select the elements he/she prefers for the + given MIME types. + </para> + </sect1> + <sect1> <title>GStreamer basic types</title> <para> diff --git a/docs/manual/ghostpads.sgml b/docs/manual/ghostpads.sgml new file mode 100644 index 0000000000..276ab416d5 --- /dev/null +++ b/docs/manual/ghostpads.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-ghostpads"> + <title>Ghostpads</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/gstreamer-manual.sgml b/docs/manual/gstreamer-manual.sgml index c80881776c..eb7fb5d12b 100644 --- a/docs/manual/gstreamer-manual.sgml +++ b/docs/manual/gstreamer-manual.sgml @@ -11,8 +11,20 @@ <!ENTITY HELLOWORLD SYSTEM "helloworld.sgml"> <!ENTITY FACTORIES SYSTEM "factories.sgml"> -]> +<!ENTITY HELLOWORLD2 SYSTEM "helloworld2.sgml"> +<!ENTITY THREADS SYSTEM "threads.sgml"> +<!ENTITY QUEUES SYSTEM "queues.sgml"> +<!ENTITY COTHREADS SYSTEM "cothreads.sgml"> +<!ENTITY DYNAMIC SYSTEM "dynamic.sgml"> +<!ENTITY GHOSTPADS SYSTEM "ghostpads.sgml"> +<!ENTITY TYPEDETECTION SYSTEM "typedetection.sgml"> +<!ENTITY UTILITY SYSTEM "utility.sgml"> + +<!ENTITY XML SYSTEM "xml.sgml"> +<!ENTITY PLUGINS SYSTEM "plugins.sgml"> +<!ENTITY PROGRAMS SYSTEM "programs.sgml"> +]> <book id="GStreamer"> <bookinfo> @@ -110,6 +122,7 @@ &FACTORIES; + &HELLOWORLD2; </part> <!-- ############ Advanced GStreamer - part ############# --> @@ -118,10 +131,27 @@ <partintro> <para> - Wanna know more? + In this part we will cover the more advanced features of GStreamer. + With the basics you learned in the prevous part you should be + able to create a 'simple' pipeline. If you want more control over + the media types and the pipeline you should use the more + low-level features of GStreamer. </para> </partintro> + &THREADS; + + &QUEUES; + + &COTHREADS; + + &DYNAMIC; + + &GHOSTPADS; + + &TYPEDETECTION; + + &UTILITY; </part> <!-- ############ XML in GStreamer - part ############# --> @@ -130,10 +160,13 @@ <partintro> <para> - Just say how we use it... + GStreamer has the posibility to externalize the pipelines + you create using an XML format. You can load a previously + created pipeline by loading the XML file. </para> </partintro> + &XML; </part> <!-- ############ XML in GStreamer - part ############# --> @@ -142,10 +175,12 @@ <partintro> <para> - A lot of text will follow... + In this part we will describe how you create a new plugin + to be used in GStreamer. </para> </partintro> + &PLUGINS; </part> <!-- ############ Appendices - part ############# --> @@ -155,8 +190,12 @@ <partintro> <para> + GStreamer comes prepackaged with a few programs. </para> </partintro> + + &PROGRAMS; + </part> </book> diff --git a/docs/manual/helloworld2.sgml b/docs/manual/helloworld2.sgml new file mode 100644 index 0000000000..bc9db8e0ab --- /dev/null +++ b/docs/manual/helloworld2.sgml @@ -0,0 +1,182 @@ +<chapter id="cha-hello2"> + <title>Your second application</title> + <para> + In the previous chapter we created a first version of the helloworld + application. We then explained a better way of creating the elements + using factories identified by MIME types. + </para> + <para> + In this chapter we will introduce you to autoplugging. Using the MIME + types of the elements GStreamer can automatically create a pipeline + for you. + </para> + + <sect1> + <title>Autoplugging helloworld</title> + <para> + We will create a second version of the helloworld application using + autoplugging. Its source code is considerably more easy to write and + can also much more data types. + </para> + + <programlisting> + +#include <gst/gst.h> + +static gboolean playing; + +/* eos will be called when the src element has an end os stream */ +void eos(GstSrc *src) +{ + g_print("have eos, quitting\n"); + + playing = FALSE; +} + +int main(int argc,char *argv[]) +{ + GstElement *disksrc, *audiosink; + GstPipeline *pipeline; + + if (argc != 2) { + g_print("usage: %s <filename>\n", argv[0]); + exit(-1); + } + + gst_init(&argc,&argv); + gst_plugin_load_all(); + g_print("\n"); + + /* create a new bin to hold the elements */ + pipeline = gst_pipeline_new("pipeline"); + + /* create a disk reader */ + disksrc = gst_elementfactory_make("disksrc", "disk_source"); + gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL); + gtk_signal_connect(GTK_OBJECT(disksrc),"eos", + GTK_SIGNAL_FUNC(eos),NULL); + + /* and an audio sink */ + audiosink = gst_elementfactory_make("audiosink", "play_audio"); + + /* add objects to the main pipeline */ + gst_bin_add(GST_BIN(pipeline), disksrc); + gst_bin_add(GST_BIN(pipeline), audiosink); + + if (!gst_pipeline_autoplug(pipeline)) { + g_print("unable to handle stream\n"); + exit(-1); + } + + /* find out how to handle this bin */ + gst_bin_create_plan(GST_BIN(pipeline)); + + /* make it ready */ + gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_READY); + /* start playing */ + gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING); + + playing = TRUE; + + while (playing) { + gst_bin_iterate(GST_BIN(pipeline)); + } + + /* stop the bin */ + gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL); + + gst_pipeline_destroy(pipeline); + + exit(0); +} + + </programlisting> + + <para> + first of all, we do not use any mpg123 or mp3parse element in this example. + In fact, we only specify a source element and a sink element and add them + to a pipeline. + </para> + + <para> + The most interesting change however is the following: + </para> + <programlisting> + + ... + if (!gst_pipeline_autoplug(pipeline)) { + g_print("unable to handle stream\n"); + exit(-1); + } + ... + + </programlisting> + + <para> + This piece of code does all the magic. + </para> + + <para> + <itemizedlist> + <listitem> + <para> + The source and the sink elements will be found inside the pipeline + </para> + </listitem> + <listitem> + <para> + Since the source has no type, a typedetection will be started on + the source element. + </para> + </listitem> + <listitem> + <para> + The best set of elements that connect the MIME type of the source + element to the MIME type of the sink are found. + </para> + </listitem> + <listitem> + <para> + The elements are added to the pipeline and their pads are connected. + </para> + </listitem> + </itemizedlist> + </para> + + <para> + After this autoplugging, the pipeline is ready to play. Remember that this + pipeline will be able to playback all of the media types for which an + appropriate plugin exists since the autoplugging is all done using MIME + types. + </para> + + <para> + I you really want, you can use the GSteamer components to do the + autoplugging yourself. + </para> + + <para> + To compile the helloworld2 example, use: + </para> + <programlisting> + gcc -Wall `gstreamer-config --cflags` `gtk-config --cflags` helloworld2.c \ + -o helloworld2 `gstreamer-config --libs` `gtk-config --libs` + </programlisting> + <para> + You can run the example with (substitute helloworld.mp3 with you favorite MP3 file): + </para> + <programlisting> + ./helloworld2 helloworld.mp3 + </programlisting> + <para> + You can also try to use an AVI or MPEG file as its input. Using autoplugging, + GStreamer will automatically figure out how to handle the stream. Remember that + only the audio part will be played because we have only added an audiosink to + the pipeline. + </para> + <programlisting> + ./helloworld2 helloworld.mpeg + </programlisting> + + </sect1> +</chapter> diff --git a/docs/manual/outline.txt b/docs/manual/outline.txt index ee0aece6e7..def2e4720c 100644 --- a/docs/manual/outline.txt +++ b/docs/manual/outline.txt @@ -53,6 +53,8 @@ Building apps MIME types GStreamer types Basic types + Your second application + advanced concepts @@ -61,24 +63,27 @@ advanced concepts cothreads dynamic pipeline construction ghost pads - types type detection - plugin registry - bufferpools - Quality of service utility functions - XML in GStreamer (saving) (loading a pipeline) Plugin development + plugin types + chain based + loop based buffers metadata subbufers adding pads libraries + plugin registry + types + type detection + QoS messages + clocks GStreamer programs editor diff --git a/docs/manual/plugins.sgml b/docs/manual/plugins.sgml new file mode 100644 index 0000000000..00ffa18986 --- /dev/null +++ b/docs/manual/plugins.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-plugins"> + <title>Plugin development</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/programs.sgml b/docs/manual/programs.sgml new file mode 100644 index 0000000000..d2fcd39991 --- /dev/null +++ b/docs/manual/programs.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-programs"> + <title>Programs</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/queues.sgml b/docs/manual/queues.sgml new file mode 100644 index 0000000000..1a77d71aff --- /dev/null +++ b/docs/manual/queues.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-queues"> + <title>Queues</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/threads.sgml b/docs/manual/threads.sgml new file mode 100644 index 0000000000..cb6592dd9d --- /dev/null +++ b/docs/manual/threads.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-threads"> + <title>Threads</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/typedetection.sgml b/docs/manual/typedetection.sgml new file mode 100644 index 0000000000..1ec4f42794 --- /dev/null +++ b/docs/manual/typedetection.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-typedetection"> + <title>Typedetection</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/utility.sgml b/docs/manual/utility.sgml new file mode 100644 index 0000000000..aa3a0ee45e --- /dev/null +++ b/docs/manual/utility.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-utility"> + <title>Utility functions</title> + <para> + </para> + +</chapter> diff --git a/docs/manual/xml.sgml b/docs/manual/xml.sgml new file mode 100644 index 0000000000..5099bcd11b --- /dev/null +++ b/docs/manual/xml.sgml @@ -0,0 +1,6 @@ +<chapter id="cha-xml"> + <title>XML in GStreamer</title> + <para> + </para> + +</chapter> diff --git a/examples/helloworld2/helloworld2.c b/examples/helloworld2/helloworld2.c index 019998500c..e2a0ab7ef1 100644 --- a/examples/helloworld2/helloworld2.c +++ b/examples/helloworld2/helloworld2.c @@ -24,8 +24,6 @@ int main(int argc,char *argv[]) gst_plugin_load_all(); g_print("\n"); - gst_type_dump(); - /* create a new bin to hold the elements */ pipeline = gst_pipeline_new("pipeline"); diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c index 56bdd1ba39..104a500737 100644 --- a/gst/gstpipeline.c +++ b/gst/gstpipeline.c @@ -54,6 +54,7 @@ static GstElementStateReturn gst_pipeline_change_state(GstElement *element); static void gst_pipeline_prepare(GstPipeline *pipeline); static void gst_pipeline_have_type(GstSink *sink, GstSink *sink2, gpointer data); +static void gst_pipeline_pads_autoplug(GstElement *src, GstElement *sink); static GstBin *parent_class = NULL; //static guint gst_pipeline_signals[LAST_SIGNAL] = { 0 }; @@ -160,6 +161,66 @@ static guint16 gst_pipeline_typefind(GstPipeline *pipeline, GstElement *element) return type_id; } +static void gst_pipeline_pads_autoplug_func(GstElement *src, GstPad *pad, GstElement *sink) { + GList *sinkpads; + GstPad *sinkpad; + + g_print("gstpipeline: autoplug pad connect function type %d\n", pad->type); + + sinkpads = gst_element_get_pad_list(sink); + while (sinkpads) { + sinkpad = (GstPad *)sinkpads->data; + + // if we have a match, connect the pads + if (sinkpad->type == pad->type && sinkpad->direction == GST_PAD_SINK && !GST_PAD_CONNECTED(sinkpad)) { + gst_pad_connect(pad, sinkpad); + g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", pad->name, pad->type, gst_element_get_name(src)); + g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinkpad->type, gst_element_get_name(sink)); + break; + } + sinkpads = g_list_next(sinkpads); + } +} + +static void gst_pipeline_pads_autoplug(GstElement *src, GstElement *sink) { + GList *srcpads, *sinkpads; + gboolean connected = FALSE; + + srcpads = gst_element_get_pad_list(src); + + while (srcpads) { + GstPad *srcpad = (GstPad *)srcpads->data; + GstPad *sinkpad; + + if (srcpad->direction == GST_PAD_SRC && !GST_PAD_CONNECTED(srcpad)) { + + sinkpads = gst_element_get_pad_list(sink); + // FIXME could O(n) if the types were sorted... + while (sinkpads) { + sinkpad = (GstPad *)sinkpads->data; + + // if we have a match, connect the pads + if (sinkpad->type == srcpad->type && sinkpad->direction == GST_PAD_SINK && !GST_PAD_CONNECTED(sinkpad)) { + gst_pad_connect(srcpad, sinkpad); + g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", srcpad->name, srcpad->type, gst_element_get_name(src)); + g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinkpad->type, gst_element_get_name(sink)); + connected = TRUE; + goto end; + } + sinkpads = g_list_next(sinkpads); + } + } + srcpads = g_list_next(srcpads); + } + +end: + if (!connected) { + g_print("gstpipeline: delaying pad connections\n"); + gtk_signal_connect(GTK_OBJECT(src),"new_pad", + GTK_SIGNAL_FUNC(gst_pipeline_pads_autoplug_func), sink); + } +} + gboolean gst_pipeline_autoplug(GstPipeline *pipeline) { GList *elements; GstElement *element, *srcelement, *sinkelement; @@ -175,7 +236,7 @@ gboolean gst_pipeline_autoplug(GstPipeline *pipeline) { elements = gst_bin_get_list(GST_BIN(pipeline)); - // fase 1, find all the sinks and sources... + // fase 1, find all the sinks and sources... FIXME need better way to do this... while (elements) { element = GST_ELEMENT(elements->data); @@ -250,10 +311,7 @@ gboolean gst_pipeline_autoplug(GstPipeline *pipeline) { element = gst_elementfactory_create(factory, factory->name); gst_bin_add(GST_BIN(pipeline), element); - // FIXME match paths to connect with MIME types instead - // of names. - gst_pad_connect(gst_element_get_pad(srcelement,"src"), - gst_element_get_pad(element,"sink")); + gst_pipeline_pads_autoplug(srcelement, element); srcelement = element; @@ -263,8 +321,7 @@ gboolean gst_pipeline_autoplug(GstPipeline *pipeline) { } if (complete) { - gst_pad_connect(gst_element_get_pad(srcelement,"src"), - gst_element_get_pad(sinkelement,"sink")); + gst_pipeline_pads_autoplug(srcelement, sinkelement); return TRUE; } @@ -282,8 +339,6 @@ static GstElementStateReturn gst_pipeline_change_state(GstElement *element) { switch (GST_STATE_PENDING(pipeline)) { case GST_STATE_READY: // we need to set up internal state - g_print("preparing pipeline \"%s\" for iterations:\n", - gst_element_get_name(GST_ELEMENT(element))); gst_pipeline_prepare(pipeline); break; default: diff --git a/gst/gsttype.c b/gst/gsttype.c index a3aea32e62..29c1dbf782 100644 --- a/gst/gsttype.c +++ b/gst/gsttype.c @@ -33,6 +33,8 @@ GList *_gst_types; guint16 _gst_maxtype; +#define MAX_COST 999999 + struct _gst_type_node { int iNode; @@ -302,7 +304,7 @@ static GList *construct_path (gst_type_node *rgnNodes, gint chNode) GstType *type; GList *converters; - while (current != 999) + while (current != MAX_COST) { type = gst_type_find_by_id(current); converters = (GList *)g_hash_table_lookup(type->converters, GUINT_TO_POINTER(src)); @@ -322,7 +324,7 @@ static guint gst_type_find_cost(gint src, gint dest) { GList *converters = (GList *)g_hash_table_lookup(type->converters, GUINT_TO_POINTER(dest)); if (converters) return 1; - return 999; + return MAX_COST; } GList *gst_type_get_sink_to_src(guint16 sinkid, guint16 srcid) { @@ -339,13 +341,13 @@ GList *gst_type_get_sink_to_src(guint16 sinkid, guint16 srcid) { for (i=0; i< _gst_maxtype; i++) { rgnNodes[i].iNode = i; - rgnNodes[i].iDist = 999; - rgnNodes[i].iPrev = 999; + rgnNodes[i].iDist = MAX_COST; + rgnNodes[i].iPrev = MAX_COST; } rgnNodes[sinkid].iDist = 0; - rgnNodes[sinkid].iPrev = 999; + rgnNodes[sinkid].iPrev = MAX_COST; - queue = gst_type_enqueue(queue, sinkid, 0, 999); + queue = gst_type_enqueue(queue, sinkid, 0, MAX_COST); while (g_list_length(queue) > 0) { @@ -353,8 +355,8 @@ GList *gst_type_get_sink_to_src(guint16 sinkid, guint16 srcid) { for (i=0; i< _gst_maxtype; i++) { iCost = gst_type_find_cost(iNode, i); - if (iCost != 999) { - if((999 == rgnNodes[i].iDist) || + if (iCost != MAX_COST) { + if((MAX_COST == rgnNodes[i].iDist) || (rgnNodes[i].iDist > (iCost + iDist))) { rgnNodes[i].iDist = iDist + iCost; rgnNodes[i].iPrev = iNode; diff --git a/tests/old/examples/helloworld2/helloworld2.c b/tests/old/examples/helloworld2/helloworld2.c index 019998500c..e2a0ab7ef1 100644 --- a/tests/old/examples/helloworld2/helloworld2.c +++ b/tests/old/examples/helloworld2/helloworld2.c @@ -24,8 +24,6 @@ int main(int argc,char *argv[]) gst_plugin_load_all(); g_print("\n"); - gst_type_dump(); - /* create a new bin to hold the elements */ pipeline = gst_pipeline_new("pipeline");