More on factories
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 what they are called.
We will first explain the concepts involved before we move on
to the reworked helloworld example using autoplugging.
The problems with the helloworld example
If we take a look at how the elements were created in the previous
example we used a rather crude mechanism:
...
/* now it's time to get the parser */
decoder = gst_element_factory_make ("mad", "decoder");
...
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 three other MP3 decoders in the
system. We will see how we can use a more general way to create an
MP3 decoder element.
We have to introduce the concept of MIME types and capabilities
added to the source and sink pads.
More on MIME Types
GStreamer uses MIME types to identify 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.
A MIME (Multipurpose Internet Mail Extension) type is a pair of
strings that denote a certain type of data. Examples include:
audio/x-raw-int : raw audio samples
audio/mpeg : MPEG audio
video/mpeg : MPEG video
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.
As we have seen in the previous chapter, MIME types are added
to the Capability structure of a pad.
shows the MIME types associated with
each pad from the "hello world" example.
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.
The typing of the source and sink pads also makes it possible to
'autoplug' a pipeline. We will have the ability to say: "construct
a pipeline that does an audio/mpeg to audio/x-raw-int conversion".
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.
GStreamer types
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.
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.
The type information is maintained in a list of
GstType. The definition of a
GstType is like:
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 */
};
All operations on GstType occur
via their guint16 id numbers, with
the GstType structure private to the GStreamer
library.
MIME type to id conversion
We can obtain the id for a given MIME type
with the following piece of code:
guint16 id;
id = gst_type_find_by_mime ("audio/mpeg");
This function will return 0 if the type was not known.
id to GstType conversion
We can obtain the GstType for a given id
with the following piece of code:
GstType *type;
type = gst_type_find_by_id (id);
This function will return NULL if the id was not associated with
any known GstTypeextension to id conversion
We can obtain the id for a given file extension
with the following piece of code:
guint16 id;
id = gst_type_find_by_ext (".mp3");
This function will return 0 if the extension was not known.
For more information, see .
Creating elements with the factory
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:
GstElementFactory *factory;
GstElement *element;
// obtain the factory
factory = ...
element = gst_element_factory_create (factory, "name");
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.
GStreamer basic types
GStreamer only has two builtin types:
audio/raw : raw audio samples
video/raw and image/raw : raw video data
All other MIME types are maintained by the plugin elements.