Merge branch 'library'
This commit is contained in:
commit
98d3716fcb
10 changed files with 700 additions and 12 deletions
|
|
@ -19,6 +19,17 @@ libcin3_a_srcdir = $(top_srcdir)/src/lib
|
|||
noinst_LIBRARIES += libcin3.a
|
||||
|
||||
libcin3_a_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror
|
||||
libcin3_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
libcin3_a_SOURCES = \
|
||||
$(libcin3_a_srcdir)/plugin.c \
|
||||
$(libcin3_a_srcdir)/error.c \
|
||||
$(libcin3_a_srcdir)/time.c \
|
||||
$(libcin3_a_srcdir)/framerate.c
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(libcin3_a_srcdir)/plugin.h \
|
||||
$(libcin3_a_srcdir)/error.h \
|
||||
$(libcin3_a_srcdir)/time.h \
|
||||
$(libcin3_a_srcdir)/framerate.h
|
||||
|
||||
libcin3_a_SOURCES = $(libcin3_a_srcdir)/plugin.c $(libcin3_a_srcdir)/error.c
|
||||
noinst_HEADERS += $(libcin3_a_srcdir)/plugin.h $(libcin3_a_srcdir)/error.h
|
||||
|
|
|
|||
25
src/lib/framerate.c
Normal file
25
src/lib/framerate.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
framerate.c - framerate 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.
|
||||
*/
|
||||
|
||||
#include "lib/error.h"
|
||||
|
||||
CINELERRA_ERROR_DEFINE(FRAMERATE_ILLEGAL_TIME, "invalid time given");
|
||||
CINELERRA_ERROR_DEFINE(FRAMERATE_ILLEGAL_FRAME, "invalid frame given");
|
||||
103
src/lib/framerate.h
Normal file
103
src/lib/framerate.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
framerate.h - framerate 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_FRAMERATE_H
|
||||
#define CINELERRA_FRAMERATE_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "lib/error.h"
|
||||
#include "lib/time.h"
|
||||
|
||||
/**
|
||||
* framerates are defined as a rational number
|
||||
* for example NTSC with 30000/1001fps
|
||||
*/
|
||||
struct cinelerra_framerate_struct
|
||||
{
|
||||
unsigned n; //numerator
|
||||
unsigned d; //denominator
|
||||
};
|
||||
|
||||
typedef struct cinelerra_framerate_struct cinelerra_framerate;
|
||||
typedef cinelerra_framerate* CinelerraFramerate;
|
||||
|
||||
typedef signed long cinelerra_framepos;
|
||||
|
||||
CINELERRA_ERROR_DECLARE(FRAMERATE_ILLEGAL_TIME);
|
||||
CINELERRA_ERROR_DECLARE(FRAMERATE_ILLEGAL_FRAME);
|
||||
|
||||
#define CINELERRA_FRAMEPOS_ERROR LONG_MIN
|
||||
|
||||
/**
|
||||
* Get the frame number of a given time at a given frame rate.
|
||||
* frame indexing starts with 1
|
||||
* @param framerate is a pointer to the framerate used, defined as rational number. Must be given.
|
||||
* @param time is a pointer to a cinelerra_time which shall be converted.
|
||||
* @return frame at the given time or CINELERRA_FRAMEPOS_ERROR on error.
|
||||
*/
|
||||
static inline cinelerra_framepos
|
||||
cinelerra_framerate_frame_get_time (const CinelerraFramerate framerate, CinelerraTime time)
|
||||
{
|
||||
REQUIRE (framerate);
|
||||
if (!time || time->tv_sec == (time_t)-1)
|
||||
{
|
||||
cinelerra_error_set(CINELERRA_ERROR_FRAMERATE_ILLEGAL_TIME);
|
||||
return CINELERRA_FRAMEPOS_ERROR;
|
||||
}
|
||||
|
||||
/* we add a magic microsecond for rounding, because of integer truncation frames may be calculated at most 1us earlier,
|
||||
the idea is to compensate odd framerates which fall out off microsecond precision.
|
||||
*/
|
||||
return ((time->tv_sec * 1000000ULL + time->tv_usec + /*magic*/1) * framerate->n)/(framerate->d * 1000000ULL) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start time for a frame.
|
||||
* frame indexing starts with 1
|
||||
* @param framerate is a pointer to the framerate used, defined as rational number. Must be given.
|
||||
* @param time is a pointer to a cinelerra_time which shall take the result.
|
||||
* @param frame frame number to be converted to time. This frame number must be greater than 0.
|
||||
* @return the pointer given in time or NULL on error (or when it was given as time).
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_framerate_time_get_time_frame (const CinelerraFramerate framerate,
|
||||
CinelerraTime time,
|
||||
cinelerra_framepos frame)
|
||||
{
|
||||
REQUIRE (framerate);
|
||||
if (time)
|
||||
{
|
||||
if (frame < 1)
|
||||
{
|
||||
cinelerra_error_set(CINELERRA_ERROR_FRAMERATE_ILLEGAL_FRAME);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned long long usec = ((frame-1) * framerate->d * 1000000ULL - (/*magic*/frame>1?1:0)) / framerate->n;
|
||||
|
||||
time->tv_sec = usec / 1000000;
|
||||
time->tv_usec = usec % 1000000;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
#endif
|
||||
26
src/lib/time.c
Normal file
26
src/lib/time.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "lib/error.h"
|
||||
|
||||
CINELERRA_ERROR_DEFINE(TIME_OVERFLOW, "Time overflow");
|
||||
CINELERRA_ERROR_DEFINE(TIME_UNDERFLOW, "Time underflow");
|
||||
CINELERRA_ERROR_DEFINE(TIME_NEGATIVE, "Time negative");
|
||||
247
src/lib/time.h
Normal file
247
src/lib/time.h
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
time.h - Time 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 <math.h>
|
||||
|
||||
#include "lib/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_OVERFLOW);
|
||||
CINELERRA_ERROR_DECLARE(TIME_UNDERFLOW);
|
||||
CINELERRA_ERROR_DECLARE(TIME_NEGATIVE);
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
/**
|
||||
* normalize time after operations.
|
||||
* used internally
|
||||
*/
|
||||
static inline void
|
||||
cinelerra_time_normalize (CinelerraTime time)
|
||||
{
|
||||
REQUIRE (time);
|
||||
if (time->tv_usec >= 1000000)
|
||||
{
|
||||
time->tv_sec += (time->tv_usec / 1000000);
|
||||
time->tv_usec = (time->tv_usec % 1000000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set a time value to zero.
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_time_clear (CinelerraTime time)
|
||||
{
|
||||
if(time)
|
||||
{
|
||||
time->tv_sec = 0;
|
||||
time->tv_usec = 0;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* get current time.
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_time_current (CinelerraTime time)
|
||||
{
|
||||
if (time)
|
||||
{
|
||||
/* gettime should never ever fail in a correct program */
|
||||
if (gettimeofday (time, NULL))
|
||||
CINELERRA_DIE;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* init from floating point representation.
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_time_set_double (CinelerraTime time, double fp)
|
||||
{
|
||||
if (time)
|
||||
{
|
||||
if (fp >= 0.0)
|
||||
{
|
||||
time->tv_sec = fp;
|
||||
time->tv_usec = round((fp - time->tv_sec) * 1000000.0);
|
||||
return time;
|
||||
}
|
||||
else
|
||||
{
|
||||
time->tv_sec = (time_t)-1;
|
||||
time->tv_usec = (suseconds_t)-1;
|
||||
cinelerra_error_set(CINELERRA_ERROR_TIME_NEGATIVE);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize with seconds and microseconds.
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_time_init (CinelerraTime time, time_t sec, suseconds_t usec)
|
||||
{
|
||||
if (time)
|
||||
{
|
||||
time->tv_sec = sec;
|
||||
time->tv_usec = usec;
|
||||
cinelerra_time_normalize (time);
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the seconds part from a time.
|
||||
*/
|
||||
static inline time_t
|
||||
cinelerra_time_sec (CinelerraTime time)
|
||||
{
|
||||
if (time)
|
||||
return time->tv_sec;
|
||||
else
|
||||
return (time_t)-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the microseconds part of a time.
|
||||
*/
|
||||
static inline suseconds_t
|
||||
cinelerra_time_usec (CinelerraTime time)
|
||||
{
|
||||
if (time)
|
||||
return time->tv_usec;
|
||||
else
|
||||
return (suseconds_t)-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert to floating point repesentation.
|
||||
*/
|
||||
static inline double
|
||||
cinelerra_time_double_get (CinelerraTime time)
|
||||
{
|
||||
if (time)
|
||||
{
|
||||
double fp;
|
||||
|
||||
fp = time->tv_sec;
|
||||
fp += time->tv_usec / 1000000.0;
|
||||
return fp;
|
||||
}
|
||||
return NAN;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy time
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_time_copy (CinelerraTime dest, const CinelerraTime src)
|
||||
{
|
||||
if (dest && src)
|
||||
{
|
||||
dest->tv_sec = src->tv_sec;
|
||||
dest->tv_usec = src->tv_usec;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* add time.
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_time_add (CinelerraTime dest, const CinelerraTime src)
|
||||
{
|
||||
if (dest && src)
|
||||
{
|
||||
time_t t = dest->tv_sec;
|
||||
|
||||
dest->tv_sec += src->tv_sec;
|
||||
dest->tv_usec += src->tv_usec;
|
||||
|
||||
cinelerra_time_normalize (dest);
|
||||
|
||||
if (dest->tv_sec < t)
|
||||
{
|
||||
cinelerra_error_set (CINELERRA_ERROR_TIME_OVERFLOW);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* substact time.
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_time_sub (CinelerraTime dest, const CinelerraTime src)
|
||||
{
|
||||
if (dest && src)
|
||||
{
|
||||
time_t t = dest->tv_sec;
|
||||
|
||||
dest->tv_sec -= src->tv_sec;
|
||||
if (dest->tv_usec >= src->tv_usec)
|
||||
dest->tv_usec -= src->tv_usec;
|
||||
else
|
||||
{
|
||||
--dest->tv_sec;
|
||||
dest->tv_usec += 1000000 - src->tv_usec;
|
||||
}
|
||||
|
||||
cinelerra_time_normalize (dest);
|
||||
|
||||
if (dest->tv_sec > t)
|
||||
{
|
||||
cinelerra_error_set (CINELERRA_ERROR_TIME_UNDERFLOW);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,15 +1,126 @@
|
|||
|
||||
TESTING "Time functions"
|
||||
TESTING "Time functions" ./test-time
|
||||
|
||||
PLANNED "get time"
|
||||
PLANNED "add time, normalized"
|
||||
PLANNED "substract time, normalized"
|
||||
TEST "time init" init 15 500000 <<END
|
||||
out: 15 500000
|
||||
END
|
||||
|
||||
TEST "time normalize" init 0 1500000 <<END
|
||||
out: 1 500000
|
||||
END
|
||||
|
||||
TEST "time to float" todouble 15 500000 <<END
|
||||
out: 15.5
|
||||
END
|
||||
|
||||
TEST "time to float, NULL gives a NaN" todoublenull <<END
|
||||
out: nan
|
||||
END
|
||||
|
||||
TEST "float to time" fromdouble 33.6666666661 <<END
|
||||
out: 33 666667
|
||||
END
|
||||
|
||||
TEST "float to time, round down" fromdouble 0.00000049 <<END
|
||||
out: 0 0
|
||||
END
|
||||
|
||||
TEST "float to time, round up" fromdouble 0.0000005 <<END
|
||||
out: 0 1
|
||||
END
|
||||
|
||||
TEST "current time" currenttime <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
TEST "add time, normalized" add 1000001 2000002 <<END
|
||||
out: 3 3
|
||||
END
|
||||
|
||||
TEST "substract time, normalized" sub 3000003 2000002 <<END
|
||||
out: 1 1
|
||||
END
|
||||
|
||||
PLANNED "overflow"
|
||||
PLANNED "underflow"
|
||||
|
||||
# frame 1 begins at time 0
|
||||
TEST "time to frame NTSC frame 1 begin" ntscframefromtime 0 0 <<END
|
||||
out: 1
|
||||
END
|
||||
|
||||
# and ends at 33365
|
||||
TEST "time to frame NTSC frame 1 end" ntscframefromtime 0 33365 <<END
|
||||
out: 1
|
||||
END
|
||||
|
||||
# thus 33366 is start of frame 2
|
||||
TEST "time to frame NTSC frame 2 begin" ntscframefromtime 0 33366 <<END
|
||||
out: 2
|
||||
END
|
||||
|
||||
# and 66732 is the end of frame 2
|
||||
TEST "time to frame NTSC frame 2 end" ntscframefromtime 0 66732 <<END
|
||||
out: 2
|
||||
END
|
||||
|
||||
# this makes 66733 the start of frame 3
|
||||
TEST "time to frame NTSC frame 3 begin" ntscframefromtime 0 66733 <<END
|
||||
out: 3
|
||||
END
|
||||
|
||||
# after 1 hour we are at frame 107893
|
||||
TEST "time to frame NTSC after 1hour" ntscframefromtime 3600 0 <<END
|
||||
out: 107893
|
||||
END
|
||||
|
||||
# after 200 days we are at frame 517881601
|
||||
TEST "time to frame NTSC after 200 days" ntscframefromtime 17280000 0 <<END
|
||||
out: 517882118
|
||||
END
|
||||
|
||||
|
||||
# the next ones for different common framerates, check corner cases
|
||||
PLANNED "time to frame"
|
||||
PLANNED "frame to time"
|
||||
TEST "frame to time NTSC frame 1" ntscframestart 1 <<END
|
||||
out: 0 0
|
||||
END
|
||||
|
||||
TEST "frame to time NTSC frame 2" ntscframestart 2 <<END
|
||||
out: 0 33366
|
||||
END
|
||||
|
||||
TEST "frame->time->frame conversion 2" ntscframecheck 2 <<END
|
||||
out: frame 2 1
|
||||
END
|
||||
|
||||
TEST "frame->time->frame conversion 3" ntscframecheck 3 <<END
|
||||
out: frame 3 2
|
||||
END
|
||||
TEST "frame->time->frame conversion 4" ntscframecheck 4 <<END
|
||||
out: frame 4 3
|
||||
END
|
||||
TEST "frame->time->frame conversion 5" ntscframecheck 5 <<END
|
||||
out: frame 5 4
|
||||
END
|
||||
TEST "frame->time->frame conversion 6" ntscframecheck 6 <<END
|
||||
out: frame 6 5
|
||||
END
|
||||
TEST "frame->time->frame conversion 7" ntscframecheck 7 <<END
|
||||
out: frame 7 6
|
||||
END
|
||||
TEST "frame->time->frame conversion 8" ntscframecheck 8 <<END
|
||||
out: frame 8 7
|
||||
END
|
||||
TEST "frame->time->frame conversion 9" ntscframecheck 9 <<END
|
||||
out: frame 9 8
|
||||
END
|
||||
|
||||
TEST "frame->time->frame conversion 100000" ntscframecheck 100000 <<END
|
||||
out: frame 100000 99999
|
||||
END
|
||||
|
||||
TEST "frame->time->frame conversion 999999" ntscframecheck 999999 <<END
|
||||
out: frame 999999 999998
|
||||
END
|
||||
|
||||
# how long are N frames on average (beware of precision!)
|
||||
PLANNED "frame duration"
|
||||
|
|
|
|||
|
|
@ -18,10 +18,14 @@
|
|||
|
||||
tests_srcdir = $(top_srcdir)/tests
|
||||
|
||||
check_PROGRAMS += test-error
|
||||
check_PROGRAMS += test-error test-time
|
||||
|
||||
test_error_SOURCES = $(tests_srcdir)/error/errortest.c
|
||||
test_error_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
test_error_LDADD = $(builddir)/libcin3.a -lnobugmt -lpthread -ldl
|
||||
|
||||
test_time_SOURCES = $(tests_srcdir)/time/test-time.c
|
||||
test_time_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
test_time_LDADD = $(builddir)/libcin3.a -lnobugmt -lpthread -ldl -lm
|
||||
|
||||
TESTS = $(tests_srcdir)/test.sh
|
||||
|
|
|
|||
1
tests/time/DIR_INFO
Normal file
1
tests/time/DIR_INFO
Normal file
|
|
@ -0,0 +1 @@
|
|||
test time and frame calculations
|
||||
147
tests/time/test-time.c
Normal file
147
tests/time/test-time.c
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
test-time.c - test time and framerate functions
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/time.h"
|
||||
#include "lib/framerate.h"
|
||||
|
||||
|
||||
CINELERRA_ERROR_DEFINE(TEST, "test error");
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
NOBUG_INIT;
|
||||
|
||||
if (argc == 1)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(argv[1], "init"))
|
||||
{
|
||||
cinelerra_time time;
|
||||
|
||||
cinelerra_time_init (&time, atol (argv[2]), atol(argv[3]));
|
||||
|
||||
printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "todouble"))
|
||||
{
|
||||
cinelerra_time time;
|
||||
|
||||
cinelerra_time_init (&time, atol (argv[2]), atol(argv[3]));
|
||||
|
||||
printf ("%g\n", cinelerra_time_double_get (&time));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "todoublenull"))
|
||||
{
|
||||
printf ("%g\n", cinelerra_time_double_get (NULL));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "fromdouble"))
|
||||
{
|
||||
cinelerra_time time;
|
||||
|
||||
cinelerra_time_set_double (&time, atof (argv[2]));
|
||||
|
||||
printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "currenttime"))
|
||||
{
|
||||
cinelerra_time time;
|
||||
|
||||
cinelerra_time_current (&time);
|
||||
|
||||
printf ("%lu %lu\n", (long)cinelerra_time_sec (&time), (long)cinelerra_time_usec (&time));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "add"))
|
||||
{
|
||||
cinelerra_time time1, time2;
|
||||
|
||||
cinelerra_time_init (&time1, 0, atol (argv[2]));
|
||||
cinelerra_time_init (&time2, 0, atol (argv[3]));
|
||||
cinelerra_time_add (&time1, &time2);
|
||||
|
||||
printf ("%lu %lu\n", (long)cinelerra_time_sec (&time1), (long)cinelerra_time_usec (&time1));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "sub"))
|
||||
{
|
||||
cinelerra_time time1, time2;
|
||||
|
||||
cinelerra_time_init (&time1, 0, atol (argv[2]));
|
||||
cinelerra_time_init (&time2, 0, atol (argv[3]));
|
||||
cinelerra_time_sub (&time1, &time2);
|
||||
|
||||
printf ("%lu %lu\n", (long)cinelerra_time_sec (&time1), (long)cinelerra_time_usec (&time1));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "ntscframefromtime"))
|
||||
{
|
||||
cinelerra_framerate ntsc = {30000, 1001};
|
||||
cinelerra_time time;
|
||||
|
||||
cinelerra_time_init (&time, atol (argv[2]), atol (argv[3]));
|
||||
|
||||
printf ("%lu\n", (long)cinelerra_framerate_frame_get_time (&ntsc, &time));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "ntscframestart"))
|
||||
{
|
||||
cinelerra_framerate ntsc = {30000, 1001};
|
||||
cinelerra_time time;
|
||||
|
||||
if(cinelerra_framerate_time_get_time_frame (&ntsc, &time, atol (argv[2])))
|
||||
printf ("%lu %lu\n", (long)cinelerra_time_sec(&time), (long)cinelerra_time_usec(&time));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "ntscframecheck"))
|
||||
{
|
||||
cinelerra_framerate ntsc = {30000, 1001};
|
||||
cinelerra_time time1;
|
||||
cinelerra_time time2;
|
||||
cinelerra_framepos frame;
|
||||
|
||||
cinelerra_framepos frame1;
|
||||
cinelerra_framepos frame2;
|
||||
|
||||
frame = atol (argv[2]);
|
||||
|
||||
|
||||
if (cinelerra_framerate_time_get_time_frame (&ntsc, &time1, frame))
|
||||
{
|
||||
printf("frame %lu ", frame1 = cinelerra_framerate_frame_get_time (&ntsc, &time1));
|
||||
|
||||
cinelerra_time_init (&time2, 0, 1);
|
||||
cinelerra_time_sub (&time1, &time2);
|
||||
printf("%lu\n", frame2 = cinelerra_framerate_frame_get_time (&ntsc, &time1));
|
||||
ENSURE (frame1 == frame2+1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -720,6 +720,19 @@ We use a common base class for all our application specific exceptions. These ex
|
|||
* getting standardized error messages automatically
|
||||
</pre>
|
||||
</div>
|
||||
<div title="FrameAndTime" modifier="CehTeh" modified="200708282024" created="200708261938" changecount="2">
|
||||
<pre>! Framerates
|
||||
Framerates are stored as rational numbers eg. 30000/1001 for NTSC, this representation allows highly precise integer calculations for frames and times.
|
||||
|
||||
! Frames
|
||||
All calculations in cinelerra are based on frames which is a signed integer type. Together with a Framerate and a starting point, every frame can be exactly located.
|
||||
|
||||
! Time
|
||||
Time is used only internally in cinelerra, every external representation of time will be converted to frames. Time has a precision of 1 microsecond and is stored in POSIX struct timeval. Time is always handled as absolute time, thus frame addresses map to absolute times, there is at worst a 1us precision jitter but no drift.
|
||||
|
||||
!! SMPTE and other Timecodes
|
||||
will be added on demand, but be frame based, not time based</pre>
|
||||
</div>
|
||||
<div title="FullScreenPlugin" modifier="CehTeh" modified="200706110313" created="200607241016" tags="systemConfig lewcidExtension" server.type="file" server.host="file:///home/ct/.homepage/home.html" server.page.revision="200706110313">
|
||||
<pre>/***
|
||||
|Name|FullScreenPlugin|
|
||||
|
|
@ -2360,7 +2373,7 @@ h1,h2,h3,h4,h5,h6 {
|
|||
/*}}}*/
|
||||
</pre>
|
||||
</div>
|
||||
<div title="SupportLibrary" modifier="MichaelPloujnikov" modified="200707160346" created="200707102314" changecount="6">
|
||||
<div title="SupportLibrary" modifier="CehTeh" modified="200708261935" created="200707102314" changecount="8">
|
||||
<pre>The Support Library contains all tools we need at various places, but by themselves don't defines a subsystem on their own.
|
||||
|
||||
These things are:
|
||||
|
|
@ -2369,7 +2382,7 @@ These things are:
|
|||
* a wrapper for POSIX Threads
|
||||
** Thread creation joining and canceling
|
||||
** Locking primitives like Condition variables and Mutexes
|
||||
|
||||
* [[Frame and Time handling and calculations|FrameAndTime]]
|
||||
|
||||
(... to be continued)
|
||||
</pre>
|
||||
|
|
|
|||
Loading…
Reference in a new issue