put framerate caclulation in a single file
This commit is contained in:
parent
9472c115e7
commit
c2898d26f2
4 changed files with 172 additions and 20 deletions
79
src/lib/framerate.h
Normal file
79
src/lib/framerate.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
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 "lib/error.h"
|
||||
#include "lib/time.h"
|
||||
|
||||
/**
|
||||
* framerates are defined as a rational number
|
||||
* for example NTSC with 29.97fps is {2997, 100}
|
||||
*/
|
||||
struct cinelerra_framerate_struct
|
||||
{
|
||||
unsigned n; //numerator
|
||||
unsigned d; //denominator
|
||||
};
|
||||
|
||||
typedef struct cinelerra_framerate_struct cinelerra_framerate;
|
||||
typedef cinelerra_framerate* CinelerraFramerate;
|
||||
|
||||
typedef unsigned long cinelerra_framepos;
|
||||
|
||||
/**
|
||||
* Get the frame number of a given time at a given frame rate.
|
||||
* frame indexing starts with 1
|
||||
*/
|
||||
static inline cinelerra_framepos
|
||||
cinelerra_framerate_frame_get_time (const CinelerraFramerate framerate, CinelerraTime time)
|
||||
{
|
||||
REQUIRE (framerate);
|
||||
TODO ("if(!time)..");
|
||||
/* 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
|
||||
*/
|
||||
static inline CinelerraTime
|
||||
cinelerra_framerate_time_get_time_frame (const CinelerraFramerate framerate,
|
||||
CinelerraTime time,
|
||||
cinelerra_framepos frame)
|
||||
{
|
||||
REQUIRE (framerate);
|
||||
REQUIRE (frame>0);
|
||||
TODO ("if(!time)..");
|
||||
|
||||
unsigned long long usec = (frame-1) * (framerate->d * 1000000ULL) / framerate->n;
|
||||
|
||||
time->tv_sec = usec / 1000000;
|
||||
time->tv_usec = usec % 1000000;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
time.h - Time and frame calculations
|
||||
time.h - Time calculations
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
|
@ -49,22 +49,6 @@ CINELERRA_ERROR_DECLARE(TIME_NEGATIVE);
|
|||
typedef struct timeval cinelerra_time;
|
||||
typedef cinelerra_time* CinelerraTime;
|
||||
|
||||
/**
|
||||
* framerates are defined as a rational number
|
||||
* for example NTSC with 29.97fps is {2997, 100}
|
||||
*/
|
||||
struct cinelerra_framerate_struct
|
||||
{
|
||||
unsigned numerator;
|
||||
unsigned denominator;
|
||||
};
|
||||
|
||||
typedef struct cinelerra_framerate_struct cinelerra_framerate;
|
||||
typedef cinelerra_framerate* CinelerraFramerate;
|
||||
|
||||
typedef unsigned long cinelerra_frame;
|
||||
|
||||
|
||||
/**
|
||||
* normalize time after operations.
|
||||
* used internally
|
||||
|
|
|
|||
|
|
@ -44,10 +44,76 @@ 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
|
||||
|
||||
# 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
|
||||
END
|
||||
|
||||
# after 200 days we are at frame 517881601
|
||||
TEST "time to frame NTSC after 200 days" ntscframefromtime 17280000 0 <<END
|
||||
out: 517881601
|
||||
END
|
||||
|
||||
|
||||
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 to time NTSC frame 3" ntscframestart 3 <<END
|
||||
out: 0 66733
|
||||
END
|
||||
|
||||
TEST "frame to time NTSC frame 4" ntscframestart 4 <<END
|
||||
out: 0 100100
|
||||
END
|
||||
|
||||
TEST "frame to time NTSC 1 hour" ntscframestart 107893 <<END
|
||||
out: 3600 0
|
||||
END
|
||||
|
||||
TEST "frame to time NTSC 200 days" ntscframestart 517881601 <<END
|
||||
out: 17280000 0
|
||||
END
|
||||
|
||||
# the next ones for different common framerates, check corner cases
|
||||
PLANNED "time to frame"
|
||||
PLANNED "frame to time"
|
||||
|
||||
|
||||
# how long are N frames on average (beware of precision!)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "lib/time.h"
|
||||
#include "lib/frames.h"
|
||||
|
||||
|
||||
CINELERRA_ERROR_DEFINE(TEST, "test error");
|
||||
|
|
@ -30,6 +31,8 @@ CINELERRA_ERROR_DEFINE(TEST, "test error");
|
|||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
NOBUG_INIT;
|
||||
|
||||
if (argc == 1)
|
||||
return 0;
|
||||
|
||||
|
|
@ -96,6 +99,26 @@ main (int argc, char** argv)
|
|||
printf ("%lu %lu\n", (long)cinelerra_time_sec (&time1), (long)cinelerra_time_usec (&time1));
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "ntscframefromtime"))
|
||||
{
|
||||
cinelerra_framerate ntsc = {2997, 100};
|
||||
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 = {2997, 100};
|
||||
cinelerra_time time;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue