2001-01-08 23:55:27 +00:00
|
|
|
<chapter id="cha-boilerplate">
|
|
|
|
<title>Constructing the boilerplate</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. I shall refer to these details
|
|
|
|
collectively as the <emphasis>boilerplate</emphasis>.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<sect1 id="sect-boilerplate-gobject">
|
|
|
|
<title>Doing it the hard way with GstObject</title>
|
|
|
|
<para>
|
|
|
|
The standard way of defining the boilerplate is simply to write some
|
|
|
|
code, and fill in some structures. The easiest way to do this is to
|
|
|
|
copy an example and modify according to your needs.
|
|
|
|
</para>
|
|
|
|
<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/plugins/example.h</filename>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="sect-boilerplate-filterfactory">
|
|
|
|
<title>Doing it the easy way with FilterFactory</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.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Unfortunately, this hasn't yet been implemented. It is also likely
|
|
|
|
that when it is, it will not be possible to cover all the possibilities
|
|
|
|
available by writing the boilerplate yourself, so some plugins will
|
|
|
|
always need to be manually registered.
|
|
|
|
</para>
|
2001-01-19 02:06:40 +00:00
|
|
|
<para>
|
|
|
|
As a rough outline of what is planned: the FilterFactory will take a
|
|
|
|
list of appropriate function pointers, and data structures to define
|
|
|
|
a filter. With a reasonable measure of preprocessor magic, the
|
|
|
|
plugin writer will then simply need to provide definitions of the
|
|
|
|
functions and data structures desired, and a name for the filter, and
|
|
|
|
then call a macro from within plugin_init() which will register the
|
|
|
|
new filter. All the fluff that goes into the definition of a filter
|
|
|
|
will thus be hidden from view.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Ideally, we will come up with a way for various FilterFactory-provided
|
|
|
|
functions to be overridden, to the point where you can construct
|
|
|
|
almost the most complex stuff with it, it just saves typing.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Of course, the filter factory can be used to create sources and sinks
|
|
|
|
too: simply create a filter with only source or sink pads.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
You may be thinking that this should really be called an
|
|
|
|
ElementFactory. Well, we agree, but there is already something else
|
|
|
|
justifiably ealled an ElementFactory (this is the thing which actually
|
|
|
|
makes instances of elements). There is also already something called
|
|
|
|
a PluginFactory. We just have too many factories and not enough words.
|
|
|
|
And since this isn't yet written, it doesn't get priority for claiming
|
|
|
|
a name.
|
|
|
|
</para>
|
2001-01-08 23:55:27 +00:00
|
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
|
|
|
|
<chapter id="cha-idfilter">
|
|
|
|
<title>An identity filter</title>
|
|
|
|
<para>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<sect1 id="sect-idfilter-pads">
|
|
|
|
<title>Building an object with pads</title>
|
|
|
|
<para>
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="sect-idfilter-fns">
|
|
|
|
<title>Attaching functions</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="sect-idfilter-fns">
|
|
|
|
<title>The chain function</title>
|
|
|
|
<para>
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
|
|
|
|
<chapter id="cha-plugininit">
|
|
|
|
<title>The plugin_init function</title>
|
|
|
|
<para>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<sect1 id="sect-plugininit-types">
|
|
|
|
<title>Registering the types</title>
|
|
|
|
<para>
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="sect-plugininit-filter">
|
|
|
|
<title>Registering the filter</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
|
|
|
|
<sect1 id="sect-plugininit-multiple">
|
|
|
|
<title>Having multiple filters in a single plugin</title>
|
|
|
|
<para>
|
|
|
|
</para>
|
|
|
|
</sect1>
|
|
|
|
</chapter>
|