From cc5f591c17a9f5fd70825da0733daa9adcbdf0de Mon Sep 17 00:00:00 2001 From: Leif Johnson Date: Fri, 27 Sep 2002 18:17:05 +0000 Subject: [PATCH] Moving the "Filter Writer's Guide" to the "Plugin Writers' Guide". Original commit message from CVS: Moving the "Filter Writer's Guide" to the "Plugin Writers' Guide". --- docs/fwg/.gitignore | 13 - docs/fwg/Makefile.am | 18 - docs/fwg/base.css | 0 docs/fwg/buffers.xml | 23 - docs/fwg/checklist.xml | 14 - docs/fwg/dparams.xml | 380 ----------- docs/fwg/gst-plugin-writers-guide.xml | 878 -------------------------- docs/fwg/intro.xml | 173 ----- docs/fwg/loopbased.xml | 27 - docs/fwg/magic-pdf | 1 - docs/fwg/magic-png | 1 - docs/fwg/srcnsink.xml | 16 - docs/fwg/statemanage.xml | 14 - docs/fwg/testapp.xml | 25 - docs/fwg/titlepage.xml | 48 -- 15 files changed, 1631 deletions(-) delete mode 100644 docs/fwg/.gitignore delete mode 100644 docs/fwg/Makefile.am delete mode 100644 docs/fwg/base.css delete mode 100644 docs/fwg/buffers.xml delete mode 100644 docs/fwg/checklist.xml delete mode 100644 docs/fwg/dparams.xml delete mode 100644 docs/fwg/gst-plugin-writers-guide.xml delete mode 100644 docs/fwg/intro.xml delete mode 100644 docs/fwg/loopbased.xml delete mode 100644 docs/fwg/magic-pdf delete mode 100644 docs/fwg/magic-png delete mode 100644 docs/fwg/srcnsink.xml delete mode 100644 docs/fwg/statemanage.xml delete mode 100644 docs/fwg/testapp.xml delete mode 100644 docs/fwg/titlepage.xml diff --git a/docs/fwg/.gitignore b/docs/fwg/.gitignore deleted file mode 100644 index c9012a5e02..0000000000 --- a/docs/fwg/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -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/fwg/Makefile.am b/docs/fwg/Makefile.am deleted file mode 100644 index 72a07dc4c5..0000000000 --- a/docs/fwg/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -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/fwg/base.css b/docs/fwg/base.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/fwg/buffers.xml b/docs/fwg/buffers.xml deleted file mode 100644 index 66e691713b..0000000000 --- a/docs/fwg/buffers.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - Anatomy of a Buffer - - - - - - - - Refcounts and mutability - - - - - - - - Metadata - - - - diff --git a/docs/fwg/checklist.xml b/docs/fwg/checklist.xml deleted file mode 100644 index d67fcb7864..0000000000 --- a/docs/fwg/checklist.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - Things to check when writing a filter - - - - - - - Things to check when writing a source or sink - - - - diff --git a/docs/fwg/dparams.xml b/docs/fwg/dparams.xml deleted file mode 100644 index f8e0bd9965..0000000000 --- a/docs/fwg/dparams.xml +++ /dev/null @@ -1,380 +0,0 @@ - - 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/fwg/gst-plugin-writers-guide.xml b/docs/fwg/gst-plugin-writers-guide.xml deleted file mode 100644 index 3774220067..0000000000 --- a/docs/fwg/gst-plugin-writers-guide.xml +++ /dev/null @@ -1,878 +0,0 @@ - - -%magic-entities; - - - - - - - - - - -GStreamer"> -]> - - - &TITLEPAGE; - - - - Introduction - - - &GStreamer; is a framework for creating - streaming media applications. It is extremely powerful and versatile, - and this versatility stems in part from its modularity, and its ability - to incorporate new modules seamlessly into its framework. - This document describes how to extend the capabilities of - &GStreamer; by creating new plugins. - - - It first describes the concepts required and the ways in which - &GStreamer; can be extended. It then goes - through a worked example of how to write a simple filter (for data - processing), and how to test and debug it. More advanced concepts are - then introduced, with worked examples of each. Next, writing source - and sink elements (for performing input and output) is discussed. - Finally, checklists of things to be sure to do when extending - &GStreamer; are presented. - - - - &INTRO; - - - - - Basic concepts - - - - This section introduces the basic concepts required to understand the - issues involved in extending &GStreamer; - - - Many of these concepts are explained in greater detail in the - GStreamer Application Development Manual, and are merely mentioned - here to refresh your memory. - - - - - - - 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 gstreamer-register utility and the - documentation in the GStreamer Application Development - Manual for more details. - - - User extensions to &GStreamer; can be installed in the main plugin - directory, and will immediately be available for use in applications. - gstreamer-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;. - - - - - Elements - - 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. - - - An element may be constructed in several different ways, but all must - conform to the same basic rules. A 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. - - - - - 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). - - - - - 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 later in this document for - details of the available types. - - - - - Metadata - - - - - - Scheduling - - - - - - Chain vs Loop Elements - - - - - - 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. - - - - - - - - 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. - - - - - - - - The basic types - - This is a list of the basic types used for buffers. For each type, we - give the name ("mime type") of the type, the list of properties which - are associated with the type, the meaning of each property, and the - purpose of the type. - - - - - audio/raw - - Unstructured and uncompressed raw audio data. - - rate - - The sample rate of the data, in samples per second. - - channels - - The number of channels of audio data. - - format - - This describes the format in which the audio data is passed. - This is a string for which there are currently two valid values: - "int" for integer data and "float" for floating point data. - - law - - Valid only if format=int. The law used to describe the data. - This is an integer for which there are three valid values: 0 for - linear, 1 for mu law, 2 for A law. - - endianness - - Valid only if format=int. The order of bytes in a sample. This - is a boolean: 0 means little-endian (ie, bytes are least - significant first), 1 means big-endian (ie, most significant byte - first). - - signed - - Valid only if format=int. Whether the samples are signed or not. - This is a boolean: 0 means unsigned, 1 means signed. - - width - - Valid only if format=int. The number of bits per sample. This - is extremely likely to be a multiple of 8, but as ever this is up - to each element supporting this format to specify. - - depth - - Valid only if format=int. The number of bits used per sample. - This must be less than or equal to the width: if less than the - width, the low bits are assumed to be the ones used. For example, - width=32, depth=24 means that each sample is stored in a 32 bit - word, but only the low 24 bits are actually used. - - layout - - Valid only if format=float. A string representing the way in - which the floating point data is represented. For now, the only - valid value is gfloat, meaning that the data is passed as a series - of gfloat values. - - intercept - - Valid only if format=float. A floating point value representing - the value that the signal "centres" on. - - slope - - Valid only if format=float. A floating point value representing - how far the signal deviates from the intercept. So 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. - - - For example: 16 bit integer, unsigned, linear, monophonic, big-endian, - 44100KHz audio would be represented by - "format=int,law=0,endianness=1,signed=0,width=16,depth=16,rate=44100,channels=1" - and floating point, using gfloat's, in the range -1.0 to 1.0, - 8000KHz stereo audio would be represented by - "format=float,layout=gfloat,intercept=0.0,slope=1.0,rate=8000,channels=2" - - - - - - - audio/mp3 - - Audio data compressed using the mp3 encoding scheme. - - framed - - This is a boolean. If true (1), each buffer contains exactly - one frame. If false (0), frames and buffers do not (necessarily) - match up. If the data is not framed, the values of some of the - properties will not be available, but others will be assumed to - be constant throughout the file, or may be found in other ways. - - layer - - The compression scheme layer used to compress the data. - This is an integer, and can currently have the value 1, 2 - or 3. - - bitrate - - The bitrate, in kilobits per second. - For VBR (variable bitrate) mp3 data, this is the average bitrate. - - channels - - The number of channels of audio data present. This could - theoretically be any integer greater than 0, but in practice will - be either 1 or 2. - - joint-stereo - - Boolean. If true, channels must not be zero. 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. - - There are many other properties relevant for - audio/mp3 data: these may be added to this - specification at a later date. - - - - - - - audio/x-ogg - - Audio data compressed using the Ogg Vorbis encoding scheme. - There are currently no parameters defined for this type. FIXME. - - - - - - - video/raw - - Raw video data. - - fourcc - - 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 - - The number of pixels wide that each video frame is. - - height - - The number of pixels high that each video frame is. - - - - - - - video/mpeg - - Video data compressed using an mpeg encoding scheme. - - mpegversion - - systemstream - - - - - - - video/avi - - Video data compressed using the AVI encoding scheme. - There are currently no parameters defined for this type. FIXME. - - - - - - - Building a simple format for testing - - - - - - A simple MIME type - - - - - - Type properties - - - - - - Typefind functions and autoplugging - - - - - - - - - Building our first plugin - - - We are now have the neccessary concepts to build our first plugin. - We are going to build an element which has a single input pad and - a single output pad, and simply passes anything it reads on - the input pad through and out on the output pad. We will also - see where we could add code to convert this plugin into something - more useful. - - - The example code used in this section can be found in - examples/plugins/ - - - - - Constructing the boilerplate - - The first thing to do when making a new element is to specify some basic - details about it: what its name is, who wrote it, what version number it - is, etc. We also need to define an object to represent the element and to - store the data the element needs. I shall refer to these details - collectively as the boilerplate. - - - - Doing it the hard way with GstObject - - The standard way of defining the boilerplate is simply to write some - code, and fill in some structures. The easiest way to do this is to - copy an example and modify according to your needs. - - - 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/plugins/example.h - - - - /* 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); - - - - - - Doing it the easy way with FilterFactory - - 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. - - - Unfortunately, this hasn't yet been implemented. It is also likely - that when it is, it will not be possible to cover all the possibilities - available by writing the boilerplate yourself, so some plugins will - always need to be manually registered. - - - As a rough outline of what is planned: the FilterFactory will take a - list of appropriate function pointers, and data structures to define - a filter. With a reasonable measure of preprocessor magic, the - plugin writer will then simply need to provide definitions of the - functions and data structures desired, and a name for the filter, and - then call a macro from within plugin_init() which will register the - new filter. All the fluff that goes into the definition of a filter - will thus be hidden from view. - - - Ideally, we will come up with a way for various FilterFactory-provided - functions to be overridden, to the point where you can construct - almost the most complex stuff with it, it just saves typing. - - - Of course, the filter factory can be used to create sources and sinks - too: simply create a filter with only source or sink pads. - - - You may be thinking that this should really be called an - ElementFactory. Well, we agree, but there is already something else - justifiably ealled an ElementFactory (this is the thing which actually - makes instances of elements). There is also already something called - a PluginFactory. We just have too many factories and not enough words. - And since this isn't yet written, it doesn't get priority for claiming - a name. - - - - - - Defining an element - - A new element is defined by creating an element factory. This is a - structure containing all the information needed to create an instance - of the element. Creating a factory requires two things: a type for - the element to be created - (this was defined in the boilerplate above: FIXME - reorganise), - and a GstElementDetails structure, which contains some - general information about the element to be created. - - - - 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 ".". - - 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. - - - - - Specifying the pads - - - - - - Attaching functions - - - - - - The chain function - - - - - - Adding arguments - - Define arguments in enum. - - - - - - Signals - - Define signals in enum. - - - - - - - Defining a type - - A new type is defined by creating an type factory. This is a - structure containing all the information needed to create an instance - of the type. - - - - - 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. - - - - Registering new types - - - - - void gst_plugin_add_type(GstPlugin *plugin, - GstTypeFactory *factory); - - - - - - - Registering new element factories - - - - void gst_plugin_add_factory(GstPlugin *plugin, - GstElementFactory *factory); - - - Multiple element factories can be provided by a single plugin: - all it needs to do is call gst_plugin_add_factory() for each - element factory it wishes to provide. - - - - - Registering new autopluggers - - - - void gst_plugin_add_autoplugger(GstPlugin *plugin, - GstAutoplugFactory *factory); - - - - - - - - - - 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 - - - - - - - &DPARAMS; - - - - - Building a simple test application - - - - - - &TESTAPP; - - - - - Loop-based Elements - - - - - - &LOOPBASED; - - - - - Buffers and Metadata - - - - - - &BUFFERS; - - - - - Sources and Sinks - - - - - - &SRCNSINK; - - - - - State management - - - - - - &STATEMANAGE; - - - - - Checklist - - - - - - &CHECKLIST; - - - diff --git a/docs/fwg/intro.xml b/docs/fwg/intro.xml deleted file mode 100644 index f7f764ef63..0000000000 --- a/docs/fwg/intro.xml +++ /dev/null @@ -1,173 +0,0 @@ - - Do I care? - - This guide explains how to write new modules for GStreamer. It is - relevant to: - - - - - Anyone who wants to add support for new input and output - devices, often called sources and sinks. For example, - adding the ability to write to a new video output system - could be done by writing an appropriate sink plugin. - - - - - Anyone who wants to add support for new ways of processing - data in GStreamer, often called - filters. For example, a new data format converter could be - created. - - - - - 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 it places on the - rest of the code. And you might be surprised 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 use an application which uses GStreamer. - You lot can go away. Shoo... (You might find the GStreamer - Application Development Manual helpful though.) - - - - - Preliminary reading - - The reader should be familiar with the basic workings of - GStreamer. For a gentle introduction to - GStreamer, you may wish to read the GStreamer Application - Development Manual. Since GStreamer - adheres to the GObject programming model, the reader is also assumed to - understand the basics of GObject. - - - - - Structure of this guide - - The GStreamer API for developing plugins is - rather extensive and powerful. We will first try to get you up and running - with a simple plugin as fast as possible. We will then gradually add more - features to our example plugin. The basic topics will be: - - - - - Short overview of the GStreamer concepts. People familiar with the - GStreamer Application Development Manual can use - this short overview to refresh their memory. - - - - - Introduction to the basic structure of the plugin. We will cover all the - different steps you have to perform in order to build a plugin. This will - include a general overview of the structure of your source files. - - - - - Creating the plugin boilerplate. We will show you how to define and set up - the different aspects for creating a plugin. This will cover extending the - GstElement class and creating the elementfactory structures. This will include - setting up the .h and .c files of your plugin. - - - - - Defining the entry point of the plugin and registering the elementfactory. - After this step your plugin will become available for application programmers. - - - - - Setting up the basic components of the element like adding pads and setting - up the scheduling entry points of your plugin. - - - - - Adding arguments and signals to the plugin. Users of your plugin will be - able to listen for specific events your plugin generates as well as change and - adjust the different properties of your plugin. - - - - - Compiling and testing the basic plugin. - - - - - After this first section, you should be able to create a simple plugin. We will then - introduce the more advanced concepts of plugins, including: - - - - - Adding padtemplates to the plugin. This will allow your plugin to become fully - integrated in the GStreamer plugin registry and will allow users of your plugin - to know what media types your plugin operates on. - - - - - Adding new mime-types to the registry along with typedetect functions. This will allow - your plugin to operate on a completely new media type. - - - - - Adding caps to the plugins input pads. This will allow other plugins to know what - media type your plugin is handling at runtime. - - - - - Choosing between a loop-based or a chain-based plugin. We will teach you how to - create plugins with a more complicated input/output behaviour. - - - - - Adding request pads to the plugin. Request pads allow the application programmer - to let your plugin dynamically create a pad based on a template. - - - - - Caps negotiation will show you how your plugin can addapt to the plugins it - is connected to. - - - - - Creating compound and complex elements by extending from a GstBin. This will - allow you to create plugins that have other plugins embedded in them. - - - - - Creating custom schedulers when the default schedulers are insufficient. - - - - - Creating custom autopluggers when the default ones are insufficient for your needs. - - - - - As you can see, there a lot to learn, so let's get started... - - - diff --git a/docs/fwg/loopbased.xml b/docs/fwg/loopbased.xml deleted file mode 100644 index 249f9ff9ad..0000000000 --- a/docs/fwg/loopbased.xml +++ /dev/null @@ -1,27 +0,0 @@ - - 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/fwg/magic-pdf b/docs/fwg/magic-pdf deleted file mode 100644 index abc274e270..0000000000 --- a/docs/fwg/magic-pdf +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/fwg/magic-png b/docs/fwg/magic-png deleted file mode 100644 index 6941e28950..0000000000 --- a/docs/fwg/magic-png +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/fwg/srcnsink.xml b/docs/fwg/srcnsink.xml deleted file mode 100644 index 33d5223db4..0000000000 --- a/docs/fwg/srcnsink.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - Writing a source - - - Pull vs loop based - Region pulling - - - - - Writing a sink - - - - diff --git a/docs/fwg/statemanage.xml b/docs/fwg/statemanage.xml deleted file mode 100644 index 4d8a1e1474..0000000000 --- a/docs/fwg/statemanage.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - What are states? - - - - - - - Mangaging filter state - - - - diff --git a/docs/fwg/testapp.xml b/docs/fwg/testapp.xml deleted file mode 100644 index bfbd66abdd..0000000000 --- a/docs/fwg/testapp.xml +++ /dev/null @@ -1,25 +0,0 @@ - - Initialization - - - - - - Instantiating the plugins - - (NOTE: we really should have a debugging Sink) - - - - - Connecting the plugins - - - - - - Running the pipeline - - - - diff --git a/docs/fwg/titlepage.xml b/docs/fwg/titlepage.xml deleted file mode 100644 index 1a7dd862a2..0000000000 --- a/docs/fwg/titlepage.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - Richard - John - Boulton - - - richard-gst@tartarus.org - - - - - - Erik - Walthinsen - - - omega@temple-baptist.com - - - - - - Steve - Baker - - - stevebaker_org@yahoo.co.uk - - - - - - - - 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/" ) - - - - <application>GStreamer</application> Plugin Writer's Guide - -