Library: clarify usage of the basic time scale
effectively we rely in the micro tick timescale promoted by libGAVL, but it seems indicated to introduce our own constant definition. And also clarify some comments and tests. (this changeset does not change any values or functionality)
This commit is contained in:
parent
b68d0f24cb
commit
48a829d544
11 changed files with 54 additions and 44 deletions
|
|
@ -70,16 +70,14 @@ namespace error = lumiera::error;
|
|||
|
||||
|
||||
|
||||
/* GAVL_TIME_SCALE is the correct factor or dividend when using gavl_time_t for
|
||||
* units of whole seconds from gavl_time_t. Since we want to use milliseconds,
|
||||
* we need to multiply or divide by 1000 to get correct results. */
|
||||
#define GAVL_TIME_SCALE_MS (GAVL_TIME_SCALE / 1000)
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace time {
|
||||
|
||||
|
||||
const gavl_time_t TimeValue::SCALE = GAVL_TIME_SCALE;
|
||||
|
||||
|
||||
/** @note the allowed time range is explicitly limited to help overflow protection */
|
||||
const Time Time::MAX ( TimeValue::buildRaw_(+std::numeric_limits<gavl_time_t>::max() / 30) );
|
||||
|
|
@ -90,7 +88,13 @@ namespace time {
|
|||
const Time Time::NEVER (Time::MAX);
|
||||
|
||||
const Offset Offset::ZERO (Time::ZERO);
|
||||
|
||||
|
||||
/** scale factor _used locally within this implementation header_.
|
||||
* GAVL_TIME_SCALE rsp. TimeValue::SCALE is the correct factor or dividend when using gavl_time_t
|
||||
* for units of whole seconds from gavl_time_t. Since we want to use milliseconds,
|
||||
* we need to multiply or divide by 1000 to get correct results. */
|
||||
#define TIME_SCALE_MS (lib::time::TimeValue::SCALE / 1000)
|
||||
|
||||
|
||||
/** convenience constructor to build an
|
||||
|
|
@ -143,7 +147,7 @@ namespace time {
|
|||
bool negative = (time < 0);
|
||||
|
||||
if (negative) time = -time;
|
||||
time /= GAVL_TIME_SCALE_MS;
|
||||
time /= TIME_SCALE_MS;
|
||||
millis = time % 1000;
|
||||
seconds = time / 1000;
|
||||
|
||||
|
|
@ -262,7 +266,7 @@ lumiera_tmpbuf_print_time (gavl_time_t time)
|
|||
if (negative)
|
||||
time = -time;
|
||||
|
||||
time /= GAVL_TIME_SCALE_MS;
|
||||
time /= TIME_SCALE_MS;
|
||||
milliseconds = time % 1000;
|
||||
time /= 1000;
|
||||
seconds = time % 60;
|
||||
|
|
@ -281,7 +285,7 @@ lumiera_tmpbuf_print_time (gavl_time_t time)
|
|||
gavl_time_t
|
||||
lumiera_rational_to_time (FSecs const& fractionalSeconds)
|
||||
{
|
||||
return rational_cast<gavl_time_t> (GAVL_TIME_SCALE * fractionalSeconds);
|
||||
return rational_cast<gavl_time_t> (lib::time::TimeValue::SCALE * fractionalSeconds);
|
||||
}
|
||||
|
||||
gavl_time_t
|
||||
|
|
@ -290,7 +294,7 @@ lumiera_framecount_to_time (uint64_t frameCount, FrameRate const& fps)
|
|||
// convert to 64bit
|
||||
boost::rational<uint64_t> framerate (fps.numerator(), fps.denominator());
|
||||
|
||||
return rational_cast<gavl_time_t> (GAVL_TIME_SCALE * frameCount / framerate);
|
||||
return rational_cast<gavl_time_t> (lib::time::TimeValue::SCALE * frameCount / framerate);
|
||||
}
|
||||
|
||||
gavl_time_t
|
||||
|
|
@ -322,7 +326,7 @@ namespace { // implementation: basic frame quantisation....
|
|||
|
||||
const int64_t limit_num = std::numeric_limits<gavl_time_t>::max() / framerate;
|
||||
const int64_t limit_den = std::numeric_limits<gavl_time_t>::max() / framerate_divisor;
|
||||
const int64_t microScale(GAVL_TIME_SCALE);
|
||||
const int64_t microScale {lib::time::TimeValue::SCALE};
|
||||
|
||||
// protect against numeric overflow
|
||||
if (abs(time) < limit_num && microScale < limit_den)
|
||||
|
|
@ -377,7 +381,7 @@ lumiera_build_time(long millis, uint secs, uint mins, uint hours)
|
|||
+ 1000 * secs
|
||||
+ 1000 * 60 * mins
|
||||
+ 1000 * 60 * 60 * hours;
|
||||
time *= GAVL_TIME_SCALE_MS;
|
||||
time *= TIME_SCALE_MS;
|
||||
return time;
|
||||
}
|
||||
|
||||
|
|
@ -388,39 +392,39 @@ lumiera_build_time_fps (uint fps, uint frames, uint secs, uint mins, uint hours)
|
|||
+ 1000 * secs
|
||||
+ 1000 * 60 * mins
|
||||
+ 1000 * 60 * 60 * hours;
|
||||
time *= GAVL_TIME_SCALE_MS;
|
||||
time *= TIME_SCALE_MS;
|
||||
return time;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_hours (gavl_time_t time)
|
||||
{
|
||||
return time / GAVL_TIME_SCALE_MS / 1000 / 60 / 60;
|
||||
return time / TIME_SCALE_MS / 1000 / 60 / 60;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_minutes (gavl_time_t time)
|
||||
{
|
||||
return (time / GAVL_TIME_SCALE_MS / 1000 / 60) % 60;
|
||||
return (time / TIME_SCALE_MS / 1000 / 60) % 60;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_seconds (gavl_time_t time)
|
||||
{
|
||||
return (time / GAVL_TIME_SCALE_MS / 1000) % 60;
|
||||
return (time / TIME_SCALE_MS / 1000) % 60;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_millis (gavl_time_t time)
|
||||
{
|
||||
return (time / GAVL_TIME_SCALE_MS) % 1000;
|
||||
return (time / TIME_SCALE_MS) % 1000;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_time_frames (gavl_time_t time, uint fps)
|
||||
{
|
||||
REQUIRE (fps < uint(std::numeric_limits<int>::max()));
|
||||
return floordiv (lumiera_time_millis(time) * int(fps), GAVL_TIME_SCALE_MS);
|
||||
return floordiv<int> (lumiera_time_millis(time) * int(fps), TIME_SCALE_MS);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -101,13 +101,13 @@ namespace time {
|
|||
* In any case, the actual number is required to end with a trailing \c 'sec'
|
||||
* @par Example specifications
|
||||
\verbatim
|
||||
12sec --> 12 * GAVL_TIME_SCALE
|
||||
-4sec --> -4 * GAVL_TIME_SCALE
|
||||
5/4sec --> 1.25 * GAVL_TIME_SCALE
|
||||
-5/25sec --> -0.2 * GAVL_TIME_SCALE
|
||||
1+1/2sec --> 1.5 * GAVL_TIME_SCALE
|
||||
1-1/25sec --> 0.96 * GAVL_TIME_SCALE
|
||||
-12-1/4sec --> -11.75 * GAVL_TIME_SCALE
|
||||
12sec --> 12 * TimeValue::SCALE
|
||||
-4sec --> -4 * TimeValue::SCALE
|
||||
5/4sec --> 1.25 * TimeValue::SCALE
|
||||
-5/25sec --> -0.2 * TimeValue::SCALE
|
||||
1+1/2sec --> 1.5 * TimeValue::SCALE
|
||||
1-1/25sec --> 0.96 * TimeValue::SCALE
|
||||
-12-1/4sec --> -11.75 * TimeValue::SCALE
|
||||
\endverbatim
|
||||
* @param seconds string containing a time spec in seconds
|
||||
* @param grid coordinate system the parsed value is based on
|
||||
|
|
|
|||
|
|
@ -100,12 +100,15 @@ namespace time {
|
|||
friend class Mutation;
|
||||
|
||||
public:
|
||||
/** Lumiera uses micro ticks (µs) as basic time scale */
|
||||
static const gavl_time_t SCALE;
|
||||
|
||||
/** explicit limit of allowed time range */
|
||||
static gavl_time_t limited (gavl_time_t raw);
|
||||
|
||||
|
||||
explicit
|
||||
TimeValue (gavl_time_t val=0)
|
||||
TimeValue (gavl_time_t val=0) ///< time given in µ ticks here
|
||||
: t_(limited (val))
|
||||
{ }
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ namespace util {
|
|||
|
||||
/** floor function for integer arithmetics.
|
||||
* Unlike the built-in integer division, this function
|
||||
* always rounds towards the next \em smaller integer,
|
||||
* always rounds towards the _next smaller integer,_
|
||||
* even for negative numbers.
|
||||
* @warning floor on doubles performs way better
|
||||
* @see UtilFloordiv_test
|
||||
|
|
@ -103,7 +103,7 @@ namespace util {
|
|||
/** scale wrapping operation.
|
||||
* Quantises the numerator value into the scale given by the denominator.
|
||||
* Unlike the built-in integer division, this function always rounds towards
|
||||
* the next \em smaller integer and also relates the remainder (=modulo) to
|
||||
* the _next smaller integer_ and also relates the remainder (=modulo) to
|
||||
* this next lower scale grid point.
|
||||
* @return quotient and remainder packed into a struct
|
||||
* @see UtilFloorwarp_test
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
namespace vault {
|
||||
|
||||
#define MICRO_TICS_PER_NANOSECOND (1000*1000*1000 / GAVL_TIME_SCALE)
|
||||
#define MICRO_TICS_PER_NANOSECOND (1000*1000*1000 / TimeValue::SCALE)
|
||||
|
||||
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ namespace vault {
|
|||
////////////////////////////////////////////TODO (what happens on ntp adjustments?)
|
||||
////////////////////////////////////////////TICKET #886
|
||||
|
||||
gavl_time_t ticksSince1970 = now.tv_sec * GAVL_TIME_SCALE
|
||||
gavl_time_t ticksSince1970 = now.tv_sec * TimeValue::SCALE
|
||||
+ now.tv_nsec / MICRO_TICS_PER_NANOSECOND;
|
||||
|
||||
ENSURE (ticksSince1970 == Time::limited (ticksSince1970));
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "steam/streamtype.hpp"
|
||||
#include "steam/control/stypemanager.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include <gavl/gavl.h>
|
||||
|
|
@ -42,12 +43,14 @@ extern "C" {
|
|||
namespace steam {
|
||||
namespace test_format {
|
||||
|
||||
using lib::time::TimeValue;
|
||||
|
||||
namespace { // constants used to parametrise tests
|
||||
|
||||
const int TEST_IMG_WIDTH = 40;
|
||||
const int TEST_IMG_HEIGHT = 30;
|
||||
|
||||
const int TEST_FRAME_DUR = GAVL_TIME_SCALE / 25;
|
||||
const int TEST_FRAME_DUR = TimeValue::SCALE / 25;
|
||||
}
|
||||
|
||||
Symbol GAVL = "GAVL";
|
||||
|
|
@ -72,11 +75,11 @@ namespace test_format {
|
|||
type.frame_width = TEST_IMG_WIDTH; // Width of the frame buffer in pixels, might be larger than image_width
|
||||
type.frame_height = TEST_IMG_WIDTH; // Height of the frame buffer in pixels, might be larger than image_height
|
||||
|
||||
type.pixel_width = 1; // Relative width of a pixel (pixel aspect ratio is pixel_width/pixel_height)
|
||||
type.pixel_height = 1; // Relative height of a pixel (pixel aspect ratio is pixel_width/pixel_height)
|
||||
type.pixel_width = 1; // Relative width of a pixel (pixel aspect ratio is pixel_width/pixel_height)
|
||||
type.pixel_height = 1; // Relative height of a pixel (pixel aspect ratio is pixel_width/pixel_height)
|
||||
|
||||
type.frame_duration = TEST_FRAME_DUR; // Duration of a frame in timescale tics.
|
||||
type.timescale = GAVL_TIME_SCALE; // Timescale in tics per second (is defined to be 1000000 as of 9/2008)
|
||||
type.frame_duration = TEST_FRAME_DUR; // Duration of a frame in timescale ticks.
|
||||
type.timescale = TimeValue::SCALE; // Timescale in ticks per second (is defined to be 1000000 as of 9/2008)
|
||||
|
||||
return type;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ namespace test{
|
|||
: FixedFrameQuantiser
|
||||
{
|
||||
TestQuant (int origin=0)
|
||||
: FixedFrameQuantiser( FrameRate(GAVL_TIME_SCALE, 3 ), TimeValue(origin))
|
||||
: FixedFrameQuantiser( FrameRate(TimeValue::SCALE, 3 ), TimeValue(origin))
|
||||
{ }
|
||||
|
||||
int
|
||||
|
|
@ -210,7 +210,7 @@ namespace test{
|
|||
CHECK (hugeFrame == not_really_larger);
|
||||
|
||||
// frame sizes below the time micro grid get trapped
|
||||
long subAtomic = 2*GAVL_TIME_SCALE; // too small for this universe...
|
||||
long subAtomic = 2*TimeValue::SCALE; // too small for this universe...
|
||||
VERIFY_ERROR (BOTTOM_VALUE, FixedFrameQuantiser quark(subAtomic) );
|
||||
VERIFY_ERROR (BOTTOM_VALUE, FixedFrameQuantiser quark(Duration (FSecs (1,subAtomic))) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ namespace test{
|
|||
random_or_get (string arg)
|
||||
{
|
||||
if (isnil(arg))
|
||||
return gavl_time_t (1 + (rand() % 100000)) * GAVL_TIME_SCALE;
|
||||
return gavl_time_t (1 + (rand() % 100000)) * TimeValue::SCALE;
|
||||
else
|
||||
return lexical_cast<gavl_time_t> (arg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace test{
|
|||
random_or_get (string arg)
|
||||
{
|
||||
if (isnil(arg))
|
||||
return gavl_time_t (1 + (rand() % 100000)) * GAVL_TIME_SCALE;
|
||||
return gavl_time_t (1 + (rand() % 100000)) * TimeValue::SCALE;
|
||||
else
|
||||
return lexical_cast<gavl_time_t> (arg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,20 +171,20 @@ namespace test{
|
|||
|
||||
// time in seconds
|
||||
Time t1(FSecs(1));
|
||||
CHECK (t1 == TimeValue(GAVL_TIME_SCALE));
|
||||
CHECK (t1 == TimeValue(TimeValue::SCALE));
|
||||
|
||||
// create from fractional seconds
|
||||
FSecs halve(1,2);
|
||||
CHECK (0.5 == boost::rational_cast<double> (halve));
|
||||
Time th(halve);
|
||||
CHECK (th == TimeValue(GAVL_TIME_SCALE/2));
|
||||
CHECK (th == TimeValue(TimeValue::SCALE/2));
|
||||
|
||||
Time tx1(500,0);
|
||||
CHECK (tx1 == th);
|
||||
Time tx2(1,2);
|
||||
CHECK (tx2 == TimeValue(2.001*GAVL_TIME_SCALE));
|
||||
CHECK (tx2 == TimeValue(2.001*TimeValue::SCALE));
|
||||
Time tx3(1,1,1,1);
|
||||
CHECK (tx3 == TimeValue(GAVL_TIME_SCALE*(0.001 + 1 + 60 + 60*60)));
|
||||
CHECK (tx3 == TimeValue(TimeValue::SCALE*(0.001 + 1 + 60 + 60*60)));
|
||||
|
||||
CHECK ("1:01:01.001" == string(tx3));
|
||||
|
||||
|
|
@ -195,8 +195,8 @@ namespace test{
|
|||
CHECK (th-th == TimeValue(0));
|
||||
|
||||
// that was indeed a temporary and didn't affect the originals
|
||||
CHECK (t1 == TimeValue(GAVL_TIME_SCALE));
|
||||
CHECK (th == TimeValue(GAVL_TIME_SCALE/2));
|
||||
CHECK (t1 == TimeValue(TimeValue::SCALE));
|
||||
CHECK (th == TimeValue(TimeValue::SCALE/2));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -208,7 +208,7 @@ namespace lumiera {
|
|||
* invoked, which gives additional diagnostics.*/
|
||||
void terminateUnknown () noexcept
|
||||
{
|
||||
throw Error("You'll never get me, won't you?");
|
||||
throw Error{"Catch the hedgehog..."};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue