Moved "Filter Writer's Guide" to "Plugin Writer's Guide". Divided existing info from...
authorLeif Johnson <leif@ambient.2y.net>
Fri, 27 Sep 2002 18:34:33 +0000 (18:34 +0000)
committerLeif Johnson <leif@ambient.2y.net>
Fri, 27 Sep 2002 18:34:33 +0000 (18:34 +0000)
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 ...

34 files changed:
docs/Makefile.am
docs/pwg/.gitignore [new file with mode: 0644]
docs/pwg/Makefile.am [new file with mode: 0644]
docs/pwg/advanced-clock.xml [new file with mode: 0644]
docs/pwg/advanced-dparams.xml [new file with mode: 0644]
docs/pwg/advanced-midi.xml [new file with mode: 0644]
docs/pwg/advanced-request.xml [new file with mode: 0644]
docs/pwg/advanced-scheduling.xml [new file with mode: 0644]
docs/pwg/advanced-types.xml [new file with mode: 0644]
docs/pwg/appendix-checklist.xml [new file with mode: 0644]
docs/pwg/appendix-python.xml [new file with mode: 0644]
docs/pwg/base.css [new file with mode: 0644]
docs/pwg/basics-autoplugging.xml [new file with mode: 0644]
docs/pwg/basics-buffers.xml [new file with mode: 0644]
docs/pwg/basics-elements.xml [new file with mode: 0644]
docs/pwg/basics-events.xml [new file with mode: 0644]
docs/pwg/basics-plugins.xml [new file with mode: 0644]
docs/pwg/basics-types.xml [new file with mode: 0644]
docs/pwg/building-boiler.xml [new file with mode: 0644]
docs/pwg/building-chainfn.xml [new file with mode: 0644]
docs/pwg/building-pads.xml [new file with mode: 0644]
docs/pwg/building-props.xml [new file with mode: 0644]
docs/pwg/building-signals.xml [new file with mode: 0644]
docs/pwg/building-state.xml [new file with mode: 0644]
docs/pwg/building-testapp.xml [new file with mode: 0644]
docs/pwg/gst-plugin-writers-guide.xml [new file with mode: 0644]
docs/pwg/intro-basics.xml [new file with mode: 0644]
docs/pwg/intro-preface.xml [new file with mode: 0644]
docs/pwg/magic-pdf [new file with mode: 0644]
docs/pwg/magic-png [new file with mode: 0644]
docs/pwg/other-autoplugger.xml [new file with mode: 0644]
docs/pwg/other-sink.xml [new file with mode: 0644]
docs/pwg/other-source.xml [new file with mode: 0644]
docs/pwg/titlepage.xml [new file with mode: 0644]

index 46b3674..666d62e 100644 (file)
@@ -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
 
diff --git a/docs/pwg/.gitignore b/docs/pwg/.gitignore
new file mode 100644 (file)
index 0000000..c9012a5
--- /dev/null
@@ -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
diff --git a/docs/pwg/Makefile.am b/docs/pwg/Makefile.am
new file mode 100644 (file)
index 0000000..72a07dc
--- /dev/null
@@ -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
diff --git a/docs/pwg/advanced-clock.xml b/docs/pwg/advanced-clock.xml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs/pwg/advanced-dparams.xml b/docs/pwg/advanced-dparams.xml
new file mode 100644 (file)
index 0000000..2311380
--- /dev/null
@@ -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 &lt;gst/control/control.h&gt;
+  </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-&gt;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>&amp;(example-&gt;volume)</filename>.
+    </para>
+    <programlisting>
+  gst_dpman_add_required_dparam_direct (
+    example-&gt;dpman,
+    g_param_spec_float("volume","Volume","Volume of the audio",
+                       0.0, 1.0, 0.8, G_PARAM_READWRITE),
+    FALSE,
+    FALSE,
+    &amp;(example-&gt;volume)
+  );
+    </programlisting>
+    <para>
+      You can now use <filename>example-&gt;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-&gt;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-&gt;volume_f = g_value_get_float(value);
+  example-&gt;volume_i = example-&gt;volume_f * 8192;
+}
+    </programlisting>
+    <para>
+      Now <filename>example-&gt;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 &lt; num_samples; j++) {
+    float_data[j] *= example-&gt;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-&gt;dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
+  ...
+  while (GST_DPMAN_PROCESS_COUNTDOWN(example-&gt;dpman, frame_countdown, j)) {
+    float_data[j++] *= example-&gt;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>
diff --git a/docs/pwg/advanced-midi.xml b/docs/pwg/advanced-midi.xml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs/pwg/advanced-request.xml b/docs/pwg/advanced-request.xml
new file mode 100644 (file)
index 0000000..01f8afc
--- /dev/null
@@ -0,0 +1,6 @@
+<chapter id="cha-advanced-request">
+  <title>Request pads</title>
+  <para>
+    aka pushing and pulling
+  </para>
+</chapter>
diff --git a/docs/pwg/advanced-scheduling.xml b/docs/pwg/advanced-scheduling.xml
new file mode 100644 (file)
index 0000000..249f9ff
--- /dev/null
@@ -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>
+
diff --git a/docs/pwg/advanced-types.xml b/docs/pwg/advanced-types.xml
new file mode 100644 (file)
index 0000000..62ed2cf
--- /dev/null
@@ -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>
diff --git a/docs/pwg/appendix-checklist.xml b/docs/pwg/appendix-checklist.xml
new file mode 100644 (file)
index 0000000..d67fcb7
--- /dev/null
@@ -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>
diff --git a/docs/pwg/appendix-python.xml b/docs/pwg/appendix-python.xml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs/pwg/base.css b/docs/pwg/base.css
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs/pwg/basics-autoplugging.xml b/docs/pwg/basics-autoplugging.xml
new file mode 100644 (file)
index 0000000..f6a927d
--- /dev/null
@@ -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>
diff --git a/docs/pwg/basics-buffers.xml b/docs/pwg/basics-buffers.xml
new file mode 100644 (file)
index 0000000..28267d4
--- /dev/null
@@ -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>
diff --git a/docs/pwg/basics-elements.xml b/docs/pwg/basics-elements.xml
new file mode 100644 (file)
index 0000000..1caf8d1
--- /dev/null
@@ -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>
+
diff --git a/docs/pwg/basics-events.xml b/docs/pwg/basics-events.xml
new file mode 100644 (file)
index 0000000..ac84310
--- /dev/null
@@ -0,0 +1,8 @@
+
+<!-- ############ chapter ############# -->
+
+<chapter id="cha-events">
+  <title>Events</title>
+  <para>
+  </para>
+</chapter>
diff --git a/docs/pwg/basics-plugins.xml b/docs/pwg/basics-plugins.xml
new file mode 100644 (file)
index 0000000..051f99b
--- /dev/null
@@ -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>
diff --git a/docs/pwg/basics-types.xml b/docs/pwg/basics-types.xml
new file mode 100644 (file)
index 0000000..e0e130a
--- /dev/null
@@ -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>
diff --git a/docs/pwg/building-boiler.xml b/docs/pwg/building-boiler.xml
new file mode 100644 (file)
index 0000000..5e864fd
--- /dev/null
@@ -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 &lt;your.name@your.isp&gt;",
+      "(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>
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/pwg/building-chainfn.xml b/docs/pwg/building-chainfn.xml
new file mode 100644 (file)
index 0000000..11fb3b2
--- /dev/null
@@ -0,0 +1,8 @@
+
+<!-- ############ chapter ############# -->
+
+<chapter id="cha-building-chainfn">
+  <title>The chain function</title>
+  <para>
+  </para>
+</chapter>
diff --git a/docs/pwg/building-pads.xml b/docs/pwg/building-pads.xml
new file mode 100644 (file)
index 0000000..f327af1
--- /dev/null
@@ -0,0 +1,9 @@
+
+<!-- ############ chapter ############# -->
+
+<chapter id="cha-building-pads">
+  <title>Specifying the pads</title>
+  <para>
+  </para>
+</chapter>
+
diff --git a/docs/pwg/building-props.xml b/docs/pwg/building-props.xml
new file mode 100644 (file)
index 0000000..16d4b20
--- /dev/null
@@ -0,0 +1,9 @@
+<!-- ############ chapter ############# -->
+
+<chapter id="cha-building-args" xreflabel="Adding Arguments">
+  <title>Adding Arguments</title>
+  <para>
+    Define arguments in enum.
+  </para>
+</chapter>
+
diff --git a/docs/pwg/building-signals.xml b/docs/pwg/building-signals.xml
new file mode 100644 (file)
index 0000000..8299104
--- /dev/null
@@ -0,0 +1,9 @@
+
+<!-- ############ chapter ############# -->
+
+<chapter id="cha-building-signals">
+  <title>Signals</title>
+  <para>
+    Define signals in enum.
+  </para>
+</chapter>
diff --git a/docs/pwg/building-state.xml b/docs/pwg/building-state.xml
new file mode 100644 (file)
index 0000000..4d8a1e1
--- /dev/null
@@ -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>
diff --git a/docs/pwg/building-testapp.xml b/docs/pwg/building-testapp.xml
new file mode 100644 (file)
index 0000000..bfbd66a
--- /dev/null
@@ -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>
+
diff --git a/docs/pwg/gst-plugin-writers-guide.xml b/docs/pwg/gst-plugin-writers-guide.xml
new file mode 100644 (file)
index 0000000..dfee7db
--- /dev/null
@@ -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>
diff --git a/docs/pwg/intro-basics.xml b/docs/pwg/intro-basics.xml
new file mode 100644 (file)
index 0000000..31770d4
--- /dev/null
@@ -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&nbsp;law</quote>, and 2 indicates
+              <quote>A&nbsp;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>
\ No newline at end of file
diff --git a/docs/pwg/intro-preface.xml b/docs/pwg/intro-preface.xml
new file mode 100644 (file)
index 0000000..45c20c4
--- /dev/null
@@ -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 &mdash; and there are quite a lot of
+      plugins already &mdash; 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> &mdash;
+          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> &mdash;
+          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> &mdash; 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> &mdash; 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>
diff --git a/docs/pwg/magic-pdf b/docs/pwg/magic-pdf
new file mode 100644 (file)
index 0000000..abc274e
--- /dev/null
@@ -0,0 +1 @@
+<!ENTITY magic "pdf">
diff --git a/docs/pwg/magic-png b/docs/pwg/magic-png
new file mode 100644 (file)
index 0000000..6941e28
--- /dev/null
@@ -0,0 +1 @@
+<!ENTITY magic "png">
diff --git a/docs/pwg/other-autoplugger.xml b/docs/pwg/other-autoplugger.xml
new file mode 100644 (file)
index 0000000..627d15f
--- /dev/null
@@ -0,0 +1,9 @@
+
+<!-- ############ chapter ############# -->
+
+<chapter id="cha-other-autoplugger" xreflabel="Writing an Autoplugger">
+  <title>Writing an Autoplugger</title>
+  <para>
+    FIXME: write.
+  </para>
+</chapter>
diff --git a/docs/pwg/other-sink.xml b/docs/pwg/other-sink.xml
new file mode 100644 (file)
index 0000000..af2a310
--- /dev/null
@@ -0,0 +1,9 @@
+
+<!-- ############ chapter ############# -->
+
+<chapter id="cha-other-sink" xreflabel="Writing a Sink">
+  <title>Writing a Sink</title>
+  <para>
+    FIXME: write.
+  </para>
+</chapter>
diff --git a/docs/pwg/other-source.xml b/docs/pwg/other-source.xml
new file mode 100644 (file)
index 0000000..bb991d2
--- /dev/null
@@ -0,0 +1,9 @@
+
+<!-- ############ chapter ############# -->
+
+<chapter id="cha-other-source" xreflabel="Writing a Source">
+  <title>Writing a Source</title>
+  <para>
+    FIXME: write.
+  </para>
+</chapter>
diff --git a/docs/pwg/titlepage.xml b/docs/pwg/titlepage.xml
new file mode 100644 (file)
index 0000000..e4a58e2
--- /dev/null
@@ -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>