| 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. |