LUMIERA.clone/doc/devel/rfc/TimeHandling.txt
Ichthyostega b556d2b770 clean-up: comb through the historical pages to fix markup errors
Some sections of the Lumiera website document meeting minutes,
discussion protocols and design proposals from the early days
of the project; these pages were initially authored in the
»Moin Moin Wiki« operated by Cehteh on pipapo.org at that time;
this wiki backed the first publications of the »Cinelerra-3«
initiative, which turned into the Lumiera project eventually.

Some years later, those pages were transliterated into Asciidoc
semi-automatically, resulting in a lot of broken markup and links.
This is a long standing maintenance problem problem plaguing the
Lumiera website, since those breakages cause a lot of warnings
and flood the logs of any linkchecker run.
2025-09-21 05:40:15 +02:00

153 lines
6.8 KiB
Text

Design Process : Time Handling
==============================
[options="autowidth"]
|====================================
|*State* | _Final_
|*Date* | _2007-06-21_
|*Proposed by* | Ichthyostega
|====================================
Handling of Time and Time Quantisation
--------------------------------------
How to handle time values in the code and which policy to apply
to the ``current'' position
Description
~~~~~~~~~~~
. *Representation of time values*
* We use an uniform time type. Time is time, not frames, samples etc.
* All timings in Lumiera are based on integral datatypes
* We use a fixed, very fine grid, something of the sort of microseconds
* The internal representation is based on a `using raw_time_64 = int64_t`
* We use a set of library routines and convenience-methods to
- Get time in different formats (fractional seconds, frame counts)
- Calculate with time values (overloaded operators)
* Time measurement is zero based (of course 😁 )
. *Quantizing to a frame index or similar*
* Quantizing/rounding shall happen only once at a defined point in the
calculation chain and, if in doubt, be done always as late as possible.
* Values needing to be quantized to time (grid) positions are calculated by
applying a suitable rounding scheme uniformly, e.g. half-way rounding, but
the result should not depend on the actual zero-point of the scale
** `floor(0.5+val)`
** `quant(0.5)` ⟼ 1
** `quant(0.49)` ⟼ 0
** `quant(-0.5)` ⟼ 0
. *Position of frames*
* Frame numbers are zero based and Frame 0 starts at time≡0 (or whatever the
nominal start time is)
* Each frame starts when the locator hits its lower border (inclusively) and
ends when the locator is on its upper border (exclusively)
image:{imgd}/Lumi.FramePositions1.png[]
* When the locator snaps to frames this means it can be placed on the start
positions of the frames solely
* When the locator is placed on such a start position, this means _always_
displaying the frame starting at this position, irrespective of playback
direction.
. *Current position for keyframe nodes and automation*
* When parameter values for plugins/automation need to be retrieved on a per
frame base (which normally is the case), for each frame there is a well
defined 'point of evaluation' time position, irrespective of the playback
direction
* There is no single best choice where to put this ``POE'', thus we provide a
switch
image:{imgd}/Lumi.FramePositions2.png[]
- 'Point of evaluation' of the automation is in the middle of the timespan
covered by a frame
- 'Point of evaluation' is on the lower bound of each frame
* Maybe additional position or fraction (?)
* Moreover, we provide an option to snap the keyframe nodes to the 'point of
evaluation' within each frame or to be able to move them arbitrarily
* When keyframes are set by tweaking of parameters, they are located at the
'point of evaluation' position.
Tasks
^^^^^
* Figure out what has to be done when switching the ``current position''
policy for an existing project.
Alternatives
^^^^^^^^^^^^
Leave everything as in Cinelerra-2, i.e. show frames after the locator has
passed over them, behave different when playing backwards and set the keyframes
on the position of the locator but use them on the frame actually to be shown
(which differs according to the playback direction but is always ``one off'').
Why not? because it makes frame-precise working with keyframes a real pain and
even creates contradictory situations when you switch back and forward while
tweaking.
Similar for the issues with quantized values. At first sight, e.g. directly
using the frame numbers as coordinates (as Cinelerra does) seems to be clever,
but on the long run we get lots of case distinctions scattered all over the
code. Thus better use one uniform scheme and work with precise time values as
long as possible and only quantize for rendering a given frame.
Rationale
~~~~~~~~~
The intention is to make time handling and calculations as uniform and
_deterministic_ as possible. We try to stick to the precise mathematical values
and let the calculations just yield an result in an uniform manner, instead of
relying on ``simple'' values like frame counts or even a session-wide frame rate
. Time and interval calculations are tricky. Solve this question once and be done.
. Rounding is always dangerous, rounded values are by no means the ``cleaner'' values.
The floor-rounding rule is chosen, because the length of an interval after
quantisation should not depend on the position in relation to the zero point.
The usual mathematical rounding behaves _symmetrical_ to the zero point,
which could yield a different length after quantisation if an interval
contains the zero point
. This is based on the analogy with real film running through a film projector
(or the usual »fence post problem«)
. While using the actual position of the locator as ``the current'' position for
keyframes seems more natural at first, it crates problems when mixing footage
with different framerate or when using a low-framerate proxy footage.
Comments
~~~~~~~~
* This is the summary of a discussion _cehteh_, _Plouj_ and _ichthyo_ just had on IRC.
Ichthyostega:: '2007-06-21T05:12:03Z'
* We use lib GAVL now (needs to be included in the build system)
ct:: '2008-03-05T16:19:22Z'
* I have tidied up this old design proposal, we could make it final now. I've
changed the rounding rule, please check if it's OK. In the original proposal,
we wanted to use the common mathematical rounding rule, i.e. round(-x) = -
round(x) . I changed this, because of the danger of interval lengths or
alignment to ``jump'' depending on the position in relation to the time zero
point.
Ichthyostega:: '2008-10-04T22:47:54Z'
* Looks ok to me, maybe we should wrap up the Gavl time handling in a very thin
layer to unify our time functions and then cast this again into a
authoritative testsuite/specification. Anyways I think this can be finalized.
ct:: '2008-10-06T06:44:21Z'
Conclusion
~~~~~~~~~~
* The adapted form of this proposal was __`accepted'__ by the
link:{ldoc}/devel/meeting_summary/2008-10-10.html#_time_handling[October.2008 developer meeting].
* The proposed thin library layer to centralize time calculations shall be
added on demand. When doing so, we need to add thorough test coverage for
time calculations too.
TIP: this library layer was first implemented as a collection of functions,
but has been transformed into a system of adaptor types meanwhile,
so that any conversion into a _Time Code_ also has to go through
a suitable _quantisation_ into a predefined _time grid_.
-> link:{ldoc}/design/architecture/time/index.html[read more here...]
''''
Back to link:/x/DesignProcess.html[Lumiera Design Process overview]