diff --git a/server.c b/server.c index 6c47232..02e33f8 100644 --- a/server.c +++ b/server.c @@ -15,8 +15,7 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -/* 10 frames per second (if we can) */ -#define PICTURE_TIMEOUT (1.0/10.0) +#define FPS 10 #define UINPUT_ABS_MAX INT16_MAX #define UINPUT_MAX_KEY 256 @@ -26,22 +25,27 @@ struct Vec2d { }; struct Vec2d resolution; -/* - * throttle camera updates -*/ -static int TimeToTakePicture() { - static struct timeval now={0,0}, then={0,0}; - double elapsed, dnow, dthen; +#define SLEEPNS (1000000000 / FPS) +static void between_frames() { + static struct timespec now={0,0}, then={0,0}, tmp={0,0}; - gettimeofday(&now,NULL); - - dnow = now.tv_sec + (now.tv_usec /1000000.0); - dthen = then.tv_sec + (then.tv_usec/1000000.0); - elapsed = dnow - dthen; - - if (elapsed > PICTURE_TIMEOUT) - memcpy((char *)&then, (char *)&now, sizeof(struct timeval)); - return elapsed > PICTURE_TIMEOUT; + clock_gettime(CLOCK_MONOTONIC, &now); + memcpy((char*)&then, (char*)&tmp, sizeof(struct timespec)); + tmp.tv_nsec += SLEEPNS; + if (tmp.tv_nsec >= 1000000000) { + tmp.tv_sec ++; + tmp.tv_nsec %= 1000000000; + } + if (now.tv_sec < tmp.tv_sec || (now.tv_sec == tmp.tv_sec && now.tv_nsec < tmp.tv_nsec)) { + then.tv_sec = tmp.tv_sec - now.tv_sec; + then.tv_nsec = tmp.tv_nsec - now.tv_nsec; + if (then.tv_nsec < 0) { + then.tv_sec --; + then.tv_nsec += 1000000000; + } + nanosleep(&then, &then); + } + memcpy((char*)&now, (char*)&then, sizeof(struct timespec)); } static void convert_bgrx_to_rgb(const char* in, int width, int height, char* buff) { @@ -477,9 +481,7 @@ int main(int argc, const char **argv) size_t buflen = fb->width * fb->height * 32 / 8; char *buf = malloc(buflen); - char *buf2 = malloc(buflen); memset(buf, 0, buflen); - memset(buf2, 0, buflen); resolution.x = fb->width; resolution.y = fb->height; @@ -498,11 +500,11 @@ int main(int argc, const char **argv) rfbInitServer(server); rfbRunEventLoop(server,-1,TRUE); while (rfbIsActive(server)) { - if (server->clientHead && TimeToTakePicture()) { + between_frames(); + if (server->clientHead) { funcs.sync_start(primefd); - memcpy(buf2, mapped, buflen); + funcs.convert(mapped, fb->width, fb->height, buf); funcs.sync_end(primefd); - funcs.convert(buf2, fb->width, fb->height, buf); rfbMarkRectAsModified(server, 0, 0, fb->width, fb->height); } }