141 lines
6.3 KiB
Text
141 lines
6.3 KiB
Text
Design Process : Time Handling
|
|
==============================
|
|
|
|
[grid="all"]
|
|
`------------`-----------------------
|
|
*State* _Final_
|
|
*Date* _2007-06-21_
|
|
*Proposed by* link:Ichthyostega[]
|
|
-------------------------------------
|
|
|
|
Time handling
|
|
-------------
|
|
How to handle time values in the code and which policy to aply 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 `typedef int64_t gavl_time_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
|
|
half-way rounding, but the result should not depend on the actual
|
|
zero-point of the scale (i.e. `floor(0.5+val)`, thus quant(0.5) yields 1,
|
|
quant(0.49) yields 0, quant(-0.5) yields 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
|
|
on a existing project.
|
|
|
|
|
|
Alternatives
|
|
~~~~~~~~~~~~
|
|
Leave everything as in Cinelerra2, 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
|
|
"rational" 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
|
|
sticking to "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 not the more "clean" 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 fencepost 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.
|
|
-- link:Ichthyostega[] [[DateTime(2007-06-21T05:12:03Z)]]
|
|
|
|
* We use GAVL now (needs to be included in the build system)
|
|
-- link:ct[] [[DateTime(2008-03-05T16:19:22Z)]]
|
|
|
|
* I've 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" dependant on the position in relation to the time zero
|
|
point.
|
|
-- link:Ichthyostega[] [[DateTime(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.
|
|
-- link:ct[] [[DateTime(2008-10-06T06:44:21Z)]]
|
|
|
|
|
|
Conclusion
|
|
~~~~~~~~~~
|
|
* The adapted form of this proposal was *accepted* by 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.
|
|
|
|
Back to link:/documentation/devel/rfc.html[Lumiera Design Process overview]
|