diff --git a/docs/Makefile.am b/docs/Makefile.am
index 46b3674ea3..666d62ef69 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -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
index 0000000000..c9012a5e02
--- /dev/null
+++ b/docs/pwg/.gitignore
@@ -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
index 0000000000..72a07dc4c5
--- /dev/null
+++ b/docs/pwg/Makefile.am
@@ -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
index 0000000000..e69de29bb2
diff --git a/docs/pwg/advanced-dparams.xml b/docs/pwg/advanced-dparams.xml
new file mode 100644
index 0000000000..2311380d50
--- /dev/null
+++ b/docs/pwg/advanced-dparams.xml
@@ -0,0 +1,481 @@
+
+
+
+
+ Supporting Dynamic Parameters
+
+ 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.
+
+
+ Throughout this section, the term dparams will be used
+ as an abbreviation for "Dynamic Parameters".
+
+
+
+ Comparing Dynamic Parameters with GObject Properties
+
+ 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.
+
+
+
+
+
+
+ Object Properties
+ Dynamic Parameters
+
+
+
+
+ Parameter definition
+ Class level at compile time
+ Any level at run time
+
+
+ Getting and setting
+ Implemented by element subclass as functions
+ Handled entirely by dparams subsystem
+
+
+ Extra objects required
+ None - all functionality is derived from base GObject
+ Element needs to create and store a GstDParamManager at object creation
+
+
+ Frequency and resolution of updates
+ Object properties will only be updated between calls to _get, _chain or _loop
+ dparams can be updated at any rate independant of calls to _get, _chain or _loop up to sample-level accuracy
+
+
+
+
+
+
+
+
+ Getting Started
+
+
+ The dparams subsystem is contained within the
+ gstcontrol library. You need to include the header in
+ your element's source file:
+
+
+ #include <gst/control/control.h>
+
+
+
+ Even though the gstcontrol library may be linked into
+ the host application, you should make sure it is loaded in your
+ plugin_init function:
+
+
+ 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;
+ }
+
+ ...
+ }
+
+
+
+ You need to store an instance of GstDParamManager in
+ your element's struct:
+
+
+ struct _GstExample {
+ GstElement element;
+ ...
+
+ GstDParamManager *dpman;
+
+ ...
+ };
+
+
+
+ The GstDParamManager can be initialised in your
+ element's init function:
+
+
+ static void
+ gst_example_init (GstExample *example)
+ {
+ ...
+
+ example->dpman = gst_dpman_new ("example_dpman", GST_ELEMENT(example));
+
+ ...
+ }
+
+
+
+
+
+ Defining Parameter Specificiations
+
+ You can define the dparams you need anywhere within your element but will
+ usually need to do so in only a couple of places:
+
+
+ In the element init function, just after the call
+ to gst_dpman_new
+
+
+ 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.
+
+
+
+
+ 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:
+
+ gst_dpman_add_required_dparam_direct
+ gst_dpman_add_required_dparam_callback
+ gst_dpman_add_required_dparam_array
+
+ These functions will return TRUE if the required dparam was added
+ successfully.
+
+
+ The following function will be used as an example.
+
+ gboolean
+ gst_dpman_add_required_dparam_direct (GstDParamManager *dpman,
+ GParamSpec *param_spec,
+ gboolean is_log,
+ gboolean is_rate,
+ gpointer update_data)
+
+ The common parameters to these functions are:
+
+
+ GstDParamManager *dpman the element's dparam
+ manager
+
+
+ GParamSpec *param_spec the param spec which defines
+ the required dparam
+
+
+ gboolean is_log whether this dparam value should be
+ interpreted on a log scale (such as a frequency or a decibel value)
+
+
+ gboolean is_rate 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.
+
+
+
+
+ Direct Method
+
+ 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.
+
+
+ struct _GstExample {
+ GstElement element;
+ ...
+
+ GstDParamManager *dpman;
+ gfloat volume;
+ ...
+ };
+
+
+ Then to define the required dparam just call
+ gst_dpman_add_required_dparam_direct and pass in the
+ location of the parameter to change. In this case the location is
+ &(example->volume).
+
+
+ gst_dpman_add_required_dparam_direct (
+ example->dpman,
+ g_param_spec_float("volume","Volume","Volume of the audio",
+ 0.0, 1.0, 0.8, G_PARAM_READWRITE),
+ FALSE,
+ FALSE,
+ &(example->volume)
+ );
+
+
+ You can now use example->volume anywhere in your
+ element knowing that it will always contain the correct value to use.
+
+
+
+ Callback Method
+
+ 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.
+
+
+ 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.
+
+
+ struct _GstExample {
+ GstElement element;
+ ...
+
+ GstDParamManager *dpman;
+ gfloat volume_f;
+ gint volume_i;
+ ...
+ };
+
+
+ When the required dparam is defined, the callback function
+ gst_example_update_volume and some user data (which
+ in this case is our element instance) is passed in to the call to
+ gst_dpman_add_required_dparam_callback.
+
+
+ gst_dpman_add_required_dparam_callback (
+ example->dpman,
+ g_param_spec_float("volume","Volume","Volume of the audio",
+ 0.0, 1.0, 0.8, G_PARAM_READWRITE),
+ FALSE,
+ FALSE,
+ gst_example_update_volume,
+ example
+ );
+
+
+ The callback function needs to conform to this signiture
+
+
+typedef void (*GstDPMUpdateFunction) (GValue *value, gpointer data);
+
+
+ In our example the callback function looks like this
+
+
+static void
+gst_example_update_volume(GValue *value, gpointer data)
+{
+ GstExample *example = (GstExample*)data;
+ g_return_if_fail(GST_IS_EXAMPLE(example));
+
+ example->volume_f = g_value_get_float(value);
+ example->volume_i = example->volume_f * 8192;
+}
+
+
+ Now example->volume_i can be used elsewhere and it
+ will always contain the correct value.
+
+
+
+ Array Method
+
+ 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.
+
+
+
+
+ Certain optimisations may be possible since you can iterate over your
+ dparams array and your buffer data together.
+
+
+ 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.
+
+
+
+ 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.
+
+
+
+
+
+ The Data Processing Loop
+
+ This is the most critical aspect of the dparams subsystem as it relates to
+ elements. In a traditional audio processing loop, a for
+ 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.
+
+
+static void
+example_chain (GstPad *pad, GstBuffer *buf)
+{
+ ...
+ gfloat *float_data;
+ int j;
+ GstExample *example = GST_EXAMPLE(GST_OBJECT_PARENT (pad));
+ int num_samples = GST_BUFFER_SIZE(buf)/sizeof(gfloat);
+ float_data = (gfloat *)GST_BUFFER_DATA(buf);
+ ...
+ for (j = 0; j < num_samples; j++) {
+ float_data[j] *= example->volume;
+ }
+ ...
+}
+
+
+ To make this dparams aware, a couple of changes are needed.
+
+
+static void
+example_chain (GstPad *pad, GstBuffer *buf)
+{
+ ...
+ int j = 0;
+ GstExample *example = GST_EXAMPLE(GST_OBJECT_PARENT (pad));
+ int num_samples = GST_BUFFER_SIZE(buf)/sizeof(gfloat);
+ gfloat *float_data = (gfloat *)GST_BUFFER_DATA(buf);
+ int frame_countdown = GST_DPMAN_PREPROCESS(example->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
+ ...
+ while (GST_DPMAN_PROCESS_COUNTDOWN(example->dpman, frame_countdown, j)) {
+ float_data[j++] *= example->volume;
+ }
+ ...
+}
+
+
+ The biggest changes here are 2 new macros,
+ GST_DPMAN_PREPROCESS and
+ GST_DPMAN_PROCESS_COUNTDOWN. You will also notice that
+ the for loop has become a while loop.
+ GST_DPMAN_PROCESS_COUNTDOWN 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 sample accurate. This means
+ that parameters change at the exact timestamp that they are supposed to -
+ not after the buffer has finished being processed.
+
+
+ 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.
+
+
+#define GST_DPMAN_PROCESS_COUNTDOWN(dpman, frame_countdown, frame_count) \
+ (frame_countdown-- || \
+ (frame_countdown = GST_DPMAN_PROCESS(dpman, frame_count)))
+
+
+ So as long as frame_countdown is greater than 0,
+ GST_DPMAN_PROCESS will not be called at all. Also in
+ many cases, GST_DPMAN_PROCESS will do nothing and
+ simply return 0, meaning that there is no more data in the buffer to
+ process.
+
+
+ The macro GST_DPMAN_PREPROCESS will do the following:
+
+
+ Update any dparams which are due to be updated.
+
+
+ Calculate how many samples should be processed before the next required
+ update
+
+
+ Return the number of samples until next update, or the number of samples
+ in the buffer - whichever is less.
+
+
+ In fact GST_DPMAN_PROCESS may do the same things as
+ GST_DPMAN_PREPROCESS depending on the mode that the
+ dparam manager is running in (see below).
+
+
+ DParam Manager Modes
+
+ 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:
+
+
+ Timelined - all parameter changes are known in
+ advance before the pipeline is run.
+
+
+ Realtime low-latency - Nothing is known ahead of
+ time about when a parameter might change. Changes need to be
+ propagated to the element as soon as possible.
+
+
+ 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 "synchronous" and
+ "asynchronous".
+
+
+ If you are in a realtime low-latency situation then the
+ "synchronous" mode is appropriate. During
+ GST_DPMAN_PREPROCESS this mode will poll all dparams
+ for required updates and propagate them.
+ GST_DPMAN_PROCESS 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.
+
+
+ In a timelined situation, the "asynchronous" mode
+ will be required. This mode hasn't actually been implemented yet but will
+ be described anyway. The GST_DPMAN_PREPROCESS call
+ will precalculate when and how often each dparam needs to update for the
+ duration of the current buffer. From then on
+ GST_DPMAN_PROCESS 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 "asynchronous"
+ mode this could be done without affecting the sample accuracy of the
+ parameter updates
+
+
+
+ DParam Manager Modes
+
+ 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 GST_DPMAN_PREPROCESS should be
+ required. For more than one frame per buffer, treat it the same as the
+ audio case.
+
+
+
diff --git a/docs/pwg/advanced-midi.xml b/docs/pwg/advanced-midi.xml
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/docs/pwg/advanced-request.xml b/docs/pwg/advanced-request.xml
new file mode 100644
index 0000000000..01f8afcd78
--- /dev/null
+++ b/docs/pwg/advanced-request.xml
@@ -0,0 +1,6 @@
+
+ Request pads
+
+ aka pushing and pulling
+
+
diff --git a/docs/pwg/advanced-scheduling.xml b/docs/pwg/advanced-scheduling.xml
new file mode 100644
index 0000000000..249f9ff9ad
--- /dev/null
+++ b/docs/pwg/advanced-scheduling.xml
@@ -0,0 +1,27 @@
+
+ How scheduling works
+
+ aka pushing and pulling
+
+
+
+
+ How a loopfunc works
+
+ aka pulling and pushing
+
+
+
+
+ Adding a second output
+
+ Identity is now a tee
+
+
+
+
+ Modifying the test application
+
+
+
+
diff --git a/docs/pwg/advanced-types.xml b/docs/pwg/advanced-types.xml
new file mode 100644
index 0000000000..62ed2cf1aa
--- /dev/null
+++ b/docs/pwg/advanced-types.xml
@@ -0,0 +1,88 @@
+
+
+
+ Types and Properties
+
+ 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).
+
+
+ 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.
+
+
+ For now, the policy is simple:
+
+
+
+ Do not create a new type if you could use one which already exists.
+
+
+
+
+ If creating a new type, discuss it first with the other &GStreamer;
+ developers, on at least one of: IRC, mailing lists, the &GStreamer;
+ wiki.
+
+
+
+
+ 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.
+
+
+
+
+ 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.
+
+
+
+
+
+
+
+
+ Building a Simple Format for Testing
+
+
+
+
+
+
+
+ A Simple Mime Type
+
+
+
+
+
+
+
+ Type Properties
+
+
+
+
+
+
+
+ Typefind Functions and Autoplugging
+
+
+
+
diff --git a/docs/pwg/appendix-checklist.xml b/docs/pwg/appendix-checklist.xml
new file mode 100644
index 0000000000..d67fcb7864
--- /dev/null
+++ b/docs/pwg/appendix-checklist.xml
@@ -0,0 +1,14 @@
+
+
+ Things to check when writing a filter
+
+
+
+
+
+
+ Things to check when writing a source or sink
+
+
+
+
diff --git a/docs/pwg/appendix-python.xml b/docs/pwg/appendix-python.xml
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/docs/pwg/base.css b/docs/pwg/base.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/docs/pwg/basics-autoplugging.xml b/docs/pwg/basics-autoplugging.xml
new file mode 100644
index 0000000000..f6a927d717
--- /dev/null
+++ b/docs/pwg/basics-autoplugging.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ Autopluggers
+
+ &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.
+
+
+ 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.
+
+
diff --git a/docs/pwg/basics-buffers.xml b/docs/pwg/basics-buffers.xml
new file mode 100644
index 0000000000..28267d4d29
--- /dev/null
+++ b/docs/pwg/basics-buffers.xml
@@ -0,0 +1,32 @@
+
+
+
+
+ Buffers
+
+ 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).
+
+
+
+ Anatomy of a buffer
+
+
+
+
+
+ Refcounts and mutability
+
+
+
+
+
+ Metadata
+
+
+
+
diff --git a/docs/pwg/basics-elements.xml b/docs/pwg/basics-elements.xml
new file mode 100644
index 0000000000..1caf8d1beb
--- /dev/null
+++ b/docs/pwg/basics-elements.xml
@@ -0,0 +1,39 @@
+
+
+
+
+ Elements, Plugins, and Filters
+
+ In the &GStreamer; framework, a plugin 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.
+Filters are an
+ important subset of plugins that process data, as opposed to producing or
+ consuming data. (Producers and consumers of data are called
+ source and sink plugins,
+ respectively.)
+
+
+ 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.
+
+
+ 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;.
+
+
+ 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.
+
+
+
diff --git a/docs/pwg/basics-events.xml b/docs/pwg/basics-events.xml
new file mode 100644
index 0000000000..ac84310d02
--- /dev/null
+++ b/docs/pwg/basics-events.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ Events
+
+
+
diff --git a/docs/pwg/basics-plugins.xml b/docs/pwg/basics-plugins.xml
new file mode 100644
index 0000000000..051f99bf3c
--- /dev/null
+++ b/docs/pwg/basics-plugins.xml
@@ -0,0 +1,30 @@
+
+
+
+
+ Plugins
+
+ 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.
+
+
+ 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 gst-register
+ utility and the documentation in the &GstAppDevMan; for more details.
+
+
+ User extensions to &GStreamer; can be installed in the main plugin
+ directory, and will immediately be available for use in applications.
+ gst-register 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.
+
+
+ User specific plugin directories and registries will be available in future
+ versions of &GStreamer;.
+
+
diff --git a/docs/pwg/basics-types.xml b/docs/pwg/basics-types.xml
new file mode 100644
index 0000000000..e0e130a596
--- /dev/null
+++ b/docs/pwg/basics-types.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ Typing and Properties
+
+ 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.
+
+
diff --git a/docs/pwg/building-boiler.xml b/docs/pwg/building-boiler.xml
new file mode 100644
index 0000000000..5e864fd6af
--- /dev/null
+++ b/docs/pwg/building-boiler.xml
@@ -0,0 +1,295 @@
+
+
+
+ Constructing the Boilerplate
+
+ 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.
+
+
+
+
+
+ Getting the Gstreamer Plugin Templates
+
+ 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.
+
+
+ The first step is to check out a copy of the
+ gst-template CVS module to get an important tool and
+ the source code template for the basic &GStreamer; plugin. To check out
+ the gst-template module, type the following two
+ commands on a command line:
+
+
+shell $ cvs -d:pserver:anonymous@cvs.gstreamer.sourceforge.net:/cvsroot/gstreamer login
+Logging in to :pserver:anonymous@cvs.gstreamer.sourceforge.net:2401/cvsroot/gstreamer
+CVS password:
+shell $ cvs -z3 -d:pserver:anonymous@cvs.gstreamer.sourceforge.net:/cvsroot/gstreamer co gst-template
+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
+...
+
+
+ After the first command, you will have to press ENTER 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 ./gst-template. The template you will be
+ using is in ./gst-template/gst-plugin/ 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.
+
+
+
+
+
+
+ Using Filterstamp
+
+ 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 boilerplate.
+
+
+ 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
+ pluginstamp.sh in the tools/ directory of the
+ gst-template source tree that does exactly this.
+
+
+ To use pluginstamp.sh, first open up a terminal window.
+ Change to the gst-template
+ directory, and then run the pluginstamp.sh command. The
+ arguments to the pluginstamp.sh are:
+
+
+
+ the name of the plugin, and
+
+
+
+ the directory that should hold a new subdirectory for the source tree
+ of the plugin.
+
+
+
+
+ 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 ~/src/examplefilter/:
+
+
+shell $ cd gst-template
+shell $ tools/pluginstamp.sh ExampleFilter ~/src
+
+
+
+
+
+
+ Examining the Basic Code
+
+ 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
+ examples/pwg/examplefilter/boiler/gstexamplefilter.h.
+
+
+
+ Example Plugin Header File
+
+ /* 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);
+
+
+
+
+
+
+
+ Creating a Filter With FilterFactory (Future)
+
+ 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.
+
+
+ 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.
+
+
+ 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.
+
+
+
+
+
+
+ GstElementDetails
+
+ 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:
+
+
+
+ A long, english, name for the element.
+
+ 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)
+
+ A brief description of the purpose of the element.
+
+ 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.
+
+
+ Version numbers should be stored in major.minor.patch form: ie, 3
+ (decimal) numbers, separated by periods (.).
+
+ The name of the author of the element, optionally followed by a contact
+ email address in angle brackets.
+
+ The copyright details for the element.
+
+
+
+ For example:
+
+
+ static GstElementDetails example_details = {
+ "An example plugin",
+ "Example/FirstExample",
+ "Shows the basic structure of a plugin",
+ VERSION,
+ "your name <your.name@your.isp>",
+ "(C) 2001",
+ };
+
+
+
+
+
+
+ Constructor Functions
+
+ 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.
+
+
+
+
+
+
+ The plugin_init function
+
+ 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.
+
+
+ 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.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/pwg/building-chainfn.xml b/docs/pwg/building-chainfn.xml
new file mode 100644
index 0000000000..11fb3b2076
--- /dev/null
+++ b/docs/pwg/building-chainfn.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ The chain function
+
+
+
diff --git a/docs/pwg/building-pads.xml b/docs/pwg/building-pads.xml
new file mode 100644
index 0000000000..f327af13ea
--- /dev/null
+++ b/docs/pwg/building-pads.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Specifying the pads
+
+
+
+
diff --git a/docs/pwg/building-props.xml b/docs/pwg/building-props.xml
new file mode 100644
index 0000000000..16d4b204c1
--- /dev/null
+++ b/docs/pwg/building-props.xml
@@ -0,0 +1,9 @@
+
+
+
+ Adding Arguments
+
+ Define arguments in enum.
+
+
+
diff --git a/docs/pwg/building-signals.xml b/docs/pwg/building-signals.xml
new file mode 100644
index 0000000000..82991047be
--- /dev/null
+++ b/docs/pwg/building-signals.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Signals
+
+ Define signals in enum.
+
+
diff --git a/docs/pwg/building-state.xml b/docs/pwg/building-state.xml
new file mode 100644
index 0000000000..4d8a1e1474
--- /dev/null
+++ b/docs/pwg/building-state.xml
@@ -0,0 +1,14 @@
+
+
+ What are states?
+
+
+
+
+
+
+ Mangaging filter state
+
+
+
+
diff --git a/docs/pwg/building-testapp.xml b/docs/pwg/building-testapp.xml
new file mode 100644
index 0000000000..bfbd66abdd
--- /dev/null
+++ b/docs/pwg/building-testapp.xml
@@ -0,0 +1,25 @@
+
+ Initialization
+
+
+
+
+
+ Instantiating the plugins
+
+ (NOTE: we really should have a debugging Sink)
+
+
+
+
+ Connecting the plugins
+
+
+
+
+
+ Running the pipeline
+
+
+
+
diff --git a/docs/pwg/gst-plugin-writers-guide.xml b/docs/pwg/gst-plugin-writers-guide.xml
new file mode 100644
index 0000000000..dfee7db9fb
--- /dev/null
+++ b/docs/pwg/gst-plugin-writers-guide.xml
@@ -0,0 +1,156 @@
+
+
+%magic-entities;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+GStreamer">
+
+GStreamer Application Development Manual">
+GStreamer Library Reference">
+]>
+
+
+ &TITLEPAGE;
+
+
+
+
+ Introduction
+
+
+ &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, CORBA), writing new
+ plugins is not always easy.
+
+
+ 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;.
+
+
+
+ &INTRO_PREFACE;
+ &INTRO_BASICS;
+
+
+
+
+
+ Building a Filter
+
+
+ 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 ExampleFilter
.
+
+
+ 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, , you will be able to add even more
+ functionality to your plugins.
+
+
+ The example code used in this part of the guide can be found in
+ examples/pwg/examplefilter/ in
+ your &GStreamer; directory.
+
+
+
+ &BUILDING_BOILER;
+ &BUILDING_PADS;
+ &BUILDING_CHAINFN;
+ &BUILDING_STATE;
+ &BUILDING_PROPS;
+ &BUILDING_SIGNALS;
+ &BUILDING_TESTAPP;
+
+
+
+
+
+ Advanced Filter Concepts
+
+
+
+
+
+ &ADVANCED_SCHEDULING;
+ &ADVANCED_TYPES;
+ &ADVANCED_REQUEST;
+ &ADVANCED_CLOCK;
+ &ADVANCED_DPARAMS;
+ &ADVANCED_MIDI;
+
+
+
+
+
+ Other Element Types
+
+
+
+
+
+ &OTHER_SOURCE;
+ &OTHER_SINK;
+ &OTHER_AUTOPLUGGER;
+
+
+
+
+
+ Appendices
+
+
+
+
+
+ &APPENDIX_CHECKLIST;
+ &APPENDIX_PYTHON;
+
+
+
diff --git a/docs/pwg/intro-basics.xml b/docs/pwg/intro-basics.xml
new file mode 100644
index 0000000000..31770d4ab4
--- /dev/null
+++ b/docs/pwg/intro-basics.xml
@@ -0,0 +1,472 @@
+
+
+
+ Basic Concepts
+
+ 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.
+
+
+
+
+
+ Elements and Plugins
+
+ Elements are at the core of &GStreamer;. In the context of plugin
+ development, an element is an object derived from the
+ GstElement 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.
+
+
+ A filter 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
+ source and sink elements,
+ respectively.
+
+
+ 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
+ plugin 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.
+
+
+ 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.
+
+
+ See the &GstLibRef; for the current implementation details of GstElement
+ and GstPlugin.
+
+
+
+
+
+
+ Pads
+
+ Pads are used to negotiate connections and data flow
+ between elements in &GStreamer;. A pad can be viewed as a
+ place
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.
+
+
+ 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.
+
+
+ See the &GstLibRef; for the current implementation details of a GstPad.
+
+
+
+
+
+
+ Buffers
+
+ 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.
+ Buffers 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.
+
+
+ Buffers also contain metadata describing the buffer's contents. Some of
+ the important types of metadata are:
+
+
+
+ A pointer to the buffer's data.
+
+
+
+
+ An integer indicating the size of the buffer's data.
+
+
+
+
+ A GstData object describing the type of the
+ buffer's data.
+
+
+
+
+ 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 for more details).
+
+
+
+
+
+ See the &GstLibRef; for the current implementation details of a GstBuffer.
+
+
+
+ Buffer Allocation and Buffer Pools
+
+ 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.
+
+
+ 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.
+
+
+
+
+
+
+
+ Types and Properties
+
+ &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.
+
+
+
+
+
+ The Basic Types
+
+ &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.
+
+
+
+ Table of Basic Types
+
+
+
+
+ Mime Type
+ Description
+ Property
+ Property Type
+ Property Values
+ Property Description
+
+
+
+
+
+
+
+
+ audio/raw
+
+ Unstructured and uncompressed raw audio data.
+
+ rate
+ integer
+ greater than 0
+
+ The sample rate of the data, in samples per second.
+
+
+
+ channels
+ integer
+ greater than 0
+
+ The number of channels of audio data.
+
+
+
+ format
+ string
+ int
or float
+
+ The format in which the audio data is passed.
+
+
+
+ law
+ integer
+ 0, 1, or 2
+
+ (Valid only if the data is in integer format.) The law used to
+ describe the data. The value 0 indicates linear
, 1
+ indicates mu law
, and 2 indicates
+ A law
.
+
+
+
+ endianness
+ boolean
+ 0 or 1
+
+ (Valid only if the data is in integer format.) The order of bytes
+ in a sample. The value 0 means little-endian
(bytes
+ are least significant first). The value 1 means
+ big-endian
(most significant byte first).
+
+
+
+ signed
+ boolean
+ 0 or 1
+
+ (Valid only if the data is in integer format.) Whether the samples
+ are signed or not.
+
+
+
+ width
+ integer
+ greater than 0
+
+ (Valid only if the data is in integer format.) The number of bits
+ per sample.
+
+
+
+ depth
+ integer
+ greater than 0
+
+ (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.
+
+
+
+ layout
+ string
+ gfloat
+
+ (Valid only if the data is in float format.) A string representing
+ the way in which the floating point data is represented.
+
+
+
+ intercept
+ float
+ any, normally 0
+
+ (Valid only if the data is in float format.) A floating point
+ value representing the value that the signal
+ centers
on.
+
+
+
+ slope
+ float
+ any, normally 1.0
+
+ (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.
+
+
+
+
+
+
+ audio/mp3
+
+ Audio data compressed using the mp3 encoding scheme.
+
+ framed
+ boolean
+ 0 or 1
+
+ A true value indicates that each buffer contains exactly one
+ frame. A false value indicates that frames and buffers do not
+ necessarily match up.
+
+
+
+ layer
+ integer
+ 1, 2, or 3
+
+ The compression scheme layer used to compress the data.
+
+
+
+ bitrate
+ integer
+ greater than 0
+
+ The bitrate, in kilobits per second. For VBR (variable bitrate)
+ mp3 data, this is the average bitrate.
+
+
+
+ channels
+ integer
+ greater than 0
+
+ The number of channels of audio data present.
+
+
+
+ joint-stereo
+ boolean
+ 0 or 1
+
+ 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 channels
+ attribute must not be zero.
+
+
+
+
+
+
+ audio/x-ogg
+
+ Audio data compressed using the Ogg Vorbis encoding scheme.
+
+
+
+
+
+ FIXME: There are currently no parameters defined for this type.
+
+
+
+
+
+
+ video/raw
+
+ Raw video data.
+
+ fourcc
+ FOURCC code
+
+
+ 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
+ http://www.webartz.com/fourcc/
+
+
+
+ width
+ integer
+ greater than 0
+
+ The number of pixels wide that each video frame is.
+
+
+
+ height
+ integer
+ greater than 0
+
+ The number of pixels high that each video frame is.
+
+
+
+
+
+
+ video/mpeg
+
+ Video data compressed using an MPEG encoding scheme.
+
+
+
+
+
+ FIXME: There are currently no parameters defined for this type.
+
+
+
+
+
+
+ video/avi
+
+ Video data compressed using the AVI encoding scheme.
+
+
+
+
+
+ FIXME: There are currently no parameters defined for this type.
+
+
+
+
+
+
+
+
+
+
+
+
+ Events
+
+ Events are a special type of data in &GStreamer;.
+ Events 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 GstBuffer, so an event buffer will contain
+ only an event, not any other type of data.
+
+
+ See the &GstLibRef; for the current implementation details of a GstEvent.
+
+
+
\ No newline at end of file
diff --git a/docs/pwg/intro-preface.xml b/docs/pwg/intro-preface.xml
new file mode 100644
index 0000000000..45c20c4dc8
--- /dev/null
+++ b/docs/pwg/intro-preface.xml
@@ -0,0 +1,192 @@
+
+
+
+
+ Preface
+
+
+
+
+ Who Should Read This Guide?
+
+ This guide explains how to write new modules for &GStreamer;. The guide is
+ relevant to several groups of people:
+
+
+
+
+ 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.
+
+
+
+
+ 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.
+
+
+
+
+ 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.
+
+
+
+
+ This guide is not relevant to you if you only want to use the existing
+ functionality of &GStreamer;, or if you just want to use an application
+ that uses &GStreamer;. If you are only interested in using existing
+ plugins to write a new application — and there are quite a lot of
+ plugins already — you might want to check the &GstAppDevMan;. If you
+ are just trying to get help with a &GStreamer; application, then you
+ should check with the user manual for that particular application.
+
+
+
+
+
+
+ Preliminary Reading
+
+ 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 &GStreamer; web site,
+ particularly the documents available in the &GStreamer; wiki.
+
+
+ Since &GStreamer; adheres to the GObject programming model, this guide
+ also assumes that you understand the basics of GObject
+ programming. There are several good introductions to the GObject library,
+ including the GTK+ Tutorial.
+
+
+
+
+
+
+ Structure of This Guide
+
+ 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:
+
+
+
+
+ —
+ 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 . Then you
+ will learn how to write the code to get a basic filter plugin working.
+ Several chapters cover these concepts, including , ,
+ , and .
+
+
+ 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 and . Finally, you will learn to test your
+ new plugin in .
+
+
+
+
+ —
+ 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 ,
+ , , , and . Since these features are more advanced,
+ the chapters can basically be read in any order, as you need the
+ features for your custom plugins.
+
+
+
+
+ — 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 and
+ . The chapter on describes writing autoplugger
+ plugins.
+
+
+
+
+ — The
+ appendices contain some information that stubbornly refused to fit
+ cleanly in other sections of this guide, like the and . FIXME: organize better.
+
+
+
+
+
+ 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 ,
+ , , ,
+ and .
+
+
+
+ As you can see, there a lot to learn, so let's get started!
+
+
+
+
+
+ Creating compound and complex elements by extending from a GstBin.
+ This will allow you to create plugins that have other plugins embedded
+ in them.
+
+
+
+
+ Adding new mime-types to the registry along with typedetect functions.
+ This will allow your plugin to operate on a completely new media type.
+
+
+
+
+ Creating custom schedulers when the default schedulers are
+ insufficient.
+
+
+
+
+ Creating custom autopluggers when the default ones are insufficient
+ for your needs.
+
+
+
+
+
diff --git a/docs/pwg/magic-pdf b/docs/pwg/magic-pdf
new file mode 100644
index 0000000000..abc274e270
--- /dev/null
+++ b/docs/pwg/magic-pdf
@@ -0,0 +1 @@
+
diff --git a/docs/pwg/magic-png b/docs/pwg/magic-png
new file mode 100644
index 0000000000..6941e28950
--- /dev/null
+++ b/docs/pwg/magic-png
@@ -0,0 +1 @@
+
diff --git a/docs/pwg/other-autoplugger.xml b/docs/pwg/other-autoplugger.xml
new file mode 100644
index 0000000000..627d15f067
--- /dev/null
+++ b/docs/pwg/other-autoplugger.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Writing an Autoplugger
+
+ FIXME: write.
+
+
diff --git a/docs/pwg/other-sink.xml b/docs/pwg/other-sink.xml
new file mode 100644
index 0000000000..af2a31038e
--- /dev/null
+++ b/docs/pwg/other-sink.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Writing a Sink
+
+ FIXME: write.
+
+
diff --git a/docs/pwg/other-source.xml b/docs/pwg/other-source.xml
new file mode 100644
index 0000000000..bb991d26af
--- /dev/null
+++ b/docs/pwg/other-source.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Writing a Source
+
+ FIXME: write.
+
+
diff --git a/docs/pwg/titlepage.xml b/docs/pwg/titlepage.xml
new file mode 100644
index 0000000000..e4a58e2450
--- /dev/null
+++ b/docs/pwg/titlepage.xml
@@ -0,0 +1,58 @@
+
+
+
+
+ Richard
+ John
+ Boulton
+
+
+ richard-gst@tartarus.org
+
+
+
+
+
+ Erik
+ Walthinsen
+
+
+ omega@temple-baptist.com
+
+
+
+
+
+ Steve
+ Baker
+
+
+ stevebaker_org@yahoo.co.uk
+
+
+
+
+
+ Leif
+ Johnson
+
+
+ leif@ambient.2y.net
+
+
+
+
+
+
+
+ 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 http://www.opencontent.org/openpub/).
+
+
+
+ &GStreamer; Plugin Writer's Guide
+
+