From: Antonio Ospite Date: Tue, 17 Dec 2013 23:03:11 +0000 (+0100) Subject: Split out fps-limit.h X-Git-Url: https://git.ao2.it/experiments/fps-limit.git/commitdiff_plain/306059ddaeae629c80b97b742af99e2356e516cd?ds=inline;hp=cdb5bba4158d7231d638c957b1ecf0a397d126cc Split out fps-limit.h --- diff --git a/Makefile b/Makefile index 961ef03..cec8b3c 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,7 @@ CFLAGS += -D_POSIX_C_SOURCE=200112L LDLIBS += -lrt fps-limit: fps-limit.o +fps-limit.o: fps-limit.h clean: rm -rf *~ *.o fps-limit diff --git a/fps-limit.c b/fps-limit.c index 3ed784f..101f126 100644 --- a/fps-limit.c +++ b/fps-limit.c @@ -17,77 +17,10 @@ * along with this program. If not, see . */ -#include -#include -#include - -#ifdef DEBUG -#define dbg(...) \ - do { \ - printf(__VA_ARGS__); \ - printf("\n"); \ - fflush(stdout); \ - } while(0) -#else -#define dbg(...) do {} while(0) -#endif +#include "fps-limit.h" #define FPS 60 -#define NSEC_PER_SEC 1000000000 - -#define timespecsub(a, b, result) \ - do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \ - if ((result)->tv_nsec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_nsec += 1000000000; \ - } \ - } while(0) - -struct fps_limit_stats { - struct timespec time_start; - struct timespec time_end; - unsigned int fps; -}; - -static void fps_limit_init(struct fps_limit_stats *stats, unsigned int fps) -{ - memset(stats, 0, sizeof(*stats)); - - clock_gettime(CLOCK_MONOTONIC, &stats->time_start); - dbg("Init time: s: %ld, ns: %ld", stats->time_start.tv_sec, stats->time_start.tv_nsec); - - stats->fps = fps; -} - -static void fps_limit_sleep(struct fps_limit_stats *stats) -{ - struct timespec elapsed; - - dbg("Start time: s: %ld, ns: %ld", stats->time_start.tv_sec, stats->time_start.tv_nsec); - - clock_gettime(CLOCK_MONOTONIC, &stats->time_end); - dbg("End time: s: %ld, ns: %ld", stats->time_end.tv_sec, stats->time_end.tv_nsec); - - timespecsub(&stats->time_end, &stats->time_start, &elapsed); - dbg("Elapsed s: %ld ns: %ld", elapsed.tv_sec, elapsed.tv_nsec); - - if (elapsed.tv_sec == 0 && elapsed.tv_nsec < NSEC_PER_SEC / stats->fps) { - struct timespec remaining = {0, 0}; - - /* remaining delay, _relative_ to time_end */ - remaining.tv_nsec = (NSEC_PER_SEC / stats->fps) - elapsed.tv_nsec; - dbg("Sleeping for: ns: %ld", remaining.tv_nsec); - - clock_nanosleep(CLOCK_MONOTONIC, 0, &remaining, NULL); - } - - /* update the stats for the next iteration */ - clock_gettime(CLOCK_MONOTONIC, &stats->time_start); -} - int main(void) { struct fps_limit_stats stats; diff --git a/fps-limit.h b/fps-limit.h new file mode 100644 index 0000000..101cf1d --- /dev/null +++ b/fps-limit.h @@ -0,0 +1,91 @@ +/* + * fps-limit - Some functions to limit frames per seconds + * + * Copyright (C) 2013 Antonio Ospite + * + * 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 3 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, see . + */ + +#ifndef FPS_LIMIT_H +#define FPS_LIMIT_H + +#include +#include +#include + +#ifdef DEBUG +#define dbg(...) \ + do { \ + printf(__VA_ARGS__); \ + printf("\n"); \ + fflush(stdout); \ + } while(0) +#else +#define dbg(...) do {} while(0) +#endif + +#define NSEC_PER_SEC 1000000000 + +#define timespecsub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \ + if ((result)->tv_nsec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_nsec += 1000000000; \ + } \ + } while(0) + +struct fps_limit_stats { + struct timespec time_start; + struct timespec time_end; + unsigned int fps; +}; + +static void fps_limit_init(struct fps_limit_stats *stats, unsigned int fps) +{ + memset(stats, 0, sizeof(*stats)); + + clock_gettime(CLOCK_MONOTONIC, &stats->time_start); + dbg("Init time: s: %ld, ns: %ld", stats->time_start.tv_sec, stats->time_start.tv_nsec); + + stats->fps = fps; +} + +static void fps_limit_sleep(struct fps_limit_stats *stats) +{ + struct timespec elapsed; + + dbg("Start time: s: %ld, ns: %ld", stats->time_start.tv_sec, stats->time_start.tv_nsec); + + clock_gettime(CLOCK_MONOTONIC, &stats->time_end); + dbg("End time: s: %ld, ns: %ld", stats->time_end.tv_sec, stats->time_end.tv_nsec); + + timespecsub(&stats->time_end, &stats->time_start, &elapsed); + dbg("Elapsed s: %ld ns: %ld", elapsed.tv_sec, elapsed.tv_nsec); + + if (elapsed.tv_sec == 0 && elapsed.tv_nsec < NSEC_PER_SEC / stats->fps) { + struct timespec remaining = {0, 0}; + + /* remaining delay, _relative_ to time_end */ + remaining.tv_nsec = (NSEC_PER_SEC / stats->fps) - elapsed.tv_nsec; + dbg("Sleeping for: ns: %ld", remaining.tv_nsec); + + clock_nanosleep(CLOCK_MONOTONIC, 0, &remaining, NULL); + } + + /* update the stats for the next iteration */ + clock_gettime(CLOCK_MONOTONIC, &stats->time_start); +} +#endif /* FPS_LIMIT_H */