add documentation and error handling to framerate functions

This commit is contained in:
Christian Thaeter 2007-08-29 17:41:10 +02:00
parent 017e19c108
commit e438ad6e8f
4 changed files with 70 additions and 19 deletions

View file

@ -24,8 +24,9 @@ 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)/time.c \
$(libcin3_a_srcdir)/framerate.c
noinst_HEADERS += \
$(libcin3_a_srcdir)/plugin.h \
$(libcin3_a_srcdir)/error.h \

25
src/lib/framerate.c Normal file
View 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");

View file

@ -22,6 +22,8 @@
#ifndef CINELERRA_FRAMERATE_H
#define CINELERRA_FRAMERATE_H
#include <limits.h>
#include "lib/error.h"
#include "lib/time.h"
@ -38,17 +40,30 @@ struct cinelerra_framerate_struct
typedef struct cinelerra_framerate_struct cinelerra_framerate;
typedef cinelerra_framerate* CinelerraFramerate;
typedef unsigned long cinelerra_framepos;
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);
TODO ("if(!time)..");
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.
*/
@ -58,6 +73,10 @@ cinelerra_framerate_frame_get_time (const CinelerraFramerate framerate, Cinelerr
/**
* 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,
@ -65,14 +84,19 @@ cinelerra_framerate_time_get_time_frame (const CinelerraFramerate framerate,
cinelerra_framepos frame)
{
REQUIRE (framerate);
REQUIRE (frame>0);
TODO ("if(!time)..");
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;
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;
}

View file

@ -114,9 +114,8 @@ main (int argc, char** argv)
cinelerra_framerate ntsc = {30000, 1001};
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));
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"))
@ -132,14 +131,16 @@ main (int argc, char** argv)
frame = atol (argv[2]);
cinelerra_framerate_time_get_time_frame (&ntsc, &time1, frame);
printf("frame %lu ", frame1 = cinelerra_framerate_frame_get_time (&ntsc, &time1));
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));
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);
}
ENSURE (frame1 == frame2+1);
}
return 0;