time.h for initial! review
This commit is contained in:
parent
e8ff2cf533
commit
1b85206c85
2 changed files with 218 additions and 4 deletions
191
src/lib/time.h
Normal file
191
src/lib/time.h
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
time.h - Time and frame calculations
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef CINELERRA_TIME_H
|
||||
#define CINELERRA_TIME_H
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
/*
|
||||
this time functions are small macro like wrapers, they are all inlined for performance reasons
|
||||
time is passed around as pointers, this pointer must never be NULL
|
||||
|
||||
timehandling is a delicate business, be careful of precision errors accumulating, TODO explain how to use time
|
||||
|
||||
*/
|
||||
|
||||
/* over or underflow (tried to make a movie which has negative length? or more than some hundreds days?) */
|
||||
CINELERRA_ERROR_DECLARE(TIME_RANGE);
|
||||
|
||||
/*
|
||||
Note: we measure time starting from zero,
|
||||
time never becomes negative
|
||||
(I didnt checked if the time types are signed)
|
||||
*/
|
||||
typedef struct timeval cinelerra_time;
|
||||
typedef cinelerra_time* CinelerraTime;
|
||||
|
||||
/**
|
||||
* framerates are defined as a rational number and a base time (usually 1sec (do we need this?))
|
||||
* for example NTSC with 29.97fps is {2997, 100, {1, 0}}
|
||||
*/
|
||||
struct cinelerra_framerate_struct
|
||||
{
|
||||
unsigned numerator;
|
||||
unsigned denominator;
|
||||
cinelerra_time base;
|
||||
};
|
||||
|
||||
typedef struct cinelerra_framerate_struct cinelerra_framerate;
|
||||
typedef cinelerra_framerate CinelerraFramerate;
|
||||
|
||||
typedef unsigned long cinelerra_frame;
|
||||
|
||||
|
||||
|
||||
|
||||
/** set a time value to zero.
|
||||
*/
|
||||
inline CinelerraTime
|
||||
cinelerra_time_clear (CinelerraTime time)
|
||||
{
|
||||
REQUIRE (time);
|
||||
time->tv_sec = 0;
|
||||
time->tv_usec = 0;
|
||||
return time;
|
||||
}
|
||||
|
||||
/** get current time.
|
||||
*/
|
||||
inline CinelerraTime
|
||||
cinelerra_time_current (CinelerraTime time)
|
||||
{
|
||||
REQUIRE (time);
|
||||
/* gettime should never ever fail in a correct program */
|
||||
if (gettimeofday (time, 0))
|
||||
CINELERRA_DIE;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
/** init from floating point representation.
|
||||
*/
|
||||
inline CinelerraTime
|
||||
cinelerra_time_set_double (CinelerraTime time, double fp)
|
||||
{
|
||||
REQUIRE (time);
|
||||
REQUIRE (fp >= 0.0);
|
||||
|
||||
time->tv_sec = fp;
|
||||
time->tv_usec = (fp - time->tv_sec) * 1000000.0;
|
||||
return time;
|
||||
}
|
||||
|
||||
/** convert to floating point repesentation.
|
||||
*/
|
||||
inline double
|
||||
cinelerra_time_double_get (CinelerraTime time)
|
||||
{
|
||||
REQUIRE (time);
|
||||
double fp;
|
||||
|
||||
fp = time->tv_sec;
|
||||
fp += time->tv_usec / 1000000.0;
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** convert from floating point repesentation.
|
||||
*/
|
||||
inline CinelerraTime
|
||||
cinelerra_time_set_double (CinelerraTime time, double fp)
|
||||
{
|
||||
REQUIRE (time);
|
||||
REQUIRE (fp >= 0.0);
|
||||
|
||||
time->tv_sec = fp;
|
||||
time->tv_usec = (fp - time->tv_sec) * 1000000.0;
|
||||
return time;
|
||||
}
|
||||
|
||||
/* internal function */
|
||||
inline void
|
||||
cinelerra_time_normalize (CinelerraTime time)
|
||||
{
|
||||
if (time->tv_usec >= 1000000)
|
||||
{
|
||||
time->tv_sec += (time->tv_usec / 1000000);
|
||||
time->tv_usec = (time->tv_usec % 1000000);
|
||||
}
|
||||
}
|
||||
|
||||
/** copy time
|
||||
*/
|
||||
inline CinelerraTime
|
||||
cinelerra_time_copy (CinelerraTime dest, const CinelerraTime src)
|
||||
{
|
||||
REQUIRE (dest);
|
||||
REQUIRE (src);
|
||||
dest->tv_sec = src->tv_sec;
|
||||
dest->tv_usec = src->tv_usec;
|
||||
return time;
|
||||
}
|
||||
|
||||
/** add time.
|
||||
*/
|
||||
inline CinelerraTime
|
||||
cinelerra_time_add (CinelerraTime dest, const CinelerraTime to_add)
|
||||
{
|
||||
REQUIRE (dest);
|
||||
REQUIRE (to_add);
|
||||
REQUIRE (dest->tv_sec + to_add->tv_sec > dest->tv_sec, "time overflow");
|
||||
TODO ("handling overflow as error?");
|
||||
|
||||
dest->tv_sec += to_add->tv_sec;
|
||||
time->tv_usec += to_add->tv_usec;
|
||||
|
||||
cinelerra_time_normalize (dest);
|
||||
return dest;
|
||||
}
|
||||
|
||||
/** substact time.
|
||||
*/
|
||||
inline CinelerraTime
|
||||
cinelerra_time_sub (CinelerraTime dest, const CinelerraTime to_sub)
|
||||
{
|
||||
REQUIRE (dest);
|
||||
REQUIRE (to_sub);
|
||||
REQUIRE (dest->tv_sec - to_sub->tv_sec < dest->tv_sec, "time underflow");
|
||||
TODO ("handling underflow as error?");
|
||||
|
||||
dest->tv_sec -= to_sub->tv_sec;
|
||||
time->tv_usec -= to_sub->tv_usec;
|
||||
|
||||
cinelerra_time_normalize (dest);
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,9 +1,32 @@
|
|||
|
||||
TESTING "Time functions"
|
||||
TESTING "Time functions" ./test_time
|
||||
|
||||
PLANNED "get time"
|
||||
PLANNED "add time, normalized"
|
||||
PLANNED "substract time, normalized"
|
||||
TEST "time to float" tofloat 15 500000 <<END
|
||||
out: 15.5
|
||||
END
|
||||
|
||||
PLANNED "float to time" fromfloat 33.6666666661 <<END
|
||||
out: 33 666667
|
||||
END
|
||||
|
||||
PLANNED "from rational" fromrational 4 3 <<END
|
||||
out: 1 333333
|
||||
END
|
||||
|
||||
PLANNED "get time" gettime <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
PLANNED "add time, normalized" add 1234567890 123456789 <<END
|
||||
out: 13580 24679
|
||||
END
|
||||
|
||||
PLANNED "substract time, normalized" sub 1234567890 123456789 <<END
|
||||
out: 11111 11101
|
||||
END
|
||||
|
||||
PLANNED "overflow"
|
||||
PLANNED "underflow"
|
||||
|
||||
|
||||
# the next ones for different common framerates, check corner cases
|
||||
|
|
|
|||
Loading…
Reference in a new issue