added error handling, removed timebase from framerate
This commit is contained in:
parent
1b85206c85
commit
bf32b80521
1 changed files with 97 additions and 65 deletions
132
src/lib/time.h
132
src/lib/time.h
|
|
@ -36,7 +36,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* over or underflow (tried to make a movie which has negative length? or more than some hundreds days?) */
|
/* over or underflow (tried to make a movie which has negative length? or more than some hundreds days?) */
|
||||||
CINELERRA_ERROR_DECLARE(TIME_RANGE);
|
CINELERRA_ERROR_DECLARE(TIME_OVERFLOW);
|
||||||
|
CINELERRA_ERROR_DECLARE(TIME_UNDERFLOW);
|
||||||
|
CINELERRA_ERROR_DECLARE(TIME_NEGATIVE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Note: we measure time starting from zero,
|
Note: we measure time starting from zero,
|
||||||
|
|
@ -47,93 +49,101 @@ typedef struct timeval cinelerra_time;
|
||||||
typedef cinelerra_time* CinelerraTime;
|
typedef cinelerra_time* CinelerraTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* framerates are defined as a rational number and a base time (usually 1sec (do we need this?))
|
* framerates are defined as a rational number
|
||||||
* for example NTSC with 29.97fps is {2997, 100, {1, 0}}
|
* for example NTSC with 29.97fps is {2997, 100}
|
||||||
*/
|
*/
|
||||||
struct cinelerra_framerate_struct
|
struct cinelerra_framerate_struct
|
||||||
{
|
{
|
||||||
unsigned numerator;
|
unsigned numerator;
|
||||||
unsigned denominator;
|
unsigned denominator;
|
||||||
cinelerra_time base;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct cinelerra_framerate_struct cinelerra_framerate;
|
typedef struct cinelerra_framerate_struct cinelerra_framerate;
|
||||||
typedef cinelerra_framerate CinelerraFramerate;
|
typedef cinelerra_framerate* CinelerraFramerate;
|
||||||
|
|
||||||
typedef unsigned long cinelerra_frame;
|
typedef unsigned long cinelerra_frame;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** set a time value to zero.
|
/**
|
||||||
|
* set a time value to zero.
|
||||||
*/
|
*/
|
||||||
inline CinelerraTime
|
inline CinelerraTime
|
||||||
cinelerra_time_clear (CinelerraTime time)
|
cinelerra_time_clear (CinelerraTime time)
|
||||||
{
|
{
|
||||||
REQUIRE (time);
|
if(time)
|
||||||
|
{
|
||||||
time->tv_sec = 0;
|
time->tv_sec = 0;
|
||||||
time->tv_usec = 0;
|
time->tv_usec = 0;
|
||||||
|
}
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get current time.
|
/**
|
||||||
|
* get current time.
|
||||||
*/
|
*/
|
||||||
inline CinelerraTime
|
inline CinelerraTime
|
||||||
cinelerra_time_current (CinelerraTime time)
|
cinelerra_time_current (CinelerraTime time)
|
||||||
{
|
{
|
||||||
REQUIRE (time);
|
if (time)
|
||||||
|
{
|
||||||
/* gettime should never ever fail in a correct program */
|
/* gettime should never ever fail in a correct program */
|
||||||
if (gettimeofday (time, 0))
|
if (gettimeofday (time, NULL))
|
||||||
CINELERRA_DIE;
|
CINELERRA_DIE;
|
||||||
|
}
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** init from floating point representation.
|
/**
|
||||||
|
* init from floating point representation.
|
||||||
*/
|
*/
|
||||||
inline CinelerraTime
|
inline CinelerraTime
|
||||||
cinelerra_time_set_double (CinelerraTime time, double fp)
|
cinelerra_time_set_double (CinelerraTime time, double fp)
|
||||||
{
|
{
|
||||||
REQUIRE (time);
|
if (time)
|
||||||
REQUIRE (fp >= 0.0);
|
{
|
||||||
|
if (fp >= 0.0)
|
||||||
|
{
|
||||||
time->tv_sec = fp;
|
time->tv_sec = fp;
|
||||||
time->tv_usec = (fp - time->tv_sec) * 1000000.0;
|
time->tv_usec = (fp - time->tv_sec) * 1000000.0;
|
||||||
return time;
|
return time;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cinelerra_error_set(CINELERRA_ERROR_TIME_NEGATIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** convert to floating point repesentation.
|
/**
|
||||||
|
* convert to floating point repesentation.
|
||||||
*/
|
*/
|
||||||
inline double
|
inline double
|
||||||
cinelerra_time_double_get (CinelerraTime time)
|
cinelerra_time_double_get (CinelerraTime time)
|
||||||
{
|
{
|
||||||
REQUIRE (time);
|
if (time)
|
||||||
|
{
|
||||||
double fp;
|
double fp;
|
||||||
|
|
||||||
fp = time->tv_sec;
|
fp = time->tv_sec;
|
||||||
fp += time->tv_usec / 1000000.0;
|
fp += time->tv_usec / 1000000.0;
|
||||||
return fp;
|
return fp;
|
||||||
|
}
|
||||||
|
return NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** convert from floating point repesentation.
|
/**
|
||||||
|
* normalize time after operations.
|
||||||
|
* used internally
|
||||||
*/
|
*/
|
||||||
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
|
inline void
|
||||||
cinelerra_time_normalize (CinelerraTime time)
|
cinelerra_time_normalize (CinelerraTime time)
|
||||||
{
|
{
|
||||||
|
REQUIRE (time);
|
||||||
if (time->tv_usec >= 1000000)
|
if (time->tv_usec >= 1000000)
|
||||||
{
|
{
|
||||||
time->tv_sec += (time->tv_usec / 1000000);
|
time->tv_sec += (time->tv_usec / 1000000);
|
||||||
|
|
@ -141,49 +151,71 @@ cinelerra_time_normalize (CinelerraTime time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** copy time
|
/**
|
||||||
|
* copy time
|
||||||
*/
|
*/
|
||||||
inline CinelerraTime
|
inline CinelerraTime
|
||||||
cinelerra_time_copy (CinelerraTime dest, const CinelerraTime src)
|
cinelerra_time_copy (CinelerraTime dest, const CinelerraTime src)
|
||||||
{
|
{
|
||||||
REQUIRE (dest);
|
if (dest && src)
|
||||||
REQUIRE (src);
|
{
|
||||||
dest->tv_sec = src->tv_sec;
|
dest->tv_sec = src->tv_sec;
|
||||||
dest->tv_usec = src->tv_usec;
|
dest->tv_usec = src->tv_usec;
|
||||||
return time;
|
}
|
||||||
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** add time.
|
/**
|
||||||
|
* add time.
|
||||||
*/
|
*/
|
||||||
inline CinelerraTime
|
inline CinelerraTime
|
||||||
cinelerra_time_add (CinelerraTime dest, const CinelerraTime to_add)
|
cinelerra_time_add (CinelerraTime dest, const CinelerraTime src)
|
||||||
{
|
{
|
||||||
REQUIRE (dest);
|
if (dest && src)
|
||||||
REQUIRE (to_add);
|
{
|
||||||
REQUIRE (dest->tv_sec + to_add->tv_sec > dest->tv_sec, "time overflow");
|
time_t t = dest->tv_sec;
|
||||||
TODO ("handling overflow as error?");
|
|
||||||
|
|
||||||
dest->tv_sec += to_add->tv_sec;
|
dest->tv_sec += src->tv_sec;
|
||||||
time->tv_usec += to_add->tv_usec;
|
time->tv_usec += src->tv_usec;
|
||||||
|
|
||||||
cinelerra_time_normalize (dest);
|
cinelerra_time_normalize (dest);
|
||||||
|
|
||||||
|
if (dest->tv_sec < t)
|
||||||
|
{
|
||||||
|
cinelerra_error_set (CINELERRA_ERROR_TIME_OVERFLOW);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** substact time.
|
/**
|
||||||
|
* substact time.
|
||||||
*/
|
*/
|
||||||
inline CinelerraTime
|
inline CinelerraTime
|
||||||
cinelerra_time_sub (CinelerraTime dest, const CinelerraTime to_sub)
|
cinelerra_time_sub (CinelerraTime dest, const CinelerraTime src)
|
||||||
{
|
{
|
||||||
REQUIRE (dest);
|
if (dest && src)
|
||||||
REQUIRE (to_sub);
|
{
|
||||||
REQUIRE (dest->tv_sec - to_sub->tv_sec < dest->tv_sec, "time underflow");
|
time_t t = dest->tv_sec;
|
||||||
TODO ("handling underflow as error?");
|
|
||||||
|
|
||||||
dest->tv_sec -= to_sub->tv_sec;
|
dest->tv_sec -= src->tv_sec;
|
||||||
time->tv_usec -= to_sub->tv_usec;
|
if (time->tv_usec >= src->tv_usec)
|
||||||
|
time->tv_usec -= src->tv_usec;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--dest->tv_sec;
|
||||||
|
time->tv_usec += src->tv_usec;
|
||||||
|
}
|
||||||
|
|
||||||
cinelerra_time_normalize (dest);
|
cinelerra_time_normalize (dest);
|
||||||
|
|
||||||
|
if (dest->tv_sec > t)
|
||||||
|
{
|
||||||
|
cinelerra_error_set (CINELERRA_ERROR_TIME_UNDERFLOW);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue