SOMEWHAT OUTDATED, design still holds though
--------------------------------------------


1. Introduction
---------------

The type system is used to attach meaning to the bytes in a GstBuffer.
A plugin can decide to add metadata to the GstBuffer, this metadata
will carry an associated typeid.

Types are also used by the plugins to expose the type of their pads to
the type system.

Types are essential for autoplugging. 

We will explain the inner workings of the type system in this document, as
well as the API used in the plugins.

2. major types
--------------

major types are identified with mime types and are used to denote a 
family of types.

More specific information about the type is given using properties. This
will allow us to be very specific without creating a lot of mime types.

3. API
------

Both a simple array based specification and a real API will be
provided to build the capabilities. 

In the array based approach, we basically build an array of pointers.
Some macros will be available to specify ranges, boolean values, lists
and id's. (not sure if this can be done)

#define GST_TYPE_INT_RANGE(a, b) GST_TYPE_RANGE,(a),(b)
#define GST_TYPE_BOOLEAN(a) GST_TYPE_BOOLEAN,(a)
#define GST_TYPE_LIST(a...) GST_TYPE_LIST,(##a),NULL

for example:

  static GstTypeCapsFactory mpg123_sink_caps[] = {
    "audio/mp3",
    "layer", 	GST_TYPE_INT_RANGE (1, 3),
    "bitrate",	GST_TYPE_INT_RANGE (8, 320),
    "framed",	GST_TYPE_BOOLEAN (true),
    NULL
  };

will expand to the array:

  static GstTypeCapsFactory mpg123_sink_caps[] = {
    "audio/mp3",
    "layer", 	GST_TYPE_RANGE,1,3,
    "bitrate",	GST_TYPE_RANGE,8,320,
    "famed",	GST_TYPE_BOOLEAN,true,
    NULL,
  };

when we register the caps factory, the strings will be converted
into GQuarks and be stored into a GData Keyed Data List.

This will result in a GstTypeCaps structure:

struct _GstTypeCaps {
  guint16 id;                 // if of the major type 

  GData *properties;
}

4. example using arrays
-----------------------

mpg123: an mpeg audio decoder.

  // a factory for the major type we use
  static GstTypeFactory mp3factory = {
    "audio/mp3",		// major type
    ".mp3 .mp2 .mp1 .mpga",	// extensions
    NULL,			// typefind function
  };

  // capabilities of the sink pad
  static GstTypeCapsFactory mpg123_sink_caps[] = {
    "audio/mp3",
    "layer", 	GST_TYPE_INT_RANGE (1, 3),
    "bitrate",	GST_TYPE_INT_RANGE (8, 320),
    "framed",	GST_TYPE_BOOLEAN (true),
    NULL
  };

  // capabilities of the source pad
  static GstTypeCapsFactory mpg123_src_caps[] = {
    "audio/raw",
    "rate", 	GST_TYPE_INT_RANGE (8000, 48000),
    "channels",	GST_TYPE_INT_RANGE (1, 2),
    NULL
  };

  static GstTypeCaps *sinkcaps = NULL, *rawcaps = NULL;

  static gst_mpg123_init (GstMpg123 *mpg123) 
  {
    mpg123->sinpad = gst_pad_new ("sink", GST_PAD_SINK);
    gst_element_add_pad (GST_ELEMENT (mpg123), mpg123->sinkpad);
    gst_pad_set_caps (mpg123->sinkpad, sinkcaps);

    ...
  }

  GstPlugin *plugin_init (GModule *module)
  {
    ...
    plugin = gst_plugin_new ("mpg123");
   
    gst_plugin_add_type_factory (plugin, mp3factory);
  
    ...
    sinkcaps = gst_type_register_caps (mpg123_sink_caps, NULL);
    rawcaps  = gst_type_register_caps (mpg123_src_caps, NULL);
    ...
  }

mpeg2dec: an mpeg video decoder that can do mpeg1 and mpeg2.

  static GstTypeFactory mpegfactory = {
    "video/mpeg",		// major type
    ".mpg .mpeg",		// extensions
    NULL,			// typefind function
  };

  static GstTypeCapsFactory mpeg2dec_sink_caps[] = {
    "video/mpeg",
    "mpegtype", GST_TYPE_LIST (
                        GST_TYPE_INT(1),
                        GST_TYPE_INT(2),
			),
    NULL
  };

  static GstTypeCapsFactory mpeg2dec_src_caps[] = {
    "video/raw",
    "fourcc", 	GST_TYPE_LIST (
                        GST_TYPE_INT32 (0x32315659), 
			GST_TYPE_INT32 (0x32...), 
			),
    "width",	GST_TYPE_INT_RANGE (16, 4096),
    "height",	GST_TYPE_INT_RANGE (16, 4096),
    NULL
  };

  static GstTypeCaps *sinkcaps = NULL, *rawcaps = NULL;

  GstPlugin *plugin_init (GModule *module)
  {
    ...
    plugin = gst_plugin_new ("mpeg2dec");
   
    ...
    sinkcaps = gst_type_register_caps (mpeg2dec_sink_caps, NULL);
    rawcaps  = gst_type_register_caps (mpeg2dec_src_caps, NULL);
    ...
  }


5. capability compatibility
--------------------------

Two pads are compatible if:

- The major types are equal
- range of the sink pad contains the range of the src pad
 

