mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
docs/pwg/advanced_types.xml: Finish documenting the current state of mimetypes.
Original commit message from CVS: 2004-01-27 Ronald Bultje <rbultje@ronald.bitfreak.net> * docs/pwg/advanced_types.xml: Finish documenting the current state of mimetypes. * docs/pwg/building_boiler.xml: * docs/pwg/building_chainfn.xml: * docs/pwg/building_pads.xml: * docs/pwg/building_props.xml: * docs/pwg/building_testapp.xml: Start documenting the "how to build a simple audio filter" part of the PWG. Most stuff is ready by now. Stuff remaining: signals, states and (maybe?) a short introduction to capsnego in the chapter on pads (building_pads.xml). Capsnego should probably be explained fully in advanced_capsnego.xml or so.
This commit is contained in:
parent
3607f4f024
commit
8e29a5888a
7 changed files with 1183 additions and 93 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2004-01-27 Ronald Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* docs/pwg/advanced_types.xml:
|
||||
Finish documenting the current state of mimetypes.
|
||||
* docs/pwg/building_boiler.xml:
|
||||
* docs/pwg/building_chainfn.xml:
|
||||
* docs/pwg/building_pads.xml:
|
||||
* docs/pwg/building_props.xml:
|
||||
* docs/pwg/building_testapp.xml:
|
||||
Start documenting the "how to build a simple audio filter" part
|
||||
of the PWG. Most stuff is ready by now. Stuff remaining: signals,
|
||||
states and (maybe?) a short introduction to capsnego in the chapter
|
||||
on pads (building_pads.xml). Capsnego should probably be explained
|
||||
fully in advanced_capsnego.xml or so.
|
||||
|
||||
2004-01-26 David Schleef <ds@schleef.org>
|
||||
|
||||
* gst/gstpad.c: (gst_pad_try_set_caps_nonfixed):
|
||||
|
|
|
@ -92,13 +92,33 @@
|
|||
<title>List of Defined Types</title>
|
||||
<para>
|
||||
Below is a list of all the defined types in &GStreamer;. They are split
|
||||
up in separate tables for audio, video, container, text and other
|
||||
up in separate tables for audio, video, container, subtitle and other
|
||||
types, for the sake of readability. Below each table might follow a
|
||||
list of notes that apply to that table. In the definition of each type,
|
||||
we try to follow the types and rules as defined by <ulink type="http"
|
||||
url="http://www.isi.edu/in-notes/iana/assignments/media-types/media-types">
|
||||
IANA</ulink> for as far as possible.
|
||||
</para>
|
||||
<para>
|
||||
Jump directly to a specific table:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><xref linkend="table-audio-types"/></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><xref linkend="table-video-types"/></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><xref linkend="table-container-types"/></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><xref linkend="table-subtitle-types"/></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><xref linkend="table-other-types"/></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
Note that many of the properties are not <emphasis>required</emphasis>,
|
||||
but rather <emphasis>optional</emphasis> properties. This means that
|
||||
|
@ -110,7 +130,9 @@
|
|||
content. Example: the AVI header provides samplerate of the contained
|
||||
audio stream in the header. MPEG system streams don't. This means that
|
||||
an AVI stream demuxer would provide samplerate as a property for MPEG
|
||||
audio streams, whereas an MPEG demuxer would not.
|
||||
audio streams, whereas an MPEG demuxer would not. A decoder needing
|
||||
this data would require a stream parser in between two extract this
|
||||
from the header or calculate it from the stream.
|
||||
</para>
|
||||
|
||||
<table frame="all" id="table-audio-types" xreflabel="Table of Audio Types">
|
||||
|
@ -433,20 +455,6 @@
|
|||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>audio/x-pn-realaudio</entry>
|
||||
<entry>Real Audio data.</entry>
|
||||
<entry>raversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>1 or 2</entry>
|
||||
<entry>
|
||||
The version of the Real Audio codec used to encode the stream.
|
||||
1 stands for a 14k4 stream, 2 stands for a 28k8 stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>audio/x-qdm2</entry>
|
||||
<entry>Data encoded by the QDM version 2 codec.</entry>
|
||||
|
@ -461,6 +469,20 @@
|
|||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>audio/x-pn-realaudio</entry>
|
||||
<entry>Realmedia Audio data.</entry>
|
||||
<entry>raversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>1 or 2</entry>
|
||||
<entry>
|
||||
The version of the Real Audio codec used to encode the stream.
|
||||
1 stands for a 14k4 stream, 2 stands for a 28k8 stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>audio/x-speex</entry>
|
||||
<entry>Data encoded by the Speex audio codec</entry>
|
||||
|
@ -502,7 +524,7 @@
|
|||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
|
||||
<table frame="all" id="table-video-types" xreflabel="Table of Video Types">
|
||||
<title>Table of Video Types</title>
|
||||
<tgroup cols="6" align="left" colsep="1" rowsep="1">
|
||||
|
@ -650,6 +672,20 @@
|
|||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-3ivx</entry>
|
||||
<entry>3ivx video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-divx</entry>
|
||||
<entry>DivX video.</entry>
|
||||
|
@ -660,8 +696,504 @@
|
|||
Version of the DivX codec used to encode the stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-dx</entry>
|
||||
<entry>Digital Video.</entry>
|
||||
<entry>systemstream</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>FALSE</entry>
|
||||
<entry>
|
||||
Indicates that this stream is <emphasis>not</emphasis> a system
|
||||
container stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-ffv</entry>
|
||||
<entry>FFMpeg video.</entry>
|
||||
<entry>ffvversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>1</entry>
|
||||
<entry>
|
||||
Version of the FFMpeg video codec used to encode the stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-h263</entry>
|
||||
<entry>H-263 video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-h264</entry>
|
||||
<entry>H-264 video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-huffyuv</entry>
|
||||
<entry>Huffyuv video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-indeo</entry>
|
||||
<entry>Indeo video.</entry>
|
||||
<entry>indeoversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>3</entry>
|
||||
<entry>
|
||||
Version of the Indeo codec used to encode this stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-jpeg</entry>
|
||||
<entry>Motion-JPEG video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type. Note that video/x-jpeg only applies to Motion-JPEG
|
||||
pictures (YUY2 colourspace). RGB colourspace JPEG images are
|
||||
referred to as image/jpeg (JPEG image).
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry morerows="1">video/mpeg</entry>
|
||||
<entry morerows="1">MPEG video.</entry>
|
||||
<entry>mpegversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>1, 2 or 4</entry>
|
||||
<entry>
|
||||
Version of the MPEG codec that this stream was encoded with.
|
||||
Note that we have different mimetypes for 3ivx, XviD, DivX and
|
||||
"standard" ISO MPEG-4. This is <emphasis>not</emphasis> a good
|
||||
thing and we're fully aware of this. However, we do not have a
|
||||
solution yet.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>systemstream</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>FALSE</entry>
|
||||
<entry>
|
||||
Indicates that this stream is <emphasis>not</emphasis> a system
|
||||
container stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-msmpeg</entry>
|
||||
<entry>Microsoft MPEG-4 video deviations.</entry>
|
||||
<entry>msmpegversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>41, 42 or 43</entry>
|
||||
<entry>
|
||||
Version of the MS-MPEG-4-like codec that was used to encode this
|
||||
version. A value of 41 refers to MS MPEG 4.1, 42 to 4.2 and 43
|
||||
to version 4.3.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-pn-realvideo</entry>
|
||||
<entry>Realmedia video.</entry>
|
||||
<entry>rmversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>1, 2 or 3</entry>
|
||||
<entry>
|
||||
Version of the Real Video codec that this stream was encoded
|
||||
with.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-svq</entry>
|
||||
<entry>Sorensen Video.</entry>
|
||||
<entry>svqversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>1 or 3</entry>
|
||||
<entry>
|
||||
Version of the Sorensen codec that the stream was encoded with.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-tarkin</entry>
|
||||
<entry>Tarkin video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-theora</entry>
|
||||
<entry>Theora video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-vp3</entry>
|
||||
<entry>VP-3 video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type. Note that we have different mimetypes for VP-3 and
|
||||
Theora, which is not necessarily a good idea. This could probably
|
||||
be improved.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-wmv</entry>
|
||||
<entry>Windows Media Video.</entry>
|
||||
<entry>wmvversion</entry>
|
||||
<entry>integer</entry>
|
||||
<entry>1 or 2</entry>
|
||||
<entry>
|
||||
Version of the WMV codec that the stream was encoded with.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-xvid</entry>
|
||||
<entry>XviD video.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ subtitle ############# -->
|
||||
|
||||
<row>
|
||||
<entry spanname="fullwidth">
|
||||
<emphasis>All image types.</emphasis>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>image/jpeg</entry>
|
||||
<entry>Joint Picture Expert Group Image.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type. Note that image/jpeg only applies to RGB-colourspace
|
||||
JPEG images; YUY2-colourspace JPEG pictures are referred to as
|
||||
video/x-jpeg ("Motion JPEG").
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>image/png</entry>
|
||||
<entry>Portable Network Graphics Image.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table frame="all" id="table-container-types" xreflabel="Table of Container Types">
|
||||
<title>Table of Container Types</title>
|
||||
<tgroup cols="6" align="left" colsep="1" rowsep="1">
|
||||
<colspec colnum="1" colname="colc1" colwidth="1*"/>
|
||||
<colspec colnum="6" colname="colc6" colwidth="6*"/>
|
||||
<spanspec spanname="fullwidth" namest="colc1" nameend="colc6"/>
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Mime Type</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Property</entry>
|
||||
<entry>Property Type</entry>
|
||||
<entry>Property Values</entry>
|
||||
<entry>Property Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody valign="top">
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-ms-asf</entry>
|
||||
<entry>Advanced Streaming Format (ASF).</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-msvideo</entry>
|
||||
<entry>AVI.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-dv</entry>
|
||||
<entry>Digital Video.</entry>
|
||||
<entry>systemstream</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>TRUE</entry>
|
||||
<entry>
|
||||
Indicates that this is a container system stream rather than an
|
||||
elementary video stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-matroska</entry>
|
||||
<entry>Matroska.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/mpeg</entry>
|
||||
<entry>Motion Pictures Expert Group System Stream.</entry>
|
||||
<entry>systemstream</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>TRUE</entry>
|
||||
<entry>
|
||||
Indicates that this is a container system stream rather than an
|
||||
elementary video stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>application/ogg</entry>
|
||||
<entry>Ogg.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/quicktime</entry>
|
||||
<entry>Quicktime.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>video/x-pn-realvideo</entry>
|
||||
<entry>Digital Video.</entry>
|
||||
<entry>systemstream</entry>
|
||||
<entry>boolean</entry>
|
||||
<entry>TRUE</entry>
|
||||
<entry>
|
||||
Indicates that this is a container system stream rather than an
|
||||
elementary video stream.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry>audio/x-wav</entry>
|
||||
<entry>WAV.</entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
There are currently no specific properties defined or needed for
|
||||
this type.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table frame="all" id="table-subtitle-types" xreflabel="Table of Subtitle Types">
|
||||
<title>Table of Subtitle Types</title>
|
||||
<tgroup cols="6" align="left" colsep="1" rowsep="1">
|
||||
<colspec colnum="1" colname="colt1" colwidth="1*"/>
|
||||
<colspec colnum="6" colname="colt6" colwidth="6*"/>
|
||||
<spanspec spanname="fullwidth" namest="colt1" nameend="colt6"/>
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Mime Type</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Property</entry>
|
||||
<entry>Property Type</entry>
|
||||
<entry>Property Values</entry>
|
||||
<entry>Property Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody valign="top">
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
None defined yet.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table frame="all" id="table-other-types" xreflabel="Table of Other Types">
|
||||
<title>Table of Other Types</title>
|
||||
<tgroup cols="6" align="left" colsep="1" rowsep="1">
|
||||
<colspec colnum="1" colname="colo1" colwidth="1*"/>
|
||||
<colspec colnum="6" colname="colo6" colwidth="6*"/>
|
||||
<spanspec spanname="fullwidth" namest="colo1" nameend="colo6"/>
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Mime Type</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Property</entry>
|
||||
<entry>Property Type</entry>
|
||||
<entry>Property Values</entry>
|
||||
<entry>Property Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody valign="top">
|
||||
|
||||
<!-- ############ type ############# -->
|
||||
|
||||
<row>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry></entry>
|
||||
<entry>
|
||||
None defined yet.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
|
|
@ -33,10 +33,10 @@
|
|||
</para>
|
||||
<screen>
|
||||
<prompt>shell $ </prompt><userinput>cd .</userinput>
|
||||
<prompt>shell $ </prompt><userinput>cvs -d:pserver:anonymous@cvs.gstreamer.sourceforge.net:/cvsroot/gstreamer login</userinput>
|
||||
Logging in to :pserver:anonymous@cvs.gstreamer.sourceforge.net:2401/cvsroot/gstreamer
|
||||
<prompt>shell $ </prompt><userinput>cvs -d:pserver:anonymous@cvs.freedesktop.org:/home/cvs/gstreamer login</userinput>
|
||||
Logging in to :pserver:anonymous@cvs.freedesktop.org:2401/home/cvs/gstreamer
|
||||
CVS password:
|
||||
<prompt>shell $ </prompt><userinput>cvs -z3 -d:pserver:anonymous@cvs.gstreamer.sourceforge.net:/cvsroot/gstreamer co gst-template</userinput>
|
||||
<prompt>shell $ </prompt><userinput>cvs -z3 -d:pserver:anonymous@cvs.freedesktop.org:/home/cvs/gstreamer co gst-template</userinput>
|
||||
U gst-template/README
|
||||
U gst-template/gst-app/AUTHORS
|
||||
U gst-template/gst-app/ChangeLog
|
||||
|
@ -136,9 +136,9 @@ U gst-template/gst-app/src/Makefile.am
|
|||
struct _GstExample {
|
||||
GstElement element;
|
||||
|
||||
GstPad *sinkpad,*srcpad;
|
||||
GstPad *sinkpad, *srcpad;
|
||||
|
||||
gint8 active;
|
||||
gboolean silent;
|
||||
};
|
||||
|
||||
/* Standard definition defining a class for this element. */
|
||||
|
@ -160,7 +160,7 @@ U gst-template/gst-app/src/Makefile.am
|
|||
(GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EXAMPLE))
|
||||
|
||||
/* Standard function returning type information. */
|
||||
GtkType gst_example_get_type(void);
|
||||
GType gst_example_get_type (void);
|
||||
</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
|
@ -213,35 +213,105 @@ U gst-template/gst-app/src/Makefile.am
|
|||
give a better reference to them)
|
||||
</para></listitem><listitem><para>
|
||||
A brief description of the purpose of the element.
|
||||
</para></listitem><listitem><para>
|
||||
The version number of the element. For elements in the main GStreamer
|
||||
source code, this will often simply be VERSION, which is a macro defined
|
||||
to be the version number of the current GStreamer version. The only
|
||||
requirement, however, is that the version number should increase
|
||||
monotonically.
|
||||
</para>
|
||||
<para>
|
||||
Version numbers should be stored in major.minor.patch form: ie, 3
|
||||
(decimal) numbers, separated by periods (.).
|
||||
</para></listitem><listitem><para>
|
||||
The name of the author of the element, optionally followed by a contact
|
||||
email address in angle brackets.
|
||||
</para></listitem><listitem><para>
|
||||
The copyright details for the element.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
For example:
|
||||
</para>
|
||||
<programlisting>
|
||||
static GstElementDetails example_details = {
|
||||
"An example plugin",
|
||||
"Example/FirstExample",
|
||||
"Shows the basic structure of a plugin",
|
||||
VERSION,
|
||||
"your name <your.name@your.isp>",
|
||||
"(C) 2001",
|
||||
static GstElementDetails example_details = {
|
||||
"An example plugin",
|
||||
"Example/FirstExample",
|
||||
"Shows the basic structure of a plugin",
|
||||
"your name <your.name@your.isp>"
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
The element details are registered with the plugin during
|
||||
<function>_base_init ()</function>.
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
gst_my_filter_base_init (GstMyFilterClass *klass)
|
||||
{
|
||||
static GstElementDetails my_filter_details = {
|
||||
[..]
|
||||
};
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
[..]
|
||||
gst_element_class_set_details (element_class, &my_filter_details);
|
||||
}
|
||||
</programlisting>
|
||||
</sect1>
|
||||
|
||||
<!-- ############ sect1 ############# -->
|
||||
|
||||
<sect1 id="sect1-boiler-padtemplates">
|
||||
<title>GstStaticPadTemplate</title>
|
||||
<para>
|
||||
A GstStaticPadTemplate is a description of a pad that the element will
|
||||
(or might) create and use. It contains:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>A short name for the pad.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Pad direction.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Existence property. This indicates whether the pad exists always (an
|
||||
<quote>always</quote> pad), only in some cases (a
|
||||
<quote>sometimes</quote> pad) or only if the application requested
|
||||
such a pad (a <quote>request</quote> pad).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Supported types by this element (capabilities).</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
For example:
|
||||
</para>
|
||||
<programlisting>
|
||||
static GstStaticPadTemplate sink_factory =
|
||||
GST_STATIC_PAD_TEMPLATE (
|
||||
"sink",
|
||||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS ("ANY")
|
||||
);
|
||||
</programlisting>
|
||||
<para>
|
||||
Those pad templates are registered during the
|
||||
<function>_base_init ()</function> function. Pads are created from these
|
||||
templates in the element's <function>_init ()</function> function using
|
||||
<function>gst_pad_new_from_template ()</function>. The template can be
|
||||
retrieved from the element class using
|
||||
<function>gst_element_class_get_pad_template ()</function>. See below
|
||||
for more details on this.
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
gst_my_filter_base_init (GstMyFilterClass *klass)
|
||||
{
|
||||
static GstStaticPadTemplate sink_factory =
|
||||
[..]
|
||||
, src_factory =
|
||||
[..]
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&src_factory));
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_static_pad_template_get (&sink_factory));
|
||||
[..]
|
||||
}
|
||||
</programlisting>
|
||||
</sect1>
|
||||
|
||||
|
@ -250,11 +320,14 @@ U gst-template/gst-app/src/Makefile.am
|
|||
<sect1 id="sect1-boiler-constructors">
|
||||
<title>Constructor Functions</title>
|
||||
<para>
|
||||
Each element has two functions which are used for construction of an
|
||||
element. These are the _class_init() function, which is used to initialise
|
||||
the class (specifying what signals and arguments the class has and setting
|
||||
up global state), and the _init() function, which is used to initialise a
|
||||
specific instance of the class.
|
||||
Each element has three functions which are used for construction of an
|
||||
element. These are the <function>_base_init()</function> function which
|
||||
is meant to initialize class and child class properties during each new
|
||||
child class creation; the <function>_class_init()</function> function,
|
||||
which is used to initialise the class only once (specifying what signals,
|
||||
arguments and virtual functions the class has and setting up global
|
||||
state); and the <function>_init()</function> function, which is used to
|
||||
initialise a specific instance of this type.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
@ -265,36 +338,20 @@ U gst-template/gst-app/src/Makefile.am
|
|||
<para>
|
||||
Once we have written code defining all the parts of the plugin, we need to
|
||||
write the plugin_init() function. This is a special function, which is
|
||||
called as soon as the plugin is loaded, and must return a pointer to a
|
||||
newly allocated GstPlugin structure. This structure contains the details
|
||||
of all the facilities provided by the plugin, and is the mechanism by
|
||||
which the definitions are made available to the rest of the &GStreamer;
|
||||
system. Helper functions are provided to help fill the structure: for
|
||||
future compatability it is required that these functions are used, as
|
||||
documented below, rather than attempting to access the structure directly.
|
||||
called as soon as the plugin is loaded, and should return TRUE or FALSE
|
||||
depending on whether it loaded initialized any dependencies correctly.
|
||||
Also, in this function, any supported element type in the plugin should
|
||||
be registered.
|
||||
</para>
|
||||
<para>
|
||||
Note that the information returned by the plugin_init() function will be
|
||||
cached in a central registry. For this reason, it is important that the
|
||||
same information is always returned by the function: for example, it
|
||||
must not make element factories available based on runtime conditions. If an element
|
||||
can only work in certain conditions (for example, if the soundcard is not
|
||||
being used by some other process) this must be reflected by the element
|
||||
being unable to enter the READY state if unavailable, rather than the plugin
|
||||
attempting to deny existence of the plugin.
|
||||
must not make element factories available based on runtime conditions.
|
||||
If an element can only work in certain conditions (for example, if the
|
||||
soundcard is not being used by some other process) this must be reflected
|
||||
by the element being unable to enter the READY state if unavailable,
|
||||
rather than the plugin attempting to deny existence of the plugin.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,5 +4,73 @@
|
|||
<chapter id="cha-building-chainfn">
|
||||
<title>The chain function</title>
|
||||
<para>
|
||||
The chain function is the function in which all data processing takes
|
||||
place. In the case of a simple filter, <function>_chain ()</function>
|
||||
functions are mostly lineair functions - so for each incoming buffer,
|
||||
one buffer will go out, too. Below is a very simple implementation of
|
||||
a chain function:
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
gst_my_filter_chain (GstPad *pad,
|
||||
GstData *data)
|
||||
{
|
||||
GstMyFilter *filter = GST_MY_FILTER (gst_pad_get_parent (pad));
|
||||
GstBuffer *buf = GST_BUFFER (data);
|
||||
|
||||
if (!filter->silent)
|
||||
g_print ("Have data of size %u bytes!\n", GST_BUFFER_SIZE (buf));
|
||||
|
||||
gst_pad_push (filter->srcpad, GST_DATA (buf));
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
Obviously, the above doesn't do much useful. Instead of printing that the
|
||||
data is in, you would normally process the data there. Remember, however,
|
||||
that buffers are not always writable. In more advanced elements (the ones
|
||||
that do event processing), the incoming data might not even be a buffer.
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
gst_my_filter_chain (GstPad *pad,
|
||||
GstData *data)
|
||||
{
|
||||
GstMyFilter *filter = GST_MY_FILTER (gst_pad_get_parent (pad));
|
||||
GstBuffer *buf, *outbuf;
|
||||
|
||||
if (GST_IS_EVENT (data)) {
|
||||
GstEvent *event = GST_EVENT (data);
|
||||
|
||||
switch (GST_EVENT_TYPE (event)) {
|
||||
case GST_EVENT_EOS:
|
||||
/* end-of-stream, we should close down all stream leftovers here */
|
||||
gst_my_filter_stop_processing (filter);
|
||||
/* fall-through to default event handling */
|
||||
default:
|
||||
gst_pad_event_default (pad, event);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
buf = GST_BUFFER (data);
|
||||
outbuf = gst_my_filter_process_data (buf);
|
||||
gst_buffer_unref (buf);
|
||||
if (!outbuf) {
|
||||
/* something went wrong - signal an error */
|
||||
gst_element_error (GST_ELEMENT (filter), STREAM, FAILED, (NULL), (NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
gst_pad_push (filter->srcpad, GST_DATA (outbuf));
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
In some cases, it might be useful for an element to have control over the
|
||||
input data rate, too. In that case, you probably want to write a so-called
|
||||
<emphasis>loop-based</emphasis> element. Source elements (with only source
|
||||
pads) can also be <emphasis>get-based</emphasis> elements. These concepts
|
||||
will be explained in the advanced section of this guide, and in the section
|
||||
that specifically discusses source pads.
|
||||
</para>
|
||||
</chapter>
|
||||
|
|
|
@ -4,6 +4,192 @@
|
|||
<chapter id="cha-building-pads">
|
||||
<title>Specifying the pads</title>
|
||||
<para>
|
||||
As explained before, pads are the port through which data goes in and out
|
||||
of your element, and that makes them a very important item in the process
|
||||
of element creation. In the boilerplate code, we have seen how static pad
|
||||
templates take care of registering pad templates with the element class.
|
||||
Here, we will see how to create actual elements, use <function>_link ()</function>
|
||||
and <function>_getcaps ()</function> functions to let other elements know
|
||||
their capabilities and how to register functions to let data flow through
|
||||
the element.
|
||||
</para>
|
||||
<para>
|
||||
In the element <function>_init ()</function> function, you create the pad
|
||||
from the pad template that has been registered with the element class in
|
||||
the <function>_base_init ()</function> function. After creating the pad,
|
||||
you have to set a <function>_link ()</function> function pointer and a
|
||||
<function>_getcaps ()</function> function pointer. Optionally, you can
|
||||
set a <function>_chain ()</function> function pointer (on sink pads in
|
||||
filter and sink elements) through which data will come in to the element,
|
||||
or (on source pads in source elements) a <function>_get ()</function>
|
||||
function pointer through which data will be pulled from the element. After
|
||||
that, you have to register the pad with the element. This happens like
|
||||
this:
|
||||
</para>
|
||||
<programlisting>
|
||||
static GstPadLinkReturn gst_my_filter_link (GstPad *pad,
|
||||
const GstCaps *caps);
|
||||
static GstCaps * gst_my_filter_getcaps (GstPad *pad);
|
||||
static void gst_my_filter_chain (GstPad *pad,
|
||||
GstData *data);
|
||||
|
||||
static void
|
||||
gst_my_filter_init (GstMyFilter *filter)
|
||||
{
|
||||
GstElementClass *klass = GST_ELEMENT_GET_CLASS (filter);
|
||||
|
||||
/* pad through which data comes in to the element */
|
||||
filter->sinkpad = gst_pad_new_from_template (
|
||||
gst_element_class_get_pad_template (klass, "sink"), "sink");
|
||||
gst_pad_set_link_function (filter->sinkpad, gst_my_filter_link);
|
||||
gst_pad_set_getcaps_function (filter->sinkpad, gst_my_filter_getcaps);
|
||||
gst_pad_set_chain_function (filter->sinkpad, gst_my_filter_chain);
|
||||
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
|
||||
|
||||
/* pad through which data goes out of the element */
|
||||
filter->srcpad = gst_pad_new_from_template (
|
||||
gst_element_class_get_pad_template (klass, "src"), "src");
|
||||
gst_pad_set_link_function (filter->srcpad, gst_my_filter_link);
|
||||
gst_pad_set_getcaps_function (filter->srcpad, gst_my_filter_getcaps);
|
||||
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
|
||||
[..]
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The <function>_link ()</function> is called during caps negotiation. This
|
||||
is the process where the linked pads decide on the streamtype that will
|
||||
transfer between them. A full list of type-definitions can be found in
|
||||
<xref linkend="cha-building-types"/>. A <function>_link ()</function>
|
||||
receives a pointer to a <classname>GstCaps</classname> struct that
|
||||
defines the proposed streamtype, and can respond with either
|
||||
<quote>yes</quote> (<classname>GST_PAD_LINK_OK</classname>),
|
||||
<quote>no</quote> (<classname>GST_PAD_LINK_REFUSED</classname>) or
|
||||
<quote>don't know yet</quote> (<classname>GST_PAD_LINK_DELAYED</classname>).
|
||||
If the element responds positively towards the streamtype, that type
|
||||
will be used on the pad. An example:
|
||||
</para>
|
||||
<programlisting>
|
||||
static GstPadLinkReturn
|
||||
gst_my_filter_link (GstPad *pad,
|
||||
const GstCaps *caps)
|
||||
{
|
||||
GstStructure *structure = gst_caps_get_structure (caps, 0);
|
||||
GstMyFilter *filter = GST_MY_FILTER (gst_pad_get_parent (pad));
|
||||
GstPad *otherpad = (pad == filter->srcpad) ? filter->sinkpad :
|
||||
filter->srcpad;
|
||||
GstPadLinkReturn ret;
|
||||
const gchar *mime;
|
||||
|
||||
/* Since we're an audio filter, we want to handle raw audio
|
||||
* and from that audio type, we need to get the samplerate and
|
||||
* number of channels. */
|
||||
mime = gst_structure_get_name (structure);
|
||||
if (strcmp (mime, "audio/x-raw-int") != 0) {
|
||||
GST_WARNING ("Wrong mimetype %s provided, we only support %s",
|
||||
mime, "audio/x-raw-int");
|
||||
return GST_PAD_LINK_REFUSED;
|
||||
}
|
||||
|
||||
/* we're a filter and don't touch the properties of the data.
|
||||
* That means we can set the given caps unmodified on the next
|
||||
* element, and use that negotiation return value as ours. */
|
||||
ret = gst_pad_try_set_caps (otherpad, gst_caps_copy (caps));
|
||||
if (GST_PAD_LINK_FAILED (ret))
|
||||
return ret;
|
||||
|
||||
/* Capsnego succeeded, get the stream properties for internal
|
||||
* usage and return success. */
|
||||
gst_structure_get_int (structure, "rate", &filter->samplerate);
|
||||
gst_structure_get_int (structure, "channels", &filter->channels);
|
||||
|
||||
g_print ("Caps negotiation succeeded with %d Hz @ %d channels\n",
|
||||
filter->samplerate, filter->channels);
|
||||
|
||||
return ret;
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
If your <function>_link ()</function> function does not need to perform
|
||||
any specific operation (i.e. it will only forward caps), you can set it
|
||||
to <function>gst_pad_proxy_link</function>. This is a link forwarding
|
||||
function implementation provided by the core. It is useful for elements
|
||||
such as <classname>identity</classname>.
|
||||
</para>
|
||||
<para>
|
||||
The <function>_getcaps ()</function> funtion is used to request the list
|
||||
of supported formats and properties from the element. In some cases, this
|
||||
will be equal to the formats provided by the pad template, in which case
|
||||
this function can be omitted. In some cases, too, it will not depend on
|
||||
anything inside this element, but it will rather depend on the input from
|
||||
another element linked to this element's sink or source pads. In that case,
|
||||
you can use <function>gst_pad_proxy_getcaps</function> as implementation,
|
||||
it provides getcaps forwarding in the core. However, in many cases, the
|
||||
format supported by this element cannot be defined externally, but is
|
||||
more specific than those provided by the pad template. In this case, you
|
||||
should use a <function>_getcaps ()</function> function. In the case as
|
||||
specified below, we assume that our filter is able to resample sound, so
|
||||
it would be able to provide any samplerate (indifferent from the samplerate
|
||||
specified on the other pad) on both pads. It explains how a
|
||||
<function>_getcaps ()</function> can be used to do this.
|
||||
</para>
|
||||
<programlisting>
|
||||
static GstCaps *
|
||||
gst_my_filter_getcaps (GstPad *pad)
|
||||
{
|
||||
GstMyFilter *filter = GST_MY_FILTER (gst_pad_get_parent (pad));
|
||||
GstPad *otherpad = (pad == filter->srcpad) ? filter->sinkpad :
|
||||
filter->srcpad;
|
||||
GstCaps *othercaps = gst_pad_get_allowed_caps (otherpad), *caps;
|
||||
gint n;
|
||||
|
||||
if (gst_caps_is_empty (othercaps))
|
||||
return othercaps;
|
||||
|
||||
/* We support *any* samplerate, indifferent from the samplerate
|
||||
* supported by the linked elements on both sides. */
|
||||
for (i = 0; i < gst_caps_get_size (othercaps); i++) {
|
||||
GstStructure *structure = gst_caps_get_structure (othercaps, i);
|
||||
|
||||
gst_structure_remove_field (structure, "rate");
|
||||
}
|
||||
caps = gst_caps_intersect (othercaps, gst_pad_get_pad_template_caps (pad));
|
||||
gst_caps_free (othercaps);
|
||||
|
||||
return caps;
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
Obviously, many elements will not need this complex mechanism, because they
|
||||
are much simpler than that. They only support one format, or their format
|
||||
is fixed but the contents of the format depend on the stream or something
|
||||
else. In those cases, <emphasis>explicit caps</emphasis> are an easy way
|
||||
of handling caps. Explicit caps are an easy way of specifying one, fixed,
|
||||
supported format on a pad. Pads using explicit caps do not implement their
|
||||
own <function>_getcaps ()</function> or <function>_link ()</function>
|
||||
functions. When the exact format is known, an elements uses
|
||||
<function>gst_pad_set_explicit_caps ()</function> to specify the exact
|
||||
format. This is very useful for demuxers, for example.
|
||||
</para>
|
||||
<programlisting>
|
||||
static void
|
||||
gst_my_filter_init (GstMyFilter *filter)
|
||||
{
|
||||
GstElementClass *klass = GST_ELEMENT_GET_CLASS (filter);
|
||||
[..]
|
||||
filter->srcpad = gst_pad_new_from_template (
|
||||
gst_element_class_get_pad_template (klass, "src"), "src");
|
||||
gst_pad_use_explicit_caps (filter->srcpad);
|
||||
[..]
|
||||
}
|
||||
|
||||
static void
|
||||
gst_my_filter_somefunction (GstMyFilter *filter)
|
||||
{
|
||||
GstCaps *caps = ..;
|
||||
[..]
|
||||
gst_pad_set_explicit_caps (filter->srcpad, caps);
|
||||
[..]
|
||||
}
|
||||
</programlisting>
|
||||
</chapter>
|
||||
|
||||
|
|
|
@ -3,7 +3,143 @@
|
|||
<chapter id="cha-building-args" xreflabel="Adding Arguments">
|
||||
<title>Adding Arguments</title>
|
||||
<para>
|
||||
Define arguments in enum.
|
||||
The primary and most important way of controlling how an element behaves,
|
||||
is through GObject properties. GObject properties are defined in the
|
||||
<function>_class_init ()</function> function. The element optionally
|
||||
implements a <function>_get_property ()</function> and a
|
||||
<function>_set_property ()</function> function. These functions will be
|
||||
notified if an application changes or requests the value of a property,
|
||||
and can then fill in the value or take action required for that property
|
||||
to change value internally.
|
||||
</para>
|
||||
</chapter>
|
||||
<programlisting>
|
||||
/* properties */
|
||||
enum {
|
||||
ARG_0,
|
||||
ARG_SILENT
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
static void gst_my_filter_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gst_my_filter_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void
|
||||
gst_my_filter_class_init (GstMyFilterClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
/* define properties */
|
||||
g_object_class_install_property (object_class, ARG_SILENT,
|
||||
g_param_spec_boolean ("silent", "Silent",
|
||||
"Whether to be very verbose or not",
|
||||
FALSE, G_PARAM_READWRITE));
|
||||
|
||||
/* define virtual function pointers */
|
||||
object_class->set_property = gst_my_filter_set_property;
|
||||
object_class->get_property = gst_my_filter_get_property;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_my_filter_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GstMyFilter *filter = GST_MY_FILTER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SILENT:
|
||||
filter->silent = g_value_get_boolean (value);
|
||||
g_print ("Silent argument was changed to %s\n",
|
||||
filter->silent ? "true" : "false");
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gst_my_filter_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GstMyFilter *filter = GST_MY_FILTER (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case ARG_SILENT:
|
||||
g_value_set_boolean (value, filter->silent);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
The above is a very simple example of how arguments are used. Graphical
|
||||
applications - for example GStreamer Editor - will use these properties
|
||||
and will display a user-controlleable widget with which these properties
|
||||
can be changed. This means that - for the property to be as user-friendly
|
||||
as possible - you should be as exact as possible in the definition of the
|
||||
property. Not only in defining ranges in between which valid properties
|
||||
can be located (for integers, floats, etc.), but also in using very
|
||||
descriptive (better yet: internationalized) strings in the definition of
|
||||
the property, and if possible using enums and flags instead of integers.
|
||||
The GObject documentation describes these in a very complete way, but
|
||||
below, we'll give a short example of where this is useful. Note that using
|
||||
integers here would probably completely confuse the user, because they
|
||||
make no sense in this context. The example is stolen from videotestsrc.
|
||||
</para>
|
||||
<programlisting>
|
||||
typedef enum {
|
||||
GST_VIDEOTESTSRC_SMPTE,
|
||||
GST_VIDEOTESTSRC_SNOW,
|
||||
GST_VIDEOTESTSRC_BLACK
|
||||
} GstVideotestsrcPattern;
|
||||
|
||||
[..]
|
||||
|
||||
#define GST_TYPE_VIDEOTESTSRC_PATTERN (gst_videotestsrc_pattern_get_type ())
|
||||
static GType
|
||||
gst_videotestsrc_pattern_get_type (void)
|
||||
{
|
||||
static GType videotestsrc_pattern_type = 0;
|
||||
|
||||
if (!videotestsrc_pattern_type) {
|
||||
static GEnumValue pattern_types[] = {
|
||||
{ GST_VIDEOTESTSRC_SMPTE, "smpte", "SMPTE 100% color bars" },
|
||||
{ GST_VIDEOTESTSRC_SNOW, "snow", "Random (television snow)" },
|
||||
{ GST_VIDEOTESTSRC_BLACK, "black", "0% Black" },
|
||||
{ 0, NULL, NULL },
|
||||
};
|
||||
|
||||
videotestsrc_pattern_type =
|
||||
g_enum_register_static ("GstVideotestsrcPattern",
|
||||
pattern_types);
|
||||
}
|
||||
|
||||
return videotestsrc_pattern_type;
|
||||
}
|
||||
|
||||
[..]
|
||||
|
||||
static void
|
||||
gst_videotestsrc_class_init (GstvideotestsrcClass *klass)
|
||||
{
|
||||
[..]
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TYPE,
|
||||
g_param_spec_enum ("pattern", "Pattern",
|
||||
"Type of test pattern to generate",
|
||||
GST_TYPE_VIDEOTESTSRC_PATTERN, 1, G_PARAM_READWRITE));
|
||||
[..]
|
||||
}
|
||||
</programlisting>
|
||||
</chapter>
|
||||
|
|
|
@ -1,25 +1,121 @@
|
|||
<chapter id="cha-testapp-init">
|
||||
<title>Initialization</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
<!-- ############ chapter ############# -->
|
||||
|
||||
<chapter id="cha-testapp-inst">
|
||||
<title>Instantiating the plugins</title>
|
||||
<chapter id="cha-building-testapp">
|
||||
<title>Building a Test Application</title>
|
||||
<para>
|
||||
(NOTE: we really should have a debugging Sink)
|
||||
Often, you will want to test your newly written plugin in an as small
|
||||
setting as possible. Ususally, <filename>gst-launch</filename> is a
|
||||
good first step at testing a plugin. However, you will often need more
|
||||
testing features than gst-launch can provide, such as seeking, events,
|
||||
interactivity and more. Writing your own small testing program is the
|
||||
easiest way to accomplish this. This section explains - in a few words
|
||||
- how to do that. For a complete application development guide, see the
|
||||
<ulink type="http" url="../manual/index.html">Application Development
|
||||
Manual</ulink>.
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
<chapter id="cha-testapp-link">
|
||||
<title>Linking the plugins</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
<sect1 id="cha-testapp-init" xreflabel="Initialization">
|
||||
<title>Initialization</title>
|
||||
<para>
|
||||
At the start, you need to initialize the &GStreamer; core library by
|
||||
calling <function>gst_init ()</function>. You can alternatively call
|
||||
<function>gst_init_with_popt_tables ()</function>, which will return
|
||||
a pointer to popt tables. You can then use libpopt to handle the
|
||||
given argument table, and this will finish the &GStreamer; intialization.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<chapter id="cha-testapp-running">
|
||||
<title>Running the pipeline</title>
|
||||
<para>
|
||||
</para>
|
||||
</chapter>
|
||||
<sect1 id="cha-testapp-inst" xreflabel="Instantiating the plugins">
|
||||
<title>Instantiating the plugins</title>
|
||||
<para>
|
||||
You can create elements using <function>gst_element_factory_make ()</function>,
|
||||
where the first argument is the element type that you want to create,
|
||||
and the second argument is a free-form name. The example at the end uses
|
||||
a simple filesource - decoder - soundcard output pipeline, but you can
|
||||
use specific debugging elements if that's necessary. For example, an
|
||||
<classname>identity</classname> element can be used in the middle of
|
||||
the pipeline to act as a data-to-application transmitter. This can be
|
||||
used to check the data for misbehaviours or correctness in your test
|
||||
application. Also, you can use a <classname>fakesink</classname>
|
||||
element at the end of the pipeline to dump your data to the stdout
|
||||
(in order to do this, set the <function>dump</function> property to
|
||||
TRUE). Lastly, you can use the <classname>efence</classname> element
|
||||
(indeed, an eletric fence memory debugger wrapper element) to check
|
||||
for memory errors.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="cha-testapp-link" xreflabel="Linking the plugins">
|
||||
<title>Linking the plugins</title>
|
||||
<para>
|
||||
During linking, your test application can use fixation or filtered caps
|
||||
as a way to drive a specific type of data to or from your element. This
|
||||
is a very simple and effective way of checking multiple types of input
|
||||
and output in your element.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="cha-testapp-running" xreflabel="Running the pipeline">
|
||||
<title>Running the pipeline</title>
|
||||
<para>
|
||||
Running the pipeline happens through the <function>gst_bin_iterate ()</function>
|
||||
function. Note that during running, you should connect to at least the
|
||||
<quote>error</quote> and <quote>eos</quote> signals on the pipeline
|
||||
and/or your plugin/element to check for correct handling of this. Also,
|
||||
you should add events into the pipeline and make sure your plugin handles
|
||||
these correctly (with respect to clocking, internal caching, etc.).
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="cha-testapp-cleanup" xreflabel="Cleaning up the memory">
|
||||
<title>Cleaning up the memory</title>
|
||||
<para>
|
||||
Never forget to clean up memory in your plugin or your test application.
|
||||
When going to the NULL state, your element should clean up allocated
|
||||
memory and caches. Also, it should close down any references held to
|
||||
possible support libraries. Your application should <function>unref ()</function>
|
||||
the pipeline and make sure it doesn't crash.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="cha-testapp-all" xreflabel="Summary">
|
||||
<title>Summary</title>
|
||||
<programlisting>
|
||||
#include <gst/gst.h>
|
||||
|
||||
gint
|
||||
main (gint arcg,
|
||||
gchar *argv[])
|
||||
{
|
||||
GstElement *pipeline, *filesrc, *decoder, *filter, *sink;
|
||||
|
||||
/* initialization */
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
/* create elements */
|
||||
pipeline = gst_pipeline_new ("my_pipeline");
|
||||
|
||||
filesrc = gst_element_factory_make ("filesrc", "my_filesource");
|
||||
decoder = gst_element_factory_make ("mad", "my_decoder");
|
||||
filter = gst_element_factory_make ("my_filter", "my_filter");
|
||||
sink = gst_element_factory_make ("osssink", "audiosink");
|
||||
|
||||
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
|
||||
|
||||
/* link everything together */
|
||||
gst_element_link_many (filesrc, decoder, filter, sink, NULL);
|
||||
gst_bin_add_many (GST_BIN (pipeline), filesrc, decoder, filter, sink, NULL);
|
||||
|
||||
/* run */
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
while (gst_bin_iterate (GST_BIN (pipeline)));
|
||||
|
||||
/* clean up */
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
gst_object_unref (GST_OBJECT (pipeline));
|
||||
|
||||
return 0;
|
||||
}
|
||||
</programlisting>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
|
Loading…
Reference in a new issue