docs: manual: fix formatting
[platform/upstream/gstreamer.git] / docs / pwg / building-chainfn.xml
1
2 <!-- ############ chapter ############# -->
3
4 <chapter id="chapter-building-chainfn">
5   <title>The chain function</title>
6   <para>
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
11     a chain function:
12   </para>
13   <programlisting><!-- example-begin chain.c a --><!--
14 #include "init.func"
15 #include "caps.func"
16 static gboolean
17 gst_my_filter_event (GstPad * pad, GstObject * parent, GstEvent * event)
18 {
19   return gst_pad_event_default (pad, parent, event);
20 }
21 --><!-- example-end chain.c a -->
22 <!-- example-begin chain.c b -->
23 static GstFlowReturn gst_my_filter_chain (GstPad    *pad,
24                                           GstObject *parent,
25                                           GstBuffer *buf);
26
27 [..]
28
29 static void
30 gst_my_filter_init (GstMyFilter * filter)
31 {
32 [..]
33   /* configure chain function on the pad before adding
34    * the pad to the element */
35   gst_pad_set_chain_function (filter-&gt;sinkpad,
36       gst_my_filter_chain);
37 [..]
38 }
39
40 static GstFlowReturn
41 gst_my_filter_chain (GstPad    *pad,
42                      GstObject *parent,
43                      GstBuffer *buf)
44 {
45   GstMyFilter *filter = GST_MY_FILTER (parent);
46
47   if (!filter->silent)
48     g_print ("Have data of size %" G_GSIZE_FORMAT" bytes!\n",
49         gst_buffer_get_size (buf));
50
51   return gst_pad_push (filter->srcpad, buf);
52 }
53 <!-- example-end chain.c b -->
54 <!-- example-begin chain.c c --><!--
55 static GstStateChangeReturn
56 gst_my_filter_change_state (GstElement * element, GstStateChange transition)
57 {
58   return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS,
59       change_state, (element, transition), GST_STATE_CHANGE_SUCCESS);
60 }
61 #include "register.func"
62   --><!-- example-end chain.c c --></programlisting>
63   <para>
64     Obviously, the above doesn't do much useful. Instead of printing that the
65     data is in, you would normally process the data there. Remember, however,
66     that buffers are not always writeable.
67   </para>
68   <para>
69     In more advanced elements (the ones that do event processing), you may want
70     to additionally specify an event handling function, which will be called
71     when stream-events are sent (such as caps, end-of-stream, newsegment, tags, etc.).
72   </para>
73   <programlisting>
74 static void
75 gst_my_filter_init (GstMyFilter * filter)
76 {
77 [..]
78   gst_pad_set_event_function (filter-&gt;sinkpad,
79       gst_my_filter_sink_event);
80 [..]
81 }
82 <!-- example-begin chain2.c a --><!--
83 #include "init.func"
84 #include "caps.func"
85 #include "chain.func"
86 --><!-- example-end chain2.c a -->
87 <!-- example-begin chain.func a --><!--
88 static void
89 gst_my_filter_stop_processing (GstMyFilter * filter)
90 {
91 }
92
93 static GstBuffer *
94 gst_my_filter_process_data (GstMyFilter * filter, const GstBuffer * buf)
95 {
96   return NULL;
97 }
98 --><!-- example-end chain.func a -->
99 <!-- example-begin chain.func b -->
100 static gboolean
101 gst_my_filter_sink_event (GstPad    *pad,
102                           GstObject *parent,
103                           GstEvent  *event)
104 {
105   GstMyFilter *filter = GST_MY_FILTER (parent);
106
107   switch (GST_EVENT_TYPE (event)) {
108     case GST_EVENT_CAPS:
109       /* we should handle the format here */
110       break;
111     case GST_EVENT_EOS:
112       /* end-of-stream, we should close down all stream leftovers here */
113       gst_my_filter_stop_processing (filter);
114       break;
115     default:
116       break;
117   }
118
119   return gst_pad_event_default (pad, parent, event);
120 }
121
122 static GstFlowReturn
123 gst_my_filter_chain (GstPad    *pad,
124                      GstObject *parent,
125                      GstBuffer *buf)
126 {
127   GstMyFilter *filter = GST_MY_FILTER (parent);
128   GstBuffer *outbuf;
129
130   outbuf = gst_my_filter_process_data (filter, buf);
131   gst_buffer_unref (buf);
132   if (!outbuf) {
133     /* something went wrong - signal an error */
134     GST_ELEMENT_ERROR (GST_ELEMENT (filter), STREAM, FAILED, (NULL), (NULL));
135     return GST_FLOW_ERROR;
136   }
137
138   return gst_pad_push (filter->srcpad, outbuf);
139 }
140 <!-- example-end chain.func b -->
141 <!-- example-begin chain2.c b --><!--
142 static GstStateChangeReturn
143 gst_my_filter_change_state (GstElement * element, GstStateChange transition)
144 {
145   return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS,
146       change_state, (element, transition), GST_STATE_CHANGE_SUCCESS);
147 }
148 #include "register.func"
149   --><!-- example-end chain2.c b --></programlisting>
150   <para>
151     In some cases, it might be useful for an element to have control over the
152     input data rate, too. In that case, you probably want to write a so-called
153     <emphasis>loop-based</emphasis> element. Source elements (with only source
154     pads) can also be <emphasis>get-based</emphasis> elements. These concepts
155     will be explained in the advanced section of this guide, and in the section
156     that specifically discusses source pads.
157   </para>
158 </chapter>