mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-16 13:26:36 +00:00
319 lines
9.3 KiB
Text
319 lines
9.3 KiB
Text
|
<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>
|