mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
99d26b49c2
Original commit message from CVS: first commit in the branch to test
221 lines
9.5 KiB
XML
221 lines
9.5 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> 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>
|
|
</sect1>
|
|
|
|
<sect1 id="section-pads-explicitcaps" xreflabel="Explicit caps">
|
|
<title>Explicit caps</title>
|
|
<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>
|
|
</sect1>
|
|
</chapter>
|
|
|