| <chapter id="cha-factories"> |
| <title>More on factories</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 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> |
| 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 */ |
| decoder = gst_elementfactory_make ("mad", "decoder"); |
| ... |
| </programlisting> |
| |
| <para> |
| While this mechanism is quite effective it also has some big problems: |
| The elements are created based on their name. Indeed, we create an |
| element mad by explicitly stating the mad element's name. |
| Our little program therefore always uses the mad 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 and capabilities |
| added to the source and sink pads. |
| </para> |
| </sect1> |
| |
| <sect1> |
| <title>More on 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 denote 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> |
| As we have seen in the previous chapter, the MIME types are added |
| to the Capability structure of a pad. |
| </para> |
| |
| <para> |
| In our helloworld example the elements we constructed would have the |
| following MIME types associated with their source and sink pads: |
| </para> |
| <figure float="1" id="sec-mime-img"> |
| <title>The Hello world pipeline with MIME types</title> |
| <mediaobject> |
| <imageobject> |
| <imagedata fileref="images/mime-world.&magic;" format="&magic;" /> |
| </imageobject> |
| </mediaobject> |
| |
| </figure> |
| <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. |
| 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, but the use of typefind |
| functions (similar to file(1)) is preferred.. |
| </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 GstCaps (*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 */ |
| }; |
| </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> |
| <para> |
| For more information, see <xref linkend="cha-autoplug"/>. |
| </para> |
| </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> |