reorganizing manual so that concepts are explained before code is shown.

Original commit message from CVS:
reorganizing manual so that concepts are explained before code is shown.
needs some proofreading, will get to it.
This commit is contained in:
Thomas Vander Stichele 2003-12-29 14:15:02 +00:00
parent 1b407ae8d4
commit abe422b141
20 changed files with 958 additions and 1461 deletions

View file

@ -46,203 +46,4 @@
</listitem>
</itemizedlist>
</para>
<sect1 id="sec-bin-create">
<title>Creating a bin</title>
<para>
Bins are created in the same way that other elements are created. ie.
using an element factory, or any of the associated convenience functions:
</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_element_factory_make ("bin", "mybin");
/* create a new thread, and give it a unique name */
thread = gst_element_factory_make ("thread", NULL);
/* the core bins (GstBin, GstThread, GstPipeline) also have convenience APIs,
gst_&lt;bintype&gt;_new (). these are equivalent to the gst_element_factory_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_element_factory_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. Pipelines shouldn't be added to any other element, though.
They are toplevel bins and they are directly linked to the scheduler.
</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 a 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-&gt;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, use the gst_bin_add_many
() function. 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 allows you to write an MPEG audio
decoder with just the following lines of code:
</para>
<programlisting>
/* create the mp3player element */
GstElement *mp3player = gst_element_factory_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"/>.
</para>
<para>
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 <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.&image;" format="&IMAGE;" />
</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.&image;" format="&IMAGE;" />
</imageobject>
</mediaobject>
</figure>
<para>
<xref linkend="sec-bin-ghost-img"/>
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_element_factory_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.
</para>
<para>
We can now, for example, link the source pad of a filesrc element
to the bin with:
</para>
<programlisting>
GstElement *filesrc;
filesrc = gst_element_factory_create ("filesrc", "disk_reader");
gst_element_link_pads (filesrc, "src", bin, "sink");
...
</programlisting>
</sect1>
</chapter>

View file

@ -115,142 +115,4 @@
</figure>
</sect2>
</sect1>
<sect1 id="sec-elements-create">
<title>Creating a GstElement</title>
<para>
A <classname>GstElement</classname> object is created from
a factory. To create an element, you have to get access to a
<classname>GstElementFactory</classname> object using a unique
factory name.
</para>
<para>
The following code example is used to get a factory that can be used
to create the 'mad' element, an mp3 decoder.
</para>
<programlisting>
GstElementFactory *factory;
factory = gst_element_factory_find ("mad");
</programlisting>
<para>
Once you have the handle to the element factory, you can create a
real element with the following code fragment:
</para>
<programlisting>
GstElement *element;
element = gst_element_factory_create (factory, "decoder");
</programlisting>
<para>
<function>gst_element_factory_create</function> will use the element
factory to create an element with the given name. The name of the
element is something you can use later on to look up the element in
a bin, for example. You can pass <symbol>NULL</symbol> as the name
argument to get a unique, default name.
</para>
<para>
A simple shortcut exists for creating an element from a factory. The
following example creates an element named "decoder" from the element
factory named "mad". This convenience function is most widely used to
create an element.
</para>
<programlisting>
GstElement *element;
element = gst_element_factory_make ("mad", "decoder");
</programlisting>
<para>
When you don't need the element anymore, you need to unref it, as shown in the following
example.
</para>
<programlisting>
GstElement *element;
...
gst_element_unref (element);
</programlisting>
</sect1>
<sect1 id="sec-elements-properties">
<title>GstElement properties</title>
<para>
A <classname>GstElement</classname> can have several properties
which are implemented using standard <classname>GObject</classname>
properties. The usual <classname>GObject</classname> methods to query,
set and get property values and <classname>GParamSpecs</classname>
are therefore supported.
</para>
<para>
Every <classname>GstElement</classname> inherits at least
one property of its parent <classname>GstObject</classname>:
the "name" property. This is the name you provide to the
functions <function>gst_element_factory_make</function> or
<function>gst_element_factory_create</function>. You can get and set
this property using the functions
<function>gst_object_set_name</function>
and <function>gst_object_get_name</function> or use the
<classname>GObject</classname> property mechanism as shown below.
</para>
<programlisting>
GstElement *element;
GValue value = { 0, }; /* initialize the GValue for g_object_get() */
element = gst_element_factory_make ("mad", "decoder");
g_object_set (G_OBJECT (element), "name", "mydecoder", NULL);
...
g_value_init (&amp;value, G_TYPE_STRING);
g_object_get_property (G_OBJECT (element), "name", &amp;value);
...
</programlisting>
<para>
Most plugins provide additional properties to provide more information
about their configuration or to configure the element.
<command>gst-inspect</command> is a useful tool to query the properties
of a particular element, it will also use property introspection to give
a short explanation about the function of the property and about the
parameter types and ranges it supports.
</para>
<para>
For more information about <classname>GObject</classname>
properties we recommend you read the <ulink
url="http://developer.gnome.org/doc/API/2.0/gobject/index.html"
type="http">GObject manual</ulink> and an introduction to <ulink
url="http://le-hacker.org/papers/gobject/index.html" type="http">
The Glib Object system</ulink>.
</para>
</sect1>
<sect1 id="sec-elements-signals">
<title>GstElement signals</title>
<para>
A <classname>GstElement</classname> also provides various
<classname>GObject</classname> signals that can be used as a flexible
callback mechanism.
</para>
</sect1>
<sect1 id="sec-elements-factories">
<title>More about GstElementFactory</title>
<para>
We talk some more about the GstElementFactory object.
</para>
<sect2 id="sec-elements-factories-details">
<title>Getting information about an element using the factory details</title>
<para>
</para>
</sect2>
<sect2 id="sec-elements-factories-padtemplates">
<title>Finding out what pads an element can contain</title>
<para>
</para>
</sect2>
<sect2 id="sec-elements-factories-query">
<title>Different ways of querying the factories</title>
<para>
</para>
</sect2>
</sect1>
</chapter>

View file

@ -24,57 +24,6 @@
</para></footnote>
</para>
<sect1 id="sec-pads-get">
<title>Getting pads from an element</title>
<para>
Once you have created an element, you can get one of its pads with:
</para>
<programlisting>
GstPad *srcpad;
...
srcpad = gst_element_get_pad (element, "src");
...
</programlisting>
<para>
This function will get the pad named "src" from the given element.
</para>
<para>
Alternatively, you can request a GList of pads from the element. The
following code example will print the names of all the pads of an
element.
</para>
<programlisting>
GList *pads;
...
pads = gst_element_get_pad_list (element);
while (pads) {
GstPad *pad = GST_PAD (pads-&gt;data);
g_print ("pad name %s\n", gst_pad_get_name (pad));
pads = g_list_next (pads);
}
...
</programlisting>
<sect2 id="sec-pads-functions">
<title>Useful pad functions</title>
<para>
You can get the name of a pad with gst_pad_get_name () and set its name with
get_pad_set_name().
</para>
<para>
gst_pad_get_direction (GstPad *pad) can be used to query if the pad
is a sink or a source pad. Remember that a source pad is a pad that
can output data and a sink pad is one that accepts data.
</para>
<para>
You can get the parent of the pad, this is the element that this pad belongs to,
with get_pad_get_parent(GstPad *pad). This function will return a pointer to a
GstElement.
</para>
</sect2>
</sect1>
<sect1 id="sec-pads-type">
<title>Types of pads</title>
@ -97,51 +46,6 @@
will see that this is very important when you are going to create dynamic
pipelines later on in this manual.
</para>
<para>
You can attach a signal to an element to inform you when the element has created
a new pad from one of its padtemplates. The following piece of code is an example
of how to do this:
</para>
<programlisting>
static void
pad_link_func (GstElement *parser, GstPad *pad, GstElement *pipeline)
{
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
gst_element_set_state (pipeline, GST_STATE_PAUSED);
if (strncmp (gst_pad_get_name (pad), "private_stream_1.0", 18) == 0) {
// set up an AC3 decoder pipeline
...
// link pad to the AC3 decoder pipeline
...
}
gst_element_set_state (GST_ELEMENT (audio_thread), GST_STATE_READY);
}
int
main(int argc, char *argv[])
{
GstElement *pipeline;
GstElement *mpeg2parser;
// create pipeline and do something useful
...
mpeg2parser = gst_element_factory_make ("mpegdemux", "mpegdemux");
g_signal_connect (G_OBJECT (mpeg2parser), "new_pad", pad_link_func, pipeline);
...
// start the pipeline
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
...
}
</programlisting>
<note>
<para>
A pipeline cannot be changed in the PLAYING state.
</para>
</note>
</sect2>
<sect2 id="sec-pads-request">
<title>Request pads</title>
@ -155,45 +59,6 @@ main(int argc, char *argv[])
output pads. Whenever an element wants to get an output pad from the tee element, it
has to request the pad.
</para>
<para>
The following piece of code can be used to get a pad from the tee element. After
the pad has been requested, it can be used to link another element to it.
</para>
<programlisting>
...
GstPad *pad;
...
element = gst_element_factory_make ("tee", "element");
pad = gst_element_get_request_pad (element, "src%d");
g_print ("new pad %s\n", gst_pad_get_name (pad));
...
</programlisting>
<para>
The gst_element_get_request_pad method can be used to get a pad
from the element based on the name_template of the padtemplate.
</para>
<para>
It is also possible to request a pad that is compatible with another
pad template. This is very useful if you want to link an element
to a multiplexer element and you need to request a pad that is
compatible. The gst_element_get_compatible_pad is used to request
a compatible pad, as is shown in the next example.
</para>
<programlisting>
...
GstPadTemplate *templ;
GstPad *pad;
...
element = gst_element_factory_make ("tee", "element");
mad = gst_element_factory_make ("mad", "mad");
templ = gst_element_get_pad_template_by_name (mad, "sink");
pad = gst_element_get_compatible_pad (element, templ);
g_print ("new pad %s\n", gst_pad_get_name (pad));
...
</programlisting>
</sect2>
</sect1>
@ -212,7 +77,7 @@ main(int argc, char *argv[])
</para>
<sect2 id="sec-pads-caps">
<title>What are capabilities ?</title>
<title>Capabilities</title>
<para>
Capabilities are attached to a pad in order to describe
what type of media the pad can handle.
@ -225,29 +90,16 @@ main(int argc, char *argv[])
The basic entity is a capability, and is defined by a name, a MIME
type and a set of properties. A capability can be chained to
another capability, which is why we commonly refer to a chain of
capability entities as "capabilities".<footnote>
capability entities as "capabilities".
<footnote>
<para>
It is important to understand that the term "capabilities" refers
to a chain of one capability or more. This will be clearer when
you see the structure definition of a <classname>GstCaps</classname>
element.
</para></footnote>
</para>
</footnote>
</para>
<para>
Its structure is:
</para>
<programlisting>
struct _GstCaps {
gchar *name; /* the name of this caps */
guint16 id; /* type id (major type) */
guint refcount; /* caps are refcounted */
GstProps *properties; /* properties for this capability */
GstCaps *next; /* caps can be chained together */
};
</programlisting>
<para>
Below is a dump of the capabilities of the element mad, as shown by
<command>gst-inspect</command>.
@ -387,146 +239,5 @@ Pads:
</listitem>
</itemizedlist>
</sect2>
<sect2 id="sec-pads-caps-get">
<title>Getting the capabilities of a pad</title>
<para>
A pad can have a chain of capabilities attached to it. You can get the capabilities chain
with:
</para>
<programlisting>
GstCaps *caps;
...
caps = gst_pad_get_caps (pad);
g_print ("pad name %s\n", gst_pad_get_name (pad));
while (caps) {
g_print (" Capability name %s, MIME type %s\n",
gst_caps_get_name (cap),
gst_caps_get_mime (cap));
caps = caps-&gt;next;
}
...
</programlisting>
</sect2>
<sect2 id="sec-pads-caps-create">
<title>Creating capability structures</title>
<para>
While capabilities are mainly used inside a plugin to describe the
media type of the pads, the application programmer also has to have
basic understanding of capabilities in order to interface with the
plugins, specially when using the autopluggers.
</para>
<para>
As we said, a capability has a name, a mime-type and some
properties. The signature of the function to create a new
<classname>GstCaps</classname> structure is:
<programlisting>
GstCaps* gst_caps_new (const gchar *name, const gchar *mime, GstProps *props);
</programlisting>
</para>
<para>
You can therefore create a new capability with no properties like this:
<programlisting>
GstCaps *newcaps;
newcaps = gst_caps_new ("my_caps", "audio/wav", NULL);
</programlisting>
</para>
<para>
<classname>GstProps</classname> basically consist of a set of key-value pairs
and are created with a function with this signature:
<programlisting>
GstProps* gst_props_new (const gchar *firstname, ...);
</programlisting>
</para>
<para>
The keys are given as strings and the values are given with a set of macros:
<itemizedlist>
<listitem>
<para>
GST_PROPS_INT(a): An integer value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FLOAT(a): A floating point value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FOURCC(a): A fourcc value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_BOOLEAN(a): A boolean value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_STRING(a): A string value
</para>
</listitem>
</itemizedlist>
The values can also be specified as ranges with:
<itemizedlist>
<listitem>
<para>
GST_PROPS_INT_RANGE(a,b): An integer range from a to b
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FLOAT_RANGE(a,b): A float ragne from a to b
</para>
</listitem>
</itemizedlist>
All of the above values can be given with a list too, using:
<itemizedlist>
<listitem>
<para>
GST_PROPS_LIST(a,...): A list of property values.
</para>
</listitem>
</itemizedlist>
</para>
<para>
A more complex capability with properties is created like this:
<programlisting>
GstCaps *newcaps;
newcaps = gst_caps_new ("my_caps",
"audio/wav",
gst_props_new (
"bitrate", GST_PROPS_INT_RANGE (11025,22050),
"depth", GST_PROPS_INT (16),
"signed", GST_PROPS_LIST (
GST_PROPS_BOOLEAN (TRUE),
GST_PROPS_BOOLEAN (FALSE)
),
NULL
);
</programlisting>
Optionally, the convenient shortcut macro can be used. The above complex
capability can be created with:
<programlisting>
GstCaps *newcaps;
newcaps = GST_CAPS_NEW ("my_caps",
"audio/wav",
"bitrate", GST_PROPS_INT_RANGE (11025,22050),
"depth", GST_PROPS_INT (16),
"signed", GST_PROPS_LIST (
GST_PROPS_BOOLEAN (TRUE),
GST_PROPS_BOOLEAN (FALSE)
)
);
</programlisting>
</para>
</sect2>
</sect1>
</chapter>

View file

@ -28,56 +28,4 @@
</para>
</listitem>
</itemizedlist>
<para>
All plugins should implement one function, <function>plugin_init</function>,
that creates all the element factories and registers all the type
definitions contained in the plugin.
Without this function, a plugin cannot be registered.
</para>
<para>
The plugins are maintained in the plugin system. Optionally, the
type definitions and the element factories can be saved into an XML
representation so that the plugin system does not have to load all
available plugins in order to know their definition.
</para>
<para>
The basic plugin structure has the following fields:
</para>
<programlisting>
typedef struct _GstPlugin GstPlugin;
struct _GstPlugin {
gchar *name; /* name of the plugin */
gchar *longname; /* long name of plugin */
gchar *filename; /* filename it came from */
GList *types; /* list of types provided */
gint numtypes;
GList *elements; /* list of elements provided */
gint numelements;
GList *autopluggers; /* list of autopluggers provided */
gint numautopluggers;
gboolean loaded; /* if the plugin is in memory */
};
</programlisting>
<para>
You can query a <classname>GList</classname> of available plugins with the
function <function>gst_plugin_get_list</function> as this example shows:
</para>
<programlisting>
GList *plugins;
plugins = gst_plugin_get_list ();
while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins-&gt;data;
g_print ("plugin: %s\n", gst_plugin_get_name (plugin));
plugins = g_list_next (plugins);
}
</programlisting>
</chapter>

201
docs/manual/bins-api.xml Normal file
View file

@ -0,0 +1,201 @@
<chapter id="cha-bins-api">
<title>Bins</title>
<sect1 id="sec-bin-create">
<title>Creating a bin</title>
<para>
Bins are created in the same way that other elements are created. ie.
using an element factory, or any of the associated convenience functions:
</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_element_factory_make ("bin", "mybin");
/* create a new thread, and give it a unique name */
thread = gst_element_factory_make ("thread", NULL);
/* the core bins (GstBin, GstThread, GstPipeline) also have convenience APIs,
gst_&lt;bintype&gt;_new (). these are equivalent to the gst_element_factory_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_element_factory_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. Pipelines shouldn't be added to any other element, though.
They are toplevel bins and they are directly linked to the scheduler.
</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 a 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-&gt;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, use the gst_bin_add_many
() function. 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 allows you to write an MPEG audio
decoder with just the following lines of code:
</para>
<programlisting>
/* create the mp3player element */
GstElement *mp3player = gst_element_factory_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"/>.
</para>
<para>
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 <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.&image;" format="&IMAGE;" />
</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.&image;" format="&IMAGE;" />
</imageobject>
</mediaobject>
</figure>
<para>
<xref linkend="sec-bin-ghost-img"/>
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_element_factory_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.
</para>
<para>
We can now, for example, link the source pad of a filesrc element
to the bin with:
</para>
<programlisting>
GstElement *filesrc;
filesrc = gst_element_factory_create ("filesrc", "disk_reader");
gst_element_link_pads (filesrc, "src", bin, "sink");
...
</programlisting>
</sect1>
</chapter>

View file

@ -46,203 +46,4 @@
</listitem>
</itemizedlist>
</para>
<sect1 id="sec-bin-create">
<title>Creating a bin</title>
<para>
Bins are created in the same way that other elements are created. ie.
using an element factory, or any of the associated convenience functions:
</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_element_factory_make ("bin", "mybin");
/* create a new thread, and give it a unique name */
thread = gst_element_factory_make ("thread", NULL);
/* the core bins (GstBin, GstThread, GstPipeline) also have convenience APIs,
gst_&lt;bintype&gt;_new (). these are equivalent to the gst_element_factory_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_element_factory_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. Pipelines shouldn't be added to any other element, though.
They are toplevel bins and they are directly linked to the scheduler.
</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 a 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-&gt;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, use the gst_bin_add_many
() function. 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 allows you to write an MPEG audio
decoder with just the following lines of code:
</para>
<programlisting>
/* create the mp3player element */
GstElement *mp3player = gst_element_factory_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"/>.
</para>
<para>
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 <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.&image;" format="&IMAGE;" />
</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.&image;" format="&IMAGE;" />
</imageobject>
</mediaobject>
</figure>
<para>
<xref linkend="sec-bin-ghost-img"/>
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_element_factory_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.
</para>
<para>
We can now, for example, link the source pad of a filesrc element
to the bin with:
</para>
<programlisting>
GstElement *filesrc;
filesrc = gst_element_factory_create ("filesrc", "disk_reader");
gst_element_link_pads (filesrc, "src", bin, "sink");
...
</programlisting>
</sect1>
</chapter>

View file

@ -0,0 +1,6 @@
<chapter id="cha-buffers-api">
<title>Buffers</title>
<para>
</para>
</chapter>

View file

@ -0,0 +1,141 @@
<chapter id="cha-elements-api">
<title>Elements</title>
<sect1 id="sec-elements-create">
<title>Creating a GstElement</title>
<para>
A <classname>GstElement</classname> object is created from
a factory. To create an element, you have to get access to a
<classname>GstElementFactory</classname> object using a unique
factory name.
</para>
<para>
The following code example is used to get a factory that can be used
to create the 'mad' element, an mp3 decoder.
</para>
<programlisting>
GstElementFactory *factory;
factory = gst_element_factory_find ("mad");
</programlisting>
<para>
Once you have the handle to the element factory, you can create a
real element with the following code fragment:
</para>
<programlisting>
GstElement *element;
element = gst_element_factory_create (factory, "decoder");
</programlisting>
<para>
<function>gst_element_factory_create</function> will use the element
factory to create an element with the given name. The name of the
element is something you can use later on to look up the element in
a bin, for example. You can pass <symbol>NULL</symbol> as the name
argument to get a unique, default name.
</para>
<para>
A simple shortcut exists for creating an element from a factory. The
following example creates an element named "decoder" from the element
factory named "mad". This convenience function is most widely used to
create an element.
</para>
<programlisting>
GstElement *element;
element = gst_element_factory_make ("mad", "decoder");
</programlisting>
<para>
When you don't need the element anymore, you need to unref it, as shown in the following
example.
</para>
<programlisting>
GstElement *element;
...
gst_element_unref (element);
</programlisting>
</sect1>
<sect1 id="sec-elements-properties">
<title>GstElement properties</title>
<para>
A <classname>GstElement</classname> can have several properties
which are implemented using standard <classname>GObject</classname>
properties. The usual <classname>GObject</classname> methods to query,
set and get property values and <classname>GParamSpecs</classname>
are therefore supported.
</para>
<para>
Every <classname>GstElement</classname> inherits at least
one property of its parent <classname>GstObject</classname>:
the "name" property. This is the name you provide to the
functions <function>gst_element_factory_make</function> or
<function>gst_element_factory_create</function>. You can get and set
this property using the functions
<function>gst_object_set_name</function>
and <function>gst_object_get_name</function> or use the
<classname>GObject</classname> property mechanism as shown below.
</para>
<programlisting>
GstElement *element;
GValue value = { 0, }; /* initialize the GValue for g_object_get() */
element = gst_element_factory_make ("mad", "decoder");
g_object_set (G_OBJECT (element), "name", "mydecoder", NULL);
...
g_value_init (&amp;value, G_TYPE_STRING);
g_object_get_property (G_OBJECT (element), "name", &amp;value);
...
</programlisting>
<para>
Most plugins provide additional properties to provide more information
about their configuration or to configure the element.
<command>gst-inspect</command> is a useful tool to query the properties
of a particular element, it will also use property introspection to give
a short explanation about the function of the property and about the
parameter types and ranges it supports.
</para>
<para>
For more information about <classname>GObject</classname>
properties we recommend you read the <ulink
url="http://developer.gnome.org/doc/API/2.0/gobject/index.html"
type="http">GObject manual</ulink> and an introduction to <ulink
url="http://le-hacker.org/papers/gobject/index.html" type="http">
The Glib Object system</ulink>.
</para>
</sect1>
<sect1 id="sec-elements-signals">
<title>GstElement signals</title>
<para>
A <classname>GstElement</classname> also provides various
<classname>GObject</classname> signals that can be used as a flexible
callback mechanism.
</para>
</sect1>
<sect1 id="sec-elements-factories">
<title>More about GstElementFactory</title>
<para>
We talk some more about the GstElementFactory object.
</para>
<sect2 id="sec-elements-factories-details">
<title>Getting information about an element using the factory details</title>
<para>
</para>
</sect2>
<sect2 id="sec-elements-factories-padtemplates">
<title>Finding out what pads an element can contain</title>
<para>
</para>
</sect2>
<sect2 id="sec-elements-factories-query">
<title>Different ways of querying the factories</title>
<para>
</para>
</sect2>
</sect1>
</chapter>

View file

@ -115,142 +115,4 @@
</figure>
</sect2>
</sect1>
<sect1 id="sec-elements-create">
<title>Creating a GstElement</title>
<para>
A <classname>GstElement</classname> object is created from
a factory. To create an element, you have to get access to a
<classname>GstElementFactory</classname> object using a unique
factory name.
</para>
<para>
The following code example is used to get a factory that can be used
to create the 'mad' element, an mp3 decoder.
</para>
<programlisting>
GstElementFactory *factory;
factory = gst_element_factory_find ("mad");
</programlisting>
<para>
Once you have the handle to the element factory, you can create a
real element with the following code fragment:
</para>
<programlisting>
GstElement *element;
element = gst_element_factory_create (factory, "decoder");
</programlisting>
<para>
<function>gst_element_factory_create</function> will use the element
factory to create an element with the given name. The name of the
element is something you can use later on to look up the element in
a bin, for example. You can pass <symbol>NULL</symbol> as the name
argument to get a unique, default name.
</para>
<para>
A simple shortcut exists for creating an element from a factory. The
following example creates an element named "decoder" from the element
factory named "mad". This convenience function is most widely used to
create an element.
</para>
<programlisting>
GstElement *element;
element = gst_element_factory_make ("mad", "decoder");
</programlisting>
<para>
When you don't need the element anymore, you need to unref it, as shown in the following
example.
</para>
<programlisting>
GstElement *element;
...
gst_element_unref (element);
</programlisting>
</sect1>
<sect1 id="sec-elements-properties">
<title>GstElement properties</title>
<para>
A <classname>GstElement</classname> can have several properties
which are implemented using standard <classname>GObject</classname>
properties. The usual <classname>GObject</classname> methods to query,
set and get property values and <classname>GParamSpecs</classname>
are therefore supported.
</para>
<para>
Every <classname>GstElement</classname> inherits at least
one property of its parent <classname>GstObject</classname>:
the "name" property. This is the name you provide to the
functions <function>gst_element_factory_make</function> or
<function>gst_element_factory_create</function>. You can get and set
this property using the functions
<function>gst_object_set_name</function>
and <function>gst_object_get_name</function> or use the
<classname>GObject</classname> property mechanism as shown below.
</para>
<programlisting>
GstElement *element;
GValue value = { 0, }; /* initialize the GValue for g_object_get() */
element = gst_element_factory_make ("mad", "decoder");
g_object_set (G_OBJECT (element), "name", "mydecoder", NULL);
...
g_value_init (&amp;value, G_TYPE_STRING);
g_object_get_property (G_OBJECT (element), "name", &amp;value);
...
</programlisting>
<para>
Most plugins provide additional properties to provide more information
about their configuration or to configure the element.
<command>gst-inspect</command> is a useful tool to query the properties
of a particular element, it will also use property introspection to give
a short explanation about the function of the property and about the
parameter types and ranges it supports.
</para>
<para>
For more information about <classname>GObject</classname>
properties we recommend you read the <ulink
url="http://developer.gnome.org/doc/API/2.0/gobject/index.html"
type="http">GObject manual</ulink> and an introduction to <ulink
url="http://le-hacker.org/papers/gobject/index.html" type="http">
The Glib Object system</ulink>.
</para>
</sect1>
<sect1 id="sec-elements-signals">
<title>GstElement signals</title>
<para>
A <classname>GstElement</classname> also provides various
<classname>GObject</classname> signals that can be used as a flexible
callback mechanism.
</para>
</sect1>
<sect1 id="sec-elements-factories">
<title>More about GstElementFactory</title>
<para>
We talk some more about the GstElementFactory object.
</para>
<sect2 id="sec-elements-factories-details">
<title>Getting information about an element using the factory details</title>
<para>
</para>
</sect2>
<sect2 id="sec-elements-factories-padtemplates">
<title>Finding out what pads an element can contain</title>
<para>
</para>
</sect2>
<sect2 id="sec-elements-factories-query">
<title>Different ways of querying the factories</title>
<para>
</para>
</sect2>
</sect1>
</chapter>

78
docs/manual/init-api.xml Normal file
View file

@ -0,0 +1,78 @@
<chapter id="cha-initialisation">
<title>Initializing <application>GStreamer</application></title>
<para>
When writing a <application>GStreamer</application> application, you can
simply include <filename class='headerfile'>gst/gst.h</filename> to get
access to the library functions.
</para>
<para>
Before the <application>GStreamer</application> libraries can be used,
<function>gst_init</function> has to be called from the main application.
This call will perform the necessary initialization of the library as
well as parse the GStreamer-specific command line options.
</para>
<para>
A typical program would start like this:
</para>
<programlisting>
#include &lt;gst/gst.h&gt;
...
int
main (int argc, char *argv[])
{
...
gst_init (&amp;argc, &amp;argv);
...
}
</programlisting>
<para>
Use the <symbol>GST_VERSION_MAJOR</symbol>,
<symbol>GST_VERSION_MINOR</symbol> and <symbol>GST_VERSION_MICRO</symbol>
macros to get the <application>GStreamer</application> version you are
building against, or use the function <function>gst_version</function>
to get the version your application is linked against.
<!-- FIXME: include an automatically generated list of these options. -->
</para>
<para>
It is also possible to call the <function>gst_init</function> function
with two <symbol>NULL</symbol> arguments, in which case no command line
options will parsed by <application>GStreamer</application>.
</para>
<sect1>
<title>The popt interface</title>
<para>
You can also use a popt table to initialize your own parameters as shown in the next code fragment:
</para>
<programlisting>
int
main(int argc, char *argv[])
{
gboolean silent = FALSE;
gchar *savefile = NULL;
struct poptOption options[] = {
{"silent", 's', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &amp;silent, 0,
"do not output status information", NULL},
{"output", 'o', POPT_ARG_STRING|POPT_ARGFLAG_STRIP, &amp;savefile, 0,
"save xml representation of pipeline to FILE and exit", "FILE"},
POPT_TABLEEND
};
gst_init_with_popt_table (&amp;argc, &amp;argv, options);
...
</programlisting>
<para>
As shown in this fragment, you can use a <ulink
url="http://developer.gnome.org/doc/guides/popt/"
type="http">popt</ulink> table to define your application-specific
command line options, and pass this table to the
function <function>gst_init_with_popt_table</function>. Your
application options will be parsed in addition to the standard
<application>GStreamer</application> options.
</para>
</sect1>
</chapter>

79
docs/manual/links-api.xml Normal file
View file

@ -0,0 +1,79 @@
<chapter id="cha-links-api">
<title>Linking elements</title>
<sect1 id="sec-link-basic">
<title>Making simple links</title>
<para>
You can link two pads with:
</para>
<programlisting>
GstPad *srcpad, *sinkpad;
srcpad = gst_element_get_pad (element1, "src");
sinpad = gst_element_get_pad (element2, "sink");
// link them
gst_pad_link (srcpad, sinkpad);
....
// and unlink them
gst_pad_unlink (srcpad, sinkpad);
</programlisting>
<para>
A convenient shortcut for the above code is done with the gst_element_link_pads ()
function:
</para>
<programlisting>
// link them
gst_element_link_pads (element1, "src", element2, "sink");
....
// and unlink them
gst_element_unlink_pads (element1, "src", element2, "sink");
</programlisting>
<para>
An even more convenient shortcut for single-source, single-sink elements is the
gst_element_link () function:
</para>
<programlisting>
// link them
gst_element_link (element1, element2);
....
// and unlink them
gst_element_unlink (element1, element2);
</programlisting>
<para>
If you have more than one element to link, the gst_element_link_many () function takes
a NULL-terminated list of elements:
</para>
<programlisting>
// link them
gst_element_link_many (element1, element2, element3, element4, NULL);
....
// and unlink them
gst_element_unlink_many (element1, element2, element3, element4, NULL);
</programlisting>
<para>
You can query if a pad is linked with GST_PAD_IS_LINKED (pad).
</para>
<para>
To query for the <classname>GstPad</classname> a pad is linked to, use
gst_pad_get_peer (pad).
</para>
</sect1>
<sect1 id="sec-link-filtered">
<title>Making filtered links</title>
<para>
You can also force a specific media type on the link by using gst_pad_link_filtered ()
and gst_element_link_filtered () with capabilities.
See <xref linkend="sec-caps"/> for
an explanation of capabilities.
</para>
</sect1>
</chapter>

View file

@ -26,81 +26,4 @@
the sink element is your audiocard. We will use this simple graph to
construct an MPEG player later in this manual.
</para>
<sect1 id="sec-link-basic">
<title>Making simple links</title>
<para>
You can link two pads with:
</para>
<programlisting>
GstPad *srcpad, *sinkpad;
srcpad = gst_element_get_pad (element1, "src");
sinpad = gst_element_get_pad (element2, "sink");
// link them
gst_pad_link (srcpad, sinkpad);
....
// and unlink them
gst_pad_unlink (srcpad, sinkpad);
</programlisting>
<para>
A convenient shortcut for the above code is done with the gst_element_link_pads ()
function:
</para>
<programlisting>
// link them
gst_element_link_pads (element1, "src", element2, "sink");
....
// and unlink them
gst_element_unlink_pads (element1, "src", element2, "sink");
</programlisting>
<para>
An even more convenient shortcut for single-source, single-sink elements is the
gst_element_link () function:
</para>
<programlisting>
// link them
gst_element_link (element1, element2);
....
// and unlink them
gst_element_unlink (element1, element2);
</programlisting>
<para>
If you have more than one element to link, the gst_element_link_many () function takes
a NULL-terminated list of elements:
</para>
<programlisting>
// link them
gst_element_link_many (element1, element2, element3, element4, NULL);
....
// and unlink them
gst_element_unlink_many (element1, element2, element3, element4, NULL);
</programlisting>
<para>
You can query if a pad is linked with GST_PAD_IS_LINKED (pad).
</para>
<para>
To query for the <classname>GstPad</classname> a pad is linked to, use
gst_pad_get_peer (pad).
</para>
</sect1>
<sect1 id="sec-link-filtered">
<title>Making filtered links</title>
<para>
You can also force a specific media type on the link by using gst_pad_link_filtered ()
and gst_element_link_filtered () with capabilities.
See <xref linkend="sec-caps"/> for
an explanation of capabilities.
</para>
</sect1>
</chapter>

View file

@ -6,23 +6,37 @@
<!ENTITY % version-entities SYSTEM "version.entities">
%version-entities;
<!-- Part 1: Overview -->
<!ENTITY INTRO SYSTEM "intro.xml">
<!ENTITY MOTIVATION SYSTEM "motivation.xml">
<!ENTITY GOALS SYSTEM "goals.xml">
<!ENTITY INIT SYSTEM "init.xml">
<!-- Part 2: Basic Concepts -->
<!ENTITY ELEMENTS SYSTEM "elements.xml">
<!ENTITY PADS SYSTEM "pads.xml">
<!ENTITY LINKS SYSTEM "links.xml">
<!ENTITY BINS SYSTEM "bins.xml">
<!ENTITY BUFFERS SYSTEM "buffers.xml">
<!ENTITY STATES SYSTEM "states.xml">
<!ENTITY PLUGINS SYSTEM "plugins.xml">
<!-- Part 3: Basic API -->
<!ENTITY INIT-API SYSTEM "init-api.xml">
<!ENTITY ELEMENTS-API SYSTEM "elements-api.xml">
<!ENTITY PADS-API SYSTEM "pads-api.xml">
<!ENTITY LINKS-API SYSTEM "links-api.xml">
<!ENTITY BINS-API SYSTEM "bins-api.xml">
<!ENTITY BUFFERS-API SYSTEM "buffers-api.xml">
<!ENTITY STATES-API SYSTEM "states-api.xml">
<!ENTITY PLUGINS-API SYSTEM "plugins-api.xml">
<!-- Part 4: Building An Application -->
<!ENTITY HELLOWORLD SYSTEM "helloworld.xml">
<!ENTITY FACTORIES SYSTEM "factories.xml">
<!ENTITY AUTOPLUGGING SYSTEM "autoplugging.xml">
<!ENTITY HELLOWORLD2 SYSTEM "helloworld2.xml">
<!-- Part 5: Advanced Concepts -->
<!ENTITY THREADS SYSTEM "threads.xml">
<!ENTITY QUEUES SYSTEM "queues.xml">
<!ENTITY COTHREADS SYSTEM "cothreads.xml">
@ -34,7 +48,6 @@
<!ENTITY DPARAMS SYSTEM "dparams-app.xml">
<!ENTITY XML SYSTEM "xml.xml">
<!ENTITY PLUGINS SYSTEM "plugins.xml">
<!ENTITY DEBUGGING SYSTEM "debugging.xml">
<!ENTITY PROGRAMS SYSTEM "programs.xml">
<!ENTITY COMPONENTS SYSTEM "components.xml">
@ -125,7 +138,7 @@
<!-- ############ Basic concepts - part ############# -->
<part id="basic-concepts"><title>Basic concepts</title>
<part id="basic-concepts"><title>Basic Concepts</title>
<partintro>
<para>
We will first describe the basics of
@ -138,9 +151,6 @@
</para>
</partintro>
<!-- ############ Basic concepts - chapter ############# -->
&INIT;
&ELEMENTS;
&PADS;
@ -154,8 +164,29 @@
&BUFFERS;
&STATES;
</part>
<!-- ############ Basic API - part ############# -->
<part id="basic-api"><title>Basic API</title>
&INIT-API;
&ELEMENTS-API;
&PADS-API;
&PLUGINS-API;
&LINKS-API;
&BINS-API;
&BUFFERS-API;
&STATES-API;
</part>
<!-- ############ Building Apps - part ############# -->
<part id="build-app"><title>Building an application</title>

301
docs/manual/pads-api.xml Normal file
View file

@ -0,0 +1,301 @@
<chapter id="cha-pads-api">
<title>Pads</title>
<para>
As we have seen in <xref linkend="cha-elements"/>, the pads are the element's
interface to the outside world.
</para>
<para>
The specific type of media that the element can handle will be exposed by the pads.
The description of this media type is done with capabilities(see
<xref linkend="sec-caps"/>)
</para>
<para>
Pads are either source or sink pads. The terminology is defined from the
view of the element itself: elements accept data on their sink pads, and
send data out on their source pads. Sink pads are drawn on the left,
while source pads are drawn on the right of an element. In general,
data flows from left to right in the graph.<footnote>
<para>
In reality, there is no objection to data flowing from a
source pad to the sink pad of an element upstream. Data will, however,
always flow from a source pad of one element to the sink pad of
another.
</para></footnote>
</para>
<sect1 id="sec-pads-api-type">
<title>Types of pads</title>
<sect2 id="sec-pads-api-dynamic">
<title>Dynamic pads</title>
<para>
You can attach a signal to an element to inform you when the element has created
a new pad from one of its padtemplates. The following piece of code is an example
of how to do this:
</para>
<programlisting>
static void
pad_link_func (GstElement *parser, GstPad *pad, GstElement *pipeline)
{
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
gst_element_set_state (pipeline, GST_STATE_PAUSED);
if (strncmp (gst_pad_get_name (pad), "private_stream_1.0", 18) == 0) {
// set up an AC3 decoder pipeline
...
// link pad to the AC3 decoder pipeline
...
}
gst_element_set_state (GST_ELEMENT (audio_thread), GST_STATE_READY);
}
int
main(int argc, char *argv[])
{
GstElement *pipeline;
GstElement *mpeg2parser;
// create pipeline and do something useful
...
mpeg2parser = gst_element_factory_make ("mpegdemux", "mpegdemux");
g_signal_connect (G_OBJECT (mpeg2parser), "new_pad", pad_link_func, pipeline);
...
// start the pipeline
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
...
}
</programlisting>
<note>
<para>
A pipeline cannot be changed in the PLAYING state.
</para>
</note>
</sect2>
<sect2 id="sec-pads-api-request">
<title>Request pads</title>
<para>
The following piece of code can be used to get a pad from the tee element. After
the pad has been requested, it can be used to link another element to it.
</para>
<programlisting>
...
GstPad *pad;
...
element = gst_element_factory_make ("tee", "element");
pad = gst_element_get_request_pad (element, "src%d");
g_print ("new pad %s\n", gst_pad_get_name (pad));
...
</programlisting>
<para>
The gst_element_get_request_pad method can be used to get a pad
from the element based on the name_template of the padtemplate.
</para>
<para>
It is also possible to request a pad that is compatible with another
pad template. This is very useful if you want to link an element
to a multiplexer element and you need to request a pad that is
compatible. The gst_element_get_compatible_pad is used to request
a compatible pad, as is shown in the next example.
</para>
<programlisting>
...
GstPadTemplate *templ;
GstPad *pad;
...
element = gst_element_factory_make ("tee", "element");
mad = gst_element_factory_make ("mad", "mad");
templ = gst_element_get_pad_template_by_name (mad, "sink");
pad = gst_element_get_compatible_pad (element, templ);
g_print ("new pad %s\n", gst_pad_get_name (pad));
...
</programlisting>
</sect2>
</sect1>
<sect1 id="sec-api-caps">
<title>Capabilities of a pad</title>
<para>
Since the pads play a very important role in how the element is viewed by the
outside world, a mechanism is implemented to describe the data that can
flow through the pad by using capabilities.
</para>
<para>
We will briefly describe what capabilities are, enough for you to get a basic understanding
of the concepts. You will find more information on how to create capabilities in the
Plugin Writer's Guide.
</para>
<sect2 id="sec-pads-api-caps">
<title>Capabilities</title>
<para>
Capabilities are attached to a pad in order to describe
what type of media the pad can handle.
</para>
<para>
Its structure is:
</para>
<programlisting>
struct _GstCaps {
gchar *name; /* the name of this caps */
guint16 id; /* type id (major type) */
guint refcount; /* caps are refcounted */
GstProps *properties; /* properties for this capability */
GstCaps *next; /* caps can be chained together */
};
</programlisting>
</sect2>
<sect2 id="sec-pads-api-caps-get">
<title>Getting the capabilities of a pad</title>
<para>
A pad can have a chain of capabilities attached to it. You can get the capabilities chain
with:
</para>
<programlisting>
GstCaps *caps;
...
caps = gst_pad_get_caps (pad);
g_print ("pad name %s\n", gst_pad_get_name (pad));
while (caps) {
g_print (" Capability name %s, MIME type %s\n",
gst_caps_get_name (cap),
gst_caps_get_mime (cap));
caps = caps-&gt;next;
}
...
</programlisting>
</sect2>
<sect2 id="sec-pads-api-caps-create">
<title>Creating capability structures</title>
<para>
While capabilities are mainly used inside a plugin to describe the
media type of the pads, the application programmer also has to have
basic understanding of capabilities in order to interface with the
plugins, specially when using the autopluggers.
</para>
<para>
As we said, a capability has a name, a mime-type and some
properties. The signature of the function to create a new
<classname>GstCaps</classname> structure is:
<programlisting>
GstCaps* gst_caps_new (const gchar *name, const gchar *mime, GstProps *props);
</programlisting>
</para>
<para>
You can therefore create a new capability with no properties like this:
<programlisting>
GstCaps *newcaps;
newcaps = gst_caps_new ("my_caps", "audio/wav", NULL);
</programlisting>
</para>
<para>
<classname>GstProps</classname> basically consist of a set of key-value pairs
and are created with a function with this signature:
<programlisting>
GstProps* gst_props_new (const gchar *firstname, ...);
</programlisting>
</para>
<para>
The keys are given as strings and the values are given with a set of macros:
<itemizedlist>
<listitem>
<para>
GST_PROPS_INT(a): An integer value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FLOAT(a): A floating point value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FOURCC(a): A fourcc value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_BOOLEAN(a): A boolean value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_STRING(a): A string value
</para>
</listitem>
</itemizedlist>
The values can also be specified as ranges with:
<itemizedlist>
<listitem>
<para>
GST_PROPS_INT_RANGE(a,b): An integer range from a to b
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FLOAT_RANGE(a,b): A float ragne from a to b
</para>
</listitem>
</itemizedlist>
All of the above values can be given with a list too, using:
<itemizedlist>
<listitem>
<para>
GST_PROPS_LIST(a,...): A list of property values.
</para>
</listitem>
</itemizedlist>
</para>
<para>
A more complex capability with properties is created like this:
<programlisting>
GstCaps *newcaps;
newcaps = gst_caps_new ("my_caps",
"audio/wav",
gst_props_new (
"bitrate", GST_PROPS_INT_RANGE (11025,22050),
"depth", GST_PROPS_INT (16),
"signed", GST_PROPS_LIST (
GST_PROPS_BOOLEAN (TRUE),
GST_PROPS_BOOLEAN (FALSE)
),
NULL
);
</programlisting>
Optionally, the convenient shortcut macro can be used. The above complex
capability can be created with:
<programlisting>
GstCaps *newcaps;
newcaps = GST_CAPS_NEW ("my_caps",
"audio/wav",
"bitrate", GST_PROPS_INT_RANGE (11025,22050),
"depth", GST_PROPS_INT (16),
"signed", GST_PROPS_LIST (
GST_PROPS_BOOLEAN (TRUE),
GST_PROPS_BOOLEAN (FALSE)
)
);
</programlisting>
</para>
</sect2>
</sect1>
</chapter>

View file

@ -24,57 +24,6 @@
</para></footnote>
</para>
<sect1 id="sec-pads-get">
<title>Getting pads from an element</title>
<para>
Once you have created an element, you can get one of its pads with:
</para>
<programlisting>
GstPad *srcpad;
...
srcpad = gst_element_get_pad (element, "src");
...
</programlisting>
<para>
This function will get the pad named "src" from the given element.
</para>
<para>
Alternatively, you can request a GList of pads from the element. The
following code example will print the names of all the pads of an
element.
</para>
<programlisting>
GList *pads;
...
pads = gst_element_get_pad_list (element);
while (pads) {
GstPad *pad = GST_PAD (pads-&gt;data);
g_print ("pad name %s\n", gst_pad_get_name (pad));
pads = g_list_next (pads);
}
...
</programlisting>
<sect2 id="sec-pads-functions">
<title>Useful pad functions</title>
<para>
You can get the name of a pad with gst_pad_get_name () and set its name with
get_pad_set_name().
</para>
<para>
gst_pad_get_direction (GstPad *pad) can be used to query if the pad
is a sink or a source pad. Remember that a source pad is a pad that
can output data and a sink pad is one that accepts data.
</para>
<para>
You can get the parent of the pad, this is the element that this pad belongs to,
with get_pad_get_parent(GstPad *pad). This function will return a pointer to a
GstElement.
</para>
</sect2>
</sect1>
<sect1 id="sec-pads-type">
<title>Types of pads</title>
@ -97,51 +46,6 @@
will see that this is very important when you are going to create dynamic
pipelines later on in this manual.
</para>
<para>
You can attach a signal to an element to inform you when the element has created
a new pad from one of its padtemplates. The following piece of code is an example
of how to do this:
</para>
<programlisting>
static void
pad_link_func (GstElement *parser, GstPad *pad, GstElement *pipeline)
{
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
gst_element_set_state (pipeline, GST_STATE_PAUSED);
if (strncmp (gst_pad_get_name (pad), "private_stream_1.0", 18) == 0) {
// set up an AC3 decoder pipeline
...
// link pad to the AC3 decoder pipeline
...
}
gst_element_set_state (GST_ELEMENT (audio_thread), GST_STATE_READY);
}
int
main(int argc, char *argv[])
{
GstElement *pipeline;
GstElement *mpeg2parser;
// create pipeline and do something useful
...
mpeg2parser = gst_element_factory_make ("mpegdemux", "mpegdemux");
g_signal_connect (G_OBJECT (mpeg2parser), "new_pad", pad_link_func, pipeline);
...
// start the pipeline
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
...
}
</programlisting>
<note>
<para>
A pipeline cannot be changed in the PLAYING state.
</para>
</note>
</sect2>
<sect2 id="sec-pads-request">
<title>Request pads</title>
@ -155,45 +59,6 @@ main(int argc, char *argv[])
output pads. Whenever an element wants to get an output pad from the tee element, it
has to request the pad.
</para>
<para>
The following piece of code can be used to get a pad from the tee element. After
the pad has been requested, it can be used to link another element to it.
</para>
<programlisting>
...
GstPad *pad;
...
element = gst_element_factory_make ("tee", "element");
pad = gst_element_get_request_pad (element, "src%d");
g_print ("new pad %s\n", gst_pad_get_name (pad));
...
</programlisting>
<para>
The gst_element_get_request_pad method can be used to get a pad
from the element based on the name_template of the padtemplate.
</para>
<para>
It is also possible to request a pad that is compatible with another
pad template. This is very useful if you want to link an element
to a multiplexer element and you need to request a pad that is
compatible. The gst_element_get_compatible_pad is used to request
a compatible pad, as is shown in the next example.
</para>
<programlisting>
...
GstPadTemplate *templ;
GstPad *pad;
...
element = gst_element_factory_make ("tee", "element");
mad = gst_element_factory_make ("mad", "mad");
templ = gst_element_get_pad_template_by_name (mad, "sink");
pad = gst_element_get_compatible_pad (element, templ);
g_print ("new pad %s\n", gst_pad_get_name (pad));
...
</programlisting>
</sect2>
</sect1>
@ -212,7 +77,7 @@ main(int argc, char *argv[])
</para>
<sect2 id="sec-pads-caps">
<title>What are capabilities ?</title>
<title>Capabilities</title>
<para>
Capabilities are attached to a pad in order to describe
what type of media the pad can handle.
@ -225,29 +90,16 @@ main(int argc, char *argv[])
The basic entity is a capability, and is defined by a name, a MIME
type and a set of properties. A capability can be chained to
another capability, which is why we commonly refer to a chain of
capability entities as "capabilities".<footnote>
capability entities as "capabilities".
<footnote>
<para>
It is important to understand that the term "capabilities" refers
to a chain of one capability or more. This will be clearer when
you see the structure definition of a <classname>GstCaps</classname>
element.
</para></footnote>
</para>
</footnote>
</para>
<para>
Its structure is:
</para>
<programlisting>
struct _GstCaps {
gchar *name; /* the name of this caps */
guint16 id; /* type id (major type) */
guint refcount; /* caps are refcounted */
GstProps *properties; /* properties for this capability */
GstCaps *next; /* caps can be chained together */
};
</programlisting>
<para>
Below is a dump of the capabilities of the element mad, as shown by
<command>gst-inspect</command>.
@ -387,146 +239,5 @@ Pads:
</listitem>
</itemizedlist>
</sect2>
<sect2 id="sec-pads-caps-get">
<title>Getting the capabilities of a pad</title>
<para>
A pad can have a chain of capabilities attached to it. You can get the capabilities chain
with:
</para>
<programlisting>
GstCaps *caps;
...
caps = gst_pad_get_caps (pad);
g_print ("pad name %s\n", gst_pad_get_name (pad));
while (caps) {
g_print (" Capability name %s, MIME type %s\n",
gst_caps_get_name (cap),
gst_caps_get_mime (cap));
caps = caps-&gt;next;
}
...
</programlisting>
</sect2>
<sect2 id="sec-pads-caps-create">
<title>Creating capability structures</title>
<para>
While capabilities are mainly used inside a plugin to describe the
media type of the pads, the application programmer also has to have
basic understanding of capabilities in order to interface with the
plugins, specially when using the autopluggers.
</para>
<para>
As we said, a capability has a name, a mime-type and some
properties. The signature of the function to create a new
<classname>GstCaps</classname> structure is:
<programlisting>
GstCaps* gst_caps_new (const gchar *name, const gchar *mime, GstProps *props);
</programlisting>
</para>
<para>
You can therefore create a new capability with no properties like this:
<programlisting>
GstCaps *newcaps;
newcaps = gst_caps_new ("my_caps", "audio/wav", NULL);
</programlisting>
</para>
<para>
<classname>GstProps</classname> basically consist of a set of key-value pairs
and are created with a function with this signature:
<programlisting>
GstProps* gst_props_new (const gchar *firstname, ...);
</programlisting>
</para>
<para>
The keys are given as strings and the values are given with a set of macros:
<itemizedlist>
<listitem>
<para>
GST_PROPS_INT(a): An integer value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FLOAT(a): A floating point value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FOURCC(a): A fourcc value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_BOOLEAN(a): A boolean value
</para>
</listitem>
<listitem>
<para>
GST_PROPS_STRING(a): A string value
</para>
</listitem>
</itemizedlist>
The values can also be specified as ranges with:
<itemizedlist>
<listitem>
<para>
GST_PROPS_INT_RANGE(a,b): An integer range from a to b
</para>
</listitem>
<listitem>
<para>
GST_PROPS_FLOAT_RANGE(a,b): A float ragne from a to b
</para>
</listitem>
</itemizedlist>
All of the above values can be given with a list too, using:
<itemizedlist>
<listitem>
<para>
GST_PROPS_LIST(a,...): A list of property values.
</para>
</listitem>
</itemizedlist>
</para>
<para>
A more complex capability with properties is created like this:
<programlisting>
GstCaps *newcaps;
newcaps = gst_caps_new ("my_caps",
"audio/wav",
gst_props_new (
"bitrate", GST_PROPS_INT_RANGE (11025,22050),
"depth", GST_PROPS_INT (16),
"signed", GST_PROPS_LIST (
GST_PROPS_BOOLEAN (TRUE),
GST_PROPS_BOOLEAN (FALSE)
),
NULL
);
</programlisting>
Optionally, the convenient shortcut macro can be used. The above complex
capability can be created with:
<programlisting>
GstCaps *newcaps;
newcaps = GST_CAPS_NEW ("my_caps",
"audio/wav",
"bitrate", GST_PROPS_INT_RANGE (11025,22050),
"depth", GST_PROPS_INT (16),
"signed", GST_PROPS_LIST (
GST_PROPS_BOOLEAN (TRUE),
GST_PROPS_BOOLEAN (FALSE)
)
);
</programlisting>
</para>
</sect2>
</sect1>
</chapter>

View file

@ -0,0 +1,56 @@
<chapter id="cha-plugins-api">
<title>Plugins</title>
<!-- FIXME: introduce type definitions before this chapter -->
<para>
All plugins should implement one function, <function>plugin_init</function>,
that creates all the element factories and registers all the type
definitions contained in the plugin.
Without this function, a plugin cannot be registered.
</para>
<para>
The plugins are maintained in the plugin system. Optionally, the
type definitions and the element factories can be saved into an XML
representation so that the plugin system does not have to load all
available plugins in order to know their definition.
</para>
<para>
The basic plugin structure has the following fields:
</para>
<programlisting>
typedef struct _GstPlugin GstPlugin;
struct _GstPlugin {
gchar *name; /* name of the plugin */
gchar *longname; /* long name of plugin */
gchar *filename; /* filename it came from */
GList *types; /* list of types provided */
gint numtypes;
GList *elements; /* list of elements provided */
gint numelements;
GList *autopluggers; /* list of autopluggers provided */
gint numautopluggers;
gboolean loaded; /* if the plugin is in memory */
};
</programlisting>
<para>
You can query a <classname>GList</classname> of available plugins with the
function <function>gst_plugin_get_list</function> as this example shows:
</para>
<programlisting>
GList *plugins;
plugins = gst_plugin_get_list ();
while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins-&gt;data;
g_print ("plugin: %s\n", gst_plugin_get_name (plugin));
plugins = g_list_next (plugins);
}
</programlisting>
</chapter>

View file

@ -28,56 +28,4 @@
</para>
</listitem>
</itemizedlist>
<para>
All plugins should implement one function, <function>plugin_init</function>,
that creates all the element factories and registers all the type
definitions contained in the plugin.
Without this function, a plugin cannot be registered.
</para>
<para>
The plugins are maintained in the plugin system. Optionally, the
type definitions and the element factories can be saved into an XML
representation so that the plugin system does not have to load all
available plugins in order to know their definition.
</para>
<para>
The basic plugin structure has the following fields:
</para>
<programlisting>
typedef struct _GstPlugin GstPlugin;
struct _GstPlugin {
gchar *name; /* name of the plugin */
gchar *longname; /* long name of plugin */
gchar *filename; /* filename it came from */
GList *types; /* list of types provided */
gint numtypes;
GList *elements; /* list of elements provided */
gint numelements;
GList *autopluggers; /* list of autopluggers provided */
gint numautopluggers;
gboolean loaded; /* if the plugin is in memory */
};
</programlisting>
<para>
You can query a <classname>GList</classname> of available plugins with the
function <function>gst_plugin_get_list</function> as this example shows:
</para>
<programlisting>
GList *plugins;
plugins = gst_plugin_get_list ();
while (plugins) {
GstPlugin *plugin = (GstPlugin *)plugins-&gt;data;
g_print ("plugin: %s\n", gst_plugin_get_name (plugin));
plugins = g_list_next (plugins);
}
</programlisting>
</chapter>

View file

@ -0,0 +1,48 @@
<chapter id="cha-states-api">
<title>Element states</title>
<sect1 id="sec-states-api">
<title>Changing element state</title>
<para>
The state of an element can be changed with the following code:
</para>
<programlisting>
GstElement *bin;
// create a bin, put elements in it and link them
...
gst_element_set_state (bin, GST_STATE_PLAYING);
...
</programlisting>
<para>
You can set the following states on an element:
</para>
<informaltable pgwide="1" frame="none" role="enum">
<tgroup cols="2">
<tbody>
<row>
<entry><literal>GST_STATE_NULL</literal></entry>
<entry>Reset the state of an element.
</entry>
</row>
<row>
<entry><literal>GST_STATE_READY</literal></entry>
<entry>will make the element ready to start processing data.
</entry>
</row>
<row>
<entry><literal>GST_STATE_PAUSED</literal></entry>
<entry>temporary stops the data flow.
</entry>
</row>
<row>
<entry><literal>GST_STATE_PLAYING</literal></entry>
<entry>means there really is data flowing through the graph.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</sect1>
</chapter>

View file

@ -40,17 +40,6 @@
PLAYING. When going from NULL to PLAYING, GStreamer will
internally go throught the intermediate states.
</para>
<para>
The state of an element can be changed with the following code:
</para>
<programlisting>
GstElement *bin;
// create a bin, put elements in it and link them
...
gst_element_set_state (bin, GST_STATE_PLAYING);
...
</programlisting>
<para>
You can set the following states on an element: