refined and corrected framerate caclulation

This commit is contained in:
Christian Thaeter 2007-08-28 19:28:41 +02:00
parent c2898d26f2
commit e41059497f
4 changed files with 56 additions and 27 deletions

View file

@ -29,5 +29,6 @@ libcin3_a_SOURCES = \
noinst_HEADERS += \
$(libcin3_a_srcdir)/plugin.h \
$(libcin3_a_srcdir)/error.h \
$(libcin3_a_srcdir)/time.h
$(libcin3_a_srcdir)/time.h \
$(libcin3_a_srcdir)/framerate.h

View file

@ -27,7 +27,7 @@
/**
* framerates are defined as a rational number
* for example NTSC with 29.97fps is {2997, 100}
* for example NTSC with 30000/1001fps
*/
struct cinelerra_framerate_struct
{
@ -68,7 +68,7 @@ cinelerra_framerate_time_get_time_frame (const CinelerraFramerate framerate,
REQUIRE (frame>0);
TODO ("if(!time)..");
unsigned long long usec = (frame-1) * (framerate->d * 1000000ULL) / framerate->n;
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;

View file

@ -69,16 +69,6 @@ TEST "time to frame NTSC frame 3 begin" ntscframefromtime 0 66733 <<END
out: 3
END
# and 100099 the end of frame 3
TEST "time to frame NTSC frame 3 end" ntscframefromtime 0 100099 <<END
out: 3
END
# and 100100 the start of frame 4
TEST "time to frame NTSC frame 4 start" ntscframefromtime 0 100100 <<END
out: 4
END
# after 1 hour we are at frame 107893
TEST "time to frame NTSC after 1hour" ntscframefromtime 3600 0 <<END
out: 107893
@ -86,7 +76,7 @@ END
# after 200 days we are at frame 517881601
TEST "time to frame NTSC after 200 days" ntscframefromtime 17280000 0 <<END
out: 517881601
out: 517882118
END
@ -98,24 +88,40 @@ TEST "frame to time NTSC frame 2" ntscframestart 2 <<END
out: 0 33366
END
TEST "frame to time NTSC frame 3" ntscframestart 3 <<END
out: 0 66733
TEST "frame->time->frame conversion 2" ntscframecheck 2 <<END
out: frame 2 1
END
TEST "frame to time NTSC frame 4" ntscframestart 4 <<END
out: 0 100100
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 to time NTSC 1 hour" ntscframestart 107893 <<END
out: 3600 0
TEST "frame->time->frame conversion 100000" ntscframecheck 100000 <<END
out: frame 100000 99999
END
TEST "frame to time NTSC 200 days" ntscframestart 517881601 <<END
out: 17280000 0
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"

View file

@ -23,7 +23,7 @@
#include <string.h>
#include "lib/time.h"
#include "lib/frames.h"
#include "lib/framerate.h"
CINELERRA_ERROR_DEFINE(TEST, "test error");
@ -101,7 +101,7 @@ main (int argc, char** argv)
if (!strcmp(argv[1], "ntscframefromtime"))
{
cinelerra_framerate ntsc = {2997, 100};
cinelerra_framerate ntsc = {30000, 1001};
cinelerra_time time;
cinelerra_time_init (&time, atol (argv[2]), atol (argv[3]));
@ -111,7 +111,7 @@ main (int argc, char** argv)
if (!strcmp(argv[1], "ntscframestart"))
{
cinelerra_framerate ntsc = {2997, 100};
cinelerra_framerate ntsc = {30000, 1001};
cinelerra_time time;
cinelerra_framerate_time_get_time_frame (&ntsc, &time, atol (argv[2]));
@ -119,6 +119,28 @@ main (int argc, char** argv)
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]);
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;
}