mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
Moved "Filter Writer's Guide" to "Plugin Writer's Guide". Divided existing info from old guide into several files, on...
Original commit message from CVS: Moved "Filter Writer's Guide" to "Plugin Writer's Guide". Divided existing info from old guide into several files, one per chapter. The guide still needs much work ...
This commit is contained in:
parent
cc5f591c17
commit
622a80da54
34 changed files with 2067 additions and 2 deletions
|
@ -5,8 +5,8 @@ else
|
|||
SUBDIRS_PLUGINS =
|
||||
endif
|
||||
|
||||
SUBDIRS = manual fwg gst libs $(SUBDIRS_PLUGINS) devhelp
|
||||
DIST_SUBDIRS = manual fwg gst libs plugins xsl devhelp
|
||||
SUBDIRS = manual pwg gst libs $(SUBDIRS_PLUGINS) devhelp
|
||||
DIST_SUBDIRS = manual pwg gst libs plugins xsl devhelp
|
||||
|
||||
EXTRA_DIST = slides manuals.mak
|
||||
|
||||
|
|
13
docs/pwg/.gitignore
vendored
Normal file
13
docs/pwg/.gitignore
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
*.bak
|
||||
.deps
|
||||
images
|
||||
gst-plugin-writers-guide
|
||||
gst-plugin-writers-guide.pdf
|
||||
gst-plugin-writers-guide.ps
|
||||
gst-plugin-writers-guide.dvi
|
||||
gst-plugin-writers-guide.tex
|
||||
gst-plugin-writers-guide.log
|
||||
gst-plugin-writers-guide.aux
|
||||
gst-plugin-writers-guide.junk
|
18
docs/pwg/Makefile.am
Normal file
18
docs/pwg/Makefile.am
Normal file
|
@ -0,0 +1,18 @@
|
|||
DOC=gst-plugin-writers-guide
|
||||
MAIN=$(DOC).xml
|
||||
XML=$(wildcard *.xml)
|
||||
XSLFO=$(srcdir)/../xsl/fo.xsl
|
||||
XSLFOMODS=$(srcdir)/../xsl/ulink.xsl $(srcdir)/../xsl/keycombo.xsl
|
||||
XSLHTML=$(srcdir)/../xsl/html.xsl
|
||||
XSLHTMLMODS=$(srcdir)/../xsl/fileext.xsl $(srcdir)/../xsl/admon.xsl \
|
||||
$(srcdir)/../xsl/keycombo.xsl $(srcdir)/../xsl/css.xsl
|
||||
XSLS=$(XSLFO) $(XSLFOMODS) $(XSLHTML) $(XSLHTMLMODS)
|
||||
FIGS= # $(wildcard *.fig) (uncomment when pngs are added)
|
||||
PNGS=$(FIGS:.fig=.png)
|
||||
PDFS=$(FIGS:.fig=.pdf)
|
||||
SRC=$(XML)
|
||||
CSS=base.css
|
||||
|
||||
EXTRA_DIST = $(XML) $(FIGS) $(CSS) magic-png magic-pdf
|
||||
|
||||
include $(srcdir)/../manuals.mak
|
0
docs/pwg/advanced-clock.xml
Normal file
0
docs/pwg/advanced-clock.xml
Normal file
481
docs/pwg/advanced-dparams.xml
Normal file
481
docs/pwg/advanced-dparams.xml
Normal file
|
@ -0,0 +1,481 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-dparams">
|
||||
<title>Supporting Dynamic Parameters</title>
|
||||
<para>
|
||||
Sometimes object properties are not powerful enough to control the
|
||||
parameters that affect the behaviour of your element. When this is the case
|
||||
you can expose these parameters as Dynamic Parameters which can be
|
||||
manipulated by any Dynamic Parameters aware application.
|
||||
</para>
|
||||
<para>
|
||||
Throughout this section, the term <emphasis>dparams</emphasis> will be used
|
||||
as an abbreviation for "Dynamic Parameters".
|
||||
</para>
|
||||
|
||||
<sect1 id="sect-dparams-compare">
|
||||
<title>Comparing Dynamic Parameters with GObject Properties</title>
|
||||
<para>
|
||||
Your first exposure to dparams may be to convert an existing element from
|
||||
using object properties to using dparams. The following table gives an
|
||||
overview of the difference between these approaches. The significance of
|
||||
these differences should become apparent later on.
|
||||
</para>
|
||||
<informaltable frame="all">
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry>Object Properties</entry>
|
||||
<entry>Dynamic Parameters</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><emphasis>Parameter definition</emphasis></entry>
|
||||
<entry>Class level at compile time</entry>
|
||||
<entry>Any level at run time</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><emphasis>Getting and setting</emphasis></entry>
|
||||
<entry>Implemented by element subclass as functions</entry>
|
||||
<entry>Handled entirely by dparams subsystem</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><emphasis>Extra objects required</emphasis></entry>
|
||||
<entry>None - all functionality is derived from base GObject</entry>
|
||||
<entry>Element needs to create and store a <filename>GstDParamManager</filename> at object creation</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><emphasis>Frequency and resolution of updates</emphasis></entry>
|
||||
<entry>Object properties will only be updated between calls to _get, _chain or _loop</entry>
|
||||
<entry>dparams can be updated at any rate independant of calls to _get, _chain or _loop up to sample-level accuracy</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-dparam-start">
|
||||
<title>Getting Started</title>
|
||||
|
||||
<para>
|
||||
The dparams subsystem is contained within the
|
||||
<filename>gstcontrol</filename> library. You need to include the header in
|
||||
your element's source file:
|
||||
</para>
|
||||
<programlisting>
|
||||
#include <gst/control/control.h>
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
Even though the <filename>gstcontrol</filename> library may be linked into
|
||||
the host application, you should make sure it is loaded in your
|
||||
<filename>plugin_init</filename> function:
|
||||
</para>
|
||||
<programlisting>
|
||||
static gboolean
|
||||
plugin_init (GModule *module, GstPlugin *plugin)
|
||||
{
|
||||
...
|
||||
|
||||
/* load dparam support library */
|
||||
if (!gst_library_load ("gstcontrol"))
|
||||
{
|
||||
gst_info ("example: could not load support library: 'gstcontrol'\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
You need to store an instance of <filename>GstDParamManager</filename> in
|
||||
your element's struct:
|
||||
</para>
|
||||
<programlisting>
|
||||
struct _GstExample {
|
||||
GstElement element;
|
||||
...
|
||||
|
||||
GstDParamManager *dpman;
|
||||
|
||||
...
|
||||
};
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
The <filename>GstDParamManager</filename> can be initialised in your
|
||||
element's init function:
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
gst_example_init (GstExample *example)
|
||||
{
|
||||
...
|
||||
|
||||
example->dpman = gst_dpman_new ("example_dpman", GST_ELEMENT(example));
|
||||
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-dparam-define">
|
||||
<title>Defining Parameter Specificiations</title>
|
||||
<para>
|
||||
You can define the dparams you need anywhere within your element but will
|
||||
usually need to do so in only a couple of places:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
In the element <filename>init</filename> function, just after the call
|
||||
to <filename>gst_dpman_new</filename>
|
||||
</listitem>
|
||||
<listitem>
|
||||
Whenever a new pad is created so that parameters can affect data going
|
||||
into or out of a specific pad. An example of this would be a mixer
|
||||
element where a seperate volume parameter is needed on every pad.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
There are three different ways the dparams subsystem can pass parameters
|
||||
into your element. Which one you use will depend on how that parameter is
|
||||
used within your element. Each of these methods has its own function to
|
||||
define a required dparam:
|
||||
<itemizedlist>
|
||||
<listitem><filename>gst_dpman_add_required_dparam_direct</filename></listitem>
|
||||
<listitem><filename>gst_dpman_add_required_dparam_callback</filename></listitem>
|
||||
<listitem><filename>gst_dpman_add_required_dparam_array</filename></listitem>
|
||||
</itemizedlist>
|
||||
These functions will return TRUE if the required dparam was added
|
||||
successfully.
|
||||
</para>
|
||||
<para>
|
||||
The following function will be used as an example.
|
||||
<programlisting>
|
||||
gboolean
|
||||
gst_dpman_add_required_dparam_direct (GstDParamManager *dpman,
|
||||
GParamSpec *param_spec,
|
||||
gboolean is_log,
|
||||
gboolean is_rate,
|
||||
gpointer update_data)
|
||||
</programlisting>
|
||||
The common parameters to these functions are:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<filename>GstDParamManager *dpman</filename> the element's dparam
|
||||
manager
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>GParamSpec *param_spec</filename> the param spec which defines
|
||||
the required dparam
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>gboolean is_log</filename> whether this dparam value should be
|
||||
interpreted on a log scale (such as a frequency or a decibel value)
|
||||
</listitem>
|
||||
<listitem>
|
||||
<filename>gboolean is_rate</filename> whether this dparam value is a
|
||||
proportion of the sample rate. For example with a sample rate of 44100,
|
||||
0.5 would be 22050 Hz and 0.25 would be 11025 Hz.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<sect2 id="sect-dparam-direct">
|
||||
<title>Direct Method</title>
|
||||
<para>
|
||||
This method is the simplest and has the lowest overhead for parameters
|
||||
which change less frequently than the sample rate. First you need
|
||||
somewhere to store the parameter - this will usually be in your element's
|
||||
stuct.
|
||||
</para>
|
||||
<programlisting>
|
||||
struct _GstExample {
|
||||
GstElement element;
|
||||
...
|
||||
|
||||
GstDParamManager *dpman;
|
||||
gfloat volume;
|
||||
...
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
Then to define the required dparam just call
|
||||
<filename>gst_dpman_add_required_dparam_direct</filename> and pass in the
|
||||
location of the parameter to change. In this case the location is
|
||||
<filename>&(example->volume)</filename>.
|
||||
</para>
|
||||
<programlisting>
|
||||
gst_dpman_add_required_dparam_direct (
|
||||
example->dpman,
|
||||
g_param_spec_float("volume","Volume","Volume of the audio",
|
||||
0.0, 1.0, 0.8, G_PARAM_READWRITE),
|
||||
FALSE,
|
||||
FALSE,
|
||||
&(example->volume)
|
||||
);
|
||||
</programlisting>
|
||||
<para>
|
||||
You can now use <filename>example->volume</filename> anywhere in your
|
||||
element knowing that it will always contain the correct value to use.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="sect-dparam-callback">
|
||||
<title>Callback Method</title>
|
||||
<para>
|
||||
This should be used if the you have other values to calculate whenever a
|
||||
parameter changes. If you used the direct method you wouldn't know if a
|
||||
parameter had changed so you would have to recalculate the other values
|
||||
every time you needed them. By using the callback method, other values
|
||||
only have to be recalculated when the dparam value actually changes.
|
||||
</para>
|
||||
<para>
|
||||
The following code illustrates an instance where you might want to use the
|
||||
callback method. If you had a volume dparam which was represented by a
|
||||
gfloat number, your element may only deal with integer arithmatic. The
|
||||
callback could be used to calculate the integer scaler when the volume
|
||||
changes. First you will need somewhere to store these values.
|
||||
</para>
|
||||
<programlisting>
|
||||
struct _GstExample {
|
||||
GstElement element;
|
||||
...
|
||||
|
||||
GstDParamManager *dpman;
|
||||
gfloat volume_f;
|
||||
gint volume_i;
|
||||
...
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
When the required dparam is defined, the callback function
|
||||
<filename>gst_example_update_volume</filename> and some user data (which
|
||||
in this case is our element instance) is passed in to the call to
|
||||
<filename>gst_dpman_add_required_dparam_callback</filename>.
|
||||
</para>
|
||||
<programlisting>
|
||||
gst_dpman_add_required_dparam_callback (
|
||||
example->dpman,
|
||||
g_param_spec_float("volume","Volume","Volume of the audio",
|
||||
0.0, 1.0, 0.8, G_PARAM_READWRITE),
|
||||
FALSE,
|
||||
FALSE,
|
||||
gst_example_update_volume,
|
||||
example
|
||||
);
|
||||
</programlisting>
|
||||
<para>
|
||||
The callback function needs to conform to this signiture
|
||||
</para>
|
||||
<programlisting>
|
||||
typedef void (*GstDPMUpdateFunction) (GValue *value, gpointer data);
|
||||
</programlisting>
|
||||
<para>
|
||||
In our example the callback function looks like this
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
gst_example_update_volume(GValue *value, gpointer data)
|
||||
{
|
||||
GstExample *example = (GstExample*)data;
|
||||
g_return_if_fail(GST_IS_EXAMPLE(example));
|
||||
|
||||
example->volume_f = g_value_get_float(value);
|
||||
example->volume_i = example->volume_f * 8192;
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
Now <filename>example->volume_i</filename> can be used elsewhere and it
|
||||
will always contain the correct value.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="sect-dparam-array">
|
||||
<title>Array Method</title>
|
||||
<para>
|
||||
This method is quite different from the other two. It could be thought of
|
||||
as a specialised method which should only be used if you need the
|
||||
advantages that it provides. Instead of giving the element a single value
|
||||
it provides an array of values where each item in the array corresponds to
|
||||
a sample of audio in your buffer. There are a couple of reasons why this
|
||||
might be useful.
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
Certain optimisations may be possible since you can iterate over your
|
||||
dparams array and your buffer data together.
|
||||
</listitem>
|
||||
<listitem>
|
||||
Some dparams may be able to interpolate changing values at the sample
|
||||
rate. This would allow the array to contain very smoothly changing
|
||||
values which may be required for the stability and quality of some DSP
|
||||
algorithms.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
The array method is currently the least mature of the three methods and is
|
||||
not yet ready to be used in elements, but plugin writers should be aware
|
||||
of its existance for the future.
|
||||
</para>
|
||||
</sect2>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-dparam-loop">
|
||||
<title>The Data Processing Loop</title>
|
||||
<para>
|
||||
This is the most critical aspect of the dparams subsystem as it relates to
|
||||
elements. In a traditional audio processing loop, a <filename>for</filename>
|
||||
loop will usually iterate over each sample in the buffer, processing one
|
||||
sample at a time until the buffer is finished. A simplified loop with no
|
||||
error checking might look something like this.
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
example_chain (GstPad *pad, GstBuffer *buf)
|
||||
{
|
||||
...
|
||||
gfloat *float_data;
|
||||
int j;
|
||||
GstExample *example = GST_EXAMPLE(GST_OBJECT_PARENT (pad));
|
||||
int num_samples = GST_BUFFER_SIZE(buf)/sizeof(gfloat);
|
||||
float_data = (gfloat *)GST_BUFFER_DATA(buf);
|
||||
...
|
||||
for (j = 0; j < num_samples; j++) {
|
||||
float_data[j] *= example->volume;
|
||||
}
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
To make this dparams aware, a couple of changes are needed.
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
example_chain (GstPad *pad, GstBuffer *buf)
|
||||
{
|
||||
...
|
||||
int j = 0;
|
||||
GstExample *example = GST_EXAMPLE(GST_OBJECT_PARENT (pad));
|
||||
int num_samples = GST_BUFFER_SIZE(buf)/sizeof(gfloat);
|
||||
gfloat *float_data = (gfloat *)GST_BUFFER_DATA(buf);
|
||||
int frame_countdown = GST_DPMAN_PREPROCESS(example->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
|
||||
...
|
||||
while (GST_DPMAN_PROCESS_COUNTDOWN(example->dpman, frame_countdown, j)) {
|
||||
float_data[j++] *= example->volume;
|
||||
}
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The biggest changes here are 2 new macros,
|
||||
<filename>GST_DPMAN_PREPROCESS</filename> and
|
||||
<filename>GST_DPMAN_PROCESS_COUNTDOWN</filename>. You will also notice that
|
||||
the for loop has become a while loop.
|
||||
<filename>GST_DPMAN_PROCESS_COUNTDOWN</filename> is called as the condition
|
||||
for the while loop so that any required dparams can be updated in the middle
|
||||
of a buffer if required. This is because one of the required behaviours of
|
||||
dparams is that they can be <emphasis>sample accurate</emphasis>. This means
|
||||
that parameters change at the exact timestamp that they are supposed to -
|
||||
not after the buffer has finished being processed.
|
||||
</para>
|
||||
<para>
|
||||
It may be alarming to see a macro as the condition for a while loop, but it
|
||||
is actually very efficient. The macro expands to the following.
|
||||
</para>
|
||||
<programlisting>
|
||||
#define GST_DPMAN_PROCESS_COUNTDOWN(dpman, frame_countdown, frame_count) \
|
||||
(frame_countdown-- || \
|
||||
(frame_countdown = GST_DPMAN_PROCESS(dpman, frame_count)))
|
||||
</programlisting>
|
||||
<para>
|
||||
So as long as <filename>frame_countdown</filename> is greater than 0,
|
||||
<filename>GST_DPMAN_PROCESS</filename> will not be called at all. Also in
|
||||
many cases, <filename>GST_DPMAN_PROCESS</filename> will do nothing and
|
||||
simply return 0, meaning that there is no more data in the buffer to
|
||||
process.
|
||||
</para>
|
||||
<para>
|
||||
The macro <filename>GST_DPMAN_PREPROCESS</filename> will do the following:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
Update any dparams which are due to be updated.
|
||||
</listitem>
|
||||
<listitem>
|
||||
Calculate how many samples should be processed before the next required
|
||||
update
|
||||
</listitem>
|
||||
<listitem>
|
||||
Return the number of samples until next update, or the number of samples
|
||||
in the buffer - whichever is less.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
In fact <filename>GST_DPMAN_PROCESS</filename> may do the same things as
|
||||
<filename>GST_DPMAN_PREPROCESS</filename> depending on the mode that the
|
||||
dparam manager is running in (see below).
|
||||
</para>
|
||||
<sect2 id="sect-dparam-modes">
|
||||
<title>DParam Manager Modes</title>
|
||||
<para>
|
||||
A brief explanation of dparam manager modes might be useful here even
|
||||
though it doesn't generally affect the way your element is written. There
|
||||
are different ways media applications will be used which require that an
|
||||
element's parameters be updated in differently. These include:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<emphasis>Timelined</emphasis> - all parameter changes are known in
|
||||
advance before the pipeline is run.
|
||||
</listitem>
|
||||
<listitem>
|
||||
<emphasis>Realtime low-latency</emphasis> - Nothing is known ahead of
|
||||
time about when a parameter might change. Changes need to be
|
||||
propagated to the element as soon as possible.
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
When a dparam-aware application gets the dparam manager for an element,
|
||||
the first thing it will do is set the dparam manager mode. Current modes
|
||||
are <filename>"synchronous"</filename> and
|
||||
<filename>"asynchronous"</filename>.
|
||||
</para>
|
||||
<para>
|
||||
If you are in a realtime low-latency situation then the
|
||||
<filename>"synchronous"</filename> mode is appropriate. During
|
||||
<filename>GST_DPMAN_PREPROCESS</filename> this mode will poll all dparams
|
||||
for required updates and propagate them.
|
||||
<filename>GST_DPMAN_PROCESS</filename> will do nothing in this mode. To
|
||||
then achieve the desired latency, the size of the buffers needs to be
|
||||
reduced so that the dparams will be polled for updates at the desired
|
||||
frequency.
|
||||
</para>
|
||||
<para>
|
||||
In a timelined situation, the <filename>"asynchronous"</filename> mode
|
||||
will be required. This mode hasn't actually been implemented yet but will
|
||||
be described anyway. The <filename>GST_DPMAN_PREPROCESS</filename> call
|
||||
will precalculate when and how often each dparam needs to update for the
|
||||
duration of the current buffer. From then on
|
||||
<filename>GST_DPMAN_PROCESS</filename> will propagate the calculated
|
||||
updates each time it is called until end of the buffer. If the application
|
||||
is rendering to disk in non-realtime, the render could be sped up by
|
||||
increasing the buffer size. In the <filename>"asynchronous"</filename>
|
||||
mode this could be done without affecting the sample accuracy of the
|
||||
parameter updates
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="sect-dparam-audio-video">
|
||||
<title>DParam Manager Modes</title>
|
||||
<para>
|
||||
All of the explanation so far has presumed that the buffer contains audio
|
||||
data with many samples. Video should be regarded differently since a video
|
||||
buffer often contains only 1 frame. In this case some of the complexity of
|
||||
dparams isn't required but the other benefits still make it useful for
|
||||
video parameters. If a buffer only contains one frame of video, only a
|
||||
single call to <filename>GST_DPMAN_PREPROCESS</filename> should be
|
||||
required. For more than one frame per buffer, treat it the same as the
|
||||
audio case.
|
||||
</para>
|
||||
</sect2>
|
||||
</chapter>
|
0
docs/pwg/advanced-midi.xml
Normal file
0
docs/pwg/advanced-midi.xml
Normal file
6
docs/pwg/advanced-request.xml
Normal file
6
docs/pwg/advanced-request.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<chapter id="cha-advanced-request">
|
||||
<title>Request pads</title>
|
||||
<para>
|
||||
aka pushing and pulling
|
||||
</para>
|
||||
</chapter>
|
27
docs/pwg/advanced-scheduling.xml
Normal file
27
docs/pwg/advanced-scheduling.xml
Normal file
|
@ -0,0 +1,27 @@
|
|||
<chapter id="cha-loopbased-sched">
|
||||
<title>How scheduling works</title>
|
||||
<para>
|
||||
aka pushing and pulling
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-loopbased-loopfn">
|
||||
<title>How a loopfunc works</title>
|
||||
<para>
|
||||
aka pulling and pushing
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-loopbased-secnd">
|
||||
<title>Adding a second output</title>
|
||||
<para>
|
||||
Identity is now a tee
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-loopbased-modappl">
|
||||
<title>Modifying the test application</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
|
88
docs/pwg/advanced-types.xml
Normal file
88
docs/pwg/advanced-types.xml
Normal file
|
@ -0,0 +1,88 @@
|
|||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-building-types">
|
||||
<title>Types and Properties</title>
|
||||
<para>
|
||||
There is a very large set of possible types that may be used to pass data
|
||||
between elements. Indeed, each new element that is defined may use a new
|
||||
data format (though unless at least one other element recognises that
|
||||
format, it will be most likely be useless since nothing will be able to
|
||||
link with it).
|
||||
</para>
|
||||
<para>
|
||||
In order for types to be useful, and for systems like autopluggers to
|
||||
work, it is neccessary that all elements agree on the type definitions,
|
||||
and which properties are required for each type. The &GStreamer; framework
|
||||
itself simply provides the ability to define types and parameters, but
|
||||
does not fix the meaning of types and parameters, and does not enforce
|
||||
standards on the creation of new types. This is a matter for a policy to
|
||||
decide, not technical systems to enforce.
|
||||
</para>
|
||||
<para>
|
||||
For now, the policy is simple:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not create a new type if you could use one which already exists.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If creating a new type, discuss it first with the other &GStreamer;
|
||||
developers, on at least one of: IRC, mailing lists, the &GStreamer;
|
||||
wiki.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Try to ensure that the name for a new format is as unlikely to
|
||||
conflict with anything else created already, and is not a more
|
||||
generalised name than it should be. For example: "audio/compressed"
|
||||
would be too generalised a name to represent audio data compressed
|
||||
with an mp3 codec. Instead "audio/mp3" might be an appropriate name,
|
||||
or "audio/compressed" could exist and have a property indicating the
|
||||
type of compression used.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Ensure that, when you do create a new type, you specify it clearly,
|
||||
and get it added to the list of known types so that other developers
|
||||
can use the type correctly when writing their elements.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-types-test" xreflabel="Building a Simple Format for Testing">
|
||||
<title>Building a Simple Format for Testing</title>
|
||||
<para>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-types-mime" xreflabel="A Simple Mime Type">
|
||||
<title>A Simple Mime Type</title>
|
||||
<para>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-types-properties" xreflabel="Type Properties">
|
||||
<title>Type Properties</title>
|
||||
<para>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-types-typefind" xreflabel="Typefind Functions and Autoplugging">
|
||||
<title>Typefind Functions and Autoplugging</title>
|
||||
<para>
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
14
docs/pwg/appendix-checklist.xml
Normal file
14
docs/pwg/appendix-checklist.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<chapter id="cha-checklist-filter">
|
||||
<title>
|
||||
Things to check when writing a filter
|
||||
</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
<chapter id="cha-checklist-srcsink">
|
||||
<title>
|
||||
Things to check when writing a source or sink
|
||||
</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
0
docs/pwg/appendix-python.xml
Normal file
0
docs/pwg/appendix-python.xml
Normal file
0
docs/pwg/base.css
Normal file
0
docs/pwg/base.css
Normal file
18
docs/pwg/basics-autoplugging.xml
Normal file
18
docs/pwg/basics-autoplugging.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-autopluggers">
|
||||
<title>Autopluggers</title>
|
||||
<para>
|
||||
&GStreamer; has an autoplugging mechanism, which enables application writers
|
||||
to simply specify start and end elements for a path, and the system will
|
||||
then create a path which links these elements, in accordance with the type
|
||||
information provided by the elements.
|
||||
</para>
|
||||
<para>
|
||||
It is possible to devise many different schemes for generating such
|
||||
pathways, perhaps to optimise based on special criteria, or with some
|
||||
specific constraints. It is thus possible to define new autoplugging
|
||||
systems, using the plugin system.
|
||||
</para>
|
||||
</chapter>
|
32
docs/pwg/basics-buffers.xml
Normal file
32
docs/pwg/basics-buffers.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-buffers">
|
||||
<title>Buffers</title>
|
||||
<para>
|
||||
Buffers are structures used to pass data between elements. All streams of
|
||||
data are chopped up into chunks which are stored in buffers. Buffers can be
|
||||
of any size, and also contain metadata indicating the type of data contained
|
||||
in them. Buffers can be allocated by various different schemes, and may
|
||||
either be passed on by elements or unreferenced (and the memory used by the
|
||||
buffer freed).
|
||||
</para>
|
||||
|
||||
<sect1 id="sect1-buffers-anatomy">
|
||||
<title>Anatomy of a buffer</title>
|
||||
<para>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="sect1-buffers-refcounts">
|
||||
<title>Refcounts and mutability</title>
|
||||
<para>
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="sect1-buffers-metadata">
|
||||
<title>Metadata</title>
|
||||
<para>
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
39
docs/pwg/basics-elements.xml
Normal file
39
docs/pwg/basics-elements.xml
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-basics-elements">
|
||||
<title>Elements, Plugins, and Filters</title>
|
||||
<para>
|
||||
In the &GStreamer; framework, a <emphasis>plugin</emphasis> is a specific
|
||||
sort of code module that gets loaded when a program requests the
|
||||
functionality that the plugin provides. A plugin is essentially a shared
|
||||
code library.
|
||||
<emphasis>Filters</emphasis> are an
|
||||
important subset of plugins that process data, as opposed to producing or
|
||||
consuming data. (Producers and consumers of data are called
|
||||
<emphasis>source</emphasis> and <emphasis>sink</emphasis> plugins,
|
||||
respectively.)
|
||||
</para>
|
||||
<para>
|
||||
Elements are at the core of &GStreamer;. Without elements, &GStreamer; is
|
||||
just a bunch of pipe fittings with nothing to connect. A large number of
|
||||
elements (filters, sources, and sinks) ship with &GStreamer;, but extra
|
||||
elements can also be written. The purpose of this guide is to help you
|
||||
learn to create new elements.
|
||||
</para>
|
||||
<para>
|
||||
An element may be constructed in several different ways, but all must
|
||||
conform to the same basic rules. This guide presents one basic way to build
|
||||
a filter elementA simple filter may be built with the
|
||||
FilterFactory, where the only code that need be written is the actual filter
|
||||
code. A more complex filter, or a source or sink, will need to be written
|
||||
out fully for complete access to the features and performance possible with
|
||||
&GStreamer;.
|
||||
</para>
|
||||
<para>
|
||||
The implementation of a new element will be contained in a plugin: a single
|
||||
plugin may contain the implementation of several elements, or just a single
|
||||
one.
|
||||
</para>
|
||||
</chapter>
|
||||
|
8
docs/pwg/basics-events.xml
Normal file
8
docs/pwg/basics-events.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-events">
|
||||
<title>Events</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
30
docs/pwg/basics-plugins.xml
Normal file
30
docs/pwg/basics-plugins.xml
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-plugins">
|
||||
<title>Plugins</title>
|
||||
<para>
|
||||
Extensions to &GStreamer; can be made using a plugin mechanism. This is used
|
||||
extensively in &GStreamer; even if only the standard package is being used:
|
||||
a few very basic functions reside in the core library, and all others are
|
||||
implemented in plugins.
|
||||
</para>
|
||||
<para>
|
||||
Plugins are only loaded when needed: a plugin registry is used to store the
|
||||
details of the plugins so that it is not neccessary to load all plugins to
|
||||
determine which are needed. This registry needs to be updated whenever a new
|
||||
plugin is added to the system: see the <emphasis>gst-register</emphasis>
|
||||
utility and the documentation in the &GstAppDevMan; for more details.
|
||||
</para>
|
||||
<para>
|
||||
User extensions to &GStreamer; can be installed in the main plugin
|
||||
directory, and will immediately be available for use in applications.
|
||||
<emphasis>gst-register</emphasis> should be run to update the repository:
|
||||
but the system should work correctly even if it hasn't been - it will just
|
||||
take longer to load the correct plugin.
|
||||
</para>
|
||||
<para>
|
||||
User specific plugin directories and registries will be available in future
|
||||
versions of &GStreamer;.
|
||||
</para>
|
||||
</chapter>
|
15
docs/pwg/basics-types.xml
Normal file
15
docs/pwg/basics-types.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-typing">
|
||||
<title>Typing and Properties</title>
|
||||
<para>
|
||||
A type system is used to ensure that the data passed between elements is in
|
||||
a recognised format, and that the various parameters required to fully
|
||||
specify that format match up correctly. Each connection that is made between
|
||||
elements has a specified type. This is related, but different, to the
|
||||
metadata in buffers which describes the type of data in that particular
|
||||
buffer. See the next chapter of this document for details of the available
|
||||
types.
|
||||
</para>
|
||||
</chapter>
|
295
docs/pwg/building-boiler.xml
Normal file
295
docs/pwg/building-boiler.xml
Normal file
|
@ -0,0 +1,295 @@
|
|||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-building-boiler" xreflabel="Constructing the Boilerplate">
|
||||
<title>Constructing the Boilerplate</title>
|
||||
<para>
|
||||
In this chapter you will learn how to construct the bare minimum code for a
|
||||
new plugin. Starting from ground zero, you will see how to get the
|
||||
&GStreamer; template source. Then you will learn how to use a few simple
|
||||
command line tools to copy and modify a template plugin and thus create your
|
||||
new plugin. By the end of all this, you will have a functional audio filter
|
||||
plugin that you can compile and test.
|
||||
</para>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-boiler-source" xreflabel="Getting the Gstreamer Plugin Templates">
|
||||
<title>Getting the Gstreamer Plugin Templates</title>
|
||||
<para>
|
||||
There are currently two ways to develop a new plugin for &GStreamer;: You
|
||||
can write the entire plugin by hand, or you can copy an existing plugin
|
||||
template and write the plugin code you need. The second method is by far
|
||||
the simpler of the two, so the first method will not even be described
|
||||
here.
|
||||
</para>
|
||||
<para>
|
||||
The first step is to check out a copy of the
|
||||
<filename>gst-template</filename> CVS module to get an important tool and
|
||||
the source code template for the basic &GStreamer; plugin. To check out
|
||||
the <filename>gst-template</filename> module, type the following two
|
||||
commands on a command line:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>shell $ </prompt><userinput>cvs -d:pserver:anonymous@cvs.gstreamer.sourceforge.net:/cvsroot/gstreamer login</userinput>
|
||||
Logging in to :pserver:anonymous@cvs.gstreamer.sourceforge.net:2401/cvsroot/gstreamer
|
||||
CVS password:
|
||||
<prompt>shell $ </prompt><userinput>cvs -z3 -d:pserver:anonymous@cvs.gstreamer.sourceforge.net:/cvsroot/gstreamer co gst-template</userinput>
|
||||
U gst-template/README
|
||||
U gst-template/gst-app/AUTHORS
|
||||
U gst-template/gst-app/ChangeLog
|
||||
U gst-template/gst-app/Makefile.am
|
||||
U gst-template/gst-app/NEWS
|
||||
U gst-template/gst-app/README
|
||||
U gst-template/gst-app/autogen.sh
|
||||
U gst-template/gst-app/configure.ac
|
||||
U gst-template/gst-app/src/Makefile.am
|
||||
...
|
||||
</screen>
|
||||
<para>
|
||||
After the first command, you will have to press <keycap>ENTER</keycap> to
|
||||
log in to the CVS server. You might have to log in twice. The second
|
||||
command will check out a series of files and directories into <filename
|
||||
class="directory">./gst-template</filename>. The template you will be
|
||||
using is in <filename
|
||||
class="directory">./gst-template/gst-plugin/</filename> directory. You
|
||||
should look over the files in that directory to get a general idea of the
|
||||
structure of a source tree for a plugin.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-boiler-filterstamp" xreflabel="Using Filterstamp">
|
||||
<title>Using Filterstamp</title>
|
||||
<para>
|
||||
The first thing to do when making a new element is to specify some basic
|
||||
details about it: what its name is, who wrote it, what version number it
|
||||
is, etc. We also need to define an object to represent the element and to
|
||||
store the data the element needs. These details are collectively known as
|
||||
the <emphasis>boilerplate</emphasis>.
|
||||
</para>
|
||||
<para>
|
||||
The standard way of defining the boilerplate is simply to write some code,
|
||||
and fill in some structures. As mentioned in the previous section, the
|
||||
easiest way to do this is to copy a template and add functionality
|
||||
according to your needs. To help you do so, there is a script called
|
||||
<command>pluginstamp.sh</command> in the <filename
|
||||
class="directory">tools/</filename> directory of the
|
||||
<filename>gst-template</filename> source tree that does exactly this.
|
||||
</para>
|
||||
<para>
|
||||
To use <command>pluginstamp.sh</command>, first open up a terminal window.
|
||||
Change to the <filename class="directory">gst-template</filename>
|
||||
directory, and then run the <command>pluginstamp.sh</command> command. The
|
||||
arguments to the <command>pluginstamp.sh</command> are:
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>the name of the plugin, and</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
the directory that should hold a new subdirectory for the source tree
|
||||
of the plugin.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
Note that capitalization is important for the name of the plugin. Under
|
||||
some operating systems, capitalization is also important when specifying
|
||||
directory names. For example, the
|
||||
following commands create the ExampleFilter plugin based on the plugin
|
||||
template and put the output files in a new directory called <filename
|
||||
class="directory">~/src/examplefilter/</filename>:
|
||||
</para>
|
||||
<screen>
|
||||
<prompt>shell $ </prompt><userinput>cd gst-template</userinput>
|
||||
<prompt>shell $ </prompt><userinput>tools/pluginstamp.sh ExampleFilter ~/src</userinput>
|
||||
</screen>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 name="sect1-boiler-examine" xreflabel="Examining the Basic Code">
|
||||
<title>Examining the Basic Code</title>
|
||||
<para>
|
||||
First we will examine the code you would be likely to place in a header
|
||||
file (although since the interface to the code is entirely defined by the
|
||||
pluging system, and doesn't depend on reading a header file, this is not
|
||||
crucial.)
|
||||
|
||||
The code here can be found in
|
||||
<filename>examples/pwg/examplefilter/boiler/gstexamplefilter.h</filename>.
|
||||
</para>
|
||||
|
||||
<example name="ex-boiler-examine-h" xreflabel="Example Plugin Header File">
|
||||
<title>Example Plugin Header File</title>
|
||||
<programlisting>
|
||||
/* Definition of structure storing data for this element. */
|
||||
typedef struct _GstExample GstExample;
|
||||
|
||||
struct _GstExample {
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad,*srcpad;
|
||||
|
||||
gint8 active;
|
||||
};
|
||||
|
||||
/* Standard definition defining a class for this element. */
|
||||
typedef struct _GstExampleClass GstExampleClass;
|
||||
struct _GstExampleClass {
|
||||
GstElementClass parent_class;
|
||||
};
|
||||
|
||||
/* Standard macros for defining types for this element. */
|
||||
#define GST_TYPE_EXAMPLE \
|
||||
(gst_example_get_type())
|
||||
#define GST_EXAMPLE(obj) \
|
||||
(GTK_CHECK_CAST((obj),GST_TYPE_EXAMPLE,GstExample))
|
||||
#define GST_EXAMPLE_CLASS(klass) \
|
||||
(GTK_CHECK_CLASS_CAST((klass),GST_TYPE_EXAMPLE,GstExample))
|
||||
#define GST_IS_EXAMPLE(obj) \
|
||||
(GTK_CHECK_TYPE((obj),GST_TYPE_EXAMPLE))
|
||||
#define GST_IS_EXAMPLE_CLASS(obj) \
|
||||
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EXAMPLE))
|
||||
|
||||
/* Standard function returning type information. */
|
||||
GtkType gst_example_get_type(void);
|
||||
</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-boiler-filterfactory" xreflabel="Creating a Filter With FilterFactory">
|
||||
<title>Creating a Filter With FilterFactory (Future)</title>
|
||||
<para>
|
||||
A plan for the future is to create a FilterFactory, to make the process of
|
||||
making a new filter a simple process of specifying a few details, and
|
||||
writing a small amount of code to perform the actual data processing.
|
||||
Ideally, a FilterFactory would perform the tasks of boilerplate creation,
|
||||
code functionality implementation, and filter registration.
|
||||
</para>
|
||||
<para>
|
||||
Unfortunately, this has not yet been implemented. Even when someone
|
||||
eventually does write a FilterFactory, this element will not be able to
|
||||
cover all the possibilities available for filter writing. Thus, some
|
||||
plugins will always need to be manually coded and registered.
|
||||
</para>
|
||||
<para>
|
||||
Here is a rough outline of what is planned: You run the FilterFactory and
|
||||
give the factory a list of appropriate function pointers and data
|
||||
structures to define a filter. With a reasonable measure of preprocessor
|
||||
magic, you just need to provide a name for the filter and definitions of
|
||||
the functions and data structures desired. Then you call a macro from
|
||||
within plugin_init() that registers the new filter. All the fluff that
|
||||
goes into the definition of a filter is thus be hidden from view.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-boiler-details">
|
||||
<title>GstElementDetails</title>
|
||||
<para>
|
||||
The GstElementDetails structure gives a heirarchical type for the element,
|
||||
a human-readable description of the element, as well as author and version
|
||||
data. The entries are:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
A long, english, name for the element.
|
||||
</para></listitem><listitem><para>
|
||||
The type of the element, as a heirarchy. The heirarchy is defined by
|
||||
specifying the top level category, followed by a "/", followed by the
|
||||
next level category, etc. The type should be defined according to the
|
||||
guidelines elsewhere in this document. (FIXME: write the guidelines, and
|
||||
give a better reference to them)
|
||||
</para></listitem><listitem><para>
|
||||
A brief description of the purpose of the element.
|
||||
</para></listitem><listitem><para>
|
||||
The version number of the element. For elements in the main GStreamer
|
||||
source code, this will often simply be VERSION, which is a macro defined
|
||||
to be the version number of the current GStreamer version. The only
|
||||
requirement, however, is that the version number should increase
|
||||
monotonically.
|
||||
</para>
|
||||
<para>
|
||||
Version numbers should be stored in major.minor.patch form: ie, 3
|
||||
(decimal) numbers, separated by periods (.).
|
||||
</para></listitem><listitem><para>
|
||||
The name of the author of the element, optionally followed by a contact
|
||||
email address in angle brackets.
|
||||
</para></listitem><listitem><para>
|
||||
The copyright details for the element.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
For example:
|
||||
</para>
|
||||
<programlisting>
|
||||
static GstElementDetails example_details = {
|
||||
"An example plugin",
|
||||
"Example/FirstExample",
|
||||
"Shows the basic structure of a plugin",
|
||||
VERSION,
|
||||
"your name <your.name@your.isp>",
|
||||
"(C) 2001",
|
||||
};
|
||||
</programlisting>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-boiler-constructors">
|
||||
<title>Constructor Functions</title>
|
||||
<para>
|
||||
Each element has two functions which are used for construction of an
|
||||
element. These are the _class_init() function, which is used to initialise
|
||||
the class (specifying what signals and arguments the class has and setting
|
||||
up global state), and the _init() function, which is used to initialise a
|
||||
specific instance of the class.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-boiler-plugininit">
|
||||
<title>The plugin_init function</title>
|
||||
<para>
|
||||
Once we have written code defining all the parts of the plugin, we need to
|
||||
write the plugin_init() function. This is a special function, which is
|
||||
called as soon as the plugin is loaded, and must return a pointer to a newly
|
||||
allocated GstPlugin structure. This structure contains the details of all
|
||||
the facilities provided by the plugin, and is the mechanism by which the
|
||||
definitions are made available to the rest of the &GStreamer; system. Helper
|
||||
functions are provided to help fill the structure: for future compatability
|
||||
it is recommended that these functions are used, as documented below, rather
|
||||
than attempting to access the structure directly.
|
||||
</para>
|
||||
<para>
|
||||
Note that the information returned by the plugin_init() function will be
|
||||
cached in a central registry. For this reason, it is important that the same
|
||||
information is always returned by the function: for example, it must not
|
||||
make element factories available based on runtime conditions. If an element
|
||||
can only work in certain conditions (for example, if the soundcard is not
|
||||
being used by some other process) this must be reflected by the element
|
||||
being unable to enter the READY state if unavailable, rather than the plugin
|
||||
attempting to deny existence of the plugin.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
8
docs/pwg/building-chainfn.xml
Normal file
8
docs/pwg/building-chainfn.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-building-chainfn">
|
||||
<title>The chain function</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
9
docs/pwg/building-pads.xml
Normal file
9
docs/pwg/building-pads.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-building-pads">
|
||||
<title>Specifying the pads</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
|
9
docs/pwg/building-props.xml
Normal file
9
docs/pwg/building-props.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-building-args" xreflabel="Adding Arguments">
|
||||
<title>Adding Arguments</title>
|
||||
<para>
|
||||
Define arguments in enum.
|
||||
</para>
|
||||
</chapter>
|
||||
|
9
docs/pwg/building-signals.xml
Normal file
9
docs/pwg/building-signals.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-building-signals">
|
||||
<title>Signals</title>
|
||||
<para>
|
||||
Define signals in enum.
|
||||
</para>
|
||||
</chapter>
|
14
docs/pwg/building-state.xml
Normal file
14
docs/pwg/building-state.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<chapter id="cha-statemanage-states">
|
||||
<title>
|
||||
What are states?
|
||||
</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
<chapter id="cha-statemanage-filters">
|
||||
<title>
|
||||
Mangaging filter state
|
||||
</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
25
docs/pwg/building-testapp.xml
Normal file
25
docs/pwg/building-testapp.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<chapter id="cha-testapp-init">
|
||||
<title>Initialization</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-testapp-inst">
|
||||
<title>Instantiating the plugins</title>
|
||||
<para>
|
||||
(NOTE: we really should have a debugging Sink)
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-testapp-connect">
|
||||
<title>Connecting the plugins</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-testapp-running">
|
||||
<title>Running the pipeline</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
|
156
docs/pwg/gst-plugin-writers-guide.xml
Normal file
156
docs/pwg/gst-plugin-writers-guide.xml
Normal file
|
@ -0,0 +1,156 @@
|
|||
<?xml version='1.0'?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
|
||||
<!ENTITY % magic-entities SYSTEM "magic">
|
||||
%magic-entities;
|
||||
|
||||
<!ENTITY TITLEPAGE SYSTEM "titlepage.xml">
|
||||
|
||||
<!ENTITY INTRO_PREFACE SYSTEM "intro_preface.xml">
|
||||
<!ENTITY INTRO_BASICS SYSTEM "intro_basics.xml">
|
||||
|
||||
<!ENTITY BUILDING_BOILER SYSTEM "building_boiler.xml">
|
||||
<!ENTITY BUILDING_PADS SYSTEM "building_pads.xml">
|
||||
<!ENTITY BUILDING_CHAINFN SYSTEM "building_chainfn.xml">
|
||||
<!ENTITY BUILDING_STATE SYSTEM "building_state.xml">
|
||||
<!ENTITY BUILDING_PROPS SYSTEM "building_props.xml">
|
||||
<!ENTITY BUILDING_SIGNALS SYSTEM "building_signals.xml">
|
||||
<!ENTITY BUILDING_TESTAPP SYSTEM "building_testapp.xml">
|
||||
|
||||
<!ENTITY ADVANCED_SCHEDULING SYSTEM "advanced_scheduling.xml">
|
||||
<!ENTITY ADVANCED_TYPES SYSTEM "advanced_types.xml">
|
||||
<!ENTITY ADVANCED_REQUEST SYSTEM "advanced_request.xml">
|
||||
<!ENTITY ADVANCED_CLOCK SYSTEM "advanced_clock.xml">
|
||||
<!ENTITY ADVANCED_DPARAMS SYSTEM "advanced_dparams.xml">
|
||||
<!ENTITY ADVANCED_MIDI SYSTEM "advanced_midi.xml">
|
||||
|
||||
<!ENTITY OTHER_SOURCE SYSTEM "other_source.xml">
|
||||
<!ENTITY OTHER_SINK SYSTEM "other_sink.xml">
|
||||
<!ENTITY OTHER_AUTOPLUGGER SYSTEM "other_autoplugger.xml">
|
||||
|
||||
<!ENTITY APPENDIX_CHECKLIST SYSTEM "appendix_checklist.xml">
|
||||
<!ENTITY APPENDIX_PYTHON SYSTEM "appendix_python.xml">
|
||||
|
||||
<!ENTITY GStreamer "<application>GStreamer</application>">
|
||||
<!ENTITY GstVersion "0.4.1">
|
||||
<!ENTITY GstAppDevMan "<emphasis>GStreamer Application Development Manual</emphasis>">
|
||||
<!ENTITY GstLibRef "<emphasis>GStreamer Library Reference</emphasis>">
|
||||
]>
|
||||
|
||||
<book id="book-gst-plugin-writers-guide">
|
||||
&TITLEPAGE;
|
||||
|
||||
<!-- ############# part ############### -->
|
||||
|
||||
<part id="part-introduction" xreflabel="Introduction">
|
||||
<title>Introduction</title>
|
||||
<partintro>
|
||||
<para>
|
||||
&GStreamer; is an exremely powerful and versatile framework for creating
|
||||
streaming media applications. Many of the virtues of the &GStreamer;
|
||||
framework come from its modularity: &GStreamer; can seamlessly
|
||||
incorporate new plugin modules. But because modularity and power often
|
||||
come at a cost of greater complexity (consider, for example, <ulink
|
||||
type="http" url="http://www.omg.org/">CORBA</ulink>), writing new
|
||||
plugins is not always easy.
|
||||
</para>
|
||||
<para>
|
||||
This guide is intended to help you understand the &GStreamer; framework
|
||||
so you can develop new plugins to extend &GStreamer;'s functionality.
|
||||
This guide introduces most of the basic plugin writing issues in version
|
||||
&GstVersion; of &GStreamer;. This guide presents most issues in the
|
||||
context of an example audio filter plugin written in C. However, the
|
||||
guide also addresses some issues involved in writing other types of
|
||||
plugins, and the end of the guide also describes some of the Python
|
||||
bindings for &GStreamer;.
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
&INTRO_PREFACE;
|
||||
&INTRO_BASICS;
|
||||
</part>
|
||||
|
||||
<!-- ############ part ############# -->
|
||||
|
||||
<part id="part-building" xreflabel="Building a Filter">
|
||||
<title>Building a Filter</title>
|
||||
<partintro>
|
||||
<para>
|
||||
You now have the neccessary concepts to build your first plugin. In this
|
||||
part of the guide, you will learn how to apply these concepts to write a
|
||||
simple audio filter plugin. The previous parts of the guide have
|
||||
contained no explicit example code, perhaps making things a bit abstract
|
||||
and difficult to understand. In contrast, this section will present both
|
||||
applications and code by following the development of an example audio
|
||||
filter plugin called <quote>ExampleFilter</quote>.
|
||||
</para>
|
||||
<para>
|
||||
The example filter will begin with a single input pad and a single
|
||||
output pad. The filter will, at first, simply pass data through without
|
||||
modification. But by the end of this part of the guide, you will learn
|
||||
to add some more interesting functionality, including properties and
|
||||
signal handlers. And after reading the next part of the guide, <xref
|
||||
linkend="part-advanced"/>, you will be able to add even more
|
||||
functionality to your plugins.
|
||||
</para>
|
||||
<para>
|
||||
The example code used in this part of the guide can be found in
|
||||
<filename class="directory">examples/pwg/examplefilter/</filename> in
|
||||
your &GStreamer; directory.
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
&BUILDING_BOILER;
|
||||
&BUILDING_PADS;
|
||||
&BUILDING_CHAINFN;
|
||||
&BUILDING_STATE;
|
||||
&BUILDING_PROPS;
|
||||
&BUILDING_SIGNALS;
|
||||
&BUILDING_TESTAPP;
|
||||
</part>
|
||||
|
||||
<!-- ############ part ############# -->
|
||||
|
||||
<part id="part-advanced" xreflabel="Advanced Filter Concepts">
|
||||
<title>Advanced Filter Concepts</title>
|
||||
<partintro>
|
||||
<para>
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
&ADVANCED_SCHEDULING;
|
||||
&ADVANCED_TYPES;
|
||||
&ADVANCED_REQUEST;
|
||||
&ADVANCED_CLOCK;
|
||||
&ADVANCED_DPARAMS;
|
||||
&ADVANCED_MIDI;
|
||||
</part>
|
||||
|
||||
<!-- ############ part ############# -->
|
||||
|
||||
<part id="part-other" xreflabel="Other Element Types">
|
||||
<title>Other Element Types</title>
|
||||
<partintro>
|
||||
<para>
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
&OTHER_SOURCE;
|
||||
&OTHER_SINK;
|
||||
&OTHER_AUTOPLUGGER;
|
||||
</part>
|
||||
|
||||
<!-- ############ part ############# -->
|
||||
|
||||
<part id="part-appendix" xreflabel="Appendices">
|
||||
<title>Appendices</title>
|
||||
<partintro>
|
||||
<para>
|
||||
</para>
|
||||
</partintro>
|
||||
|
||||
&APPENDIX_CHECKLIST;
|
||||
&APPENDIX_PYTHON;
|
||||
</part>
|
||||
|
||||
</book>
|
472
docs/pwg/intro-basics.xml
Normal file
472
docs/pwg/intro-basics.xml
Normal file
|
@ -0,0 +1,472 @@
|
|||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-intro-basics" xreflabel="Basic Concepts">
|
||||
<title>Basic Concepts</title>
|
||||
<para>
|
||||
This chapter of the guide introduces the basic concepts of &GStreamer;.
|
||||
Understanding these concepts will help you see the issues involved in
|
||||
extending &GStreamer;. Many of these concepts are explained in greater
|
||||
detail in the &GstAppDevMan;. The basic concepts presented here serve mainly
|
||||
to refresh your memory.
|
||||
</para>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-basics-elements" xreflabel="Elements and Plugins">
|
||||
<title>Elements and Plugins</title>
|
||||
<para>
|
||||
Elements are at the core of &GStreamer;. In the context of plugin
|
||||
development, an <emphasis>element</emphasis> is an object derived from the
|
||||
<classname>GstElement</classname> class. An element provides some sort of
|
||||
functionality when connected with other elements. Without elements,
|
||||
&GStreamer; is just a bunch of conceptual pipe fittings with nothing to
|
||||
connect. A large number of elements ship with &GStreamer;, but extra
|
||||
elements can also be written. The purpose of this guide is to help you
|
||||
learn to create new elements, which are encapsulated in plugins as
|
||||
described below.
|
||||
</para>
|
||||
<para>
|
||||
A <emphasis>filter</emphasis> is an important type of element that
|
||||
processes a stream of data, as opposed to producing or consuming streams
|
||||
of data. Producers and consumers of data are called
|
||||
<emphasis>source</emphasis> and <emphasis>sink</emphasis> elements,
|
||||
respectively.
|
||||
</para>
|
||||
<para>
|
||||
Just writing a new element is not entirely enough, however: You will need
|
||||
to encapsulate your element in a plugin to enable &GStreamer; to use it. A
|
||||
<emphasis>plugin</emphasis> is essentially a loadable block of code,
|
||||
usually a shared object file or dynamically linked library. A single
|
||||
plugin may contain the implementation of several elements, or just a
|
||||
single one. For simplicity, this guide concentrates primarily on plugins
|
||||
containing one filter type element.
|
||||
</para>
|
||||
<para>
|
||||
The plugin mechanism is used everywhere in &GStreamer;, even if only the
|
||||
standard package is being used. A few very basic functions reside in the
|
||||
core library, and all others are implemented in plugins. A plugin registry
|
||||
is used to store the details of the plugins in an XML file. This way, a
|
||||
program using &GStreamer; does not have to load all plugins to determine
|
||||
which are needed. Plugins are only loaded when their provided elements are
|
||||
requested.
|
||||
</para>
|
||||
<para>
|
||||
See the &GstLibRef; for the current implementation details of <ulink
|
||||
type="http"
|
||||
url="http://gstreamer.net/docs/0.4.0/gstreamer/gstelement.html"><classname>GstElement</classname></ulink>
|
||||
and <ulink type="http"
|
||||
url="http://gstreamer.net/docs/0.4.0/gstreamer/gstreamer-gstplugin.html"><classname>GstPlugin</classname></ulink>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-basics-pads" xreflabel="Pads">
|
||||
<title>Pads</title>
|
||||
<para>
|
||||
<emphasis>Pads</emphasis> are used to negotiate connections and data flow
|
||||
between elements in &GStreamer;. A pad can be viewed as a
|
||||
<quote>place</quote> on an element where connections may be made with
|
||||
other elements. Pads have specific data handling capabilities: That is, a
|
||||
pad only knows how to give or receive certain types of data. Connections
|
||||
are only allowed when the capabilities of two pads are compatible.
|
||||
</para>
|
||||
<para>
|
||||
An analogy may be helpful here. A pad is similar to a plug or jack on a
|
||||
physical device. Consider, for example, a home theater system consisting
|
||||
of an amplifier, a DVD player, and a television. Connecting the DVD player
|
||||
to the amplifier is allowed only because both devices have audio jacks,
|
||||
and connecting the television to the DVD player is allowed because both
|
||||
devices have compatible video jacks. Pads in &GStreamer; serve the same
|
||||
purpose as the jacks in the home theater system.
|
||||
</para>
|
||||
<para>
|
||||
See the &GstLibRef; for the current implementation details of a <ulink
|
||||
type="http"
|
||||
url="http://gstreamer.net/docs/0.4.0/gstreamer/gstreamer-gstpad.html"><classname>GstPad</classname></ulink>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-basics-buffers" xreflabel="Buffers">
|
||||
<title>Buffers</title>
|
||||
<para>
|
||||
All streams of data in &GStreamer; are chopped up into chunks that are
|
||||
passed from a source pad on one element to a sink pad on another element.
|
||||
<emphasis>Buffers</emphasis> are structures used to hold these chunks of
|
||||
data. Buffers can be of any size, theoretically. Buffers may contain any
|
||||
sort of data that the two pads involved know how to handle: Normally, a
|
||||
buffer contains a chunk of some sort of audio or video data that flows
|
||||
from one element to another.
|
||||
</para>
|
||||
<para>
|
||||
Buffers also contain metadata describing the buffer's contents. Some of
|
||||
the important types of metadata are:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
A pointer to the buffer's data.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
An integer indicating the size of the buffer's data.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A <classname>GstData</classname> object describing the type of the
|
||||
buffer's data.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
A reference count indicating the number of elements currently
|
||||
holding a reference to the buffer. When the buffer reference count
|
||||
falls to zero, the buffer will be unlinked, and its memory will be
|
||||
freed in some sense (see the next part about <xref
|
||||
linkend="sect2-buffers-bufferpools"/> for more details).
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
See the &GstLibRef; for the current implementation details of a <ulink
|
||||
type="http"
|
||||
url="http://gstreamer.net/docs/0.4.0/gstreamer/gstreamer-gstbuffer.html"><classname>GstBuffer</classname></ulink>.
|
||||
</para>
|
||||
|
||||
<sect2 id="sect2-buffers-bufferpools" xreflabel="Buffer Allocation and
|
||||
Buffer Pools">
|
||||
<title>Buffer Allocation and Buffer Pools</title>
|
||||
<para>
|
||||
Buffers can be allocated using various schemes, and they may either be
|
||||
passed on by an element or unreferenced, thus freeing the memory used by
|
||||
the buffer.
|
||||
</para>
|
||||
<para>
|
||||
Normally, filter elements in &GStreamer; deal with a buffer in place,
|
||||
meaning that they do not create or destroy buffers. Sometimes, however,
|
||||
elements might need to alter the reference count of a buffer to copy or
|
||||
destroy the buffer, or to create a new buffer. For the most part, this
|
||||
guide does not deal with elements that alter a buffer's reference count,
|
||||
but buffer referencing is an important concept to know.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-basics-types" xreflabel="Types and Properties">
|
||||
<title>Types and Properties</title>
|
||||
<para>
|
||||
&GStreamer; uses a type system to ensure that the data passed between
|
||||
elements is in a recognized format. The type system is also important for
|
||||
ensuring that the parameters required to fully specify a format match up
|
||||
correctly when connecting pads between elements. Each connection that is
|
||||
made between elements has a specified type.
|
||||
</para>
|
||||
|
||||
<!-- ############ sect2 ############# -->
|
||||
|
||||
<sect2 id="sect2-types-basictypes" xreflabel="Basic Types">
|
||||
<title>The Basic Types</title>
|
||||
<para>
|
||||
&GStreamer; already supports many basic media types. Following is a
|
||||
table of the basic types used for buffers in &GStreamer;. The table
|
||||
contains the name ("mime type") and a description of the type, the
|
||||
properties associated with the type, and the meaning of each property.
|
||||
</para>
|
||||
|
||||
<table frame="all" id="table-basictypes" xreflabel="Table of Basic Types">
|
||||
<title>Table of Basic Types</title>
|
||||
<tgroup cols="6" align="left" colsep="1" rowsep="1">
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Mime Type</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Property</entry>
|
||||
<entry>Property Type</entry>
|
||||
<entry>Property Values</entry>
|
||||
<entry>Property Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody valign="top">
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry morerows="10">audio/raw</entry>
|
||||
<entry morerows="10">
|
||||
Unstructured and uncompressed raw audio data.
|
||||
</entry>
|
||||
<entry>rate</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>greater than 0</entry>
|
||||
<entry>
|
||||
The sample rate of the data, in samples per second.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>channels</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>greater than 0</entry>
|
||||
<entry>
|
||||
The number of channels of audio data.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>format</entry>
|
||||
<entry>string</entry>
|
||||
<entry><quote>int</quote> or <quote>float</quote></entry>
|
||||
<entry>
|
||||
The format in which the audio data is passed.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>law</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>0, 1, or 2</entry>
|
||||
<entry>
|
||||
(Valid only if the data is in integer format.) The law used to
|
||||
describe the data. The value 0 indicates <quote>linear</quote>, 1
|
||||
indicates <quote>mu law</quote>, and 2 indicates
|
||||
<quote>A law</quote>.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>endianness</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>0 or 1</entry>
|
||||
<entry>
|
||||
(Valid only if the data is in integer format.) The order of bytes
|
||||
in a sample. The value 0 means <quote>little-endian</quote> (bytes
|
||||
are least significant first). The value 1 means
|
||||
<quote>big-endian</quote> (most significant byte first).
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>signed</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>0 or 1</entry>
|
||||
<entry>
|
||||
(Valid only if the data is in integer format.) Whether the samples
|
||||
are signed or not.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>width</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>greater than 0</entry>
|
||||
<entry>
|
||||
(Valid only if the data is in integer format.) The number of bits
|
||||
per sample.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>depth</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>greater than 0</entry>
|
||||
<entry>
|
||||
(Valid only if the data is in integer format.) The number of bits
|
||||
used per sample. This must be less than or equal to the width: If
|
||||
the depth is less than the width, the low bits are assumed to be
|
||||
the ones used. For example, a width of 32 and a depth of 24 means
|
||||
that each sample is stored in a 32 bit word, but only the low 24
|
||||
bits are actually used.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>layout</entry>
|
||||
<entry>string</entry>
|
||||
<entry><quote>gfloat</quote></entry>
|
||||
<entry>
|
||||
(Valid only if the data is in float format.) A string representing
|
||||
the way in which the floating point data is represented.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>intercept</entry>
|
||||
<entry>float</entry>
|
||||
<entry>any, normally 0</entry>
|
||||
<entry>
|
||||
(Valid only if the data is in float format.) A floating point
|
||||
value representing the value that the signal
|
||||
<quote>centers</quote> on.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>slope</entry>
|
||||
<entry>float</entry>
|
||||
<entry>any, normally 1.0</entry>
|
||||
<entry>
|
||||
(Valid only if the data is in float format.) A floating point
|
||||
value representing how far the signal deviates from the intercept.
|
||||
A slope of 1.0 and an intercept of 0.0 would mean an audio signal
|
||||
with minimum and maximum values of -1.0 and 1.0. A slope of
|
||||
0.5 and intercept of 0.5 would represent values in the range 0.0
|
||||
to 1.0.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry morerows="4">audio/mp3</entry>
|
||||
<entry morerows="4">
|
||||
Audio data compressed using the mp3 encoding scheme.
|
||||
</entry>
|
||||
<entry>framed</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>0 or 1</entry>
|
||||
<entry>
|
||||
A true value indicates that each buffer contains exactly one
|
||||
frame. A false value indicates that frames and buffers do not
|
||||
necessarily match up.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>layer</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>1, 2, or 3</entry>
|
||||
<entry>
|
||||
The compression scheme layer used to compress the data.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>bitrate</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>greater than 0</entry>
|
||||
<entry>
|
||||
The bitrate, in kilobits per second. For VBR (variable bitrate)
|
||||
mp3 data, this is the average bitrate.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>channels</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>greater than 0</entry>
|
||||
<entry>
|
||||
The number of channels of audio data present.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>joint-stereo</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>0 or 1</entry>
|
||||
<entry>
|
||||
If true, this implies that stereo data is stored as a combined
|
||||
signal and the difference between the signals, rather than as two
|
||||
entirely separate signals. If true, the <quote>channels</quote>
|
||||
attribute must not be zero.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry morerows="0">audio/x-ogg</entry>
|
||||
<entry morerows="0">
|
||||
Audio data compressed using the Ogg Vorbis encoding scheme.
|
||||
</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
FIXME: There are currently no parameters defined for this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry morerows="2">video/raw</entry>
|
||||
<entry morerows="2">
|
||||
Raw video data.
|
||||
</entry>
|
||||
<entry>fourcc</entry>
|
||||
<entry>FOURCC code</entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
A FOURCC code identifying the format in which this data is stored.
|
||||
FOURCC (Four Character Code) is a simple system to allow
|
||||
unambiguous identification of a video datastream format. See
|
||||
<ulink url="http://www.webartz.com/fourcc/"
|
||||
type="http">http://www.webartz.com/fourcc/</ulink>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>width</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>greater than 0</entry>
|
||||
<entry>
|
||||
The number of pixels wide that each video frame is.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>height</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>greater than 0</entry>
|
||||
<entry>
|
||||
The number of pixels high that each video frame is.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry morerows="0">video/mpeg</entry>
|
||||
<entry morerows="0">
|
||||
Video data compressed using an MPEG encoding scheme.
|
||||
</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
FIXME: There are currently no parameters defined for this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry morerows="0">video/avi</entry>
|
||||
<entry morerows="0">
|
||||
Video data compressed using the AVI encoding scheme.
|
||||
</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
FIXME: There are currently no parameters defined for this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-basics-events" xreflabel="Events">
|
||||
<title>Events</title>
|
||||
<para>
|
||||
Events are a special type of data in &GStreamer;.
|
||||
<emphasis>Events</emphasis> indicate some sort of notable event that has
|
||||
happened somewhere in an element's pipeline. Just like any other data
|
||||
type, an event comes to an element through its pads. Events are contained
|
||||
in a <classname>GstBuffer</classname>, so an event buffer will contain
|
||||
only an event, not any other type of data.
|
||||
</para>
|
||||
<para>
|
||||
See the &GstLibRef; for the current implementation details of a <ulink
|
||||
type="http"
|
||||
url="http://gstreamer.net/docs/0.4.0/gstreamer/gstreamer-gstevent.html"><classname>GstEvent</classname></ulink>.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
192
docs/pwg/intro-preface.xml
Normal file
192
docs/pwg/intro-preface.xml
Normal file
|
@ -0,0 +1,192 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-intro-preface" xreflabel="Preface">
|
||||
<title>Preface</title>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-preface-who" xreflabel="Who Should Read This Guide?">
|
||||
<title>Who Should Read This Guide?</title>
|
||||
<para>
|
||||
This guide explains how to write new modules for &GStreamer;. The guide is
|
||||
relevant to several groups of people:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Anyone who wants to add support for new ways of processing data in
|
||||
&GStreamer;. For example, a person in this group might want to create
|
||||
a new data format converter, a new visualization tool, or a new
|
||||
decoder or encoder.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Anyone who wants to add support for new input and output devices. For
|
||||
example, people in this group might want to add the ability to write
|
||||
to a new video output system or read data from a digital camera or
|
||||
special microphone.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Anyone who wants to extend &GStreamer; in any way. You need to have an
|
||||
understanding of how the plugin system works before you can understand
|
||||
the constraints that the plugin system places on the rest of the code.
|
||||
Also, you might be surprised after reading this at how much can be
|
||||
done with plugins.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
This guide is not relevant to you if you only want to use the existing
|
||||
functionality of &GStreamer;, or if you just want to use an application
|
||||
that uses &GStreamer;. If you are only interested in using existing
|
||||
plugins to write a new application — and there are quite a lot of
|
||||
plugins already — you might want to check the &GstAppDevMan;. If you
|
||||
are just trying to get help with a &GStreamer; application, then you
|
||||
should check with the user manual for that particular application.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-preface-reading" xreflabel="Preliminary Reading">
|
||||
<title>Preliminary Reading</title>
|
||||
<para>
|
||||
This guide assumes that you are somewhat familiar with the basic workings
|
||||
of &GStreamer;. For a gentle introduction to programming concepts in
|
||||
&GStreamer;, you may wish to read the &GstAppDevMan; first. Also check out
|
||||
the documentation available on the <ulink type="http"
|
||||
url="http://gstreamer.net/docs/">&GStreamer; web site</ulink>,
|
||||
particularly the documents available in the <ulink type="http"
|
||||
url="http://gstreamer.net/wiki/">&GStreamer; wiki</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
Since &GStreamer; adheres to the GObject programming model, this guide
|
||||
also assumes that you understand the basics of <ulink type="http"
|
||||
url="http://developer.gnome.org/doc/API/2.0/gobject/index.html">GObject</ulink>
|
||||
programming. There are several good introductions to the GObject library,
|
||||
including the <emphasis><ulink type="http"
|
||||
url="http://www.gtk.org/tutorial/">GTK+ Tutorial</ulink></emphasis>.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-preface-structure" xreflabel="Structure of This Guide">
|
||||
<title>Structure of This Guide</title>
|
||||
<para>
|
||||
To help you navigate through this guide, it is divided into several large
|
||||
parts. Each part addresses a particular broad topic concerning &GStreamer;
|
||||
plugin development. The parts of this guide are laid out in the following
|
||||
order:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
<guilabel><xref linkend="part-building"/></guilabel> —
|
||||
Introduction to the structure of a plugin. This part covers all the
|
||||
different steps you have to perform to build a basic audio filter
|
||||
plugin. The discussion begins by giving examples of generating the
|
||||
basic structures with <xref linkend="cha-building-boiler"/>. Then you
|
||||
will learn how to write the code to get a basic filter plugin working.
|
||||
Several chapters cover these concepts, including <xref
|
||||
linkend="cha-building-types"/>, <xref linkend="cha-building-pads"/>,
|
||||
<xref linkend="cha-building-chainfn"/>, and <xref
|
||||
linkend="cha-building-state"/>.
|
||||
</para>
|
||||
<para>
|
||||
After you have finished these chapters, you will have a working
|
||||
plugin, but your new plugin might not have all the functionality you
|
||||
need. To provide some standard functionality, you will learn how to
|
||||
add features to a filter in the chapters on <xref
|
||||
linkend="cha-building-props"/> and <xref
|
||||
linkend="cha-building-signals"/>. Finally, you will learn to test your
|
||||
new plugin in <xref linkend="cha-building-testapp"/>.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<guilabel><xref linkend="part-advanced"/></guilabel> —
|
||||
Information on advanced features of &GStreamer; plugin development.
|
||||
After learning about the basic steps, you should be able to create a
|
||||
functional audio or video filter plugin with some nice features.
|
||||
However, &GStreamer; offers more for plugin writers. This part of the
|
||||
guide includes chapters on <xref linkend="cha-advanced-scheduling"/>,
|
||||
<xref linkend="cha-advanced-request"/>, <xref
|
||||
linkend="cha-advanced-clock"/>, <xref
|
||||
linkend="cha-advanced-dparams"/>, and <xref
|
||||
linkend="cha-advanced-midi"/>. Since these features are more advanced,
|
||||
the chapters can basically be read in any order, as you need the
|
||||
features for your custom plugins.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<guilabel><xref linkend="part-other"/></guilabel> — Explanation
|
||||
of writing source and sink plugins. Although the concepts introduced
|
||||
in the two previous parts of this guide apply to filter plugins, many
|
||||
of the concepts apply equally to source and sink plugins. This part
|
||||
will take a look at creating source and sink type plugins for
|
||||
&GStreamer; in the chapters on <xref linkend="cha-other-source"/> and
|
||||
<xref linkend="cha-other-sink"/>. The chapter on <xref
|
||||
linkend="cha-other-autoplugger"/> describes writing autoplugger
|
||||
plugins.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<guilabel><xref linkend="part-appendix"/></guilabel> — The
|
||||
appendices contain some information that stubbornly refused to fit
|
||||
cleanly in other sections of this guide, like the <xref
|
||||
linkend="cha-appendix-checklist"/> and <xref
|
||||
linkend="cha-appendix-python"/>. FIXME: organize better.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
The remainder of this introductory part presents a short overview of the
|
||||
basic concepts involved in &GStreamer; plugin development. People familiar
|
||||
with the &GstAppDevMan; can use this short overview to refresh their
|
||||
memory. Topics covered include <xref linkend="sect1-basics-elements"/>,
|
||||
<xref linkend="sect1-basics-pads"/>, <xref
|
||||
linkend="sect1-basics-buffers"/>, <xref linkend="sect1-basics-types"/>,
|
||||
and <xref linkend="sect1-basics-events"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As you can see, there a lot to learn, so let's get started!
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Creating compound and complex elements by extending from a GstBin.
|
||||
This will allow you to create plugins that have other plugins embedded
|
||||
in them.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Adding new mime-types to the registry along with typedetect functions.
|
||||
This will allow your plugin to operate on a completely new media type.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Creating custom schedulers when the default schedulers are
|
||||
insufficient.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Creating custom autopluggers when the default ones are insufficient
|
||||
for your needs.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
</chapter>
|
1
docs/pwg/magic-pdf
Normal file
1
docs/pwg/magic-pdf
Normal file
|
@ -0,0 +1 @@
|
|||
<!ENTITY magic "pdf">
|
1
docs/pwg/magic-png
Normal file
1
docs/pwg/magic-png
Normal file
|
@ -0,0 +1 @@
|
|||
<!ENTITY magic "png">
|
9
docs/pwg/other-autoplugger.xml
Normal file
9
docs/pwg/other-autoplugger.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-other-autoplugger" xreflabel="Writing an Autoplugger">
|
||||
<title>Writing an Autoplugger</title>
|
||||
<para>
|
||||
FIXME: write.
|
||||
</para>
|
||||
</chapter>
|
9
docs/pwg/other-sink.xml
Normal file
9
docs/pwg/other-sink.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-other-sink" xreflabel="Writing a Sink">
|
||||
<title>Writing a Sink</title>
|
||||
<para>
|
||||
FIXME: write.
|
||||
</para>
|
||||
</chapter>
|
9
docs/pwg/other-source.xml
Normal file
9
docs/pwg/other-source.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-other-source" xreflabel="Writing a Source">
|
||||
<title>Writing a Source</title>
|
||||
<para>
|
||||
FIXME: write.
|
||||
</para>
|
||||
</chapter>
|
58
docs/pwg/titlepage.xml
Normal file
58
docs/pwg/titlepage.xml
Normal file
|
@ -0,0 +1,58 @@
|
|||
<bookinfo>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Richard</firstname>
|
||||
<othername>John</othername>
|
||||
<surname>Boulton</surname>
|
||||
<authorblurb>
|
||||
<para>
|
||||
<email>richard-gst@tartarus.org</email>
|
||||
</para>
|
||||
</authorblurb>
|
||||
</author>
|
||||
|
||||
<author>
|
||||
<firstname>Erik</firstname>
|
||||
<surname>Walthinsen</surname>
|
||||
<authorblurb>
|
||||
<para>
|
||||
<email>omega@temple-baptist.com</email>
|
||||
</para>
|
||||
</authorblurb>
|
||||
</author>
|
||||
|
||||
<author>
|
||||
<firstname>Steve</firstname>
|
||||
<surname>Baker</surname>
|
||||
<authorblurb>
|
||||
<para>
|
||||
<email>stevebaker_org@yahoo.co.uk</email>
|
||||
</para>
|
||||
</authorblurb>
|
||||
</author>
|
||||
|
||||
<author>
|
||||
<firstname>Leif</firstname>
|
||||
<surname>Johnson</surname>
|
||||
<authorblurb>
|
||||
<para>
|
||||
<email>leif@ambient.2y.net</email>
|
||||
</para>
|
||||
</authorblurb>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<legalnotice id="legalnotice">
|
||||
<para>
|
||||
This material may be distributed only subject to the terms and
|
||||
conditions set forth in the Open Publication License, v1.0 or later (the
|
||||
latest version is presently available at <ulink
|
||||
url="http://www.opencontent.org/openpub/"
|
||||
type="http">http://www.opencontent.org/openpub/</ulink>).
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
||||
<title>&GStreamer; Plugin Writer's Guide</title>
|
||||
|
||||
</bookinfo>
|
Loading…
Reference in a new issue