]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - docs/random/omega/sched/chains
docs, gst: typo fixes
[glsdk/gstreamer0-10.git] / docs / random / omega / sched / chains
1 A new concept in scheduling is that of chains of elements that need to be schedule separately, even in the same set of
2 managed elements (which is the set of elements that the Bin in question [a pipeline or thread] is responsible for).  
3 An example would by anywhere you have a non-blocking queue in place for buffering.  This kind of element might be
4 useful in cases where the scheduling on a buffer level is tight enough that deadlocks might occur.
6 The scheduler will find chains by traversing the pipeline through the list of managed elements.  A chain boundary is 
7 anywhere you have a 'DECOUPLED' element.  A DECOUPLED element is one where there is no direct correlation between the 
8 activities of the various pads.  A source fits this description, although the normal single-pad source is the 
9 degenerate case.  A queue more properly fits the bill, since pushing a buffer at the sink pad doesn't trigger anything 
10 on the src pad, and vice versa.  A multi-src async source is probably the best example, since you want to leave the 
11 scheduling up to the elements connected to it.
13 Anyway, first the simple case:
15 fakesrc -> fakesink
17 Both of them should probably have the DECOUPLED bit set, at least to be true to the nature of the actual fake elements.  
18 These two end up being a chain, and scheduling has to be set up for the chain.  There are no cothreaded elements in the 
19 chain, which means it's relatively easy.  The goal is to find a single entry into the chain, which can be called in a 
20 loop to get things done.  Since the fakesrc is DECOUPLED, and we'd be messing with the source pad, it has lower 
21 priority than a DECOUPLED sink pad, so the fakesrc's sink pad is the ideal entry into the chain.  This can be 
22 simplified into saying that the fakesink is the entry.
24 In the end, the code to do this boils down to:
26   buf = gst_pad_pull (fakesink->sinkpad);
27   gst_pad_push (fakesink->sinkpad, buf);
29 Because of the way things are no implemented for scheduling, turning it around and making the source the entry has no
30 effect as far as the efficiency.  That's because _get no longer directly calls gst_pad_push(), so we have to do it
31 outside.  No big deal, it boils down to the same thing I think, modulo a cache-line of stack (i.e. one or two fewer
32 this way).
34 If we put an identity in the middle:
36 fakesrc -> identity -> fakesink
38 then we have the same thing, except that there's now an element that isn't DECOUPLED, so it gets higher priority.  That 
39 means the identity is now the entry, and when we push the buffer into its chain function, the fakesink gets called.
41 Now, we can make this much more complex, with the following elementary echo meta-filter:
43             |=====| -> delay1 -> |=====|
44             |     |              |     |
45 -> queue -> | tee | -> delay2 -> | mix | -> queue ->
46             |     |              |     |
47             |=====| -> delay3 -> |=====|
49 The tee takes a buffer in and spits three out, delay shifts the timestamps around and possibly reframes things to be 
50 friendly.  mix takes the three buffers and simply sums them (they're all audio).  The tee element takes one buffer in 
51 and promptly spits three out, one after another.  Delay takes an element and immediately spits out a buffer (it 
52 zero-pads at the beginning [the duration of the delay] for the sake of argument).  Mix in this case is chained, but 
53 assumes that buffer will arrive in order.  On the last chain, it does a push of the newly mixed audio buffer.
55 The queues are both DECOUPLED, so they have lower weight.  That leaves a bunch of other elements sitting there ripe for 
56 entry.  But if we were to take delay1, what would happen?  Well we can't, since there's no _get function on the tee's 
57 src pads.
59 This just re-enforces the idea that the left-most (closest to the source, for you right-to-left people) element should 
60 get to be the entry.  But what if we have multiple left-most elements?:
62 -> queue -> eq1 -> |=====|
63                    | mix | -> queue
64 -> queue -> eq2 -> |=====|
66 If eq1 is the only entry, we call pull on the queue, then chain over to mix.  Mix then doesn't do anything with it, 
67 since it's waiting for another buffer before doing anything.  That means we have to do the same with eq2, and have it 
68 chain to mix, at which point mix will do its magic and chain out to the right-hand side.  Figure out to actually use 
69 both entries is hard, because the idea at this point is that there's only a single entry to a chain.
71 Does this mean that we should make mix a DECOUPLED element?  That would fix it to some extent, giving us three chains 
72 in the above case.  Each eq chain would be driven by the eq element, pulling from the queue and pushing into the mixer.  
73 The mixer -> queue chain is problematic, because there is no possibly entry.  The mixer side has no _get function 
74 (since the push always happens upon the receipt of a buffer from the second sink pad), which means that those two
75 pads have no possible entrance.
77 Cothreads make this case much easier, since the mix element would drive things, forcing the eq elements to pull and 
78 process buffers in order as needed.  It may be that the best option in the case where there are any multi-sinkpad 
79 elements is to turn them into cothreads.
82 Now, on to cothreaded cases.  The simplest possible is to turn all the elements into cothreads.  I may punt on this and 
83 do just that for the moment, but there's still the question of what to do at the ends of the chain, where the DECOUPLED 
84 elements are.  The easiest is to simply always make then chained, so there's never any worry about who owns the 
85 cothread context for the element, simply because there never will be one.
87 fakesrc -> queue -> @identity -> fakesink
89 We just set it up so both ends of the queue are chained, and all is well.