Git init
[framework/multimedia/gstreamer0.10.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, GstEvent * event)
18 {
19   return gst_pad_event_default (pad, event);
20 }
21 --><!-- example-end chain.c a -->
22 <!-- example-begin chain.c b -->
23 static GstFlowReturn
24 gst_my_filter_chain (GstPad    *pad,
25                      GstBuffer *buf)
26 {
27   GstMyFilter *filter = GST_MY_FILTER (GST_OBJECT_PARENT (pad));
28
29   if (!filter->silent)
30     g_print ("Have data of size %u bytes!\n", GST_BUFFER_SIZE (buf));
31
32   return gst_pad_push (filter->srcpad, buf);
33 }
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)
38 {
39   return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS,
40       change_state, (element, transition), GST_STATE_CHANGE_SUCCESS);
41 }
42 #include "register.func"
43   --><!-- example-end chain.c c --></programlisting>
44   <para>
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.).
51   </para>
52   <programlisting>
53 static void
54 gst_my_filter_init (GstMyFilter * filter)
55 {
56 [..]
57   gst_pad_set_event_function (filter-&gt;sinkpad,
58       gst_my_filter_event);
59 [..]
60 }
61 <!-- example-begin chain2.c a --><!--
62 #include "init.func"
63 #include "caps.func"
64 #include "chain.func"
65 --><!-- example-end chain2.c a -->
66 <!-- example-begin chain.func a --><!--
67 static void
68 gst_my_filter_stop_processing (GstMyFilter * filter)
69 {
70 }
71
72 static GstBuffer *
73 gst_my_filter_process_data (GstMyFilter * filter, const GstBuffer * buf)
74 {
75   return NULL;
76 }
77 --><!-- example-end chain.func a -->
78 <!-- example-begin chain.func b -->
79 static gboolean
80 gst_my_filter_event (GstPad   *pad,
81                      GstEvent *event)
82 {
83   GstMyFilter *filter = GST_MY_FILTER (GST_OBJECT_PARENT (pad));
84
85   switch (GST_EVENT_TYPE (event)) {
86     case GST_EVENT_EOS:
87       /* end-of-stream, we should close down all stream leftovers here */
88       gst_my_filter_stop_processing (filter);
89       break;
90     default:
91       break;
92   }
93
94   return gst_pad_event_default (pad, event);
95 }
96
97 static GstFlowReturn
98 gst_my_filter_chain (GstPad    *pad,
99                      GstBuffer *buf)
100 {
101   GstMyFilter *filter = GST_MY_FILTER (gst_pad_get_parent (pad));
102   GstBuffer *outbuf;
103
104   outbuf = gst_my_filter_process_data (filter, buf);
105   gst_buffer_unref (buf);
106   if (!outbuf) {
107     /* something went wrong - signal an error */
108     GST_ELEMENT_ERROR (GST_ELEMENT (filter), STREAM, FAILED, (NULL), (NULL));
109     return GST_FLOW_ERROR;
110   }
111
112   return gst_pad_push (filter->srcpad, outbuf);
113 }
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)
118 {
119   return GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS,
120       change_state, (element, transition), GST_STATE_CHANGE_SUCCESS);
121 }
122 #include "register.func"
123   --><!-- example-end chain2.c b --></programlisting>
124   <para>
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.
131   </para>
132 </chapter>