2 <!-- ############ chapter ############# -->
4 <chapter id="chapter-building-chainfn">
5 <title>The chain function</title>
7 The chain function is the function in which all data processing takes
8 place. In the case of a simple filter, <function>_chain ()</function>
9 functions are mostly linear functions - so for each incoming buffer,
10 one buffer will go out, too. Below is a very simple implementation of
13 <programlisting><!-- example-begin chain.c a --><!--
17 gst_my_filter_event (GstPad * pad, GstEvent * event)
19 return gst_pad_event_default (pad, event);
21 --><!-- example-end chain.c a -->
22 <!-- example-begin chain.c b -->
24 gst_my_filter_chain (GstPad *pad,
27 GstMyFilter *filter = GST_MY_FILTER (GST_OBJECT_PARENT (pad));
30 g_print ("Have data of size %u bytes!\n", GST_BUFFER_SIZE (buf));
32 return gst_pad_push (filter->srcpad, buf);
34 <!-- example-end chain.c b -->
35 <!-- example-begin chain.c c --><!--
36 static GstStateChangeReturn
37 gst_my_filter_change_state (GstElement * element, GstStateChange transition)
39 return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS,
40 change_state, (element, transition), GST_STATE_CHANGE_SUCCESS);
42 #include "register.func"
43 --><!-- example-end chain.c c --></programlisting>
45 Obviously, the above doesn't do much useful. Instead of printing that the
46 data is in, you would normally process the data there. Remember, however,
47 that buffers are not always writeable. In more advanced elements (the ones
48 that do event processing), you may want to additionally specify an event
49 handling function, which will be called when stream-events are sent (such
50 as end-of-stream, discontinuities, tags, etc.).
54 gst_my_filter_init (GstMyFilter * filter)
57 gst_pad_set_event_function (filter->sinkpad,
61 <!-- example-begin chain2.c a --><!--
65 --><!-- example-end chain2.c a -->
66 <!-- example-begin chain.func a --><!--
68 gst_my_filter_stop_processing (GstMyFilter * filter)
73 gst_my_filter_process_data (GstMyFilter * filter, const GstBuffer * buf)
77 --><!-- example-end chain.func a -->
78 <!-- example-begin chain.func b -->
80 gst_my_filter_event (GstPad *pad,
83 GstMyFilter *filter = GST_MY_FILTER (GST_OBJECT_PARENT (pad));
85 switch (GST_EVENT_TYPE (event)) {
87 /* end-of-stream, we should close down all stream leftovers here */
88 gst_my_filter_stop_processing (filter);
94 return gst_pad_event_default (pad, event);
98 gst_my_filter_chain (GstPad *pad,
101 GstMyFilter *filter = GST_MY_FILTER (gst_pad_get_parent (pad));
104 outbuf = gst_my_filter_process_data (filter, buf);
105 gst_buffer_unref (buf);
107 /* something went wrong - signal an error */
108 GST_ELEMENT_ERROR (GST_ELEMENT (filter), STREAM, FAILED, (NULL), (NULL));
109 return GST_FLOW_ERROR;
112 return gst_pad_push (filter->srcpad, outbuf);
114 <!-- example-end chain.func b -->
115 <!-- example-begin chain2.c b --><!--
116 static GstStateChangeReturn
117 gst_my_filter_change_state (GstElement * element, GstStateChange transition)
119 return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS,
120 change_state, (element, transition), GST_STATE_CHANGE_SUCCESS);
122 #include "register.func"
123 --><!-- example-end chain2.c b --></programlisting>
125 In some cases, it might be useful for an element to have control over the
126 input data rate, too. In that case, you probably want to write a so-called
127 <emphasis>loop-based</emphasis> element. Source elements (with only source
128 pads) can also be <emphasis>get-based</emphasis> elements. These concepts
129 will be explained in the advanced section of this guide, and in the section
130 that specifically discusses source pads.