mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
25b9d5e292
Original commit message from CVS: fixed a few typos, relabeled introductionary list of types more notes abut dparam changes many comments and notes on dparam implementation new dparams are were not initialized to the default value from param specs
222 lines
9.6 KiB
XML
222 lines
9.6 KiB
XML
|
|
<!-- ############ chapter ############# -->
|
|
|
|
<chapter id="chapter-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>
|
|
|
|
<sect1 id="section-pads-linkfn" xreflabel="The link function">
|
|
<title>The link function</title>
|
|
<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="chapter-building-types"/>. A <function>_link ()</function>
|
|
receives a pointer to a <ulink type="http"
|
|
url="../../gstreamer/html/gstreamer-GstCaps.html"><classname>GstCaps</classname>
|
|
</ulink> struct that defines the proposed streamtype, and can respond with
|
|
either <quote>yes</quote> (<symbol>GST_PAD_LINK_OK</symbol>),
|
|
<quote>no</quote> (<symbol>GST_PAD_LINK_REFUSED</symbol>) or
|
|
<quote>don't know yet</quote> (<symbol>GST_PAD_LINK_DELAYED</symbol>).
|
|
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>
|
|
In here, we check the mimetype of the provided caps. Normally, you don't
|
|
need to do that in your own plugin/element, because the core does that
|
|
for you. We simply use it to show how to retrieve the mimetype from a
|
|
provided set of caps. Types are stored in <ulink type="http"
|
|
url="../../gstreamer/html/gstreamer-GstStructure.html"><classname>GstStructure
|
|
</classname></ulink> internally. A <ulink
|
|
type="http" url="../../gstreamer/html/gstreamer-GstCaps.html"><classname>GstCaps
|
|
</classname></ulink> is nothing more than a small
|
|
wrapper for 0 or more structures/types. From the structure, you can also
|
|
retrieve properties, as is shown above with the function
|
|
<function>gst_structure_get_int ()</function>.
|
|
</para>
|
|
<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>
|
|
</sect1>
|
|
|
|
<sect1 id="section-pads-getcapsfn" xreflabel="The getcaps function">
|
|
<title>The getcaps function</title>
|
|
<para>
|
|
The <function>_getcaps ()</function> function 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>
|
|
</sect1>
|
|
|
|
<sect1 id="section-pads-explicitcaps" xreflabel="Explicit caps">
|
|
<title>Explicit caps</title>
|
|
<para>
|
|
Obviously, many elements will not need the complex mechanism described in
|
|
the previous sections, because they are much simpler than that.
|
|
Such elements 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>
|
|
</sect1>
|
|
</chapter>
|
|
|