2 In this document, the word "time" is not meant to represent a representation of
3 time that is close to reality. Though that is the idea in most cases, it is not
4 the focus. Time in this document is meant to represent time inside a stream that
5 is played back by GStreamer. There might be reasons to represent time in non-
6 realtime, for example when the processor is too slow to allow for video playback
7 in realtime, the clock might not update fast enough. Or one might want to use
8 a clock that purposefully increases/reduces the speed of time.
9 Time in this document is not meant to be linear either. Whereas elements can set
10 time freely by seeking, clocks should do their best to supply linear time. It is
11 not a requirement however, there might for example be slight inconsistencies
12 when audio clocks have buffer over/underruns.
15 The job of a clock is to report the time as exactly as possible that has elapsed
16 in the stream since the stream was started.
17 A Clock does never seek, so if someone seeks the stream back to the beginning,
18 the clock will still represent the time since a start.
19 The state of the clock is managed by all elements using its time as a state of a
20 bin is changed according to its children. A clock will try to synchronize its
21 state with its provider. (FIXME: or with all its children like a bin? FIXME:
22 What to do in the case of a providerless clock like _a_ systemclock (we might
23 use multiple systemclocks)? Attach to one element that uses it and reattach if
24 element is removed? FIXME: What do we do when a provider is removed from a
25 scheduler? Sounds like a good time to get a new clock to take over. FIXME:
26 Write a test that does exactly this in Gst-Player when changing the GConf Key.)
28 Nobody cares about time reported by the clock.
30 Clock is supposed to present the time elapsed since it was started.
32 The clock has to remember the time it was stopped and resume with that time
33 when it restarts playing.
36 An element only can request time information if it uses a clock. The element can
37 query functions that give information about the elements time. Time information
38 for the element is always in relation to the timestamps the element expects on
40 Example: XVideosink will output a new frame, when xvideosinks time matches the
41 timestamps of the buffer.
42 The elements time is in no relation to the time of its clock because of seeks.
43 If an element seeks, it adjusts its time by the difference the seek has
45 Example: Playback of a song with duration 1000 that is looping. Clock and
46 element start at time offset 0, when the element is first set to
47 PLAYING. After the first loop, the elements time is (by request of that
48 element) reset to 0. The clock's time stays at 1000.
49 Note: If an element goes into the PAUSED state the elements time will continue
50 running. (FIXME: possibility to change that needed? Why would you want to
51 pause an element that should be synced while the others continue running?
52 FIXME: What happens if a clock provider and therefore the clock are
53 already at EOS while other elements are still playing? I'd vote for make
54 all other elements go as fast as possible. FIXME: Ask some video people if
55 that sounds reasonable or if we gotta force the clock to go on, which
56 would make it difficult to detect the difference between EOS and pause.
59 Providers are elements that can provide timing information and therefore provide
60 a clock to other elements. These elements have to update the clock, when it is
61 used. When a clock is used (state != NULL - FIXME: or other states?), the
62 provider is guaranteed to use this clock. (FIXME: necessary?). The element is
63 however required to synchronize to the clock it was assigned to, whether it is
67 FIXME: Is it necessary to have sync points? This would allow to supply a fixed
68 time between sync point "SOURCE" and "SINK" so one could buffer the time
69 inbetween. Or is there another solution for this problem? It's possibly easier
70 to use an element that does TIMESTAMP = TIMESTAMP - x inside the pipeline and
71 drops every buffer before.
74 FIXME: Use GstTime(Diff) instead of GstClockTime(Diff) ?
76 GstClockTime gst_clock_get_time (GstClock *clock);
77 GstElementState gst_clock_get_state (GstClock *clock); /* setting works internally */
78 GstClockReturn gst_clock_wait (GstClock *clock, GstClockTime until, GstClockTimeDiff *jitter);
80 GST_FLAG GST_ELEMENT_NEEDS_CLOCK; /* whether we want a clock or not */
81 GstClockTime gst_element_get_time (GstElement *element);
82 void gst_element_(clock_)seek (GstElement *element, GstClockTimeDiff diff);
83 GstClock * gst_element_get_clock (GstElement *element);
84 GstClockReturn gst_element_(clock_)wait (GstElement *element, GstClockTime until, GstClockTimeDiff *jitter);
87 GstClockTime gst_clock_get_resolution (GstClock *clock); /* sounds interesting */
88 void gst_clock_wait_async (GstClock *clock, GFunc callback, gpointer data); /* useless IMO */
89 void gst_clock_unlock (GstClock *clock); /* dunno what for */
90 void gst_clock_set_state (GstClock *clock, GstElementState state); /* might be needed, but screw up alot */
92 Hm, this looks to easy when you only need an API of 8 functions. But it's quite
93 a bit of internal hacking because of the state changes.