mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
some thoughts about clocking - this looks suspiciously easy. Either i'm missing something (it's late) or it's a quite...
Original commit message from CVS: some thoughts about clocking - this looks suspiciously easy. Either i'm missing something (it's late) or it's a quite good approach.
This commit is contained in:
parent
54b35086ea
commit
8703409089
1 changed files with 93 additions and 0 deletions
93
docs/random/company/clocks
Normal file
93
docs/random/company/clocks
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
TIME
|
||||||
|
In this document, the word "time" is not meant to represent a representation of
|
||||||
|
time that is close to reality. Though that is the idea in most cases, it is not
|
||||||
|
the focus. Time in this document is meant to represent time inside a stream that
|
||||||
|
is played back by GStreamer. There might be reasons to represent time in non-
|
||||||
|
realtime, for example when the processor is too slow to allow for video playback
|
||||||
|
in realtime, the clock might not update fast enough. Or one might want to use
|
||||||
|
a clock that purposefully increases/reduces the speed of time.
|
||||||
|
Time in this document is not meant to be linear either. Whereas elements can set
|
||||||
|
time freely by seeking, clocks should do their best to supply linear time. It is
|
||||||
|
not a requirement however, there might for example be slight inconsistencies
|
||||||
|
when audio clocks have buffer over/underruns.
|
||||||
|
|
||||||
|
TIME IN A CLOCK
|
||||||
|
The job of a clock is to report the time as exactly as possible that has elapsed
|
||||||
|
in the stream since the stream was started.
|
||||||
|
A Clock does never seek, so if someone seeks the stream back to the beginning,
|
||||||
|
the clock will still represent the time since a start.
|
||||||
|
The state of the clock is managed by all elements using its time as a state of a
|
||||||
|
bin is changed according to its children. A clock will try to synchronize its
|
||||||
|
state with its provider. (FIXME: or with all its children like a bin? FIXME:
|
||||||
|
What to do in the case of a providerless clock like _a_ systemclock (we might
|
||||||
|
use multiple systemclocks)? Attach to one element that uses it and reattach if
|
||||||
|
element is removed? FIXME: What do we do when a provider is removed from a
|
||||||
|
scheduler? Sounds like a good time to get a new clock to take over. FIXME:
|
||||||
|
Write a test that does exactly this in Gst-Player when changing the GConf Key.)
|
||||||
|
- NULL / READY
|
||||||
|
Nobody cares about time reported by the clock.
|
||||||
|
- PLAYING
|
||||||
|
Clock is supposed to present the time elapsed since it was started.
|
||||||
|
- PAUSED
|
||||||
|
The clock has to remember the time it was stopped and resume with that time
|
||||||
|
when it restarts playing.
|
||||||
|
|
||||||
|
TIME IN AN ELEMENT
|
||||||
|
An element only can request time information if it uses a clock. The element can
|
||||||
|
query functions that give information about the elements time. Time information
|
||||||
|
for the element is always in relation to the timestamps the element expects on
|
||||||
|
its buffers.
|
||||||
|
Example: XVideosink will output a new frame, when xvideosinks time matches the
|
||||||
|
timestamps of the buffer.
|
||||||
|
The elements time is in no relation to the time of its clock because of seeks.
|
||||||
|
If an element seeks, it adjusts its time by the difference the seek has
|
||||||
|
introduced.
|
||||||
|
Example: Playback of a song with duration 1000 that is looping. Clock and
|
||||||
|
element start at time offset 0, when the element is first set to
|
||||||
|
PLAYING. After the first loop, the elements time is (by request of that
|
||||||
|
element) reset to 0. The clock's time stays at 1000.
|
||||||
|
Note: If an element goes into the PAUSED state the elements time will continue
|
||||||
|
running. (FIXME: possibility to change that needed? Why would you want to
|
||||||
|
pause an element that should be synced while the others continue running?
|
||||||
|
FIXME: What happens if a clock provider and therefore the clock are
|
||||||
|
already at EOS while other elements are still playing? I'd vote for make
|
||||||
|
all other elements go as fast as possible. FIXME: Ask some video people if
|
||||||
|
that sounds reasonable or if we gotta force the clock to go on, which
|
||||||
|
would make it difficult to detect the difference between EOS and pause.
|
||||||
|
|
||||||
|
PROVIDERS
|
||||||
|
Providers are elements that can provide timing information and therefore provide
|
||||||
|
a clock to other elements. These elements have to update the clock, when it is
|
||||||
|
used. When a clock is used (state != NULL - FIXME: or other states?), the
|
||||||
|
provider is guaranteed to use this clock. (FIXME: necessary?). The element is
|
||||||
|
however required to synchronize to the clock it was assigned to, wether it is
|
||||||
|
its own clock or not.
|
||||||
|
|
||||||
|
SYNC POINTS
|
||||||
|
FIXME: Is it necessary to have sync points? This would allow to supply a fixed
|
||||||
|
time between sync point "SOURCE" and "SINK" so one could buffer the time
|
||||||
|
inbetween. Or is there another solution for this problem? It's possibly easier
|
||||||
|
to use an element that does TIMESTAMP = TIMESTAMP - x inside the pipeline and
|
||||||
|
drops every buffer before.
|
||||||
|
|
||||||
|
FUNCTIONS
|
||||||
|
FIXME: Use GstTime(Diff) instead of GstClockTime(Diff) ?
|
||||||
|
|
||||||
|
GstClockTime gst_clock_get_time (GstClock *clock);
|
||||||
|
GstElementState gst_clock_get_state (GstClock *clock); /* setting works internally */
|
||||||
|
GstClockReturn gst_clock_wait (GstClock *clock, GstClockTime until, GstClockTimeDiff *jitter);
|
||||||
|
|
||||||
|
GST_FLAG GST_ELEMENT_NEEDS_CLOCK; /* wether we want a clock or not */
|
||||||
|
GstClockTime gst_element_get_time (GstElement *element);
|
||||||
|
void gst_element_(clock_)seek (GstElement *element, GstClockTimeDiff diff);
|
||||||
|
GstClock * gst_element_get_clock (GstElement *element);
|
||||||
|
GstClockReturn gst_element_(clock_)wait (GstElement *element, GstClockTime until, GstClockTimeDiff *jitter);
|
||||||
|
|
||||||
|
possible extensions:
|
||||||
|
GstClockTime gst_clock_get_resolution (GstClock *clock); /* sounds interesting */
|
||||||
|
void gst_clock_wait_async (GstClock *clock, GFunc callback, gpointer data); /* useless IMO */
|
||||||
|
void gst_clock_unlock (GstClock *clock); /* dunno what for */
|
||||||
|
void gst_clock_set_state (GstClock *clock, GstElementState state); /* might be needed, but screw up alot */
|
||||||
|
|
||||||
|
Hm, this looks to easy when you only need an API of 8 functions. But it's quite
|
||||||
|
a bit of internal hacking because of the state changes.
|
Loading…
Reference in a new issue