Remove old school plugins listing generator
[platform/upstream/gstreamer.git] / markdown / additional / design / gstghostpad.md
1 # Ghostpads
2
3 GhostPads are used to build complex compound elements out of existing
4 elements. They are used to expose internal element pads on the complex
5 element.
6
7 ## Some design requirements
8
9 - Must look like a real `GstPad` on both sides.
10 - target of Ghostpad must be changeable
11 - target can be initially NULL
12
13 - a GhostPad is implemented using a private `GstProxyPad` class:
14
15 ```
16 GstProxyPad
17 (------------------)
18 | GstPad           |
19 |------------------|
20 | GstPad *target   |
21 (------------------)
22 | GstPad *internal |
23 (------------------)
24
25 GstGhostPad
26 (------------------)   -\
27 | GstPad           |    |
28 |------------------|    |
29 | GstPad *target   |     > GstProxyPad
30 |------------------|    |
31 | GstPad *internal |    |
32 |------------------|   -/
33 | <private data>   |
34 (------------------)
35 ```
36
37 A `GstGhostPad` (X) is _always_ created together with a `GstProxyPad` (Y).
38 The internal pad pointers are set to point to eachother. The
39 `GstProxyPad` pairs have opposite directions, the `GstGhostPad` has the same
40 direction as the (future) ghosted pad (target).
41
42 ```
43 (- X --------)
44 |            |
45 | target *   |
46 |------------|
47 | internal *----+
48 (------------)  |
49   ^             V
50   |  (- Y --------)
51   |  |            |
52   |  | target *   |
53   |  |------------|
54   +----* internal |
55      (------------)
56
57 Which we will abbreviate to:
58
59 (- X --------)
60 |            |
61 | target *--------->//
62 (------------)
63      |
64     (- Y --------)
65     | target *----->//
66     (------------)
67 ```
68
69 The `GstGhostPad` (X) is also set as the parent of the `GstProxyPad` (Y).
70
71 The target is a pointer to the internal pads peer. It is an optimisation to
72 quickly get to the peer of a ghostpad without having to dereference the
73 internal->peer.
74
75 Some use case follow with a description of how the datastructure
76 is modified.
77
78 ## Creating a ghostpad with a target:
79
80 ```
81 gst_ghost_pad_new (char *name, GstPad *target)
82 ```
83
84 1) create new GstGhostPad X + GstProxyPad Y
85 2) X name set to @name
86 3) X direction is the same as the target, Y is opposite.
87 4) the target of X is set to @target
88 5) Y is linked to @target
89 6) link/unlink and activate functions are set up
90    on GstGhostPad.
91
92 ```
93                                 (--------------
94   (- X --------)                |
95   |            |                |------)
96   | target *------------------> | sink |
97   (------------)       -------> |------)
98        |              /         (--------------
99       (- Y --------) / (pad link)
100 //<-----* target   |/
101       (------------)
102 ```
103
104 - Automatically takes same direction as target.
105 - target is filled in automatically.
106
107 ## Creating a ghostpad without a target
108
109 ```
110 gst_ghost_pad_new_no_target (char *name, GstPadDirection dir)
111 ```
112
113 1) create new GstGhostPad X + GstProxyPad Y
114 2) X name set to @name
115 3) X direction is @dir
116 5) link/unlink and activate functions are set up on GstGhostPad.
117
118 ```
119 (- X --------)
120 |            |
121 | target *--------->//
122 (------------)
123      |
124     (- Y --------)
125     | target *----->//
126     (------------)
127 ```
128
129 - allows for setting the target later
130
131 ## Setting target on an untargetted unlinked ghostpad
132
133 ```
134 gst_ghost_pad_set_target (char *name, GstPad *newtarget)
135
136 (- X --------)
137 |            |
138 | target *--------->//
139 (------------)
140      |
141     (- Y --------)
142     | target *----->//
143     (------------)
144 ```
145
146 1) assert direction of newtarget == X direction
147 2) target is set to newtarget
148 3) internal pad Y is linked to newtarget
149
150 ```
151                                 (--------------
152   (- X --------)                |
153   |            |                |------)
154   | target *------------------> | sink |
155   (------------)       -------> |------)
156        |              /         (--------------
157       (- Y --------) / (pad link)
158 //<-----* target   |/
159       (------------)
160 ```
161
162 ## Setting target on a targetted unlinked ghostpad
163
164 ```
165 gst_ghost_pad_set_target (char *name, GstPad *newtarget)
166
167                                 (--------------
168   (- X --------)                |
169   |            |                |-------)
170   | target *------------------> | sink1 |
171   (------------)       -------> |-------)
172        |              /         (--------------
173       (- Y --------) / (pad link)
174 //<-----* target   |/
175       (------------)
176 ```
177
178 1) assert direction of newtarget (sink2) == X direction
179 2) unlink internal pad Y and oldtarget
180 3) target is set to newtarget (sink2)
181 4) internal pad Y is linked to newtarget
182
183 ```
184                                 (--------------
185   (- X --------)                |
186   |            |                |-------)
187   | target *------------------> | sink2 |
188   (------------)       -------> |-------)
189        |              /         (--------------
190       (- Y --------) / (pad link)
191 //<-----* target   |/
192       (------------)
193 ```
194
195 - Linking a pad to an untargetted ghostpad:
196
197 ```
198     gst_pad_link (src, X)
199
200          (- X --------)
201          |            |
202          | target *--------->//
203          (------------)
204               |
205              (- Y --------)
206              | target *----->//
207              (------------)
208 -------)
209        |
210  (-----|
211  | src |
212  (-----|
213 -------)
214 ```
215
216 X is a sink `GstGhostPad` without a target. The internal `GstProxyPad` Y has
217 the same direction as the src pad (peer).
218
219 1) link function is called
220   - Y direction is same as @src
221   - Y target is set to @src
222   - Y is activated in the same mode as X
223   - core makes link from @src to X
224
225         ```
226                           (- X --------)
227                           |            |
228                           | target *----->//
229                          >(------------)
230         (real pad link) /      |
231                        /      (- Y ------)
232                       /    -----* target |
233            -------)  /    /   (----------)
234                   | /    /
235             (-----|/    /
236             | src |<----
237             (-----|
238            -------)
239         ```
240
241 ## Linking a pad to a targetted ghostpad:
242
243 ```
244     gst_pad_link (src, X)
245
246                                        (--------
247                (- X --------)          |
248                |            |          |------)
249                | target *------------->| sink |
250                (------------)         >|------)
251                           |          / (--------
252                           |         /
253                           |        /
254 -------)                  |       / (real pad link)
255        |            (- Y ------) /
256  (-----|            |          |/
257  | src |       //<----* target |
258  (-----|            (----------)
259 -------)
260 ```
261
262 1) link function is called
263   - Y direction is same as @src
264   - Y target is set to @src
265   - Y is activated in the same mode as X
266   - core makes link from @src to X
267
268 ```
269                                           (--------
270                   (- X --------)          |
271                   |            |          |------)
272                   | target *------------->| sink |
273                  >(------------)         >|------)
274 (real pad link) /            |          / (--------
275                /             |         /
276               /              |        /
277    -------)  /               |       / (real pad link)
278           | /          (- Y ------) /
279     (-----|/           |          |/
280     | src |<-------------* target |
281     (-----|            (----------)
282    -------)
283 ```
284
285 ## Setting target on untargetted linked ghostpad:
286
287 ```
288             gst_ghost_pad_set_target (char *name, GstPad *newtarget)
289
290                   (- X --------)
291                   |            |
292                   | target *------>//
293                  >(------------)
294 (real pad link) /            |
295                /             |
296               /              |
297    -------)  /               |
298           | /          (- Y ------)
299     (-----|/           |          |
300     | src |<-------------* target |
301     (-----|            (----------)
302    -------)
303 ```
304
305 1) assert direction of @newtarget == X direction
306 2) X target is set to @newtarget
307 3) Y is linked to @newtarget
308
309 ```
310                                           (--------
311                   (- X --------)          |
312                   |            |          |------)
313                   | target *------------->| sink |
314                  >(------------)         >|------)
315 (real pad link) /            |          / (--------
316                /             |         /
317               /              |        /
318    -------)  /               |       / (real pad link)
319           | /          (- Y ------) /
320     (-----|/           |          |/
321     | src |<-------------* target |
322     (-----|            (----------)
323    -------)
324 ```
325
326 ## Setting target on targetted linked ghostpad:
327
328 ```
329     gst_ghost_pad_set_target (char *name, GstPad *newtarget)
330
331                                           (--------
332                   (- X --------)          |
333                   |            |          |-------)
334                   | target *------------->| sink1 |
335                  >(------------)         >|-------)
336 (real pad link) /            |          / (--------
337                /             |         /
338               /              |        /
339    -------)  /               |       / (real pad link)
340           | /          (- Y ------) /
341     (-----|/           |          |/
342     | src |<-------------* target |
343     (-----|            (----------)
344    -------)
345 ```
346
347 1) assert direction of @newtarget == X direction
348 2) Y and X target are unlinked
349 2) X target is set to @newtarget
350 3) Y is linked to @newtarget
351
352 ```
353                                           (--------
354                   (- X --------)          |
355                   |            |          |-------)
356                   | target *------------->| sink2 |
357                  >(------------)         >|-------)
358 (real pad link) /            |          / (--------
359                /             |         /
360               /              |        /
361    -------)  /               |       / (real pad link)
362           | /          (- Y ------) /
363     (-----|/           |          |/
364     | src |<-------------* target |
365     (-----|            (----------)
366    -------)
367 ```
368
369 ## Activation
370
371 Sometimes ghost pads should proxy activation functions. This thingie
372 attempts to explain how it should work in the different cases.
373
374 ```
375     +---+     +----+                             +----+       +----+
376     | A +-----+ B  |                             | C  |-------+ D  |
377     +---+     +---=+                             +=---+       +----+
378                 +--=-----------------------------=-+
379                 |  +=---+   +----+  +----+  +---=+ |
380                 |  | a  +---+ b  ====  c +--+ d  | |
381                 |  +----+   +----+  +----+  +----+ |
382                 |                                  |
383                 +----------------------------------+
384                 state change goes from right to left
385        <-----------------------------------------------------------
386 ```
387
388 All of the labeled boxes are pads. The dashes (---) show pad links, and
389 the double-lines (===) are internal connections. The box around a, b, c,
390 and d is a bin. B and C are ghost pads, and a and d are proxy pads. The
391 arrow represents the direction of a state change algorithm. Not counting
392 the bin, there are three elements involved here — the parent of D, the
393 parent of A, and the parent of b and c.
394
395 Now, in the state change from READY to PAUSED, assuming the pipeline
396 does not have a live source, all of the pads will end up activated at
397 the end. There are 4 possible activation modes:
398
399 1) AD and ab in PUSH, cd and CD in PUSH
400 2) AD and ab in PUSH, cd and CD in PULL
401 3) AD and ab in PULL, cd and CD in PUSH
402 4) AD and ab in PULL, cd and CD in PULL
403
404 When activating (1), the state change algorithm will first visit the
405 parent of D and activate D in push mode. Then it visits the bin. The bin
406 will first change the state of its child before activating its pads.
407 That means c will be activated in push mode. \[\*\] At this point, d and
408 C should also be active in push mode, because it could be that
409 activating c in push mode starts a thread, which starts pushing to pads
410 which aren’t ready yet. Then b is activated in push mode. Then, the bin
411 activates C in push mode, which should already be in push mode, so
412 nothing is done. It then activates B in push mode, which activates b in
413 push mode, but it’s already there, then activates a in push mode as
414 well. The order of activating a and b does not matter in this case.
415 Then, finally, the state change algorithm moves to the parent of A,
416 activates A in push mode, and dataflow begins.
417
418 \[\*\] Not yet implemented.
419
420 Activation mode (2) is implausible, so we can ignore it for now. That
421 leaves us with the rest.
422
423 (3) is the same as (1) until you get to activating b. Activating b will
424 proxy directly to activating a, which will activate B and A as well.
425 Then when the state change algorithm gets to B and A it sees that they
426 are already active, so it ignores them.
427
428 Similarly in (4), activating D will cause the activation of all of the
429 rest of the pads, in this order: C d c b a B A. Then when the state
430 change gets to the other elements they are already active, and in fact
431 data flow is already occurring.
432
433 So, from these scenarios, we can distill how ghost pad activation
434 functions should work:
435
436 Ghost source pads (e.g. C): push: called by: element state change
437 handler behavior: just return TRUE pull: called by: peer’s activatepull
438 behavior: change the internal pad, which proxies to its peer e.g. C
439 changes d which changes c.
440
441 Internal sink pads (e.g. d): push: called by: nobody (doesn’t seem
442 possible) behavior: n/a pull: called by: ghost pad behavior: proxy to
443 peer first
444
445 Internal src pads (e.g. a): push: called by: ghost pad behavior:
446 activate peer in push mode pull: called by: peer’s activatepull
447 behavior: proxy to ghost pad, which proxies to its peer (e.g. a calls B
448 which calls A)
449
450 Ghost sink pads (e.g. B): push: called by: element state change handler
451 behavior: change the internal pad, which proxies to peer (e.g. B changes
452 a which changes b) pull: called by: internal pad behavior: proxy to peer
453
454 It doesn’t really make sense to have activation functions on proxy pads
455 that aren’t part of a ghost pad arrangement.