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