Specifying the pads
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 a _setcaps
()-functions to configure for a particular format and how to
register functions to let data flow through the element.
In the element _init () function, you create the pad
from the pad template that has been registered with the element class in
the _base_init () function. After creating the pad,
you have to set a _setcaps () function pointer and
optionally a _getcaps () function pointer. Also, you
have to set a _chain () function pointer.
Alternatively, pads can also operate in looping mode, which means that they
can pull data themselves. More on this topic later. After that, you have
to register the pad with the element. This happens like this:
static gboolean gst_my_filter_setcaps (GstPad *pad,
GstCaps *caps);
static GstFlowReturn gst_my_filter_chain (GstPad *pad,
GstBuffer *buf);
static void
gst_my_filter_init (GstMyFilter *filter, GstMyFilterClass *filter_klass)
{
GstElementClass *klass = GST_ELEMENT_CLASS (filter_klass);
/* 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_setcaps_function (filter->sinkpad, gst_my_filter_setcaps);
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_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
/* properties initial value */
filter->silent = FALSE;
}
The setcaps-function
The _setcaps ()-function is called during caps
negotiation, which is discussed in great detail in . 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 . A _link ()
receives a pointer to a GstCaps
struct that defines the proposed streamtype, and can respond with
either yes
(TRUE) or no
(FALSE). If the element responds positively towards
the streamtype, that type will be used on the pad. An example:
static gboolean
gst_my_filter_setcaps (GstPad *pad,
GstCaps *caps)
{
GstStructure *structure = gst_caps_get_structure (caps, 0);
GstMyFilter *filter = GST_MY_FILTER (GST_OBJECT_PARENT (pad));
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") != 0) {
GST_WARNING ("Wrong mimetype %s provided, we only support %s",
mime, "audio/x-raw");
return FALSE;
}
/* 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. */
if (!gst_pad_set_caps (filter->srcpad, caps))
return FALSE;
/* 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 TRUE;
}
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 GstStructure
internally. A GstCaps
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
gst_structure_get_int ().
If your _link () function does not need to perform
any specific operation (i.e. it will only forward caps), you can set it
to gst_pad_proxy_link (). This is a link forwarding
function implementation provided by the core. It is useful for elements
such as identity.