mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 02:30:35 +00:00
146 lines
5.4 KiB
XML
146 lines
5.4 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 an <function>_event
|
|
()</function>-function to configure for a particular format 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>_class_init ()</function> function. After creating the pad,
|
|
you have to set a <function>_chain ()</function> function pointer that will
|
|
receive and process the input data on the sinkpad.
|
|
You can optionally also set an <function>_event ()</function> function
|
|
pointer and a <function>_query ()</function> 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:
|
|
</para>
|
|
<programlisting><!-- example-begin init.func a --><!--
|
|
#include "filter.h"
|
|
#include <string.h>
|
|
|
|
static GstStateChangeReturn
|
|
gst_my_filter_change_state (GstElement * element, GstStateChange transition);
|
|
|
|
G_DEFINE_TYPE (GstMyFilter, gst_my_filter, GST_TYPE_ELEMENT);
|
|
|
|
static void
|
|
gst_my_filter_class_init (gpointer klass)
|
|
{
|
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
|
static GstStaticPadTemplate sink_template =
|
|
GST_STATIC_PAD_TEMPLATE (
|
|
"sink",
|
|
GST_PAD_SINK,
|
|
GST_PAD_ALWAYS,
|
|
GST_STATIC_CAPS ("ANY")
|
|
);
|
|
static GstStaticPadTemplate src_template =
|
|
GST_STATIC_PAD_TEMPLATE (
|
|
"src",
|
|
GST_PAD_SRC,
|
|
GST_PAD_ALWAYS,
|
|
GST_STATIC_CAPS ("ANY")
|
|
);
|
|
|
|
gst_element_class_set_static_metadata (element_class,
|
|
"An example plugin",
|
|
"Example/FirstExample",
|
|
"Shows the basic structure of a plugin",
|
|
"your name <your.name@your.isp>");
|
|
|
|
gst_element_class_add_pad_template (element_class,
|
|
gst_static_pad_template_get (&src_template));
|
|
gst_element_class_add_pad_template (element_class,
|
|
gst_static_pad_template_get (&sink_template));
|
|
}
|
|
|
|
static void
|
|
gst_my_filter_class_init (GstMyFilterClass * klass)
|
|
{
|
|
GST_ELEMENT_CLASS (klass)->change_state = gst_my_filter_change_state;
|
|
}
|
|
--><!-- example-end init.func a -->
|
|
<!-- example-begin init.func c --><!--
|
|
static GstFlowReturn gst_my_filter_chain (GstPad *pad,
|
|
GstObject *parent,
|
|
GstBuffer *buf);
|
|
static gboolean gst_my_filter_sink_event (GstPad *pad,
|
|
GstObject *parent,
|
|
GstEvent *event);
|
|
static gboolean gst_my_filter_src_query (GstPad *pad,
|
|
GstObject *parent,
|
|
GstQuery *query);
|
|
static gboolean gst_my_filter_sink_query (GstPad *pad,
|
|
GstObject *parent,
|
|
GstQuery *query);
|
|
--><!-- example-end init.func c -->
|
|
<!-- example-begin init.func d -->
|
|
|
|
static void
|
|
gst_my_filter_init (GstMyFilter *filter)
|
|
{
|
|
/* pad through which data comes in to the element */
|
|
filter->sinkpad = gst_pad_new_from_static_template (
|
|
&sink_template, "sink");
|
|
/* pads are configured here with gst_pad_set_*_function () */
|
|
<!-- example-end init.func d -->
|
|
<!-- example-begin init.func e --><!--
|
|
gst_pad_set_chain_function (filter->sinkpad, gst_my_filter_chain);
|
|
gst_pad_set_event_function (filter->sinkpad, gst_my_filter_sink_event);
|
|
gst_pad_set_query_function (filter->sinkpad, gst_my_filter_sink_query);
|
|
--><!-- example-end init.func e -->
|
|
<!-- example-begin init.func f -->
|
|
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
|
|
|
|
/* pad through which data goes out of the element */
|
|
filter->srcpad = gst_pad_new_from_static_template (
|
|
&src_template, "src");
|
|
/* pads are configured here with gst_pad_set_*_function () */
|
|
<!-- example-end init.func f -->
|
|
<!-- example-begin init.func g --><!--
|
|
gst_pad_set_query_function (filter->srcpad, gst_my_filter_src_query);
|
|
--><!-- example-end init.func g -->
|
|
<!-- example-begin init.func h -->
|
|
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
|
|
|
|
/* properties initial value */
|
|
filter->silent = FALSE;
|
|
}
|
|
<!-- example-end init.func h --></programlisting>
|
|
|
|
<!-- example-begin pads.c --><!--
|
|
#include "init.func"
|
|
|
|
static gboolean
|
|
gst_my_filter_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
|
{
|
|
return gst_pad_event_default (pad, parent, event);
|
|
}
|
|
|
|
static GstFlowReturn
|
|
gst_my_filter_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
|
|
{
|
|
return gst_pad_push (GST_MY_FILTER (parent)->srcpad, buf);
|
|
}
|
|
|
|
static GstStateChangeReturn
|
|
gst_my_filter_change_state (GstElement * element, GstStateChange transition)
|
|
{
|
|
return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS,
|
|
change_state, (element, transition), GST_STATE_CHANGE_SUCCESS);
|
|
}
|
|
|
|
#include "register.func"
|
|
--><!-- example-end pads.c -->
|
|
</chapter>
|
|
|