4 A proposal for proper syncing and clocking of a pipeline.
9 - elements should be able to get the time and wait for a specific
11 - some elements should be able to control and adjust the clock.
13 - the application should be able to provide another clock.
18 A clock extends the abstract GstClock class.
20 gst_clock_get_time should always report an equal or increasing
21 value with each succesive call.
28 Clock providers call gst_element_provides_clock (element, clock)
29 in their _init function. This will set some element flags.
30 This also means that a clock provider cannot stop being a clock
33 Clock providers will update the clock at specific intervals.
34 get_resolution/set_resolution can be used to control the resolution.
36 When a clock provider is not going to update the clock anymore
37 it should make sure elements still blocked on the clock get
38 unblocked at the right time. This can be done by converting all
39 blocking waits to a select call. All further waits on the clock
40 should be estimated (using gettimeofday for example)
46 An element needing a clock must implement the element receive_clock method.
47 It has to use the clock received in this function or if the
48 clock == NULL it should not do any waiting at all.
51 Clocks and the scheduler
52 ------------------------
54 The scheduler knows about the clocks, else a clock provider and receiver
55 in the same scheduler could cause a deadlock.
57 Only one clock provider is allowed per scheduler. multiple clock
58 receivers are allowed per scheduler.
65 on every bin with a scheduler, gst_bin_use_clock (bin, clock) can be used
66 to force the use of this specific clock for all the elements in this bin.
68 gst_bin_use_clock (bin, NULL) to disable all clocking for this bin.
70 gst_bin_auto_clock (bin) to use the default algorithm to find a clock.
72 bins that get a use clock set a flag and store the clock, they also call
73 set_clock on all of their children. When other children are added, they
74 all get the stored clock.
80 clock providers and receivers are collected in the bins on element
81 add/remove, recursing bins if needed.
83 the toplevel bin with a scheduler selects the global clock and calls
84 set_clock on itself. This happens in the NULL->READY state.
86 bins dispatch the set_clock to to all of the reveivers. Bins with
87 a scheduler and another use_clock do nothing.
89 Bins with a scheduler also notify the scheduler of the clock.
95 when an element wants to wait for a specific time, if calls
96 gst_element_clock_wait (elements, clock, time). The call is dispatched
97 to the scheduler of the element which can use the owner field
98 of the clock to check if the elements are in the same scheduler.
100 For elements waiting for a clock provided by an element in another
101 scheduler there is no problem.
103 When provider and receiver are in the same scheduler, a deadlock can
104 occur since the scheduler will block on the wait without being able to
105 schedule the provider again to update the clock.
107 A solution would be to call the async notify of the clock and schedule
108 some other element (the provider?). We probably need an event based
109 scheduler for this. When the async event arrives we can reschedule
110 the receiver and continue.
112 The current scheduler will assert on this condition for now.
118 The clock can only be changed when the bin is in the PAUSED state.
124 When the pipeline is PAUSED, the clock is stopped with
125 gst_clock_enable (clock, FALSE). The clock should unblock all
126 waiting elements ASAP and return GST_CLOCK_STOP in the wait.
128 Elements waiting for a clock and receiving the STOP should
129 process the last buffer ASAP and break out of their loop.
131 When the pipeline is brought to the READY state, the clock is
134 When the clock is enabled again, it should start counting from where
135 it was last disabled.
137 NULL->READY : distribute clock, clock_reset,
138 READY->PAUSED : clock_activate (FALSE)
139 PAUSED->PLAYING : clock_activate (TRUE)
140 PLAYING->PAUSED : clock_activate (FALSE);
141 PAUSED->READY : clock_reset
142 READY->NULL : delete clock;
145 automatic Clock selection
146 -------------------------
148 Select a random clock from the Src elements.
149 if no Src elements exist with a clock, select a random clock from the
151 else use a default System Clock.
153 Src elements with a clock are prefered because they usualy provide
159 ossrc ! osssink can cause clock drift if osssink doesn't process the bytes
160 at the same rate osssrc provides them (different hardware). Things will
161 stutter and cracle if this is the case. QoS and a resampler could solve
167 -- queue ! mpeg2dec ! videosink
171 -- queue ! mad ! osssink
174 videosink is a receiver
175 osssink is a provider
177 osssink is selected as a clock provider since it is a Sink. The global
178 pipeline distributes the clock to videosink and osssink.
179 osssink sees that it receives its own clock.
181 osssink uses the OSS ioctls to determine the number of bytes processed
182 by the hardware. using the audio rate it can figure out the exact time
183 and updates its clock with a resolution that matches the resolution
184 as closely as possible.
186 videosink blocks on the clock. with each update of the clock videosink
187 is unblocked if the current time >= wait time and shows the frame.
189 when osssink is PAUSED, the clock will not be updated anymore. osssink
190 instructs its clock to convert all requests to select() calls.
191 When it is set to PLAYING again, it resumes normal operation.