| <chapter id="cha-bins"> |
| <title>Bins</title> |
| <para> |
| A Bin is a container element. You can add elements to a bin. Since a bin is |
| an <classname>GstElement</classname> itself, it can also be added to another bin. |
| </para> |
| <para> |
| Bins allow you to combine connected elements into one logical element. You do |
| not deal with the individual elements anymore but with just one element, the bin. |
| We will see that this is extremely powerful when you are going to construct |
| complex pipelines since it allows you to break up the pipeline in smaller chunks. |
| </para> |
| <para> |
| The bin will also manage the elements contained in it. It will figure out how |
| the data will flow in the bin and generate an optimal plan for that data flow. Plan |
| generation is one of the most complicated procedures in GStreamer. |
| </para> |
| |
| <figure float="1" id="sec-bin-img"> |
| <title>Visualisation of a <classname>GstBin</classname> element with some elements in it</title> |
| <mediaobject> |
| <imageobject> |
| <imagedata fileref="images/bin-element.&magic;" format="&magic;" /> |
| </imageobject> |
| </mediaobject> |
| </figure> |
| |
| <para> |
| There are two standard bins available to the GStreamer programmer: |
| |
| <itemizedlist> |
| <listitem> |
| <para> |
| A pipeline (<classname>GstPipeline</classname>). Which is a generic container you will |
| use most of the time. The toplevel bin has to be a pipeline. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| A thread (<classname>GstThread</classname>). The plan for the |
| <classname>GstThread</classname> will be run in a separate thread. You will have to use |
| this bin if you have to carefully synchronize audio and video, for example. You will learn |
| more about threads in <xref linkend="cha-threads"/>. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </para> |
| |
| <sect1 id="sec-bin-create"> |
| <title>Creating a bin</title> |
| <para> |
| Bins register themselves in the GStreamer registry, so they can be created in the normal way: |
| </para> |
| <programlisting> |
| GstElement *bin, *thread, *pipeline; |
| |
| /* create a new bin called 'mybin'. this bin will be only for organizational purposes; a normal |
| GstBin doesn't affect plan generation */ |
| bin = gst_elementfactory_make ("bin", "mybin"); |
| |
| /* create a new thread, and give it a unique name */ |
| thread = gst_elementfactory_make ("thread", NULL); |
| |
| /* the core bins (GstBin, GstThread, GstPipeline) also have convenience APIs, |
| gst_<bintype>_new (). these are equivalent to the gst_elementfactory_make () syntax. */ |
| pipeline = gst_pipeline_new ("pipeline_name"); |
| </programlisting> |
| </sect1> |
| |
| <sect1 id="sec-bin-adding"> |
| <title>Adding elements to a bin</title> |
| <para> |
| Elements are added to a bin with the following code sample: |
| </para> |
| <programlisting> |
| GstElement *element; |
| GstElement *bin; |
| |
| bin = gst_bin_new ("mybin"); |
| |
| element = gst_elementfactory_make ("mpg123", "decoder"); |
| gst_bin_add (GST_BIN (bin), element); |
| ... |
| </programlisting> |
| <para> |
| Bins and threads can be added to other bins too. This allows you to create nested bins. Note |
| that it doesn't make very much sense to add a <classname>GstPipeline</classname> to anything, |
| as it's a toplevel bin that needs to be explicitly iterated. |
| </para> |
| <para> |
| To get an element from the bin you can use: |
| </para> |
| <programlisting> |
| GstElement *element; |
| |
| element = gst_bin_get_by_name (GST_BIN (bin), "decoder"); |
| ... |
| </programlisting> |
| <para> |
| You can see that the name of the element becomes very handy for retrieving the |
| element from an bin by using the element's name. gst_bin_get_by_name () will |
| recursively search nested bins. |
| </para> |
| <para> |
| To get a list of elements in a bin, use: |
| </para> |
| <programlisting> |
| GList *elements; |
| |
| elements = gst_bin_get_list (GST_BIN (bin)); |
| |
| while (elements) { |
| GstElement *element = GST_ELEMENT (elements->data); |
| |
| g_print ("element in bin: %s\n", GST_OBJECT_NAME (GST_OBJECT (element))); |
| |
| elements = g_list_next (elements); |
| } |
| ... |
| </programlisting> |
| <para> |
| To remove an element from a bin use: |
| </para> |
| <programlisting> |
| GstElement *element; |
| |
| gst_bin_remove (GST_BIN (bin), element); |
| ... |
| </programlisting> |
| <para> |
| To add many elements to a bin at the same time, try the gst_bin_add_many () API. Remember to |
| pass NULL as the last argument. |
| </para> |
| <programlisting> |
| GstElement *filesrc, *decoder, *audiosink; |
| GstBin *bin; |
| |
| /* instantiate the elements and the bins... */ |
| |
| gst_bin_add_many (bin, filesrc, decoder, audiosink, NULL); |
| </programlisting> |
| </sect1> |
| |
| <sect1 id="sec-bin-custom"> |
| <title>Custom bins</title> |
| <para> |
| The application programmer can create custom bins packed with elements to perform a |
| specific task. This allow you to write an MPEG audio decoder with just the follwing lines |
| of code: |
| </para> |
| <programlisting> |
| |
| /* create the mp3player element */ |
| GstElement *mp3player = gst_elementfactory_make ("mp3player", "mp3player"); |
| /* set the source mp3 audio file */ |
| g_object_set (G_OBJECT (mp3player), "location", "helloworld.mp3", NULL); |
| /* start playback */ |
| gst_element_set_state (GST_ELEMENT (mp3player), GST_STATE_PLAYING); |
| ... |
| /* pause playback */ |
| gst_element_set_state (GST_ELEMENT (mp3player), GST_STATE_PAUSED); |
| ... |
| /* stop */ |
| gst_element_set_state (GST_ELEMENT (mp3player), GST_STATE_NULL); |
| </programlisting> |
| <para> |
| Note that the above code assumes that the mp3player bin derives itself from a |
| <classname>GstThread</classname>, which begins to play as soon as its state is set to PLAYING. |
| Other bin types may need explicit iteration. For more information, see <xref |
| linkend="cha-threads"/>. |
| |
| Custom bins can be created with a plugin or an XML description. You will find more |
| information about creating custom bin in the Plugin Writers Guide (FIXME ref). |
| </para> |
| </sect1> |
| |
| <sect1 id="sec-bin-ghostpads"> |
| <title>Ghost pads</title> |
| <para> |
| You can see from figure <xref linkend="sec-bin-noghost-img"/> how a bin has no pads of its own. |
| This is where "ghost pads" come into play. |
| </para> |
| <figure float="1" id="sec-bin-noghost-img"> |
| <title>Visualisation of a <classname>GstBin</classname> element without ghost pads</title> |
| <mediaobject> |
| <imageobject> |
| <imagedata fileref="images/bin-element-noghost.&magic;" format="&magic;" /> |
| </imageobject> |
| </mediaobject> |
| </figure> |
| <para> |
| A ghost pad is a pad from some element in the bin that has been promoted to the bin. |
| This way, the bin also has a pad. The bin becomes just another element with a pad and |
| you can then use the bin just like any other element. This is a very important feature |
| for creating custom bins. |
| </para> |
| |
| <figure float="1" id="sec-bin-ghost-img"> |
| <title>Visualisation of a <classname>GstBin</classname> element with a ghost pad</title> |
| <mediaobject> |
| <imageobject> |
| <imagedata fileref="images/bin-element-ghost.&magic;" format="&magic;" /> |
| </imageobject> |
| </mediaobject> |
| </figure> |
| <para> |
| Above is a representation of a ghost pad. The sink pad of element one is now also a pad |
| of the bin. |
| </para> |
| <para> |
| Ghost pads can actually be added to all <classname>GstElement</classname>s and not just |
| <classname>GstBin</classname>s. Use the following code example to add a ghost pad to a bin: |
| </para> |
| <programlisting> |
| GstElement *bin; |
| GstElement *element; |
| |
| element = gst_elementfactory_create ("mad", "decoder"); |
| bin = gst_bin_new ("mybin"); |
| |
| gst_bin_add (GST_BIN (bin), element); |
| |
| gst_element_add_ghost_pad (bin, gst_element_get_pad (element, "sink"), "sink"); |
| |
| </programlisting> |
| <para> |
| In the above example, the bin now also has a pad: the pad called 'sink' of the |
| given element. We can now, for example, connect the srcpad of a filesrc to the |
| bin with: |
| </para> |
| <programlisting> |
| GstElement *filesrc; |
| |
| filesrc = gst_elementfactory_create ("filesrc", "disk_reader"); |
| |
| gst_element_connect_pads (filesrc, "src", bin, "sink"); |
| ... |
| </programlisting> |
| </sect1> |
| |
| </chapter> |