From: Antonio Ospite Date: Sun, 14 Jul 2013 11:14:26 +0000 (+0200) Subject: Factor out some more useful functions X-Git-Url: https://git.ao2.it/experiments/fps-limit.git/commitdiff_plain/79510a9d3bee77059bd543413ccc9aa739881c52?ds=inline;hp=ce00a8af50035f3db13f1795061d55e943f2e969 Factor out some more useful functions --- diff --git a/fps-limit.c b/fps-limit.c index 7759349..3ed784f 100644 --- a/fps-limit.c +++ b/fps-limit.c @@ -18,6 +18,7 @@ */ #include +#include #include #ifdef DEBUG @@ -45,34 +46,61 @@ } \ } while(0) -int main(void) -{ +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; - struct timespec remaining = {0, 0}; + 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; struct timespec tmp; + fps_limit_init(&stats, FPS); while (1) { - clock_gettime(CLOCK_MONOTONIC, &time_start); - dbg("Start time: s: %ld, ns: %ld", time_start.tv_sec, time_start.tv_nsec); - dbg("Doing some work, max: %d", NSEC_PER_SEC / FPS); tmp.tv_sec = 0; tmp.tv_nsec = (NSEC_PER_SEC / FPS) * 2 / 3; nanosleep(&tmp, NULL); - clock_gettime(CLOCK_MONOTONIC, &time_end); - dbg("End time: s: %ld, ns: %ld", time_end.tv_sec, time_end.tv_nsec); - timespecsub(&time_end, &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 / FPS) { - /* remaining delay, _relative_ to time_end */ - remaining.tv_nsec = (NSEC_PER_SEC / FPS) - elapsed.tv_nsec; - dbg("Sleeping for: ns: %ld", remaining.tv_nsec); - clock_nanosleep(CLOCK_MONOTONIC, 0, &remaining, NULL); - } + fps_limit_sleep(&stats); } return 0;