2 This short document gives some guidelines to plugin writers.
8 - the plugin has a chain function on each sink pad (can be the same function)
11 ! chain (GstPad *pad, GstBuffer *buffer)
13 ! MyElement *elem = MY_ELEMENT (gst_pad_get_parent (pad));
14 ! GstBuffer *new_buffer;
17 ! (process the buffer)
20 ! /* you can push as many buffers (0 or more) as you want */
25 ! gst_pad_push (elem->some_sink_pad, new_buffer);
27 ! /* if you're like going to send a large amount of buffers
28 ! * it's a good idea to call _yield from time to time after
29 ! * the buffer has been pushed */
30 ! (optional gst_element_yield (GST_ELEMENT (elem)); )
35 - chain based functions are usually easy and recommended.
36 - use gst_element_yield if you are going to push a lot of buffers.
43 - one loop function for the element.
44 - required for bytestream based plugins.
49 - one pull at the start
51 - if you do something like this, you really should consider using a
52 chain function as it can be significantly optimised by the scheduler.
55 ! loop (GstElement *element)
57 ! MyElement *elem = MY_ELEMENT (element);
59 ! GstBuffer *new_buffer;
61 ! buffer = gst_pad_pull (elem->sinkpad);
67 ! /* you can push as many buffers (0 or more) as you want */
72 ! gst_pad_push (elem->some_sink_pad, new_buffer);
74 ! /* if you're like going to send a large amount of buffers
75 ! * it's a good idea to call _yield from time to time after
76 ! * the buffer has been pushed */
77 ! (optional gst_element_yield (GST_ELEMENT (elem)); )
101 * you can fix this by either:
103 - setting the GST_ELEMENT_INFINITE_LOOP flag on the element. this is
104 not recommended, if all plugins in the pipeline (or depending on the
105 pipeline, some plugins) have this flag, the pipeline will not run.
106 - calling break; from time to time to get out of the loop. (duh, then
107 it's not an infinite loop anymore). beware that the next time the loop
108 function is called, it will be started from the top.
109 - calling gst_element_yield() from time to time (see NOTES).
110 - this is fine (albeit rather useless, use a chain function):
123 - so is this (albeit rather useless, consider removing the while and the _yield):
135 ! gst_element_yield (element);
143 - allocate data, loop, free data
169 - the free will NEVER happen!.
171 * You can fix this by:
173 - allocating/freeing data in the state change function
174 - you could think the following code would work too:
176 ! (*WRONG* example follows)
201 but it'll only free the data if the pipeline was shut down with
202 and EOS so don't try it. Besides, on EOS, a state change will happen
203 anyway so free the data there.
206 bytestream/multiple pull case
207 -----------------------------
209 - same as the simple case, but you can't use a chain based function unless
210 you want to make things a little harder then they should be.
216 - push and pull are completely mixed.
217 - the flow is usually something like this:
225 ! while (something) {
231 ! while (something_else) {
240 ! while (something_useful) {
248 (example made complicated on purpose, but vorbisdec comes close)
250 - you cannot call break to avoid infinite loops and there are loops that
251 take a significant amount of time to execute, possibly pushing/pulling
254 * You can fix this by:
256 - inserting gst_element_yield () in sane places, don't exagerate because
257 every yield can potentially never return so you need to keep track of
258 allocations (see the NOTES below).
265 - a call to _yield() can never return. if you have data allocated on the
266 stack before the yield, keep a pointer to it in the element struct
267 and free it in the state change function.
270 IMPLEMENATION DETAILS
271 =====================
273 The infinite loops are only problematic if the scheduler chooses to select
274 the plugin as an entry point in the chain. _yield() will be a nop if this is
275 not the case. The scheduler will not select plugins with the INFINITE_LOOP
276 flag set as entries in a chain.
278 A _yield in an entry will hand over control to the main thread context, allowing
279 state changes and other actions to be performed. It will basically exit the
280 _iterate() function. spending a long time in a loop will degrade app responsiveness
281 because _iterate will take a long time.
283 Calling yield, pulling, pushing can potentially never return because a state change
284 might have happened, killing off execution of the plugin. pulling/pushing buffers
285 will cause no leaks in this case because the core will free pending buffers in a
286 state change to READY. The plugin must free allocated data/buffers itself in the state
287 change function if the yield didn't retrun.