added error handling, removed timebase from framerate

This commit is contained in:
Christian Thaeter 2007-08-23 11:15:01 +02:00
parent 1b85206c85
commit bf32b80521

View file

@ -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_usec = 0; time->tv_sec = 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 */ {
if (gettimeofday (time, 0)) /* gettime should never ever fail in a correct program */
CINELERRA_DIE; if (gettimeofday (time, NULL))
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_usec = (fp - time->tv_sec) * 1000000.0; time->tv_sec = fp;
return time; time->tv_usec = (fp - time->tv_sec) * 1000000.0;
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;
} }