| <chapter id="chapter-bins"> |
| <title>Bins</title> |
| <para> |
| A bin is a container element. You can add elements to a bin. Since a |
| bin is an element itself, a bin can be handled in the same way as any |
| other element. Therefore, the whole previous chapter (<xref |
| linkend="chapter-elements"/>) applies to bins as well. |
| </para> |
| |
| <sect1 id="section-bins"> |
| <title>What are bins</title> |
| <para> |
| Bins allow you to combine a group of linked 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 |
| perform state changes on the elements as well as collect and |
| forward bus messages. |
| </para> |
| |
| <figure float="1" id="section-bin-img"> |
| <title>Visualisation of a bin with some elements in it</title> |
| <mediaobject> |
| <imageobject> |
| <imagedata scale="75" fileref="images/bin-element.ℑ" format="&IMAGE;"/> |
| </imageobject> |
| </mediaobject> |
| </figure> |
| |
| <para> |
| There is one specialized type of bin available to the |
| &GStreamer; programmer: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| A pipeline: a generic container that manages the synchronization |
| and bus messages of the contained elements. The toplevel bin has |
| to be a pipeline, every application thus needs at least one of |
| these. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </sect1> |
| |
| <sect1 id="section-bin-create"> |
| <title>Creating a bin</title> |
| <para> |
| Bins are created in the same way that other elements are created, |
| i.e. using an element factory. There are also convenience functions |
| available (<function>gst_bin_new ()</function> and |
| <function>gst_pipeline_new ()</function>). |
| To add elements to a bin or remove elements from a |
| bin, you can use <function>gst_bin_add ()</function> and |
| <function>gst_bin_remove ()</function>. Note that the bin that you |
| add an element to will take ownership of that element. If you |
| destroy the bin, the element will be dereferenced with it. If you |
| remove an element from a bin, it will be dereferenced automatically. |
| </para> |
| <programlisting><!-- example-begin bin.c a --> |
| #include <gst/gst.h> |
| |
| int |
| main (int argc, |
| char *argv[]) |
| { |
| GstElement *bin, *pipeline, *source, *sink; |
| |
| /* init */ |
| gst_init (&argc, &argv); |
| |
| /* create */ |
| pipeline = gst_pipeline_new ("my_pipeline"); |
| bin = gst_bin_new ("my_bin"); |
| source = gst_element_factory_make ("fakesrc", "source"); |
| sink = gst_element_factory_make ("fakesink", "sink"); |
| |
| /* First add the elements to the bin */ |
| gst_bin_add_many (GST_BIN (bin), source, sink, NULL); |
| /* add the bin to the pipeline */ |
| gst_bin_add (GST_BIN (pipeline), bin); |
| |
| /* link the elements */ |
| gst_element_link (source, sink); |
| <!-- example-end bin.c a --> |
| [..]<!-- example-begin bin.c b --><!-- |
| return 0; |
| --><!-- example-end bin.c b --> |
| <!-- example-begin bin.c c --> |
| } |
| <!-- example-end bin.c c --></programlisting> |
| <para> |
| There are various functions to lookup elements in a bin. The most |
| commonly used are <function>gst_bin_get_by_name ()</function> and |
| <function>gst_bin_get_by_interface ()</function>. You can also |
| iterate over all elements that a bin contains using the function |
| <function>gst_bin_iterate_elements ()</function>. See the API references |
| of <ulink type="http" |
| url="&URLAPI;GstBin.html"><classname>GstBin</classname></ulink> |
| for details. |
| </para> |
| </sect1> |
| |
| <sect1 id="section-bin-custom"> |
| <title>Custom bins</title> |
| <para> |
| The application programmer can create custom bins packed with elements |
| to perform a specific task. This allows you, for example, to write |
| an Ogg/Vorbis decoder with just the following lines of code: |
| </para> |
| <programlisting> |
| int |
| main (int argc, |
| char *argv[]) |
| { |
| GstElement *player; |
| |
| /* init */ |
| gst_init (&argc, &argv); |
| |
| /* create player */ |
| player = gst_element_factory_make ("oggvorbisplayer", "player"); |
| |
| /* set the source audio file */ |
| g_object_set (player, "location", "helloworld.ogg", NULL); |
| |
| /* start playback */ |
| gst_element_set_state (GST_ELEMENT (player), GST_STATE_PLAYING); |
| [..] |
| } |
| </programlisting> |
| <para> |
| (This is a silly example of course, there already exists a much more |
| powerful and versatile custom bin like this: the playbin element.) |
| </para> |
| <para> |
| Custom bins can be created with a plugin or from the application. You |
| will find more information about creating custom bin in the <ulink |
| type="http" |
| url="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html">Plugin |
| Writers Guide</ulink>. |
| </para> |
| <para> |
| Examples of such custom bins are the playbin and uridecodebin elements from<ulink |
| type="http" |
| url="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/index.html"> |
| gst-plugins-base</ulink>. |
| </para> |
| </sect1> |
| <sect1 id="section-bin-state-change-handling"> |
| <title>Bins manage states of their children</title> |
| <para> |
| Bins manage the state of all elements contained in them. If you set |
| a bin (or a pipeline, which is a special top-level type of bin) to |
| a certain target state using <function>gst_element_set_state ()</function>, |
| it will make sure all elements contained within it will also be set |
| to this state. This means it's usually only necessary to set the state |
| of the top-level pipeline to start up the pipeline or shut it down. |
| </para> |
| <para> |
| The bin will perform the state changes on all its children from the |
| sink element to the source element. This ensures that the downstream |
| element is ready to receive data when the upstream element is brought |
| to PAUSED or PLAYING. Similarly when shutting down, the sink elements |
| will be set to READY or NULL first, which will cause the upstream |
| elements to receive a FLUSHING error and stop the streaming threads |
| before the elements are set to the READY or NULL state. |
| </para> |
| <para> |
| Note, however, that if elements are added to a bin or pipeline that's |
| already running, , e.g. from within a "pad-added" |
| signal callback, its state will not automatically be brought in line with |
| the current state or target state of the bin or pipeline it was added to. |
| Instead, you have to need to set it to the desired target state yourself |
| using <function>gst_element_set_state ()</function> or |
| <function>gst_element_sync_state_with_parent ()</function> when adding |
| elements to an already-running pipeline. |
| </para> |
| </sect1> |
| </chapter> |